_______________________________________________________________________________________________________________________________
Home | Latest News | Download | developer info | Italian | Contact
_______________________________________________________________________________________________________________________________
Intro | Let's dig in | The TP-UD | Things you will need | my sourcecode
_______________________________________________________________________________________________________________________________
||||||||||||||||| SendMyStuff (Prototype0.1) |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Developer Information
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
If you find useful information here, and you want to say "Thank you",
then please do me a favour and click on my sponsor's banner. Its NOT
one of those neverending trick banners, just takes you to a freeware site.
Thanks.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ok, as I got so many interested emails from you, the developers out
there, I want to help you with doing an app like SendMyStuff your-
self, and maybe even much better. Hope you find everything you need
to understand the complex relation between the text you want to send
and the PDU the phone has to receive. But let me explain a few things
first:
1. I am not responsible for anything you do with this information. Please
accept any copyrights possibly attached to these documents, and
do not do anything with them you aren't allowed to ;-)
2. SendMyStuff is strictly nonprofit. The same applies to
publishing these links and documents here. If I am doing something
illegal here (maybe because I am not allowed to publish a certain
document here) please tell me immediately, and I will erase the link
or document in question.
3. My sourcecode, published further down on this page, is freely available
and I would be proud to find ideas of it in a professional app.
I do not earn my money by programming apps, I usually do those fancy
multimedia stuff you find everywhere, and websites, hopefully better
one than this here ;-)
But there's one thing I ask you to do: if you used this code, or any
information you found here, and it helped you, please send me a
version of the app you did, or an email telling me you did it. Thank you.
4. If you find any errors, think my english is terrible, or just wanna
chat find me on IRC-net as negg or email me.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Intro
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Why all that Stuff?
First let me explain why everything is so complicated, and why you can't
simply type a text on your computer and send it to your phone. I try to
explain in the way I finally understood the whole thing, and please remark
that not everything might be technically correct...
This prcedure does not apply to every mobile phone. There are mobile
phones out there that understand clear text messages. Read more about
this on the startpage.
SMS-messages are sent to mobile phones with AT-commands very similar
to the ones that every modem understands. The AT-format is
at+cmgs = (message length) (press enter)
> (enter the PDU, explained below) (press CTRL-z)
+ CMGS = (ID)
OK
(Things you have to type in are bold!)
Wanna try? Enter this with a terminal-program connected to your phone:
at+cmgs=53 (press enter)
05010c9194717758185200002dc8329bfd668192a0701b242f87c969f719947fd7e520f4bb5d8687cf6517284907dddff275991c02 (press CTRL-z)
This way you send me a message saying:
"Hello, I am reading your homepage. It worked!"
If you are lucky I will answer you in a few minutes!
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Let's dig in.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Any SMS-message has to be sent to the mobile phone as a hexadecimal string called
the PDU. It is built the following way:
Example PDU:
05010c91947177581852000003c16010
05--__91____________0000--_________
| | | | | | |
| | | | | | -----tp_ud (user data)
| | | | | -----------tp_udl (userdatalength)
| | | | ---------------------tp_da (destination address byte swapped telephone number)
| | | -----------------------------type of adress (91 = national coding)
| | -------------------------------Adress-Length (Number of useful semi-octets in tp_da)
| ---------------------------------Message Identifier (increment!)
-----------------------------------Always 05
Explanation:
1. 05 (standard-value)
Read more about this on page 40ff of ETSI
GSM 03.40 documentation. Its a value that calcualtes from several standard
settings for a standard SMS-message. I tried this value, and it works, so
why bother...? Because you wanna know?
Ok, more exactly. It consists of:
- TP-MTI (TP-Message-Type-Indicator - 2bits)
- TP-RD (TP-Reject-Duplicates - 1bit)
- TP-VPF (TP-Validity-Period-Format - 2bits)
- TP-RP (TP-Reply-Path - 1bit)
- TP-UDHI (TP-User-Data-Header-Indicator - 1bit)
- TP-SRR (TP-Status-Report-Request - 1bit)
2. Message Identifier:
That's the TP-MR (TP-Message-Reference - IntegerValue). Usually this
increments 1 every time you send a message. But I found no sideeffects
when leaving this the same all the time. I used the "01".
3. Adress-Length
hex-Value of the length of the destination-phonenumber
Example: 4917712345 length=10 => 0a (hex)
4. type of adress
91 = national coding, that means a german number looks like 49xxxxxxxxx
5. tp_da
destination address byte swapped telephone number
Byte swapped means take two digits at a time and turn them around. For example:
123456 becomes 214365 ...got it? Good joke, huh? Don't ask me, why
you have to do this, but you have to!
And in case you've got an odd number of digits in your phone number just
add an "F" to the end before byte-swapping!
6. tp_udl
userdatalength is calculated just like the adr-length
7. tp_ud: this will take a little longer, sit back and relax:
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The TP-UD
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
As far as I found out the initial problem is that SMS-messages have to be small.
So the inventors of the SMS-standard did the same thing that the inventors of
the email-format did: they saved space and reduced the size of the message
by saying: "We do not need 256 different characters, people can tell their
stuff with 128 different chars as well."
This is done by encoding every character with 7 bits (0101001) instead of
8 bits (00101001) (this is the way normal text on a computer is encoded.)
But its not that easy, and the following really took me a lot of my nerves ;-)
To write a text on a computer (whatever OS it might be using) and have the
mobile phone send it you need to write the text, and do as if it was 7bit
text. That means:
1. ABAB (8bit) = 01000001 01000010 01000001 01000010
2. leave out the first bit, and you have 7bit:
ABAB (7 Bit) = 1000001 1000010 1000001 1000010
This of course means you can't use all the characters of the usual ASCII-Table
to get the numeric values of a character. Instead there is a special table
for the SMS-7bit alphabet, that has to be used.
What comes next is necessary to produce a string of Hexadecimal values
that the phone understands. This is a little hard to understand, but
maybe the ETSI-documentation helps you understanding this...
3. You have to turn around the order of the characters (this is
for mathematical reasons. If someone has a good explanation, go ahead!!!)
BABA (7bit) = 1000010 1000001 1000010 1000001
4. Attach the two values to form a long string:
1000010100000110000101000001
5. If the length of the string is not a multiple of 8 (i.e. 16, 24, 32...)
then add zeros at the beginning until it is:
00001000010100000110000101000001
6. Snip it in 8bit-long pices:
00001000 01010000 01100001 01000001
7. convert these to hexadecimal values
41h 61h 50h 08h
8. And there you go: this is for the phone:
41615008
(Interestingly every mail program does nearly the same when encoding a binary
attachment to send it with your email, so there has to be a routine that
does this task. But I couldn't find one, so I developend one myself. This
is why SendMyStuff is so slow: it takes a lot of calculation with
my routine to conver 8 to 7 bit. So if there?s anyone out there who knows
a better solution, please tell me!)
You are still reading? Well, then I guess you really want to do this
SMS-app you're planning! Ok, let's go on. And don't forget:
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Things you will need
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Well, first check if the producer of your phone has any documentation
about the topic. I found the docs for mine (good'ol SH888) on the
Ericsson-Website (thanks to Alex T.):
SH888 at-documentation.
http://www.etsi.org
This is important, but expect to find nothing at first ;-))) there
just too much information there.
Search the site for the following documents:
ETS 300 585 ed.5 (1997-04)
GSM 03.38
GSM 03.40 <---Especially important
GSM 03.41
GSM 04.11
GTS GSM 07.05 V5.3.0 (1997-08)
TS 101 343 V6.1.0 (1998-07) General Packet Radio Service
TS 101 369 V6.2.0 (1998-10) Terminal Equipment to Mobile Sta... <--think
this is less important
http://www.sics.se/~lpe/help/sms/
This document explains the PDU.
http://hp.vector.co.jp/authors/VA002416/teraterm.html
A good terminal app for wCE.
SendMyStuff for Windows 9x, 2000
The PC version of my app is useful for developers having difficulties with
their own SMS-programs. Use SendMyStuff to check your PDUs!
(this is no installation-version, just open it on your PC! It does not save
or modify any files, to uninstall just delete it.)
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
my sourcecode
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
As I said I used a language called "Dialect", because
it is free for noncommercial-purposes, and it is easy to understand, and there
are versions for w98 and wCE. I don't want to explain too much any more,
so just have a look and compare the functions to what you just read.
BTW: I snipped off all the parts not necessary for understanding the PDU.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class sendSMS
getString = func(nrInput,textInput)
lenText = Len(textInput)
invText = ""
dec7Bit = array(lenText)
bin7Bit = array(lenText)
binText = ""
bin8Bit = array(lenText, "00000000")
dec = 0
byte = ""
hex = 0
tp_dal = "" // DestinationAddressLength
tp_udl = "" // UserDataLength (see ETSI GSM 03.40 Page52)
tp_ud = "" // UserData
pdu = "0501"
// TP-DAL DestinationAddressLength
i = Len(nrInput) / 2
if i - int(i) > 0 then
nrInput = nrInput + "0"
endif
tp_dal = format("%x",Len(nrInput))
if Len(tp_dal) < 2 then
tp_dal = "0" + tp_dal
endif
pdu = pdu + tp_dal + "91" // 91 is Standard Type-of-Adress
// TP-DA DestinationAddress
for i = 1 to Len(nrInput)
if i/2 - int(i/2) > 0 then
byte = byte + nrInput[i+1]
else
byte = byte + nrInput[i-1]
endif
endfor
pdu = pdu + byte + "0000" // 0000 = TP-PID und TP-DCS
byte = ""
tp_udl = format("%x",lenText)
if Len(tp_udl) < 2 then
tp_udl = "0" + tp_udl
endif
pdu = pdu + tp_udl
// 7Bit-Text reversing
for i = 1 to lenText
invText = textInput[i] + invText
endfor
// convert 7Bit-Text in ascii-Codes and then into binary
for i = 1 to lenText
a = Asc(invText[i])
if a = 64 then a = 0 // Correct the differences between Ascii und 7Bit Standard-Alphabet
elseif a = 36 then a = 2
elseif a = -60 then a = 91
elseif a = -42 then a = 92
elseif a = -36 then a = 94
elseif a = -47 then a = 93
elseif a = -89 then a = 95
elseif a = 96 then a = 39
elseif a = -28 then a = 123
elseif a = -10 then a = 124
elseif a = -15 then a = 125
elseif a = -4 then a = 126
elseif a = -32 then a = 127
endif
dec7Bit[i] = a
pow = 64
for ii = 0 to 6
bit = 0
if int (dec7Bit[i] / pow) = 1 then
bit = 1
dec7Bit[i] = dec7Bit[i] - pow
endif
bin7Bit[i] = bin7Bit[i] + Str$(bit)
pow = pow / 2
endfor
binText = binText + bin7Bit[i]
endfor
// make length a multiple of 8 by adding zeros at the beginning
i = Len(binText) / 8
if i - int(i) > 0 then
addBit = (1 - (i - int(i))) * 8
for i = 1 to int(addBit)
binText = "0" + binText
endfor
endif
// snip into bytes
lenText = Len(binText)
byteNr = 1
for i = 1 to lenText
bitNr = lenText + 1 - i
byte = binText[bitNr] + byte
if Len(Byte) = 8 then
bin8Bit[byteNr] = byte
byte = ""
byteNr = byteNr + 1
endif
endfor
// convert to 8bit-decimal
byte = ""
for i = 1 to byteNr -1
pow = 128
for ii = 1 to 8
if bin8Bit[i][ii] = "1" then
dec = dec + pow
endif
pow = pow / 2
endfor
// convert to hexadecimal
dec = format("%x",dec)
if Len(dec) < 2 then
dec = "0" + dec
endif
tp_ud = tp_ud + dec
dec = 0
endfor
pdu = pdu + tp_ud
at = "at+cmgs=" + Str$(int(Len(pdu)/2))
// that's it, return the PDU
return [at,pdu]
endfunc
endclass
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ok. That's it. Pffffffffffffffffffffft.
Any more questions?