at_socket_ec20.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. /*
  2. * File : at_socket_ec20.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2018-06-12 chenyong first version
  23. * 2018-08-12 Marcus port to ec20
  24. */
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <rtthread.h>
  28. #include <sys/socket.h>
  29. #include <at.h>
  30. #include <at_socket.h>
  31. #if !defined(RT_USING_NETDEV)
  32. #error "This RT-Thread version is older, please check and updata laster RT-Thread!"
  33. #else
  34. #include <arpa/inet.h>
  35. #include <netdev.h>
  36. #endif /* RT_USING_NETDEV */
  37. #if !defined(AT_SW_VERSION_NUM) || AT_SW_VERSION_NUM < 0x10200
  38. #error "This AT Client version is older, please check and update latest AT Client!"
  39. #endif
  40. #define LOG_TAG "at.ec20"
  41. #include <at_log.h>
  42. #ifdef AT_DEVICE_EC20
  43. #define EC20_NETDEV_NAME "ec20"
  44. #define EC20_MODULE_SEND_MAX_SIZE 1460
  45. #define EC20_WAIT_CONNECT_TIME 5000
  46. #define EC20_THREAD_STACK_SIZE 1024
  47. #define EC20_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX/2)
  48. /* set real event by current socket and current state */
  49. #define SET_EVENT(socket, event) (((socket + 1) << 16) | (event))
  50. /* AT socket event type */
  51. #define EC20_EVENT_CONN_OK (1L << 0)
  52. #define EC20_EVENT_SEND_OK (1L << 1)
  53. #define EC20_EVENT_RECV_OK (1L << 2)
  54. #define EC20_EVNET_CLOSE_OK (1L << 3)
  55. #define EC20_EVENT_CONN_FAIL (1L << 4)
  56. #define EC20_EVENT_SEND_FAIL (1L << 5)
  57. #define EC20_EVENT_DOMAIN_OK (1L << 6)
  58. /* AT+QICSGP command default*/
  59. char *QICSGP_CHINA_MOBILE = "AT+QICSGP=1,1,\"CMNET\",\"\",\"\",0";
  60. char *QICSGP_CHINA_UNICOM = "AT+QICSGP=1,1,\"UNINET\",\"\",\"\",0";
  61. char *QICSGP_CHINA_TELECOM = "AT+QICSGP=1,1,\"CTNET\",\"\",\"\",0";
  62. static int cur_socket;
  63. static char recv_ip[16] = { 0 };
  64. static rt_event_t at_socket_event;
  65. static rt_mutex_t at_event_lock;
  66. static at_evt_cb_t at_evt_cb_set[] = {
  67. [AT_SOCKET_EVT_RECV] = NULL,
  68. [AT_SOCKET_EVT_CLOSED] = NULL,
  69. };
  70. static void at_cme_errcode_parse(int result)
  71. {
  72. switch(result)
  73. {
  74. case 0 : LOG_E("%d : Phone failure", result); break;
  75. case 1 : LOG_E("%d : No connection to phone", result); break;
  76. case 2 : LOG_E("%d : Phone-adaptor link reserved", result); break;
  77. case 3 : LOG_E("%d : Operation not allowed", result); break;
  78. case 4 : LOG_E("%d : Operation not supported", result); break;
  79. case 5 : LOG_E("%d : PH-SIM PIN required", result); break;
  80. case 6 : LOG_E("%d : PH-FSIM PIN required", result); break;
  81. case 7 : LOG_E("%d : PH-FSIM PUK required", result); break;
  82. case 10 : LOG_E("%d : SIM not inserted", result); break;
  83. case 11 : LOG_E("%d : SIM PIN required", result); break;
  84. case 12 : LOG_E("%d : SIM PUK required", result); break;
  85. case 13 : LOG_E("%d : SIM failure", result); break;
  86. case 14 : LOG_E("%d : SIM busy", result); break;
  87. case 15 : LOG_E("%d : SIM wrong", result); break;
  88. case 16 : LOG_E("%d : Incorrect password", result); break;
  89. case 17 : LOG_E("%d : SIM PIN2 required", result); break;
  90. case 18 : LOG_E("%d : SIM PUK2 required", result); break;
  91. case 20 : LOG_E("%d : Memory full", result); break;
  92. case 21 : LOG_E("%d : Invalid index", result); break;
  93. case 22 : LOG_E("%d : Not found", result); break;
  94. case 23 : LOG_E("%d : Memory failure", result); break;
  95. case 24 : LOG_E("%d : Text string too long", result); break;
  96. case 25 : LOG_E("%d : Invalid characters in text string", result); break;
  97. case 26 : LOG_E("%d : Dial string too long", result); break;
  98. case 27 : LOG_E("%d : Invalid characters in dial string", result); break;
  99. case 30 : LOG_E("%d : No network service", result); break;
  100. case 31 : LOG_E("%d : Network timeout", result); break;
  101. case 32 : LOG_E("%d : Network not allowed - emergency calls only", result); break;
  102. case 40 : LOG_E("%d : Network personalization PIN required", result); break;
  103. case 41 : LOG_E("%d : Network personalization PUK required", result); break;
  104. case 42 : LOG_E("%d : Network subset personalization PIN required", result); break;
  105. case 43 : LOG_E("%d : Network subset personalization PUK required", result); break;
  106. case 44 : LOG_E("%d : Service provider personalization PIN required", result); break;
  107. case 45 : LOG_E("%d : Service provider personalization PUK required", result); break;
  108. case 46 : LOG_E("%d : Corporate personalization PIN required", result); break;
  109. case 47 : LOG_E("%d : Corporate personalization PUK required", result); break;
  110. case 901 : LOG_E("%d : Audio unknown error", result); break;
  111. case 902 : LOG_E("%d : Audio invalid parameters", result); break;
  112. case 903 : LOG_E("%d : Audio operation not supported", result); break;
  113. case 904 : LOG_E("%d : Audio device busy", result); break;
  114. default : LOG_E("%d : Unknown err code", result); break;
  115. }
  116. }
  117. static void at_cms_errcode_parse(int result)
  118. {
  119. switch(result)
  120. {
  121. case 300 : LOG_E("%d : ME failure", result); break;
  122. case 301 : LOG_E("%d : SMS ME reserved", result); break;
  123. case 302 : LOG_E("%d : Operation not allowed", result); break;
  124. case 303 : LOG_E("%d : Operation not supported", result); break;
  125. case 304 : LOG_E("%d : Invalid PDU mode", result); break;
  126. case 305 : LOG_E("%d : Invalid text mode", result); break;
  127. case 310 : LOG_E("%d : SIM not inserted", result); break;
  128. case 311 : LOG_E("%d : SIM pin necessary", result); break;
  129. case 312 : LOG_E("%d : PH SIM pin necessary", result); break;
  130. case 313 : LOG_E("%d : SIM failure", result); break;
  131. case 314 : LOG_E("%d : SIM busy", result); break;
  132. case 315 : LOG_E("%d : SIM wrong", result); break;
  133. case 316 : LOG_E("%d : SIM PUK required", result); break;
  134. case 317 : LOG_E("%d : SIM PIN2 required", result); break;
  135. case 318 : LOG_E("%d : SIM PUK2 required", result); break;
  136. case 320 : LOG_E("%d : Memory failure", result); break;
  137. case 321 : LOG_E("%d : Invalid memory index", result); break;
  138. case 322 : LOG_E("%d : Memory full", result); break;
  139. case 330 : LOG_E("%d : SMSC address unknown", result); break;
  140. case 331 : LOG_E("%d : No network", result); break;
  141. case 332 : LOG_E("%d : Network timeout", result); break;
  142. case 500 : LOG_E("%d : Unknown", result); break;
  143. case 512 : LOG_E("%d : SIM not ready", result); break;
  144. case 513 : LOG_E("%d : Message length exceeds", result); break;
  145. case 514 : LOG_E("%d : Invalid request parameters", result); break;
  146. case 515 : LOG_E("%d : ME storage failure", result); break;
  147. case 517 : LOG_E("%d : Invalid service mode", result); break;
  148. case 528 : LOG_E("%d : More message to send state error", result); break;
  149. case 529 : LOG_E("%d : MO SMS is not allow", result); break;
  150. case 530 : LOG_E("%d : GPRS is suspended", result); break;
  151. case 531 : LOG_E("%d : ME storage full", result); break;
  152. default : LOG_E("%d : Unknown err code", result); break;
  153. }
  154. }
  155. static void at_mms_errcode_parse(int result)//MMS
  156. {
  157. switch(result)
  158. {
  159. case 751 : LOG_E("%d : Unknown error", result); break;
  160. case 752 : LOG_E("%d : URL length error", result); break;
  161. case 753 : LOG_E("%d : URL error", result); break;
  162. case 754 : LOG_E("%d : Invalid proxy type", result); break;
  163. case 755 : LOG_E("%d : Proxy address error", result); break;
  164. case 756 : LOG_E("%d : Invalid parameter", result); break;
  165. case 757 : LOG_E("%d : Recipient address full", result); break;
  166. case 758 : LOG_E("%d : CC recipient address full", result); break;
  167. case 759 : LOG_E("%d : BCC recipient address full", result); break;
  168. case 760 : LOG_E("%d : Attachments full", result); break;
  169. case 761 : LOG_E("%d : File error", result); break;
  170. case 762 : LOG_E("%d : No recipient", result); break;
  171. case 763 : LOG_E("%d : File not found", result); break;
  172. case 764 : LOG_E("%d : MMS busy", result); break;
  173. case 765 : LOG_E("%d : Server response failed", result); break;
  174. case 766 : LOG_E("%d : Error response of HTTP(S) post", result); break;
  175. case 767 : LOG_E("%d : Invalid report of HTTP(S) post", result); break;
  176. case 768 : LOG_E("%d : PDP activation failed", result); break;
  177. case 769 : LOG_E("%d : PDP deactivated", result); break;
  178. case 770 : LOG_E("%d : Socket creation failed", result); break;
  179. case 771 : LOG_E("%d : Socket connection failed", result); break;
  180. case 772 : LOG_E("%d : Socket read failed", result); break;
  181. case 773 : LOG_E("%d : Socket write failed", result); break;
  182. case 774 : LOG_E("%d : Socket closed", result); break;
  183. case 775 : LOG_E("%d : Timeout", result); break;
  184. case 776 : LOG_E("%d : Encode data error", result); break;
  185. case 777 : LOG_E("%d : HTTP(S) decode data error", result); break;
  186. default : LOG_E("%d : Unknown err code", result); break;
  187. }
  188. }
  189. static void at_tcp_ip_errcode_parse(int result)//TCP/IP_QIGETERROR
  190. {
  191. switch(result)
  192. {
  193. case 0 : LOG_D("%d : Operation successful", result); break;
  194. case 550 : LOG_E("%d : Unknown error", result); break;
  195. case 551 : LOG_E("%d : Operation blocked", result); break;
  196. case 552 : LOG_E("%d : Invalid parameters", result); break;
  197. case 553 : LOG_E("%d : Memory not enough", result); break;
  198. case 554 : LOG_E("%d : Create socket failed", result); break;
  199. case 555 : LOG_E("%d : Operation not supported", result); break;
  200. case 556 : LOG_E("%d : Socket bind failed", result); break;
  201. case 557 : LOG_E("%d : Socket listen failed", result); break;
  202. case 558 : LOG_E("%d : Socket write failed", result); break;
  203. case 559 : LOG_E("%d : Socket read failed", result); break;
  204. case 560 : LOG_E("%d : Socket accept failed", result); break;
  205. case 561 : LOG_E("%d : Open PDP context failed", result); break;
  206. case 562 : LOG_E("%d : Close PDP context failed", result); break;
  207. case 563 : LOG_W("%d : Socket identity has been used", result); break;
  208. case 564 : LOG_E("%d : DNS busy", result); break;
  209. case 565 : LOG_E("%d : DNS parse failed", result); break;
  210. case 566 : LOG_E("%d : Socket connect failed", result); break;
  211. case 567 : LOG_W("%d : Socket has been closed", result); break;
  212. case 568 : LOG_E("%d : Operation busy", result); break;
  213. case 569 : LOG_E("%d : Operation timeout", result); break;
  214. case 570 : LOG_E("%d : PDP context broken down", result); break;
  215. case 571 : LOG_E("%d : Cancel send", result); break;
  216. case 572 : LOG_E("%d : Operation not allowed", result); break;
  217. case 573 : LOG_E("%d : APN not configured", result); break;
  218. case 574 : LOG_E("%d : Port busy", result); break;
  219. default : LOG_E("%d : Unknown err code", result); break;
  220. }
  221. }
  222. static void at_http_errcode_parse(int result)//HTTP
  223. {
  224. switch(result)
  225. {
  226. case 0 : LOG_D("%d : Operation successful", result); break;
  227. case 701 : LOG_E("%d : HTTP(S) unknown error", result); break;
  228. case 702 : LOG_E("%d : HTTP(S) timeout", result); break;
  229. case 703 : LOG_E("%d : HTTP(S) busy", result); break;
  230. case 704 : LOG_E("%d : HTTP(S) UART busy", result); break;
  231. case 705 : LOG_E("%d : HTTP(S) no GET/POST requests", result); break;
  232. case 706 : LOG_E("%d : HTTP(S) network busy", result); break;
  233. case 707 : LOG_E("%d : HTTP(S) network open failed", result); break;
  234. case 708 : LOG_E("%d : HTTP(S) network no configuration", result); break;
  235. case 709 : LOG_E("%d : HTTP(S) network deactivated", result); break;
  236. case 710 : LOG_E("%d : HTTP(S) network error", result); break;
  237. case 711 : LOG_E("%d : HTTP(S) URL error", result); break;
  238. case 712 : LOG_E("%d : HTTP(S) empty URL", result); break;
  239. case 713 : LOG_E("%d : HTTP(S) IP address error", result); break;
  240. case 714 : LOG_E("%d : HTTP(S) DNS error", result); break;
  241. case 715 : LOG_E("%d : HTTP(S) socket create error", result); break;
  242. case 716 : LOG_E("%d : HTTP(S) socket connect error", result); break;
  243. case 717 : LOG_E("%d : HTTP(S) socket read error", result); break;
  244. case 718 : LOG_E("%d : HTTP(S) socket write error", result); break;
  245. case 719 : LOG_E("%d : HTTP(S) socket closed", result); break;
  246. case 720 : LOG_E("%d : HTTP(S) data encode error", result); break;
  247. case 721 : LOG_E("%d : HTTP(S) data decode error", result); break;
  248. case 722 : LOG_E("%d : HTTP(S) read timeout", result); break;
  249. case 723 : LOG_E("%d : HTTP(S) response failed", result); break;
  250. case 724 : LOG_E("%d : Incoming call busy", result); break;
  251. case 725 : LOG_E("%d : Voice call busy", result); break;
  252. case 726 : LOG_E("%d : Input timeout", result); break;
  253. case 727 : LOG_E("%d : Wait data timeout", result); break;
  254. case 728 : LOG_E("%d : Wait HTTP(S) response timeout", result); break;
  255. case 729 : LOG_E("%d : Memory allocation failed", result); break;
  256. case 730 : LOG_E("%d : Invalid parameter", result); break;
  257. default : LOG_E("%d : Unknown err code", result); break;
  258. }
  259. }
  260. static void at_http_rsponsecode_parse(int result)//HTTP
  261. {
  262. switch(result)
  263. {
  264. case 200 : LOG_D("%d : OK", result); break;
  265. case 400 : LOG_E("%d : Bad request", result); break;
  266. case 403 : LOG_E("%d : Forbidden", result); break;
  267. case 404 : LOG_E("%d : Not found", result); break;
  268. case 409 : LOG_E("%d : Conflict", result); break;
  269. case 411 : LOG_E("%d : Length required", result); break;
  270. case 500 : LOG_E("%d : Internal server error", result); break;
  271. case 502 : LOG_E("%d : Bad gate way", result); break;
  272. default : LOG_E("%d : Unknown err code", result); break;
  273. }
  274. }
  275. static void at_ftp_errcode_parse(int result)//FTP
  276. {
  277. switch(result)
  278. {
  279. case 0 : LOG_D("%d : Operation successful", result); break;
  280. case 601 : LOG_E("%d : Unknown error", result); break;
  281. case 602 : LOG_E("%d : FTP(S) server blocked", result); break;
  282. case 603 : LOG_E("%d : FTP(S) server busy", result); break;
  283. case 604 : LOG_E("%d : DNS parse failed", result); break;
  284. case 605 : LOG_E("%d : Network error", result); break;
  285. case 606 : LOG_E("%d : Control connection closed.", result); break;
  286. case 607 : LOG_E("%d : Data connection closed", result); break;
  287. case 608 : LOG_E("%d : Socket closed by peer", result); break;
  288. case 609 : LOG_E("%d : Timeout error", result); break;
  289. case 610 : LOG_E("%d : Invalid parameter", result); break;
  290. case 611 : LOG_E("%d : Failed to open file", result); break;
  291. case 612 : LOG_E("%d : File position invalid", result); break;
  292. case 613 : LOG_E("%d : File error", result); break;
  293. case 614 : LOG_E("%d : Service not available, closing control connection", result); break;
  294. case 615 : LOG_E("%d : Open data connection failed", result); break;
  295. case 616 : LOG_E("%d : Connection closed; transfer aborted", result); break;
  296. case 617 : LOG_E("%d : Requested file action not taken", result); break;
  297. case 618 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  298. case 619 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  299. case 620 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  300. case 621 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  301. case 622 : LOG_E("%d : Command not implemented", result); break;
  302. case 623 : LOG_E("%d : Bad sequence of commands", result); break;
  303. case 624 : LOG_E("%d : Command parameter not implemented", result); break;
  304. case 625 : LOG_E("%d : Not logged in", result); break;
  305. case 626 : LOG_E("%d : Need account for storing files", result); break;
  306. case 627 : LOG_E("%d : Requested action not taken", result); break;
  307. case 628 : LOG_E("%d : Requested action aborted: page type unknown", result); break;
  308. case 629 : LOG_E("%d : Requested file action aborted", result); break;
  309. case 630 : LOG_E("%d : Requested file name invalid", result); break;
  310. case 631 : LOG_E("%d : SSL authentication failed", result); break;
  311. default : LOG_E("%d : Unknown err code", result); break;
  312. }
  313. }
  314. static void at_ftp_protocol_errcode_parse(int result)//FTP_Protocol
  315. {
  316. switch(result)
  317. {
  318. case 421 : LOG_E("%d : Service not available, closing control connection", result); break;
  319. case 425 : LOG_E("%d : Open data connection failed", result); break;
  320. case 426 : LOG_E("%d : Connection closed; transfer aborted", result); break;
  321. case 450 : LOG_E("%d : Requested file action not taken", result); break;
  322. case 451 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  323. case 452 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  324. case 500 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  325. case 501 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  326. case 502 : LOG_E("%d : Command not implemented", result); break;
  327. case 503 : LOG_E("%d : Bad sequence of commands", result); break;
  328. case 504 : LOG_E("%d : Command parameter not implemented", result); break;
  329. case 530 : LOG_E("%d : Not logged in", result); break;
  330. case 532 : LOG_E("%d : Need account for storing files", result); break;
  331. case 550 : LOG_E("%d : Requested action not taken: file unavailable", result); break;
  332. case 551 : LOG_E("%d : Requested action aborted: page type unknown", result); break;
  333. case 552 : LOG_E("%d : Requested file action aborted: exceeded storage allocation", result); break;
  334. case 553 : LOG_E("%d : Requested action not taken: file name not allowed", result); break;
  335. default : LOG_E("%d : Unknown err code", result); break;
  336. }
  337. }
  338. static void at_smtp_errcode_parse(int result)//Email
  339. {
  340. switch(result)
  341. {
  342. case 651 : LOG_E("%d : Unknown error", result); break;
  343. case 652 : LOG_E("%d : The SMTP server is busy, such as uploading the body or sending an email.", result); break;
  344. case 653 : LOG_E("%d : Failed to get IP address according to the domain name.", result); break;
  345. case 654 : LOG_E("%d : Network error, such as failed to activate GPRS/CSD context, failed to establish the TCP connection with the SMTP server or failed to send an email to the SMTP server, etc.", result); break;
  346. case 655 : LOG_E("%d : Unsupported authentication type", result); break;
  347. case 656 : LOG_E("%d : The connection for the SMTP server is closed by peer.", result); break;
  348. case 657 : LOG_E("%d : GPRS/CSD context is deactivated.", result); break;
  349. case 658 : LOG_E("%d : Timeout", result); break;
  350. case 659 : LOG_E("%d : No recipient for the SMTP server", result); break;
  351. case 660 : LOG_E("%d : Failed to send an email", result); break;
  352. case 661 : LOG_E("%d : Failed to open a file", result); break;
  353. case 662 : LOG_E("%d : No enough memory for the attachment", result); break;
  354. case 663 : LOG_E("%d : Failed to save the attachment", result); break;
  355. case 664 : LOG_E("%d : The input parameter is wrong", result); break;
  356. case 665 : LOG_E("%d : SSL authentication failed", result); break;
  357. case 666 : LOG_E("%d : Service not available, closing transmission channel", result); break;
  358. case 667 : LOG_E("%d : Requested mail action not taken: mailbox unavailable", result); break;
  359. case 668 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  360. case 669 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  361. case 670 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  362. case 671 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  363. case 672 : LOG_E("%d : Command not implemented", result); break;
  364. case 673 : LOG_E("%d : Bad sequence of commands", result); break;
  365. case 674 : LOG_E("%d : Command parameter not implemented", result); break;
  366. case 675 : LOG_E("%d : <domain> does not accept mail (see RFC1846)", result); break;
  367. case 676 : LOG_E("%d : Access denied", result); break;
  368. case 677 : LOG_E("%d : Authentication failed", result); break;
  369. case 678 : LOG_E("%d : Requested action not taken: mailbox unavailable", result); break;
  370. case 679 : LOG_E("%d : User not local; please try <forward-path>", result); break;
  371. case 680 : LOG_E("%d : Requested mail action aborted: exceeded storage allocation", result); break;
  372. case 681 : LOG_E("%d : Requested action not taken: mailbox name not allowed", result); break;
  373. case 682 : LOG_E("%d : Transaction failed", result); break;
  374. default : LOG_E("%d : Unknown err code", result); break;
  375. }
  376. }
  377. static void at_smtp_protocol_errcode_parse(int result)//Email_Protocol
  378. {
  379. switch(result)
  380. {
  381. case 421 : LOG_E("%d : Service not available, closing transmission channel", result); break;
  382. case 450 : LOG_E("%d : Requested mail action not taken: mailbox unavailable", result); break;
  383. case 451 : LOG_E("%d : Requested action aborted: local error in processing", result); break;
  384. case 452 : LOG_E("%d : Requested action not taken: insufficient system storage", result); break;
  385. case 500 : LOG_E("%d : Syntax error, command unrecognized", result); break;
  386. case 501 : LOG_E("%d : Syntax error in parameters or arguments", result); break;
  387. case 502 : LOG_E("%d : Command not implemented", result); break;
  388. case 503 : LOG_E("%d : Bad sequence of commands", result); break;
  389. case 504 : LOG_E("%d : Command parameter not implemented", result); break;
  390. case 521 : LOG_E("%d : <domain> does not accept mail (see RFC1846)", result); break;
  391. case 530 : LOG_E("%d : Access denied", result); break;
  392. case 535 : LOG_E("%d : Authentication failed", result); break;
  393. case 550 : LOG_E("%d : Requested action not taken: mailbox unavailable", result); break;
  394. case 551 : LOG_E("%d : User not local; please try <forward-path>", result); break;
  395. case 552 : LOG_E("%d : Requested mail action aborted: exceeded storage allocation", result); break;
  396. case 553 : LOG_E("%d : Requested action not taken: mailbox name not allowed", result); break;
  397. case 554 : LOG_E("%d : Transaction failed", result); break;
  398. default : LOG_E("%d : Unknown err code", result); break;
  399. }
  400. }
  401. static int at_socket_event_send(uint32_t event)
  402. {
  403. return (int) rt_event_send(at_socket_event, event);
  404. }
  405. static int at_socket_event_recv(uint32_t event, uint32_t timeout, rt_uint8_t option)
  406. {
  407. int result = 0;
  408. rt_uint32_t recved;
  409. result = rt_event_recv(at_socket_event, event, option | RT_EVENT_FLAG_CLEAR, timeout, &recved);
  410. if (result != RT_EOK)
  411. {
  412. return -RT_ETIMEOUT;
  413. }
  414. return recved;
  415. }
  416. /**
  417. * close socket by AT commands.
  418. *
  419. * @param current socket
  420. *
  421. * @return 0: close socket success
  422. * -1: send AT commands error
  423. * -2: wait socket event timeout
  424. * -5: no memory
  425. */
  426. static int ec20_socket_close(int socket)
  427. {
  428. int result = 0;
  429. at_response_t resp = RT_NULL;
  430. resp = at_create_resp(128, 0, RT_TICK_PER_SECOND);
  431. if (!resp)
  432. {
  433. LOG_E("No memory for response structure!");
  434. return -RT_ENOMEM;
  435. }
  436. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  437. /* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
  438. result = at_exec_cmd(resp, "AT+QICLOSE=%d,1", socket);
  439. if (result < 0)
  440. {
  441. return result;
  442. }
  443. rt_mutex_release(at_event_lock);
  444. if (resp)
  445. {
  446. at_delete_resp(resp);
  447. }
  448. return result;
  449. }
  450. /**
  451. * create TCP/UDP client or server connect by AT commands.
  452. *
  453. * @param socket current socket
  454. * @param ip server or client IP address
  455. * @param port server or client port
  456. * @param type connect socket type(tcp, udp)
  457. * @param is_client connection is client
  458. *
  459. * @return 0: connect success
  460. * -1: connect failed, send commands error or type error
  461. * -2: wait socket event timeout
  462. * -5: no memory
  463. */
  464. static int ec20_socket_connect(int socket, char *ip, int32_t port, enum at_socket_type type, rt_bool_t is_client)
  465. {
  466. int result = 0, event_result = 0;
  467. rt_bool_t retryed = RT_FALSE;
  468. at_response_t resp = RT_NULL;
  469. RT_ASSERT(ip);
  470. RT_ASSERT(port >= 0);
  471. resp = at_create_resp(128, 0, 5 * RT_TICK_PER_SECOND);
  472. if (!resp)
  473. {
  474. LOG_E("No memory for response structure!");
  475. return -RT_ENOMEM;
  476. }
  477. /* lock AT socket connect */
  478. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  479. __retry:
  480. /* Clear socket connect event */
  481. at_socket_event_recv(SET_EVENT(socket, EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL), 0, RT_EVENT_FLAG_OR);
  482. if (is_client)
  483. {
  484. switch (type)
  485. {
  486. case AT_SOCKET_TCP:
  487. /* send AT commands(AT+QIOPEN=<contextID>,<socket>,"<TCP/UDP>","<IP_address>/<domain_name>",<remote_port>,<local_port>,<access_mode>) to connect TCP server */
  488. /* contextID = 1 : use same contextID as AT+QICSGP & AT+QIACT */
  489. /* local_port=0 : local port assigned automatically */
  490. /* access_mode = 1 : Direct push mode */
  491. if (at_exec_cmd(resp, "AT+QIOPEN=1,%d,\"TCP\",\"%s\",%d,0,1", socket, ip, port) < 0)
  492. {
  493. result = -RT_ERROR;
  494. goto __exit;
  495. }
  496. break;
  497. case AT_SOCKET_UDP:
  498. if (at_exec_cmd(resp, "AT+QIOPEN=1,%d,\"UDP\",\"%s\",%d,0,1", socket, ip, port) < 0)
  499. {
  500. result = -RT_ERROR;
  501. goto __exit;
  502. }
  503. break;
  504. default:
  505. LOG_E("Not supported connect type : %d.", type);
  506. return -RT_ERROR;
  507. }
  508. }
  509. /* waiting result event from AT URC, the device default connection timeout is 75 seconds, but it set to 10 seconds is convenient to use.*/
  510. if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  511. {
  512. LOG_E("socket (%d) connect failed, wait connect result timeout.", socket);
  513. result = -RT_ETIMEOUT;
  514. goto __exit;
  515. }
  516. /* waiting OK or failed result */
  517. if ((event_result = at_socket_event_recv(EC20_EVENT_CONN_OK | EC20_EVENT_CONN_FAIL, 1 * RT_TICK_PER_SECOND,
  518. RT_EVENT_FLAG_OR)) < 0)
  519. {
  520. LOG_E("socket (%d) connect failed, wait connect OK|FAIL timeout.", socket);
  521. result = -RT_ETIMEOUT;
  522. goto __exit;
  523. }
  524. /* check result */
  525. if (event_result & EC20_EVENT_CONN_FAIL)
  526. {
  527. if (!retryed)
  528. {
  529. LOG_W("socket (%d) connect failed, maybe the socket was not be closed at the last time and now will retry.", socket);
  530. /* default connection timeout is 10 seconds, but it set to 1 seconds is convenient to use.*/
  531. if (ec20_socket_close < 0)
  532. {
  533. result = -RT_ERROR;
  534. goto __exit;
  535. }
  536. retryed = RT_TRUE;
  537. goto __retry;
  538. }
  539. LOG_E("socket (%d) connect failed, failed to establish a connection.", socket);
  540. result = -RT_ERROR;
  541. goto __exit;
  542. }
  543. __exit:
  544. /* unlock AT socket connect */
  545. rt_mutex_release(at_event_lock);
  546. if (resp)
  547. {
  548. at_delete_resp(resp);
  549. }
  550. return result;
  551. }
  552. static int at_get_send_size(int socket, size_t *size, size_t *acked, size_t *nacked)
  553. {
  554. at_response_t resp = at_create_resp(128, 0, 5 * RT_TICK_PER_SECOND);
  555. int result = 0;
  556. if (!resp)
  557. {
  558. LOG_E("No memory for response structure!");
  559. result = -RT_ENOMEM;
  560. goto __exit;
  561. }
  562. if (at_exec_cmd(resp, "AT+QISEND=%d,0", socket) < 0)
  563. {
  564. result = -RT_ERROR;
  565. goto __exit;
  566. }
  567. if (at_resp_parse_line_args_by_kw(resp, "+QISEND:", "+QISEND: %d,%d,%d", size, acked, nacked) <= 0)
  568. {
  569. result = -RT_ERROR;
  570. goto __exit;
  571. }
  572. __exit:
  573. if (resp)
  574. {
  575. at_delete_resp(resp);
  576. }
  577. return result;
  578. }
  579. static int at_wait_send_finish(int socket, size_t settings_size)
  580. {
  581. /* get the timeout by the input data size */
  582. rt_tick_t timeout = rt_tick_from_millisecond(settings_size);
  583. rt_tick_t last_time = rt_tick_get();
  584. size_t size = 0, acked = 0, nacked = 0xFFFF;
  585. while (rt_tick_get() - last_time <= timeout)
  586. {
  587. at_get_send_size(socket, &size, &acked, &nacked);
  588. if (nacked == 0)
  589. {
  590. return RT_EOK;
  591. }
  592. rt_thread_mdelay(50);
  593. }
  594. return -RT_ETIMEOUT;
  595. }
  596. /**
  597. * send data to server or client by AT commands.
  598. *
  599. * @param socket current socket
  600. * @param buff send buffer
  601. * @param bfsz send buffer size
  602. * @param type connect socket type(tcp, udp)
  603. *
  604. * @return >=0: the size of send success
  605. * -1: send AT commands error or send data error
  606. * -2: waited socket event timeout
  607. * -5: no memory
  608. */
  609. static int ec20_socket_send(int socket, const char *buff, size_t bfsz, enum at_socket_type type)
  610. {
  611. int result = 0, event_result = 0;
  612. at_response_t resp = RT_NULL;
  613. size_t cur_pkt_size = 0, sent_size = 0;
  614. RT_ASSERT(buff);
  615. resp = at_create_resp(128, 2, 5 * RT_TICK_PER_SECOND);
  616. if (!resp)
  617. {
  618. LOG_E("No memory for response structure!");
  619. return -RT_ENOMEM;
  620. }
  621. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  622. /* Clear socket send event */
  623. at_socket_event_recv(SET_EVENT(socket, EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL), 0, RT_EVENT_FLAG_OR);
  624. /* set current socket for send URC event */
  625. cur_socket = socket;
  626. /* set AT client end sign to deal with '>' sign.*/
  627. at_set_end_sign('>');
  628. while (sent_size < bfsz)
  629. {
  630. if (bfsz - sent_size < EC20_MODULE_SEND_MAX_SIZE)
  631. {
  632. cur_pkt_size = bfsz - sent_size;
  633. }
  634. else
  635. {
  636. cur_pkt_size = EC20_MODULE_SEND_MAX_SIZE;
  637. }
  638. /* send the "AT+QISEND" commands to AT server than receive the '>' response on the first line. */
  639. if (at_exec_cmd(resp, "AT+QISEND=%d,%d", socket, cur_pkt_size) < 0)
  640. {
  641. result = -RT_ERROR;
  642. goto __exit;
  643. }
  644. /* send the real data to server or client */
  645. result = (int) at_client_send(buff + sent_size, cur_pkt_size);
  646. if (result == 0)
  647. {
  648. result = -RT_ERROR;
  649. goto __exit;
  650. }
  651. /* waiting result event from AT URC */
  652. if (at_socket_event_recv(SET_EVENT(socket, 0), 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  653. {
  654. result = -RT_ETIMEOUT;
  655. goto __exit;
  656. }
  657. /* waiting OK or failed result */
  658. if ((event_result = at_socket_event_recv(EC20_EVENT_SEND_OK | EC20_EVENT_SEND_FAIL, 1 * RT_TICK_PER_SECOND,
  659. RT_EVENT_FLAG_OR)) < 0)
  660. {
  661. LOG_E("socket (%d) send failed, wait connect OK|FAIL timeout.", socket);
  662. result = -RT_ETIMEOUT;
  663. goto __exit;
  664. }
  665. /* check result */
  666. if (event_result & EC20_EVENT_SEND_FAIL)
  667. {
  668. LOG_E("socket (%d) send failed, return failed.", socket);
  669. result = -RT_ERROR;
  670. goto __exit;
  671. }
  672. if (type == AT_SOCKET_TCP)
  673. {
  674. at_wait_send_finish(socket, cur_pkt_size);
  675. }
  676. sent_size += cur_pkt_size;
  677. }
  678. __exit:
  679. /* reset the end sign for data conflict */
  680. at_set_end_sign(0);
  681. rt_mutex_release(at_event_lock);
  682. if (resp)
  683. {
  684. at_delete_resp(resp);
  685. }
  686. return result;
  687. }
  688. /**
  689. * domain resolve by AT commands.
  690. *
  691. * @param name domain name
  692. * @param ip parsed IP address, it's length must be 16
  693. *
  694. * @return 0: domain resolve success
  695. * -1: send AT commands error or response error
  696. * -2: wait socket event timeout
  697. * -5: no memory
  698. */
  699. static int ec20_domain_resolve(const char *name, char ip[16])
  700. {
  701. #define RESOLVE_RETRY 3
  702. int i, result;
  703. // char recv_ip[16] = { 0 };
  704. at_response_t resp = RT_NULL;
  705. RT_ASSERT(name);
  706. RT_ASSERT(ip);
  707. /* The maximum response time is 60 seconds, but it set to 10 seconds is convenient to use. */
  708. resp = at_create_resp(128, 0, 10 * RT_TICK_PER_SECOND);
  709. if (!resp)
  710. {
  711. LOG_E("No memory for response structure!");
  712. return -RT_ENOMEM;
  713. }
  714. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  715. /* Clear EC20_EVENT_DOMAIN_OK */
  716. at_socket_event_recv(EC20_EVENT_DOMAIN_OK, 0, RT_EVENT_FLAG_OR);
  717. result = at_exec_cmd(resp, "AT+QIDNSGIP=1,\"%s\"", name);
  718. if (result < 0)
  719. {
  720. goto __exit;
  721. }
  722. if (result == RT_EOK)
  723. {
  724. for(i = 0; i < RESOLVE_RETRY; i++)
  725. {
  726. /* waiting result event from AT URC, the device default connection timeout is 60 seconds.*/
  727. if (at_socket_event_recv(EC20_EVENT_DOMAIN_OK, 10 * RT_TICK_PER_SECOND, RT_EVENT_FLAG_OR) < 0)
  728. {
  729. continue;
  730. }
  731. else
  732. {
  733. if (strlen(recv_ip) < 8)
  734. {
  735. rt_thread_mdelay(100);
  736. /* resolve failed, maybe receive an URC CRLF */
  737. result = -RT_ERROR;
  738. continue;
  739. }
  740. else
  741. {
  742. strncpy(ip, recv_ip, 15);
  743. ip[15] = '\0';
  744. result = RT_EOK;
  745. break;
  746. }
  747. }
  748. }
  749. /* response timeout */
  750. if (i == RESOLVE_RETRY)
  751. {
  752. result = -RT_ENOMEM;
  753. }
  754. }
  755. __exit:
  756. rt_mutex_release(at_event_lock);
  757. if (resp)
  758. {
  759. at_delete_resp(resp);
  760. }
  761. return result;
  762. }
  763. /**
  764. * set AT socket event notice callback
  765. *
  766. * @param event notice event
  767. * @param cb notice callback
  768. */
  769. static void ec20_socket_set_event_cb(at_socket_evt_t event, at_evt_cb_t cb)
  770. {
  771. if (event < sizeof(at_evt_cb_set) / sizeof(at_evt_cb_set[1]))
  772. {
  773. at_evt_cb_set[event] = cb;
  774. }
  775. }
  776. static void urc_connect_func(const char *data, rt_size_t size)
  777. {
  778. int socket = 0;
  779. int result = 0;
  780. RT_ASSERT(data && size);
  781. sscanf(data, "+QIOPEN: %d,%d", &socket , &result);
  782. if (result == 0)
  783. {
  784. at_socket_event_send(SET_EVENT(socket, EC20_EVENT_CONN_OK));
  785. }
  786. else
  787. {
  788. at_tcp_ip_errcode_parse(result);
  789. at_socket_event_send(SET_EVENT(socket, EC20_EVENT_CONN_FAIL));
  790. }
  791. }
  792. static void urc_send_func(const char *data, rt_size_t size)
  793. {
  794. RT_ASSERT(data && size);
  795. if (strstr(data, "SEND OK"))
  796. {
  797. at_socket_event_send(SET_EVENT(cur_socket, EC20_EVENT_SEND_OK));
  798. }
  799. else if (strstr(data, "SEND FAIL"))
  800. {
  801. at_socket_event_send(SET_EVENT(cur_socket, EC20_EVENT_SEND_FAIL));
  802. }
  803. }
  804. static void urc_close_func(const char *data, rt_size_t size)
  805. {
  806. int socket = 0;
  807. RT_ASSERT(data && size);
  808. sscanf(data, "+QIURC: \"closed\",%d", &socket);
  809. /* notice the socket is disconnect by remote */
  810. if (at_evt_cb_set[AT_SOCKET_EVT_CLOSED])
  811. {
  812. at_evt_cb_set[AT_SOCKET_EVT_CLOSED](socket, AT_SOCKET_EVT_CLOSED, NULL, 0);
  813. }
  814. // /* when TCP socket service is closed, host must send "AT+QICLOSE= <connID>,0" command to close socket */
  815. // at_exec_cmd(RT_NULL, "AT+QICLOSE=%d,0\r\n", socket);
  816. // rt_thread_mdelay(100);
  817. }
  818. static void urc_recv_func(const char *data, rt_size_t size)
  819. {
  820. int socket = 0;
  821. rt_size_t bfsz = 0, temp_size = 0;
  822. rt_int32_t timeout;
  823. char *recv_buf = RT_NULL, temp[8];
  824. RT_ASSERT(data && size);
  825. /* get the current socket and receive buffer size by receive data */
  826. sscanf(data, "+QIURC: \"recv\",%d,%d", &socket, (int *) &bfsz);
  827. /* get receive timeout by receive buffer length */
  828. timeout = bfsz;
  829. if (socket < 0 || bfsz == 0)
  830. return;
  831. recv_buf = rt_calloc(1, bfsz);
  832. if (!recv_buf)
  833. {
  834. LOG_E("no memory for URC receive buffer (%d)!", bfsz);
  835. /* read and clean the coming data */
  836. while (temp_size < bfsz)
  837. {
  838. if (bfsz - temp_size > sizeof(temp))
  839. {
  840. at_client_recv(temp, sizeof(temp), timeout);
  841. }
  842. else
  843. {
  844. at_client_recv(temp, bfsz - temp_size, timeout);
  845. }
  846. temp_size += sizeof(temp);
  847. }
  848. return;
  849. }
  850. /* sync receive data */
  851. if (at_client_recv(recv_buf, bfsz, timeout) != bfsz)
  852. {
  853. LOG_E("receive size(%d) data failed!", bfsz);
  854. rt_free(recv_buf);
  855. return;
  856. }
  857. /* notice the receive buffer and buffer size */
  858. if (at_evt_cb_set[AT_SOCKET_EVT_RECV])
  859. {
  860. at_evt_cb_set[AT_SOCKET_EVT_RECV](socket, AT_SOCKET_EVT_RECV, recv_buf, bfsz);
  861. }
  862. }
  863. static void urc_pdpdeact_func(const char *data, rt_size_t size)
  864. {
  865. int connectID = 0;
  866. RT_ASSERT(data && size);
  867. sscanf(data, "+QIURC: \"pdpdeact\",%d", &connectID);
  868. LOG_E("Context (%d) is deactivated.", connectID);
  869. }
  870. static void urc_dnsqip_func(const char *data, rt_size_t size)
  871. {
  872. int i = 0, j = 0;
  873. int result, ip_count, dns_ttl;
  874. RT_ASSERT(data && size);
  875. for (i = 0; i < size; i++)
  876. {
  877. if (*(data + i) == '.')
  878. j++;
  879. }
  880. /* There would be several dns result, we just pickup one */
  881. if (j == 3)
  882. {
  883. sscanf(data, "+QIURC: \"dnsgip\",\"%[^\"]", recv_ip);
  884. recv_ip[15] = '\0';
  885. at_socket_event_send(EC20_EVENT_DOMAIN_OK);
  886. }
  887. else
  888. {
  889. sscanf(data, "+QIURC: \"dnsgip\",%d,%d,%d", &result, &ip_count, &dns_ttl);
  890. if (result)
  891. {
  892. at_tcp_ip_errcode_parse(result);
  893. }
  894. }
  895. }
  896. static void urc_func(const char *data, rt_size_t size)
  897. {
  898. RT_ASSERT(data);
  899. LOG_I("URC data : %.*s", size, data);
  900. }
  901. static void urc_qiurc_func(const char *data, rt_size_t size)
  902. {
  903. RT_ASSERT(data && size);
  904. // LOG_D("qiurc : %s", data);
  905. switch(*(data+9))
  906. {
  907. case 'c' : urc_close_func(data, size); break;//+QIURC: "closed"
  908. case 'r' : urc_recv_func(data, size); break;//+QIURC: "recv"
  909. case 'p' : urc_pdpdeact_func(data, size); break;//+QIURC: "pdpdeact"
  910. case 'd' : urc_dnsqip_func(data, size); break;//+QIURC: "dnsgip"
  911. default : urc_func(data, size); break;//
  912. }
  913. }
  914. static const struct at_urc urc_table[] = {
  915. {"SEND OK", "\r\n", urc_send_func},
  916. {"SEND FAIL", "\r\n", urc_send_func},
  917. {"+QIOPEN:", "\r\n", urc_connect_func},
  918. {"+QIURC:", "\r\n", urc_qiurc_func},
  919. };
  920. #define AT_SEND_CMD(resp, resp_line, timeout, cmd) \
  921. do \
  922. { \
  923. if (at_exec_cmd(at_resp_set_info(resp, 128, resp_line, rt_tick_from_millisecond(timeout)), cmd) < 0) \
  924. { \
  925. result = -RT_ERROR; \
  926. goto __exit; \
  927. } \
  928. } while(0); \
  929. static int ec20_netdev_set_info(struct netdev *netdev);
  930. static int ec20_netdev_check_link_status(struct netdev *netdev);
  931. /* init for EC20 */
  932. static void ec20_init_thread_entry(void *parameter)
  933. {
  934. #define AT_RETRY 10
  935. #define CIMI_RETRY 10
  936. #define CSQ_RETRY 20
  937. #define CREG_RETRY 10
  938. #define CGREG_RETRY 20
  939. at_response_t resp = RT_NULL;
  940. int i, qi_arg[3];
  941. char parsed_data[20];
  942. rt_err_t result = RT_EOK;
  943. resp = at_create_resp(128, 0, rt_tick_from_millisecond(300));
  944. if (!resp)
  945. {
  946. LOG_E("No memory for response structure!");
  947. result = -RT_ENOMEM;
  948. goto __exit;
  949. }
  950. LOG_D("Start initializing the EC20 module");
  951. /* wait EC20 startup finish, Send AT every 500ms, if receive OK, SYNC success*/
  952. if (at_client_wait_connect(EC20_WAIT_CONNECT_TIME))
  953. {
  954. result = -RT_ETIMEOUT;
  955. goto __exit;
  956. }
  957. /* set response format to ATV1 */
  958. AT_SEND_CMD(resp, 0, 300, "ATV1");
  959. /* disable echo */
  960. AT_SEND_CMD(resp, 0, 300, "ATE0");
  961. /* Use AT+CMEE=2 to enable result code and use verbose values */
  962. AT_SEND_CMD(resp, 0, 300, "AT+CMEE=2");
  963. /* Get the baudrate */
  964. AT_SEND_CMD(resp, 0, 300, "AT+IPR?");
  965. at_resp_parse_line_args_by_kw(resp, "+IPR:", "+IPR: %d", &i);
  966. LOG_D("Baudrate %d", i);
  967. /* get module version */
  968. AT_SEND_CMD(resp, 0, 300, "ATI");
  969. /* show module version */
  970. for (i = 0; i < (int) resp->line_counts - 1; i++)
  971. {
  972. LOG_D("%s", at_resp_get_line(resp, i + 1));
  973. }
  974. /* Use AT+GSN to query the IMEI of module */
  975. AT_SEND_CMD(resp, 0, 300, "AT+GSN");
  976. /* check SIM card */
  977. AT_SEND_CMD(resp, 2, 5 * 1000, "AT+CPIN?");
  978. if (!at_resp_get_line_by_kw(resp, "READY"))
  979. {
  980. LOG_E("SIM card detection failed");
  981. result = -RT_ERROR;
  982. goto __exit;
  983. }
  984. /* waiting for dirty data to be digested */
  985. rt_thread_mdelay(10);
  986. /* Use AT+CIMI to query the IMSI of SIM card */
  987. // AT_SEND_CMD(resp, 2, 300, "AT+CIMI");
  988. i = 0;
  989. while(at_exec_cmd(at_resp_set_info(resp, 128, 0, rt_tick_from_millisecond(300)), "AT+CIMI") < 0)
  990. {
  991. i++;
  992. LOG_D("AT+CIMI %d", i);
  993. if(i > CIMI_RETRY)
  994. {
  995. LOG_E("Read CIMI failed");
  996. result = -RT_ERROR;
  997. goto __exit;
  998. }
  999. rt_thread_mdelay(1000);
  1000. }
  1001. /* Use AT+QCCID to query ICCID number of SIM card */
  1002. AT_SEND_CMD(resp, 0, 300, "AT+QCCID");
  1003. /* check signal strength */
  1004. for (i = 0; i < CSQ_RETRY; i++)
  1005. {
  1006. AT_SEND_CMD(resp, 0, 300, "AT+CSQ");
  1007. at_resp_parse_line_args_by_kw(resp, "+CSQ:", "+CSQ: %d,%d", &qi_arg[0], &qi_arg[1]);
  1008. if (qi_arg[0] != 99)
  1009. {
  1010. LOG_D("Signal strength: %d Channel bit error rate: %d", qi_arg[0], qi_arg[1]);
  1011. break;
  1012. }
  1013. rt_thread_mdelay(1000);
  1014. }
  1015. if (i == CSQ_RETRY)
  1016. {
  1017. LOG_E("Signal strength check failed (%s)", parsed_data);
  1018. result = -RT_ERROR;
  1019. goto __exit;
  1020. }
  1021. /* check the GSM network is registered */
  1022. for (i = 0; i < CREG_RETRY; i++)
  1023. {
  1024. AT_SEND_CMD(resp, 0, 300, "AT+CREG?");
  1025. at_resp_parse_line_args_by_kw(resp, "+CREG:", "+CREG: %s", &parsed_data);
  1026. if (!strncmp(parsed_data, "0,1", sizeof(parsed_data)) || !strncmp(parsed_data, "0,5", sizeof(parsed_data)))
  1027. {
  1028. LOG_D("GSM network is registered (%s)", parsed_data);
  1029. break;
  1030. }
  1031. rt_thread_mdelay(1000);
  1032. }
  1033. if (i == CREG_RETRY)
  1034. {
  1035. LOG_E("The GSM network is register failed (%s)", parsed_data);
  1036. result = -RT_ERROR;
  1037. goto __exit;
  1038. }
  1039. /* check the GPRS network is registered */
  1040. for (i = 0; i < CGREG_RETRY; i++)
  1041. {
  1042. AT_SEND_CMD(resp, 0, 300, "AT+CGREG?");
  1043. at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %s", &parsed_data);
  1044. if (!strncmp(parsed_data, "0,1", sizeof(parsed_data)) || !strncmp(parsed_data, "0,5", sizeof(parsed_data)))
  1045. {
  1046. LOG_D("GPRS network is registered (%s)", parsed_data);
  1047. break;
  1048. }
  1049. rt_thread_mdelay(1000);
  1050. }
  1051. if (i == CGREG_RETRY)
  1052. {
  1053. LOG_E("The GPRS network is register failed (%s)", parsed_data);
  1054. result = -RT_ERROR;
  1055. goto __exit;
  1056. }
  1057. /*Use AT+CEREG? to query current EPS Network Registration Status*/
  1058. AT_SEND_CMD(resp, 0, 300, "AT+CEREG?");
  1059. /* Use AT+COPS? to query current Network Operator */
  1060. AT_SEND_CMD(resp, 0, 300, "AT+COPS?");
  1061. at_resp_parse_line_args_by_kw(resp, "+COPS:", "+COPS: %*[^\"]\"%[^\"]", &parsed_data);
  1062. if(strcmp(parsed_data,"CHINA MOBILE") == 0)
  1063. {
  1064. /* "CMCC" */
  1065. LOG_I("%s", parsed_data);
  1066. AT_SEND_CMD(resp, 0, 300, QICSGP_CHINA_MOBILE);
  1067. }
  1068. else if(strcmp(parsed_data,"CHN-UNICOM") == 0)
  1069. {
  1070. /* "UNICOM" */
  1071. LOG_I("%s", parsed_data);
  1072. AT_SEND_CMD(resp, 0, 300, QICSGP_CHINA_UNICOM);
  1073. }
  1074. else if(strcmp(parsed_data,"CHN-CT") == 0)
  1075. {
  1076. AT_SEND_CMD(resp, 0, 300, QICSGP_CHINA_TELECOM);
  1077. /* "CT" */
  1078. LOG_I("%s", parsed_data);
  1079. }
  1080. /* Enable automatic time zone update via NITZ and update LOCAL time to RTC */
  1081. AT_SEND_CMD(resp, 0, 300, "AT+CTZU=3");
  1082. /* Get RTC time */
  1083. AT_SEND_CMD(resp, 0, 300, "AT+CCLK?");
  1084. /* Deactivate context profile */
  1085. AT_SEND_CMD(resp, 0, 40 * 1000, "AT+QIDEACT=1");
  1086. /* Activate context profile */
  1087. AT_SEND_CMD(resp, 0, 150 * 1000, "AT+QIACT=1");
  1088. /* Query the status of the context profile */
  1089. AT_SEND_CMD(resp, 0, 150 * 1000, "AT+QIACT?");
  1090. at_resp_parse_line_args_by_kw(resp, "+QIACT:", "+QIACT: %*[^\"]\"%[^\"]", &parsed_data);
  1091. LOG_I("%s", parsed_data);
  1092. __exit:
  1093. if (resp)
  1094. {
  1095. at_delete_resp(resp);
  1096. }
  1097. if (!result)
  1098. {
  1099. /* set network interface device status and address information */
  1100. ec20_netdev_set_info(netdev_get_by_name(EC20_NETDEV_NAME));
  1101. ec20_netdev_check_link_status(netdev_get_by_name(EC20_NETDEV_NAME));
  1102. LOG_I("AT network initialize success!");
  1103. }
  1104. else
  1105. {
  1106. LOG_E("AT network initialize failed (%d)!", result);
  1107. }
  1108. }
  1109. /* EC20 device network initialize */
  1110. void ec20_net_init(void)
  1111. {
  1112. #ifdef PKG_AT_INIT_BY_THREAD
  1113. rt_thread_t tid;
  1114. tid = rt_thread_create("ec20_net_init", ec20_init_thread_entry, RT_NULL, EC20_THREAD_STACK_SIZE, EC20_THREAD_PRIORITY, 20);
  1115. if (tid)
  1116. {
  1117. rt_thread_startup(tid);
  1118. }
  1119. else
  1120. {
  1121. LOG_E("Create AT initialization thread failed!");
  1122. }
  1123. #else
  1124. ec20_init_thread_entry(RT_NULL);
  1125. #endif
  1126. }
  1127. #ifdef FINSH_USING_MSH
  1128. #include <finsh.h>
  1129. MSH_CMD_EXPORT_ALIAS(ec20_net_init, at_net_init, initialize AT network);
  1130. #endif
  1131. static const struct at_device_ops ec20_socket_ops = {
  1132. ec20_socket_connect,
  1133. ec20_socket_close,
  1134. ec20_socket_send,
  1135. ec20_domain_resolve,
  1136. ec20_socket_set_event_cb,
  1137. };
  1138. /* set ec20 network interface device status and address information */
  1139. static int ec20_netdev_set_info(struct netdev *netdev)
  1140. {
  1141. #define EC20_IEMI_RESP_SIZE 32
  1142. #define EC20_IPADDR_RESP_SIZE 64
  1143. #define EC20_DNS_RESP_SIZE 96
  1144. #define EC20_INFO_RESP_TIMO rt_tick_from_millisecond(300)
  1145. int result = RT_EOK;
  1146. at_response_t resp = RT_NULL;
  1147. ip_addr_t addr;
  1148. if (netdev == RT_NULL)
  1149. {
  1150. LOG_E("Input network interface device is NULL.\n");
  1151. return -RT_ERROR;
  1152. }
  1153. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  1154. /* set network interface device status */
  1155. netdev_low_level_set_status(netdev, RT_TRUE);
  1156. netdev_low_level_set_link_status(netdev, RT_TRUE);
  1157. netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
  1158. resp = at_create_resp(EC20_IEMI_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
  1159. if (resp == RT_NULL)
  1160. {
  1161. LOG_E("EC20 set netdev information failed, no memory for response object.");
  1162. result = -RT_ENOMEM;
  1163. goto __exit;
  1164. }
  1165. /* set network interface device hardware address(IEMI) */
  1166. {
  1167. #define EC20_NETDEV_HWADDR_LEN 8
  1168. #define EC20_IEMI_LEN 15
  1169. char iemi[EC20_IEMI_LEN] = {0};
  1170. int i = 0, j = 0;
  1171. /* send "AT+GSN" commond to get device IEMI */
  1172. if (at_exec_cmd(resp, "AT+GSN") < 0)
  1173. {
  1174. result = -RT_ERROR;
  1175. goto __exit;
  1176. }
  1177. if (at_resp_parse_line_args(resp, 2, "%s", iemi) <= 0)
  1178. {
  1179. LOG_E("Prase \"AT+GSN\" commands resposne data error!");
  1180. result = -RT_ERROR;
  1181. goto __exit;
  1182. }
  1183. LOG_D("EC20 IEMI number: %s", iemi);
  1184. netdev->hwaddr_len = EC20_NETDEV_HWADDR_LEN;
  1185. /* get hardware address by IEMI */
  1186. for (i = 0, j = 0; i < EC20_NETDEV_HWADDR_LEN && j < EC20_IEMI_LEN; i++, j+=2)
  1187. {
  1188. if (j != EC20_IEMI_LEN - 1)
  1189. {
  1190. netdev->hwaddr[i] = (iemi[j] - '0') * 10 + (iemi[j + 1] - '0');
  1191. }
  1192. else
  1193. {
  1194. netdev->hwaddr[i] = (iemi[j] - '0');
  1195. }
  1196. }
  1197. }
  1198. /* set network interface device IP address */
  1199. {
  1200. #define IP_ADDR_SIZE_MAX 16
  1201. char ipaddr[IP_ADDR_SIZE_MAX] = {0};
  1202. at_resp_set_info(resp, EC20_IPADDR_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
  1203. /* send "AT+QIACT?" commond to get IP address */
  1204. if (at_exec_cmd(resp, "AT+QIACT?") < 0)
  1205. {
  1206. result = -RT_ERROR;
  1207. goto __exit;
  1208. }
  1209. /* parse response data "+QIACT: 1,<context_state>,<context_type>[,<IP_address>]" */
  1210. if (at_resp_parse_line_args_by_kw(resp, "+QIACT:", "+QIACT: %*[^\"]\"%[^\"]", ipaddr) <= 0)
  1211. {
  1212. LOG_E("Prase \"AT+QIACT?\" commands resposne data error!");
  1213. result = -RT_ERROR;
  1214. goto __exit;
  1215. }
  1216. LOG_D("EC20 IP address: %s", ipaddr);
  1217. /* set network interface address information */
  1218. inet_aton(ipaddr, &addr);
  1219. netdev_low_level_set_ipaddr(netdev, &addr);
  1220. }
  1221. /* set network interface device dns server */
  1222. {
  1223. #define DNS_ADDR_SIZE_MAX 16
  1224. char dns_server1[DNS_ADDR_SIZE_MAX] = {0}, dns_server2[DNS_ADDR_SIZE_MAX] = {0};
  1225. at_resp_set_info(resp, EC20_DNS_RESP_SIZE, 0, EC20_INFO_RESP_TIMO);
  1226. /* send "AT+QIDNSCFG=1" commond to get DNS servers address */
  1227. if (at_exec_cmd(resp, "AT+QIDNSCFG=1") < 0)
  1228. {
  1229. result = -RT_ERROR;
  1230. goto __exit;
  1231. }
  1232. /* parse response data "+QIDNSCFG: <contextID>,<pridnsaddr>,<secdnsaddr>" */
  1233. if (at_resp_parse_line_args_by_kw(resp, "+QIDNSCFG:", "+QIDNSCFG: 1,\"%[^\"]\",\"%[^\"]\"",
  1234. dns_server1, dns_server2) <= 0)
  1235. {
  1236. LOG_E("Prase \"AT+QIDNSCFG=1\" commands resposne data error!");
  1237. result = -RT_ERROR;
  1238. goto __exit;
  1239. }
  1240. LOG_D("EC20 primary DNS server address: %s", dns_server1);
  1241. LOG_D("EC20 secondary DNS server address: %s", dns_server2);
  1242. inet_aton(dns_server1, &addr);
  1243. netdev_low_level_set_dns_server(netdev, 0, &addr);
  1244. inet_aton(dns_server2, &addr);
  1245. netdev_low_level_set_dns_server(netdev, 1, &addr);
  1246. }
  1247. __exit:
  1248. if (resp)
  1249. {
  1250. at_delete_resp(resp);
  1251. }
  1252. rt_mutex_release(at_event_lock);
  1253. return result;
  1254. }
  1255. static void ec20_check_link_status_entry(void *parameter)
  1256. {
  1257. #define EC20_LINK_RESP_SIZE 64
  1258. #define EC20_LINK_RESP_TIMO (3 * RT_TICK_PER_SECOND)
  1259. #define EC20_LINK_DELAY_TIME (30 * RT_TICK_PER_SECOND)
  1260. int link_stat = 0;
  1261. at_response_t resp = RT_NULL;
  1262. struct netdev *netdev = (struct netdev *) parameter;
  1263. resp = at_create_resp(EC20_LINK_RESP_SIZE, 0, EC20_LINK_RESP_TIMO);
  1264. if (resp == RT_NULL)
  1265. {
  1266. LOG_E("EC20 set check link status failed, no memory for response object.");
  1267. return;
  1268. }
  1269. while (1)
  1270. {
  1271. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  1272. /* send "AT+CGREG" commond to check netweork interface device link status */
  1273. if (at_exec_cmd(resp, "AT+CGREG?") < 0)
  1274. {
  1275. if (netdev_is_link_up(netdev))
  1276. {
  1277. netdev_low_level_set_link_status(netdev, RT_FALSE);
  1278. }
  1279. rt_mutex_release(at_event_lock);
  1280. rt_thread_mdelay(EC20_LINK_DELAY_TIME);
  1281. continue;
  1282. }
  1283. else
  1284. {
  1285. at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %*d,%d", &link_stat);
  1286. /* 1 Registered, home network,5 Registered, roaming */
  1287. if (link_stat == 1 || link_stat == 5)
  1288. {
  1289. if (netdev_is_link_up(netdev) == RT_FALSE)
  1290. {
  1291. netdev_low_level_set_link_status(netdev, RT_TRUE);
  1292. }
  1293. }
  1294. else
  1295. {
  1296. if (netdev_is_link_up(netdev))
  1297. {
  1298. netdev_low_level_set_link_status(netdev, RT_FALSE);
  1299. }
  1300. }
  1301. }
  1302. rt_mutex_release(at_event_lock);
  1303. rt_thread_mdelay(EC20_LINK_DELAY_TIME);
  1304. }
  1305. }
  1306. static int ec20_netdev_check_link_status(struct netdev *netdev)
  1307. {
  1308. #define EC20_LINK_THREAD_STACK_SIZE 1024
  1309. #define EC20_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
  1310. #define EC20_LINK_THREAD_TICK 20
  1311. rt_thread_t tid;
  1312. if (netdev == RT_NULL)
  1313. {
  1314. LOG_E("Input network interface device is NULL.\n");
  1315. return -RT_ERROR;
  1316. }
  1317. /* create WIZnet link status Polling thread */
  1318. tid = rt_thread_create("ec20_link", ec20_check_link_status_entry, (void *) netdev,
  1319. EC20_LINK_THREAD_STACK_SIZE, EC20_LINK_THREAD_PRIORITY, EC20_LINK_THREAD_TICK);
  1320. if (tid != RT_NULL)
  1321. {
  1322. rt_thread_startup(tid);
  1323. }
  1324. return RT_EOK;
  1325. }
  1326. static int ec20_netdev_set_up(struct netdev *netdev)
  1327. {
  1328. netdev_low_level_set_status(netdev, RT_TRUE);
  1329. LOG_D("EC20 network interface set up status.");
  1330. return RT_EOK;
  1331. }
  1332. static int ec20_netdev_set_down(struct netdev *netdev)
  1333. {
  1334. netdev_low_level_set_status(netdev, RT_FALSE);
  1335. LOG_D("EC20 network interface set down status.");
  1336. return RT_EOK;
  1337. }
  1338. static int ec20_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server)
  1339. {
  1340. #define EC20_DNS_RESP_LEN 8
  1341. #define EC20_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
  1342. at_response_t resp = RT_NULL;
  1343. int result = RT_EOK;
  1344. RT_ASSERT(netdev);
  1345. RT_ASSERT(dns_server);
  1346. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  1347. resp = at_create_resp(EC20_DNS_RESP_LEN, 0, EC20_DNS_RESP_TIMEO);
  1348. if (resp == RT_NULL)
  1349. {
  1350. LOG_D("EC20 set dns server failed, no memory for response object.");
  1351. result = -RT_ENOMEM;
  1352. goto __exit;
  1353. }
  1354. /* send "AT+QIDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
  1355. if (at_exec_cmd(resp, "AT+QIDNSCFG=1,\"%s\"", inet_ntoa(*dns_server)) < 0)
  1356. {
  1357. result = -RT_ERROR;
  1358. goto __exit;
  1359. }
  1360. netdev_low_level_set_dns_server(netdev, dns_num, dns_server);
  1361. __exit:
  1362. if (resp)
  1363. {
  1364. at_delete_resp(resp);
  1365. }
  1366. rt_mutex_release(at_event_lock);
  1367. return result;
  1368. }
  1369. static int ec20_netdev_ping(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
  1370. {
  1371. #define EC20_PING_RESP_SIZE 128
  1372. #define EC20_PING_IP_SIZE 16
  1373. #define EC20_PING_TIMEO (5 * RT_TICK_PER_SECOND)
  1374. at_response_t resp = RT_NULL;
  1375. rt_err_t result = RT_EOK;
  1376. int response = -1, recv_data_len, ping_time, ttl;
  1377. char ip_addr[EC20_PING_IP_SIZE] = {0};
  1378. RT_ASSERT(netdev);
  1379. RT_ASSERT(host);
  1380. RT_ASSERT(ping_resp);
  1381. rt_mutex_take(at_event_lock, RT_WAITING_FOREVER);
  1382. resp = at_create_resp(EC20_PING_RESP_SIZE, 4, EC20_PING_TIMEO);
  1383. if (resp == RT_NULL)
  1384. {
  1385. LOG_D("No memory for response structure!\n");
  1386. return -RT_ENOMEM;
  1387. }
  1388. /* send "AT+QPING="<host>"[,[<timeout>][,<pingnum>]]" commond to send ping request */
  1389. if (at_exec_cmd(resp, "AT+QPING=1,\"%s\",%d,1", host, timeout / RT_TICK_PER_SECOND) < 0)
  1390. {
  1391. result = -RT_ERROR;
  1392. goto __exit;
  1393. }
  1394. at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d", &response);
  1395. /* Received the ping response from the server */
  1396. if (response == 0)
  1397. {
  1398. if (at_resp_parse_line_args_by_kw(resp, "+QPING:", "+QPING:%d,\"%[^\"]\",%d,%d,%d",
  1399. &response, ip_addr, &recv_data_len, &ping_time, &ttl) <= 0)
  1400. {
  1401. result = -RT_ERROR;
  1402. goto __exit;
  1403. }
  1404. }
  1405. /* prase response number */
  1406. switch (response)
  1407. {
  1408. case 0:
  1409. inet_aton(ip_addr, &(ping_resp->ip_addr));
  1410. ping_resp->data_len = recv_data_len;
  1411. ping_resp->ticks = ping_time;
  1412. ping_resp->ttl = ttl;
  1413. result = RT_EOK;
  1414. break;
  1415. case 569:
  1416. result = -RT_ETIMEOUT;
  1417. break;
  1418. default:
  1419. result = -RT_ERROR;
  1420. break;
  1421. }
  1422. __exit:
  1423. if (resp)
  1424. {
  1425. at_delete_resp(resp);
  1426. }
  1427. rt_mutex_release(at_event_lock);
  1428. return result;
  1429. }
  1430. void ec20_netdev_netstat(struct netdev *netdev)
  1431. {
  1432. // TODO
  1433. return;
  1434. }
  1435. const struct netdev_ops ec20_netdev_ops =
  1436. {
  1437. ec20_netdev_set_up,
  1438. ec20_netdev_set_down,
  1439. RT_NULL,
  1440. ec20_netdev_set_dns_server,
  1441. RT_NULL,
  1442. ec20_netdev_ping,
  1443. ec20_netdev_netstat,
  1444. };
  1445. static int ec20_netdev_add(const char *netdev_name)
  1446. {
  1447. #define ETHERNET_MTU 1500
  1448. #define HWADDR_LEN 6
  1449. struct netdev *netdev = RT_NULL;
  1450. netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
  1451. if (netdev == RT_NULL)
  1452. {
  1453. return RT_NULL;
  1454. }
  1455. netdev->mtu = ETHERNET_MTU;
  1456. netdev->ops = &ec20_netdev_ops;
  1457. netdev->hwaddr_len = HWADDR_LEN;
  1458. #ifdef SAL_USING_AT
  1459. extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
  1460. /* set the network interface socket/netdb operations */
  1461. sal_at_netdev_set_pf_info(netdev);
  1462. #endif
  1463. return netdev_register(netdev, netdev_name, RT_NULL);
  1464. }
  1465. static int at_socket_device_init(void)
  1466. {
  1467. /* create current AT socket event */
  1468. at_socket_event = rt_event_create("at_se", RT_IPC_FLAG_FIFO);
  1469. if (!at_socket_event)
  1470. {
  1471. LOG_E("AT client port initialize failed! at_sock_event create failed!");
  1472. return -RT_ENOMEM;
  1473. }
  1474. /* create current AT socket lock */
  1475. at_event_lock = rt_mutex_create("at_se", RT_IPC_FLAG_FIFO);
  1476. if (!at_event_lock)
  1477. {
  1478. LOG_E("AT client port initialize failed! at_sock_lock create failed!");
  1479. rt_event_delete(at_socket_event);
  1480. return -RT_ENOMEM;
  1481. }
  1482. /* initialize AT client */
  1483. at_client_init(AT_DEVICE_NAME, AT_DEVICE_RECV_BUFF_LEN);
  1484. /* register URC data execution function */
  1485. at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
  1486. /* Add ec20 network inetrface device to the netdev list */
  1487. if (ec20_netdev_add(EC20_NETDEV_NAME) < 0)
  1488. {
  1489. LOG_E("EC20 network interface device(%d) add failed.", EC20_NETDEV_NAME);
  1490. return -RT_ENOMEM;
  1491. }
  1492. /* initialize EC20 network */
  1493. ec20_net_init();
  1494. /* set EC20 AT Socket options */
  1495. at_socket_device_register(&ec20_socket_ops);
  1496. return RT_EOK;
  1497. }
  1498. INIT_APP_EXPORT(at_socket_device_init);
  1499. #endif /* AT_DEVICE_EC20 */