Notices


Reply
Thread Tools
Posts: 14 | Thanked: 18 times | Joined on Dec 2009
#21
Originally Posted by pende View Post
Thanks for your reply, I tried it but with no success. Where should I put phone number and message?
Hi Pende,

In test.py, there is ths line:
arr = dbus.Array(smsutil.createPDUmessage('31201516','Th is'))
replace the first argument with the receiver's number and the second argument with your message.

Note: I hope the length of your phone number is 'even' otherwise it will not work because the code in smsutil.py expects the length of the number to be even and not odd. If length is odd, then you might have to change smsutil.py a bit. Also check http://www.dreamfabric.com/sms/ for an explanation on the phone number.

regards,
shaun

Last edited by shaunramos; 2009-12-29 at 01:08.
 
Posts: 8 | Thanked: 7 times | Joined on Dec 2009 @ London
#22
My files:


Code:
#!/usr/bin/env python2.5

import dbus
import smsutil

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(smsutil.createPDUmessage('077197xxxxx','This'))
#arr = dbus.Array([dbus.Byte(1),dbus.Byte(10),dbus.Byte(8),dbus.Byte(129),dbus.Byte(129),dbus.Byte(19),dbus.Byte(2),dbus.Byte(81),dbus.Byte(97),dbus.Byte(0),dbus.Byte(0),dbus.Byte(4),dbus.Byte(84),dbus.Byte($
msg = dbus.Array([arr])
smsiface.Send(msg,'')

Code:
#!/usr/bin/env python2.5

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)
			octets.append(octet)
		except IndexError:
			octets.append(byte)
		
		bitsconsumed += 1
		referencebit -= 1
	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.
		'''
		
		digit_1 = int(str[0])
		digit_2 = int(str[1])	
		octet = (digit_2 << 4) | digit_1
		return octet

def createPDUmessage(number, msg):
        '''
        Returns a list of bytes to represent a valid PDU message
        '''
        octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,8,2) ]
        octifiedmsg = octify(msg)
        HEADER = 1
        FIRSTOCTETOFSMSDELIVERMSG = 10 
        ADDR_TYPE = 129 #unknown format
        number_length = len(number)
        msg_length = len(octifiedmsg)
        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

if __name__ == '__main__':
    print createPDUmessage('077197xxxxx', 'This')

when I do
./test.py
script executes but nothing happens, I don't get any sms on my second phone.

If I change second parameter from This to something different I get this

Code:
./test.py
Traceback (most recent call last):
  File "./test.py", line 9, in <module>
    arr = dbus.Array(smsutil.createPDUmessage('077197xxxxx','test message'))
  File "/root/smsutil.py", line 47, in createPDUmessage
    octifiedmsg = octify(msg)
  File "/root/smsutil.py", line 18, in octify
    bitstocopy = (nextbyte & (0xff >> referencebit)) << referencebit
ValueError: negative shift count
any ideas?
 
Posts: 14 | Thanked: 18 times | Joined on Dec 2009
#23
Two things:
1. My code does not handle odd phone number length and in fact, it can only handle 8-digit numbers. My bad.
2. The negative shift count is another error in my code but i have fixed it.

I have just done some quick changes to the code and have not fully validated it but could you please try this:

smsutil.py:

Code:
#!/usr/bin/env python2.5
import sched, time
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)
			octets.append(octet)
		except:
			octets.append(byte)
		bitsconsumed += 1
		referencebit -= 1
		if referencebit == 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 createPDUmessage(number, msg):
	'''
	Returns a list of bytes to represent a valid PDU message
	'''
	numlength = len(number)
	if (numlength % 2) == 0:
		rangelength = numlength
	else:
		number = number + 'F'
		rangelength = len(number)

	octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,rangelength,2) ]
	octifiedmsg = octify(msg)
	HEADER = 1
	FIRSTOCTETOFSMSDELIVERMSG = 10 
	ADDR_TYPE = 129 #unknown format
	number_length = len(number)
	msg_length = len(octifiedmsg)
	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

Last edited by shaunramos; 2009-12-29 at 02:53.
 
Posts: 8 | Thanked: 7 times | Joined on Dec 2009 @ London
#24
Hi shaunramos,

I have tested your code and now It works. I tried with different messages and with short messages (several chars) it works perfect but with longer I got something like this on my second phone

Sent message: test test test
Received message: test tes@@@èéΓ

Sent message: this is long test message
Received message: this is @@¥ùì@4e@@@@é3s@
 
Posts: 14 | Thanked: 18 times | Joined on Dec 2009
#25
Originally Posted by pende View Post
Hi shaunramos,

I have tested your code and now It works. I tried with different messages and with short messages (several chars) it works perfect but with longer I got something like this on my second phone

Sent message: test test test
Received message: test tes@@@èéΓ

Sent message: this is long test message
Received message: this is @@¥ùì@4e@@@@é3s@
Hi Pende,

It happened to me too. I have to fix the part where it transforms the message string to octets. I will get back to you wheni have fixed it today.
 

The Following 3 Users Say Thank You to shaunramos For This Useful Post:
Posts: 8 | Thanked: 7 times | Joined on Dec 2009 @ London
#26
Hi,
I added this

if bitsconsumed == 7:
bitsconsumed = 0

into smsutil.py and now I noticed that it sends all the message but it duplicate first char every eighth run

abcdefghijklmnopqrstuvwxyz0123456789
abcdefghhijklmnoopqrstuvvwxyz012234
 
Posts: 8 | Thanked: 7 times | Joined on Dec 2009 @ London
#27
I am posting working code

test.py

Code:
#!/usr/bin/env python2.5

import dbus
import smsutil
import sys

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(smsutil.createPDUmessage('004477xxxxxxxx','hello world!'))

msg = dbus.Array([arr])
smsiface.Send(msg,'')
smsutil.py

Code:
#!/usr/bin/env python2.5          
import sched, time                

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 createPDUmessage(number, msg):
        '''
        Returns a list of bytes to represent a valid PDU message
        '''
        numlength = len(number)
        if (numlength % 2) == 0:
                rangelength = numlength
        else:
                number = number + 'F'
                rangelength = len(number)

        octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,rangelength,2) ]
        octifiedmsg = octify(msg)
        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
 

The Following 5 Users Say Thank You to pende For This Useful Post:
Posts: 19 | Thanked: 2 times | Joined on Dec 2009
#28
Thanks Pende and Shaunramos!

Works perfectly, now to just add cli argument handling to accept phone# and message
 
Posts: 8 | Thanked: 7 times | Joined on Dec 2009 @ London
#29
Hi Houz,

I am working on it. I will publish code when ready
 
Posts: 14 | Thanked: 18 times | Joined on Dec 2009
#30
Hi Pende and Houz,

I have updated the script with changes from Pende (thanks Pende for the help). Now, all the code is in one script - sms.py. The script now would ask for the number and the message and can also schedule sending. Updated script is right here:
http://www.paraiso.dk/pymaemosms.txt.

regards,
shaun
 

The Following 6 Users Say Thank You to shaunramos For This Useful Post:
Reply


 
Forum Jump


All times are GMT. The time now is 16:22.