def device_plugged(self, vid, pid, vendor): for url, srv in self.__hosts.items(): try: srv.device_plugged(vid, pid, vendor) except xmlrpclib.Fault, err: error("Removing XML-RPC server '%s' due error, %s" % (url, err)) self.__hosts.__delitem__(url)
def __on_tty_event(self, client, action, device): # -- By new TTY ports only create the object and store the corresponding ID if action == "add": _parent = parent_from_device(device) _id = create_parent_id(_parent) if _id is None: return if self.device_list.has_key(_id) is False: try: # -- @XXX: Correct place for defining the Gobject signals with the callbacks? DEVICE_SIGNALS = [ ["modem-ready", self.__modem_ready_cb], ["modem-removed", self.__modem_removed_cb], ["modem-failure", self.__modem_failure_cb], ["device-removed", self.__device_removed_cb], ] dev = self._Device(_parent, self.bus_name, MM_DEVICE_PATH, _id, DEVICE_SIGNALS) self.device_list[_id] = dev except Exception, err: error("Unexpected failure adding device, %s" % err)
def __start(self): while self.__stop is False: try: self.__task_added.wait(self.WAIT_TASK_ADDED_TIME) self.__task_added.clear() # -- Now execute the next task of the queue _task = self.__pop() if _task is not None: # -- Change the state to busy self.__state = self.STATE_BUSY self.__tasklog.start(_task) retval = _task.execute() if retval == _task.RESULT_OK: self.__errors = 0 elif retval == _task.RESULT_ERROR: self.__errors += 1 # -- Failure threshold reached, so try to reset the device and stop the task queue if self.__errors == self.ERRORS_THRESHOLD: self.stop() self.__device.reset() break # -- Set the state to idle self.__state = self.STATE_IDLE self.__tasklog.end(_task) except Exception, err: error("Unexpected failure in TaskPool thread, %s" % err) self.__state = self.STATE_IDLE
def modem_ready(self, vid, pid, com_minor, aux_minor, model, revision): for url, srv in self.__hosts.items(): try: srv.modem_ready(vid, pid, com_minor, aux_minor, model, revision) except xmlrpclib.Fault, err: error("Removing XML-RPC server '%s' due error, %s" % (url, err)) self.__hosts.__delitem__(url)
def modem_failure(self, vid, pid): for url, srv in self.__hosts.items(): try: srv.modem_failure(vid, pid) except xmlrpclib.Fault, err: error("Removing XML-RPC server '%s' due error, %s" % (url, err)) self.__hosts.__delitem__(url)
def function(task): cmd = 'AT+CIMI' regex = '^(\+CIMI:\ +|)(?P<cimi>.+)' r_values = ["cimi"] for i in range(0, 3): res = self.io.com.send_query({ "type": "regex", "cmd": cmd, "task": task, "regex": regex, "r_values": r_values }) if res == None: return "" try: # Test it is a valid integer number int(res["cimi"]) # If the IMSI seems valid store it in a cache self.cache["imsi"] = res["cimi"] return self.cache["imsi"] except ValueError: warning("Got erroneous IMSI, trying again") error("Got erroneous IMSI for three times, desisting")
def modem_removed(self, vid, pid): for url, srv in self.__hosts.items(): try: srv.modem_removed(vid, pid) except xmlrpclib.Fault, err: error("Removing XML-RPC server '%s' due error, %s" % (url, err)) self.__hosts.__delitem__(url)
def close(self, flush=True): if self.__fd is not None: try: self.__flush() os.close(self.__fd) except Exception, err: error("Closing port %s, %s" % (self.__devnode, err)) finally:
def __close_serial_port(self): try: tcflush(self._fd, TCIOFLUSH) except: warning("Got error flushing port") try: os.close(self._fd) except Exception as err: error("Got error closing port: %s" % str(err))
def write(self, msg): _len = len(msg) while True: ret = os.write(self.__fd, msg) if ret < 0: raise IOError, "Got write() failure, %i" % ret # -- @FIXME: Evaluate the return value! if ret != _len: error("@XXX: Coulnd't write all the data!") break
def __get_interface_number(self): if self.__iface is None: ifacenr = -1 # -- In some f*****g cases, the gudev device doesn't provide the interface number! # -- So we need to get it from the sysfs path file! try: iface_path = os.path.dirname(self.__sysfs_path) + "/../../bInterfaceNumber" fd = open(iface_path) ifacenr = int(fd.read()) fd.close() # -- @XXX: Always choice the configuration index zero? # -- Ubuntu and Fedora provide different tupples with the interfaces for x in self.__usbdev.configurations[0].interfaces: for y in x: if y.interfaceNumber == ifacenr: self.__iface = y return except Exception, err: error("*** @FIXME: No interface '%i' for port %s, %s" % (ifacenr, self.__devnode, err)) error(" --> sysfs path : %s" % iface_path) error(" --> configurations : %s" % repr(self.__usbdev.configurations)) error(" --> interfaces : %s" % repr(self.__usbdev.configurations[0].interfaces)) # -- At this point we have a problem, so inform our caller about this raise PortError, "Couldn't assign an USB interface to port '%s'" % self.__devnode
def wait(self): # -- By timeouts waiting for the queue happens, then execute the below steps: # -- * Set the error type/message and return self.__queue_event.wait(self.__timeout_queue) if not self.__queue_event.isSet(): self.__raise_abort(TaskQueueTimeout, "Queue waiting timeout", self.__timeout_queue) self.__task_event.wait(self.__timeout_task) if not self.__task_event.isSet(): self.__raise_abort(SerialResponseTimeout, "Execution timeout (state %i)" % self.__state, self.__timeout_task) # -- By errors pass it to the task creator if self.__error is not None: error("Task '%s' error : %s" % (self.__msg, self.__error)) raise self.__error
def __do_read_until_chars(self, task=None, stop_chars=None, timeout=None, debug=False): # -- Inform the task pool that we are going to start a read operation if task is not None: task.state(task.STATE_READING) _line = "" _reopened = False timeout_read = self.__calculate_timeout_loops(timeout, task, self.READ_TIMEOUT_DEFAULT, self.READ_SELECT_TIME) timeout = timeout_read while True: ready = select.select([self._fd], [ ], [ ], self.READ_SELECT_TIME) if self._fd in ready[0]: # -- @FIXME: Read all the available data, but for now we must return only one line! _chr = os.read(self._fd, 1) if (stop_chars is None) and (_chr == "\n" or _chr == "\r"): break if (stop_chars is not None) and (_chr in stop_chars): break _line += _chr if (task is not None) and task.aborted(): if debug is True: print "--> read: '%s'" % repr(_line) raise TaskAborted, "Task was aborted, stopping read()" timeout -= 1 if timeout == 0: if _reopened is False: error("Got timeout in READ select. Reopening port.") self.__reopen_serial_port_for_recover() self.__write(self.__last_cmd, task=task, timeout=timeout, debug=debug) _reopened = True timeout = timeout_read else: raise SerialResponseTimeout, "Got timeout in read select" return _line
def function(task): cmd = "AT+CIMI" regex = "^(\+CIMI:\ +|)(?P<cimi>.+)" r_values = ["cimi"] for i in range(0, 3): res = self.io.com.send_query( {"type": "regex", "cmd": cmd, "task": task, "regex": regex, "r_values": r_values} ) if res == None: return "" try: # Test it is a valid integer number int(res["cimi"]) # If the IMSI seems valid store it in a cache self.cache["imsi"] = res["cimi"] return self.cache["imsi"] except ValueError: warning("Got erroneous IMSI, trying again") error("Got erroneous IMSI for three times, desisting")
def __on_tty_event(self, client, action, device): # -- By new TTY ports only create the object and store the corresponding ID if action == "add": _parent = parent_from_device(device) _id = create_parent_id(_parent) if _id is None: return if self.device_list.has_key(_id) is False: try: # -- @XXX: Correct place for defining the Gobject signals with the callbacks? DEVICE_SIGNALS = [ [ "modem-ready" , self.__modem_ready_cb ], [ "modem-removed" , self.__modem_removed_cb ], [ "modem-failure" , self.__modem_failure_cb ], [ "device-removed" , self.__device_removed_cb ], ] dev = self._Device(_parent, self.bus_name, MM_DEVICE_PATH, _id, DEVICE_SIGNALS) self.device_list[_id] = dev except Exception, err: error("Unexpected failure adding device, %s" % err)
def __write(self, command, task=None, timeout=None, debug=False): # -- Inform the Task pool which command are we going to execute if task is not None: task.command(command) task.state(task.STATE_WRITING) _cmd = command + "\r" _len = len(_cmd) _retries = 4 # -- We need a timeout otherwise we will have an endless loop! _reopened = False timeout_write = self.__calculate_timeout_loops(timeout, task, self.WRITE_TIMEOUT_DEFAULT, self.WRITE_SELECT_TIME) if debug is True: print "--> write: '%s'" % repr(_cmd) timeout = timeout_write exception = None while _len > 0: try: ready = select.select([ ], [ self._fd ], [ ], self.WRITE_SELECT_TIME) if (task is not None) and task.aborted(): exception = TaskAborted("Task was aborted, stopping write()") break timeout -= 1 if timeout == 0: if _reopened is False: error("Got timeout in WRITE select. Reopening port.") self.__reopen_serial_port_for_recover() _reopened = True _cmd = command + "\r" _len = len(_cmd) timeout = timeout_write continue else: exception = SerialResponseTimeout("Aborting write operation due timeout") break if self._fd in ready[1]: ret = os.write(self._fd, _cmd) _cmd = _cmd[ret:] _len = _len - ret except Exception, err: if _retries: _retries -= 1 error("Unexpected error, %s. Going to reopen the port." % err) self.__reopen_serial_port_for_recover() _cmd = command + "\r" else: error("Can't recover from exception, %s" % err) raise Exception, err
def __save(self): try: self.__cfg.save(self.__vendors) except Exception, err: error("Couldn't update '%s', %s" % (self.__cfg.fpath(), err))
def __raise_abort(self, exception, msg, timeout): errmsg = self.__timeout_errmsg(msg, timeout) error(errmsg) self.__error = exception(errmsg) self.__abort_event.set() raise self.__error
def error(self, msg): error(msg)
def __device_removed_cb(self, driver, mm_device_path): try: info("Going to remove the device '%s'" % mm_device_path) self.__remove(driver) except Exception, err: error("Unexpected failure removing device, %s" % err)
def free_modem_id(num): if _modem_ids.__contains__(num) is True: _modem_ids.remove(num) else: error("Couldn't free invalid Modem ID %i" % int(num))
def error(self, msg): error("%s: %s" % (self.__vid_pid, msg))