def device_program(self, devname, address, filename):
        if self.connected == False:
            return False
        if devname not in self.subscribed:
            print "error: device {0} not subscribed".format(devname)
            return False
        if address.startswith('0x') == False:
            print "error: wrong address input {0}, address should start with 0x".format(address)
            return False
        try:
            expandname = os.path.expanduser(filename)
        except:
            print "{0} does not exist".format(filename)
            return False
        if os.path.exists(expandname) == False:
            print "{0} does not exist".format(filename)
            return False
        if self.send_file_to_client(devname, expandname) == False:
            return False

        filehash = TBframe.hash_of_file(expandname)
        content = self.subscribed[devname] + ',' + address + ',' + filehash
        data = TBframe.construct(TBframe.DEVICE_PROGRAM, content);
        self.send_data(data)
        self.wait_cmd_excute_done(270)
        if self.cmd_excute_state == "done":
            ret = True
        else:
            ret = False
        self.cmd_excute_state = 'idle'
        return ret
Ejemplo n.º 2
0
 def send_file_to_someone(self, dst, filename):
     if os.path.exists(filename) == False:
         print "{0} does not exist\n".format(filename)
         return False
     print "sending {0} to {1} ...".format(filename, dst['addr']),
     file = open(filename, 'r')
     content = filename.split('/')[-1]
     data = TBframe.construct(TBframe.FILE_BEGIN, content)
     try:
         dst['socket'].send(data)
     except:
         print "failed"
         return False
     content = file.read(1024)
     while (content):
         data = TBframe.construct(TBframe.FILE_DATA, content)
         try:
             dst['socket'].send(data)
         except:
             print "failed"
             return False
         content = file.read(1024)
     file.close()
     content = filename.split('/')[-1]
     data = TBframe.construct(TBframe.FILE_END, content)
     try:
         dst['socket'].send(data)
     except:
         print "failed"
         return False
     print "succeed"
     return True
Ejemplo n.º 3
0
    def log_on_off(self, args):
        if len(args) < 2:
            self.cmdrun_status_display(
                "Usage error, usage: log on/off devices")
            return False

        if args[0] == "on":
            type = TBframe.LOG_SUB
        elif args[0] == "off":
            type = TBframe.LOG_UNSUB
        else:
            self.cmdrun_status_display(
                "Usage error, usage: log on/off devices")
            return False

        for dev in args[1:]:
            indexes = self.parse_device_index(dev)
            if not indexes:
                self.cmdrun_status_display(
                    'invalid device index {0}'.format(dev))
                continue
            for index in indexes:
                dev_str = self.get_devstr_by_index(index)
                if type == TBframe.LOG_SUB and dev_str not in self.log_subscribed:
                    data = TBframe.construct(type, dev_str)
                    self.send_data(data)
                    self.log_subscribed.append(dev_str)
                elif type == TBframe.LOG_UNSUB and dev_str in self.log_subscribed:
                    data = TBframe.construct(type, dev_str)
                    self.send_data(data)
                    self.log_subscribed.remove(dev_str)
Ejemplo n.º 4
0
    def server_interaction(self):
        msg = ''
        while self.keep_running:
            try:
                new_msg = self.service_socket.recv(MAX_MSG_LENTH)
                if new_msg == '':
                    print 'connection lost'
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = TBframe.parse(msg)
                    if type == TBframe.TYPE_NONE:
                        break

                    #print type, length
                    if type == TBframe.ALL_DEV:
                        new_list = {}
                        clients = value.split(':')
                        for c in clients:
                            if c == '':
                                continue
                            devs = c.split(',')
                            uuid = devs[0]
                            devs = devs[1:]
                            for d in devs:
                                if d == '':
                                    continue
                                [dev, using] = d.split('|')
                                new_list[uuid + ',' + dev] = using

                        old_list = list(self.device_list)
                        for dev in list(new_list):
                            if dev not in old_list:
                                data = TBframe.construct(
                                    TBframe.STATUS_SUB, dev)
                                self.service_socket.send(data)
                            self.device_list[dev] = new_list[dev]

                        for dev in list(self.device_list):
                            if dev in list(new_list):
                                continue
                            self.device_list.pop(dev)
                    if type == TBframe.DEVICE_STATUS:
                        print value
            except:
                if DEBUG:
                    raise
                break
        self.keep_running = False
        print 'server interaction thread exited'
    def device_run_cmd(self, devname, args, expect_lines = 0, timeout=0.8, filters=[""]):
        if self.connected == False:
            return False
        if devname not in self.subscribed:
            return False
        if len(args) == 0:
            return False
        content = self.subscribed[devname]
        content += ':' + '|'.join(args)
        data = TBframe.construct(TBframe.DEVICE_CMD, content)
        with self.filter_lock:
            self.filter['devname'] = devname
            self.filter['cmdstr'] = ' '.join(args)
            self.filter['lines_exp'] = expect_lines
            self.filter['lines_num'] = 0
            self.filter['filters'] = filters
            self.filter['response'] = []

        retry = 3
        while retry > 0:
            self.send_data(data)
            self.filter_event.clear()
            self.filter_event.wait(timeout)
            if self.filter['lines_num'] > 0:
                break;
            retry -= 1
        response = self.filter['response']
        with self.filter_lock:
            self.filter = {}
        return response
 def heartbeat_func(self):
     heartbeat_timeout = time.time() + 10
     while self.keep_running:
         time.sleep(0.05)
         if time.time() < heartbeat_timeout:
             continue
         self.send_data(TBframe.construct(TBframe.HEARTBEAT, ''))
         heartbeat_timeout += 10
Ejemplo n.º 7
0
 def send_device_list_to_all(self):
     devs = self.construct_dev_list()
     data = TBframe.construct(TBframe.ALL_DEV, devs)
     for t in self.terminal_list:
         try:
             t['socket'].send(data)
         except:
             continue
 def device_unsubscribe(self, devices):
     for devname in list(devices):
         if devname not in self.subscribed:
             continue
         data = TBframe.construct(TBframe.LOG_UNSUB, self.subscribed[devname])
         self.send_data(data)
         self.subscribed_reverse.pop(self.subscribed[devname])
         self.subscribed.pop(devname)
Ejemplo n.º 9
0
 def send_device_list(self):
     device_list = []
     for port in list(self.devices):
         if self.devices[port]['valid']:
             device_list.append(port)
     content = ':'.join(device_list)
     data = TBframe.construct(TBframe.CLIENT_DEV, content)
     try:
         self.service_socket.send(data)
     except:
         self.connected = False
Ejemplo n.º 10
0
 def heartbeat_func(self):
     heartbeat_timeout = time.time() + 10
     while self.keep_running:
         time.sleep(0.05)
         if time.time() < heartbeat_timeout:
             continue
         try:
             self.service_socket.send(TBframe.construct(TBframe.HEARTBEAT, ''))
         except:
             continue
         heartbeat_timeout += 10
