Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5210
  • Last Modified:

Decoding SMS PDU-messages

I use Nokia Datasuite and AT-commands to retrieve sms-messages from mobile phone. It returns them in PDU mode like this:

0791534850020200040C915348707795140000108092327123800DD4F29C0E6A97E7F3F0B91C02

That PDU data contains message "Test message!" from number +358407775941

This site has detailed description of that format:
http://www.gsm-gps.de/sms-pdu-mode.html

Now i need somebody to code Delphi prosedure that decodes PDU message into plain text and return message part and senders phone number..

I don't handle bit-shifting etc. very well.. :(

It would help my project VERY VERY much, and i can guarantee that the inventor of that Delphi procedure will be mentioned in my programs credits and manuals..

-Lazyjeff-
email: seppo@sormunen.com

0
LazyJeff
Asked:
LazyJeff
  • 2
  • 2
1 Solution
 
jeurkCommented:
Hi,
Maybe this is what you need...
See you,
John.

it's written by Barna Szternak
mail: barna.szternak@vodafone.hu
the archive can be found here:
http://delphi.planetmirror.com/ftp/d20free/Text2pdu.rar

------------------------------
Dear user!

With this pas file u can converting texts into PDU format easily, and vica versa.

2 functions were developed:

function texttosms(smscenter: string; targetms: string; text: string): Tpdu;
function smstotext(pdu: string): Tsms;

WARNING! The SMSCenter parameter was currently removed from the function due to the ETSI standards...

Eg. if you want to create an sms in pdu format:

pdu:=texttosms('','36309304401','Test message');

Where pdu is a Tpdu variable, pdu[1] is the sms in pdu format, and pdu[2] is the length of the sms.
Eg. you can send the sms via a nokia phone like this:

'AT+CMGS='+pdu[2]+#13+pdu[1]+s, where s is the CTRL+Z character

Reverse way (processing a received sms):

sms:=smstotext(pdu formatted text);

Where sms is a Tsms variable, sms[1] is the smscenter number, sms[2] is the sender, sms[3] is the timestamp, sms[4] is the sms body.


Included 2 types:

Tpdu = array [1..2] of string;
Tsms = array [1..4] of string;


If you have any more problems, or found a bug, please send me a mail: barna.szternak@vodafone.hu

Best regards: Barna Szternak
-------------------------------------

the unit
----------------------
unit Text2pdu;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs, Math;

type
  Tpdu = array [1..2] of string;
  Tsms = array [1..4] of string;
  TText2pdu = class(TComponent)
  private
    { Private declarations }
    prKillEvent: THandle;
  protected
    { Protected declarations }
    procedure Execute;
  public
    { Public declarations }
    constructor Create(aOwner: TComponent);
    destructor Destroy; override;

  published
    { Published declarations }
    function texttosms(smscenter: string; targetms: string; text: string): Tpdu;
    function smstotext(pdu: string): Tsms;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SMS', [TText2pdu]);
end;

constructor TText2pdu.Create(aOwner: TComponent);
begin
  //inherited Create(True);
  prKillEvent := CreateEvent(nil, false, false, nil);
end;

destructor TText2pdu.Destroy;
begin
  SetEvent(prKillEvent);
  CloseHandle(prKillEvent);
  inherited;
end;

procedure TText2pdu.Execute;
begin
  //inherited Create(True);
end;

function TText2pdu.texttosms(smscenter: string; targetms: string; text: string): Tpdu;
var
  smsc,targ,leng,data : string;
  ses1 : string;
  i,d,e,j,k,n : integer;
  a,b,c : array [1..8] of byte;
  smsh : integer;
  jump : boolean;
  res : Tpdu;

begin
  ses1:=smscenter;
  smsc:=ses1[2]+ses1[1]+ses1[4]+ses1[3]+ses1[6]+ses1[5]+ses1[8]+ses1[7]+ses1[10]+ses1[9]+'F'+ses1[11];
  ses1:=targetms;
  targ:=ses1[2]+ses1[1]+ses1[4]+ses1[3]+ses1[6]+ses1[5]+ses1[8]+ses1[7]+ses1[10]+ses1[9]+'F'+ses1[11];
  ses1:=text;

  j:=0;
  d:=ord(ses1[1]);

  c[8]:=round((d and 128)/128);
  c[7]:=round((d and 64)/64);
  c[6]:=round((d and 32)/32);
  c[5]:=round((d and 16)/16);
  c[4]:=round((d and 8)/8);
  c[3]:=round((d and 4)/4);
  c[2]:=round((d and 2)/2);
  c[1]:=round((d and 1));
  jump:=false;
  for i:=2 to length(ses1) do
  begin
    j:=j+1;
    if j=8 then
    begin
      j:=0;
      jump:=true;
    end;

    d:=ord(ses1[i]);

    a[8]:=round((d and 128)/128);
    a[7]:=round((d and 64)/64);
    a[6]:=round((d and 32)/32);
    a[5]:=round((d and 16)/16);
    a[4]:=round((d and 8)/8);
    a[3]:=round((d and 4)/4);
    a[2]:=round((d and 2)/2);
    a[1]:=round((d and 1));

    if jump=false then
    begin
      for e:=1 to 8-j do
      begin
        b[e]:=c[e];
      end;

      k:=0;

      for e:=8-j+1 to 8 do
      begin
        k:=k+1;
        b[e]:=a[k];
      end;

      n:=128*b[8]+64*b[7]+32*b[6]+16*b[5]+8*b[4]+4*b[3]+2*b[2]+b[1];
      if n>0 then data:=data+inttohex(n,2);

    end;

    jump:=false;

    for e:=1 to 8-j do
    begin
      c[e]:=a[e+j]
    end;

    for e:=8-j to 8 do
    begin
      c[e]:=0;
    end;
  end;
  n:=128*c[8]+64*c[7]+32*c[6]+16*c[5]+8*c[4]+4*c[3]+2*c[2]+c[1];
  if n>0 then data:=data+inttohex(n,2);
  leng:=inttohex(length(text),2);
  res[1]:='0011000B91'+targ+'0000A7'+leng+data;
  smsh:=round(length(res[1])/2-1);
  res[2]:=inttostr(smsh);
  result:=res;
