首页  编辑  

NameNick的手机短信DLL

Tags: /超级猛料/Network.网络通讯/BP短讯和手机短消息/   Date Created:

主  题:  大放送!!!!手机短讯源码。

作  者:  NameNick (三三)  

等  级:    

信 誉 值:  100

所属论坛:  Delphi 基础类

问题点数:  1

回复次数:  24

发表时间:  2002-7-16 23:15:21

用GSM模块发中文短讯,必须以PDU包的形式发送。我将它写成了Dll,直接调用SMSEncode函数即可得到追后的编码。现将原码公开:

unit EnCodeCompnent;

interface

uses

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

   function SMSEncode(s:WideString;Result_Code:pchar):Bool;Stdcall;export;

   function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;Stdcall;export;

   function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;stdcall;export;

   function ConvertPhoneNum(strNum:string):string;

   function Transposition(instr:pchar;Result_str:pchar):Bool;stdcall;export;//将一个字符串两两交换位置

   { Public declarations }

implementation

function SMSEncode(s:WideString;Result_Code:pchar):Bool;

var

 i,len:Integer;

 cur:Integer;

 t,temp:String;

begin

if length(s)>0 then

 begin

   len:=Length(s);

   i:=1;

   while i<=len do

     begin

       cur:=ord(s[i]);

       //BCD convert

       FmtStr(t,'%4.4X',[cur]);

       temp:=temp+t;

       inc(i);

     end;

   StrCopy(Result_Code,pchar(temp));

   Result:=true;

 end

else

 Result:=false;

end;

function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;

var

 str:string;

 i:integer;

 temp:string;

 A_PWideChar:array[0..300] of widechar;

 R_String:string;

 A_integer:integer;

begin

 str:=string(Input_Code);

 R_String:='';

 if length(str)<=0 then

   begin

     Result:=false;

     exit;

   end;

 i:=0;

 while i<length(str) do

   begin

     temp:=copy(str,i+1,4);

     A_integer:=strtoint('$'+temp);

     move(A_integer,A_PWideChar[i div 4],sizeof(A_PWideChar[i div 4]));

     inc(i,4);

   end;

 A_PWideChar[length(str) div 4]:=#0;

 R_String:=WideCharToString(@A_PWideChar);

 StrCopy(Result_Str,pchar(R_String));

 Result:=true;

end;

function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;

const

 lenSmsInfo='00';

 firstOctet='11';

 TPMessageReference='00';

 TypeOfAddress='91';

 TpId='00';

 TpDcs='08';//"00" is 7 bit encode "08" is 8 bit encode;

 TPValidityPeriod='AA';//aa is 4 day

var

 DestPhoneNum:string;

 AddressLength:string;

 TpUserData:string;

 TPUserDataLength:string;

 temp:WideString;

 Tmp_Pchar:pchar;

 Rlt_str:string;

begin

 if (DestNumber='') or (Content='') then

   begin

     Result:=false;

     exit;

   end

 else

   begin

     DestPhoneNum:=ConvertPhoneNum(DestNumber);

     AddressLength:=format('%2.2X',[length(DestNumber)]);

     temp:=Content;

     Tmp_Pchar:=StrAlloc(1000);

     if SMSEncode(temp,Tmp_Pchar) then

       TpUserData:=string(Tmp_Pchar);

     if TpDcs='08' then

       TPUserDataLength:=format('%2.2X',[length(TpUserData) div 2])

     else

       TPUserDataLength:=format('%2.2X',[((length(TpUserData) div 2)*8) div 7]);

     Rlt_str:=lenSmsInfo

             +firstOctet

             +TPMessageReference

             +AddressLength

             +TypeOfAddress

             +DestPhoneNum

             +TpId

             +TpDcs

             +TPValidityPeriod

             +TPUserDataLength

             +TpUserData;//TpUserData have to Encoded;

     StrCopy(Result_String,pchar(Rlt_str));

     Result:=true;

    end;

end;

function ConvertPhoneNum(strNum:string):string;

var

i:integer;

str:string;

A_Pchar:pchar;

