Interested SMS/Serial Programmer/Developers Resource

Polerio Babao Jr.II admin at polerio.com
Thu Oct 9 03:03:52 EDT 2003


file fbus3.py 
resource shared by Chris Liechti <cliechti at gmx.net>

during the 
[Nokia 3310 SMS Application, done:connecting to serial
port(linux/win), done:reading some hex like \x00 . . .,
problem:write/send command! noresponse]
conversation last september 2002. I made it available so that other
user would benefit from it. I've used with some of my projects and I'm
done with it. hope anyone would benefit from it

#------------------------------------------------------------------------------------------------

#!/usr/bin/env python

import serial, time, sys, Queue, threading

DEBUG = 0

FB_FRAME_ID = 0x1e
FB_DEVICE_PHONE = 0x00
FB_DEVICE_PC = 0x0c

#FB_FRAME_HEADER = '\x00\x01\x00'

FB_SYNC_BYTE  = '\x55'
FB_IR_END_INIT_BYTE  = '\xc1'
FB_FRTYPE_ACK = 0x7f

##/* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
##/* Characters in hex position 10, [12 to 1a] and 24 are not present
on
##   latin1 charset, so we cannot reproduce on the screen, however
they are
##   greek symbol not present even on Nokia */
GSM_Default_Alphabet = ''.join([
    '@',  '\xa3', '$',  '\xa5','\xe8','\xe9','\xf9','\xec', 
   '\xf2','\xc7', '\n', '\xd8','\xf8', '\r', '\xc5','\xe5',
    '?',   '_',   '?',   '?',   '?',   '?',   '?',   '?',
    '?',   '?',   '?',   '?',  '\xc6','\xe6','\xdf','\xc9',
    ' ',   '!',   '\"',  '#',  '\xa4', '%',   '&',   '\'',
    '(',   ')',   '*',   '+',   ',',   '-',   '.',   '/',
    '0',   '1',   '2',   '3',   '4',   '5',   '6',   '7',
    '8',   '9',   ':',   ';',   '<',   '=',   '>',   '?',
   '\xa1', 'A',   'B',   'C',   'D',   'E',   'F',   'G',
    'H',   'I',   'J',   'K',   'L',   'M',   'N',   'O',
    'P',   'Q',   'R',   'S',   'T',   'U',   'V',   'W',
    'X',   'Y',   'Z', '\xc4', '\xd6','\xd1','\xdc','\xa7',
   '\xbf', 'a',   'b',   'c',   'd',   'e',   'f',   'g',
    'h',   'i',   'j',   'k',   'l',   'm',   'n',   'o',
    'p',   'q',   'r',   's',   't',   'u',   'v',   'w',
    'x',   'y',   'z', '\xe4', '\xf6','\xf1','\xfc','\xe0'
])

def bin(x):
    return ''.join([((x & (1<<i)) and '1' or '0') for i in range(8)])

def rev(x):
    m = list(x)
    m.reverse()
    return ''.join(m)

class Version:
    def __init__(self, value):
        self.version, self.date, self.firmware, self.copy =
value.split('\n')
    def __str__(self):
        return "%s %s %s %s" % (self.version, self.date,
self.firmware, self.copy)

class SMS:
    def __init__(self, message=""):
        #8bit packed -> 7 bit decode
        bs = ''.join([bin(ord(x)) for x in message])
        #print len(message), len(bs)
        self.message = ''.join([chr(int(rev(bs[x:x+7]), 2)) for x in
range(0, len(bs), 7)])

    def __str__(self):
        return "%r" % (self.message)

class PhonebookEntry:
    def __init__(self, name, number):
        self.name = name
        self.number = number
        
    def __str__(self):
        return "%s: %s" % (self.name, self.number)
        
class Phone:
    def __init__(self, comport=1):
        self.s = serial.Serial(comport, 115200, timeout=None)
        self.seq = 0
        self.s.setRTS(0)  #hehe - NEEDED! whatever insane comm the
have desigend? 8-)
        self.sync()
        self.s.flushInput()   #err character/power up garabge ?!?
        self.queue = Queue.Queue()
        self.thread = threading.Thread(target=self._recvThread)
        self.thread.setDaemon(1)
        self.thread.start()
        
    def sync(self):
        if DEBUG: print "sync...",
        for i in range(32):
            time.sleep(0.01)
            self.s.write(FB_SYNC_BYTE)    #sync char
        self.s.write(FB_IR_END_INIT_BYTE)     #sync end char
        self.FB_TX_SendMessage(0x04, '\x00\x01\x00\x01');
        if DEBUG: print "ok"

    def getVersion(self):
        if DEBUG: print "get ver..."
        self.FB_TX_SendMessage(0xd1, '\x00\x01\x00\x03\x00')
        return self.queue.get()

    def getPhonbookEntry(self, num):
        if DEBUG: print "Get Phonebook %d" % num
        self.FB_TX_SendMessage(0x03, '\x00\x01\x00\x01\x01%c\x00' %
num)
        return self.queue.get()
    
    def getSMS(self, num):
        if DEBUG: print "Get SMS message %d" % num
        self.FB_TX_SendMessage(0x02, '\x00\x01\x00\x07\x02%c\x01\x64'
% num)
        return self.queue.get()


    def _recvThread(self):
        """receive packets, sequences are collected before handling"""
        buffer = ''
        while 1:
            if DEBUG: print "receive header"
            head = self.s.read(6)                           #get