end;

function TText2pdu.smstotext(pdu: string): Tsms;

var
  res : Tsms;
  ins : string;
  smsc,sendr,dt,body : string;
  binb,s,ss,t : string;
  i,j,k,chv : integer;
  smsbody : string;

begin
  ins:=pdu;
  if copy(ins,1,4)='0791' then
  begin
    smsc:=copy(ins,5,12);
    smsc:=smsc[2]+smsc[1]+smsc[4]+smsc[3]+smsc[6]+smsc[5]+smsc[8]+smsc[7]+smsc[10]+smsc[9]+smsc[12];
    res[1]:=smsc;
    sendr:=copy(ins,23,12);
    sendr:=sendr[2]+sendr[1]+sendr[4]+sendr[3]+sendr[6]+sendr[5]+sendr[8]+sendr[7]+sendr[10]+sendr[9]+sendr[12];
    res[2]:=sendr;
    dt:=copy(ins,39,14);
    dt:=dt[2]+dt[1]+'/'+dt[4]+dt[3]+'/'+dt[6]+dt[5]+' '+dt[8]+dt[7]+':'+dt[10]+dt[9]+':'+dt[12]+dt[11]+'.'+dt[14]+dt[13];
    res[3]:=dt;
    body:=copy(ins,55,length(ins)-54);
    for i:=1 to length(body) do
    begin
      case body[i] of
        '0': binb:=binb+'0000';
        '1': binb:=binb+'0001';
        '2': binb:=binb+'0010';
        '3': binb:=binb+'0011';
        '4': binb:=binb+'0100';
        '5': binb:=binb+'0101';
        '6': binb:=binb+'0110';
        '7': binb:=binb+'0111';
        '8': binb:=binb+'1000';
        '9': binb:=binb+'1001';
        'A': binb:=binb+'1010';
        'B': binb:=binb+'1011';
        'C': binb:=binb+'1100';
        'D': binb:=binb+'1101';
        'E': binb:=binb+'1110';
        'F': binb:=binb+'1111';
      end;
    end;
    j:=8;
    t:='';
    for i:=0 to round(length(binb)/8)-1 do
    begin
      s:=copy(binb,i*8+1,8);
      j:=j-1;
      if j=0 then j:=7;
      ss:=copy(s,9-j,j)+t;
      ss:='0'+ss;
      t:=copy(s,1,8-j);
      chv:=0;
      for k:=1 to 8 do
      begin
        chv:=chv+strtoint(ss[k])*round(power(2,8-k));
      end;
      smsbody:=smsbody+chr(chv);
      if length(t)=7 then
      begin
        ss:='0'+t;
        chv:=0;
        for k:=1 to 8 do
        begin
          chv:=chv+strtoint(ss[k])*round(power(2,8-k));
        end;
        t:='';
        smsbody:=smsbody+chr(chv);
      end;
    end;
    res[4]:=smsbody;
  end;
  result:=res;
end;

end.
0
 
LazyJeffAuthor Commented:
Functions are fine, but they cannot decode 160 long messages ! Short messages work just fine, but end of longer massages is messed up..

Any ideas what could cause this ? And what if senders phone number is different lenght ?

- Lj -
0
 
jeurkCommented:
honnestly I don't know...
You might want to write to the author of the functions ?
0
 
LazyJeffAuthor Commented:
I'm doing some research with my friend.. I will email the author about these features. If we find the problem i let u know.. The points are reserved to you Jeurk anyway.. so when we solve this problem i send the points..

This is very intresting problem and i'm going to solve it !

Those routines helped A LOT !

- Lj -
0
 
geobulCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

accept jeurk's comment as answer

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Thanks,

geobul
EE Cleanup Volunteer
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now