Ejemplo n.º 1
0
 def plusCLIP(self, righthandside):
     """
     Connecting Line Identification Presence
     """
     number, ntype, rest = safesplit(righthandside, ',', 2)
     number = number.replace('"', '')
     logger.warning("plusCLIP not handled -- please fix me")
Ejemplo n.º 2
0
    def percentCSTAT(self, righthandside):
        """
        TI Calypso subsystem status report

        PHB is phonebook, SMS is messagebook. RDY is supposed to be sent, after
        PHB and SMS both being 1, however it's not sent on all devices.
        EONS is completely undocumented.

        Due to RDY being unreliable, we wait for PHB and SMS sending availability
        and then synthesize a global SimReady signal.
        """
        subsystem, available = safesplit(righthandside, ",")
        if not bool(int(available)):  # not ready
            if subsystem in ("PHB", "SMS"):
                self.subsystemReadyness[subsystem] = False
                logger.info("subsystem %s readyness now %s" %
                            (subsystem, self.subsystemReadyness[subsystem]))
                if not self.fullReadyness == False:
                    self._object.ReadyStatus(False)
                    self.fullReadyness = False
        else:  # ready
            if subsystem in ("PHB", "SMS"):
                self.subsystemReadyness[subsystem] = True
                logger.info("subsystem %s readyness now %s" %
                            (subsystem, self.subsystemReadyness[subsystem]))
                newFullReadyness = self.subsystemReadyness[
                    "PHB"] and self.subsystemReadyness["SMS"]
                if newFullReadyness and (not self.fullReadyness == True):
                    self._object.ReadyStatus(True)
                    self.fullReadyness = True

        logger.info("full readyness now %s" % self.fullReadyness)
Ejemplo n.º 3
0
    def plusCIEV(self, righthandside):
        """
        Indicator Event Reporting. Based on 3GPP TS 07.07, Chapter 8.9, but slightly extended.

        As +CIND=? gives us a hint (one of the few test commands EZX exposes), we conclude:

        0: battery charge level (0-5)
        1: signal level (0-5)
        2: service availability (0-1)
        3: call active? (0-1)
        4: voice mail (message) (0-1)
        5: transmit activated by voice activity (0-1)
        6: call progress (0-3) [0:no more in progress, 1:incoming, 2:outgoing, 3:ringing]
        7: roaming (0-2)
        8: sms storage full (0-1)
        11: ???
        20: ??? (SIM not inserted?)
        """
        indicator, value = (int(x) for x in safesplit(righthandside, ','))

        try:
            method = getattr(self, "CIEV_%d" % indicator)
        except AttributeError:
            logger.debug("EZX: unhandled CIEV", indicator, value)
        else:
            method(value)
Ejemplo n.º 4
0
 def percentCSQ(self, righthandside):
     """
     signal strength report
     """
     strength, snr, quality = safesplit(righthandside, ",")
     self._object.SignalStrength(
         const.signalQualityToPercentage(int(strength)))  # send dbus signal
Ejemplo n.º 5
0
 def percentCCCN(self, righthandside):
     direction, callId, ie = safesplit(righthandside, ",")
     # this is ASN.1 BER, but we don't want a full decoder here
     info = {}
     if ie[0:8] + ie[10:30] == "A10E020102011030068101428F01":
         info["held"] = bool(int(ie[30:32], 16))
     if info:
         self._callHandler.statusChangeFromNetwork(int(callId) + 1, info)
Ejemplo n.º 6
0
 def plusCCTP(self, righthandside):
     callnumber, peer = safesplit(righthandside, ',')
     callnumber = int(callnumber)
     peer = peer.strip('"')
     # synthesize call status
     self._callHandler.statusChangeFromNetwork(callnumber, {
         "status": "outgoing",
         "peer": peer
     })
Ejemplo n.º 7
0
 def plusCMT(self, righthandside, pdu):
     """
     Message Transfer Indication
     """
     header = safesplit(righthandside, ',')
     length = int(header[1])
     # Now we decode the actual PDU
     sms = ogsmd.gsm.sms.SMS.decode(pdu, "sms-deliver")
     self._object.IncomingMessage(str(sms.addr), sms.ud, sms.properties)
Ejemplo n.º 8
0
 def plusCMTI(self, righthandside):
     """
     Message Transfer Indication
     """
     storage, index = safesplit(righthandside, ',')
     if storage != '"SM"':
         logger.warning("unhandled +CMTI message notification")
     else:
         self._object.IncomingStoredMessage(int(index))