Ejemplo n.º 11
0
    def device_log_poll(self, port, exit_condition):
        log_time = time.time()
        log = ''
        if LOCALLOG:
            logfile = 'client/' + port.split('/')[-1] + '.log'
            flog = open(logfile, 'a+')
        while os.path.exists(port) and exit_condition.is_set() == False:
            if self.connected == False or self.devices[port]['slock'].locked():
                time.sleep(0.01)
                continue

            newline = False
            while self.devices[port]['slock'].acquire(False) == True:
                try:
                    c = self.devices[port]['serial'].read(1)
                except:
                    c = ''
                finally:
                    self.devices[port]['slock'].release()

                if c == '':
                    break

                if log == '':
                    log_time = time.time()
                log += c
                if c == '\n':
                    newline = True
                    break

            if newline == True and log != '':
                if self.poll_str in log:
                    queue_safeput(self.devices[port]['plog_queue'], log)
                else:
                    self.device_log_filter(port, log)
                if LOCALLOG:
                    flog.write('{0:.3f}:'.format(log_time) + log)
                log = port + ':{0:.3f}:'.format(log_time) + log
                data = TBframe.construct(TBframe.DEVICE_LOG, log)
                log = ''
                try:
                    self.service_socket.send(data)
                except:
                    #self.connected = False
                    continue
        if LOCALLOG:
            flog.close()
        print 'device {0} removed'.format(port)
        self.devices[port]['valid'] = False
        exit_condition.set()
        self.devices[port]['serial'].close()
        self.send_device_list()
        print 'device log poll thread for {0} exited'.format(port)
Ejemplo n.º 12
0
 def heartbeat_func(self):
     heartbeat_timeout = time.time() + 10
     while self.keep_running:
         time.sleep(0.05)
         if time.time() >= heartbeat_timeout:
             try:
                 self.service_socket.send(
                     TBframe.construct(TBframe.HEARTBEAT, ''))
                 heartbeat_timeout += 10
             except:
                 continue
     print 'heart beat thread exited'
Ejemplo n.º 13
0
    def device_program(self, devname, address, filepath):
        """ program device with a firmware file

        arguments:
           devname : the device to be programmed
           address : start address write the firware(in hex format), example: '0x13200'
           filepath: firmware file path, only bin file is supported right now

        return: Ture - succeed; False - failed
        """
        if self.connected == False:
            return False
        if devname not in self.subscribed:
            print "error: device {0} not subscribed".format(devname)
            return False
        if address.startswith('0x') == False:
            print "error: wrong address input {0}, address should start with 0x".format(
                address)
            return False
        try:
            expandname = path.expanduser(filepath)
        except:
            print "{0} does not exist".format(filepath)
            return False
        if path.exists(expandname) == False:
            print "{0} does not exist".format(filepath)
            return False

        retry = 3
        while retry:
            if self.send_file_to_client(devname, expandname) == False:
                retry -= 1
                time.sleep(5)
            else:
                break
        if retry == 0:
            return False

        filehash = pkt.hash_of_file(expandname)
        content = self.subscribed[devname] + ',' + address + ',' + filehash
        self.send_packet(pkt.DEVICE_PROGRAM, content)
        elapsed_time = time.time()
        response = self.wait_cmd_response(pkt.DEVICE_PROGRAM, 270)
        if response == "success":
            ret = True
        else:
            ret = False
        elapsed_time = time.time() - elapsed_time
        print "Programming device {0} finished in {1:0.1f}S, result:{2}".format(
            devname, elapsed_time, ret == True and 'succeed' or 'failed')
        return ret
Ejemplo n.º 14
0
 def packet_send_thread(self):
     heartbeat_timeout = time.time() + 10
     while self.keep_running:
         try:
             [type, content] = self.output_queue.get(block=True,
                                                     timeout=0.1)
         except Queue.Empty:
             type = None
             pass
         if self.service_socket == None:
             continue
         if type == None:
             if time.time() < heartbeat_timeout:
                 continue
             heartbeat_timeout += 10
             data = pkt.construct(pkt.HEARTBEAT, '')
         else:
             data = pkt.construct(type, content)
         try:
             self.service_socket.send(data)
         except:
             self.connected = False
             continue
    def device_control(self, devname, operation):
        operations = {"start":TBframe.DEVICE_START, "stop":TBframe.DEVICE_STOP, "reset":TBframe.DEVICE_RESET}

        if self.connected == False:
            return False
        if devname not in self.subscribed:
            return False
        if operation not in list(operations):
            return False

        content = self.subscribed[devname]
        data = TBframe.construct(operations[operation], content)
        self.send_data(data)
        return True
 def device_erase(self, devname):
     if self.connected == False:
         return False
     if devname not in self.subscribed:
         print "error: device {0} not subscribed".format(devname)
         return False
     content = self.subscribed[devname]
     data = TBframe.construct(TBframe.DEVICE_ERASE, content);
     self.send_data(data)
     self.wait_cmd_excute_done(10)
     if self.cmd_excute_state == "done":
         ret = True
     else:
         ret = False
     self.cmd_excute_state = 'idle'
     return ret
 def device_subscribe(self, devices):
     if self.connected == False:
         return False
     for devname in list(devices):
         devstr = self.get_devstr_by_partialstr(devices[devname])
         if devstr == "":
             self.subscribed = {}
             self.subscribed_reverse = {}
             return False
         else:
             self.subscribed[devname] = devstr;
             self.subscribed_reverse[devstr] = devname
     for devname in devices:
         data = TBframe.construct(TBframe.LOG_SUB, self.subscribed[devname])
         self.send_data(data)
     return True
 def device_allocate(self, type, number, timeout, purpose='general'):
     if self.connected == False:
         return []
     content = ','.join([type, str(number), purpose])
     data = TBframe.construct(TBframe.DEVICE_ALLOC, content)
     timeout += time.time()
     while time.time() < timeout:
         self.send_data(data)
         self.wait_cmd_excute_done(0.8)
         if self.cmd_excute_return == None or self.cmd_excute_return == []:
             time.sleep(8)
             continue
         if len(self.cmd_excute_return) != number:
             print "error: allocated number does not equal requested"
         break
     if time.time() > timeout:
         self.cmd_excute_return = []
     return self.cmd_excute_return
Ejemplo n.º 19
0
    def control_devices(self, operate, args):
        if len(args) < 1:
            self.cmdrun_status_display("Usage error, usage: reset devices")
            return False

        operations = {
            "start": TBframe.DEVICE_START,
            "stop": TBframe.DEVICE_STOP,
            "reset": TBframe.DEVICE_RESET
        }
        operate = operations[operate]
        succeed = []
        failed = []
        for dev in args:
            indexes = self.parse_device_index(dev)
            if indexes == []:
                self.cmdrun_status_display(
                    'invalid device index {0}'.format(dev))
                return False

            for index in indexes:
                dev_str = self.get_devstr_by_index(index)
                data = TBframe.construct(operate, dev_str)
                self.send_data(data)
                self.wait_cmd_excute_done(1.5)
                if self.cmd_excute_state == "done":
                    succeed.append(index)
                else:
                    failed.append(index)
                self.cmd_excute_state = 'idle'
                if dev_str not in self.using_list:
                    self.using_list.append(dev_str)
        status_str = ''
        if succeed != []:
            status_str += "succeed: {0}".format(succeed)
        if failed != []:
            if status_str != '':
                status_str += ', '
            status_str += "failed: {0}".format(failed)
        self.cmdrun_status_display(status_str)
