def add_contact(self, contact): name = from_u(contact.name) number = from_u(contact.number) if 'UCS2' in self.device.sim.charset: name = pack_ucs2_bytes(name) number = pack_ucs2_bytes(number) # common arguments for both operations (name and number) args = [name, number] if contact.index: # contact.index is set, user probably wants to overwrite an # existing contact args.append(contact.index) d = super(WCDMAWrapper, self).add_contact(*args) d.addCallback(lambda _: contact.index) return d # contact.index is not set, this means that we need to obtain the # first slot free on the phonebook and then add the contact def get_next_id_cb(index): args.append(index) d2 = super(WCDMAWrapper, self).add_contact(*args) # now we just fake add_contact's response and we return the index d2.addCallback(lambda _: index) return d2 d = self._get_next_contact_id() d.addCallback(get_next_id_cb) return d
def hso_authenticate(self, user, passwd, auth): conn_id = self.state_dict.get('conn_id') if conn_id is None: raise E.CallIndexError("conn_id is None") # Bitfield '00111': MSCHAPv2, MSCHAP, CHAP, PAP, None if auth is None: iauth = consts.MM_ALLOWED_AUTH_UNKNOWN else: iauth = auth & 0x1f # only the lowest 5 bits if iauth == consts.MM_ALLOWED_AUTH_UNKNOWN: iauth = consts.MM_ALLOWED_AUTH_PAP # the old default # convert to string try: _auth = bin(iauth)[2:].zfill(5) # Python 2.6+ except: _auth = '' for i in range(5 - 1, -1, -1): _auth += "%d" % ((iauth >> i) & 1) if self.device.sim.charset == 'UCS2': args = (conn_id, pack_ucs2_bytes(user), pack_ucs2_bytes(passwd), _auth) else: args = (conn_id, user, passwd, _auth) return self.send_at('AT*EIAAUW=%d,1,"%s","%s",%s' % args)
def test_pack_ucs2_bytes(self): # 07911356131313F311000A9260214365870008AA080068006F006C0061 self.assertEqual(pack_ucs2_bytes('hola'), '0068006F006C0061') # 07911356131313F311000A9260214365870008AA0A0068006F006C00610073 self.assertEqual(pack_ucs2_bytes('holas'), '0068006F006C00610073') self.assertEqual(pack_ucs2_bytes(u"中华人民共和国"), '4E2D534E4EBA6C115171548C56FD')
def v_ucs2_name(value): if value == '': return PARTIAL from wader.common.encoding import pack_ucs2_bytes try: pack_ucs2_bytes(value) except: return PARTIAL else: return VALID
def enable_pin(self, pin, enable): where = "SC" if 'UCS2' in self.device.sim.charset: where = pack_ucs2_bytes("SC") pin = pack_ucs2_bytes(pin) at_str = 'AT+CLCK="%s",%d,"%s"' % (where, int(enable), pin) d = self.queue_at_cmd(ATCmd(at_str, name='enable_pin')) d.addCallback(lambda result: result[0].group('resp')) return d
def mbm_authenticate(self, user, passwd): conn_id = self.state_dict.get('conn_id') if conn_id is None: raise E.CallIndexError("conn_id is None") if self.device.sim.charset == 'UCS2': args = (conn_id, pack_ucs2_bytes(user), pack_ucs2_bytes(passwd)) else: args = (conn_id, user, passwd) return self.send_at('AT*EIAAUW=%d,1,"%s","%s"' % args)
def change_pin(self, oldpin, newpin): where = "SC" if 'UCS2' in self.device.sim.charset: where = pack_ucs2_bytes("SC") oldpin = pack_ucs2_bytes(oldpin) newpin = pack_ucs2_bytes(newpin) atstr = 'AT+CPWD="%s","%s","%s"' % (where, oldpin, newpin) d = self.queue_at_cmd(ATCmd(atstr, name='change_pin')) d.addCallback(lambda result: result[0].group('resp')) return d
def get_pin_status(self): def ericsson_get_pin_status(facility): """ Checks whether the pin is enabled or disabled """ cmd = ATCmd('AT+CLCK="%s",2' % facility, name='get_pin_status') return self.queue_at_cmd(cmd) def pinreq_errback(failure): failure.trap(E.SimPinRequired) return 1 def aterror_eb(failure): failure.trap(E.General) # return the failure or wont work return failure facility = 'SC' if self.device.sim.charset == 'UCS2': facility = pack_ucs2_bytes('SC') d = ericsson_get_pin_status(facility) # call the local one d.addCallback(lambda response: int(response[0].group('status'))) d.addErrback(pinreq_errback) d.addErrback(aterror_eb) return d
def add_contact(self, contact): """ Adds ``contact`` to the SIM and returns the index where was stored """ ucs2 = 'UCS2' in self.device.sim.charset name = pack_ucs2_bytes(contact.name) if ucs2 else from_u(contact.name) # common arguments for both operations (name and number) args = [name, from_u(contact.number)] if contact.index: # contact.index is set, user probably wants to overwrite an # existing contact args.append(contact.index) d = super(WCDMAWrapper, self).add_contact(*args) d.addCallback(lambda _: contact.index) return d def get_next_id_cb(index): args.append(index) d2 = super(WCDMAWrapper, self).add_contact(*args) # now we just fake add_contact's response and we return the index d2.addCallback(lambda _: index) return d2 # contact.index is not set, this means that we need to obtain the # first free slot on the phonebook and then add the contact d = self._get_next_contact_id() d.addCallback(get_next_id_cb) return d
def set_charset(self, charset): # The oddity here is that the set command needs to have its charset # value encoded in the current character set if self.device.sim.charset == 'UCS2': charset = pack_ucs2_bytes(charset) d = super(EricssonWrapper, self).set_charset(charset) return d
def set_smsc(self, smsc): """Sets the SIMS's SMSC number to ``smsc``""" if 'UCS2' in self.device.sim.charset: smsc = pack_ucs2_bytes(smsc) d = super(WCDMAWrapper, self).set_smsc(smsc) d.addCallback(lambda response: response[0].group('resp')) return d
def find_contacts(self, pattern): """ Returns all the `Contact` objects whose name matches ``pattern`` :rtype: list """ if 'UCS2' in self.device.sim.charset: pattern = pack_ucs2_bytes(pattern) d = super(WCDMAWrapper, self).find_contacts(pattern) d.addCallback(lambda matches: map(self._regexp_to_contact, matches)) return d
def get_net_info_cb(netinfo): """ Returns a (Networkname, ConnType) tuple It returns None if there's no info """ if not netinfo: return None netinfo = netinfo[0] if netinfo.group('error'): # this means that we've received a response like # +COPS: 0 which means that we don't have network temporaly # we should raise an exception here raise E.NoNetwork() # TS 27007 got updated as of 10.4 _map = { '0': MM_GSM_ACCESS_TECH_GPRS, # strictly GSM '1': MM_GSM_ACCESS_TECH_GSM_COMPAT, '2': MM_GSM_ACCESS_TECH_UMTS, # strictly UTRAN '3': MM_GSM_ACCESS_TECH_EDGE, '4': MM_GSM_ACCESS_TECH_HSDPA, '5': MM_GSM_ACCESS_TECH_HSUPA, '6': MM_GSM_ACCESS_TECH_HSPA, '7': MM_GSM_ACCESS_TECH_LTE, } conn_type = _map.get(netinfo.group('status')) netname = netinfo.group('netname') if netname in ['Limited Service', pack_ucs2_bytes('Limited Service')]: raise ex.LimitedServiceNetworkError # netname can be in UCS2, as a string, or as a network id (int) if check_if_ucs2(netname): return unpack_ucs2_bytes(netname), conn_type else: # now can be either a string or a network id (int) try: netname = int(netname) except ValueError: # we got a string ID return netname, conn_type # if we have arrived here, that means that the network id # is a five, six or seven digit integer return str(netname), conn_type
def _add_contact(self, name, number, index): """ Adds a contact to the SIM card """ raw = 0 try: # are all ascii chars name.encode('ascii') except: # write in TS31.101 type 80 raw format name = '80%sFF' % pack_ucs2_bytes(name) raw = 1 category = 145 if number.startswith('+') else 129 args = (index, number, category, name, raw) cmd = ATCmd('AT^CPBW=%d,"%s",%d,"%s",%d' % args, name='add_contact') return self.queue_at_cmd(cmd)
def get_net_info_cb(netinfo): """ Returns a (Networkname, ConnType) tuple It returns None if there's no info """ if not netinfo: return None netinfo = netinfo[0] if netinfo.group('error'): # this means that we've received a response like # +COPS: 0 which means that we don't have network temporaly # we should raise an exception here raise E.NoNetwork() conn_type = 'GPRS' netname = netinfo.group('netname') if netname in ['Limited Service', pack_ucs2_bytes('Limited Service')]: raise LimitedServiceNetworkError() # netname can be in UCS2, as a string, or as a network id (int) if check_if_ucs2(netname): return unpack_ucs2_bytes(netname), conn_type else: # now can be either a string or a network id (int) try: netname = int(netname) except ValueError: # we got a string ID return netname, conn_type # if we have arrived here, that means that the network id # is a five digit integer return str(netname), conn_type
def send_ussd(self, ussd, force_ascii=False, loose_charset_check=False): """Sends the ussd command ``ussd``""" def convert_response(response): index = response[0].group('index') if index == '1': self.device.set_property(USD_INTFACE, 'State', 'user-response') else: self.device.set_property(USD_INTFACE, 'State', 'idle') resp = response[0].group('resp') if resp is None: return "" # returning the Empty string is valid if not check_if_ucs2(resp, limit=LATIN_EX_B): if 'UCS2' in self.device.sim.charset and \ not loose_charset_check: raise E.MalformedUssdPduError(resp) else: return resp else: try: return unpack_ucs2_bytes(resp) except (TypeError, UnicodeDecodeError): raise E.MalformedUssdPduError(resp) def reset_state(failure): if self.device.get_property(USD_INTFACE, 'State') != 'idle': self.device.set_property(USD_INTFACE, 'State', 'idle') failure.raiseException() # re-raise if 'UCS2' in self.device.sim.charset and not force_ascii: ussd = pack_ucs2_bytes(ussd) d = super(WCDMAWrapper, self).send_ussd(str(ussd)) d.addCallback(convert_response) d.addErrback(reset_state) return d
def _send_pin(charset, pin): if 'UCS2' in charset: pin = pack_ucs2_bytes(pin) return super(EricssonWrapper, self).send_pin(pin)
def send_ussd(self, ussd): """ Sends the USSD command ``ussd`` Sends plain or UCS2 encoded text Receives GSM 7bit compressed text """ # AT+CUSD=1,"*100#",15 # (*100#) # or # AT+CUSD=1,"002A0031003000300023",15 # (*100#) # +CUSD: 1,"5079191E4E935BCDB2DBAF88818E753A3A2C2EBBD76F37FDAD90818E7" # "53A3A2C2EBB5BD6B2DCEC3F8BC3F275394D57CC40C1BA991D26D7DD67" # "D0B14E4787C565F70B1A1EAF5BF477EBF856D040D0F0780D6A86DDE17" # "359AEB881A86179DA9C769BDF0A1C0899669BCB",15 # Prepaid-Menü\n # 1 Guthabenkonto\n # 2 Guthaben-Verfügbarkeit\n # 3 Aufladung Guthaben/Pack-to-Go\n # 4 Pack Manager\n # 7 Tarifinfo\n # 8 Hilfe def convert_response(response): index = response[0].group('index') if index == '1': self.device.set_property( consts.USD_INTFACE, 'State', 'user-response') else: self.device.set_property(consts.USD_INTFACE, 'State', 'idle') resp = response[0].group('resp') if resp is None: return "" # returning the Empty string is valid try: ret = unpack_msg(resp).decode("gsm0338") if is_gsm_text(ret): return ret except UnicodeError: pass try: return resp.decode('hex') except TypeError: raise MalformedUssdPduError(resp) def reset_state(failure): if self.device.get_property(consts.USD_INTFACE, 'State') != 'idle': self.device.set_property(consts.USD_INTFACE, 'State', 'idle') failure.raiseException() # re-raise if 'UCS2' in self.device.sim.charset: ussd = pack_ucs2_bytes(ussd) d = super(WCDMAWrapper, self).send_ussd(str(ussd)) d.addCallback(convert_response) d.addErrback(reset_state) return d