[pkg-fso-commits] [SCM] FSO frameworkd Debian packaging branch, master, updated. milestone4-368-g700ab82

Daniel Willmann daniel at totalueberwachung.de
Mon Feb 2 18:51:41 UTC 2009


The following commit has been merged in the master branch:
commit def440027b0abae8ad1b061c43473df2ae58133a
Author: Daniel Willmann <daniel at totalueberwachung.de>
Date:   Thu Dec 18 19:15:59 2008 +0100

    ogsmd: Add support for different SMS message types
    
    This patch also (hopefully!) fixes the SMS PDU breakage that has been
    around in master for some time.
    SMS types are now sms-{deliver,submit} and sms-{deliver,submit}-report

diff --git a/framework/subsystems/ogsmd/gsm/const.py b/framework/subsystems/ogsmd/gsm/const.py
index e94314a..257bd79 100644
--- a/framework/subsystems/ogsmd/gsm/const.py
+++ b/framework/subsystems/ogsmd/gsm/const.py
@@ -803,19 +803,21 @@ NETWORK_CIPHER_STATUS = { \
 #=========================================================================#
 # PDU TP definitions follow here according to the appearance in GSM 03.40
 # chapter 9.2.3
-TP_MTI_INCOMING = { \
+TP_MTI_INCOMING = BiDict( { \
     "sms-deliver" : 0,
     "sms-submit-report" : 1,
     "sms-status-report" : 2,
     "reserved" : 3,
-}
+} )
+TP_MTI_INCOMING.AUTOINVERSE = True
 
-TP_MTI_OUTGOING = { \
+TP_MTI_OUTGOING = BiDict( { \
     "sms-deliver-report" : 0,
     "sms-submit" : 1,
     "sms-command" : 2,
     "reserved" : 3,
-}
+} )
+TP_MTI_OUTGOING.AUTOINVERSE = True
 
 #=========================================================================#
 TP_VPF = { \
diff --git a/framework/subsystems/ogsmd/gsm/sms.py b/framework/subsystems/ogsmd/gsm/sms.py
index 906838a..3bf0c0d 100644
--- a/framework/subsystems/ogsmd/gsm/sms.py
+++ b/framework/subsystems/ogsmd/gsm/sms.py
@@ -12,7 +12,7 @@ Module: pdu
 
 """
 from ogsmd.gsm.convert import *
-from ogsmd.gsm.const import CB_PDU_DCS_LANGUAGE
+from ogsmd.gsm.const import CB_PDU_DCS_LANGUAGE, TP_MTI_INCOMING, TP_MTI_OUTGOING
 import math
 
 class SMSError(Exception):
@@ -90,64 +90,79 @@ class PDUAddress:
 
 class SMS(object):
     @classmethod
-    def decode( cls, pdu, direction ):
+    def decode( cls, pdu, smstype ):
         # first convert the string into a bytestream
         try:
             bytes = [ int( pdu[i:i+2], 16 ) for i in range(0, len(pdu), 2) ]
         except ValueError:
             raise SMSError, "PDU malformed"
 
-        sms = cls( direction )
-
+        sms = cls( smstype )
         offset = 0
-        # SCA - Service Center address
-        sca_len = bytes[offset]
-        offset += 1
-        if sca_len > 0:
-            sms.sca = PDUAddress.decode( bytes[offset:offset+sca_len] )
-        else:
-            sms.sca = False
 
-        offset += sca_len
+        if sms.type == "sms-deliver" or sms.type == "sms-submit":
+            # SCA - Service Center address
+            sca_len = bytes[offset]
+            offset += 1
+            if sca_len > 0:
+                sms.sca = PDUAddress.decode( bytes[offset:offset+sca_len] )
+            else:
+                sms.sca = False
+            offset += sca_len
+
         # PDU type
         pdu_type = bytes[offset]
 
         sms.pdu_mti = pdu_type & 0x03
-        sms.pdu_rp = pdu_type & 0x80 != 0
-        sms.pdu_udhi = pdu_type & 0x40 != 0
-        sms.pdu_srr = pdu_type & 0x20 != 0
-        sms.pdu_sri = sms.pdu_srr
-        sms.pdu_vpf =  (pdu_type & 0x18)>>3
-        sms.pdu_rd = pdu_type & 0x04 != 0
-        sms.pdu_mms = sms.pdu_rd
+        if sms.type == "sms-deliver" or sms.type == "sms-submit":
+            sms.pdu_rp = pdu_type & 0x80 != 0
+            sms.pdu_udhi = pdu_type & 0x40 != 0
+            sms.pdu_srr = pdu_type & 0x20 != 0
+            sms.pdu_sri = sms.pdu_srr
+            sms.pdu_vpf =  (pdu_type & 0x18)>>3
+            sms.pdu_rd = pdu_type & 0x04 != 0
+            sms.pdu_mms = sms.pdu_rd
+        elif sms.type == "sms-submit-report":
+            sms.pdu_udhi = pdu_type & 0x04 != 0
 
         offset += 1
-        if sms.pdu_mti == 1:
+        if sms.type == "sms-submit":
             # MR - Message Reference
             sms.mr = bytes[offset]
             offset += 1
 
         # OA/DA - Originating or Destination Address
         # WARNING, the length is coded in digits of the number, not in octets occupied!
-        oa_len = 1 + (bytes[offset] + 1) / 2
-        offset += 1
-        sms.oa = PDUAddress.decode( bytes[offset:offset+oa_len] )
-        sms.da = sms.oa
+        if sms.type == "sms-submit" or sms.type == "sms-deliver":
+            oa_len = 1 + (bytes[offset] + 1) / 2
+            offset += 1
+            sms.oa = PDUAddress.decode( bytes[offset:offset+oa_len] )
+            sms.da = sms.oa
 
-        offset += oa_len
-        # PID - Protocol identifier
-        sms.pid = bytes[offset]
+            offset += oa_len
+            # PID - Protocol identifier
+            sms.pid = bytes[offset]
 
-        offset += 1
-        # DCS - Data Coding Scheme
-        sms.dcs = bytes[offset]
+            offset += 1
+            # DCS - Data Coding Scheme
+            sms.dcs = bytes[offset]
 
-        offset += 1
-        if sms.pdu_mti == 0:
+            offset += 1
+
+        if sms.type == "sms-submit-report":
+            pi = bytes[offset]
+            offset += 1
+
+            sms.pdu_pidi = pi & 0x01 != 0
+            sms.pdu_dcsi = pi & 0x02 != 0
+            sms.pdu_udli = pi & 0x04 != 0
+
+
+        if sms.type == "sms-deliver" or sms.type == "sms-submit-report":
             # SCTS - Service Centre Time Stamp
             sms.scts = decodePDUTime( bytes[offset:offset+7] )
             offset += 7
-        else:
+        elif sms.type == "sms-submit":
             # VP - Validity Period FIXME
             if sms.pdu_vpf == 2:
                 # Relative
@@ -158,14 +173,17 @@ class SMS(object):
                 sms.vp = decodePDUTime( bytes[offset:offset+7] )
                 offset += 7
 
+        if sms.type == "sms-submit-report" and not sms.pdu_udli:
+            return sms
+
         # UD - User Data
         ud_len = bytes[offset]
         offset += 1
         sms._parse_userdata( ud_len, bytes[offset:] )
         return sms
 
-    def __init__( self, direction ):
-        self.direction = direction
+    def __init__( self, type ):
+        self.type = type
         self.sca = False
         self.pdu_udhi = False
         self.pdu_srr = False
@@ -296,19 +314,15 @@ class SMS(object):
     dcs = property( _getDCS, _setDCS )
 
     def _getType( self ):
-        if self.direction == "MT":
-            map = TP_MTI_INCOMING
-        elif self.direction == "MO":
-            map = TP_MTI_OUTGOING
-        return map[self.pdu_mti]
+        return self.mtimap[self.pdu_mti]
 
     def _setType( self, smstype ):
         if TP_MTI_INCOMING.has_key(smstype):
-            self.direction = "MT"
-            self.pdu_mti = TP_MTI_INCOMING[smstype]
+            self.mtimap = TP_MTI_INCOMING
         elif TP_MTI_OUTGOING.has_key(smstype):
-            self.direction = "MO"
-            self.pdu_mti = TP_MTI_OUTGOING[smstype]
+            self.mtimap = TP_MTI_OUTGOING
+
+        self.pdu_mti = self.mtimap[smstype]
 
     type = property( _getType, _setType )
 
@@ -349,13 +363,14 @@ class SMS(object):
 
     def pdu( self ):
         pdubytes = []
-        if self.sca:
-            scabcd = self.sca.pdu()
-            # SCA has non-standard length
-            scabcd[0] = len( scabcd ) - 1
-            pdubytes.extend( scabcd )
-        else:
-            pdubytes.append( 0 )
+        if self.type == "sms-deliver" or self.type == "sms-submit":
+            if self.sca:
+                scabcd = self.sca.pdu()
+                # SCA has non-standard length
+                scabcd[0] = len( scabcd ) - 1
+                pdubytes.extend( scabcd )
+            else:
+                pdubytes.append( 0 )
 
         pdu_type = self.pdu_mti
         if self.pdu_rp:
@@ -372,36 +387,45 @@ class SMS(object):
 
         pdubytes.append( pdu_type )
 
-        if self.pdu_mti == 1:
+        if self.type == "sms-submit":
             pdubytes.append( self.mr )
 
-        pdubytes.extend( self.oa.pdu() )
-
-        pdubytes.append( self.pid )
+        if self.type == "sms-deliver" or self.type == "sms-submit":
+            pdubytes.extend( self.oa.pdu() )
+
+        if self.type == "sms-deliver" or self.type == "sms-submit":
+            pdubytes.append( self.pid )
+
+        if self.type == "sms-deliver" or self.type == "sms-submit":
+            # We need to check whether we can encode the message with the
+            # GSM default charset now, because self.dcs might change
+            if not self.dcs_alphabet is None:
+                try:
+                    pduud = self.ud.encode( self.dcs_alphabet )
+                except UnicodeError:
+                    self.dcs_alphabet = "utf_16_be"
+                    pduud = self.ud.encode( self.dcs_alphabet )
+            else:
+                pduud = self.ud
 
-        # We need to check whether we can encode the message with the
-        # GSM default charset now, because self.dcs might change
-        if not self.dcs_alphabet is None:
-            try:
-                pduud = self.ud.encode( self.dcs_alphabet )
-            except UnicodeError:
-                self.dcs_alphabet = "utf_16_be"
-                pduud = self.ud.encode( self.dcs_alphabet )
-        else:
-            pduud = self.ud
+        if self.type == "sms-deliver" or self.type == "sms-submit":
+            pdubytes.append( self.dcs )
 
-        pdubytes.append( self.dcs )
+        if self.type == "sms-submit-report":
+            pdubytes.append( 0 )
 
-        if self.pdu_mti == 0:
+        if self.type == "sms-deliver" or self.type == "sms-submit-report":
             pdubytes.extend( encodePDUTime( self.scts ) )
-        else:
+        elif self.type == "sms-submit":
             if self.pdu_vpf == 2:
                 pdubytes.append( self.vp )
             elif self.pdu_vpf == 3:
                 pdubytes.append( encodePDUTime( self.vp ) )
 
-        # User data
+        if self.type == "sms-submit-report" and not self.pdu_udli:
+            return "".join( [ "%02X" % (i) for i in pdubytes ] )
 
+        # User data
         if self.udhi:
             pduudh = flatten([ (k, len(v), v) for k,v in self.udh.items() ])
             pduudhlen = len(pduudh)
@@ -431,8 +455,9 @@ class SMS(object):
     def serviceCenter( self ):
         pass
     def __repr__( self ):
-        if self.pdu_mti == 0:
-            return """MT SMS:
+        if self.type == "sms-deliver":
+            return """SMS:
+Type: %s
 ServiceCenter: %s
 TimeStamp: %s
 PID: 0x%x
@@ -441,9 +466,10 @@ Number: %s
 Headers: %s
 Alphabet: %s
 Message: %s
-""" % (self.sca, self.scts, self.pid, self.dcs, self.oa, self.udh, self.dcs_alphabet, repr(self.ud))
-        else:
-            return """MO SMS:
+""" % (self.type, self.sca, self.scts, self.pid, self.dcs, self.oa, self.udh, self.dcs_alphabet, repr(self.ud))
+        elif self.type == "sms-submit":
+            return """SMS:
+Type: %s
 ServiceCenter: %s
 Valid: %s
 PID: 0x%x
@@ -452,7 +478,12 @@ Number: %s
 Headers: %s
 Alphabet: %s
 Message: %s
-""" % (self.sca, self.pdu_vpf, self.pid, self.dcs, self.oa, self.udh, self.dcs_alphabet, repr(self.ud))
+""" % (self.type, self.sca, self.pdu_vpf, self.pid, self.dcs, self.oa, self.udh, self.dcs_alphabet, repr(self.ud))
+        elif self.type == "sms-submit-report":
+            return """SMS:
+Type: %s
+TimeStamp: %s
+""" % (self.type, self.scts)
 
 class CellBroadcast(SMS):
     @classmethod
@@ -650,10 +681,13 @@ if __name__ == "__main__":
             print "%s, PDU was: %s\n" % (e, pdu)
 
     for pdu in pdus_MT:
-        testpdu(pdu, "MT")
+        testpdu(pdu, "sms-deliver")
 
     for pdu in pdus_MO:
-        testpdu(pdu, "MO")
+        testpdu(pdu, "sms-submit")
+
+    for pdu in pdus_ACKPDU:
+        testpdu(pdu, "sms-submit-report")
 
     for pdu in pdus_CB:
         cb = CellBroadcast.decode(pdu)
diff --git a/framework/subsystems/ogsmd/helpers.py b/framework/subsystems/ogsmd/helpers.py
index 257a17c..32d6f57 100644
--- a/framework/subsystems/ogsmd/helpers.py
+++ b/framework/subsystems/ogsmd/helpers.py
@@ -109,6 +109,12 @@ class BiDict( object ):
         else:
             return self._d.keys() + self._back.keys()
 
+    def has_key( self, k ):
+        if not self.AUTOINVERSE:
+            return self._d.has_key(k)
+        else:
+            return self._d.has_key(k) + self._back.has_key(k)
+
 #=========================================================================#
 def processIterator():
 #=========================================================================#        
diff --git a/framework/subsystems/ogsmd/modems/abstract/mediator.py b/framework/subsystems/ogsmd/modems/abstract/mediator.py
index 778cebd..476d5d0 100644
--- a/framework/subsystems/ogsmd/modems/abstract/mediator.py
+++ b/framework/subsystems/ogsmd/modems/abstract/mediator.py
@@ -854,9 +854,9 @@ class SimRetrieveMessagebook( SimMediator ):
                     index = int(header.groupdict()["index"])
                     status = const.SMS_PDU_STATUS_OUT[int(header.groupdict()["status"])]
                     if "read" in status:
-                      direction = "MT"
+                      direction = "sms-deliver"
                     else:
-                      direction = "MO"
+                      direction = "sms-submit"
                     length = int(header.groupdict()["pdulen"])
                 else:
                     # Now we decode the actual PDU
@@ -885,9 +885,9 @@ class SimRetrieveMessage( SimMediator ):
                     header = const.PAT_SMS_PDU_HEADER_SINGLE.match( self._rightHandSide(line) )
                     status = const.SMS_PDU_STATUS_OUT[int(header.groupdict()["status"])]
                     if "read" in status:
-                      direction = "MT"
+                      direction = "sms-deliver"
                     else:
-                      direction = "MO"
+                      direction = "sms-submit"
                     length = int(header.groupdict()["pdulen"])
                 else:
                     # Now we decode the actual PDU
@@ -908,7 +908,7 @@ class SimSetServiceCenterNumber( SimMediator ):
 class SimStoreMessage( SimMediator ):
 #=========================================================================#
     def trigger( self ):
-        sms = ogsmd.gsm.sms.SMS("MO")
+        sms = ogsmd.gsm.sms.SMS("sms-submit")
         sms.pdu_mti = 1
         sms.pid = 0
         sms.dcs = 0
@@ -956,7 +956,7 @@ class SimDeleteMessage( SimMediator ):
 class SmsSendMessage( SmsMediator ):
 #=========================================================================#
     def trigger( self ):
-        sms = ogsmd.gsm.sms.SMS("MO")
+        sms = ogsmd.gsm.sms.SMS("sms-submit")
         sms.pdu_mti = 1
         sms.pid = 0
         sms.dcs = 0
diff --git a/framework/subsystems/ogsmd/modems/abstract/unsolicited.py b/framework/subsystems/ogsmd/modems/abstract/unsolicited.py
index c02dada..0d3e8a1 100644
--- a/framework/subsystems/ogsmd/modems/abstract/unsolicited.py
+++ b/framework/subsystems/ogsmd/modems/abstract/unsolicited.py
@@ -130,7 +130,7 @@ class AbstractUnsolicitedResponseDelegate( object ):
         header = safesplit( righthandside, ',' )
         length = int(header[1])
         # Now we decode the actual PDU
-        sms = ogsmd.gsm.sms.SMS.decode( pdu, "MT" )
+        sms = ogsmd.gsm.sms.SMS.decode( pdu, "sms-deliver" )
         self._object.IncomingMessage( str(sms.oa), sms.ud, sms.featureMap )
 
     # +CMTI: "SM",7

-- 
FSO frameworkd Debian packaging



More information about the pkg-fso-commits mailing list