Ejemplo n.º 20
0
    def erase_devices(self, args):
        devs = args
        if devs == []:
            self.cmdrun_status_display(
                "Usage error: please specify devices you want to programg")
            return False
        succeed = []
        failed = []
        for dev in devs:
            indexes = self.parse_device_index(dev)
            if indexes == []:
                self.cmdrun_status_display(
                    'invalid device index {0}'.format(dev))
                continue

            for index in indexes:
                status_str = 'erasing {0}.{1}...'.format(
                    index, self.get_devstr_by_index(index))
                self.cmdrun_status_display(status_str)
                dev_str = self.get_devstr_by_index(index)
                data = TBframe.construct(TBframe.DEVICE_ERASE, dev_str)
                self.send_data(data)
                self.wait_cmd_excute_done(10)
                status_str += self.cmd_excute_state
                self.cmdrun_status_display(status_str)
                if self.cmd_excute_state == "done":
                    succeed.append(index)
                else:
                    failed.append(index)
                self.cmd_excute_state = 'idle'
                if dev_str not in self.using_list:
                    self.using_list.append(dev_str)
        status_str = ''
        if succeed != []:
            status_str += "succeed: {0}".format(succeed)
        if failed != []:
            if status_str != '':
                status_str += ', '
            status_str += "failed: {0}".format(failed)
        self.cmdrun_status_display(status_str)
Ejemplo n.º 21
0
    def log_download(self, args):
        if len(args) < 1:
            self.cmdrun_status_display(
                "Usage error, usage: logdownload device0 [device1 ... deviceN]"
            )
            return False

        succeed = []
        failed = []
        for dev in args:
            indexes = self.parse_device_index(dev)
            if indexes == []:
                self.cmdrun_status_display(
                    'invalid device index {0}'.format(dev))
                return False
            for index in indexes:
                device = self.get_devstr_by_index(index).split(',')
                status_str = 'downloading log file for {0}.{1}:{2}...'.format(
                    index, device[0], device[1].replace('/dev/', ''))
                self.cmdrun_status_display(status_str)
                content = ','.join(device)
                data = TBframe.construct(TBframe.LOG_DOWNLOAD, content)
                self.send_data(data)
                self.wait_cmd_excute_done(480)
                if self.cmd_excute_state == "done":
                    succeed.append(index)
                else:
                    failed.append(index)
                self.cmd_excute_state = 'idle'
        status_str = ''
        if succeed != []:
            status_str += "succeed: {0}".format(succeed)
        if failed != []:
            if status_str != '':
                status_str += ', '
            status_str += "failed: {0}".format(failed)
        self.cmdrun_status_display(status_str)
        return (len(failed) == 0)
Ejemplo n.º 22
0
    def client_serve_thread(self, conn, addr):
        file = {}
        msg = ''
        client = None
        self.conn_timeout[conn] = {
            'type': 'client',
            'addr': addr,
            'timeout': time.time() + 30
        }
        while self.keep_running:
            try:
                new_msg = conn.recv(MAX_MSG_LENTH)
                if new_msg == '':
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = TBframe.parse(msg)
                    if type == TBframe.TYPE_NONE:
                        break

                    self.conn_timeout[conn]['timeout'] = time.time() + 30
                    if client == None:
                        if type != TBframe.CLIENT_UUID:
                            data = TBframe.construct(
                                TBframe.CLIENT_UUID, 'give me your uuid first')
                            conn.send(data)
                            time.sleep(0.1)
                            continue
                        for c in self.client_list:
                            if c['uuid'] != value:
                                continue
                            client = c
                            break
                        if client == None:
                            client = {
                                'uuid': value,
                                'valid': True,
                                'socket': conn,
                                'addr': addr,
                                'devices': {}
                            }
                            self.client_list.append(client)
                            print "new client {0} connected @ {1}".format(
                                value, addr)
                        else:
                            client['socket'] = conn
                            client['addr'] = addr
                            client['valid'] = True
                            print "client {0} re-connected @ {1}".format(
                                value, addr)
                        continue

                    if type == TBframe.CLIENT_DEV:
                        new_devices = value.split(':')
                        for port in new_devices:
                            if port == "":
                                continue
                            if port in client['devices'] and client['devices'][
                                    port]['valid'] == True:
                                continue
                            if port not in client['devices']:
                                print "new device {0} added to client {1}".format(
                                    port, client['uuid'])
                                client['devices'][port] = {
                                    'lock': threading.Lock(),
                                    'valid': True,
                                    'using': 0,
                                    'status': '{}',
                                    'log_subscribe': [],
                                    'status_subscribe': []
                                }
                            else:
                                print "device {0} re-added to client {1}".format(
                                    port, client['uuid'])
                                client['devices'][port]['status'] = '{}'
                                client['devices'][port]['valid'] = True

                        for port in list(client['devices']):
                            if port in new_devices:
                                continue
                            if client['devices'][port]['valid'] == False:
                                continue
                            client['devices'][port]['status'] = '{}'
                            client['devices'][port]['valid'] = False
                            print "device {0} removed from client {1}".format(
                                port, client['uuid'])

                        for port in list(file):
                            if client['devices'][port]['valid'] == True:
                                continue
                            file[port]['handle'].close()
                            file.pop(port)
                        self.send_device_list_to_all()
                    elif type == TBframe.DEVICE_LOG:
                        port = value.split(':')[0]
                        if port not in client['devices']:
                            continue
                        #forwad log to subscribed devices
                        if client['devices'][port]['log_subscribe'] != [] and \
                           ('tag' not in client or client['tag'] not in value):
                            log = client['uuid'] + ',' + value
                            data = TBframe.construct(type, log)
                            for s in client['devices'][port]['log_subscribe']:
                                try:
                                    s.send(data)
                                except:
                                    continue

                        #save log to files
                        try:
                            logtime = value.split(':')[1]
                            logstr = value[len(port) + 1 + len(logtime):]
                            logtime = float(logtime)
                            logtimestr = time.strftime("%Y-%m-%d@%H:%M:%S",
                                                       time.localtime(logtime))
                            logtimestr += ("{0:.3f}".format(logtime -
                                                            int(logtime)))[1:]
                            logstr = logtimestr + logstr
                            logdatestr = time.strftime("%Y-%m-%d",
                                                       time.localtime(logtime))
                        except:
                            if DEBUG: traceback.print_exc()
                            continue
                        if (port not in file) or (file[port]['date'] !=
                                                  logdatestr):
                            if port in file:
                                file[port]['handle'].close()
                                file.pop(port)
                            log_dir = 'server/' + logdatestr
                            if os.path.isdir(log_dir) == False:
                                try:
                                    os.mkdir(log_dir)
                                except:
                                    print "error: can not create directory {0}".format(
                                        log_dir)
                            filename = log_dir + '/' + client[
                                'uuid'] + '-' + port.split('/')[-1] + '.log'
                            try:
                                handle = open(filename, 'a+')
                                file[port] = {
                                    'handle': handle,
                                    'date': logdatestr
                                }
                            except:
                                print "error: can not open/create file ", filename
                        if port in file and file[port]['date'] == logdatestr:
                            file[port]['handle'].write(logstr)
                    elif type == TBframe.DEVICE_STATUS:
                        #print value
                        port = value.split(':')[0]
                        if port not in client['devices']:
                            continue
                        client['devices'][port]['status'] = value[len(port) +
                                                                  1:]
                        if client['devices'][port]['status_subscribe'] != []:
                            log = client['uuid'] + ',' + port
                            log += value[len(port):]
                            data = TBframe.construct(type, log)
                            for s in client['devices'][port][
                                    'status_subscribe']:
                                try:
                                    s.send(data)
                                except:
                                    continue
                    elif type == TBframe.DEVICE_ERASE or type == TBframe.DEVICE_PROGRAM or \
                         type == TBframe.DEVICE_START or type == TBframe.DEVICE_STOP or \
                         type == TBframe.DEVICE_RESET or type == TBframe.DEVICE_CMD or \
                         type == TBframe.FILE_BEGIN or type == TBframe.FILE_DATA or \
                         type == TBframe.FILE_END:
                        values = value.split(',')
                        addr = (values[0], int(values[1]))
                        terminal = None
                        for t in self.terminal_list:
                            if t['addr'] == addr:
                                terminal = t
                        if terminal != None:
                            if values[2] != 'success' and values[2] != 'ok':
                                data = TBframe.construct(
                                    TBframe.CMD_ERROR, ','.join(values[2:]))
                            else:
                                data = TBframe.construct(
                                    TBframe.CMD_DONE, ','.join(values[2:]))
                            terminal['socket'].send(data)
                    elif type == TBframe.CLIENT_TAG:
                        client['tag'] = value
                        print 'client {0} tag: {1}'.format(
                            client['uuid'], repr(value))
            except:
                if DEBUG: traceback.print_exc()
                break
        conn.close()
        self.conn_timeout.pop(conn)
        if client:
            for port in client['devices']:
                if client['devices'][port]['valid'] == False:
                    continue
                client['devices'][port]['status'] = '{}'
                client['devices'][port]['valid'] = False
                print "device {0} removed from client {1}".format(
                    port, client['uuid'])
            client['valid'] = False
            print "client {0} @ {1} disconnected".format(client['uuid'], addr)
            self.send_device_list_to_all()
        else:
            print "client @ {0} disconnected".format(addr)
