摘要:首先介紹了用于手機短信的串口通信、AT指令以及發送模式等相關知識,然后重點解析了手機短信的編碼方法,包括7-bit編碼和UCS2編碼等,并給出了在.NET平臺下用C#實現的主要代碼。文章最后還描述了手機短信模塊在某一個實際的監視系統中的集成與應用場景。
關鍵詞:手機短信;AT指令;PDU模式;編碼
中圖分類號:TN929文獻標識碼:A文章編號:1009-3044(2008)29-0358-03
The Realization Based on .Net and Application of the Module of SMS
ZHANG Yu-dong
(School of Computer Science Technology,Xuzhou Nomal Uinivercity,Xuzhou 221116,China)
Abstract: In this article, we First let you know the knowledge about serial communication ,AT instruction, and how to send SMG based on Text MODE and PDU MODE; then expound the method of 7-bit coding and UCS2 coding, at the same time give the codes on C#.NET; last, describe briefly the application of SMS module on watching system.
Key words: SMS; AT instruction; PDU MODE; encoding
手機短信(SMS,Short Message Service)是GSM(Global System for Mobile Communication)系統提供給用戶的一種數字業務,具有快速、便捷、價格低廉之優點,應用在檢測與監視系統中,可以快速地將收集到的有用信息傳送給用戶,達到離線監視的目的。以下結合某物業管理公司監視系統的開發實例,談談與短信發送模塊相關的開發技術,并給出了用C#語言實現的關鍵代碼。
發送手機短信最簡單易行的方法是使用手機GSM模塊,只需用一根串口數據線(從方便編程的角度,可以考慮使用COM口數據線)與電腦連接,即可使用軟件控制短信的收發。涉及的主要技術有串口通信與AT指令,短信發送模式,短信編碼方法等。
1 計算機與GSM模塊的串口通信
通過串口將信息從電腦傳送到手機并通過手機GSM模塊發送短信涉及到串口編程問題和串口指令兩個方面。串口編程需要借助于串口控件(如常用的微軟公司的MSCOMM控件)來實現,而手機短信使用的串口指令是AT指令。
AT指令是驅動短信設備的標準工業命令(請參閱GSM07.05和GSM07.07行業規范),可以實現計算機與GSM模塊間的串口通信。下面是幾個常用的AT命令:
· AT+CSCA//設置或讀取短信中心號碼。
· AT+CMGF//選擇短消息信息格式:0-PDU;1-文本
· AT+CMGD//刪除SIM卡內存的短消息
· AT+CMGL//列出SIM卡中的短消息: 0-未讀,1-已讀,2-待發,3-已發,4/-全部的
· AT+CMGR//讀短消息
· AT+CMGS//發送短消息
對每條AT指令,通常都有3種調用形式:
· AT+CMGF=參數//設置參數
· AT+CMGF?//讀取設置
· AT+CMGF=?//查詢
2 手機短信發送模式
手機短信有三種模式[2]:Block Mode、基于AT命令的Text Mode和基于AT命令的PDU Mode。Block模式需要手機生產廠家提供驅動支持,目前已很少使用,Text模式不需編碼,使用簡單,但是只能發送ASCII碼,PDU模式支持Unicode字符集,但是需要編碼。
2.1 Text模式發送短信的實現
基于Text模式發送信息過程如下:
//發送手機短信中心號碼,號碼需要加引號,(char)13等同于\\r
Comm1.Output =\"AT+CSCA=\\\"8613800250500\\\"\" + (char)13
//若不是重新設定短信中心號碼,上一步可以省略
//設置為Text模式(1-Text模式,0-PDU模式)
Comm1.Output = \"AT+CMGF=1\\r\";
//目標手機號碼,需要加引號并以\\r結束
//前面可以帶\"+\"號和86
Comm1.Output = \"AT+CMGS=\\\"+13852030186\\\"\\r\";
Comm1.Output = \"Hi!\\r\"; //用戶信息
//最后需要用(char)26結束,此時才真正通過通信網絡發送
Comm1.Output = \"Hello!\" +(char)26;
2.2PDU模式發送短信的實現
//設置為PDU模式(1-Text模式,0-PDU模式)
Comm1.Output = \"AT+CMGF=0\\r\";
Thread.Sleep(1000); //延遲等候設備處理
//根據返回內容監測操作是成功
returnStr = Comm1.Input.ToString();
/*先發送AT+CMGS命令,指示PDU串——pduStr長度,長度從服務中心號碼后開始計算, =字符個數/2)*/
Comm1.Output=\"AT+CMGS=\"+pduStr.length+ (char)13;
//再發送PDU串
Comm1.Output = pduStr + (char)26;
3 PDU串的合成與編碼
3.1 PDU串的構成[3-4]
從上一節可以看出,與Text模式相比,使用PDU模式發送短信時不需要分別發送短信中心號碼、目標手機號碼和短信內容,而是將上述信息及其它一些必要信息(如本機號碼、編碼方式、發送時間等)與用戶消息內容本身合成在一個串中。同時,PDU串是需要進行編碼的。例如:
短信中心號碼:center=”+8613800250500”
對方號碼:phone=”13852030186”
消息內容:contents=“Hello!” 。
手機發出的PDU串可以是(詳見表1):
08 91 68 31 08 20 05 05 F0 11 00 0D 91 68 31 58 02 03 81 F6 00 00 00 06 C8 32 9B FD 0E 01
3.2 對PDU串的編碼
需要對PDU串的三個部分進行編碼,然后再合成。
1) 對“號碼”部分的編碼
對號碼(短信中心號碼和目標手機號碼)部分編碼比較簡單,根據表1可以看出,其編碼方法是11位碼兩位一節,每節中的兩位前后交換,并在最后一節補0,然后在前面加“+68”。
2) 對“用戶消息”部分的編碼與實現
對“用戶消息”部分的編碼有3種:7-bit編碼、8-bit編碼、和UCS2編碼。7-bit編碼用于發送普通的ASCII字符,8-bit編碼用于發送數據消息(如圖片和鈴聲),而UCS2編碼用于發送Unicode字符。
1) 7-bit編碼與實現
假設有一個串 “Hel“,7-bit編碼原理如下(參見表2):
① 將字符轉換為7位二進制;② 將后面字符的低位調到前面字符的高位,將每一個字節都補齊成8位。編碼后的字符個數=(ln / 8)*7+ln%8(其中,ln=編碼前字符個數);③ 將最后一個非空字節在高位上補“0”湊齊8位; ④ 將調整后的串轉換成“X2”格式表示的串;⑤ 在串的前面加上“編碼前”串長的“X2”格式的表示。
“Hel”編碼后成為:“03C8321B” 。
7-bit編碼的C#實現如下[1]:
stringEncode7bit(string contents)//7-bit編碼
{int ln = contents.Length; //源串字符數
int ln2= (ln / 8)*7+ln%8; //7-bit壓縮后的字符
byte[] pSrc = System.Text.Encoding.ASCII.GetBytes(contents);
//將串轉換為字節數組
byte[] pDst = new byte[ ln2 ];
//存放 pSrc 7-bit編碼后的字節數組,長度可能減小
int nSrc = 0; //源字節數組的計數值
int nDst = 0; //目標字節數組的計數值
byte nChar; //當前正在處理的組內字節,序號是0-7
byte nLeft = 0; //上一字節殘余的數據
int i = 0, j = 0;
string returnStr=1;//保存編碼后的串
/* 將源串每8個字符分為一組(不到8個字符也分1組),壓縮成7個字節,循環該處理過程,直至源串處理完*/
while (nSrc < ln)
{nChar = (byte)(nSrc 7); //取源字符的最低位
if (nChar == 0)//處理源串的每個字節
nLeft = pSrc[i];
//保存組內第一個字節,待處理下一個字節時使用
else /*組內其它字節,將其右邊部分與殘余數據相加,得到一個目標編碼字節*/
{pDst[j] = (byte)((pSrc[i] << (8 - nChar)) | nLeft);
//將該字節剩下的左邊部分,作為殘余數據保存起來
nLeft = (byte)(pSrc[i] >> nChar);
j++; nDst++;//修改目標串的指針和計數值pDst++;
}
i++; nSrc++; //修改源串的指針和計數值
}
if (ln % 8 != 0)
{ pDst[j++] = nLeft; nDst++;}
for (int i = 0; i < pDst.Length; i++)
{ returnStr += BitConverter.ToString(pDst, i, 1); }
//將字節數組表示成16進制的串
returnStr=String.Format(\"{0:X2}{1}\", ln, returnStr);
//將原串長度表示”X2”格式串,并與編碼后內容部分合并
return returnStr; }
2) UCS2編碼與實現
UCS2編碼相對簡單,首先將字符串用Unicode(16進制)表示成字節數組,然后再轉換成”X2”格式表示的串,最后在前面加上串長信息即可。
UCS2編碼的C#實現如下[1]:
string gsmPDUEncoded(string Content)
{byte[] x= System.Text.Encoding.
BigEndianUnicode.GetBytes(Content);
//unicode(16進制)編碼,每個符號(含西文)占2字節
string s = 1;
for (int i = 0; i < x.Length; i++)
{ s += BitConverter.ToString(x, i, 1); }
//將字節數組表示“X2”格式的串
s = String.Format(\"{0:X2}{1}\", x.Length, s);
//串前面加上”X2”格式的串長度值,串長=字符數*2
return s; }
4 短信模塊在檢測與監視系統中的應用
以上介紹了開發手機短信模塊的關鍵技術與C#實現,開發出該模塊后,就可以將其集成到相關的系統中。
圖1顯示了短信模塊與某物業小區檢測與監視系統的集成,這樣系統就可以對緊急郵件消息,火警消息以及采集到的其它關鍵信息按照用戶設置的條件發送短信給負責人,達到離線監視的目的。實踐表明,系統效果良好。
參考文獻:
[1] 內格爾.C#高級編程[M].李敏波,譯.北京:清華大學出版社,2002.
[2] GSM07.07[S].http://www.etsi.org.
[3] http://www.yesky.com/SoftChannel/72342380468109312/20040523/1800310_2.shtml[EB/OL].
[4] http://http://www.mocomor.com/Article/?CatalogID=265[EB/OL].