Ejemplo n.º 9
0
    def trigger(self):
        request, response, error = yield ("+CSQ")
        result = {}
        if error is not None:
            self.errorFromChannel(request, error)
        else:
            if response[-1] != "OK" or len(response) == 1:
                pass
            else:
                result["strength"] = const.signalQualityToPercentage(
                    int(safesplit(self._rightHandSide(response[0]),
                                  ',')[0]))  # +CSQ: 22,99

        request, response, error = yield ("+COPS?")
        if error is not None:
            self.errorFromChannel(request, error)
        else:
            if response[-1] != "OK" or len(response) == 1:
                pass
            else:
                values = safesplit(self._rightHandSide(response[0]), ',')
                if len(values) < 3:
                    result["mode"] = const.REGISTER_MODE[int(values[0])]
                    result["registration"] = "unregistered"
                else:
                    result["mode"] = const.REGISTER_MODE[int(values[0])]
                    roaming = self._object.modem.data("network:roaming", False)
                    result["registration"] = "roaming" if roaming else "home"

                    mccmnc = values[2].strip('"').replace('-', '')
                    if mccmnc == "":
                        result["registration"] = "busy"
                    else:
                        result["code"] = mccmnc
                        network = const.NETWORKS.get((mccmnc[:3], mccmnc[3:]),
                                                     {})
                        if "brand" in network:
                            result["provider"] = network["brand"]
                        elif "operator" in network:
                            result["provider"] = network["operator"]
                        else:
                            result["provider"] = "Unknown"

        self._ok(result)
Ejemplo n.º 10
0
 def plusEOPER(self, righthandside):
     values = safesplit(righthandside, ',')
     status = {}
     if len(values) == 1:
         status["registration"] = "unregistered"
     else:
         # FIXME: This is not correct. Need to listen for the roaming status as well
         roaming = self._object.modem.data("network:roaming", False)
         status["registration"] = "roaming" if roaming else "home"
         status["provider"] = values[1]
     self._object.Status(status)
Ejemplo n.º 11
0
 def plusCGREG(self, righthandside):
     """
     Gprs Registration Status Update
     """
     charset = currentModem()._charsets["DEFAULT"]
     values = safesplit(righthandside, ',')
     status = {}
     status["registration"] = const.REGISTER_STATUS[int(values[0])]
     if len(values) >= 3:
         status["lac"] = values[1].strip('"').decode(charset)
         status["cid"] = values[2].strip('"').decode(charset)
     self._object.NetworkStatus(status)
Ejemplo n.º 12
0
 def plusCREG(self, righthandside):
     """
     Network Registration Status Update
     """
     charset = currentModem()._charsets["DEFAULT"]
     values = safesplit(righthandside, ',')
     self.register = const.REGISTER_STATUS[int(values[0])]
     if len(values) >= 3:
         self.lac = values[1].strip('"').decode(charset)
         self.cid = values[2].strip('"').decode(charset)
     self._mediator.NetworkGetStatus(self._object, self.statusOK,
                                     self.statusERR)
Ejemplo n.º 13
0
 def plusCUSD(self, righthandside):
     """
     Incoming USSD result
     """
     charset = currentModem()._charsets["USSD"]
     values = safesplit(righthandside, ',')
     if len(values) == 1:
         mode = const.NETWORK_USSD_MODE[int(values[0])]
         self._object.IncomingUssd(mode, "")
     elif len(values) == 3:
         mode = const.NETWORK_USSD_MODE[int(values[0])]
         message = values[1].strip('" ').decode(charset)
         self._object.IncomingUssd(mode, message)
     else:
         logger.warning("Ignoring unknown format: '%s'" % righthandside)
Ejemplo n.º 14
0
 def plusCGEV(self, righthandside):
     """
     Gprs Context Event
     """
     values = safesplit(righthandside, ',')
     if len(values
            ) == 1:  # detach, but we're not having an IP context online
         if values[0] == "ME DETACH":
             # FIXME this will probably lead to a zombie
             instance = pdp.Pdp.getInstance()
             if instance is not None:
                 instance.deactivate()
             # FIXME force dropping the dataport, this will probably kill the zombie
     elif len(values) >= 3:  # detach while we were attached
         pass
Ejemplo n.º 15
0
 def plusCREG(self, righthandside):
     # call base implementation
     AbstractUnsolicitedResponseDelegate.plusCREG(self, righthandside)
     # do we care for recamping?
     if not self.checkForRecamping:
         return
     # check for recamping
     values = safesplit(righthandside, ',')
     register = const.REGISTER_STATUS[int(values[0])]
     if self.lastStatus == "unregistered":
         if self.register in "home roaming".split():
             self.reregisterIntervals.append(time.time() - self.lastTime)
             if len(self.reregisterIntervals) == 1:
                 self.firstReregister = time.time()
             gobject.idle_add(self._checkRecampingBug)
             self.lastReregister = time.time()
     self.lastStatus = register
     self.lastTime = time.time()