Ejemplo n.º 23
0
 def send_device_list_to_terminal(self, terminal):
     devs = self.construct_dev_list()
     data = TBframe.construct(TBframe.ALL_DEV, devs)
     terminal['socket'].send(data)
Ejemplo n.º 24
0
    def client_func(self, server_ip, server_port):
        self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.service_socket.connect((server_ip, server_port))
            self.connected = True
            print 'connect to server {0}:{1} succeeded'.format(
                server_ip, server_port)
        except:
            print 'connect to server {0}:{1} failed'.format(
                server_ip, server_port)
            return

        if os.path.exists('client') == False:
            os.mkdir('client')
        if os.path.exists('client/.uuid') == True:
            try:
                file = open('client/.uuid', 'rb')
                self.uuid = json.load(file)
                file.close()
            except:
                print "read uuid from file failed"
        if not self.uuid:
            bytes = os.urandom(6)
            self.uuid = ''
            for byte in bytes:
                self.uuid += '{0:02x}'.format(ord(byte))
            try:
                file = open('client/.uuid', 'w')
                file.write(json.dumps(self.uuid))
                file.close()
            except:
                print "save uuid to file failed"
        signal.signal(signal.SIGINT, signal_handler)

        self.send_packet(TBframe.CLIENT_UUID, self.uuid)
        self.send_packet(TBframe.CLIENT_TAG, self.poll_str)
        thread.start_new_thread(self.device_monitor, ())
        thread.start_new_thread(self.heartbeat_func, ())

        file_received = {}
        file_receiving = {}
        msg = ''
        while True:
            try:
                new_msg = self.service_socket.recv(MAX_MSG_LENTH)
                if new_msg == '':
                    raise ConnectionLost
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = TBframe.parse(msg)
                    if type == TBframe.TYPE_NONE:
                        break

                    for hash in list(file_receiving):
                        if time.time() > file_receiving[hash]['timeout']:
                            file_receiving[hash]['handle'].close()
                            try:
                                os.remove(file_receiving[hash]['name'])
                            except:
                                pass
                            file_receiving.pop(hash)

                    if type == TBframe.FILE_BEGIN:
                        split_value = value.split(':')
                        terminal = split_value[0]
                        hash = split_value[1]
                        filename = split_value[2]
                        if hash in file_received:
                            if os.path.exists(file_received[hash]) == True:
                                content = terminal + ',' + 'exist'
                                self.send_packet(type, content)
                                continue
                            else:
                                file_received.pop(hash)

                        if hash in file_receiving:
                            content = terminal + ',' + 'busy'
                            self.send_packet(type, content)
                            continue

                        filename = 'client/' + filename
                        filename += '-' + terminal.split(',')[0]
                        filename += '@' + time.strftime('%Y-%m-%d-%H-%M')
                        filehandle = open(filename, 'wb')
                        timeout = time.time() + 5
                        file_receiving[hash] = {
                            'name': filename,
                            'seq': 0,
                            'handle': filehandle,
                            'timeout': timeout
                        }
                        content = terminal + ',' + 'ok'
                        self.send_packet(type, content)
                        if DEBUG:
                            print 'start receiving {0} as {1}'.format(
                                split_value[2], filename)
                    elif type == TBframe.FILE_DATA:
                        split_value = value.split(':')
                        terminal = split_value[0]
                        hash = split_value[1]
                        seq = split_value[2]
                        data = value[(len(terminal) + len(hash) + len(seq) +
                                      3):]
                        seq = int(seq)
                        if hash not in file_receiving:
                            content = terminal + ',' + 'noexist'
                            self.send_packet(type, content)
                            continue
                        if file_receiving[hash][
                                'seq'] != seq and file_receiving[hash][
                                    'seq'] != seq + 1:
                            content = terminal + ',' + 'seqerror'
                            self.send_packet(type, content)
                            continue
                        if file_receiving[hash]['seq'] == seq:
                            file_receiving[hash]['handle'].write(data)
                            file_receiving[hash]['seq'] += 1
                            file_receiving[hash]['timeout'] = time.time() + 5
                        content = terminal + ',' + 'ok'
                        self.send_packet(type, content)
                    elif type == TBframe.FILE_END:
                        split_value = value.split(':')
                        terminal = split_value[0]
                        hash = split_value[1]
                        if hash not in file_receiving:
                            content = terminal + ',' + 'noexist'
                            self.send_packet(type, content)
                            continue
                        file_receiving[hash]['handle'].close()
                        localhash = TBframe.hash_of_file(
                            file_receiving[hash]['name'])
                        if localhash != hash:
                            response = 'hasherror'
                        else:
                            response = 'ok'
                            file_received[hash] = file_receiving[hash]['name']
                        if DEBUG:
                            print 'finished receiving {0}, result:{1}'.format(
                                file_receiving[hash]['name'], response)
                        file_receiving.pop(hash)
                        content = terminal + ',' + response
                        self.send_packet(type, content)
                    elif type == TBframe.DEVICE_ERASE:
                        args = value.split(',')
                        if len(args) != 3:
                            continue
                        term = args[0:2]
                        port = args[2]
                        if os.path.exists(port) and port in self.devices:
                            if self.devices[port]['queue'].full() == False:
                                self.devices[port]['queue'].put([type, term])
                                continue
                            else:
                                result = 'busy'
                                print 'erase', port, 'failed, device busy'
                        else:
                            result = 'nonexist'
                            print 'erase', port, 'failed, device nonexist'
                        content = ','.join(term) + ',' + result
                        self.send_packet(type, content)
                    elif type == TBframe.DEVICE_PROGRAM:
                        args = value.split(',')
                        if len(args) != 5:
                            continue
                        term = args[0:2]
                        port = args[2]
                        address = args[3]
                        hash = args[4]
                        if hash not in file_received:
                            content = ','.join(term) + ',' + 'error'
                            self.send_packet(type, content)
                            continue
                        filename = file_received[hash]
                        if os.path.exists(port) and port in self.devices:
                            if self.devices[port]['queue'].full() == False:
                                self.devices[port]['queue'].put(
                                    [type, term, address, filename])
                                continue
                            else:
                                result = 'busy'
                                print 'program {0} to {1} @ {2} failed, device busy'.format(
                                    filename, port, address)
                        else:
                            result = 'error'
                            print 'program {0} to {1} @ {2} failed, device nonexist'.format(
                                filename, port, address)
                        content = ','.join(term) + ',' + result
                        self.send_packet(type, content)
                    elif type == TBframe.DEVICE_RESET or type == TBframe.DEVICE_START or type == TBframe.DEVICE_STOP:
                        operations = {
                            TBframe.DEVICE_RESET: 'reset',
                            TBframe.DEVICE_START: 'start',
                            TBframe.DEVICE_STOP: 'stop'
                        }
                        args = value.split(',')
                        if len(args) != 3:
                            continue
                        term = args[0:2]
                        port = args[2]
                        if os.path.exists(port) and port in self.devices:
                            if self.devices[port]['queue'].full() == False:
                                self.devices[port]['queue'].put([type, term])
                                continue
                            else:
                                result = 'busy'
                                print operations[
                                    type], port, 'failed, device busy'
                        else:
                            result = 'nonexist'
                            print operations[
                                type], port, 'failed, device nonexist'
                        content = ','.join(term) + ',' + result
                        self.send_packet(type, content)
                    elif type == TBframe.DEVICE_CMD:
                        args = value.split(':')[0]
                        arglen = len(args) + 1
                        args = args.split(',')
                        term = args[0:2]
                        port = args[2]
                        cmd = value[arglen:].split('|')
                        cmd = ' '.join(cmd)
                        if os.path.exists(port) and port in self.devices and \
                            self.devices[port]['valid'] == True:
                            if self.devices[port]['queue'].full() == False:
                                self.devices[port]['queue'].put(
                                    [type, term, cmd])
                                continue
                            else:
                                result = 'busy'
                                print "run command '{0}' at {1} failed, device busy".format(
                                    cmd, port)
                        else:
                            result = 'nonexist'
                            print "run command '{0}' at {1} failed, device nonexist".format(
                                cmd, port)
                        content = ','.join(term) + ',' + result
                        self.send_packet(type, content)
                    elif type == TBframe.CLIENT_UUID:
                        print 'server request UUID'
                        self.send_packet(TBframe.CLIENT_UUID, self.uuid)
                        self.send_packet(TBframe.CLIENT_TAG, self.poll_str)
                        self.send_device_list()
            except ConnectionLost:
                self.connected = False
                print 'connection to server lost, try reconnecting...'
                self.service_socket.close()
                self.service_socket = socket.socket(socket.AF_INET,
                                                    socket.SOCK_STREAM)
                while True:
                    try:
                        self.service_socket.connect((server_ip, server_port))
                        time.sleep(0.1)
                        self.connected = True
                        self.send_packet(TBframe.CLIENT_UUID, self.uuid)
                        self.send_packet(TBframe.CLIENT_TAG, self.poll_str)
                        self.send_device_list()
                        break
                    except:
                        try:
                            time.sleep(1)
                        except:
                            self.service_socket.close()
                            return
                print 'connection to server resumed'
            except KeyboardInterrupt:
                print "client exiting ..."
                self.keep_running = False
                time.sleep(0.3)
                break
            except:
                if DEBUG: traceback.print_exc()
        self.service_socket.close()