begin

 str:=strNum;

 i:=length(str);

 if odd(i) then

   begin

     str:=str+'F';

     A_Pchar:=StrAlloc(40);

     if Transposition(pchar(str),A_pchar) then

       result:=string(A_Pchar)

     else

       result:='Null';

   end

 else

   begin

     A_Pchar:=StrAlloc(40);

     if Transposition(pchar(str),A_pchar) then

       result:=string(A_Pchar)

     else

       result:='Null';

   end;

end;

function Transposition(instr:pchar;Result_str:pchar):Bool;

var

 i:integer;

 temp:string;

 destStr:string;

 In_String:string;

begin

if length(instr)>0 then

 begin

   destStr:='';

   In_String:=string(instr);

   setlength(In_String,length(In_String));

   i:=1;

   while i<length(In_String) do

     begin

       temp:=In_String[i+1]+In_String[i];

       destStr:=destStr+temp;

       inc(i,2);

     end;

   StrCopy(Result_Str,pchar(destStr));

   result:=true;

 end

else

 begin

   result:=false;

 end;

end;

end.

回复人: shuixin13(犬犬(心帆)) ( ) 信誉:100  2002-7-17 1:48:00  得分:0

 

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

下面的几个函数对做手机短消息的同志一定有用,

手机发送中文时用的是UniCode码,

用GB2UniCode就行,

向串口发送

AT+CMGL=0 +#13+#10

会得到短消息,是PDU协议

数据格式分为UniCode与7Bit格式

分别用UniCode2GB 与 DecodeSMS7Bit 进行解码

我自已做了一个手机串口线适用西门子,

请到

http://mymotor.myrice.com/file/cable.htm

下载原理图

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

08 91 683108701305F0 11 00 0D 91 3176378290F9 00 00 00 02 C834

⑴08-短信息中心地址长度。指(91)+(683108701305F0)的长度。

⑵91-短信息中心号码类型。91是TON/NPI遵守International/E.164标准,指在号码前需加'+'号;此外还有其它数值,但91最常用。

91-10010001

BIT No.        7        6        5        4        3        2        1        0

Name        1        数值类型        号码鉴别

数值类型(Type of Number):000-未知,001-国际,010-国内,111-留作扩展;

号码鉴别(Numbering plan identification):0000-未知,0001-ISDN/电话号码(E.164/E.163),1111-留作扩展;

⑶683108701305F0-短信息中心号码。由于位置上略有处理,实际号码应为:8613800731500(字母F是指长度减1)。这需要根据不同的地域作相应的修改。

⑴、⑵、⑶通称短消息中心地址(Address of the SMSC)。

⑷11-文件头字节。

11&h=00010001&b

BIT No.        7        6        5        4        3        2        1        0

Name        TP-RP        TP-UDHI        TP-SPR        TP-VFP        TP-RD        TP-MTI

Value        0        0        0        1        0        0        0        1

应答路径-TP-RP(TP-Reply-Path):0-不设置; 1-设置

用户数据头标识-TP-UDHL(TP-User-Data-Header-Indicator):0-不含任何头信息; 1-含头信息

状态报告要求-TP-SPR(TP-Status-Report-Request):0-需要报告; 1-不需要报告

有效期格式-TP-VPF(TP-Validity-Period-Format):00-不提供(Not present); 10-整型(标准);01-预留; 11-提供8位字节的一半(Semi-Octet Represented)

拒绝复制-TP-RD(TP-Reject-Duplicates):0-接受复制; 1-拒绝复制

信息类型提示-TP-MTI(TP-Message-Type-Indicator):00-读出(Deliver); 01-提交(Submit)

⑸00-信息类型(TP-Message-Reference)

⑹0B-被叫号码长度。

⑺91-被叫号码类型(同⑵)。

⑻3176378290F9-被叫号码,经过了位移处理,实际号码为"13677328099"。

⑹、⑺、⑻通称目的地址(TP-Destination-Address)。

⑼00-协议标识TP-PID(TP-Protocol-Identifier)

BIT No.        7        6        5        4        3        2        1        0

Bit No.7与Bit No.6: 00-如下面定义的分配Bit No.0-Bit No.5;01-参见GSM03.40协议标识完全定义;10-预留;11-为服务中心(SC)特殊用途分配Bit No.0-Bit No.5。

