分享

分享一个GSM短信猫接口程序

 笔录收藏 2013-04-17

GSM短信猫编程的难点在与“程序与GSM”通讯是异步的。

          例如:

            AT+CSQ 查询信号指令,PC通过RS232串口发送后,GSM短信猫要等一小会才回答,而且还可能不回答。

这样一来就导致编程复杂了。

下面的程序采用了串口中断接收、定时器、线程的方式配合。实现了接收短信,并把接收到的短信存在数据库中。然后定期发送短信

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading;  
  6. using System.Windows.Forms;  
  7.   
  8. namespace SMS  
  9. {  
  10.     public class GSMModem  
  11.     {  
  12.   
  13.         private string protName;  
  14.         private int BaudRate;  
  15.         private System.Collections.ArrayList alRecevingSM;// 短信接收 缓冲区   
  16.         private System.Collections.ArrayList alSendSM;    // 短信【待】发送 缓冲区   
  17.   
  18.         private System.Collections.ArrayList alAuthorizationNumber; //授权号码,系统只会回复授权号码   
  19.   
  20.         int WORK_STATE;//短信猫工作状态     
  21.   
  22.         //错误的短信数,主要是未经授权的号码发来的短信   
  23.         private int ErrorSMCount = 0;  
  24.         public int _ErrorSMCount  
  25.         {  
  26.             get  
  27.             {  
  28.                 return ErrorSMCount;  
  29.             }  
  30.         }  
  31.         /// <summary>   
  32.         /// 0=自检   
  33.         /// 1=接收   
  34.         /// 2=发送   
  35.         /// </summary>   
  36.         public int _WORK_STATE  
  37.         {  
  38.             get  
  39.             {  
  40.                 return WORK_STATE;  
  41.             }  
  42.         }  
  43.   
  44.   
  45.         //接收和发送定时器不能同时工作,切记   
  46.   
  47.         //短信接收 轮询 定时器,定时发送 AT+CGMR={0}   
  48.         System.Windows.Forms.Timer revTimer = new System.Windows.Forms.Timer();  
  49.   
  50.         //短信发送 队列 定时器,定时发送 AT+CMGS={0}   
  51.         System.Windows.Forms.Timer sendTimer = new System.Windows.Forms.Timer();  
  52.   
  53.         //短信猫自检   
  54.         System.Windows.Forms.Timer selfCheckingTimer = new System.Windows.Forms.Timer();  
  55.   
  56.   
  57.         //短信猫连接设备端口   
  58.         System.IO.Ports.SerialPort Port = new System.IO.Ports.SerialPort();  
  59.   
  60.         //短信猫串口接收缓冲   
  61.         /*备注:该缓冲变量由串口DataReceived事件负责接收,具体的处理过程由 
  62.          *     Timer 定时器内的代码具体执行 
  63.          */  
  64.         string temp_gsm_str_buf = "";  
  65.   
  66.         //   
  67.         int CMGD_MAX_ID = 0;//短信卡最大SM容量,通常情况下设置为25   
  68.   
  69.         int CMGD_ID = 1;    //当前串口发送读取的短信ID号   
  70.   
  71.         int GSM_RST_ACT = 0;  
  72.         int GSM_MAX_RST_ACT = 8;  
  73.   
  74.         int CGMS_Count = 0; //短信发送数量   
  75.   
  76.         public int _CGMS_Count  
  77.         {  
  78.             get  
  79.             {  
  80.                 return CGMS_Count;  
  81.             }  
  82.         }  
  83.         public int _CMGD_MAX_ID  
  84.         {  
  85.             get  
  86.             {  
  87.                 return CMGD_MAX_ID;  
  88.             }  
  89.         }  
  90.   
  91.         public int _CMGD_ID  
  92.         {  
  93.             get  
  94.             {  
  95.                 return CMGD_ID;  
  96.             }  
  97.         }  
  98.   
  99.         public int _GSM_RST_ACT  
  100.         {  
  101.             get  
  102.             {  
  103.                 return GSM_RST_ACT;  
  104.             }  
  105.         }  
  106.   
  107.         public int _GSM_MAX_RST_ACT  
  108.         {  
  109.             get  
  110.             {  
  111.                 return GSM_MAX_RST_ACT;  
  112.             }  
  113.         }  
  114.  
  115.         #region 短信猫工作状态   
  116.   
  117.         string INF_GSM_CSQ;  
  118.         string INF_GSM_CSCS;  
  119.         string INF_GSM_CSCA;  
  120.         string INF_GSM_CNMI;  
  121.         bool INF_GSM_State;  
  122.   
  123.         public string _INF_GSM_CSQ  
  124.         {  
  125.             get  
  126.             {  
  127.                 return INF_GSM_CSQ;  
  128.             }  
  129.         }  
  130.   
  131.         public string _INF_GSM_CSCS  
  132.         {  
  133.             get  
  134.             {  
  135.                 return INF_GSM_CSCS;  
  136.             }  
  137.         }  
  138.   
  139.         public string _INF_GSM_CSCA  
  140.         {  
  141.             get  
  142.             {  
  143.                 return INF_GSM_CSCA;  
  144.             }  
  145.         }  
  146.   
  147.         public string _INF_GSM_CNMI  
  148.         {  
  149.             get  
  150.             {  
  151.                 return INF_GSM_CNMI;  
  152.             }  
  153.         }  
  154.   
  155.         public bool _INF_GSM_State  
  156.         {  
  157.             get  
  158.             {  
  159.                 return INF_GSM_State;  
  160.             }  
  161.         }  
  162.         #endregion   
  163.   
  164.   
  165.         private int _CmgsSleepTime;  
  166.         public GSMModem(string protName,  
  167.             string BaudRate,   
  168.             int CMGD_MAX_ID,   
  169.             System.Collections.ArrayList RecevingSM,  
  170.             System.Collections.ArrayList SendSM,  
  171.             int revTimerInterval,  
  172.             int sendTimerInterval,  
  173.             int selfCheckingTimerInterval,  
  174.             int CmgsSleepTime,  
  175.            System.Collections.ArrayList alAuthorizationNumber  
  176.             )  
  177.         {  
  178.             _CmgsSleepTime = CmgsSleepTime;//AT+CMGS 指令发送后,稍微延迟一定时间,让短信猫做出反应   
  179.   
  180.             this.alAuthorizationNumber = alAuthorizationNumber;//保存授权号码   
  181.   
  182.             this.CMGD_MAX_ID = CMGD_MAX_ID;  
  183.   
  184.             this.protName = protName;  
  185.             this.BaudRate = int.Parse(BaudRate);  
  186.             this.alRecevingSM = RecevingSM;  
  187.             this.alSendSM = SendSM;  
  188.   
  189.   
  190.             selfCheckingTimer.Enabled = false;  
  191.   
  192.             revTimer.Interval = revTimerInterval;  
  193.             revTimer.Enabled = false;  
  194.   
  195.             sendTimer.Interval = sendTimerInterval;  
  196.             sendTimer.Enabled = false;  
  197.   
  198.             revTimer.Tick += revTimer_Tick; //挂接短信轮询 定时器   
  199.             sendTimer.Tick += sendTimer_Tick;  
  200.   
  201.             selfCheckingTimer.Interval = selfCheckingTimerInterval;  
  202.             selfCheckingTimer.Tick += selfCheckingTimer_Tick;  
  203.   
  204.             Port.DataReceived += Port_DataReceived;  
  205.         }  
  206.   
  207.         public bool Start()  
  208.         {  
  209.             try  
  210.             {  
  211.                 Port.PortName = protName;  
  212.                 Port.BaudRate = BaudRate;  
  213.                 Port.Open();//打开串口   
  214.                 //短信猫 先自检,自检成功了,才能进行 接收 或 发送   
  215.                 selfCheckingTimer.Enabled = true;  
  216.   
  217.             }  
  218.             catch (Exception ex)  
  219.             {  
  220.                 MessageBox.Show(ex.Message);  
  221.                 return false;  
  222.             }  
  223.             return false;  
  224.         }  
  225.   
  226.         public bool Stop()  
  227.         {  
  228.   
  229.             sendTimer.Enabled = false;  
  230.             revTimer.Enabled = false;  
  231.             selfCheckingTimer.Enabled = false;  
  232.             Port.Close();  
  233.             CMGD_ID = 1;  
  234.             alRecevingSM.Clear();  
  235.             alSendSM.Clear();  
  236.             ErrorSMCount = 0;  
  237.             return true;  
  238.         }  
  239.   
  240.         void Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)  
  241.         {  
  242.             System.IO.Ports.SerialPort serialPort = Port;  
  243.   
  244.             int len = serialPort.BytesToRead;  
  245.             byte[] bs = new byte[len];  
  246.             serialPort.Read(bs, 0, len);  
  247.             if (len == 0)  
  248.             {  
  249.                 return;  
  250.             }  
  251.             else  
  252.             {  
  253.                 //接收处理   
  254.                 string r = Encoding.ASCII.GetString(bs, 0, len);  
  255.                 temp_gsm_str_buf += r;  
  256.                 //接收数据处理                   
  257.                 //txtGsmRevLog.Invoke(new EventHandler(DoUpdate), r);  //线程处理   
  258.                 Console.Write(r);  
  259.             }  
  260.         }  
  261.   
  262.   
  263.         private bool AuthorizationPhoneNumber(string phoneID)  
  264.         {  
  265.             for (int i = 0; i < alAuthorizationNumber.Count; i++)  
  266.             {  
  267.                 string s = alAuthorizationNumber[i].ToString();  
  268.                 if (phoneID.Equals(s))   
  269.                     return true;              
  270.             }  
  271.   
  272.             return false;  
  273.   
  274.         }  
  275.         bool DoGsmDataReceived()  
  276.         {  
  277.             //短信猫发回数据处理   
  278.             string str = temp_gsm_str_buf;  
  279.             if (str.Trim().StartsWith("+CMGR"))  
  280.             {  
  281.                 int P1 = str.IndexOf("0891");  
  282.                 if (P1 != -1)  
  283.                 {  
  284.                     str = str.Substring(P1);  
  285.                     int P2 = str.IndexOf("\r\n");  
  286.                     if (P2 != -1)  
  287.                     {  
  288.                         string uPDU = str.Substring(0, P2);  
  289.                         string decMsg = PDUDecoding.DecodingMsg(uPDU);  
  290.                         string[] content = decMsg.Split(',');  
  291.                         string stime = content[1].ToString();  
  292.                         string sphoneId = content[0].ToString().Replace("+86""");  
  293.                         string sgsmtxt = content[2].ToString();  
  294.                         //object[] row = { stime, sphoneId, sgsmtxt };   
  295.   
  296.                         if (AuthorizationPhoneNumber(sphoneId))  
  297.                         {  
  298.                             SMDATA sm = new SMDATA();  
  299.                             sm.sTime = stime;  
  300.                             sm.sPoneID = sphoneId;  
  301.                             sm.sContent = sgsmtxt;  
  302.                             sm.pdu = uPDU;  
  303.                             sm.sType = "Admin";  
  304.                             alRecevingSM.Add(sm);  
  305.   
  306.   
  307.                         }  
  308.                         else  
  309.                         {  
  310.                             //未经授权的用户,10086短信,广告信息,垃圾短信,用户手机号码   
  311.                             string[] gsmCmd = sgsmtxt.Trim().Split('+');  
  312.   
  313.                             string cmd = gsmCmd[0].ToString();  
  314.                             if (cmd == "CX")  
  315.                             {  
  316.                                 if (gsmCmd.Length == 1)  
  317.                                 {  
  318.                                     //仅限 用户手机号码   
  319.   
  320.                                     SMDATA sm = new SMDATA();  
  321.                                     sm.sTime = stime;  
  322.                                     sm.sPoneID = sphoneId;  
  323.                                     sm.sContent = "CX";  //让BI查询车辆信息   
  324.                                     sm.pdu = uPDU;  
  325.                                     sm.sType = "User";  
  326.                                     alRecevingSM.Add(sm);  
  327.                                 }  
  328.                             }  
  329.                             else  
  330.                             {  
  331.                                 Console.WriteLine("Error:" + stime + " " + sphoneId + " " + sgsmtxt);  
  332.                                 ErrorSMCount++;  
  333.                             }  
  334.                         }  
  335.   
  336.                         return true;  
  337.                     }  
  338.                 }  
  339.             }  
  340.             else  
  341.             {  
  342.   
  343.             }  
  344.   
  345.             return false;  
  346.         }  
  347.   
  348.   
  349.   
  350.         bool DoGsmDataSend()  
  351.         {  
  352.             //短信猫发回数据处理   
  353.             string str = temp_gsm_str_buf;  
  354.             if (str.Trim().IndexOf("+CMGS") > -1)  
  355.             {  
  356.                 temp_gsm_str_buf = "";  
  357.                 CGMS_Count++;  
  358.   
  359.                 return true;  
  360.             }  
  361.             else  
  362.             {  
  363.                 //接收到错误信息,可能是短信发送失败   
  364.             }  
  365.             temp_gsm_str_buf = "";  
  366.             return false;  
  367.         }  
  368.   
  369.         //短信发送 指令发送定时器   
  370.         int SendID;  
  371.         int AT_CMGS_LEN;  
  372.   
  373.         void sendTimer_Tick(object sender, EventArgs e)  
  374.         {  
  375.             WORK_STATE = 2;//设置短信猫工作模式为 发送   
  376.             if (DoGsmDataSend())  
  377.             {  
  378.                 alSendSM.RemoveAt(SendID);  
  379.             }  
  380.   
  381.             //没有发送的短信了   
  382.             if (alSendSM.Count == 0)  
  383.             {  
  384.                 CMGD_ID = 1;  
  385.                 sendTimer.Enabled = false//关闭发送   
  386.                 revTimer.Enabled = true;   //打开接收   
  387.             }  
  388.             else  
  389.             {  
  390.                 SendID = 0;  
  391.   
  392.                 SMDATA sendSM = (SMDATA)alSendSM[SendID];  
  393.                 string sPoneID = sendSM.sPoneID;  
  394.                 string sContent = sendSM.sContent;  
  395.   
  396.                 string msg = sContent;  
  397.                 string pdu = PDUDecoding.GetPDUMsg(sPoneID, msg);  
  398.                 AT_CMGS_LEN = PDUDecoding.getLenght(msg);  
  399.                 GsmWrite(string.Format("AT+CMGS={0}\r", AT_CMGS_LEN.ToString()));                  
  400.                 Thread.Sleep(_CmgsSleepTime);  //500延时,如果短信猫反应慢,设置为1000   
  401.                 GsmWrite(pdu + "\r");  
  402.   
  403.             }  
  404.   
  405.         }  
  406.   
  407.         //短信轮询 指令发送定时器   
  408.         void revTimer_Tick(object sender, EventArgs e)  
  409.         {  
  410.             //定时器每中断1次,接收1条指令   
  411.   
  412.             WORK_STATE = 1;//设置短信猫工作模式为 接收             
  413.   
  414.             if (DoGsmDataReceived())  
  415.             {  
  416.                 int old_CMGD_ID = CMGD_ID - 1;  
  417.                 GsmWrite("AT+CMGD=" + old_CMGD_ID.ToString() + "\r");  
  418.                 Thread.Sleep(1000);  
  419.             }  
  420.   
  421.             if (CMGD_ID > CMGD_MAX_ID)  
  422.             {  
  423.                 revTimer.Enabled = false;//停止接收   
  424.                 sendTimer.Enabled = true;//启动短信发送                 
  425.             }  
  426.             else  
  427.             {                
  428.   
  429.                 //再读取下一条             
  430.                 temp_gsm_str_buf = "";                
  431.   
  432.                 GsmWrite("AT+CMGR=" + CMGD_ID.ToString() + "\r");  
  433.   
  434.                 CMGD_ID++;  
  435.   
  436.             }  
  437.         }  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.         #region 短信猫初始信息   
  444.   
  445.   
  446.         private void selfCheckingTimer_Tick(object sender, EventArgs e)  
  447.         {  
  448.             //先处理串口接收的数据   
  449.             //Console.WriteLine(temp_gsm_str_buf);   
  450.   
  451.             WORK_STATE = 0;  //设置工作状态为自检   
  452.   
  453.             string str = "";  
  454.             if (temp_gsm_str_buf.Length > 0)  
  455.             {  
  456.   
  457.                 int CSQ = temp_gsm_str_buf.IndexOf("+CSQ");  
  458.   
  459.                 if (CSQ > -1)  
  460.                 {  
  461.                     str = temp_gsm_str_buf.Substring(CSQ);  
  462.                     string[] content = str.Trim().Split(':');  
  463.                     if (content.Length > 1)  
  464.                     {  
  465.                         INF_GSM_CSQ = content[1].ToString().Replace("OK""").Replace("\r\n""").Replace("\"""");  
  466.   
  467.                         GSM_RST_ACT++;  
  468.                     }  
  469.                     temp_gsm_str_buf = "";  
  470.                 }  
  471.   
  472.                 int CSCS = temp_gsm_str_buf.IndexOf("+CSCS");  
  473.                 if (CSCS > -1)  
  474.                 {  
  475.                     str = temp_gsm_str_buf.Substring(CSCS);  
  476.                     string[] content = str.Trim().Split(':');  
  477.                     if (content.Length > 1)  
  478.                     {  
  479.                         INF_GSM_CSCS = content[1].ToString().Replace("OK""").Replace("\r\n""").Replace("\"""");  
  480.                         GSM_RST_ACT++;  
  481.                     }  
  482.                     temp_gsm_str_buf = "";  
  483.                 }  
  484.   
  485.                 int CSCA = temp_gsm_str_buf.IndexOf("+CSCA");  
  486.                 if (CSCA > -1)  
  487.                 {  
  488.                     str = temp_gsm_str_buf.Substring(CSCA);  
  489.                     string[] content = str.Trim().Split(':');  
  490.                     if (content.Length > 1)  
  491.                     {  
  492.                         INF_GSM_CSCA = content[1].ToString().Replace("OK""").Replace("\r\n""").Replace("\"""");  
  493.                         GSM_RST_ACT++;  
  494.                     }  
  495.                     temp_gsm_str_buf = "";  
  496.                 }  
  497.   
  498.   
  499.                 int CNMI = temp_gsm_str_buf.IndexOf("+CNMI");  
  500.                 if (CNMI > -1)  
  501.                 {  
  502.                     str = temp_gsm_str_buf.Substring(CNMI);  
  503.                     string[] content = str.Trim().Split(':');  
  504.                     if (content.Length > 1)  
  505.                     {  
  506.                         INF_GSM_CNMI = content[1].ToString().Replace("OK""").Replace("\r\n""");  
  507.                         GSM_RST_ACT++;  
  508.                     }  
  509.                     temp_gsm_str_buf = "";  
  510.                 }  
  511.   
  512.             }  
  513.             //   
  514.             switch (GSM_RST_ACT)  
  515.             {  
  516.                 case 0: { GsmWrite("ATE0\r"); GSM_RST_ACT++; break; }  
  517.                 case 1: { GsmWrite("AT+CSQ\r"); break; }  
  518.                 case 2: { GsmWrite("AT+CMGF=1\r"); GSM_RST_ACT++; break; }  
  519.                 case 3: { GsmWrite("AT+CSCS?\r"); break; }  
  520.                 case 4: { GsmWrite("AT+CSCA?\r"); break; }  
  521.                 case 5: { GsmWrite("AT+CMGF=0\r"); GSM_RST_ACT++; break; }  
  522.   
  523.                 //AT+CNMI=0,0,0,0   
  524.                 //case 6: { GsmWrite("AT+CNMI=3,1,0,0\r"); GSM_ACT++; break; }   
  525.                 case 6: { GsmWrite("AT+CNMI=0,0,0,0\r"); GSM_RST_ACT++; break; }  
  526.   
  527.                 case 7: { GsmWrite("AT+CNMI?\r"); break; }  
  528.                 case 8:  
  529.                     {  
  530.                         INF_GSM_State = true;  
  531.                         selfCheckingTimer.Enabled = false;  
  532.   
  533.                         revTimer.Enabled = true;//启动 接收   
  534.   
  535.                         //btnSendTestSM.Enabled = true;   
  536.                         //checkBox1.Enabled = true;   
  537.   
  538.                         //btnSendTestSM.Enabled = true;   
  539.                         //timer_gsm_REST.Enabled = false;   
  540.                         break;  
  541.                     }  
  542.   
  543.                 default:  
  544.                     {  
  545.                         selfCheckingTimer.Enabled = false;  
  546.   
  547.   
  548.   
  549.                         //timer_gsm_REST.Enabled = false;   
  550.                         INF_GSM_State = false;  
  551.                         MessageBox.Show("短信猫自检失败!");  
  552.   
  553.   
  554.                         break;  
  555.                     }  
  556.             }  
  557.         }  
  558.  
  559.         #endregion   
  560.   
  561.         private void GsmWrite(string str)  
  562.         {  
  563.             Port.Write(str);  
  564.             Console.Write(str);  
  565.         }  
  566.   
  567.   
  568.         public int GetSMCount()  
  569.         {  
  570.             return alRecevingSM.Count;  
  571.         }  
  572.     }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多