SMSProcess.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. #include "StdAfx.h"
  2. #include "SMSProcess.h"
  3. namespace SMSProcess
  4. {
  5. //////////////////////////////////////////////////////////////////////////
  6. CCommRS232 *_pSMSComm = NULL;
  7. CRITICAL_SECTION _csRS232;
  8. INT _nMaxSMSChar = 70; // 短信猫一条短信最大支持的字符个数;
  9. const INT MAX_SIZE = 512;
  10. int g_nCMGFStatus = 0;//保存现在的传输格式 发送短信用0 接收短信用1;
  11. HANDLE _hSMSReceiveThread = NULL;
  12. HANDLE _hCtrlEvent = NULL;
  13. int g_nMakeCall = 0; // 发送后是否先拔打电话提醒
  14. PFCALLBACK gEnalbeAlarmCallBack = NULL;
  15. #define PDU_MAXNUMLEN 70 // 最大号码长度;
  16. #define PDU_MAXUNICODELEN 70 // pdu Unicode的最大长度;
  17. #define NUM_NAT 0x81 // 非国际号码前缀 phone number type for non- '+'(national) numbers
  18. #define NUM_INT 0x91 // 国际号码前缀 phone number type for numbers prefixed by '+'(international)
  19. //--------------------------------------------------------------------------------
  20. // FOR gsm sms
  21. #define GSM_MAX_WAIT_TIME 12000 //发送短消息时的最长等待时间
  22. #define GSM_RESPONSE_NORESPONSE 0 //无响应
  23. #define GSM_RESPONSE_OK 1 //正确返回
  24. #define GSM_RESPONSE_ERROR 2 //返回错误信息,含错误代码
  25. #define GSM_RESPONSE_UNKNOWN 3 //返回无法确定的信息
  26. #define GSM_CMS_ERROR 0 //CMS Error -- Message service error
  27. #define GSM_CME_ERROR 1 //CME Error
  28. #define NOP 183 //非可见字符
  29. #define MAX_WRITE_STR_LEN 3840
  30. #define MAX_READ_STR_LEN 512//256
  31. #define MIN_READ_STR_LEN 6
  32. #define MAX_TMPSTR_LEN 512//256
  33. void SwapChars(IN OUT TCHAR *szNumber);
  34. char ACharToBChar(char c);
  35. CString DeleteEnterForStr( CString sData );
  36. int MyCharCount(const char* szMsg);
  37. INT Str2PDU_Unicode(const TCHAR *szMsg, TCHAR *szPDU);
  38. BOOL GetValidResponse(const TCHAR *szBuff, int nCount, TCHAR *szResponse);
  39. int GSMResponse(const TCHAR *szBuff,int nCount, int &nErrorType, int &nErrorCode);
  40. int SendSMS(const char *szNo,const char *szMsg,char* szEvent);
  41. int ReceiveSms(int iIndex, char* strTelFrom, char* strTime, char* strReceiveMsg, int nCharSize);
  42. char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize);
  43. void TransformPDUPhone( IN CONST TCHAR *szPhone, OUT TCHAR* szPDUPhone, IN CONST INT& nPDUPhoneLen);
  44. void TransformPDUMsg(IN CONST TCHAR *szPhone, IN CONST TCHAR* szMsg, IN BOOL bNeedReport, OUT TCHAR* szPduContent, IN CONST INT& nContLen);
  45. DWORD WINAPI SMSReceiveThread( LPVOID lpParameter);
  46. //////////////////////////////////////////////////////////////////////////
  47. /************************************************************************/
  48. /* 函数:SwapChars[2/22/2016 IT];
  49. /* 描述:交换编码 13823652665F --> 3128632566F5, 用于电话号码编码;
  50. /* 参数:;
  51. /* [IN]szNumber:需要转换的电话号码;
  52. /* 返回:void;
  53. /* 注意:;
  54. /* 示例:;
  55. /*
  56. /* 修改:;
  57. /* 日期:;
  58. /* 内容:;
  59. /************************************************************************/
  60. void SwapChars(IN OUT TCHAR *szNumber)
  61. {
  62. int nLength;
  63. int nPosition;
  64. TCHAR ch;
  65. nLength = (int)_tcslen(szNumber);
  66. for ( nPosition = 0; nPosition < nLength-1; nPosition += 2 )
  67. {
  68. ch = szNumber[nPosition];
  69. szNumber[nPosition] = szNumber[nPosition+1];
  70. szNumber[nPosition+1] = ch;
  71. }
  72. }
  73. /************************************************************************/
  74. /* 函数:TransformPDUPhone[2/22/2016 IT];
  75. /* 描述:将电话号码转换为GSM PDU格式;
  76. /* 参数:;
  77. /* [IN]szPhone:需要转换的电话号码;
  78. /* [OUT]szPDUPhone:转换后的PDU电话号码;
  79. /* 返回:void;
  80. /* 注意:;
  81. /* 示例:;
  82. /*
  83. /* 修改:;
  84. /* 日期:;
  85. /* 内容:;
  86. /************************************************************************/
  87. void TransformPDUPhone( IN CONST TCHAR *szPhone, OUT TCHAR* szPDUPhone, IN CONST INT& nPDUPhoneLen)
  88. {
  89. TCHAR szTemp[PDU_MAXNUMLEN] = {0};
  90. INT nType = 0;
  91. INT nLen = 0;
  92. nLen = (INT)_tcslen(szPhone);
  93. if ( szPhone[0] == _T('+'))
  94. {
  95. _tcsncpy_s(szTemp, szPhone + 1, PDU_MAXNUMLEN);
  96. nType = NUM_INT;
  97. nLen--;
  98. }
  99. else
  100. {
  101. _tcsncpy_s(szTemp, szPhone, PDU_MAXNUMLEN);
  102. nType = NUM_NAT;
  103. }
  104. if ( _tcslen(szTemp) %2 )
  105. {
  106. _tcscat_s(szTemp, _T("F"));
  107. }
  108. SwapChars(szTemp);
  109. _stprintf_s(szPDUPhone, nPDUPhoneLen, _T("%02X%02X%s"), nLen, nType, szTemp);
  110. }
  111. /************************************************************************/
  112. /* 函数:TransformPDUMsg[2/22/2016 IT];
  113. /* 描述:将短消息(包括电话号码、文本)转换为GSM PDU格式;
  114. /* 参数:;
  115. /* [IN]szPhone :需要转换的电话号码;
  116. /* [IN]szMsg :需要转换的短信消息文本;
  117. /* [IN] bNeedReport:是否需要提供信息报告;
  118. /* [OUT] szPduContent:转换后的GSM PDU文本;
  119. /* [IN] nContLen:szPduContent缓冲区大小;
  120. /* 返回:void;
  121. /* 注意:;
  122. /* 示例:;
  123. /*
  124. /* 修改:;
  125. /* 日期:;
  126. /* 内容:;
  127. /************************************************************************/
  128. void TransformPDUMsg(IN CONST TCHAR *szPhone, IN CONST TCHAR* szMsg, IN BOOL bNeedReport, OUT TCHAR* szPduContent, IN CONST INT& nContLen)
  129. {
  130. INT nType = 0;
  131. INT nCodingScheme = 0;
  132. TCHAR szPDUPhone[PDU_MAXNUMLEN] = {0};
  133. TransformPDUPhone(szPhone,szPDUPhone, PDU_MAXNUMLEN);
  134. nType = 0X10 + 0X01; // 0x11 -- 0001 0001;
  135. if ( bNeedReport )
  136. {
  137. nType += 0X20; // 0x20 -- 0010 0000;
  138. }
  139. nCodingScheme = 0X08; // 0x08 -- 0000 1000 -- 16bit UCS2;
  140. TCHAR szPduMsg[1024] = {0};
  141. Str2PDU_Unicode(szMsg, szPduMsg);
  142. _stprintf_s(szPduContent, nContLen, _T("00%02X00%s00%02X00%02X%s"),
  143. //00 - 默认短消息中心;
  144. nType,// FO;
  145. //00 - TP-MO;
  146. szPDUPhone,
  147. //00 - TP-PID;
  148. nCodingScheme,
  149. //00 - TP-VP;
  150. _tcslen(szPduMsg)/2,
  151. szPduMsg);
  152. }
  153. /************************************************************************/
  154. /* 函数:Str2PDU_Unicode[2/22/2016 IT];
  155. /* 描述:将普通文本转换为gsm需要的unicode编码格式(可用于中、英文模式);
  156. /* 参数:;
  157. /* [IN] szMsg:需要转换的字符串文本;
  158. /* [OUT] szPDU:转换后的pdu unicode文本;
  159. /* [IN/OUT] :;
  160. /* 返回:int <=0 表示转换失败,否则为unicode字符长度;
  161. /* 注意:;
  162. /* 示例:;
  163. /*
  164. /* 修改:;
  165. /* 日期:;
  166. /* 内容:;
  167. /************************************************************************/
  168. INT Str2PDU_Unicode(IN CONST TCHAR *szMsg, TCHAR *szPDU)
  169. {
  170. WCHAR wszPDU[PDU_MAXUNICODELEN];
  171. int nCount = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szMsg, (int)_tcslen(szMsg), wszPDU,PDU_MAXUNICODELEN );
  172. if (nCount<1)
  173. {
  174. return 0;
  175. }
  176. for (int i=0;i<nCount;i++)
  177. {
  178. wsprintf(szPDU+i*4,_T("%4.4X"),wszPDU[i]);
  179. }
  180. return nCount;
  181. }
  182. /************************************************************************/
  183. /* 函数:GSMResponse[2/22/2016 IT];
  184. /* 描述:根据GSM模块返回的数据判断GSM模块当前的状态;
  185. /* 参数:;
  186. /* [IN] szBuff:串口收到的数据;
  187. /* [IN] nCount:数据的个数;
  188. /* [OUT] nErrorType:如果返回错误信息,返回的错误类型 0 - CME error, 1 - CMS error;
  189. /* [OUT] nErrorCode:如果返回错误信息,返回的错误代码;
  190. /* [IN/OUT] :;
  191. /* 返回:int
  192. /* GSM_RESPONSE_NORESPONSE 0 //无响应;
  193. /* GSM_RESPONSE_OK 1 //正确返回
  194. /* GSM_RESPONSE_ERROR 2 //返回错误信息,含错误代码
  195. /* GSM_RESPONSE_UNKNOWN 3 //返回无法确定的信息
  196. /* 注意:;
  197. /* 示例:;
  198. /*
  199. /* 修改:;
  200. /* 日期:;
  201. /* 内容:;
  202. /************************************************************************/
  203. int GSMResponse(const char *szBuff,int nCount, int &nErrorType, int &nErrorCode)
  204. {
  205. if (nCount==0)
  206. {
  207. return GSM_RESPONSE_NORESPONSE;
  208. }
  209. if (nCount<MIN_READ_STR_LEN)
  210. {
  211. return GSM_RESPONSE_UNKNOWN;
  212. }
  213. char szResponse[MAX_TMPSTR_LEN];
  214. //获取信息正文
  215. if ( !GetValidResponse(szBuff,nCount, szResponse) )
  216. {
  217. return GSM_RESPONSE_UNKNOWN;
  218. }
  219. if (szResponse[0]=='O' && szResponse[1]=='K' || strstr(szBuff, "OK") != NULL)
  220. {
  221. return GSM_RESPONSE_OK;
  222. }
  223. if (szResponse[5]=='E' &&
  224. szResponse[6]=='R' &&
  225. szResponse[7]=='R' &&
  226. szResponse[8]=='O' &&
  227. szResponse[9]=='R' )
  228. {
  229. //Get error type
  230. if ( szResponse[3]=='E' )
  231. {
  232. nErrorType = GSM_CME_ERROR;
  233. }
  234. else
  235. {
  236. nErrorType = GSM_CMS_ERROR;
  237. }
  238. //get error code
  239. TCHAR szErrorCode[8];
  240. _tcsncpy_s(szErrorCode,szResponse+12,strlen(szResponse)-12);
  241. szErrorCode[strlen(szResponse)-12] = '\0';
  242. nErrorCode = atoi(szErrorCode);
  243. return GSM_RESPONSE_ERROR;
  244. }// end if (szResponse...)
  245. return GSM_RESPONSE_UNKNOWN;
  246. }
  247. /************************************************************************/
  248. /* 函数:GetValidResponse[2/22/2016 IT];
  249. /* 描述:对串口返回的数据进行处理 1.判断是否有效 2.去掉首尾多余信息 3.返回有意义的数据;
  250. /* 参数:;
  251. /* [IN] szBuff:串口收到的数据;
  252. /* [IN] nCount:数据的个数;
  253. /* [OUT] szResponse:返回的(关键)正文信息;
  254. /* [IN/OUT] :;
  255. /* 返回:BOOL 成功为TRUE,否则FALSE;
  256. /* 注意:;
  257. /* 示例:;
  258. /*
  259. /* 修改:;
  260. /* 日期:;
  261. /* 内容:;
  262. /************************************************************************/
  263. BOOL GetValidResponse(const char *szBuff, int nCount, char *szResponse)
  264. {
  265. if ( nCount<6 )
  266. {
  267. return FALSE;
  268. }
  269. // if ( szBuff[nCount-1] != 0x0A ||
  270. // szBuff[nCount-2] != 0x0D )
  271. // {
  272. // return FALSE;
  273. // }
  274. INT i = 0;
  275. for ( i=nCount-3;i>0;i--)
  276. {
  277. if ( szBuff[i]==0x0A && szBuff[i-1]==0x0D )
  278. {
  279. break;
  280. }//end if
  281. }//end for
  282. if (i<1)
  283. {
  284. return FALSE;
  285. }
  286. strncpy(szResponse,szBuff+i+1,nCount-2-(i+1) ); // _tcsncpy_s
  287. szResponse[nCount-2-(i+1)] = '\0';
  288. return TRUE;
  289. }
  290. //============================================================================================
  291. /************************************************************************/
  292. /* 函数:[2/22/2016 IT];
  293. /* 描述:;
  294. /* 参数:;
  295. /* [IN] :;
  296. /* [OUT] :;
  297. /* [IN/OUT] :;
  298. /* 返回:void;
  299. /* 注意:;
  300. /* 示例:;
  301. /*
  302. /* 修改:;
  303. /* 日期:;
  304. /* 内容:;
  305. /************************************************************************/
  306. int SendSMS(const char *szNo,const char *szMsg,char* szEvent)
  307. {
  308. EnterCriticalSection( &_csRS232 );
  309. if( g_nCMGFStatus == 1 )
  310. {
  311. char szBuf[MAX_SIZE] = {0};
  312. g_nCMGFStatus = 0;
  313. strcpy(szBuf, "AT+CMGF=0\r");
  314. int nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  315. nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  316. }
  317. char WriteBuff[MAX_WRITE_STR_LEN+1] = {0};
  318. char ReadBuff[MAX_READ_STR_LEN+1] = {0};
  319. int iOffset = 0;
  320. int iDataLength = 0;
  321. char szTmp[MAX_TMPSTR_LEN+1] = {0};
  322. int nTmp;
  323. char szPDU[512];
  324. TransformPDUMsg(szNo,szMsg,FALSE,szPDU,512);
  325. sprintf(WriteBuff,"AT+CMGS=");
  326. iOffset += 8;
  327. sprintf(WriteBuff+iOffset,"%03d",strlen(szPDU)/2-1);
  328. iOffset = (int)strlen(WriteBuff);
  329. WriteBuff[iOffset] = 0x0d;
  330. iOffset++;
  331. //LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
  332. INT nReturnSize = _pSMSComm->Write((BYTE*)WriteBuff, iOffset);
  333. nReturnSize = _pSMSComm->Read((BYTE*)szTmp, MAX_READ_STR_LEN);
  334. //LOG4C_HEX_DUMP((LOG_NOTICE, szTmp, nReturnSize));
  335. iOffset = 0;
  336. sprintf(WriteBuff+iOffset,szPDU);
  337. iOffset += (int)strlen(szPDU);
  338. WriteBuff[iOffset++] = 0x1a;
  339. //LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
  340. nReturnSize = _pSMSComm->Write((BYTE*)WriteBuff, iOffset);
  341. int nErrorType,nErrorCode; //发送错误类型、编码
  342. int nResponse = GSM_RESPONSE_NORESPONSE; //发送结果
  343. Sleep(3000);//发送完短信时等待3秒发送
  344. do
  345. {
  346. nTmp = _pSMSComm->Read((BYTE*)szTmp,MAX_READ_STR_LEN);
  347. //LOG4C_HEX_DUMP((LOG_NOTICE, szTmp, nTmp));
  348. if (nTmp>0 && iDataLength < MAX_READ_STR_LEN)
  349. {
  350. strncpy(ReadBuff+iDataLength,szTmp,nTmp);
  351. iDataLength += nTmp;
  352. }
  353. else
  354. break;
  355. } while(1);
  356. nResponse = GSMResponse(ReadBuff,iDataLength,nErrorType,nErrorCode);
  357. switch(nResponse)
  358. {
  359. case GSM_RESPONSE_OK:
  360. sprintf(szEvent,"Send OK!");
  361. LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
  362. return 0;
  363. break;
  364. case GSM_RESPONSE_NORESPONSE:
  365. sprintf(szEvent,"GSM Modem No Response! Please Check The Connection!");
  366. LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
  367. return ERR_CODE_SMS_GSM_NO_RESPONSE;
  368. break;
  369. case GSM_RESPONSE_ERROR:
  370. sprintf(szEvent,"Send fail! The card maybe has little money, Please recharge!");
  371. LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
  372. return ERR_CODE_SMS_GSM_ERROR_RESPONSE;
  373. break;
  374. case GSM_RESPONSE_UNKNOWN:
  375. sprintf(szEvent,"Send Timeout. The Message may Send OK!");
  376. LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
  377. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  378. default:
  379. sprintf(szEvent,"Send Timeout. The Message may Send OK!");
  380. LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
  381. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  382. }//end switch
  383. LeaveCriticalSection( &_csRS232 );
  384. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  385. }
  386. /************************************************************************/
  387. /* 函数:[2/22/2016 IT];
  388. /* 描述:;
  389. /* 参数:;
  390. /* [IN] :;
  391. /* [OUT] :;
  392. /* [IN/OUT] :;
  393. /* 返回:void;
  394. /* 注意:;
  395. /* 示例:;
  396. /*
  397. /* 修改:;
  398. /* 日期:;
  399. /* 内容:;
  400. /************************************************************************/
  401. int ReceiveSms(int iIndex, char* strTelFrom, char* strTime, char* strReceiveMsg, int nCharSize)
  402. {
  403. EnterCriticalSection( &_csRS232 );
  404. int nRet=-1;//0:关闭报警 1:恢复正常
  405. int nLen=0;
  406. char szBuf[MAX_SIZE] = {0};
  407. //
  408. if( g_nCMGFStatus==0 )
  409. {
  410. g_nCMGFStatus = 1;
  411. strcpy(szBuf, "AT+CMGF=1\r");
  412. nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  413. nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  414. }
  415. sprintf(szBuf, "AT+CMGR=%d\r", iIndex);
  416. nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  417. nLen = _pSMSComm->Read((BYTE *)szBuf, 511);
  418. if( nLen<50 )//没有短信
  419. {
  420. LeaveCriticalSection( &_csRS232 );
  421. return nRet;
  422. }
  423. CString str;
  424. int nReaded = 0;
  425. int nTelServiceType = 0x91;
  426. int nTelType = 0x91;
  427. char szTelService[512] = {0};
  428. char szTel[512] = {0};
  429. char szTime[512] = {0};
  430. char szWideBuf[512] = {0};
  431. char szReceiAscii[512] = {0};
  432. char *pData = strstr(szBuf, "+CMGR:");
  433. char *pOK = strstr(szBuf, "\r\nOK\r\n");
  434. if(pData!= NULL && pOK!=NULL && pOK>pData)
  435. {
  436. //pOK[0] = 0;
  437. memset(pOK, 0, strlen("\r\nOK\r\n"));
  438. char* pTemp = pData+6;//strlen("+CMGR:") = 6;
  439. nReaded = atoi(pTemp);//短信已读取标志和类型
  440. pTemp = strstr(pTemp, "\r\n");
  441. str.Format("%s",pTemp );
  442. str = DeleteEnterForStr( str );
  443. str = str.MakeLower();
  444. if( str=="open" )
  445. nRet = 1;
  446. if( str=="close" )
  447. nRet = 0;
  448. }
  449. //清除
  450. //if(strlen(strTelFrom) > 0)
  451. {
  452. sprintf(szBuf, "AT+CMGD=%d\r", iIndex);
  453. nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  454. nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  455. }
  456. LeaveCriticalSection( &_csRS232 );
  457. return nRet;//return strlen(strTelFrom) > 0;
  458. }
  459. /************************************************************************/
  460. /* 函数:[2/22/2016 IT];
  461. /* 描述:;
  462. /* 参数:;
  463. /* [IN] :;
  464. /* [OUT] :;
  465. /* [IN/OUT] :;
  466. /* 返回:void;
  467. /* 注意:;
  468. /* 示例:;
  469. /*
  470. /* 修改:;
  471. /* 日期:;
  472. /* 内容:;
  473. /************************************************************************/
  474. DWORD WINAPI SMSReceiveThread(LPVOID lpParameter)
  475. {
  476. do
  477. {
  478. char sTelFrom[MAX_SIZE],sTime[MAX_SIZE],sReceiveMsg[MAX_SIZE];
  479. int nRet = ReceiveSms( 1, sTelFrom, sTime, sReceiveMsg, MAX_SIZE );
  480. if( nRet==1 )
  481. {
  482. gEnalbeAlarmCallBack( nRet );
  483. }
  484. else if( nRet==0 )
  485. {
  486. gEnalbeAlarmCallBack( nRet );
  487. }
  488. }while( WaitForSingleObject( _hCtrlEvent, 2000L ) == WAIT_TIMEOUT );
  489. return 0;
  490. }
  491. //删除字符串中的换行
  492. /************************************************************************/
  493. /* 函数:[2/22/2016 IT];
  494. /* 描述:;
  495. /* 参数:;
  496. /* [IN] :;
  497. /* [OUT] :;
  498. /* [IN/OUT] :;
  499. /* 返回:void;
  500. /* 注意:;
  501. /* 示例:;
  502. /*
  503. /* 修改:;
  504. /* 日期:;
  505. /* 内容:;
  506. /************************************************************************/
  507. CString DeleteEnterForStr( CString sData )
  508. {
  509. CString sRet;
  510. int iLen=sData.GetLength();
  511. char* pc=new char[iLen];
  512. memset(pc,0,iLen);
  513. int j=0;
  514. for(int i=0;i <iLen;i++)
  515. {
  516. if((sData[i]==0x0D)||(sData[i]==0x0A))
  517. continue;
  518. pc[j++]=sData[i];
  519. }
  520. sRet.Format("%s",pc );
  521. delete[] pc;
  522. return sRet;
  523. }
  524. //////////////////////////////////////////////////////////////////////////
  525. /************************************************************************/
  526. /* 函数:[2/22/2016 IT];
  527. /* 描述:;
  528. /* 参数:;
  529. /* [IN] :;
  530. /* [OUT] :;
  531. /* [IN/OUT] :;
  532. /* 返回:void;
  533. /* 注意:;
  534. /* 示例:;
  535. /*
  536. /* 修改:;
  537. /* 日期:;
  538. /* 内容:;
  539. /************************************************************************/
  540. int MyCharCount(const char* szMsg)
  541. {
  542. int i = 0;
  543. int nCharCount = 0;
  544. while(szMsg[i] != 0)
  545. {
  546. if(szMsg[i] & 0x80)
  547. {
  548. ASSERT(szMsg[i+1] & 0x80);
  549. if(szMsg[i+1] & 0x80)
  550. i++;
  551. }
  552. i++;
  553. nCharCount++;
  554. }
  555. return nCharCount;
  556. }
  557. /************************************************************************/
  558. /* 函数:[2/22/2016 IT];
  559. /* 描述:;
  560. /* 参数:;
  561. /* [IN] :;
  562. /* [OUT] :;
  563. /* [IN/OUT] :;
  564. /* 返回:void;
  565. /* 注意:;
  566. /* 示例:;
  567. /*
  568. /* 修改:;
  569. /* 日期:;
  570. /* 内容:;
  571. /************************************************************************/
  572. char ACharToBChar(char c)
  573. {
  574. if(c >= '0' && c <= '9')
  575. c = c - '0';
  576. else if(c >= 'A' && c <= 'F')
  577. c = c - 'A' + 10;
  578. else if(c >= 'a' && c <='f')
  579. c = c - 'a' + 10;
  580. return c;
  581. }
  582. /************************************************************************/
  583. /* 函数:[2/22/2016 IT];
  584. /* 描述:;
  585. /* 参数:;
  586. /* [IN] :;
  587. /* [OUT] :;
  588. /* [IN/OUT] :;
  589. /* 返回:void;
  590. /* 注意:;
  591. /* 示例:;
  592. /*
  593. /* 修改:;
  594. /* 日期:;
  595. /* 内容:;
  596. /************************************************************************/
  597. char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize)
  598. {
  599. char* pRtn = NULL;
  600. int i = 0;
  601. int nCharCount = 0;
  602. while(pMsgAll[i] != 0)
  603. {
  604. if(pMsgAll[i] & 0x80)
  605. {
  606. ASSERT(pMsgAll[i+1] & 0x80);
  607. if(pMsgAll[i+1] & 0x80)
  608. i++;
  609. }
  610. i++;
  611. nCharCount++;
  612. if(pMsgAll[i] == 0 || //已经到了结束符
  613. nCharCount == nSize || //大小已经达到
  614. nCharCount == nSize-1 && (pMsgAll[i]&0x80)) //或者只差最后一个字节并且后续的一个字节为汉字
  615. {
  616. memcpy(szSeg, pMsgAll, i);
  617. szSeg[i] = 0;
  618. if(pMsgAll[i] != 0)
  619. pRtn = (char*)(pMsgAll+i);
  620. break;
  621. }
  622. }
  623. return pRtn;
  624. }
  625. //////////////////////////////////////////////////////////////////////////
  626. INT SMS_INIT( IN CONST BYTE& byCommPort, IN CONST DWORD& dwBaudRate, IN CONST BYTE& bySize, IN CONST BYTE& byParity, IN CONST BYTE& byStopBits, IN CONST BYTE& byStartAddr, IN CONST INT& nInterval, IN CONST INT& nMaxSMSChar )
  627. {
  628. _nMaxSMSChar = nMaxSMSChar;
  629. if ( _pSMSComm == NULL )
  630. {
  631. _pSMSComm = new CCommRS232;
  632. if ( !_pSMSComm->InitComm(byCommPort, dwBaudRate, bySize, byParity, byStopBits, byStartAddr, nInterval) )
  633. {
  634. delete _pSMSComm;
  635. _pSMSComm = NULL;
  636. return ERR_CODE_SMS_OPEN_COMM;
  637. }
  638. }
  639. // 设置成PDU模式;
  640. TCHAR szBuf[MAX_SIZE] = _T("AT+CMGF=0\r");
  641. INT nReturnSize = _pSMSComm->Write((BYTE*)szBuf, (INT)_tcslen(szBuf));
  642. memset(szBuf, 0, MAX_SIZE);
  643. nReturnSize = _pSMSComm->Read((BYTE*)szBuf, MAX_SIZE -1);
  644. if (nReturnSize)
  645. {
  646. if ( _tcsstr(szBuf, _T("OK")) == NULL )
  647. {
  648. delete _pSMSComm;
  649. _pSMSComm = NULL;
  650. return -1;
  651. }
  652. }
  653. else
  654. {
  655. delete _pSMSComm;
  656. _pSMSComm = NULL;
  657. return -1;
  658. }
  659. // 把卡里的第一条短信删掉;
  660. _tcscpy_s(szBuf, _T("AT+CMGD=1\r"));
  661. nReturnSize = _pSMSComm->Write((BYTE*)szBuf,(INT)_tcslen(szBuf));
  662. memset(szBuf, 0, MAX_SIZE);
  663. nReturnSize = _pSMSComm->Read((BYTE*)szBuf, MAX_SIZE -1);
  664. InitializeCriticalSection(&_csRS232);
  665. return 0;
  666. }
  667. VOID SMS_UNINIT()
  668. {
  669. // 结束线程;
  670. if (_hCtrlEvent)
  671. SetEvent(_hCtrlEvent);
  672. if ( _hSMSReceiveThread )
  673. {
  674. WaitForSingleObject(_hSMSReceiveThread, INFINITE);
  675. CloseHandle(_hSMSReceiveThread);
  676. _hSMSReceiveThread = NULL;
  677. }
  678. if (_hCtrlEvent)
  679. CloseHandle(_hCtrlEvent);
  680. _hCtrlEvent = NULL;
  681. DeleteCriticalSection(&_csRS232);
  682. // 清理串口句柄;
  683. if ( _pSMSComm )
  684. {
  685. delete _pSMSComm;
  686. _pSMSComm = NULL;
  687. }
  688. }
  689. INT SMS_SENDMSG( IN CONST TCHAR *pTel, IN CONST TCHAR *pContent, IN TCHAR *pErrorMsg )
  690. {
  691. if ( pContent == NULL || pTel == NULL )
  692. return -1;
  693. INT nRet = 0;
  694. BOOL bRet = FALSE;
  695. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  696. CString strMsg = pContent;
  697. if ( MyCharCount(strMsg) < 70 )
  698. {
  699. nRet = SendSMS(pTel, strMsg, pErrorMsg);
  700. }
  701. else
  702. {
  703. char* szMsg2 = new char[strlen(strMsg)+1];
  704. strcpy(szMsg2, strMsg);
  705. char* pMsgSegLeft = (char*)szMsg2;
  706. bRet = TRUE;
  707. while (1)
  708. {
  709. char szMsgSegSend[255] = {0};
  710. int nMaxCharCanSend = _nMaxSMSChar; // 最大能够发送的字符,暂固定为70
  711. pMsgSegLeft = PickSegTxt(pMsgSegLeft, szMsgSegSend, nMaxCharCanSend);
  712. nRet = SendSMS(pTel, szMsgSegSend, pErrorMsg);
  713. if(!nRet)
  714. {
  715. bRet = FALSE;
  716. break;
  717. }
  718. if(pMsgSegLeft == NULL)
  719. break;
  720. }
  721. delete []szMsg2;
  722. }
  723. if(bRet && g_nMakeCall == 1)
  724. {
  725. //拨号通知用户留心短信(拨号20秒)
  726. char WriteBuff[MAX_WRITE_STR_LEN+1] = {0};
  727. char ReadBuff[MAX_READ_STR_LEN+1] = {0};
  728. sprintf(WriteBuff,"ATD%s;\r", pTel);
  729. int iOffset = (int)strlen(WriteBuff);
  730. _pSMSComm->Write( (BYTE *)WriteBuff, iOffset );
  731. int nLen = _pSMSComm->Read( (BYTE *)ReadBuff, MAX_READ_STR_LEN );
  732. COleDateTime timeStart = COleDateTime::GetCurrentTime();
  733. while (1)
  734. {
  735. #ifndef _DEBUG
  736. //CString strToStop;
  737. //if(GetTempVar("ToStop", strToStop) && strToStop == "1")
  738. // break;
  739. #endif
  740. COleDateTimeSpan span = COleDateTime::GetCurrentTime() - timeStart;
  741. if(span.GetTotalSeconds() > 20)
  742. break;
  743. }
  744. sprintf(WriteBuff,"ATH\r");
  745. iOffset = (int)strlen(WriteBuff);
  746. _pSMSComm->Write((BYTE *)WriteBuff, iOffset);
  747. nLen = _pSMSComm->Read((BYTE *)ReadBuff, MAX_READ_STR_LEN);
  748. }
  749. return nRet;
  750. }
  751. BOOL SMS_GETCSQ( int iMin,int iMax,int &iNowData ) // 得到短信貓的信号
  752. {
  753. bool bRet=false;
  754. EnterCriticalSection( &_csRS232 );
  755. char szBuf[MAX_SIZE] = {0};
  756. //取号码
  757. strcpy(szBuf, "AT+CSQ\r");
  758. int nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  759. memset( szBuf,0,sizeof(szBuf) );
  760. nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  761. CString str;
  762. str.Format("%s",szBuf );
  763. int nPos=str.Find("CSQ: " );
  764. str = str.Mid( nPos+5,2 );
  765. iNowData = atoi(str);
  766. if( iNowData>=iMin && iNowData<=iMax )
  767. bRet = true;
  768. LeaveCriticalSection( &_csRS232 );
  769. return bRet;
  770. }
  771. INT SMS_SetCallBack(PFCALLBACK Func)
  772. {
  773. if( Func == NULL || gEnalbeAlarmCallBack != NULL )
  774. return 0;
  775. gEnalbeAlarmCallBack = Func;
  776. _hCtrlEvent = ::CreateEvent(NULL,TRUE,0,0);
  777. DWORD dwReceiveSmsThreadId;
  778. _hSMSReceiveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SMSReceiveThread, NULL, 0, &dwReceiveSmsThreadId);
  779. return 0;
  780. }
  781. };