一般将这两位置为00。

Bit No.5:0-不使用远程网络,只是短消息设备之间的协议;1-使用远程网络。

Bit No.0-Bits No.4:00000-隐含;00001-电传;00010-group 3 telefax;00100-语音;00101-欧洲无线信息系统(ERMES);00110-国内系统;10001-任何基于X.400的公用信息处理系统;10010-Email。

⑽00-数据编码方案TP-DCS(TP-Data-Coding-Scheme)

BIT No.        7        6        5        4        3        2        1        0

Bit No.7与Bit No.6 :一般设置为00;Bit No.5:0-文本未压缩,1-文本用GSM标准压缩算法压缩;Bit No.4:0-表示Bit No.1、Bit No.0为保留位,不含信息类型信息,1-表示Bit No.1、Bit No.0含有信息类型信息;Bit No.3与Bit No.2:00-默认的字母表,01-8bit,10-USC2(16bit),11-预留;Bit No.1与Bit No.0:00-Class 0,01-Class 1,10-Class 2(SIM卡特定信息),11-Class 3。

⑾00-有效期TP-VP(TP-Valid-Period)

VP value(&h)        相应的有效期

00 to 8F        (VP+1)*5 分钟

90 to A7        12小时+(VP-143)*30分钟

A8 to C4        (VP-166)*1天

C5 to FF        (VP-192)*1 周

⑿02-用户数据长度TP-UDL(TP-User-Data-Length)

⒀C834-用户数据TP-UD(TP-User-Data)"Hi"

 

Top

回复人: shuixin13(犬犬(心帆)) ( ) 信誉:100  2002-7-17 1:49:24  得分:0

 

{===============================================================}

