Script python para enviar SMS en GSM (Telcel, Movistar)

Existen excelentes programas para enviar SMS desde el escritorio como Wammu, entre otros.

¿Pero, que sucede si se desea enviar SMS desde aplicaciones incrustadas (¿embebidas?), o simplemente se requiere mas grado de control?

El siguiente script envia SMS via puerto serial virtual Bluetooth, codificando el texto en modo PDU.
Es importante mencionar que el modo texto para envío de SMS (que es mucho mas sencillo de implementar) no siempre está disponible en todas las terminales.

El código es muy perfectible, solamente cuenta con un manejo básico de errores y no está muy a la “manera pythonica”, pero por otra parte, funciona con todo el alfabeto GSM de 7 bits y permite enviar caracteres no ingleses, como la ñ y Ñ.

Si resulta de interés, posteriormente pondré a su consideración, otras formas de codificación SMS como la UTF (que es la razón de que en ocasiones las compañías celulares nos cobren varios SMS por envío por los mismos 160 caracteres). Codificar UTF requiere modo PDU hasta donde mi conocimiento me permite saber.

Bienvenidos los comentarios, quejas y sugerencias a Idea Versátil

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# Python script to send SMS in PDU MODE.
# It is using 7 bit default alphabet as specified by GSM 03.38, even chars as ñ or Ñ
# Check www.ideaversatil.com for comments. Script provided as is. NO WARRANTIES OF ANY KIND!!!
 
import string
from time import sleep
import serial
 
def reverseMe(s):
    return s[::-1]
 
def int2bin(n, count=24):
    # (int2bin Author: adomas) http://www.sourcesnippets.com/python-decimal-to-binary-conversion.html
    return "".join([str((n >> y) & 1) for y in range(count-1, -1, -1)])
 
def bin2hex(b):
    return ( "%X" % int(b,2) ).zfill(2)
 
gsm7 = {'@':'0', u'£':'1', '$':'2', u'¥':'3', u'è':'4', u'é':'5', u'ù':'6', u'ì':'7', u'ò':'8', u'Ç':'9', '\n':'10', u'Ø':'11', u'ø':'12', '\r':'13', u'Å':'14', u'å':'15', u'Δ':'16', '_':'17', u'Φ':'18', u'Γ':'19', u'Λ':'20', u'Ω':'21', u'Π':'22', u'Ψ':'23', u'Σ':'24', u'Θ':'25', u'Ξ':'26', '\f':'27##10', '^':'27##20', '{':'27##40', '}':'27##41', '\\':'27##47', '[':'27##60', '~':'27##61', ']':'27##62', '|':'27##64', u'€':'27##101', u'Æ':'28', u'æ':'29', u'ß':'30', u'É':'31', ' ':'32', u'!':'33', '"':'34', '#':'35', u'¤':'36', '%':'37', '&':'38', '\'':'39', '(':'40', ')':'41', '*':'42', '+':'43', ',':'44', '-':'45', '.':'46', '/':'47', '0':'48', '1':'49', '2':'50', '3':'51', '4':'52', '5':'53', '6':'54', '7':'55', '8':'56', '9':'57', ':':'58', ';':'59', '<':'60', '=':'61', '>':'62', '?':'63', u'¡':'64', 'A':'65', 'B':'66', 'C':'67', 'D':'68', 'E':'69', 'F':'70', 'G':'71', 'H':'72', 'I':'73', 'J':'74', 'K':'75', 'L':'76', 'M':'77', 'N':'78', 'O':'79', 'P':'80', 'Q':'81', 'R':'82', 'S':'83', 'T':'84', 'U':'85', 'V':'86', 'W':'87', 'X':'88', 'Y':'89', 'Z':'90', u'Ä':'91', u'Ö':'92', u'Ñ':'93', u'Ü':'94', u'§':'95', u'¿':'96', 'a':'97', 'b':'98', 'c':'99', 'd':'100', 'e':'101', 'f':'102', 'g':'103', 'h':'104', 'i':'105', 'j':'106', 'k':'107', 'l':'108', 'm':'109', 'n':'110', 'o':'111', 'p':'112', 'q':'113', 'r':'114', 's':'115', 't':'116', 'u':'117', 'v':'118', 'w':'119', 'x':'120', 'y':'121', 'z':'122', u'ä':'123', u'ö':'124', u'ñ':'125', u'ü':'126', u'à':'127'}
rvphone = ""
i = 0
txtBin = ""
txtHex = ""
 
