天天看點

關于短信收發 的at指令方面的資料

關于使用GSM MODEM裝置利用AT指令處理短信的方法,網上有很多相關的内容,我也是遍覽各家所長,再加上自己的實際試驗、應用,在前人的基礎上做下總結,添加點自己經驗。也有很多問題還未解決,期望高手可以指點一二。

一、硬體接口

    偶使用的是西門子TC35iGSM無線通信控制終端,具備GSM無線通信的全部功能,支援GSM07.05、GSM07.07所定義的的AT指令集。通過序列槽與計算機相連。

二、參數設定

    1、短信收發模式設定

  短消息的發送和接收控制模式有三種:Block模式、PDU模式和Text模式。使用Block模式需要手機生産廠家提供驅動支援。目前,PDU模式已取代Block模式,而Text模式不支援中文。是以,為了系統的通用性,相容中英文短消息的發送接收,建議使用PDU模式來處理短消息。

    應設定:AT+CMGF=0 //PDU方式

    2、新資訊處理方式設定

     AT+CNMI=2,2,0,1,1 //新收到的短信直接發送至TE終端,不存儲在SM卡中

    3、回顯設定

     ATE1 //有回顯,友善測試

    4、消息服務設定

    AT+CSMS=0 //如果AT+CSMS=1,接收到短信時,TE需在一定的時間内發送回報消息至模 塊;若逾時,<mode>和<mt>的值會強制複位到0。那麼,再有新的短信将不能被正确處理,需要用"AT+CNMI”指令重新設定參數才行。這增加了程式處理的複雜性。AT+CSMS=0時,省去了這些麻煩。

三、短信發送

以要将“你好”發送到13752141860,資訊中心号碼為:+8613800220500為例:

    1、PDU資料格式分析

      應發送的PDU字元串為:

     0891683108200205F031000D91683157121468F00008AA044F60597D

     下面對這段PDU資料進行詳細分析:

  (1)08 //資訊中心号碼的長度,将91+683108200205F0的長度除2,格式化成2位的16進制字元串所得

    (2)91 //短信中心号碼類型'91是TON/NPI遵守International/E.164标準,指在号碼前需加‘+’号

       91—10010001 //每一位數字轉換為4位二進制數

            1

           001 //數值類型(Type of Number):000—未知,001—國際,010—國内,111—留作擴充;

           0001//号碼鑒别(Numbering plan identification):0000—未知,0001—ISDN/電話号碼(E.164/E.163),1111—留作擴充;

    (3)683108200205F0 //短資訊中心号碼

       轉換方法:如果号碼前面有+号,去掉“+”号→如果沒有“86”,在号碼前加上“86”:8613800220500→看看現在号碼的長度是否為偶數,如果不是,在号碼後面加上“F”:8613800220500F→将奇數位和偶數位交換,得到結果:683108200205F0

    (4)31 //TPDU頭位元組

       31&h=00110001&b //每一位數字轉換為4位二進制數

             0 //應答路徑—TP-RP(TP-Reply-Path):0—不設定; 1—設定

            0 //使用者資料頭辨別—TP-UDHL(TP-User-Data-Header-Indicator):0—不含任何頭資訊; 1—含頭資訊       

            1 //狀态報告要求—TP-SPR(TP-Status-Report-Request):0—不需要報告; 1—需要報告(有些地方寫0為需要報告,經偶測試是錯誤的)

            10 //有效期格式—TP-VPF(TP-Validity-Period-Format):00—不提供(Not present); 10—整型(标準);01—預留; 11—提供8位位元組的一半(Semi-Octet Represented)

             0 //拒絕複制—TP-RD(TP-Reject-Duplicates):0—接受複制; 1—拒絕複制

            01 //資訊類型提示—TP-MTI(TP-Message-Type-Indicator):00—讀出(Deliver); 01—送出(Submit)

    (5)00 //資訊類型

     (6)0D //被叫号碼長度,8613752141860的長度格式化為2位16進制所得

     (7)91 //短信中心号碼類型'91是TON/NPI遵守International/E.164标準,指在号碼前需加‘+’号,小靈通為81

     (8)683157121468F0 //被叫号碼,轉換方法同(3)

     (9)00 //協定辨別 TP—PID

       00--00000000 //每一位轉換為4位二進制數

           00    //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。

           0     //Bit No.5:0—不使用遠端網絡,隻是短消息裝置之間的協定;1—使用遠端網絡。

           00000 //Bit No.0—Bits No.4:00000—隐含;00001—電傳;00010—group 3 telefax;00100—語音;00101—歐洲無線資訊系統(ERMES);00110—國内系統;10001—任何基于X.400的公用資訊處理系統;10010—Email。

     (10)08 //資料編碼方案,08:中文編碼,00為英文或數字,Bit No.7與Bit No.6.Bit No.7的編碼解碼比較複雜,建議在發送純英文或數字的短信時仍使用中文編碼,測試通過.

       08--00001000

           00 //Bit No.7與Bit No.6 :一般設定為00;

           0 //Bit No.5:0—文本未壓縮,1—文本用GSM标準壓縮算法壓縮;

           0 //Bit No.4:0—表示Bit No.1、Bit No.0為保留位,不含資訊類型資訊,1—表示Bit No.1、Bit No.0含有資訊類型資訊;

           00 //Bit No.3與Bit No.2:00—預設的字母表,01—8bit,10—USC2(16bit),11—預留;

           00 //Bit No.1與Bit No.0:00—Class 0,01—Class 1,10—Class 2(SIM卡特定資訊),11—Class 3。

    (11)AA //有效期TP-VP(TP-Valid-Period),16進制數

   AA表示短資訊被保留的時間為4天,其計算方法依照表3。