Ejemplo n.º 25
0
    def terminal_serve_thread(self, conn, addr):
        terminal = {'socket': conn, 'addr': addr}
        self.terminal_list.append(terminal)
        using_list = []
        msg = ''
        self.conn_timeout[conn] = {
            'type': 'terminal',
            'addr': addr,
            'timeout': time.time() + 30
        }
        self.send_device_list_to_terminal(terminal)
        while self.keep_running:
            try:
                new_msg = terminal['socket'].recv(MAX_MSG_LENTH)
                if new_msg == '':
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = TBframe.parse(msg)
                    if type == TBframe.TYPE_NONE:
                        break

                    self.conn_timeout[conn]['timeout'] = time.time() + 30
                    if type == TBframe.FILE_BEGIN or type == TBframe.FILE_DATA or type == TBframe.FILE_END:
                        dev_str = value.split(':')[0]
                        uuid = dev_str.split(',')[0]
                        target_data = value[len(dev_str):]
                        client = self.get_client_by_uuid(uuid)
                        if client == None:
                            data = TBframe.construct(TBframe.CMD_ERROR,
                                                     'nonexist')
                            terminal['socket'].send(data)
                            continue
                        content = terminal['addr'][0] + ',' + str(
                            terminal['addr'][1])
                        content += target_data
                        data = TBframe.construct(type, content)
                        client['socket'].send(data)
                    elif type == TBframe.DEVICE_ERASE or type == TBframe.DEVICE_PROGRAM or \
                         type == TBframe.DEVICE_START or type == TBframe.DEVICE_STOP or \
                         type == TBframe.DEVICE_RESET or type == TBframe.DEVICE_CMD:
                        dev_str_split = value.split(':')[0].split(',')[0:2]
                        if len(dev_str_split) != 2:
                            data = TBframe.construct(TBframe.CMD_ERROR,
                                                     'argerror')
                            terminal['socket'].send(data)
                            continue
                        [uuid, port] = dev_str_split
                        client = self.get_client_by_uuid(uuid)
                        if client == None:
                            data = TBframe.construct(TBframe.CMD_ERROR,
                                                     'nonexist')
                            terminal['socket'].send(data)
                            continue
                        content = terminal['addr'][0]
                        content += ',' + str(terminal['addr'][1])
                        content += value[len(uuid):]
                        data = TBframe.construct(type, content)
                        client['socket'].send(data)
                        self.increase_device_refer(client, port, using_list)
                    elif type == TBframe.DEVICE_ALLOC:
                        result = self.allocate_devices(value)
                        content = ','.join(result)
                        data = TBframe.construct(TBframe.DEVICE_ALLOC, content)
                        terminal['socket'].send(data)
                    elif type == TBframe.LOG_SUB or type == TBframe.LOG_UNSUB or \
                         type == TBframe.STATUS_SUB or type == TBframe.STATUS_UNSUB:
                        dev_str_split = value.split(',')
                        if len(dev_str_split) != 2:
                            continue
                        [uuid, port] = dev_str_split
                        client = self.get_client_by_uuid(uuid)
                        if client == None:
                            continue
                        if port not in list(client['devices']):
                            continue
                        if type == TBframe.LOG_SUB:
                            if terminal['socket'] in client['devices'][port][
                                    'log_subscribe']:
                                continue
                            client['devices'][port]['log_subscribe'].append(
                                terminal['socket'])
                            print "terminal {0}:{1}".format(
                                terminal['addr'][0], terminal['addr'][1]),
                            print "subscribed log of device {0}:{1}".format(
                                uuid, port)
                        elif type == TBframe.LOG_UNSUB:
                            if terminal['socket'] not in client['devices'][
                                    port]['log_subscribe']:
                                continue
                            client['devices'][port]['log_subscribe'].remove(
                                terminal['socket'])
                            print "terminal {0}:{1}".format(
                                terminal['addr'][0], terminal['addr'][1]),
                            print "unsubscribed log of device {0}:{1}".format(
                                uuid, port)
                        elif type == TBframe.STATUS_SUB:
                            if terminal['socket'] in client['devices'][port][
                                    'status_subscribe']:
                                continue
                            client['devices'][port]['status_subscribe'].append(
                                terminal['socket'])
                            print "terminal {0}:{1}".format(
                                terminal['addr'][0], terminal['addr'][1]),
                            print "subscribed status of device {0}:{1}".format(
                                uuid, port)
                            content = client['uuid'] + ',' + port
                            content += ':' + client['devices'][port]['status']
                            data = TBframe.construct(TBframe.DEVICE_STATUS,
                                                     content)
                            terminal['socket'].send(data)
                        elif type == TBframe.STATUS_UNSUB:
                            if terminal['socket'] not in client['devices'][
                                    port]['status_subscribe']:
                                continue
                            client['devices'][port]['status_subscribe'].remove(
                                terminal['socket'])
                            print "terminal {0}:{1}".format(
                                terminal['addr'][0], terminal['addr'][1]),
                            print "unsubscribed status of device {0}:{1}".format(
                                uuid, port)
                    elif type == TBframe.LOG_DOWNLOAD:
                        dev_str_split = value.split(',')
                        if len(dev_str_split) != 2:
                            continue
                        [uuid, port] = dev_str_split
                        datestr = time.strftime('%Y-%m-%d')
                        filename = 'server/' + datestr + '/' + uuid + '-' + port.split(
                            '/')[-1] + '.log'
                        client = self.get_client_by_uuid(uuid)
                        if client == None or port not in list(
                                client['devices']) or os.path.exists(
                                    filename) == False:
                            data = TBframe.construct(TBframe.CMD_ERROR, 'fail')
                            terminal['socket'].send(data)
                            print "terminal {0}:{1}".format(
                                terminal['addr'][0], terminal['addr'][1]),
                            print "downloading log of device {0}:{1} ... failed".format(
                                uuid, port)
                            continue
                        self.send_file_to_someone(terminal, filename)
                        heartbeat_timeout = time.time() + 30
                        data = TBframe.construct(TBframe.CMD_DONE, 'success')
                        terminal['socket'].send(data)
                        print "terminal {0}:{1}".format(
                            terminal['addr'][0], terminal['addr'][1]),
                        print "downloading log of device {0}:{1} ... succeed".format(
                            uuid, port)
            except:
                if DEBUG: traceback.print_exc()
                break
        for client in self.client_list:
            for port in list(client['devices']):
                if terminal['socket'] in client['devices'][port][
                        'log_subscribe']:
                    client['devices'][port]['log_subscribe'].remove(
                        terminal['socket'])
                if terminal['socket'] in client['devices'][port][
                        'status_subscribe']:
                    client['devices'][port]['status_subscribe'].remove(
                        terminal['socket'])
        for device in using_list:
            uuid = device[0]
            port = device[1]
            client = None
            for c in self.client_list:
                if c['uuid'] != uuid:
                    continue
                client = c
                break
            if client != None and port in list(client['devices']):
                with client['devices'][port]['lock']:
                    if client['devices'][port]['using'] > 0:
                        client['devices'][port]['using'] -= 1
        terminal['socket'].close()
        self.conn_timeout.pop(conn)
        print "terminal ", terminal['addr'], "disconnected"
        self.terminal_list.remove(terminal)
        self.send_device_list_to_all()
