def broadcast(data):
    global global_seq_no
    msg = xbee_relay_cmd_pb2.XBee_Relay_Cmd()
    msg.command = BROADCAST_TO_XBEE
    msg.data = data
    msg.seq_no = global_seq_no
    global_seq_no += 1
    for client in relay_clients:
        unixIPC.sendTo('xbee_relay_cmd_pb2', msg, client)
    return msg.seq_no
def sendToXbee(xbee_addr, data):
    global global_seq_no
    msg = xbee_relay_cmd_pb2.XBee_Relay_Cmd()
    msg.command = FORWARD_TO_XBEE
    msg.data = data
    msg.to = xbee_addr
    msg.seq_no = global_seq_no
    global_seq_no += 1
    if ( xbee_addr in xbee_addr_to_relay_clients_map ):
        unixIPC.sendTo('xbee_relay_cmd_pb2',msg,xbee_addr_to_relay_clients_map[xbee_addr])
        message_tracking_map[(msg.seq_no,xbee_addr_to_relay_clients_map[xbee_addr])] = (xbee_addr, time.time());
    else:
        for client in relay_clients:
            unixIPC.sendTo('xbee_relay_cmd_pb2', msg, client)
            message_tracking_map[(msg.seq_no,client)] = (xbee_addr, time.time());
            
    return msg.seq_no
                        else:
                            print_log("Process " + exec_cmd_msg.name + " not found.")
                    elif exec_cmd_msg.command == exec_cmd_pb2.Exec_Cmd.LIST:
                        exec_resp_msg = exec_resp_pb2.Exec_Resp()
                        exec_resp_msg.type = exec_resp_pb2.Exec_Resp.STATE
                        for mod in modules:
                            proc = exec_resp_msg.processes.add()
                            proc.name = mod.name
                            if not mod.running and not mod.should_run:
                                proc.state = exec_resp_pb2.Exec_Resp.STOPPED
                            elif not mod.running and mod.should_run:
                                proc.state = exec_resp_pb2.Exec_Resp.RESTARTING
                            elif mod.running:
                                proc.state = exec_resp_pb2.Exec_Resp.RUNNING

                        unixIPC.sendTo("exec_resp_pb2", exec_resp_msg.SerializeToString(), client)
                    elif exec_cmd_msg.command == exec_cmd_pb2.Exec_Cmd.STATE:
                        exec_resp_msg = exec_resp_pb2.Exec_Resp()
                        exec_resp_msg.type = exec_resp_pb2.Exec_Resp.STATE
                        mod = find_proc(exec_cmd_msg.name)
                        if mod != None:
                            proc = exec_resp_msg.processes.add()
                            proc.name = mod.name
                            if not mod.running and not mod.should_run:
                                proc.state = exec_resp_pb2.Exec_Resp.STOPPED
                            elif not mod.running and mod.should_run:
                                proc.state = exec_resp_pb2.Exec_Resp.RESTARTING
                            elif mod.running:
                                proc.state = exec_resp_pb2.Exec_Resp.RUNNING

                            unixIPC.sendTo("exec_resp_pb2", exec_resp_msg.SerializeToString(), client)
                 client_response_map[seq_no] = (client,time.time())
             elif ( cmd_msg.command == xbee_relay_cmd_pb2.XBee_Relay_Cmd.REGISTER_AS_RELAY ):
                 print "XBee Relay at ",client.ip," added"
                 relay_clients.append(client)
             else:
                 print "Unknown command code"
         elif typ=='xbee_relay_resp_pb2':
             resp_msg = xbee_relay_resp_pb2.XBee_Relay_Resp()
             resp_msg.ParseFromString(msg);
             if ( (resp_msg.seq_no,client) in message_tracking_map ):
                 xbee_addr = message_tracking_map.pop((resp_msg.seq_no,client))[0]
                 if ( resp_msg.code == xbee_relay_resp_pb2.XBee_Relay_Resp.SUCCESS ):
                     xbee_addr_to_relay_clients_map[xbee_addr] = client;
                     if resp_msg.seq_no in client_response_map:
                         if ( unixIPC.clientConnected(client_response_map[resp_msg.seq_no][0])):
                             unixIPC.sendTo('xbee_relay_resp_pb2',msg,client_response_map.pop(resp_msg.seq_no)[0])
                 elif ( resp_msg.code != xbee_relay_resp_pb2.XBee_Relay_Resp.SUCCESS and 
                        xbee_addr in xbee_addr_to_relay_clients_map and xbee_addr_to_relay_clients_map[xbee_addr] == client ):
                     xbee_addr_to_relay_clients_map.pop(xbee_addr)
                     
         else:
             print "Unknown command "+typ
 else:
     server.reconnect();
    
 # timeouts
 rmkeys = set()
 for (seq_no,val) in client_response_map.iteritems():
     if ( time.time() > val[1] + CACHE_TIMEOUT ):
         rmkeys.add(seq_no)
         
                        #print "FRIEENDS!! ",mod_name,key
                        config_resp_msg = config_resp_pb2.Config_Resp();
                        config_resp_msg.type = config_resp_pb2.Config_Resp.VAL;
                        config_resp_msg.mod_name = mod_name;
                        config_resp_msg.key = key;
                        
                        if ( not config.map.has_key(mod_name) or not config.map[mod_name].has_key(key) ):
                            config_resp_msg.error = "Key not found"
                        else:
                            config_resp_msg.error = "OK"
                            val =  config.map[mod_name][key];
                            if (type(val) is list):
                                val = "\n"+"\n".join(val);
                            config_resp_msg.val = val;
 
                        unixIPC.sendTo("config_resp_pb2",config_resp_msg.SerializeToString(),client);
                        
                    elif config_cmd_msg.cmd == config_cmd_pb2.Config_Cmd.SET_ALL:
                        mod_names = config_cmd_msg.mod_names;
                        keys = config_cmd_msg.keys;
                        vals = config_cmd_msg.vals;
                        
                        for midx in range(0,len(mod_names)):
                            if ( not config.map.has_key(mod_names[midx]) ):
                                config.map[mod_names[midx]] = config.IPCMap();
                                
                            val = vals[midx];
                            if(val[0] == '\n'):
                                val = val[1:].split('\n');
                            config.map[mod_names[midx]][keys[midx]] = val;