VP值(10進制數) 短消息有效長度
0~143 (VP+1)×5分鐘
144~167 12時+(VP-143)×30分
168~196 1天×(VP-166)
197~255 1周×(VP-192)

    (12)04 //使用者資料長度TP-UDL(TP-User-Data-Length),4F60597D的長度除2格式化為2位16進制數所得

    (13)4F60597D //使用者資料TP-UD(TP-User-Data),這個就是我們發送的内容"你好"的UniCode碼了

       在PDU模式中,發送普通的ASCII字元用7-bit編碼方式,将一串7-bit字元編碼為8-bit資料,每8個字元可壓縮成7個。如果發送中文字元,則采用UCS2編碼方式,每個中文字元用16位的Unicode字元表示.将字元串轉換為UniCode碼的過程網上有很多,這裡提供DELPHI下的編碼函數:

***********************************************************

function Thread_Smsg.str_Gb2UniCode(text:string):String;

var

i,j,len:Integer;

cur:Integer;

t:String;

ws:WideString;

begin

Result:='';

ws:=text;

len:=Length(ws);

i:=1;

j:=0;

while i<=len do

begin

     cur:=ord(ws[i]);

     FmtStr(t,'%4.4X',[cur]); //BCD轉換

   Result:=Result+t;

   inc(i);

   //移位計數達到7位的特别處理

   j:=(j+1)mod 7;

end;

end;

***********************************************************

    2、發送短信

        做好了要發送的PDU資料包以後終于可以開始發送短信了。

首先發送AT,GSM回答OK,表明建立連接配接成功,可以測試各類AT指令;

接着發送AT+CMGS=17,17是指将PDU資料中短信中心号碼後面的字元串(本例中即為31000D91683157121468F00008AA044F60597D)的長度除以2,格式化為2位的十進制數;最大長度為164,測試過165以上就會傳回ERROR。

但是這裡有個問題,70個漢字編輯成PDU後長度是155,但是這140個字元是漢字和字母數字的組合,長度就有可能超過164,因為每一位的數字或字母也被轉為4位的UNICODE碼。