Ejemplo n.º 26
0
    def device_cmd_process(self, port, exit_condition):
        poll_fail_num = 0
        poll_queue = Queue.Queue(12)
        if self.devices[port]['attributes'] != {}:
            content = port + ':' + json.dumps(self.devices[port]['attributes'],
                                              sort_keys=True)
            data = TBframe.construct(TBframe.DEVICE_STATUS, content)
            self.service_socket.send(data)
        poll_timeout = time.time() + 5 + random.uniform(
            0, self.poll_interval / 3)
        while os.path.exists(port) and exit_condition.is_set() == False:
            try:
                if time.time() >= poll_timeout:
                    poll_timeout += self.poll_interval
                    poll_queue.put(['devname', 1, 0.2])
                    poll_queue.put(['mac', 1, 0.2])
                    poll_queue.put(['version', 2, 0.2])
                    poll_queue.put(['uuid', 1, 0.2])
                    poll_queue.put(['umesh status', 11, 0.2])
                    poll_queue.put(['umesh extnetid', 1, 0.2])
                    poll_queue.put(['umesh nbrs', 33, 0.3])

                block = True
                timeout = 0
                try:
                    args = None
                    if self.devices[port]['queue'].empty(
                    ) == True and poll_queue.empty() == True:
                        args = self.devices[port]['queue'].get(block=True,
                                                               timeout=0.1)
                    elif self.devices[port]['queue'].empty() == False:
                        args = self.devices[port]['queue'].get()
                except Queue.Empty:
                    args = None
                    continue
                except:
                    if DEBUG: traceback.print_exc()
                    args = None
                    continue

                if args != None:
                    type = args[0]
                    term = args[1]
                    if type == TBframe.DEVICE_ERASE:
                        self.device_erase(port, term)
                    elif type == TBframe.DEVICE_PROGRAM:
                        address = args[2]
                        filename = args[3]
                        self.device_program(port, address, filename, term)
                    elif type == TBframe.DEVICE_RESET or type == TBframe.DEVICE_START or type == TBframe.DEVICE_STOP:
                        self.device_control(port, type, term)
                    elif type == TBframe.DEVICE_CMD:
                        cmd = args[2]
                        self.device_run_cmd(port, cmd, term)
                    else:
                        print "error: unknown operation tyep {0}".format(
                            repr(type))
                    args = None
                    time.sleep(0.05)
                    continue

                if poll_queue.empty() == True:
                    continue

                [cmd, lines, timeout] = poll_queue.get()
                response = self.run_poll_command(port, cmd, lines, timeout)

                if cmd == 'devname':  #poll device model
                    if len(response) == lines and response[0].startswith(
                            'device name:'):
                        poll_fail_num = 0
                        self.devices[port]['attributes']['model'] = response[
                            0].split()[-1]
                    else:
                        poll_fail_num += 1
                elif cmd == 'mac':  #poll device mac
                    if len(response) == 1 and response[0].startswith(
                            'MAC address:'):
                        poll_fail_num = 0
                        macaddr = response[0].split()[-1]
                        macaddr = macaddr.replace('-', '') + '0000'
                        self.devices[port]['attributes']['macaddr'] = macaddr
                    else:
                        poll_fail_num += 1
                elif cmd == 'version':  #poll device version
                    if len(response) == lines:
                        poll_fail_num = 0
                        for line in response:
                            if 'kernel version :' in line:
                                self.devices[port]['attributes'][
                                    'kernel_version'] = line.replace(
                                        'kernel version :AOS-', '')
                            if 'app version :' in line:
                                line = line.replace('app version :', '')
                                line = line.replace('app-', '')
                                line = line.replace('APP-', '')
                                self.devices[port]['attributes'][
                                    'app_version'] = line
                    else:
                        poll_fail_num += 1
                elif cmd == 'umesh status':  #poll mesh status
                    if len(response) == lines:
                        poll_fail_num = 0
                        for line in response:
                            if 'state\t' in line:
                                self.devices[port]['attributes'][
                                    'state'] = line.replace('state\t', '')
                            elif '\tnetid\t' in line:
                                self.devices[port]['attributes'][
                                    'netid'] = line.replace('\tnetid\t', '')
                            elif '\tsid\t' in line:
                                self.devices[port]['attributes'][
                                    'sid'] = line.replace('\tsid\t', '')
                            elif '\tnetsize\t' in line:
                                self.devices[port]['attributes'][
                                    'netsize'] = line.replace(
                                        '\tnetsize\t', '')
                            elif '\trouter\t' in line:
                                self.devices[port]['attributes'][
                                    'router'] = line.replace('\trouter\t', '')
                            elif '\tchannel\t' in line:
                                self.devices[port]['attributes'][
                                    'channel'] = line.replace(
                                        '\tchannel\t', '')
                    else:
                        poll_fail_num += 1
                elif cmd == 'umesh nbrs':  #poll mesh nbrs
                    if len(response) > 0 and 'num=' in response[-1]:
                        poll_fail_num = 0
                        nbrs = {}
                        for line in response:
                            if '\t' not in line or ',' not in line:
                                continue
                            line = line.replace('\t', '')
                            nbr_info = line.split(',')
                            if len(nbr_info) < 10:
                                continue
                            nbrs[nbr_info[0]] = {'relation':nbr_info[1], \
                                                 'netid':nbr_info[2], \
                                                 'sid':nbr_info[3], \
                                                 'link_cost':nbr_info[4], \
                                                 'child_num':nbr_info[5], \
                                                 'channel':nbr_info[6], \
                                                 'reverse_rssi':nbr_info[7], \
                                                 'forward_rssi':nbr_info[8], \
                                                 'last_heard':nbr_info[9]}
                            if len(nbr_info) > 10:
                                nbrs[nbr_info[0]]['awake'] = nbr_info[10]
                        self.devices[port]['attributes']['nbrs'] = nbrs
                    else:
                        poll_fail_num += 1
                elif cmd == 'umesh extnetid':  #poll mesh extnetid
                    if len(response) == 1 and response[0].count(':') == 5:
                        poll_fail_num += 1
                        self.devices[port]['attributes'][
                            'extnetid'] = response[0]
                    else:
                        poll_fail_num += 1
                elif cmd == 'uuid':  #poll uuid
                    if len(response) == 1 and 'uuid:' in response[0]:
                        poll_fail_num = 0
                        self.devices[port]['attributes']['uuid'] = response[
                            0].replace('uuid: ', '')
                    else:
                        poll_fail_num += 1
                else:
                    print "error: unrecognized poll cmd '{0}'".format(cmd)
                    continue

                if poll_fail_num >= 7:
                    if self.devices[port]['attributes']['status'] == 'active':
                        print "device {0} become inactive".format(port)
                    self.devices[port]['attributes']['status'] = 'inactive'
                else:
                    if self.devices[port]['attributes'][
                            'status'] == 'inactive':
                        print "device {0} become active".format(port)
                    self.devices[port]['attributes']['status'] = 'active'

                if poll_queue.empty() == False:
                    continue
                content = port + ':' + json.dumps(
                    self.devices[port]['attributes'], sort_keys=True)
                data = TBframe.construct(TBframe.DEVICE_STATUS, content)
                try:
                    self.service_socket.send(data)
                except:
                    self.connected = False
                    continue
            except:
                if os.path.exists(port) == False:
                    exit_condition.set()
                    break
                if exit_condition.is_set() == True:
                    break
                if DEBUG: traceback.print_exc()
                self.devices[port]['serial'].close()
                self.devices[port]['serial'].open()
        print 'devie command process thread for {0} exited'.format(port)
    def send_file_to_client(self, devname, filename):
        #argument check
        if devname not in self.subscribed:
            print "{0} is not subscribed".format(devname)
            return False
        try:
            expandfilename = os.path.expanduser(filename)
        except:
            print "{0} does not exist".format(filename)
            return False
        if os.path.exists(expandfilename) == False:
            print "{0} does not exist".format(filename)
            return False
        filename = expandfilename

        filehash = TBframe.hash_of_file(filename)
        devstr = self.subscribed[devname]

        #send file begin
        content = devstr  + ':' + filehash + ':' + filename.split('/')[-1]
        data = TBframe.construct(TBframe.FILE_BEGIN, content)
        retry = 4
        while retry > 0:
            self.send_data(data)
            self.wait_cmd_excute_done(0.2)
            if self.cmd_excute_state == 'timeout':
                retry -= 1;
                continue
            if self.cmd_excute_return == 'busy':
                print "file transfer busy: wait..."
                time.sleep(5)
                continue
            elif self.cmd_excute_return == 'ok' or self.cmd_excute_return == 'exist':
                break
            else:
                print "file transfer error: unexpected response '{0}'".format(self.cmd_excute_return)
                return False
        if retry == 0:
            print 'file transfer error: retry timeout'
            return False
        if self.cmd_excute_return == 'exist':
            return True

        #send file data
        seq = 0
        file = open(filename,'r')
        header = devstr  + ':' + filehash + ':' + str(seq) + ':'
        content = file.read(1024)
        while(content):
            data = TBframe.construct(TBframe.FILE_DATA, header + content)
            retry = 4
            while retry > 0:
                self.send_data(data)
                self.wait_cmd_excute_done(0.2)
                if self.cmd_excute_return == None:
                    retry -= 1;
                    continue
                elif self.cmd_excute_return != 'ok':
                    file.close()
                    return False
                break

            if retry == 0:
                file.close()
                return False

            seq += 1
            header = devstr  + ':' + filehash + ':' + str(seq) + ':'
            content = file.read(1024)
        file.close()

        #send file end
        content = devstr  + ':' + filehash + ':' + filename.split('/')[-1]
        data = TBframe.construct(TBframe.FILE_END, content)
        retry = 4
        while retry > 0:
            self.send_data(data)
            self.wait_cmd_excute_done(0.2)
            if self.cmd_excute_return == None:
                retry -= 1;
                continue
            elif self.cmd_excute_return != 'ok':
                return False
            break
        if retry == 0:
            return False
        return True