{ 函数  : RESULTSTRING = HexToBin(HEXSTRING)

{ 目的   : 把十六进制字符串转换为二进制字符串  

{

{===============================================================}

{ 函数  : RESULTINTEGER = HexCharToInt(HEXCHAR)

{ 目的   : 转换一个十六进制字符为整数

{===============================================================}

{ 函数  : RESULTSTRING = HexCharToBin(HEXCHAR)

{ 目的   : 转换一个十六进制字符为二进制字符串

{===============================================================}

{ 函数  : RESULTINTEGER = Pow(BASE,POWER)

{ 目的   : 指数函数

{===============================================================}

{ 函数  : RESULTINTEGER = BinStrToInt(BINSTRING)

{ 目的   : 把二进制字符串转换为整数

{===============================================================}

{ 函数  : RESULTSTRING = DecodeSMS7Bit (PDUSTRING)

{ 目的   : 解码一个7-bit SMS (GSM 03.38) 为ASCII码

{===============================================================}

{ 函数  :  RESULTSTRING = ReverseStr (SOURCESTRING)

{ 目的   : 反转一个字符串

{===============================================================}

{===============================================================}

{ 函数  :  RESULTSTRING = UniCode2Gb (SOURCESTRING)

{ 目的   : 将UniCode字符串转换为GB

{===============================================================}

{===============================================================}

{ 函数  :  RESULTSTRING = GB2UniCode (SOURCESTRING)

{ 目的   : 将GB字符串转换为UniCode

{===============================================================}

unit BinHexTools;

interface

function HexToBin(HexNr : String): String;

function HexCharToInt(HexToken : char): Integer;

function HexCharToBin(HexToken : char): String;

function pow(base, power: integer): integer;

function BinStrToInt(BinStr : String) : Integer;

function DecodeSMS7Bit(PDU : String): String;

function ReverseStr(SourceStr : String) : String;

function GB2UniCode(GB:string): String;

function UniCode2GB(S : String): String;

implementation

uses sysutils, dialogs;

function HexCharToInt(HexToken : char):Integer;

begin

 //if HexToken>#97 then HexToken:=Chr(Ord(HexToken)-32);

 { 将小写字母转换成大写 }

 Result:=0;

 if (HexToken>#47) and (HexToken<#58) then       { chars 0....9 }

    Result:=Ord(HexToken)-48

 else if (HexToken>#64) and (HexToken<#71) then  { chars A....F }

    Result:=Ord(HexToken)-65 + 10;

end;

function HexCharToBin(HexToken : char): string;

var DivLeft : integer;

begin

   DivLeft:=HexCharToInt(HexToken);   { first HexChar->Int }

   Result:='';

                                      { Use reverse dividing }

   repeat                             { Trick; divide by 2 }

     if Odd(DivLeft) then             { result = odd ? then bit = 1 }

       Result:='1'+Result             { result = even ? then bit = 0 }

     else

       Result:='0'+Result;

     DivLeft:=DivLeft div 2;       { keep dividing till 0 left and length = 4 }

   until (DivLeft=0) and (length(Result)=4);      { 1 token = nibble = 4 bits }

end;

function HexToBin(HexNr : string): string;

{ only stringsize is limit of binnr }

var Counter : integer;

begin

 Result:='';

 for Counter:=1 to length(HexNr) do

   Result:=Result+HexCharToBin(HexNr[Counter]);

end;

function pow(base, power: integer): integer; //指数base^power

var counter : integer;

begin

 Result:=1;

 for counter:=1 to power do

   Result:=Result*base;

end;

function BinStrToInt(BinStr : string) : integer;

var counter : integer;

begin

 if length(BinStr)>16 then

   raise ERangeError.Create(#13+BinStr+#13+

           '不是一个有效的16Bit二进制单元'+#13);

 Result:=0;

 for counter:=1 to length(BinStr) do

     if BinStr[Counter]='1' then

       Result:=Result+pow(2,length(BinStr)-counter);

end;

function DecodeSMS7Bit(PDU : string):string;

var OctetStr : string;

   OctetBin : string;

   Charbin  : string;

   PrevOctet: string;

   Counter  : integer;

   Counter2 : integer;

begin

 PrevOctet:='';

 Result:='';

 for Counter:=1 to length(PDU) do

   begin

     if length(PrevOctet)>=7 then     { if 7 Bit overflow on previous }

       begin

         if BinStrToInt(PrevOctet)<>0 then

           Result:=Result+Chr(BinStrToInt(PrevOctet))

         else Result:=Result+' ';

         PrevOctet:='';

       end;

     if Odd(Counter) then            { only take two nibbles at a time }

       begin

         OctetStr:=Copy(PDU,Counter,2);

         OctetBin:=HexToBin(OctetStr);

         Charbin:='';

         for Counter2:=1 to length(PrevOctet) do

           Charbin:=Charbin+PrevOctet[Counter2];

         for Counter2:=1 to 7-length(PrevOctet) do

           Charbin:=OctetBin[8-Counter2+1]+Charbin;

         if BinStrToInt(Charbin)<>0 then Result:=Result+Chr(BinStrToInt(CharBin))

           else Result:=Result+' ';

         PrevOctet:=Copy(OctetBin,1,length(PrevOctet)+1);

       end;

   end;

end;

function ReverseStr(SourceStr : string) : string;

var Counter : integer;

begin

 Result:='';

 for Counter:=1 to length(SourceStr) do

   Result:=SourceStr[Counter]+Result;

end;

function GB2UniCode(GB:string):string;

var

 s: string;

 i, j, k: integer;

 a: array [1..160] of char;

begin

 s:='';

 StringToWideChar(GB, @(a[1]), 500);

 i:=1;

 while ((a[i]<>#0) or (a[i+1]<>#0)) do begin

   j:=Integer(a[i]);

   k:=Integer(a[i+1]);

   s:=s+Copy(Format('%X ',[k*$100+j+$10000]) ,2,4);

   //S := S + Char(k)+Char(j);

   i:=i+2;

 end;

 Result:=s;

end;

function UniCode2GB(S : String):String;

Var I: Integer;

begin

  I :=  Length(S);

  while I >=4  do begin

    try

      Result :=WideChar(StrToInt('$'+S[I-3]+S[I-2]+S[I-1]+S[I]))+ Result;

    except end;

    I := I - 4;

  end;

end;

end.

 

Top

回复人: shuixin13(犬犬(心帆)) ( ) 信誉:100  2002-7-17 1:49:36  得分:0

 

AT COMMAND_v8.6,

GSM_v0705,

SMS PDU-mode

是编程所需要的技术文件,在网上找找吧