Ejemplo n.º 16
0
 def plusCBM(self, righthandside, pdu):
     """
     Cell Broadcast Message
     """
     values = safesplit(righthandside, ',')
     if len(values) == 1:  # PDU MODE
         cb = ogsmd.gsm.sms.CellBroadcast.decode(pdu)
         sn = cb.sn
         channel = cb.mid
         dcs = cb.dcs
         page = cb.page
         data = cb.ud
     elif len(values) == 5:  # TEXT MODE
         sn, mid, dcs, page, pages = values
         channel = int(mid)
         data = pdu
     else:
         logger.warning(
             "unrecognized +CBM cell broadcast notification, please fix me..."
         )
         return
     self._object.IncomingCellBroadcast(channel, data)
Ejemplo n.º 17
0
 def plusCSSU(self, righthandside):
     code, index, number, type = safesplit(righthandside, ",")
     info = {}
     if code == "0":
         info["forwarded"] = True
     elif code == "1":
         info["cug"] = True
     elif code == "2":
         info["remotehold"] = True
     elif code == "3":
         info["remotehold"] = False
     elif code == "4":
         info["conference"] = True
     else:
         logger.info("unhandled +CSSU code '%s'" % code)
     if info:
         # This is not failsafe since we don't know the call ID
         if code in "234":
             self._callHandler.statusChangeFromNetworkByStatus(
                 "active", info)
         else:
             self._callHandler.statusChangeFromNetworkByStatus(
                 "incoming", info)
Ejemplo n.º 18
0
 def percentCPRI(self, righthandside):
     gsm, gprs = safesplit(righthandside, ',')
     cipher_gsm = const.NETWORK_CIPHER_STATUS.get(int(gsm), "unknown")
     cipher_gprs = const.NETWORK_CIPHER_STATUS.get(int(gprs), "unknown")
     self._object.CipherStatus(cipher_gsm, cipher_gprs)
Ejemplo n.º 19
0
 def plusCLIP(self, righthandside):
     number, ntype = safesplit(righthandside, ',')
     if number and ntype:
         peer = const.phonebookTupleToNumber(number[1:-1], int(ntype))
         self._mediator.Call.clip(self._object, peer)
Ejemplo n.º 20
0
 def plusCKEV(self, righthandside):
     values = safesplit(righthandside, ',')
     keyname = KEYCODES.get(int(values[0]), "unknown")
     pressed = bool(int(values[1]))
     self._object.KeypadEvent(keyname, pressed)