Ejemplo n.º 28
0
    def send_file_to_client(self, devname, filepath):
        #argument check
        if devname not in self.subscribed:
            print "{0} is not subscribed".format(devname)
            return False
        try:
            expandfilepath = path.expanduser(filepath)
        except:
            print "{0} does not exist".format(filepath)
            return False
        if path.exists(expandfilepath) == False:
            print "{0} does not exist".format(filepath)
            return False
        filepath = expandfilepath

        filehash = pkt.hash_of_file(filepath)
        devstr = self.subscribed[devname]

        #send file begin
        content = devstr + ':' + filehash + ':' + path.basename(filepath)
        retry = 4
        while retry > 0:
            self.send_packet(pkt.FILE_BEGIN, content)
            response = self.wait_cmd_response(pkt.FILE_BEGIN, 0.6)
            if response == None:  #timeout
                retry -= 1
                continue
            if response == 'busy':
                print "file transfer busy: wait..."
                time.sleep(5)
                continue
            elif response == 'ok' or response == 'exist':
                break
            else:
                print "file transfer error: unexpected response '{0}'".format(
                    response)
                return False
        if retry == 0:
            print 'file transfer error: retry timeout'
            return False
        if response == 'exist':
            return True

        #send file data
        seq = 0
        file = open(filepath, 'r')
        header = devstr + ':' + filehash + ':' + str(seq) + ':'
        content = file.read(1024)
        while (content):
            retry = 4
            while retry > 0:
                self.send_packet(pkt.FILE_DATA, header + content)
                response = self.wait_cmd_response(pkt.FILE_DATA, 0.6)
                if response == None:  #timeout
                    retry -= 1
                    continue
                elif response != 'ok':
                    print('send data fragement {0} failed, error: {1}'.format(
                        header, response))
                    file.close()
                    return False
                break

            if retry == 0:
                file.close()
                return False

            seq += 1
            header = devstr + ':' + filehash + ':' + str(seq) + ':'
            content = file.read(1024)
        file.close()

        #send file end
        content = devstr + ':' + filehash + ':' + path.basename(filepath)
        retry = 4
        while retry > 0:
            self.send_packet(pkt.FILE_END, content)
            response = self.wait_cmd_response(pkt.FILE_END, 0.6)
            if response == None:  #timeout
                retry -= 1
                continue
            elif response != 'ok':
                print('send file failed, error: {0}'.format(response))
                return False
            break
        if retry == 0:
            return False
        return True
