Modem.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. /**********************************************************************************
  2. * File Name: Modem.c
  3. * Function Describe:device for modem
  4. * Relate Module:
  5. * Explain: the modem must be using ZTE MC8332
  6. * Writer: ShiLiangWen
  7. * Date: 2015.1.20
  8. ***********************************************************************************/
  9. #define THIS_FILE_ID 2
  10. /* Includes ------------------------------------------------------------------*/
  11. #include "includes.h"
  12. char ModemMsgBuf[MODEM_AT_MSG_BUF];
  13. void ModemWaitSomeTime(int sec);
  14. /***********************************************************
  15. 将字符串IP地址转为4字节的IP地址
  16. 如"xxx.xxx.xxx.xxx"转为4个字节
  17. ************************************************************/
  18. void Str2IP(char *strIP,unsigned char IP[4])
  19. {
  20. int iip[4];
  21. sscanf(strIP, "%d.%d.%d.%d",&iip[0],&iip[1],&iip[2],&iip[3]);
  22. IP[0]=(unsigned char)iip[0];
  23. IP[1]=(unsigned char)iip[1];
  24. IP[2]=(unsigned char)iip[2];
  25. IP[3]=(unsigned char)iip[3];
  26. }
  27. unsigned short StrToNum(char *str)
  28. {
  29. unsigned short num;
  30. if(str[0]>0x2f && str[0]<0x3a){
  31. if(str[1]>0x2f && str[1]<0x3a){
  32. if(str[2]>0x2f && str[2]<0x3a){
  33. if(str[3]>0x2f && str[3]<0x3a){
  34. num=1000*(str[0]-0x30);
  35. num+=100*(str[1]-0x30);
  36. num+=10*(str[2]-0x30);
  37. num+=(str[3]-0x30);
  38. }else{
  39. num=100*(str[0]-0x30);
  40. num+=10*(str[1]-0x30);
  41. num+=(str[2]-0x30);
  42. }
  43. }else{
  44. num=10*(str[0]-0x30);
  45. num+=(str[1]-0x30);
  46. }
  47. }else{
  48. num= str[0]-0x30;
  49. }
  50. }else{
  51. num=0;
  52. }
  53. return num;
  54. }
  55. /************************************************************************************
  56. *
  57. *************************************************************************************/
  58. void ModemSendAT(char *p)
  59. {
  60. unsigned short len;
  61. len=strlen(p);
  62. Uart3Send(p,len);
  63. }
  64. /************************************************************************************
  65. *
  66. *************************************************************************************/
  67. void ModemSendData(unsigned char *pData,unsigned short datalen)
  68. {
  69. Uart3Send((char *)pData,datalen);
  70. }
  71. /**********************************************************************************
  72. 延时并抛弃模块消息
  73. ***********************************************************************************/
  74. void ModemDelayAndDiscardMsg(int time)
  75. {
  76. int r;
  77. while(time--){
  78. os_dly_wait(1);
  79. r=MsgQueueAccept(&ModemMsgQueue,ModemMsgBuf,sizeof(ModemMsgBuf));
  80. if(r>0){
  81. sutModemStatus.UartInactiveCt=0;
  82. SlwTrace(DEBUG,ModemMsgBuf);
  83. }
  84. }
  85. }
  86. void ModemClearMsg(void)
  87. {
  88. int r;
  89. while(1){
  90. r=MsgQueueAccept(&ModemMsgQueue,ModemMsgBuf,sizeof(ModemMsgBuf));
  91. if(r==0)return;
  92. }
  93. }
  94. /**********************************************************************************
  95. CSQ2Num
  96. ***********************************************************************************/
  97. int CSQ2Num(char *str)
  98. {
  99. int csq;
  100. csq=atoi(str);
  101. if(csq<0 || csq>99)return 99;
  102. else return csq;
  103. }
  104. /**********************************************************************************
  105. ModemStrCmp
  106. 比较msg内与str相同的串。其中str可以通过"|"分开N个子字串
  107. 返回:
  108. 没有匹配的返回0
  109. 第1个字串匹配返回1
  110. 第2个匹配返回2,依次类推
  111. 比如:msg="12345" str="123" , 将返回1
  112. 比如:msg="123 45" str="12345" , 将返回0
  113. 比如:msg="123 456" str="abcd|123|123 4|aa ab|123 456" , 将返回3
  114. ***********************************************************************************/
  115. int ModemStrCmp(char *msg,char *str)
  116. {
  117. char d;
  118. char *p1=str;
  119. char *p2=msg;
  120. int token=1;
  121. //SlwTrace(DEBUG,msg);
  122. //SlwTrace(DEBUG,str);
  123. while(0!=(d=*p1)){
  124. //搜索到分隔符'|',前面的都匹配,则前面的字串匹配
  125. if(d=='|')return token;//结束搜索,返回匹配字串标记
  126. if(d!=*p2){//有不相等字符,找下一个字串,如果后面没字串了则返回0
  127. //移到下一个分隔符
  128. while(0!=(d=*p1)){
  129. if(d=='|')break;
  130. p1++;
  131. }
  132. if(d!='|')return 0;//没有分隔符了,说明没有一个字串匹配,返回0
  133. //找到分隔符,分隔符后面的字串开始重新判断匹配
  134. p1++;
  135. p2=msg;
  136. token++;
  137. }else{
  138. p1++;
  139. p2++;
  140. }
  141. }
  142. return token;
  143. }
  144. /*
  145. 等待n秒,n秒内仍处理AT响应
  146. */
  147. void ModemWaitSomeTime(int sec)
  148. {
  149. int r,k;
  150. int timeout=sec*100;
  151. while(timeout--){
  152. r=MsgQueueAccept(&ModemMsgQueue,ModemMsgBuf,sizeof(ModemMsgBuf));
  153. if(0==r){
  154. os_dly_wait(1);
  155. }else{
  156. sutModemStatus.UartInactiveCt=0;
  157. if(r>0){
  158. SlwTrace(DEBUG,ModemMsgBuf);//打印MODEM信息
  159. AtHandle(ModemMsgBuf,r);//其他消息也需要处理
  160. }else{
  161. SlwTrace(DEBUG,"ModemMsgBuf OVER!\r\n");
  162. }
  163. }
  164. }
  165. }
  166. /**********************************************************************************
  167. ModemWaitAckMsg
  168. 等待模块发回的消息与*pAck匹配,超时返回0,有匹配内容将返回非零。
  169. 其中pAck指向字符串,多个字符串可用'|'分隔,如果第一个字串匹配则返回1,第2个匹配将返回2..以此类推
  170. pMsgBuf 返回消息内容
  171. pMsgLen 返回返回消息长度
  172. ***********************************************************************************/
  173. int ModemWaitAckMsg(char *pAck,char **ppMsgBuf,int *pMsgLen,int timeout)
  174. {
  175. int r,k;
  176. while(timeout){
  177. r=MsgQueueAccept(&ModemMsgQueue,ModemMsgBuf,sizeof(ModemMsgBuf));
  178. if(0==r){
  179. os_dly_wait(1);
  180. timeout--;
  181. }else if(r>0){
  182. sutModemStatus.UartInactiveCt=0;
  183. SlwTrace(DEBUG,ModemMsgBuf);//打印MODEM信息
  184. *ppMsgBuf=ModemMsgBuf;
  185. *pMsgLen=r;
  186. k=ModemStrCmp(ModemMsgBuf,pAck);
  187. if(k){
  188. //SlwTrace(DEBUG,ModemMsgBuf);
  189. return k;
  190. }else{
  191. AtHandle(ModemMsgBuf,r);//其他消息也需要处理
  192. }
  193. }else{
  194. SlwTrace(DEBUG,"ModemMsgBuf OVER!\r\n");
  195. }
  196. }
  197. *ppMsgBuf=NULL;
  198. return 0;
  199. }
  200. /*
  201. 等待"OK"消息,并清掉此消息以及之前的所有消息
  202. 用途:在发下一条AT命令之前,上一个AT命令如果有多余的OK消息,而下一条AT又依赖于"OK"消息,则很容易出现上一条AT的"OK"干扰了下一条AT
  203. 为此,在上一条AT命令处理完之后,调用此函数清掉OK消息,然后再发下一条AT
  204. */
  205. void ModemClearOKMsg(int timout)
  206. {
  207. char *pMsgBuf;
  208. int MsgBufLen;
  209. int r;
  210. r=ModemWaitAckMsg("OK",&pMsgBuf,&MsgBufLen,timout);
  211. }
  212. /**********************************************************************************
  213. ModemSendAT2WaitAckMsg
  214. Input:
  215. pATCmd--AT Command string
  216. pAck --期待回的ACK,头相同即可,可用'|'分割多个字串
  217. timeout --超时,10ms为单位
  218. Output:
  219. return 0--timeout n--与ACK第n项匹配
  220. pMsgBuf --实际消息内容
  221. pMsgBufLen --实际消息长度
  222. ***********************************************************************************/
  223. int ModemSendAT2WaitAckMsg(char *pATCmd,char *pAck,char **ppMsgBuf,int *pMsgBufLen,int timeout)
  224. {
  225. int r;
  226. ModemSendAT(pATCmd);
  227. r=ModemWaitAckMsg(pAck,ppMsgBuf,pMsgBufLen,timeout);
  228. return r;
  229. }
  230. /**********************************************************************************
  231. 发送数据,等待回OK
  232. 在发送TCP数据时有用
  233. ***********************************************************************************/
  234. //M_RESULT ModemSendDataAndWaitOK(unsigned char *Data,unsigned short len,int timeout)
  235. //{
  236. // char *pMsgBuf;
  237. // int MsgBufLen;
  238. // int r;
  239. // ModemClearMsg();
  240. // ModemSendData(Data,len);
  241. // r=ModemWaitAckMsg("OK|ERROR",&pMsgBuf,&MsgBufLen,timeout);
  242. // if(r==1)return SUCCEED;
  243. // else if(r==2)return FAIL;
  244. // else return TIMEOUT;
  245. //}
  246. /**********************************************************************************
  247. 发送数据
  248. EC20发送数据特点:
  249. AT+QISEND=socket,len\r\n后要等待回>才能发实际数据
  250. 即使发送成功,也有两种情况:
  251. 1、如果服务器没有回复数据,会收到SEND OK\r\n
  252. 2、如果服务器直接回复数据,可能收不到SEND OK,而是直接收到:+QIURC: "recv",0,20\r\nXXX..XX\r\n
  253. ***********************************************************************************/
  254. M_RESULT ModemSendToSocket(unsigned char socket,unsigned char *pData,unsigned short len)
  255. {
  256. char AtBuf[20];
  257. char AckBuf[20];
  258. char *pMsg;
  259. int MsgLen;
  260. int i,r;
  261. if(socket>11)return FAIL;
  262. ModemClearMsg();
  263. snprintf(AtBuf,sizeof(AtBuf),"AT+QISEND=%d,%d\r\n",socket,len);
  264. r=ModemSendAT2WaitAckMsg(AtBuf,">|ERROR",&pMsg,&MsgLen,1000);
  265. if(r==1){
  266. ModemSendData(pData,len);
  267. r=ModemWaitAckMsg("SEND FAIL|ERROR",&pMsg,&MsgLen,100);
  268. if(r==0){
  269. snprintf(AtBuf,sizeof(AtBuf),"AT+QISEND=%d,0\r\n",socket);
  270. for(i=0;i<120;i++){//5*24=120 sec
  271. r=ModemSendAT2WaitAckMsg(AtBuf,"+QISEND: |ERROR",&pMsg,&MsgLen,100);
  272. if(r==1){
  273. r=GetSubFromStr(pMsg,2,AckBuf,sizeof(AckBuf));//提取第2个逗号后面的字串
  274. if(r>0 && AckBuf[0]=='0'){
  275. return SUCCEED;
  276. }else{
  277. ModemWaitSomeTime(1);//等待1秒,期间仍需要处理ATHandle
  278. }
  279. }else if(r==2){
  280. return FAIL;
  281. }
  282. }
  283. }else{
  284. return FAIL;
  285. }
  286. }
  287. return TIMEOUT;
  288. }
  289. M_RESULT ModemSendToUdpSocket(unsigned char socket,unsigned char *pData,unsigned short len)
  290. {
  291. char AtBuf[50];
  292. char AckBuf[20];
  293. char *pMsg;
  294. int MsgLen;
  295. int i,r;
  296. if(socket>11)return FAIL;
  297. ModemClearMsg();
  298. snprintf(AtBuf,sizeof(AtBuf),"AT+QISEND=%d,%d\r\n",socket,len);
  299. SlwTrace(DEBUG, AtBuf);
  300. r=ModemSendAT2WaitAckMsg(AtBuf,">|ERROR",&pMsg,&MsgLen,1000);
  301. if(r==1){
  302. ModemSendData(pData,len);
  303. //r=ModemWaitAckMsg("SEND FAIL|ERROR",&pMsg,&MsgLen,100);
  304. return SUCCEED;
  305. }
  306. return TIMEOUT;
  307. }
  308. /*************************************************************************
  309. ModemGetCCID
  310. 获取SIM/UIM卡的ICCID号,20位
  311. **************************************************************************/
  312. M_RESULT ModemGetCCID(char *pCCID)
  313. {
  314. char *pMsg;
  315. int MsgLen;
  316. char num[20]={0};
  317. char *pTemp;
  318. int i,j,len;
  319. int r;
  320. RunMake(THIS_FILE_ID);
  321. //+QCCID: 89860415151870037004
  322. ModemClearMsg();
  323. r=ModemSendAT2WaitAckMsg("AT+QCCID\r\n","+QCCID: |+CME ERROR: ",&pMsg,&MsgLen,300);
  324. if(r==1){
  325. j=0;
  326. for(i=8;i<28;i++){
  327. if(pMsg[i]<=0x20){
  328. break;
  329. }
  330. pCCID[j++]=pMsg[i];
  331. }
  332. if(i==28)return SUCCEED;
  333. else return FAIL;
  334. }
  335. return TIMEOUT;
  336. }
  337. /*************************************************************************
  338. ModemGetSimCardStatus
  339. 获取SIM卡状态
  340. **************************************************************************/
  341. M_RESULT ModemGetCardStatus(void)
  342. {
  343. char *pMsg;
  344. int MsgLen;
  345. char num[20]={0};
  346. char *pTemp;
  347. int i,j,len;
  348. int r;
  349. RunMake(THIS_FILE_ID);
  350. ModemClearMsg();
  351. r=ModemSendAT2WaitAckMsg("AT+CPIN?\r\n","+CPIN: READY|+CME ERROR:",&pMsg,&MsgLen,500);
  352. if(r==1)return SUCCEED;
  353. else if(r==2){
  354. os_dly_wait(100);
  355. return FAIL;
  356. }else return TIMEOUT;
  357. }
  358. /*************************************************************************
  359. ModemGetIMEI
  360. **************************************************************************/
  361. M_RESULT ModemGetIMEI(char *pIMEI)
  362. {
  363. char *pMsg;
  364. int MsgLen;
  365. int r,i;
  366. r=ModemSendAT2WaitAckMsg("AT+CGSN\r\n","86",&pMsg,&MsgLen,300);//"861164030090890"
  367. if(r==1){
  368. for(i=0;i<15;i++){
  369. pIMEI[i]=pMsg[i];
  370. }
  371. return SUCCEED;
  372. }
  373. return TIMEOUT;
  374. }
  375. unsigned short GetCheckSum(unsigned char *data,int len)
  376. {
  377. int i;
  378. unsigned short checksum=0;
  379. for(i=0;i<len;i++){
  380. checksum+=data[i];
  381. }
  382. return checksum;
  383. }
  384. /*
  385. 等待注册上网络
  386. */
  387. M_RESULT WaitingForCReg(int second)
  388. {
  389. int i;
  390. int r,datalen;
  391. char *pMsg;
  392. int MsgLen;
  393. for(i=0;i<second ;i++){
  394. if(i%2==0){
  395. ModemSendAT2WaitAckMsg("AT+CSQ\r\n","+CSQ:",&pMsg,&MsgLen,100);
  396. }else{
  397. r=ModemSendAT2WaitAckMsg("AT+CREG?\r\n","+CREG: 0,1|+CREG: 0,5",&pMsg,&MsgLen,100);
  398. if(r>0)return SUCCEED;
  399. }
  400. os_dly_wait(100);
  401. }
  402. return TIMEOUT;
  403. }
  404. /*
  405. 在str里查找第n个',提取后面的字串到val中,返回字串长度
  406. n 指定第几个,之后开始提取字串
  407. vallen 指定用于存储字串的val允许最大长度
  408. 返回字串长度。
  409. */
  410. int GetSubFromStr(char *str,int n,char *val,unsigned short vallen)
  411. {
  412. int i=0;
  413. char *p=str;
  414. char data=p[0];
  415. //先找到第n个逗号
  416. while(data){
  417. data=*p;
  418. if(data==',')i++;
  419. if(i==n)break;
  420. p++;
  421. }
  422. if(*p!=',')return 0;
  423. p++;
  424. //从现在开始提取字串
  425. i=0;
  426. data =*p;
  427. while(data){
  428. data=*p;
  429. if(data==',' || data<=0x20){//结束
  430. return i;
  431. }
  432. *val=data;
  433. val++;
  434. p++;
  435. i++;
  436. if(i>=vallen)return 0;
  437. }
  438. return 0;
  439. }
  440. /****************************************************************
  441. ModemGetCSQ
  442. 获取CSQ值
  443. *****************************************************************/
  444. M_RESULT ModemGetCSQ(unsigned char *CSQ)
  445. {
  446. char *pMsg;
  447. int MsgLen;
  448. int r,i;
  449. int csq;
  450. r=ModemSendAT2WaitAckMsg("AT+CSQ\r\n","+CSQ:",&pMsg,&MsgLen,4000);
  451. if(r==1 && MsgLen>10){//+CSQ: 0, 99 或 +CSQ: 99, 99
  452. //找到逗号后将其修改为0
  453. if(pMsg[7]==',')pMsg[7]=0;
  454. else if(pMsg[8]==',')pMsg[8]=0;
  455. csq=atoi(&pMsg[6]);
  456. if(csq>=0 && csq<=199){
  457. *CSQ=csq;
  458. return SUCCEED;
  459. }
  460. }
  461. return TIMEOUT;
  462. }
  463. void ModemPowerOff(void)
  464. {
  465. char *pMsg;
  466. int MsgLen;
  467. int r,i;
  468. int csq;
  469. ModemClearMsg();
  470. r=ModemSendAT2WaitAckMsg("AT+QPOWD\r\n","POWERED DOWN",&pMsg,&MsgLen,1300);
  471. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
  472. USART_Cmd(USART3, DISABLE);
  473. os_dly_wait(300);
  474. MODEM_PWREN_DISABLE;
  475. }
  476. /*
  477. 重启模块
  478. */
  479. void ModemReboot(int t)
  480. {
  481. static int i;
  482. //1秒 10秒 30秒 1分 5分
  483. static unsigned short time1[]={100,1000,3000,6000,30000};// 10ms为单位
  484. //10分 30分 1小时 3小时 6小时
  485. static unsigned short time2[]={10,30,60,180,360};// 1分钟为单位
  486. ModemPowerOff();
  487. //delay time
  488. if(t<5){
  489. os_dly_wait(time1[t]);
  490. }else if(t<10){
  491. for(i=0;i<time2[t-5];i++){
  492. os_dly_wait(6000);
  493. }
  494. }else{//t>=10
  495. for(i=0;i<360;i++){
  496. os_dly_wait(6000);
  497. }
  498. }
  499. ModemInit();
  500. }
  501. /****************************************************************
  502. *获取PDP链路状态
  503. 1,<context_state>,<context_type>[,<IP_address>]
  504. ...
  505. 16,<context_state>,<context_type>[,<IP_address>]
  506. *****************************************************************/
  507. M_RESULT ModemGetPDP(void)
  508. {
  509. char *pMsg;
  510. int MsgLen;
  511. int r;
  512. ModemClearMsg();
  513. r=ModemSendAT2WaitAckMsg("AT+QIACT?\r\n","+QIACT:|ERROR",&pMsg,&MsgLen,300);
  514. if(r==1){
  515. r=ModemWaitAckMsg("1,1|1,0",&pMsg,&MsgLen,10);
  516. if(r==1){
  517. ModemClearMsg();
  518. return SUCCEED;
  519. }else{
  520. ModemClearMsg();
  521. return FAIL;
  522. }
  523. }else if(r==2)return FAIL;
  524. else return TIMEOUT;
  525. }
  526. /*****************************************************************
  527. 打开PDP链路
  528. ******************************************************************/
  529. M_RESULT ModemOpenPDP(void)
  530. {
  531. char *pMsg;
  532. int MsgLen;
  533. int r;
  534. ModemClearMsg();
  535. r=ModemSendAT2WaitAckMsg("AT+QIACT=1\r\n","OK|ERROR",&pMsg,&MsgLen,150000);
  536. if(r==1)return SUCCEED;
  537. else if(r==2)return FAIL;
  538. else return TIMEOUT;
  539. }
  540. /*****************************************************************
  541. 查询PDP链路
  542. ******************************************************************/
  543. M_RESULT ModemQueryPDP(void)
  544. {
  545. char *pMsg;
  546. int MsgLen;
  547. int r;
  548. ModemClearMsg();
  549. r=ModemSendAT2WaitAckMsg("AT+QIACT?\r\n","+QIACT: 1,1|ERROR",&pMsg,&MsgLen,150000);
  550. if(r==1)return SUCCEED;
  551. else if(r==2)return FAIL;
  552. else return TIMEOUT;
  553. }
  554. /*****************************************************************
  555. 关闭PDP链路
  556. ******************************************************************/
  557. M_RESULT ModemClosePDP(void)
  558. {
  559. char *pMsg;
  560. int MsgLen;
  561. int r;
  562. ModemClearMsg();
  563. r=ModemSendAT2WaitAckMsg("AT+QIDEACT=1\r\n","OK|ERROR",&pMsg,&MsgLen,4000);
  564. if(r==1)return SUCCEED;
  565. else if(r==2)return FAIL;
  566. else return TIMEOUT;
  567. }
  568. /*
  569. 在字符串str中,找第n个与ch相等的字符
  570. 找到返回
  571. */
  572. char* strchrN(const char *str,char ch,int n)
  573. {
  574. char *p=(char *)str;
  575. while(*p!=0){
  576. if(*p==','){
  577. if(--n==0)return p;
  578. }
  579. p++;
  580. }
  581. return NULL;
  582. }
  583. /****************************************************************
  584. Query Socket Service Status
  585. +QISTATE:<connectID>,<service_type>,<IP_address>,<remote_port>
  586. ,<local_port>,<socket_state>,<contextID>,<serverID>,<access_mode>,<AT_port>
  587. *****************************************************************/
  588. M_RESULT ModemGetSocket(int socket,int timeout)
  589. {
  590. char AtBuf[20];
  591. char AckBuf[20];
  592. char *pMsg;
  593. int MsgLen;
  594. int r;
  595. if(socket>11)return FAIL;
  596. snprintf(AtBuf,sizeof(AtBuf),"AT+QISTATE=1,%d\r\n",socket);
  597. snprintf(AckBuf,sizeof(AckBuf),"+QISTATE:%d,|OK|ERROR",socket);
  598. while(timeout--){
  599. ModemClearMsg();
  600. r=ModemSendAT2WaitAckMsg(AtBuf,AckBuf,&pMsg,&MsgLen,300);
  601. if(r==1){
  602. //+QISTATE: 0,"TCP","120.77.66.129",9137,5995,4,1,0,1,"uart1"
  603. pMsg=strchrN(pMsg,',',5);
  604. if(pMsg!=NULL)pMsg++;
  605. if(*pMsg=='1'){
  606. return SUCCEED;
  607. }else if(*pMsg=='0'){
  608. return FAIL;
  609. }else{
  610. os_dly_wait(100);
  611. }
  612. }else if(r>=2)return FAIL;
  613. else return TIMEOUT;
  614. }
  615. return TIMEOUT;
  616. }
  617. /****************************************************************
  618. AT+QIOPEN=<contextID>,<connectID
  619. >,<service_type>,<IP_address>/<dom
  620. ain_name>,<remote_port>[,<local_po
  621. rt>[,<access_mode>]]
  622. AT+QIOPEN=1,0,"TCP","120.27.39.29",30009,0,1
  623. *****************************************************************/
  624. M_RESULT ModemOpenSocket(int socket,char *tcp_udp,char *server,unsigned short Port)
  625. {
  626. char AtBuf[120];
  627. char AckBuf[50];
  628. char *pMsg;
  629. int MsgLen;
  630. int r;
  631. if(socket>11)return FAIL;
  632. ModemClearMsg();
  633. snprintf(AtBuf,sizeof(AtBuf),"AT+QIOPEN=1,%d,\"%s\",\"%s\",%d,0,1\r\n",socket,tcp_udp,server,Port);
  634. SlwTrace(DEBUG, AtBuf);
  635. snprintf(AckBuf, sizeof(AckBuf), "+QIOPEN: %d,|ERROR",socket);
  636. r=ModemSendAT2WaitAckMsg(AtBuf,AckBuf,&pMsg,&MsgLen,2000);
  637. if(r==1){
  638. if(pMsg[11]=='0')return SUCCEED;
  639. else return FAIL;
  640. }else if(r==2){
  641. return FAIL;
  642. }
  643. else return TIMEOUT;
  644. }
  645. /****************************************************************
  646. Query Socket Service Status
  647. *****************************************************************/
  648. M_RESULT ModemCloseSocket(int socket)
  649. {
  650. char AtBuf[20];
  651. char *pMsg;
  652. int MsgLen;
  653. int r;
  654. ModemClearMsg();
  655. snprintf(AtBuf,sizeof(AtBuf),"AT+QICLOSE=%d\r\n",socket);
  656. r=ModemSendAT2WaitAckMsg(AtBuf,"OK|ERROR",&pMsg,&MsgLen,1100);
  657. if(r==1)return SUCCEED;
  658. else if(r==2)return FAIL;
  659. else return TIMEOUT;
  660. }
  661. /*
  662. 设置SIM/UIM卡的APN和用户名,密码
  663. */
  664. M_RESULT ModemSetAPN(char *pApn,char *pUsrName, char *pUsrPass)
  665. {
  666. char *pMsg;
  667. int MsgLen;
  668. char sendbuf[100];
  669. int i,r;
  670. ModemClearOKMsg(100);
  671. //先查询,如果已经相同,则直接激活
  672. snprintf(sendbuf,sizeof(sendbuf),"+QICSGP: 1,\"%s\",\"%s\",\"%s\",1",pApn,pUsrName,pUsrPass);
  673. if(1==ModemSendAT2WaitAckMsg("AT+QICSGP=1\r\n",sendbuf,&pMsg,&MsgLen,100)){
  674. ModemClearOKMsg(100);
  675. if(1==ModemSendAT2WaitAckMsg("AT+QIACT=1\r\n","OK",&pMsg,&MsgLen,100)){
  676. return SUCCEED;
  677. }
  678. }
  679. ModemClearOKMsg(100);
  680. //不同则设置后激活
  681. snprintf(sendbuf,sizeof(sendbuf),"AT+QICSGP=1,1,\"%s\",\"%s\",\"%s\",1\r\n",pApn,pUsrName,pUsrPass);
  682. ModemClearOKMsg(100);
  683. if(1==ModemSendAT2WaitAckMsg(sendbuf,"OK",&pMsg,&MsgLen,100)){
  684. if(1==ModemSendAT2WaitAckMsg("AT+QIACT=1\r\n","OK",&pMsg,&MsgLen,100)){
  685. return SUCCEED;
  686. }
  687. }
  688. return FAIL;
  689. }
  690. /**********************************************************************************
  691. 等待模块启动完成
  692. 定时发AT直到回OK,
  693. times: 发多少次AT,每秒1次
  694. ***********************************************************************************/
  695. M_RESULT ModemWaitOpened(int times)
  696. {
  697. int i,r;
  698. char *pMsg;
  699. int MsgLen;
  700. ModemClearMsg();
  701. for(i=0;i<times;i++){
  702. r=ModemSendAT2WaitAckMsg("AT\r\n","OK",&pMsg,&MsgLen,100);
  703. if(r==1)return SUCCEED;
  704. }
  705. return TIMEOUT;
  706. }
  707. /*
  708. 关闭回显
  709. */
  710. M_RESULT ModemSetATE0(void)
  711. {
  712. int i,r;
  713. char *pMsg;
  714. int MsgLen;
  715. for(i=0;i<3;i++){
  716. ModemClearMsg();
  717. r=ModemSendAT2WaitAckMsg("ATE0\r\n","OK",&pMsg,&MsgLen,300);
  718. if(r==1)return SUCCEED;
  719. }
  720. return FAIL;
  721. }
  722. /**********************************************************************************
  723. ModemInit
  724. 模块初始化
  725. ***********************************************************************************/
  726. M_RESULT ModemInit(void)
  727. {
  728. char DataBuf[5];
  729. int i;
  730. GPIO_InitTypeDef GPIO_InitStructure;
  731. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  732. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  733. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  734. GPIO_InitStructure.GPIO_Pin = MODEM_PWRKEY_PIN;
  735. GPIO_Init(MODEM_PWRKEY_PORT, &GPIO_InitStructure);
  736. GPIO_InitStructure.GPIO_Pin = MODEM_RESET_PIN;
  737. GPIO_Init(MODEM_RESET_PORT, &GPIO_InitStructure);
  738. GPIO_InitStructure.GPIO_Pin = MODEM_PWREN_PIN;
  739. GPIO_Init(MODEM_PWREN_PORT, &GPIO_InitStructure);
  740. SlwTrace(DEBUG,"Modem Init...\r\n");
  741. MODEM_PWREN_DISABLE;
  742. MODEM_PWRKEY_HIGH;
  743. MODEM_RESET_HIGH;
  744. os_dly_wait(50);
  745. MODEM_PWREN_ENABLE;
  746. os_dly_wait(50);
  747. MODEM_PWRKEY_LOW;
  748. os_dly_wait(100);
  749. MODEM_PWRKEY_HIGH;
  750. os_dly_wait(200);
  751. Uart3Init();
  752. //等待开机成功
  753. if(SUCCEED==ModemWaitOpened(20)){
  754. SlwTrace(DEBUG,"Modem is opened!\r\n");
  755. ModemSetATE0();//关闭AT回显
  756. sutModemStatus.WorkStatus=OPENED;
  757. return SUCCEED;
  758. }else{
  759. sutModemStatus.WorkStatus=CLOSED;
  760. SlwTrace(DEBUG,"Modem can't open!\r\n");
  761. return FAIL;
  762. }
  763. }
  764. /*************************************************************************
  765. 通过域名获取IP
  766. **************************************************************************/
  767. M_RESULT ModemGetIPbyDNS(char *Demain,unsigned char IP[4])
  768. {
  769. char *pMsg;
  770. int MsgLen;
  771. char AtBuf[50];
  772. int i;
  773. int r;
  774. //AT+QIDNSGIP=1,"www.baidu.com"
  775. //OK
  776. //+QIURC: "dnsgip",0,2,227
  777. //+QIURC: "dnsgip","112.34.112.40"
  778. //+QIURC: "dnsgip","112.34.112.41"
  779. //AT+QIDNSGIP=1,"www.rtuol.com"
  780. //OK
  781. //+QIURC: "dnsgip",0,1,600
  782. //+QIURC: "dnsgip","47.105.59.116"
  783. ModemClearMsg();
  784. sprintf(AtBuf,"AT+QIDNSGIP=1,\"%s\"\r\n",Demain);
  785. r=ModemSendAT2WaitAckMsg(AtBuf,"+QIURC: \"dnsgip\",\"",&pMsg,&MsgLen,6000);
  786. if(r==1){
  787. for(i=18;i<20;i++){
  788. if(pMsg[i]=='"'){
  789. pMsg[i]=0;
  790. break;
  791. }
  792. }
  793. Str2IP(&pMsg[18],IP);
  794. os_dly_wait(1);
  795. ModemClearMsg();
  796. return SUCCEED;
  797. }
  798. return TIMEOUT;
  799. }
  800. /***********************************************************************************/