View Single Post
Posts: 451 | Thanked: 334 times | Joined on Sep 2009
#47
A programmer has modified the script for me to accept commandline arguments, to send an SMS, so:
Code:
#!/usr/bin/python

import dbus
import sys

def octify(str):
    '''     
    Returns a list of octet bytes representing
    each char of the input str.               
    '''                                       

    bytes = map(ord, str)
    bitsconsumed = 0     
    referencebit = 7     
    octets = []          

    while len(bytes):
            byte = bytes.pop(0)
            byte = byte >> bitsconsumed
                                       
            try:
                    nextbyte = bytes[0]
                    bitstocopy = (nextbyte & (0xff >> referencebit)) << referencebit
                    octet = (byte | bitstocopy)

            except:
                    octet = (byte | 0x00)

            if bitsconsumed != 7:
                    octets.append(byte | bitstocopy)
                    bitsconsumed += 1
                    referencebit -= 1
            else:
                    bitsconsumed = 0
                    referencebit = 7

    return octets

def semi_octify(str):
    '''
    Expects a string containing two digits.
    Returns an octet -
    first nibble in the octect is the first
    digit and the second nibble represents
    the second digit.
    '''
    try:
            digit_1 = int(str[0])
            digit_2 = int(str[1])
            octet = (digit_2 << 4) | digit_1
    except:
            octet = (1 << 4) | digit_1

    return octet

def resetnumber(number):
        '''
        Adds trailing F to number if length is
        odd.
        '''
        length = len(number)
        if (length % 2) != 0:
            number = number + 'F'
        return number

def createPDUstring(number, msg):
    '''
    Returns a list of bytes to represent a valid PDU message
    '''
    octifiedmsg = octify(msg)
    number = resetnumber(number)
    octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0, len(number), 2) ]
        
    HEADER = 1
    FIRSTOCTETOFSMSDELIVERMSG = 10
    ADDR_TYPE = 129 #unknown format
    number_length = len(number)
    msg_length = len(msg)
    pdu_message = [HEADER, FIRSTOCTETOFSMSDELIVERMSG, number_length, ADDR_TYPE]
    pdu_message.extend(octifiednumber)
    pdu_message.append(0)
    pdu_message.append(0)
    pdu_message.append(msg_length)
    pdu_message.extend(octifiedmsg)
    return pdu_message

class SMS(object):
    '''
    Sends sms messages 
    '''
    
    def __init__(self, msg, number):
        self.pdustring = createPDUstring(number, msg)
        
    def send(self):
        self.__dbus_send(self.pdustring)

    def __dbus_send(self, pdu_string):
        import dbus
        bus = dbus.SystemBus()
        smsobject = bus.get_object('com.nokia.phone.SMS', '/com/nokia/phone/SMS/ba212ae1')
        smsiface = dbus.Interface(smsobject, 'com.nokia.csd.SMS.Outgoing')
        arr = dbus.Array(pdu_string)
        msgdeliver = dbus.Array([arr]) 
        smsiface.Send(msgdeliver,'')
        
    def print_pdustring(self):
        print self.pdustring        

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print "usage %s number message" % sys.argv[0]
    else:
        sms = SMS(sys.argv[2], sys.argv[1])
        sms.send()
        print "sending sms..."
However, when you use an international format with the leading plus like: "+XXX" for the number, it bombs with:
Code:
Traceback (most recent call last):
  File "./send_sms.py", line 114, in <module>
    sms = SMS(sys.argv[2], sys.argv[1])
  File "./send_sms.py", line 93, in __init__
    self.pdustring = createPDUstring(number, msg)
  File "./send_sms.py", line 72, in createPDUstring
    octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,
  len(number), 2) ]
  File "./send_sms.py", line 52, in semi_octify
    octet = (1 << 4) | digit_1
UnboundLocalError: local variable 'digit_1' referenced before assignment
When you use two leading zeros like "00XXXX..." it doesn't bomb, but the SMS is not received, therefore probably not sent.

It seems the problem is with the PDU encoding. Anyone got the above (prior) script to actually send an SMS? Where is the problem?