Ejemplo n.º 29
0
    def server_interaction(self):
        msg = ''
        while self.keep_running:
            try:
                if self.connected == False:
                    raise ConnectionLost

                new_msg = self.service_socket.recv(MAX_MSG_LENGTH)
                if new_msg == '':
                    raise ConnectionLost
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = pkt.parse(msg)
                    if type == pkt.TYPE_NONE:
                        break

                    #print type, length
                    if type == pkt.ALL_DEV:
                        new_list = {}
                        clients = value.split(':')
                        for c in clients:
                            if c == '':
                                continue
                            devs = c.split(',')
                            uuid = devs[0]
                            devs = devs[1:]
                            for d in devs:
                                if d == '':
                                    continue
                                [dev, using] = d.split('|')
                                new_list[uuid + ',' + dev] = using

                        for dev in list(new_list):
                            self.device_list[dev] = new_list[dev]
                        continue
                    if type == pkt.DEVICE_LOG:
                        dev = value.split(':')[0]
                        logtime = value.split(':')[1]
                        log = value[len(dev) + 1 + len(logtime) + 1:]
                        try:
                            logtime = float(logtime)
                            logtimestr = time.strftime("%Y-%m-%d %H-%M-%S",
                                                       time.localtime(logtime))
                            logtimestr += ("{0:.3f}".format(logtime -
                                                            int(logtime)))[1:]
                        except:
                            continue
                        if dev not in list(self.device_list):
                            continue
                        devname = self.get_devname_by_devstr(dev)
                        if devname != "":
                            self.response_filter(devname, log)
                            if self.logfile != None:
                                log = logtimestr + ":" + devname + ":" + log
                                self.logfile.write(log)
                        continue
                    if type == pkt.RESPONSE:
                        type = value.split(',')[0]
                        value = value[len(type) + 1:]
                        try:
                            self.response_queue.put([type, value], False)
                        except:
                            pass
                        continue
            except ConnectionLost:
                self.connected = False
                self.service_socket.close()
                print 'connection to server lost, try reconnecting...'
                while True:
                    result = self.connect_to_server(self.server_ip,
                                                    self.server_port)
                    if result == 'success':
                        break
                    time.sleep(2)
                print 'connection to server resumed'
                random.seed()
                time.sleep(1.2 + random.random())
                for devname in self.subscribed:
                    self.send_packet(pkt.LOG_SUB, self.subscribed[devname])
                    self.send_packet(pkt.DEVICE_CMD,
                                     self.subscribed[devname] + ':help')
            except socket.error as e:
                if e.errno == errno.ECONNRESET:
                    print 'Warning: connection closed by server'
                    self.connected = False
                    continue
                if DEBUG: traceback.print_exc()
                break
            except:
                if DEBUG: traceback.print_exc()
                break
        self.keep_running = False
    def server_interaction(self):
        msg = ''
        while self.keep_running:
            try:
                new_msg = self.service_socket.recv(MAX_MSG_LENTH)
                if new_msg == '':
                    raise ConnectionLost
                    break

                msg += new_msg
                while msg != '':
                    type, length, value, msg = TBframe.parse(msg)
                    if type == TBframe.TYPE_NONE:
                        break

                    #print type, length
                    if type == TBframe.ALL_DEV:
                        new_list = {}
                        clients = value.split(':')
                        for c in clients:
                            if c == '':
                                continue
                            devs = c.split(',')
                            uuid = devs[0]
                            devs = devs[1:]
                            for d in devs:
                                if d == '':
                                    continue
                                [dev, using] = d.split('|')
                                new_list[uuid + ',' + dev] = using

                        for dev in list(new_list):
                            self.device_list[dev] = new_list[dev]
                    if type == TBframe.DEVICE_LOG:
                        dev = value.split(':')[0]
                        logtime = value.split(':')[1]
                        log = value[len(dev) + 1 + len(logtime) + 1:]
                        try:
                            logtime = float(logtime)
                            logtimestr = time.strftime("%Y-%m-%d %H-%M-%S", time.localtime(logtime));
                            logtimestr += ("{0:.3f}".format(logtime-int(logtime)))[1:]
                        except:
                            continue
                        if dev not in list(self.device_list):
                            continue
                        devname = self.get_devname_by_devstr(dev)
                        if devname != "":
                            self.response_filter(devname, log)
                            if self.logfile != None:
                                log =  devname + ":" + logtimestr + ":" + log
                                self.logfile.write(log)
                    if type == TBframe.CMD_DONE:
                        self.cmd_excute_return = value
                        self.cmd_excute_state = 'done'
                        self.cmd_excute_event.set()
                    if type == TBframe.CMD_ERROR:
                        self.cmd_excute_return = value
                        self.cmd_excute_state = 'error'
                        self.cmd_excute_event.set()
                    if type == TBframe.DEVICE_ALLOC:
                        values = value.split(',')
                        if len(values) != 2:
                            continue
                        result = values[0]
                        allocated = values[1].split('|')
                        if result != 'success':
                            self.cmd_excute_return = []
                            continue
                        self.cmd_excute_return = allocated
                        self.cmd_excute_state = 'done'
                        self.cmd_excute_event.set()
            except ConnectionLost:
                self.connected = False
                self.service_socket.close()
                print 'connection to server lost, try reconnecting...'
                while True:
                    result = self.connect_to_server(self.server_ip, self.server_port)
                    if result == 'success':
                        break
                    time.sleep(1)
                print 'connection to server resumed'
                random.seed()
                time.sleep(1.2 + random.random())
                for devname in self.subscribed:
                    data = TBframe.construct(TBframe.LOG_SUB, self.subscribed[devname])
                    self.send_data(data)
                    data = TBframe.construct(TBframe.DEVICE_CMD, self.subscribed[devname] + ':help')
                    self.send_data(data)
            except:
                if DEBUG:
                    traceback.print_exc()
                    raise
                break
        self.keep_running = False;