header
            log.write("receive header: %r\n" % (head)) 
            
            FrameID, DestDEV, SrcDEV, MsgType, _, FrameLength =
map(ord, head)
            if DEBUG: 
            		print "receive frame data", FrameLength
            		print FrameID, DestDEV, SrcDEV, MsgType, FrameLength
            data = self.s.read(FrameLength-2)                 #get
data
            log.write("receive data: %r\n" % (data)) 
            if DEBUG: print "receive data", data
            framecount, seqNum = map(ord, self.s.read(2))
            if FrameLength & 1: self.s.read(1)      #kill pad byte
            if DEBUG: print "receive checksum"
            ChkSum1, ChkSum2 = map(ord, self.s.read(2))     #get
checksum
            if self.s.inWaiting(): print "!!still chars in"
            #print "framecount %0x" % framecount
            if FrameID == 0x1e and DestDEV == 0x0c and SrcDEV == 0x00:
                if framecount > 1:              #multiple blocks
                    buffer += data
                else:                           #last block
                    buffer += data
                    self.dispatchPhone(MsgType, buffer)
                    buffer = ''
                self.FB_TX_SendAck(MsgType, seqNum & 0x0f)  #gen ACK
for msgtype / seq
            else:
                if DEBUG: print "message not from phone"
                buffer = ''

    #message handler
    def dispatchPhone(self, MsgType, block):
        """decode messages from the phone"""
        if DEBUG: print "dispatchPhone(%r, %r)" % (MsgType, block)
        #log.write("MsgType: 0x%02x block: %r\n" % (MsgType, block))  
 #logging
        if MsgType == 0x7f:     #ack
            if DEBUG: print "Received Ack of type 0x%02x, seq: 0x%02x"
% (ord(block[0]), ord(block[1]))
        elif MsgType == 0xd2:     #HW&SW version
            if DEBUG: print "VER: %s" % block[4:-1] #0x0003 "V "
"firmware\n" "firmware date\n"  "model\n" "(c) NMP."
            self.queue.put(Version(block[4:-1]))
            return 1
        elif MsgType == 0x14:     #SMS functions
            if block[3] == '\x08':  #receiving message
                smstype = ord(block[7])
                if smstype == 0x02:
                    if DEBUG: print "outbox"
                else:
                    if DEBUG: print "inbox"
                
            if DEBUG: print "SMS: %r" % block
            #self.queue.put(SMS(block.translate(GSM_Default_Alphabet)))
#?
            self.queue.put(SMS(block[43:]))
            return 1
        elif MsgType == 0x03:     #Phonebook functions
            #r mem location recvd    { 0x0002,
0x00,namelen,"name",numlen,"number",groupID, 0x01?, yearLO, yearHI,
month, day, hour, minute, sec. }
            #                    Note: in 3310 all entries have null
name ("feature" or bug ?)
            if block[3] == '\x02':    #r mem location recvd
                namelen = ord(block[5])
                name = block[6:6+namelen]
                numlen = ord(block[6+namelen])
                number = block[6+namelen+1:6+namelen+1+numlen]
                self.queue.put(PhonebookEntry(name, number))
                if DEBUG: print "PHONE entry: %s: %s" % (name, number)
            else:
                if DEBUG: print "PHONE unknown: %r" % block #
            return 1
        else:
            print "unhandled frame 0x%02x: %r" % (MsgType, block)

    def FB_TX_SendAck(self, message_type,  message_seq):
        if DEBUG: print "send ack..."
        return self.FB_TX_SendFrame(FB_FRTYPE_ACK, "%c%c" %
(message_type, message_seq))

    def FB_TX_SendFrame(self, message_type, buffer):
        frame = "%c%c%c%c%c%c%s" % (
            FB_FRAME_ID, FB_DEVICE_PHONE, FB_DEVICE_PC, message_type,
0, len(buffer), buffer
        )

        if len(buffer) & 1:  #align on words
            frame += '\x00'

        crce = crco = 0
        for i in range(0,len(frame),2):
            crce ^= ord(frame[i]);
            crco ^= ord(frame[i+1]);
        frame += chr(crce) + chr(crco)
        log.write("drop to pipe: %r\n" % (frame)) 
        self.s.write(frame)

    def FB_TX_SendMessage(self, message_type, block=''):
        time.sleep(0.2)
        frame_buffer = "%s%c%c" % (block, 0x01, 0x40+self.seq)
        self.seq = (self.seq+1) & 0x7
        self.FB_TX_SendFrame(message_type, frame_buffer)

#----------------------------------------------------------------------------
if __name__ == '__main__':
    

    log = open("log3.txt","w")    
	
    p = Phone()
    pg = p.getVersion()
    print "Version: %s" % pg    
    log.write("Version: %s\n--------------------------------------\n"
% pg)
    for i in range(1,5):
        pb = p.getPhonbookEntry(i)
        print "Phonebook(%d): %s" % (i, pb)  
        log.write("Phonebook(%d):
%s\n--------------------------------------\n" % (i, pb))
    for i in range(1,5):
        sm = p.getSMS(i)
        print "SMS(%d): %s" % (i, sm)
        log.write("SMS(%d):
%s\n--------------------------------------\n" % (i, sm))
    

#------------------------------------------------------------------------------------------------




More information about the Python-list mailing list