Sending SMS from command line
Let's send an SMS using USB 3G modem and Linux command line.
(If you have USB modem you may need the usbmodeswitch
package or something like it that can prepare the device to work as modem.)
Sending manully using minicom
First, install minicom
— terminal for serial communication:
# apt-get install usb-modeswitch
# apt-get install minicom
Now configure minicom:
$ minicom -s
Go to Serial port setup
and change device to one that works for your modem.
Now run minicom
without arguments and try these commands:
AT+CMGF=1
AT+CMGS="+123456789"
message
ctrl+z
The modem should send SMS "message" to the specificed number.
Sending using standard commands
You can do the same by using standard linux commands too:
# stty -F /dev/ttyUSB3 speed 9600 -brkint -icrnl ixoff -imaxbel -opost -onlcr -isig -icanon -echo -echoe
# tail -f /dev/ttyUSB3 &
# echo -e "AT+CMGF=1\r\n" > /dev/ttyUSB3
# echo -e "AT+CMGS=\"+123456789\"\r\n" > /dev/ttyUSB3
# echo -e "message\032\r\n" > /dev/ttyUSB3
What can easily be translated to sh-script.
Note the first line with stty
command. All data between computer and 3G modem are transfered through USB, so it looks like it's not necessary to set the speed and other options, but it is. So just stty
before your modem commands.
One problem here is that SMS can be sent in two modes: text and so called PDU (binary), and text SMSs are flash by default in my 3G modem at least and I couldn't figure out how to force these flash messages to be saved into flash phone memory...
Sending PDU SMS by script
So, here's a python script that send normal messages
#!/usr/bin/python
import os
import sys
import time
def dectobin(i):
b = ''
while i > 0:
j = i & 1
b = str(j) + b
i >>= 1
return b
def SendSMS(dev,number,text):
pdu_data = '00'
pdu_data += '11' #SMS-SUBMIT
pdu_data += '00' #TP-Message-Reference
pdu_data += '0B' #Address-Length
pdu_data += '91' #Address-Length
'''Convert telephone number'''
number += 'F'
pdu_number = ''
for i in range(0,len(number)):
if i%2==0:
continue
pdu_number += number[i] + number[i-1]
pdu_data += pdu_number
pdu_data += '00' #TP-Protocol identifier
pdu_data += '00' #TP-Data coding scheme
pdu_data += 'AA' #TP-Validity-Period
'''Convert text to binary format'''
pdu_text_bin = []
for i in text:
dec_s=ord(i)
if dec_s == 95:
dec_s = 17
if dec_s == 94:
dec_s = 1
if dec_s == 64:
dec_s = 0
if dec_s == 36:
dec_s = 2
if dec_s == 123:
dec_s = 40
if dec_s == 125:
dec_s = 41
if dec_s == 124:
dec_s = 64
if dec_s == 126:
dec_s = 61
if dec_s == 92:
dec_s = 47
if dec_s == 91:
dec_s = 60
if dec_s == 93:
dec_s = 62
bin = dectobin(dec_s)
le = len(bin)
while le<7:
bin='0'+bin
le = len(bin)
pdu_text_bin.append(bin)
'''Encode binary to PDU format'''
pdu_text_bin_cp = []
n=0
for i in range(0,len(text)):
if (i>0) & ((i+1)%8==0):
continue
n+=1
if n==8:
n=1
if i==len(text)-1:
cp = pdu_text_bin[i][0:8-n]
else:
cp = str(pdu_text_bin[i+1][7-n:7] + pdu_text_bin[i])[0:8]
pdu_text_bin_cp.append(cp)
'''Convert PDU to hex'''
pdu_text=''
for i in pdu_text_bin_cp:
hexi = str(hex(int(i,2)))[2:4].upper()
if len(hexi) == 1:
hexi = '0' + str(hexi)
pdu_text += hexi
'''Calculate text length'''
len_hex = hex(len(text))[2:4].upper()
if len(len_hex) == 1:
len_hex = '0' + str(len_hex)
'''Calculate PDU length'''
pdu_data+=len_hex+pdu_text
pdu_len = str(len(pdu_data)/2-1)
if True:
fd = os.open(dev, os.O_RDWR)
'''os.write(fd, "AT+CMGF=0 \015")'''
os.write(fd, "ATZ\r\n")
time.sleep(1)
os.write(fd, "AT+CMGF=0\r\n")
time.sleep(1)
os.write(fd, "AT+CMGS=" + pdu_len + "\r\n")
time.sleep(1)
os.write(fd, pdu_data + "\032\r\n")
os.close(fd)
def main(argv):
SendSMS("/dev/ttyUSB3",argv[1],argv[2])
return 0
if __name__ == '__main__': main(sys.argv)
Honestly i cant remember where i've found this crap, but it works.] It translates the message and its options into binary PDU structure and sends it to the modem with usual input/output commands (so it needs stty
too).
Good luck with smsing with your programs]
shitpoet@gmail.com