發送長度後,GSM會傳回>,然後我們發送剛才編輯的PDU字元串:0891683108200205F031000D91683157121468F00008AA044F60597D以CTRL+Z結束;

如果GSM傳回:就表示發送成功了。

        +CMGS: 183 //183是發送短信時産生的順序号,在對方接收到短信發回狀态報告時候,狀态報告中會包含此順序号

        OK

這裡需要注意的是手機傳回OK隻能确認是成功發送到GSM網絡上,接收方是否真正收到短信需要通過發送報告得知。有關如何獲得發送報告在“發送報告的PDU資料分析”中有說明。

四、短信接收

    1、接收中文短信

    以接收13752141860 号碼發送來的“你好”,資訊中心号碼為:+8613800220500為例,手機接收到字元串為:

+CMT: ,24

0891683108200205F0240D91683157121468F0000860800331220000044F60597D

其中+CMT表示新短信訓示代碼格式為收到短消息立即顯示;若+CMTI則訓示收到短消息存儲到存儲器裡;是否直接顯示是通過CNMI設定的;

24表示PDU資料中短信中心号碼後面的字元串長度/2,即240D91683157121468F0000860800331220000044F60597D的長度除以2;

下面分析一下接收到的PDU資料:

(1)08 //資訊中心号碼的長度,将91+683108200205F0的長度除2,格式化成2位的16進制字元串所得

(2)91 //短信中心号碼類型

(3)683108200205F0 //短信中心号碼,轉換方法前面有提到

(4)24 //TPDU頭位元組

(5)0D //發送源号碼長度,8613752141860的長度格式化為2位16進制所得

(6)91 //發送源号碼類型

(7)683157121468F0 //發送源号碼

(8)00 //協定辨別 TP—PID

(9)08 //資料編碼方案,08:中文編碼,00為英文或數字,Bit No.7與Bit No.6

(10)608003312200 //日期時間,奇偶互換:06-08-30 13:22:00,有論壇上寫接收到的是026080……就是前面有’02’,表示2006-08…但是我用不同的手機發送短信過來接收到的都是06,無法取得2006,不知道是發送方手機設定的問題還是哪裡的問題,還在研究中.

(11)00 //時區

(12)04 //使用者資料長度TP-UDL(TP-User-Data-Length),4F60597D的長度除2格式化為2位16進制數所得

(13) 4F60597D //”你好”的UNICODE碼,同樣提供一個DELPHI下的解碼函數:

2、接收純英文或數字

上面例子中接收到的是中文短信“你好”,那麼當接收到的短信是純中文或者數字的時候又如何解碼呢?

例如接收到13752141860發送的英文短信“hello”,手機接收到的字元串為:

+CMT: ,24

0891683108200205F0240D91683157121468F00000608003416270000461F1980C

前面編碼的意義和中文資訊相同,這裡不再重複,隻從紅色的00說起:

先前提到了這兩位表示資料編碼方案,08為中文編碼,00為英文或數字,當手機發送普通的ASCII字元即使用7-bit編碼方式,說明我們接收到的短信是英文或者數字格式的,而不是中文UNICODE碼;

04仍然是使用者資料(61F1980C)長度除2格式化為2位10進制數所得,61F1980C就是發送方發送過來的短資訊,根據前面的00我們知道這是一段7-bit碼,而不再是UNICODE碼,7-bit的解碼過程很複雜,大體過程是:

将源資料每7個位元組分為一組,解碼成8個字元。基本自然是:将第n個位元組左移n位,再加上前一位元組的剩餘資料,即第(n-1)個位元組右移(8-n)位的數值,螢幕最高位,即得到一目标字元資料,n=0…6。第7個位元組右移1位就得到解碼後的第8個字元資料。

五、序列槽通訊

知道了如何發送短信和如何解碼收到的短信,關鍵的問題是在實際開發中怎樣向GSM MODEM發送AT指令以及擷取GSM MODEM接收到的資訊呢?這就需要使用序列槽通訊控件,由于DELPHI沒有提供此類控件

繼續閱讀