txt = unicode(raw_input("Text to send: "),'utf-8')
phone = raw_input("Phone number: ")
lensms = len(txt)
 
if (len(phone) % 2) > 0:
    phone = phone + "F"
 
while i < len(phone):
    rvphone += reverseMe(phone[i:i+2])
    i += 2
phone = rvphone
 
for c in reverseMe(txt):
 
    try:
         word = gsm7[c]
    except Exception, e:
        print '%s Not found, Exception: %s' % (c,e)
        word = '63' # Using ? as wildcard
    bytes = word.split('##')
 
    if len(bytes) > 1:
        txtBin += int2bin(int(bytes[1]),7)
        lensms += 1
    txtBin += int2bin(int(bytes[0]),7)
 
mlen = len(txtBin)
txt8 =  txtBin.zfill(mlen + (8 - mlen % 8))
mlen8 = len(txt8)
i = 0
 
while i < mlen8:
    txtHex = bin2hex(txt8[i:i+8]) + txtHex
    i += 8
#Composing GSM PDU
pdu = "001100"
pdu +=  ("%X" % len(phone)).zfill(2)
pdu +=  "81" + phone
pdu += "0000AA%s%s" % ( ("%X" % (lensms)).zfill(2),txtHex )
print "AT+CMGS=%s\n%s" % ((len(pdu) / 2) - 1 ,pdu.upper()) #Printing command to send sms
 
try:
    s = serial.Serial('/dev/rfcomm0', 9600, timeout=1)
    #AT commands tested successfully on Sony Ericsson, Nokia and Motorola terminals
    s.write('ATZ\r') # Back to default phone settings
    sleep(1)
    s.write('ATE=0\r') #Turn Off Local Echo
    sleep(1)
    s.write('AT+CPMS="ME","ME"\r')#Using Phone's Memory as workspace
    sleep(1)
    s.write('AT+CMGF=0\r') #Enabling PDU Mode. AT+CMGF=1 for Text Mode
    print "Sending..."
    sleep(1)
    s.write("AT+CMGW=%s\r" % ((len(pdu) / 2) - 1 )) #Writing SMS to phone instead of actually sending SMS (debug Mode),
                                                    #change this command to AT+CMGS when  you are ready to send SMS
    sleep(1)
    s.write(pdu.upper())
    s.write(chr(26)) # CTRL+Z
    sleep(1)
    print s.read(1024) #Reading phone answers
 
    s.close()
 
except Exception, e:
    print "Unable to open /dev/rfcomm0, Exception: %s" % e

Tags: , , , , , , , ,


6 votes, average: 4.00 out of 56 votes, average: 4.00 out of 56 votes, average: 4.00 out of 56 votes, average: 4.00 out of 56 votes, average: 4.00 out of 5 (6 votes, average: 4.00 out of 5)
You need to be a registered member to rate this post.
Loading...Loading...
Linux, Programacion, Sistemas Operativos, Tips técnicos | RSS 2.0 |     3,659 views

RSS feed

3 Comments »

Comment by shellbofh
2008-12-10 14:56:11

Oye POP, hay un error cuando se publican fuentes, en las condicionales cuando se usan simbolos como el “mayor que, menor que, ampersand” (>,<,&) se reemplaza por un gt; lt; amp; respectivamente, espero se pueda resolver pronto.. Saludos!!

Comment by El Pop
2008-12-10 15:25:12

Usa al insertar código la pestaña de HTML, cuando lo haces desde el “Visual”, traslitera los valores como mencionas

 
 
Comment by phylevn
2008-12-10 15:01:55

Interesante..

Aunque otra forma más fácil de hacerlo es usando Gnokii..

sudo apt-get install gnokii

echo “SMS con Gnokii” > gnokii –sendsms 0440102030405 -r

Y listo..

Por cierto aquí puse el código para poder enviar SMS desde una página web usando la interfaz de gnokii :

http://phylevn.mexrom.net/index.php/blog/show/Como_enviar_SMS_desde_una_pagina_web_en_Linux.html

 
Name (required)
E-mail (required - never shown publicly)
URI
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.

Trackback responses to this post