VC写的短信收发程序

  1. #include "stdafx.h"   
  2. #include "Sms.h"   
  3. #include "Comm.h"   
  4.    
  5.    
  6. // 可打印字符串转换为字节数据   
  7. // 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}   
  8. // 输入: pSrc - 源字符串指针   
  9. //       nSrcLength - 源字符串长度   
  10. // 输出: pDst - 目标数据指针   
  11. // 返回: 目标数据长度   
  12. int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)   
  13. {   
  14.     for (int i = 0; i  nSrcLength; i += 2)   
  15.     {   
  16.         // 输出高4位   
  17.         if ((*pSrc >= '0') && (*pSrc = '9'))   
  18.         {   
  19.             *pDst = (*pSrc - '0') < 4;   
  20.         }   
  21.         else   
  22.         {   
  23.             *pDst = (*pSrc - 'A' + 10) < 4;   
  24.         }   
  25.    
  26.         pSrc++;   
  27.    
  28.         // 输出低4位   
  29.         if ((*pSrc>='0') && (*pSrc='9'))   
  30.         {   
  31.             *pDst |= *pSrc - '0';   
  32.         }   
  33.         else   
  34.         {   
  35.             *pDst |= *pSrc - 'A' + 10;   
  36.         }   
  37.    
  38.         pSrc++;   
  39.         TRACE("%s",pSrc);   
  40.         pDst++;   
  41.         TRACE("%s",pDst);   
  42.     }   
  43.    
  44.     // 返回目标数据长度   
  45.     return (nSrcLength / 2);   
  46. }   
  47.    
  48. // 字节数据转换为可打印字符串   
  49. // 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"    
  50. // 输入: pSrc - 源数据指针   
  51. //       nSrcLength - 源数据长度   
  52. // 输出: pDst - 目标字符串指针   
  53. // 返回: 目标字符串长度   
  54. int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)   
  55. {   
  56.     const char tab[]="0123456789ABCDEF";    // 0x0-0xf的字符查找表   
  57.    
  58.     for (int i = 0; i  nSrcLength; i++)   
  59.     {   
  60.         *pDst++ = tab[*pSrc >> 4];        // 输出高4位   
  61.         *pDst++ = tab[*pSrc & 0x0f];    // 输出低4位   
  62.         pSrc++;   
  63.     }   
  64.    
  65.     // 输出字符串加个结束符   
  66.     *pDst = '\0';      
  67.    
  68.     // 返回目标字符串长度   
  69.     return (nSrcLength * 2);   
  70. }   
  71.    
  72. // 7bit编码   
  73. // 输入: pSrc - 源字符串指针   
  74. //       nSrcLength - 源字符串长度   
  75. // 输出: pDst - 目标编码串指针   
  76. // 返回: 目标编码串长度   
  77. int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)   
  78. {   
  79.     int nSrc;       // 源字符串的计数值   
  80.     int nDst;       // 目标编码串的计数值   
  81.     int nChar;      // 当前正在处理的组内字符字节的序号,范围是0-7   
  82.     unsigned char nLeft;    // 上一字节残余的数据   
  83.    
  84.     // 计数值初始化   
  85.     nSrc = 0;   
  86.     nDst = 0;   
  87.    
  88.     // 将源串每8个字节分为一组,压缩成7个字节   
  89.     // 循环该处理过程,直至源串被处理完   
  90.     // 如果分组不到8字节,也能正确处理   
  91.     while (nSrc  nSrcLength)   
  92.     {   
  93.         // 取源字符串的计数值的最低3位   
  94.         nChar = nSrc & 7;   
  95.    
  96.         // 处理源串的每个字节   
  97.         if(nChar == 0)   
  98.         {   
  99.             // 组内第一个字节,只是保存起来,待处理下一个字节时使用   
  100.             nLeft = *pSrc;   
  101.         }   
  102.         else   
  103.         {   
  104.             // 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节   
  105.             *pDst = (*pSrc < (8-nChar)) | nLeft;   
  106.    
  107.             // 将该字节剩下的左边部分,作为残余数据保存起来   
  108.             nLeft = *pSrc >> nChar;   
  109.    
  110.             // 修改目标串的指针和计数值   
  111.             pDst++;   
  112.             nDst++;   
  113.         }   
  114.    
  115.         // 修改源串的指针和计数值   
  116.         pSrc++;   
  117.         nSrc++;   
  118.     }   
  119.    
  120.     // 返回目标串长度   
  121.     return nDst;   
  122. }   
  123.    
  124. // 7bit解码   
  125. // 输入: pSrc - 源编码串指针   
  126. //       nSrcLength - 源编码串长度   
  127. // 输出: pDst - 目标字符串指针   
  128. // 返回: 目标字符串长度   
  129. int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)   
  130. {   
  131.     int nSrc;       // 源字符串的计数值   
  132.     int nDst;       // 目标解码串的计数值   
  133.     int nByte;      // 当前正在处理的组内字节的序号,范围是0-6   
  134.     unsigned char nLeft;    // 上一字节残余的数据   
  135.    
  136.     // 计数值初始化   
  137.     nSrc = 0;   
  138.     nDst = 0;   
  139.        
  140.     // 组内字节序号和残余数据初始化   
  141.     nByte = 0;   
  142.     nLeft = 0;   
  143.    
  144.     // 将源数据每7个字节分为一组,解压缩成8个字节   
  145.     // 循环该处理过程,直至源数据被处理完   
  146.     // 如果分组不到7字节,也能正确处理   
  147.     while(nSrc<nSrcLength)   
  148.     {   
  149.         // 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节   
  150.         *pDst = ((*pSrc < nByte) | nLeft) & 0x7f;   
  151.    
  152.         // 将该字节剩下的左边部分,作为残余数据保存起来   
  153.         nLeft = *pSrc >> (7-nByte);   
  154.    
  155.         // 修改目标串的指针和计数值   
  156.         pDst++;   
  157.         nDst++;   
  158.    
  159.         // 修改字节计数值   
  160.         nByte++;   
  161.    
  162.         // 到了一组的最后一个字节   
  163.         if(nByte == 7)   
  164.         {   
  165.             // 额外得到一个目标解码字节   
  166.             *pDst = nLeft;   
  167.    
  168.             // 修改目标串的指针和计数值   
  169.             pDst++;   
  170.             nDst++;   
  171.    
  172.             // 组内字节序号和残余数据初始化   
  173.             nByte = 0;   
  174.             nLeft = 0;   
  175.         }   
  176.    
  177.         // 修改源串的指针和计数值   
  178.         pSrc++;   
  179.         nSrc++;   
  180.     }   
  181.    
  182.     // 输出字符串加个结束符   
  183.     *pDst = '\0';   
  184.    
  185.     // 返回目标串长度   
  186.     return nDst;   
  187. }   
  188.    
  189. // 8bit编码   
  190. // 输入: pSrc - 源字符串指针   
  191. //       nSrcLength - 源字符串长度   
  192. // 输出: pDst - 目标编码串指针   
  193. // 返回: 目标编码串长度   
  194. int gsmEncode8bit(const char* pSrc, unsigned char* pDst, int nSrcLength)   
  195. {   
  196.     // 简单复制   
  197.     memcpy(pDst, pSrc, nSrcLength);   
  198.    
  199.     return nSrcLength;   
  200. }   
  201.    
  202. // 8bit解码   
  203. // 输入: pSrc - 源编码串指针   
  204. //       nSrcLength -  源编码串长度   
  205. // 输出: pDst -  目标字符串指针   
  206. // 返回: 目标字符串长度   
  207. int gsmDecode8bit(const unsigned char* pSrc, char* pDst, int nSrcLength)   
  208. {   
  209.     // 简单复制   
  210.     memcpy(pDst, pSrc, nSrcLength);   
  211.    
  212.     // 输出字符串加个结束符   
  213.     *pDst = '\0';   
  214.    
  215.     return nSrcLength;   
  216. }   
  217.    
  218. // UCS2编码   
  219. // 输入: pSrc - 源字符串指针   
  220. //       nSrcLength - 源字符串长度   
  221. // 输出: pDst - 目标编码串指针   
  222. // 返回: 目标编码串长度   
  223. int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)   
  224. {   
  225.     int nDstLength;     // UNICODE宽字符数目   
  226.     WCHAR wchar[128];   // UNICODE串缓冲区   
  227.    
  228.     // 字符串-->UNICODE串   
  229.     nDstLength = MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);   
  230.    
  231.     // 高低字节对调,输出   
  232.     for(int i=0; i<nDstLength; i++)   
  233.     {   
  234.         *pDst++ = wchar[i] >> 8;      // 先输出高位字节   
  235.         *pDst++ = wchar[i] & 0xff;      // 后输出低位字节   
  236.     }   
  237. //  TRACE("%s",wchar);   
  238.     // 返回目标编码串长度   
  239.     return nDstLength * 2;   
  240. }   
  241.    
  242. // UCS2解码   
  243. // 输入: pSrc - 源编码串指针   
  244. //       nSrcLength -  源编码串长度   
  245. // 输出: pDst -  目标字符串指针   
  246. // 返回: 目标字符串长度   
  247. int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)   
  248. {   
  249.     int nDstLength;     // UNICODE宽字符数目   
  250.     WCHAR wchar[128];   // UNICODE串缓冲区   
  251.    
  252.     // 高低字节对调,拼成UNICODE   
  253.     for(int i=0; i<nSrcLength/2; i++)   
  254.     {   
  255.         wchar[i] = *pSrc++ < 8;  // 先高位字节   
  256.         wchar[i] |= *pSrc++;        // 后低位字节   
  257.     }   
  258.    
  259.     // UNICODE串-->字符串   
  260.     nDstLength = WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);   
  261.    
  262.     // 输出字符串加个结束符   
  263.     pDst[nDstLength] = '\0';   
  264.    
  265.     // 返回目标字符串长度   
  266.     return nDstLength;   
  267. }   
  268.    
  269. // 正常顺序的字符串转换为两两颠倒的字符串,若长度为奇数,补'F'凑成偶数   
  270. // 如:"8613851872468" --> "683158812764F8"   
  271. // 输入: pSrc - 源字符串指针   
  272. //       nSrcLength - 源字符串长度   
  273. // 输出: pDst - 目标字符串指针   
  274. // 返回: 目标字符串长度   
  275. int gsmInvertNumbers(const char* pSrc, char* pDst, int nSrcLength)   
  276. {   
  277.     int nDstLength;     // 目标字符串长度   
  278.     char ch;            // 用于保存一个字符   
  279.    
  280.     // 复制串长度   
  281.     nDstLength = nSrcLength;   
  282.    
  283.     // 两两颠倒   
  284.     for(int i=0; i<nSrcLength;i+=2)   
  285.     {   
  286.         ch = *pSrc++;       // 保存先出现的字符   
  287.         *pDst++ = *pSrc++;  // 复制后出现的字符   
  288.         *pDst++ = ch;       // 复制先出现的字符   
  289.     }   
  290.    
  291.     // 源串长度是奇数吗?   
  292.     if(nSrcLength & 1)   
  293.     {   
  294.         *(pDst-2) = 'F';    // 补'F'   
  295.         nDstLength++;       // 目标串长度加1   
  296.     }   
  297.    
  298.     // 输出字符串加个结束符   
  299.     *pDst = '\0';   
  300.    
  301.     // 返回目标字符串长度   
  302.     return nDstLength;   
  303. }   
  304.    
  305. // 两两颠倒的字符串转换为正常顺序的字符串   
  306. // 如:"683158812764F8" --> "8613851872468"   
  307. // 输入: pSrc - 源字符串指针   
  308. //       nSrcLength - 源字符串长度   
  309. // 输出: pDst - 目标字符串指针   
  310. // 返回: 目标字符串长度   
  311. int gsmSerializeNumbers(const char* pSrc, char* pDst, int nSrcLength)   
  312. {   
  313.     int nDstLength;     // 目标字符串长度   
  314.     char ch;            // 用于保存一个字符   
  315.    
  316.     // 复制串长度   
  317.     nDstLength = nSrcLength;   
  318.    
  319.     // 两两颠倒   
  320.     for(int i=0; i<nSrcLength;i+=2)   
  321.     {   
  322.         ch = *pSrc++;       // 保存先出现的字符   
  323.         *pDst++ = *pSrc++;  // 复制后出现的字符   
  324.         *pDst++ = ch;       // 复制先出现的字符   
  325.     }   
  326.    
  327.     // 最后的字符是'F'吗?   
  328.     if(*(pDst-1) == 'F')   
  329.     {   
  330.         pDst--;   
  331.         nDstLength--;       // 目标字符串长度减1   
  332.     }   
  333.    
  334.     // 输出字符串加个结束符   
  335.     *pDst = '\0';   
  336.    
  337.     // 返回目标字符串长度   
  338.     return nDstLength;   
  339. }   
  340.    
  341. // PDU编码,用于编制、发送短消息   
  342. // 输入: pSrc - 源PDU参数指针   
  343. // 输出: pDst - 目标PDU串指针   
  344. // 返回: 目标PDU串长度   
  345. int gsmEncodePdu(const SM_PARAM* pSrc, char* pDst)   
  346. {   
  347.     int nLength;            // 内部用的串长度   
  348.     int nDstLength;         // 目标PDU串长度   
  349.     unsigned char buf[256]; // 内部用的缓冲区   
  350.    
  351.     // SMSC地址信息段   
  352.     nLength = strlen(pSrc->SCA); // SMSC地址字符串的长度    
  353.     buf[0] = (char)((nLength & 1) == 0 ? nLength : nLength + 1) / 2 + 1;    // SMSC地址信息长度   
  354. //  TRACE("%c",buf[0]);   
  355.     buf[1] = 0x91;      // 固定: 用国际格式号码   
  356.     nDstLength = gsmBytes2String(buf, pDst, 2);     // 转换2个字节到目标PDU串   
  357. //  TRACE("%s",pDst);   
  358.     nDstLength += gsmInvertNumbers(pSrc->SCA, &pDst[nDstLength], nLength);   // 转换SMSC号码到目标PDU串   
  359. //  TRACE("%s",pDst);   
  360.    
  361.     // TPDU段基本参数、目标地址等   
  362.     nLength = strlen(pSrc->TPA); // TP-DA地址字符串的长度   
  363.     buf[0] = 0x11;                  // 是发送短信(TP-MTI=01),TP-VP用相对格式(TP-VPF=10)   
  364.     buf[1] = 0;                     // TP-MR=0   
  365.     buf[2] = (char)nLength;         // 目标地址数字个数(TP-DA地址字符串真实长度)   
  366.     buf[3] = 0x91;                  // 固定: 用国际格式号码   
  367.     nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 4);       // 转换4个字节到目标PDU串   
  368.     nDstLength += gsmInvertNumbers(pSrc->TPA, &pDst[nDstLength], nLength);   // 转换TP-DA到目标PDU串   
  369.    
  370.     // TPDU段协议标识、编码方式、用户信息等   
  371.     nLength = strlen(pSrc->TP_UD);   // 用户信息字符串的长度   
  372.     buf[0] = pSrc->TP_PID;           // 协议标识(TP-PID)   
  373.     buf[1] = pSrc->TP_DCS;           // 用户信息编码方式(TP-DCS)   
  374.     buf[2] = 0;                     // 有效期(TP-VP)为5分钟   
  375.     if(pSrc->TP_DCS == GSM_7BIT)    
  376.     {   
  377.         // 7-bit编码方式   
  378.         buf[3] = nLength;           // 编码前长度   
  379.         nLength = gsmEncode7bit(pSrc->TP_UD, &buf[4], nLength+1) + 4;    // 转换TP-DA到目标PDU串   
  380.     }   
  381.     else if(pSrc->TP_DCS == GSM_UCS2)   
  382.     {   
  383.         // UCS2编码方式   
  384.         buf[3] = gsmEncodeUcs2(pSrc->TP_UD, &buf[4], nLength);   // 转换TP-DA到目标PDU串          
  385.         nLength = buf[3] + 4;       // nLength等于该段数据长度   
  386.     }   
  387.     else   
  388.     {   
  389.         // 8-bit编码方式   
  390.         buf[3] = gsmEncode8bit(pSrc->TP_UD, &buf[4], nLength);   // 转换TP-DA到目标PDU串   
  391.         nLength = buf[3] + 4;       // nLength等于该段数据长度   
  392.     }   
  393.     nDstLength += gsmBytes2String(buf, &pDst[nDstLength], nLength);     // 转换该段数据到目标PDU串   
  394.    
  395.     // 返回目标字符串长度   
  396.     return nDstLength;   
  397. }   
  398.    
  399. // PDU解码,用于接收、阅读短消息   
  400. // 输入: pSrc - 源PDU串指针   
  401. // 输出: pDst - 目标PDU参数指针   
  402. // 返回: 用户信息串长度   
  403. int gsmDecodePdu(const char* pSrc, SM_PARAM* pDst)   
  404. {   
  405.     int nDstLength;         // 目标PDU串长度   
  406.     unsigned char tmp;      // 内部用的临时字节变量   
  407.     unsigned char buf[256]; // 内部用的缓冲区   
  408.    
  409.     // SMSC地址信息段   
  410.     gsmString2Bytes(pSrc, &tmp, 2); // 取长度   
  411.     tmp = (tmp - 1) * 2;    // SMSC号码串长度   
  412.     pSrc += 4;          // 指针后移,忽略了SMSC地址格式   
  413.     gsmSerializeNumbers(pSrc, pDst->SCA, tmp);   // 转换SMSC号码到目标PDU串   
  414.     pSrc += tmp;        // 指针后移   
  415.    
  416.     // TPDU段基本参数   
  417.     gsmString2Bytes(pSrc, &tmp, 2); // 取基本参数   
  418.     pSrc += 2;      // 指针后移   
  419.    
  420.     // 取回复号码   
  421.     gsmString2Bytes(pSrc, &tmp, 2); // 取长度   
  422.     if(tmp & 1) tmp += 1;   // 调整奇偶性   
  423.     pSrc += 4;          // 指针后移,忽略了回复地址(TP-RA)格式   
  424.     gsmSerializeNumbers(pSrc, pDst->TPA, tmp);   // 取TP-RA号码   
  425.     pSrc += tmp;        // 指针后移   
  426.    
  427.     // TPDU段协议标识、编码方式、用户信息等   
  428.     gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_PID, 2); // 取协议标识(TP-PID)   
  429.     pSrc += 2;      // 指针后移   
  430.     gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_DCS, 2); // 取编码方式(TP-DCS)   
  431.     pSrc += 2;      // 指针后移   
  432.     gsmSerializeNumbers(pSrc, pDst->TP_SCTS, 14);        // 服务时间戳字符串(TP_SCTS)    
  433.     pSrc += 14;     // 指针后移   
  434.     gsmString2Bytes(pSrc, &tmp, 2); // 用户信息长度(TP-UDL)   
  435.     pSrc += 2;      // 指针后移   
  436.     if(pDst->TP_DCS == GSM_7BIT)    
  437.     {   
  438.         // 7-bit解码   
  439.         nDstLength = gsmString2Bytes(pSrc, buf, tmp & 7 ? (int)tmp * 7 / 4 + 2 : (int)tmp * 7 / 4); // 格式转换   
  440.         gsmDecode7bit(buf, pDst->TP_UD, nDstLength); // 转换到TP-DU   
  441.         nDstLength = tmp;   
  442.     }   
  443.     else if(pDst->TP_DCS == GSM_UCS2)   
  444.     {   
  445.         // UCS2解码   
  446.         nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);           // 格式转换   
  447.         nDstLength = gsmDecodeUcs2(buf, pDst->TP_UD, nDstLength);    // 转换到TP-DU   
  448.     }   
  449.     else   
  450.     {   
  451.         // 8-bit解码   
  452.         nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);           // 格式转换   
  453.         nDstLength = gsmDecode8bit(buf, pDst->TP_UD, nDstLength);    // 转换到TP-DU   
  454.     }   
  455.    
  456.     // 返回目标字符串长度   
  457.     return nDstLength;   
  458. }   
  459.    
  460.    
  461. // 初始化GSM状态   
  462. BOOL gsmInit()   
  463. {   
  464.     char ans[128];      // 应答串   
  465.    
  466.     // 测试GSM-MODEM的存在性   
  467.     WriteComm("AT\r", 3);   
  468.     ReadComm(ans, 128);   
  469.     if (strstr(ans, "OK") == NULL)  return FALSE;   
  470.    
  471.     // ECHO OFF   
  472.     WriteComm("ATE0\r", 5);   
  473.     ReadComm(ans, 128);   
  474.    
  475.     // PDU模式   
  476.     WriteComm("AT+CMGF=0\r", 10);   
  477.     ReadComm(ans, 128);   
  478.    
  479.     return TRUE;   
  480. }   
  481.    
  482.    
  483. // 发送短消息,仅发送命令,不读取应答   
  484. // 输入: pSrc - 源PDU参数指针   
  485.    
  486. int gsmSendMessage(SM_PARAM* pSrc)   
  487. {   
  488.     int nPduLength;     // PDU串长度   
  489.     unsigned char nSmscLength;  // SMSC串长度   
  490.     int nLength;        // 串口收到的数据长度   
  491.     char cmd[16];       // 命令串   
  492.     char pdu[512];      // PDU串   
  493.     char ans[128];      // 应答串   
  494.    
  495.     nPduLength = gsmEncodePdu(pSrc, pdu);   // 根据PDU参数,编码PDU串   
  496.     strcat(pdu, "\x01a");       // 以Ctrl-Z结束   
  497. //  TRACE("%s", pdu);  //zhao   
  498.     gsmString2Bytes(pdu, &nSmscLength, 2);  // 取PDU串中的SMSC信息长度   
  499.     nSmscLength++;      // 加上长度字节本身   
  500.    
  501.     // 命令中的长度,不包括SMSC信息长度,以数据字节计   
  502.     sprintf(cmd, "AT+CMGS=%d\r", nPduLength / 2 - nSmscLength); // 生成命令   
  503.    
  504. //  TRACE("%s", cmd);     
  505. //  TRACE("%s\n", pdu);   
  506.    
  507.     WriteComm(cmd, strlen(cmd));    // 先输出命令串   
  508.    
  509.     nLength = ReadComm(ans, 128);   // 读应答数据   
  510.    
  511.     // 根据能否找到"\r\n> "决定成功与否   
  512.     if(nLength == 4 && strncmp(ans, "\r\n> ", 4) == 0)   
  513.     {   
  514.         return WriteComm(pdu, strlen(pdu));     // 得到肯定回答,继续输出PDU串   
  515.     }   
  516.    
  517.     return 0;   
  518. }   
  519.    
  520.    
  521. // 读取短消息,仅发送命令,不读取应答   
  522. // 用+CMGL代替+CMGR,可一次性读出全部短消息   
  523.    
  524. int gsmReadMessageList()   
  525. {   
  526.     return WriteComm("AT+CMGL\r", 8);  //zhao    
  527. }   
  528.    
  529.    
  530. // 删除短消息,仅发送命令,不读取应答   
  531. // 输入: index - 短消息序号,1-255   
  532.    
  533. int gsmDeleteMessage(int index)   
  534. {   
  535.     char cmd[16];       // 命令串   
  536.    
  537.     sprintf(cmd, "AT+CMGD=%d\r", index);    // 生成命令   
  538.    
  539.     // 输出命令串   
  540.     return WriteComm(cmd, strlen(cmd));   
  541. }   
  542.    
  543. // 读取GSM MODEM的应答,可能是一部分   
  544. // 输出: pBuff - 接收应答缓冲区   
  545. // 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR   
  546. // 备注: 可能需要多次调用才能完成读取一次应答,首次调用时应将pBuff初始化   
  547.    
  548. int gsmGetResponse(SM_BUFF* pBuff)   
  549. {   
  550.     int nLength;        // 串口收到的数据长度   
  551.     int nState;   
  552.    
  553.     // 从串口读数据,追加到缓冲区尾部   
  554.     nLength = ReadComm(&pBuff->data[pBuff->len], 128);       
  555.     pBuff->len += nLength;   
  556.    
  557.     // 确定GSM MODEM的应答状态   
  558.     nState = GSM_WAIT;   
  559.     if ((nLength > 0) && (pBuff->len >= 4))   
  560.     {   
  561.         if (strncmp(&pBuff->data[pBuff->len - 4], "OK\r\n", 4) == 0)  nState = GSM_OK;   
  562.         else if (strstr(pBuff->data, "+CMS ERROR") != NULL) nState = GSM_ERR;   
  563.     }   
  564.    
  565.     return nState;   
  566. }   
  567.    
  568.    
  569. // 从列表中解析出全部短消息   
  570. // 输入: pBuff - 短消息列表缓冲区   
  571. // 输出: pMsg - 短消息缓冲区   
  572. // 返回: 短消息条数   
  573. int gsmParseMessageList(SM_PARAM* pMsg, SM_BUFF* pBuff)   
  574. {   
  575.     int nMsg;           // 短消息计数值   
  576.     char* ptr;          // 内部用的数据指针   
  577.    
  578.     nMsg = 0;   
  579.     ptr = pBuff->data;   
  580.    
  581.     // 循环读取每一条短消息, 以"+CMGL:"开头   
  582.     while((ptr = strstr(ptr, "+CMGL:")) != NULL)   
  583.     {   
  584.         ptr += 6;       // 跳过"+CMGL:", 定位到序号   
  585.         sscanf(ptr, "%d", &pMsg->index); // 读取序号   
  586. //      TRACE("  index=%d\n",pMsg->index);   
  587.    
  588.         ptr = strstr(ptr, "\r\n");  // 找下一行   
  589.         if (ptr != NULL)   
  590.         {   
  591.             ptr += 2;       // 跳过"\r\n", 定位到PDU   
  592.                
  593.             gsmDecodePdu(ptr, pMsg);    // PDU串解码   
  594.    
  595.             pMsg++;     // 准备读下一条短消息   
  596.             nMsg++;     // 短消息计数加1   
  597.         }   
  598.     }   
  599.    
  600.     return nMsg;   
  601. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值