SmsProcess.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. #include "stdafx.h"
  2. #include "SmsProcess.h"
  3. #include "CommAsyn.h"
  4. #include "CommRS232.h"
  5. #include "Sms.h"
  6. HANDLE g_hRunObject = NULL;
  7. HANDLE g_hReceiveSmsThread = NULL;
  8. DWORD WINAPI ReceiveSmsThread(LPVOID lpParameter);
  9. typedef int (WINAPI *PFCALLBACK)( BOOL bEnableAlarm );//true 恢复正常 false 报警不打电话不发短信
  10. PFCALLBACK gEnalbeAlarmCallBack=NULL;
  11. CCommRS232 *g_pComm = NULL;
  12. CHAR g_strDirectory[MAX_PATH + 1] = {0}; // 软件所在路径
  13. int g_nNeedLanguageTrans = -1; // 是否需要繁简转换
  14. int g_nMaxChar = 70; // 短信猫一条短信最大支持的字符个数
  15. int g_nMakeCall = 0; // 发送后是否先拔打电话提醒
  16. extern CSmsApp theApp;
  17. int MyCharCount(const char* szMsg);
  18. char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize);
  19. void Make_PDU_Message( const char *szNumber,
  20. const char *szMsg,
  21. BOOL bNeedReport,
  22. char *szPDU );
  23. void Make_PDU_Number(const char *szNumber, char *szPDUNumber);
  24. void SwapChars(char *szNumber);
  25. int Str2PDU_Unicode(const char *szMsg, char *szPDU);
  26. int GSMResponse(const char *szBuff,int nCount, int &nErrorType, int &nErrorCode);
  27. BOOL GetValidResponse(const char *szBuff, int nCount, char *szResponse);
  28. char ACharToBChar(char c);
  29. int SendSMS(
  30. const char *szNo,
  31. const char *szMsg,
  32. char* szEvent
  33. );
  34. int SMS_DLLInit( char *pDirectory,
  35. int nAddr, // 保留,因为短信猫是串口232没有地址
  36. int nCommPort, // 串口号
  37. int nRate, // 波特率
  38. int nDataBit, // 数据位
  39. int nStopBit, // 停止位
  40. int nParity, // 校验位
  41. int nInterval, // 间隔时间
  42. int nNeedLanguageTrans, // 是否需要语言转换
  43. int nMaxChar, // 短信猫一条短信最大支持的字符个数
  44. int nMakeCall ) // 发送后是否先拔打电话提醒
  45. {
  46. strcpy(g_strDirectory, pDirectory);
  47. g_nNeedLanguageTrans = nNeedLanguageTrans;
  48. g_nMaxChar = nMaxChar;
  49. g_nMakeCall = nMakeCall;
  50. if( g_pComm == NULL )
  51. {
  52. g_pComm = new CCommRS232;
  53. PORTPARAM portParam;
  54. portParam.StartAddr = nAddr; //起止地址
  55. portParam.PortNo = nCommPort; //Com端口
  56. portParam.BaudRate = nRate; //波特率
  57. portParam.ByteSize = nDataBit; // Number of bits/byte, 4-8
  58. portParam.StopBits = nStopBit; /* 结束位 0,1,2 = 1, 1.5, 2 */
  59. portParam.Parity = nParity; /* 校验位 0-4=None,Odd,Even,Mark,Space */
  60. portParam.Interval = nInterval; //间隔时间
  61. if(!g_pComm->InitParam(&portParam))
  62. {
  63. delete g_pComm;
  64. g_pComm = NULL;
  65. return ERR_CODE_SMS_OPEN_COMM;
  66. }
  67. #if 1
  68. // 设置成PDU模式
  69. char szBuf[MAX_SIZE] = {0};
  70. //取号码
  71. strcpy(szBuf, "AT+CMGF=1\r");
  72. int nLen = g_pComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  73. nLen = g_pComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  74. #endif
  75. }
  76. return 0;
  77. }
  78. void SMS_DLLUnInit()
  79. {
  80. if( g_hRunObject )
  81. MTVERIFY( SetEvent( g_hRunObject ) );
  82. if( g_hReceiveSmsThread )
  83. {
  84. MTVERIFY( WaitForSingleObject( g_hReceiveSmsThread, INFINITE ) != WAIT_FAILED );
  85. MTVERIFY( CloseHandle( g_hReceiveSmsThread ) );
  86. g_hReceiveSmsThread = NULL;
  87. }
  88. // 关闭串口
  89. if( g_pComm )
  90. {
  91. delete g_pComm;
  92. g_pComm = NULL;
  93. }
  94. return;
  95. }
  96. int SMS_DLLSendSms(char *pTel, // 手机号码
  97. char *pContent, // 发送内容
  98. char *pErrorMsg // 错误消息
  99. )
  100. {
  101. int nRet = 0;
  102. BOOL bOK = FALSE;
  103. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  104. CString strMsg = CString(pContent);
  105. if(g_nNeedLanguageTrans)
  106. strMsg = theApp.FtToJt(strMsg);
  107. if(MyCharCount(strMsg) < 70)
  108. nRet = SendSMS(pTel, strMsg, pErrorMsg);
  109. else
  110. {
  111. char* szMsg2 = new char[strlen(strMsg)+1];
  112. strcpy(szMsg2, strMsg);
  113. char* pMsgSegLeft = (char*)szMsg2;
  114. bOK = TRUE;
  115. while (1)
  116. {
  117. char szMsgSegSend[255] = {0};
  118. int nMaxCharCanSend = g_nMaxChar; // 最大能够发送的字符,暂固定为70
  119. pMsgSegLeft = PickSegTxt(pMsgSegLeft, szMsgSegSend, nMaxCharCanSend);
  120. nRet = SendSMS(pTel, szMsgSegSend, pErrorMsg);
  121. if(!nRet)
  122. {
  123. bOK = FALSE;
  124. break;
  125. }
  126. if(pMsgSegLeft == NULL)
  127. break;
  128. }
  129. delete []szMsg2;
  130. }
  131. if(bOK && g_nMakeCall == 1)
  132. {
  133. //拨号通知用户留心短信(拨号20秒)
  134. char WriteBuff[MAX_WRITE_STR_LEN+1] = {0};
  135. char ReadBuff[MAX_READ_STR_LEN+1] = {0};
  136. sprintf(WriteBuff,"ATD%s;\r", pTel);
  137. int iOffset = (int)strlen(WriteBuff);
  138. g_pComm->Write( (BYTE *)WriteBuff, iOffset );
  139. int nLen = g_pComm->Read( (BYTE *)ReadBuff, MAX_READ_STR_LEN );
  140. COleDateTime timeStart = COleDateTime::GetCurrentTime();
  141. while (1)
  142. {
  143. #ifndef _DEBUG
  144. //CString strToStop;
  145. //if(GetTempVar("ToStop", strToStop) && strToStop == "1")
  146. // break;
  147. #endif
  148. COleDateTimeSpan span = COleDateTime::GetCurrentTime() - timeStart;
  149. if(span.GetTotalSeconds() > 20)
  150. break;
  151. }
  152. sprintf(WriteBuff,"ATH\r");
  153. iOffset = (int)strlen(WriteBuff);
  154. g_pComm->Write((BYTE *)WriteBuff, iOffset);
  155. nLen = g_pComm->Read((BYTE *)ReadBuff, MAX_READ_STR_LEN);
  156. }
  157. return nRet;
  158. }
  159. bool SMS_DLLGetCSQ( int iMin,int iMax,int &iNowData ) // 得到短信貓的信号
  160. {
  161. bool bRet=false;
  162. char szBuf[MAX_SIZE] = {0};
  163. //取号码
  164. strcpy(szBuf, "AT+CSQ\r");
  165. int nLen = g_pComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  166. memset( szBuf,0,sizeof(szBuf) );
  167. nLen = g_pComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  168. CString str;
  169. str.Format("%s",szBuf );
  170. int nPos=str.Find("CSQ: " );
  171. str = str.Mid( nPos+5,2 );
  172. iNowData = atoi(str);
  173. if( iNowData>=iMin && iNowData<=iMax )
  174. bRet = true;
  175. return bRet;
  176. }
  177. int SMS_DLLSetCallBack(PFCALLBACK Func)
  178. {
  179. if( Func==NULL || gEnalbeAlarmCallBack!=NULL )
  180. return 0;
  181. gEnalbeAlarmCallBack = Func;
  182. MTVERIFY (g_hRunObject = ::CreateEvent(
  183. NULL, /* Security */
  184. TRUE, /* Manual event */
  185. 0, /* Clear on creation */
  186. 0));
  187. DWORD dwReceiveSmsThreadId;
  188. MTVERIFY( g_hReceiveSmsThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveSmsThread,NULL, 0, &dwReceiveSmsThreadId) );
  189. return 0;
  190. }
  191. int MyCharCount(const char* szMsg)
  192. {
  193. int i = 0;
  194. int nCharCount = 0;
  195. while(szMsg[i] != 0)
  196. {
  197. if(szMsg[i] & 0x80)
  198. {
  199. ASSERT(szMsg[i+1] & 0x80);
  200. if(szMsg[i+1] & 0x80)
  201. i++;
  202. }
  203. i++;
  204. nCharCount++;
  205. }
  206. return nCharCount;
  207. }
  208. char ACharToBChar(char c)
  209. {
  210. if(c >= '0' && c <= '9')
  211. c = c - '0';
  212. else if(c >= 'A' && c <= 'F')
  213. c = c - 'A' + 10;
  214. else if(c >= 'a' && c <='f')
  215. c = c - 'a' + 10;
  216. return c;
  217. }
  218. char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize)
  219. {
  220. char* pRtn = NULL;
  221. int i = 0;
  222. int nCharCount = 0;
  223. while(pMsgAll[i] != 0)
  224. {
  225. if(pMsgAll[i] & 0x80)
  226. {
  227. ASSERT(pMsgAll[i+1] & 0x80);
  228. if(pMsgAll[i+1] & 0x80)
  229. i++;
  230. }
  231. i++;
  232. nCharCount++;
  233. if(pMsgAll[i] == 0 || //已经到了结束符
  234. nCharCount == nSize || //大小已经达到
  235. nCharCount == nSize-1 && (pMsgAll[i]&0x80)) //或者只差最后一个字节并且后续的一个字节为汉字
  236. {
  237. memcpy(szSeg, pMsgAll, i);
  238. szSeg[i] = 0;
  239. if(pMsgAll[i] != 0)
  240. pRtn = (char*)(pMsgAll+i);
  241. break;
  242. }
  243. }
  244. return pRtn;
  245. }
  246. //============================================================================================
  247. // 函数名称:Make_PDU_Number
  248. // 函数功能:将电话号码转换为gsm pdu格式
  249. // 函数参数:
  250. // [IN] char *szNumber
  251. // 需要转换的电话号码
  252. // [OUT] char *szPDUNumber
  253. // 转换后的电话号码
  254. // 返回值:
  255. //
  256. //============================================================================================
  257. void Make_PDU_Number(const char *szNumber, char *szPDUNumber)
  258. {
  259. char szTmp[PDU_MAXNUMLEN];
  260. int nType, nLen;
  261. nLen = (int)strlen(szNumber);
  262. if ( szNumber[0] == '+')
  263. {
  264. strncpy(szTmp, szNumber + 1, PDU_MAXNUMLEN);
  265. nType = NUM_INT;
  266. nLen--;
  267. }
  268. else
  269. {
  270. strncpy(szTmp,szNumber,PDU_MAXNUMLEN);
  271. nType = NUM_NAT;
  272. }//end if (szNumber[0]...)
  273. if (strlen(szTmp) % 2)
  274. {
  275. strcat(szTmp,"F");
  276. }
  277. SwapChars(szTmp);
  278. sprintf(szPDUNumber,"%02X%02X%s",nLen,nType,szTmp);
  279. }
  280. //============================================================================================
  281. // 函数名称:Make_PDU_Message
  282. // 函数功能:将短消息(包括电话号码、文本)转换为GSM PDU格式
  283. // 函数参数:
  284. // [IN] char *szNumber
  285. // 需要转换的电话号码
  286. // [IN] char *szMsg
  287. // 需要转换的短消息文本
  288. // [IN] BOOL bNeedReport
  289. // 是否需要提供信息报告
  290. // [OUT] char *szPDU
  291. // 转换后的gsm pdu文本
  292. // 返回值:
  293. //
  294. //============================================================================================
  295. void Make_PDU_Message( const char *szNumber,
  296. const char *szMsg,
  297. BOOL bNeedReport,
  298. char *szPDU )
  299. {
  300. int nType, nCodingScheme;
  301. char szPDU_Number[PDU_MAXNUMLEN];
  302. Make_PDU_Number(szNumber,szPDU_Number);
  303. nType = 0x10 + 0x01; // 0x11 -- 0001 0001
  304. if (bNeedReport)
  305. {
  306. nType = nType + 0x20; // 0x20 -- 0010 0000
  307. }
  308. nCodingScheme = 0x08; // 0x08 -- 0000 1000 -- 16bit UCS2
  309. char szPDU_Msg[500];
  310. Str2PDU_Unicode(szMsg,szPDU_Msg);
  311. //sprintf(pdu,"00%02X00%s00%02XFF%02X%s",
  312. sprintf(szPDU,"00%02X00%s00%02X00%02X%s",
  313. //00 - 默认短消息中心
  314. nType,// FO
  315. //00 - TP-MO
  316. szPDU_Number,
  317. //00 - TP-PID
  318. nCodingScheme,
  319. //00 - TP-VP
  320. strlen(szPDU_Msg)/2,
  321. szPDU_Msg);
  322. }
  323. //============================================================================================
  324. // 函数名称:SwapChars
  325. // 函数功能:交换编码 13823652665F --> 3128632566F5, 用于电话号码编码
  326. // 函数参数:
  327. // [IN/OUT] char *szNumber
  328. // 需要转换的电话号码
  329. // 返回值:
  330. //
  331. //============================================================================================
  332. void SwapChars(char *szNumber)
  333. {
  334. int nLength;
  335. int nPosition;
  336. char ch;
  337. nLength = (int)strlen(szNumber);
  338. for (nPosition=0;nPosition<nLength-1;nPosition+=2)
  339. {
  340. ch = szNumber[nPosition];
  341. szNumber[nPosition] = szNumber[nPosition+1];
  342. szNumber[nPosition+1] = ch;
  343. }
  344. }
  345. //============================================================================================
  346. // 函数名称:Str2PDU_Unicode
  347. // 函数功能:将普通文本转换为gsm需要的unicode编码格式(可用于中、英文模式)
  348. // 函数参数:
  349. // [IN] char *szMsg
  350. // 需要转换的字符串文本
  351. // [OUT] char *szPDU
  352. // 转换后的pdu unicode文本
  353. // 返回值:
  354. // int <=0 表示转换失败,否则为unicode字符长度
  355. //
  356. //============================================================================================
  357. int Str2PDU_Unicode(const char *szMsg, char *szPDU)
  358. {
  359. WCHAR wszPDU[PDU_MAXUNICODELEN];
  360. int nCount = MultiByteToWideChar( CP_ACP,
  361. MB_PRECOMPOSED,
  362. szMsg,
  363. (int)strlen(szMsg),
  364. wszPDU,
  365. PDU_MAXUNICODELEN );
  366. if (nCount<1)
  367. {
  368. return 0;
  369. }
  370. for (int i=0;i<nCount;i++)
  371. {
  372. wsprintf(szPDU+i*4,"%4.4X",wszPDU[i]);
  373. }
  374. return nCount;
  375. }
  376. //============================================================================================
  377. // 函数名称:GSMResponse
  378. // 函数功能:根据GSM模块返回的数据判断GSM模块当前的状态
  379. // 函数参数:
  380. // [IN] char *szBuff
  381. // 串口收到的数据
  382. // [IN] int nCount
  383. // 数据的个数
  384. // [OUT] int &nErrorType
  385. // 如果返回错误信息,返回的错误类型 0 - CME error, 1 - CMS error
  386. // [OUT] int &nErrorCode
  387. // 如果返回错误信息,返回的错误代码
  388. // 返回值:
  389. // int
  390. // GSM_RESPONSE_NORESPONSE 0 //无响应
  391. // GSM_RESPONSE_OK 1 //正确返回
  392. // GSM_RESPONSE_ERROR 2 //返回错误信息,含错误代码
  393. // GSM_RESPONSE_UNKNOWN 3 //返回无法确定的信息
  394. //============================================================================================
  395. int GSMResponse(const char *szBuff,int nCount, int &nErrorType, int &nErrorCode)
  396. {
  397. if (nCount==0)
  398. {
  399. return GSM_RESPONSE_NORESPONSE;
  400. }
  401. if (nCount<MIN_READ_STR_LEN)
  402. {
  403. return GSM_RESPONSE_UNKNOWN;
  404. }
  405. char szResponse[MAX_TMPSTR_LEN];
  406. //获取信息正文
  407. if ( !GetValidResponse(szBuff,nCount, szResponse) )
  408. {
  409. return GSM_RESPONSE_UNKNOWN;
  410. }
  411. if ( szResponse[0]=='O' &&
  412. szResponse[1]=='K' || strstr(szBuff, "OK") != NULL)
  413. {
  414. return GSM_RESPONSE_OK;
  415. }
  416. if ( szResponse[5]=='E' &&
  417. szResponse[6]=='R' &&
  418. szResponse[7]=='R' &&
  419. szResponse[8]=='O' &&
  420. szResponse[9]=='R' )
  421. {
  422. //Get error type
  423. if ( szResponse[3]=='E' )
  424. {
  425. nErrorType = GSM_CME_ERROR;
  426. }
  427. else
  428. {
  429. nErrorType = GSM_CMS_ERROR;
  430. }
  431. //get error code
  432. char szErrorCode[8];
  433. strncpy(szErrorCode,szResponse+12,strlen(szResponse)-12);
  434. szErrorCode[strlen(szResponse)-12] = '\0';
  435. nErrorCode = atoi(szErrorCode);
  436. return GSM_RESPONSE_ERROR;
  437. }// end if (szResponse...)
  438. return GSM_RESPONSE_UNKNOWN;
  439. }
  440. //============================================================================================
  441. // 函数名称:GetValidResponse
  442. // 函数功能:对串口返回的数据进行处理 1.判断是否有效 2.去掉首尾多余信息 3.返回有意义的数据
  443. // 函数参数:
  444. // [IN] char *szBuff
  445. // 串口收到的数据
  446. // [IN] int nCount
  447. // 数据的个数
  448. // [OUT] char *szResponse
  449. // 返回的(关键)正文信息
  450. // 返回值:
  451. // BOOL 成功为TRUE,否则FALSE
  452. //============================================================================================
  453. BOOL GetValidResponse(const char *szBuff, int nCount, char *szResponse)
  454. {
  455. if ( nCount<6 )
  456. {
  457. return FALSE;
  458. }
  459. // if ( szBuff[nCount-1] != 0x0A ||
  460. // szBuff[nCount-2] != 0x0D )
  461. // {
  462. // return FALSE;
  463. // }
  464. for (int i=nCount-3;i>0;i--)
  465. {
  466. if ( szBuff[i]==0x0A && szBuff[i-1]==0x0D )
  467. {
  468. break;
  469. }//end if
  470. }//end for
  471. if (i<1)
  472. {
  473. return FALSE;
  474. }
  475. strncpy(szResponse,szBuff+i+1,nCount-2-(i+1) );
  476. szResponse[nCount-2-(i+1)] = '\0';
  477. return TRUE;
  478. }
  479. //============================================================================================
  480. int SendSMS(
  481. const char *szNo,
  482. const char *szMsg,
  483. char* szEvent
  484. )
  485. {
  486. char WriteBuff[MAX_WRITE_STR_LEN+1] = {0};
  487. char ReadBuff[MAX_READ_STR_LEN+1] = {0};
  488. int iOffset = 0;
  489. int iDataLength = 0;
  490. char szTmp[MAX_TMPSTR_LEN+1] = {0};
  491. int nTmp;
  492. char szPDU[512];
  493. Make_PDU_Message(szNo,szMsg,FALSE,szPDU);
  494. sprintf(WriteBuff,"AT+CMGS=");
  495. iOffset += 8;
  496. sprintf(WriteBuff+iOffset,"%03d",strlen(szPDU)/2-1);
  497. iOffset = (int)strlen(WriteBuff);
  498. WriteBuff[iOffset] = 0x0d;
  499. iOffset++;
  500. //LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
  501. g_pComm->Write((BYTE*)WriteBuff, iOffset);
  502. g_pComm->Read((BYTE*)szTmp, MAX_READ_STR_LEN);
  503. iOffset = 0;
  504. sprintf(WriteBuff+iOffset,szPDU);
  505. iOffset += (int)strlen(szPDU);
  506. WriteBuff[iOffset++] = 0x1a;
  507. //LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
  508. g_pComm->Write((BYTE*)WriteBuff, iOffset);
  509. int nErrorType,nErrorCode; //发送错误类型、编码
  510. int nResponse = GSM_RESPONSE_NORESPONSE; //发送结果
  511. Sleep(3000);//发送完短信时等待3秒发送
  512. do
  513. {
  514. nTmp = g_pComm->Read((BYTE*)szTmp,MAX_READ_STR_LEN);
  515. if (nTmp>0 && iDataLength < MAX_READ_STR_LEN)
  516. {
  517. strncpy(ReadBuff+iDataLength,szTmp,nTmp);
  518. iDataLength += nTmp;
  519. }
  520. else
  521. break;
  522. } while(1);
  523. nResponse = GSMResponse(ReadBuff,iDataLength,nErrorType,nErrorCode);
  524. switch(nResponse)
  525. {
  526. case GSM_RESPONSE_OK:
  527. sprintf(szEvent,"Send OK!");
  528. return 0;
  529. break;
  530. case GSM_RESPONSE_NORESPONSE:
  531. sprintf(szEvent,"GSM Modem No Response! Please Check The Connection!");
  532. return ERR_CODE_SMS_GSM_NO_RESPONSE;
  533. break;
  534. case GSM_RESPONSE_ERROR:
  535. sprintf(szEvent,"Send fail! The card maybe has little money, Please recharge!");
  536. return ERR_CODE_SMS_GSM_ERROR_RESPONSE;
  537. break;
  538. case GSM_RESPONSE_UNKNOWN:
  539. sprintf(szEvent,"Send Timeout. The Message may Send OK!");
  540. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  541. default:
  542. sprintf(szEvent,"Send Timeout. The Message may Send OK!");
  543. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  544. }//end switch
  545. return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
  546. }
  547. int ReceiveSms(int iIndex, char* strTelFrom, char* strTime, char* strReceiveMsg, int nCharSize)
  548. {
  549. int nRet=-1;//0:关闭报警 1:恢复正常
  550. char szBuf[MAX_SIZE] = {0};
  551. //取号码
  552. strcpy(szBuf, "AT+CMGF=1\r");
  553. int nLen = g_pComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  554. nLen = g_pComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  555. //int nLen=0;
  556. sprintf(szBuf, "AT+CMGR=%d\r", 2);
  557. nLen = g_pComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  558. nLen = g_pComm->Read((BYTE *)szBuf, 511);
  559. CString str;
  560. int nReaded = 0;
  561. int nTelServiceType = 0x91;
  562. int nTelType = 0x91;
  563. char szTelService[512] = {0};
  564. char szTel[512] = {0};
  565. char szTime[512] = {0};
  566. char szWideBuf[512] = {0};
  567. char szReceiAscii[512] = {0};
  568. char *pData = strstr(szBuf, "+CMGR:");
  569. char *pOK = strstr(szBuf, "\r\nOK\r\n");
  570. if(pData!= NULL && pOK!=NULL && pOK>pData)
  571. {
  572. //pOK[0] = 0;
  573. memset(pOK, 0, strlen("\r\nOK\r\n"));
  574. char* pTemp = pData+6;//strlen("+CMGR:") = 6;
  575. nReaded = atoi(pTemp);//短信已读取标志和类型
  576. pTemp = strstr(pTemp, "\r\n");
  577. ASSERT(pTemp);
  578. if(pTemp && strlen(pTemp) > 2+5+5+14)//至少有4个元素:"\r\n"(=2), 服务中心码(>5),接受中心码(>5),时间(=14),
  579. {
  580. pTemp = pTemp + 2;//strlen("\r\n") = 2;
  581. //取发送短信的服务器号码:
  582. int nLenTelNo = 0;
  583. nLenTelNo = nLenTelNo*16 + ACharToBChar(pTemp[0]);
  584. nLenTelNo = nLenTelNo*16 + ACharToBChar(pTemp[1]);
  585. nLenTelNo = 13;//这个长度分析有问题,先定死为13.
  586. nTelServiceType = 0;
  587. nTelServiceType = nTelServiceType*16 + ACharToBChar(pTemp[2]);
  588. nTelServiceType = nTelServiceType*16 + ACharToBChar(pTemp[3]);
  589. int nOffset = 0;
  590. if(nTelServiceType == 0x91)
  591. {
  592. szTelService[nOffset++] = '+';
  593. }
  594. pTemp = pTemp + 4;
  595. int nLenTelNoFix = nLenTelNo + (nLenTelNo%2);
  596. for(int i = 0; i < nLenTelNo; i+=2)
  597. {
  598. szTelService[nOffset++] = pTemp[i+1];
  599. szTelService[nOffset++] = pTemp[i+0];
  600. }
  601. if(szTelService[nOffset-1] == 'F')
  602. szTelService[nOffset-1] = 0;
  603. pTemp += nLenTelNoFix;
  604. pTemp += 2;//暂不知道服务器号码后的两个字节是干么用的
  605. //取发送短信的手机的号码
  606. nLenTelNo = 0;
  607. nLenTelNo = nLenTelNo*16 + ACharToBChar(pTemp[0]);
  608. nLenTelNo = nLenTelNo*16 + ACharToBChar(pTemp[1]);
  609. nTelType = 0;
  610. nTelType = nTelType*16 + ACharToBChar(pTemp[2]);
  611. nTelType = nTelType*16 + ACharToBChar(pTemp[3]);
  612. nOffset = 0;
  613. if(nTelType == 0x91)
  614. {
  615. szTel[nOffset++] = '+';
  616. }
  617. pTemp = pTemp + 4;
  618. nLenTelNoFix = nLenTelNo + (nLenTelNo%2);
  619. for(i = 0; i < nLenTelNo; i+=2)
  620. {
  621. szTel[nOffset++] = pTemp[i+1];
  622. szTel[nOffset++] = pTemp[i+0];
  623. }
  624. if(szTel[nOffset-1] == 'F')
  625. szTel[nOffset-1] = 0;
  626. pTemp += nLenTelNoFix;
  627. pTemp += 4;//暂不知道手机号码后的四个字节是干么用的
  628. // 取日期
  629. nOffset = 0;
  630. ASSERT(strlen(pTemp) >=14);
  631. for(i = 0; i < 14; i+=2)
  632. {
  633. szTime[nOffset++] = pTemp[i+1];
  634. szTime[nOffset++] = pTemp[i+0];
  635. }
  636. pTemp += 14;
  637. pTemp += 2;//日期后的两个字节不知道是什么.
  638. //取短信内容
  639. strcpy(szWideBuf, pTemp);//留下原文备用
  640. unsigned short szShort[MAX_SIZE] = {0};
  641. nLen = (int)strlen(pTemp)-2;//最后两个字节是校验,不计
  642. str.Format("%s",pTemp );
  643. if( (str.Left(1)=='o' || str.Left(1)=='O') && nLen==8 )
  644. nRet = 1;
  645. else if( (str.Left(1)=='c' || str.Left(1)=='C') && nLen==10 )
  646. nRet = 0;
  647. //for(i = 0; i < nLen; i+=4)
  648. //{
  649. // szShort[i/4] = 0;
  650. // szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+0]);
  651. // szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+1]);
  652. // szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+2]);
  653. // szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+3]);
  654. //}
  655. //for(i = 0; i < nLen; i+=2)
  656. //{
  657. // szShort[i/2] = 0;
  658. // szShort[i/2] = szShort[i/2]*16 + ACharToBChar(pTemp[i+0]);
  659. // szShort[i/2] = szShort[i/2]*16 + ACharToBChar(pTemp[i+1]);
  660. // //szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+2]);
  661. // //szShort[i/4] = szShort[i/4]*16 + ACharToBChar(pTemp[i+3]);
  662. //}
  663. nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)_T(szShort), nLen, szReceiAscii, MAX_SIZE-1, NULL, NULL);
  664. }
  665. }
  666. //////////////////////////////////////////////////////////////////////////
  667. //显示
  668. if(strlen(szTel) < UINT(nCharSize))
  669. strcpy(strTelFrom, szTel);
  670. if(strlen(szTime) < UINT(nCharSize))
  671. strcpy(strTime, szTime);
  672. if(strlen(szReceiAscii) < UINT(nCharSize))
  673. strcpy(strReceiveMsg, szReceiAscii);
  674. ////清除
  675. //if(strlen(strTelFrom) > 0)
  676. //{
  677. // sprintf(szBuf, "AT+CMGD=%d\r", iIndex);
  678. // nLen = g_pComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
  679. // nLen = g_pComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
  680. //}
  681. //
  682. return nRet;//return strlen(strTelFrom) > 0;
  683. }
  684. DWORD WINAPI ReceiveSmsThread(LPVOID lpParameter)
  685. {
  686. do
  687. {
  688. char sTelFrom[MAX_SIZE],sTime[MAX_SIZE],sReceiveMsg[MAX_SIZE];
  689. int nRet = ReceiveSms( 1, sTelFrom, sTime, sReceiveMsg, MAX_SIZE );
  690. if( nRet==1 )
  691. {
  692. gEnalbeAlarmCallBack( nRet );
  693. }
  694. else if( nRet==0 )
  695. {
  696. gEnalbeAlarmCallBack( nRet );
  697. }
  698. }while( WaitForSingleObject( g_hRunObject, 500L ) == WAIT_TIMEOUT );
  699. return 0;
  700. }