Ejemplo n.º 21
0
    def percentCPI(self, righthandside):
        """
        Call Progress Indication:
        callId = call number in internal call table (same as call number in CCLD)
        msgType = 0:setup, 1:disconnect, 2:alert, 3:call proceed, 4:sync, 5:progress, 6:connected, 7:release, 8:reject (from network), 9:request (MO Setup), 10: hold
        ibt = 1, if in-band-tones enabled
        tch = 1, if traffic channel assigned
        direction = 0:MO, 1:MT, 2:CCBS, 3:MO-autoredial
        mode = 0:voice, 1:data, 2:fax, ..., 9 [see gsm spec bearer type]
        number = "number" [gsm spec]
        ntype = number type [gsm spec]
        alpha = "name", if number found in SIM phonebook [gsm spec]
        cause = GSM Network Cause [see gsm spec, section 04.08 annex H]
        line = 0, if line 1. 1, if line2.

        Typical chunks during a call:

        ... case A: incoming (MT) ...
        %CPI: 1,0,0,0,1,0,"+496912345678",145,,,0 ( setup call, MT, line one, no traffic channel yet )
        +CRING: VOICE
        %CPI: 1,0,0,1,1,0,"+496912345678",145,,,0 ( setup call, MT, line one, traffic channel assigned )
        %CPI: 1,4,0,1,1,0,"+496912345678",145,,,0 ( sync call, MT, line one, traffic channel assigned )
        %CPI: 1,0,0,1,1,0,"+496912345678",145,,,0 ( setup call, MT, line one, traffic channel assigned )
        +CRING: VOICE
        %CPI: 1,4,0,1,1,0,"+496912345678",145,,,0 ( sync call, MT, line one, traffic channel assigned )
        +CRING: VOICE

        ... case A.1: remote line hangs up ...
        %CPI: 1,1,0,1,1,0,"+496912345678",145,,,0 ( disconnect call, MT line one, traffic channel assigned )
        %CPI: 1,7,0,0,,,,,,,0 (release from network, traffic channel freed)
        (NO CARRIER, if call was connected, i.e. local accepted)

        ... case A.2: local accept (ATA) ...
        %CPI: 1,6,0,1,1,0,"+496912345678",145,,,0 ( connected call, MT, line one, traffic channel assigned )
        => from here see case A.1 or A.3

        ... case A.3: local reject (ATH) ...
        %CPI: 1,1,0,1,1,0,"+496912345678",145,,,0 ( disconnect call, MT line one, traffic channel assigned )
        %CPI: 1,7,0,0,,,,,,,0 (release from network, traffic channel freed)

        ... case B: outgoing (MO) ...
        %CPI: 1,9,0,0,0,0,"+496912345678",145,,,0 ( request call, MO, line one, no traffic channel yet )
        %CPI: 1,3,0,0,0,0,"+496912345678",145,,,0 ( call call, MO, line one, no traffic channel yet )
        %CPI: 1,4,0,1,0,0,"+496912345678",145,,,0 ( sync call, MO, line one, traffic channel assigned )
        %CPI: 1,2,1,1,0,0,"+496912345678",145,,,0 ( alert call, MO, line one, traffic channel assigned )
        (at this point, it is ringing on the other side)

        ... case B.1: remote line rejects or sends busy...
        %CPI: 1,6,0,1,0,0,"+496912345678",145,,,0 ( connect call, MO, line one, traffic channel assigned )
        (at this point, ATD returns w/ OK)
        %CPI: 1,1,0,1,0,0,"+496912345678",145,,17,0 ( disconnect call, MO, line one, traffic channel assigned )
        (at this point, BUSY(17) or NO CARRIER(16) is sent)
        %CPI: 1,7,0,0,,,,,,,0 (release from network, traffic channel freed)

        ... case B.2: remote line accepts...
        %CPI: 1,6,0,1,0,0,"+496912345678",145,,,0 ( connect call, MO, line one, traffic channel assigned )
        (at this point, ATD returns w/ OK)

        ... case B.3: local cancel ...
        ?

        ... case C.1: first call active, second incoming and accepted (puts first on hold)
        %CPI: 1,10,0,1,0,0,"+496912345678",145,,,0
        %CPI: 2,6,0,1,1,0,"+496912345679",129,,,0

        """
        callId, msgType, ibt, tch, direction, mode, number, ntype, alpha, cause, line = safesplit(
            righthandside, ",")
        if msgType == "10":
            msgType = "A"  # stupid hack to have single char types

        #devchannel = self._object.modem.communicationChannel( "DeviceMediator" )
        #devchannel.enqueue( "+CPAS;+CEER" )

        info = {}

        # Report number, reason, and line, if available
        if number and ntype:
            info["peer"] = const.phonebookTupleToNumber(
                number[1:-1], int(ntype))
        if cause:
            info["reason"] = const.ISUP_RELEASE_CAUSE.get(
                int(cause), "unknown cause")
        if line:
            info["line"] = int(line)

        # Always report the direction
        if direction == "0":
            info.update({"direction": "outgoing"})
        elif direction == "1":
            info.update({"direction": "incoming"})

        # Report mode
        if mode:
            info["mode"] = const.CALL_MODE.revlookup(int(mode))

        # Compute status

        if msgType == "0":  # setup (MT)
            info.update({"status": "incoming"})
        elif msgType == "6":  # connected (MO & MT)
            info.update({"status": "active"})
        elif msgType == "1":  # disconnected (MO & MT)
            # FIXME try to gather reason for disconnect?
            info.update({"status": "release"})
        elif msgType == "8":  # network reject (MO)
            info.update({"status": "release", "reason": "no service"})
        elif msgType == "9":  # request (MO)
            info.update({"status": "outgoing"})
        elif msgType == "3":  # Sometimes setup is not sent?!
            info.update({"status": info["direction"]})
        elif msgType == "A":  # hold
            info.update({"status": "held"})
        if msgType in "013689A":
            self._callHandler.statusChangeFromNetwork(int(callId), info)

        # DSP bandaid
        if msgType in "34":
            currentModem().channel("MiscMediator").enqueue(createDspCommand())
Ejemplo n.º 22
0
 def percentCSSN(self, righthandside):
     direction, transPart, ie = safesplit(righthandside, ",")
Ejemplo n.º 23
0
 def plusCSSU(self, righthandside):
     values = safesplit(righthandside, ',')
     if len(values) == 4:
         code, index, number, type_ = values
     else:
         code = values[0]