at_device_n720.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-27 qiyongzhong first version
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <at_device_n720.h>
  13. #define LOG_TAG "at.dev.n720"
  14. #include <at_log.h>
  15. #ifdef AT_DEVICE_USING_N720
  16. #define N720_WAIT_CONNECT_TIME 15000
  17. #define N720_THREAD_STACK_SIZE 2048
  18. #define N720_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX/2)
  19. static int n720_power_on(struct at_device *device)
  20. {
  21. struct at_device_n720 *n720 = RT_NULL;
  22. n720 = (struct at_device_n720 *)device->user_data;
  23. if (n720->power_ctrl)
  24. {
  25. (n720->power_ctrl)(1);
  26. rt_thread_mdelay(2000);
  27. }
  28. if (n720->power_pin == -1)//no power on pin
  29. {
  30. return(RT_EOK);
  31. }
  32. if (n720->power_status_pin != -1)//use power status pin
  33. {
  34. n720->power_status = rt_pin_read(n720->power_status_pin);//read power status
  35. }
  36. if (n720->power_status)//power is on
  37. {
  38. return(RT_EOK);
  39. }
  40. rt_pin_write(n720->power_pin, PIN_HIGH);
  41. if (n720->power_status_pin != -1)//use power status pin
  42. {
  43. while (rt_pin_read(n720->power_status_pin) == PIN_LOW)
  44. {
  45. rt_thread_mdelay(10);
  46. }
  47. }
  48. rt_thread_mdelay(1000);
  49. rt_pin_write(n720->power_pin, PIN_LOW);
  50. n720->power_status = RT_TRUE;
  51. return(RT_EOK);
  52. }
  53. static int n720_power_off(struct at_device *device)
  54. {
  55. struct at_device_n720 *n720 = RT_NULL;
  56. n720 = (struct at_device_n720 *)device->user_data;
  57. if (n720->power_ctrl)
  58. {
  59. n720->power_status = RT_FALSE;
  60. (n720->power_ctrl)(0);
  61. rt_thread_mdelay(2*1000);
  62. return(RT_EOK);
  63. }
  64. if (n720->power_pin == -1)//no power on pin
  65. {
  66. return(RT_EOK);
  67. }
  68. if (n720->power_status_pin != -1)//use power status pin
  69. {
  70. n720->power_status = rt_pin_read(n720->power_status_pin);//read power status
  71. }
  72. if ( ! n720->power_status)//power is off
  73. {
  74. return(RT_EOK);
  75. }
  76. if (n720->power_status_pin != -1)//use power status pin
  77. {
  78. rt_pin_write(n720->power_pin, PIN_HIGH);
  79. rt_thread_mdelay(1000);
  80. rt_pin_write(n720->power_pin, PIN_LOW);
  81. while (rt_pin_read(n720->power_status_pin) == PIN_HIGH)//wait power down
  82. {
  83. rt_thread_mdelay(100);
  84. }
  85. }
  86. else
  87. {
  88. at_obj_exec_cmd(device->client, RT_NULL, "$MYPOWEROFF");
  89. rt_thread_mdelay(5*1000);
  90. }
  91. n720->power_status = RT_FALSE;
  92. return(RT_EOK);
  93. }
  94. static int n720_sleep(struct at_device *device)
  95. {
  96. //at_response_t resp = RT_NULL;
  97. struct at_device_n720 *n720 = RT_NULL;
  98. n720 = (struct at_device_n720 *)device->user_data;
  99. if ( ! n720->power_status)//power off
  100. {
  101. return(RT_EOK);
  102. }
  103. if (n720->sleep_status)//is sleep status
  104. {
  105. return(RT_EOK);
  106. }
  107. if (n720->wakeup_pin == -1)//use wakeup pin
  108. {
  109. LOG_E("no config wakeup pin, can not entry into sleep mode.");
  110. return(-RT_ERROR);
  111. }
  112. /*
  113. resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
  114. if (resp == RT_NULL)
  115. {
  116. LOG_D("no memory for resp create.");
  117. return(-RT_ERROR);
  118. }
  119. if (at_obj_exec_cmd(device->client, resp, "AT+QSCLK=1") != RT_EOK)//enable sleep mode
  120. {
  121. LOG_D("enable sleep fail.\"AT+QSCLK=1\" execute fail.");
  122. at_delete_resp(resp);
  123. return(-RT_ERROR);
  124. }
  125. at_delete_resp(resp);
  126. */
  127. rt_pin_write(n720->wakeup_pin, PIN_HIGH);
  128. n720->sleep_status = RT_TRUE;
  129. return(RT_EOK);
  130. }
  131. static int n720_wakeup(struct at_device *device)
  132. {
  133. //at_response_t resp = RT_NULL;
  134. struct at_device_n720 *n720 = RT_NULL;
  135. n720 = (struct at_device_n720 *)device->user_data;
  136. if ( ! n720->power_status)//power off
  137. {
  138. LOG_E("the power is off and the wake-up cannot be performed");
  139. return(-RT_ERROR);
  140. }
  141. if ( ! n720->sleep_status)//no sleep status
  142. {
  143. return(RT_EOK);
  144. }
  145. rt_pin_write(n720->wakeup_pin, PIN_LOW);
  146. rt_thread_mdelay(200);
  147. /*
  148. resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
  149. if (resp == RT_NULL)
  150. {
  151. LOG_D("no memory for resp create.");
  152. return(-RT_ERROR);
  153. }
  154. if (at_obj_exec_cmd(device->client, resp, "AT+QSCLK=0") != RT_EOK)//disable sleep mode
  155. {
  156. LOG_D("wake up fail. \"AT+QSCLK=0\" execute fail.");
  157. at_delete_resp(resp);
  158. return(-RT_ERROR);
  159. }
  160. at_delete_resp(resp);
  161. */
  162. n720->sleep_status = RT_FALSE;
  163. return(RT_EOK);
  164. }
  165. static int n720_check_link_status(struct at_device *device)
  166. {
  167. at_response_t resp = RT_NULL;
  168. struct at_device_n720 *n720 = RT_NULL;
  169. int result = -RT_ERROR;
  170. n720 = (struct at_device_n720 *)device->user_data;
  171. if ( ! n720->power_status)//power off
  172. {
  173. LOG_D("the power is off.");
  174. return(-RT_ERROR);
  175. }
  176. if (n720->sleep_status)//is sleep status
  177. {
  178. rt_pin_write(n720->wakeup_pin, PIN_LOW);
  179. rt_thread_mdelay(200);
  180. }
  181. resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
  182. if (resp == RT_NULL)
  183. {
  184. LOG_D("no memory for resp create.");
  185. return(-RT_ERROR);
  186. }
  187. result = -RT_ERROR;
  188. if (at_obj_exec_cmd(device->client, resp, "AT+CGREG?") == RT_EOK)
  189. {
  190. int link_stat = 0;
  191. if (at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %*d,%d", &link_stat) > 0)
  192. {
  193. if (link_stat == 1 || link_stat == 5)
  194. {
  195. result = RT_EOK;
  196. }
  197. }
  198. }
  199. at_delete_resp(resp);
  200. if (n720->sleep_status)//is sleep status
  201. {
  202. rt_pin_write(n720->wakeup_pin, PIN_HIGH);
  203. }
  204. return(result);
  205. }
  206. /* ============================= n720 network interface operations ============================= */
  207. /* set n720 network interface device status and address information */
  208. static int n720_netdev_set_info(struct netdev *netdev)
  209. {
  210. #define N720_INFO_RESP_SIZE 128
  211. #define N720_INFO_RESP_TIMO rt_tick_from_millisecond(1000)
  212. int result = RT_EOK;
  213. ip_addr_t addr;
  214. at_response_t resp = RT_NULL;
  215. struct at_device *device = RT_NULL;
  216. RT_ASSERT(netdev);
  217. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  218. if (device == RT_NULL)
  219. {
  220. LOG_E("get device(%s) failed.", netdev->name);
  221. return -RT_ERROR;
  222. }
  223. /* set network interface device status */
  224. netdev_low_level_set_status(netdev, RT_TRUE);
  225. netdev_low_level_set_link_status(netdev, RT_TRUE);
  226. netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
  227. resp = at_create_resp(N720_INFO_RESP_SIZE, 0, N720_INFO_RESP_TIMO);
  228. if (resp == RT_NULL)
  229. {
  230. LOG_E("no memory for resp create.");
  231. result = -RT_ENOMEM;
  232. goto __exit;
  233. }
  234. /* set network interface device hardware address(IMEI) */
  235. {
  236. #define N720_NETDEV_HWADDR_LEN 8
  237. #define N720_IMEI_LEN 15
  238. char imei[N720_IMEI_LEN] = {0};
  239. int i = 0, j = 0;
  240. /* send "AT+GSN" commond to get device IMEI */
  241. if (at_obj_exec_cmd(device->client, resp, "AT+GSN") != RT_EOK)
  242. {
  243. result = -RT_ERROR;
  244. goto __exit;
  245. }
  246. if (at_resp_parse_line_args_by_kw(resp, "+GSN:", "%*[^\"]\"%[^\"]", imei) <= 0)
  247. {
  248. LOG_E("%s device prase \"AT+GSN\" cmd error.", device->name);
  249. result = -RT_ERROR;
  250. goto __exit;
  251. }
  252. LOG_D("%s device IMEI number: %s", device->name, imei);
  253. netdev->hwaddr_len = N720_NETDEV_HWADDR_LEN;
  254. /* get hardware address by IMEI */
  255. for (i = 0, j = 0; i < N720_NETDEV_HWADDR_LEN && j < N720_IMEI_LEN; i++, j+=2)
  256. {
  257. if (j != N720_IMEI_LEN - 1)
  258. {
  259. netdev->hwaddr[i] = (imei[j] - '0') * 10 + (imei[j + 1] - '0');
  260. }
  261. else
  262. {
  263. netdev->hwaddr[i] = (imei[j] - '0');
  264. }
  265. }
  266. }
  267. /* set network interface device IP address */
  268. {
  269. #define IP_ADDR_SIZE_MAX 16
  270. char ipaddr[IP_ADDR_SIZE_MAX] = {0};
  271. /* Get IP address */
  272. if (at_obj_exec_cmd(device->client, resp, "AT$MYNETACT?") != RT_EOK)
  273. {
  274. result = -RT_ERROR;
  275. goto __exit;
  276. }
  277. if (at_resp_parse_line_args_by_kw(resp, "$MYNETACT:", "$MYNETACT: %*[^\"]\"%[^\"]", ipaddr) <= 0)
  278. {
  279. LOG_E("%s device \"AT$MYNETACT?\" cmd error.", device->name);
  280. result = -RT_ERROR;
  281. goto __exit;
  282. }
  283. LOG_D("%s device IP address: %s", device->name, ipaddr);
  284. /* set network interface address information */
  285. inet_aton(ipaddr, &addr);
  286. netdev_low_level_set_ipaddr(netdev, &addr);
  287. }
  288. /* set network interface device dns server */
  289. {
  290. #define DNS_ADDR_SIZE_MAX 16
  291. char dns_server1[DNS_ADDR_SIZE_MAX] = {0}, dns_server2[DNS_ADDR_SIZE_MAX] = {0};
  292. at_resp_set_info(resp, N720_INFO_RESP_SIZE, 2, N720_INFO_RESP_TIMO);
  293. /* send "AT+DNSSERVER?" commond to get DNS servers address */
  294. if (at_obj_exec_cmd(device->client, resp, "AT+DNSSERVER?") < 0)
  295. {
  296. result = -RT_ERROR;
  297. goto __exit;
  298. }
  299. if (at_resp_parse_line_args_by_kw(resp, "+DNSSERVER:", "+DNSSERVER: dns1:%[^;];dns2:%s\r\n", dns_server1, dns_server2) <= 0)
  300. {
  301. LOG_E("Prase \"AT+DNSSERVER?\" commands resposne data error!");
  302. result = -RT_ERROR;
  303. goto __exit;
  304. }
  305. LOG_D("n58 device(%s) primary DNS server address: %s", device->name, dns_server1);
  306. LOG_D("n58 device(%s) secondary DNS server address: %s", device->name, dns_server2);
  307. inet_aton(dns_server1, &addr);
  308. netdev_low_level_set_dns_server(netdev, 0, &addr);
  309. inet_aton(dns_server2, &addr);
  310. netdev_low_level_set_dns_server(netdev, 1, &addr);
  311. }
  312. __exit:
  313. if (resp)
  314. {
  315. at_delete_resp(resp);
  316. }
  317. return result;
  318. }
  319. static void n720_check_link_status_entry(void *parameter)
  320. {
  321. #define N720_LINK_DELAY_TIME (60 * RT_TICK_PER_SECOND)
  322. rt_bool_t is_link_up;
  323. struct at_device *device = RT_NULL;
  324. struct netdev *netdev = (struct netdev *) parameter;
  325. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  326. if (device == RT_NULL)
  327. {
  328. LOG_E("get device(%s) failed.", netdev->name);
  329. return;
  330. }
  331. while (1)
  332. {
  333. rt_thread_delay(N720_LINK_DELAY_TIME);
  334. is_link_up = (n720_check_link_status(device) == RT_EOK);
  335. netdev_low_level_set_link_status(netdev, is_link_up);
  336. }
  337. }
  338. static int n720_netdev_check_link_status(struct netdev *netdev)
  339. {
  340. #define N720_LINK_THREAD_TICK 20
  341. #define N720_LINK_THREAD_STACK_SIZE (1024 + 512)
  342. #define N720_LINK_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2)
  343. rt_thread_t tid;
  344. char tname[RT_NAME_MAX] = {0};
  345. RT_ASSERT(netdev);
  346. rt_snprintf(tname, RT_NAME_MAX, "%s", netdev->name);
  347. /* create n720 link status polling thread */
  348. tid = rt_thread_create(tname, n720_check_link_status_entry, (void *)netdev,
  349. N720_LINK_THREAD_STACK_SIZE, N720_LINK_THREAD_PRIORITY, N720_LINK_THREAD_TICK);
  350. if (tid != RT_NULL)
  351. {
  352. rt_thread_startup(tid);
  353. }
  354. return RT_EOK;
  355. }
  356. static int n720_net_init(struct at_device *device);
  357. static int n720_netdev_set_up(struct netdev *netdev)
  358. {
  359. struct at_device *device = RT_NULL;
  360. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  361. if (device == RT_NULL)
  362. {
  363. LOG_E("get device(%s) failed.", netdev->name);
  364. return -RT_ERROR;
  365. }
  366. if (device->is_init == RT_FALSE)
  367. {
  368. n720_net_init(device);
  369. device->is_init = RT_TRUE;
  370. netdev_low_level_set_status(netdev, RT_TRUE);
  371. LOG_D("network interface device(%s) set up status.", netdev->name);
  372. }
  373. return RT_EOK;
  374. }
  375. static int n720_netdev_set_down(struct netdev *netdev)
  376. {
  377. struct at_device *device = RT_NULL;
  378. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  379. if (device == RT_NULL)
  380. {
  381. LOG_E("get device(%s) failed.", netdev->name);
  382. return -RT_ERROR;
  383. }
  384. if (device->is_init == RT_TRUE)
  385. {
  386. n720_power_off(device);
  387. device->is_init = RT_FALSE;
  388. netdev_low_level_set_status(netdev, RT_FALSE);
  389. LOG_D("network interface device(%s) set down status.", netdev->name);
  390. }
  391. return RT_EOK;
  392. }
  393. static int n720_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server)
  394. {
  395. #define N720_DNS_RESP_LEN 128
  396. #define N720_DNS_RESP_TIMEO rt_tick_from_millisecond(300)
  397. int result = RT_EOK;
  398. at_response_t resp = RT_NULL;
  399. struct at_device *device = RT_NULL;
  400. RT_ASSERT(netdev);
  401. RT_ASSERT(dns_server);
  402. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  403. if (device == RT_NULL)
  404. {
  405. LOG_E("get device(%s) failed.", netdev->name);
  406. return -RT_ERROR;
  407. }
  408. resp = at_create_resp(N720_DNS_RESP_LEN, 0, N720_DNS_RESP_TIMEO);
  409. if (resp == RT_NULL)
  410. {
  411. LOG_D("no memory for resp create.");
  412. result = -RT_ENOMEM;
  413. goto __exit;
  414. }
  415. /* send "AT+QIDNSCFG=<pri_dns>[,<sec_dns>]" commond to set dns servers */
  416. if (at_obj_exec_cmd(device->client, resp, "AT+DNSSERVER=%d,%s", dns_num, inet_ntoa(*dns_server)) != RT_EOK)
  417. {
  418. result = -RT_ERROR;
  419. goto __exit;
  420. }
  421. netdev_low_level_set_dns_server(netdev, dns_num, dns_server);
  422. __exit:
  423. if (resp)
  424. {
  425. at_delete_resp(resp);
  426. }
  427. return result;
  428. }
  429. #ifdef NETDEV_USING_PING
  430. static int n720_netdev_ping(struct netdev *netdev, const char *host,
  431. size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp
  432. #if RT_VER_NUM >= 0x50100
  433. , rt_bool_t is_bind
  434. #endif
  435. )
  436. {
  437. #define N720_PING_RESP_SIZE 128
  438. #define N720_PING_IP_SIZE 16
  439. #define N720_PING_TIMEO (5 * RT_TICK_PER_SECOND)
  440. rt_err_t result = RT_EOK;
  441. int response = -1, recv_data_len, ping_time, ttl;
  442. char ip_addr[N720_PING_IP_SIZE] = {0};
  443. at_response_t resp = RT_NULL;
  444. struct at_device *device = RT_NULL;
  445. #if RT_VER_NUM >= 0x50100
  446. RT_UNUSED(is_bind);
  447. #endif
  448. RT_ASSERT(netdev);
  449. RT_ASSERT(host);
  450. RT_ASSERT(ping_resp);
  451. device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
  452. if (device == RT_NULL)
  453. {
  454. LOG_E("get device(%s) failed.", netdev->name);
  455. return -RT_ERROR;
  456. }
  457. resp = at_create_resp(N720_PING_RESP_SIZE, 4, N720_PING_TIMEO);
  458. if (resp == RT_NULL)
  459. {
  460. LOG_E("no memory for resp create");
  461. return -RT_ENOMEM;
  462. }
  463. /* send "AT+QPING=<contextID>"<host>"[,[<timeout>][,<pingnum>]]" commond to send ping request */
  464. if (at_obj_exec_cmd(device->client, resp, "AT+PING=1,%s,%d,1", host, timeout / RT_TICK_PER_SECOND) < 0)
  465. {
  466. result = -RT_ERROR;
  467. goto __exit;
  468. }
  469. at_resp_parse_line_args_by_kw(resp, "+PING:", "+PING:%d", &response);
  470. /* Received the ping response from the server */
  471. if (response == 0)
  472. {
  473. if (at_resp_parse_line_args_by_kw(resp, "+PING:", "+PING:%d,\"%[^\"]\",%d,%d,%d",
  474. &response, ip_addr, &recv_data_len, &ping_time, &ttl) <= 0)
  475. {
  476. result = -RT_ERROR;
  477. goto __exit;
  478. }
  479. }
  480. /* prase response number */
  481. switch (response)
  482. {
  483. case 0:
  484. inet_aton(ip_addr, &(ping_resp->ip_addr));
  485. ping_resp->data_len = recv_data_len;
  486. ping_resp->ticks = ping_time;
  487. ping_resp->ttl = ttl;
  488. result = RT_EOK;
  489. break;
  490. case 569:
  491. result = -RT_ETIMEOUT;
  492. break;
  493. default:
  494. result = -RT_ERROR;
  495. break;
  496. }
  497. __exit:
  498. if (resp)
  499. {
  500. at_delete_resp(resp);
  501. }
  502. return result;
  503. }
  504. #endif /* NETDEV_USING_PING */
  505. const struct netdev_ops n720_netdev_ops =
  506. {
  507. n720_netdev_set_up,
  508. n720_netdev_set_down,
  509. RT_NULL,
  510. n720_netdev_set_dns_server,
  511. RT_NULL,
  512. #ifdef NETDEV_USING_PING
  513. n720_netdev_ping,
  514. #endif
  515. RT_NULL,
  516. };
  517. static struct netdev *n720_netdev_add(const char *netdev_name)
  518. {
  519. #define ETHERNET_MTU 1500
  520. #define HWADDR_LEN 8
  521. struct netdev *netdev = RT_NULL;
  522. netdev = netdev_get_by_name(netdev_name);
  523. if(netdev != RT_NULL)
  524. {
  525. return netdev;
  526. }
  527. netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
  528. if (netdev == RT_NULL)
  529. {
  530. LOG_E("no memory for netdev create.");
  531. return RT_NULL;
  532. }
  533. netdev->mtu = ETHERNET_MTU;
  534. netdev->ops = &n720_netdev_ops;
  535. netdev->hwaddr_len = HWADDR_LEN;
  536. #ifdef SAL_USING_AT
  537. extern int sal_at_netdev_set_pf_info(struct netdev *netdev);
  538. /* set the network interface socket/netdb operations */
  539. sal_at_netdev_set_pf_info(netdev);
  540. #endif
  541. netdev_register(netdev, netdev_name, RT_NULL);
  542. return netdev;
  543. }
  544. /* ============================= n720 device operations ============================= */
  545. /* initialize for n720 */
  546. static void n720_init_thread_entry(void *parameter)
  547. {
  548. #define RESP_SIZE 128
  549. #define INIT_RETRY 5
  550. #define CPIN_RETRY 10
  551. #define CSQ_RETRY 20
  552. #define CGREG_RETRY 50
  553. int i;
  554. int retry_num = INIT_RETRY;
  555. rt_err_t result = RT_EOK;
  556. at_response_t resp = RT_NULL;
  557. struct at_device *device = (struct at_device *) parameter;
  558. struct at_client *client = device->client;
  559. resp = at_create_resp(RESP_SIZE, 0, rt_tick_from_millisecond(300));
  560. if (resp == RT_NULL)
  561. {
  562. LOG_E("no memory for resp create.");
  563. return;
  564. }
  565. LOG_D("start init %s device.", device->name);
  566. while (retry_num--)
  567. {
  568. /* power on the n720 device */
  569. n720_power_on(device);
  570. rt_thread_mdelay(1000);
  571. /* wait n720 startup finish, send AT every 500ms, if receive OK, SYNC success*/
  572. if (at_client_obj_wait_connect(client, N720_WAIT_CONNECT_TIME))
  573. {
  574. result = -RT_ETIMEOUT;
  575. goto __exit;
  576. }
  577. rt_thread_mdelay(5000);
  578. /* disable echo */
  579. if (at_obj_exec_cmd(device->client, resp, "ATE0") != RT_EOK)
  580. {
  581. result = -RT_ERROR;
  582. goto __exit;
  583. }
  584. /* Get the baudrate */
  585. if (at_obj_exec_cmd(device->client, resp, "AT+IPR?") != RT_EOK)
  586. {
  587. result = -RT_ERROR;
  588. goto __exit;
  589. }
  590. at_resp_parse_line_args_by_kw(resp, "+IPR:", "+IPR: %d", &i);
  591. LOG_D("%s device baudrate %d", device->name, i);
  592. /* get module version */
  593. if (at_obj_exec_cmd(device->client, resp, "ATI") != RT_EOK)
  594. {
  595. result = -RT_ERROR;
  596. goto __exit;
  597. }
  598. for (i = 0; i < (int) resp->line_counts - 1; i++)
  599. {
  600. LOG_D("%s", at_resp_get_line(resp, i + 1));
  601. }
  602. /* check SIM card */
  603. for (i = 0; i < CPIN_RETRY; i++)
  604. {
  605. rt_thread_mdelay(1000);
  606. if (at_obj_exec_cmd(device->client, resp, "AT+CPIN?") == RT_EOK)
  607. {
  608. if (at_resp_get_line_by_kw(resp, "READY") != RT_NULL)
  609. break;
  610. }
  611. }
  612. if (i == CPIN_RETRY)
  613. {
  614. LOG_E("%s device SIM card detection failed.", device->name);
  615. result = -RT_ERROR;
  616. goto __exit;
  617. }
  618. /* check signal strength */
  619. for (i = 0; i < CSQ_RETRY; i++)
  620. {
  621. rt_thread_mdelay(1000);
  622. if (at_obj_exec_cmd(device->client, resp, "AT+CSQ") == RT_EOK)
  623. {
  624. int signal_strength = 0, err_rate = 0;
  625. if (at_resp_parse_line_args_by_kw(resp, "+CSQ:", "+CSQ: %d,%d", &signal_strength, &err_rate) > 0)
  626. {
  627. if ((signal_strength != 99) && (signal_strength != 0))
  628. {
  629. LOG_D("%s device signal strength: %d, channel bit error rate: %d",
  630. device->name, signal_strength, err_rate);
  631. break;
  632. }
  633. }
  634. }
  635. }
  636. if (i == CSQ_RETRY)
  637. {
  638. LOG_E("%s device signal strength check failed", device->name);
  639. result = -RT_ERROR;
  640. goto __exit;
  641. }
  642. /* check the GPRS network is registered */
  643. for (i = 0; i < CGREG_RETRY; i++)
  644. {
  645. rt_thread_mdelay(1000);
  646. if (at_obj_exec_cmd(device->client, resp, "AT+CGREG?") == RT_EOK)
  647. {
  648. int link_stat = 0;
  649. if (at_resp_parse_line_args_by_kw(resp, "+CGREG:", "+CGREG: %*d,%d", &link_stat) > 0)
  650. {
  651. if ((link_stat == 1) || (link_stat == 5))
  652. {
  653. LOG_D("%s device GPRS is registered", device->name);
  654. break;
  655. }
  656. }
  657. }
  658. }
  659. if (i == CGREG_RETRY)
  660. {
  661. LOG_E("%s device GPRS is register failed", device->name);
  662. result = -RT_ERROR;
  663. goto __exit;
  664. }
  665. if (((struct at_device_n720 *)(device->user_data))->wakeup_pin != -1)//use wakeup pin
  666. {
  667. if (at_obj_exec_cmd(device->client, resp, "AT+ENPWRSAVE=1") != RT_EOK)// enable sleep mode fail
  668. {
  669. result = -RT_ERROR;
  670. goto __exit;
  671. }
  672. }
  673. /* Activate context profile */
  674. resp = at_resp_set_info(resp, RESP_SIZE, 0, rt_tick_from_millisecond(30*1000));
  675. if (at_obj_exec_cmd(device->client, resp, "AT+CGATT=1") != RT_EOK)
  676. {
  677. result = -RT_ERROR;
  678. goto __exit;
  679. }
  680. /* Activate PPP */
  681. resp = at_resp_set_info(resp, RESP_SIZE, 0, rt_tick_from_millisecond(30*1000));
  682. if (at_obj_exec_cmd(device->client, resp, "AT$MYNETACT=0,1") != RT_EOK)
  683. {
  684. result = -RT_ERROR;
  685. goto __exit;
  686. }
  687. /* Get IP address */
  688. if (at_obj_exec_cmd(device->client, resp, "AT$MYNETACT?") == RT_EOK)
  689. {
  690. char ip_str[20];
  691. if (at_resp_parse_line_args_by_kw(resp, "$MYNETACT:", "$MYNETACT: %*[^\"]\"%[^\"]", ip_str) <= 0)
  692. {
  693. result = -RT_ERROR;
  694. goto __exit;
  695. }
  696. }
  697. /* initialize successfully */
  698. result = RT_EOK;
  699. break;
  700. __exit:
  701. if (result != RT_EOK)
  702. {
  703. /* power off the n720 device */
  704. n720_power_off(device);
  705. rt_thread_mdelay(3000);
  706. LOG_I("%s device initialize retry...", device->name);
  707. }
  708. }
  709. if (resp)
  710. {
  711. at_delete_resp(resp);
  712. }
  713. if (result == RT_EOK)
  714. {
  715. /* set network interface device status and address information */
  716. n720_netdev_set_info(device->netdev);
  717. /* check and create link staus sync thread */
  718. if (rt_thread_find(device->netdev->name) == RT_NULL)
  719. {
  720. n720_netdev_check_link_status(device->netdev);
  721. }
  722. LOG_I("%s device network initialize success.", device->name);
  723. }
  724. else
  725. {
  726. LOG_E("%s device network initialize failed(%d).", device->name, result);
  727. }
  728. }
  729. /* n720 device network initialize */
  730. static int n720_net_init(struct at_device *device)
  731. {
  732. #ifdef AT_DEVICE_N720_INIT_ASYN
  733. rt_thread_t tid;
  734. tid = rt_thread_create("n720_net", n720_init_thread_entry, (void *)device,
  735. N720_THREAD_STACK_SIZE, N720_THREAD_PRIORITY, 20);
  736. if (tid)
  737. {
  738. rt_thread_startup(tid);
  739. }
  740. else
  741. {
  742. LOG_E("create %s device init thread failed.", device->name);
  743. return -RT_ERROR;
  744. }
  745. #else
  746. n720_init_thread_entry(device);
  747. #endif /* AT_DEVICE_N720_INIT_ASYN */
  748. return RT_EOK;
  749. }
  750. static int n720_init(struct at_device *device)
  751. {
  752. struct at_device_n720 *n720 = RT_NULL;
  753. RT_ASSERT(device);
  754. n720 = (struct at_device_n720 *) device->user_data;
  755. n720->power_status = RT_FALSE;//default power is off.
  756. n720->sleep_status = RT_FALSE;//default sleep is disabled.
  757. /* initialize AT client */
  758. #if RT_VER_NUM >= 0x50100
  759. at_client_init(n720->client_name, n720->recv_line_num, n720->recv_line_num);
  760. #else
  761. at_client_init(n720->client_name, n720->recv_line_num);
  762. #endif
  763. device->client = at_client_get(n720->client_name);
  764. if (device->client == RT_NULL)
  765. {
  766. LOG_E("get AT client(%s) failed.", n720->client_name);
  767. return -RT_ERROR;
  768. }
  769. /* register URC data execution function */
  770. #ifdef AT_USING_SOCKET
  771. n720_socket_init(device);
  772. #endif
  773. /* add n720 device to the netdev list */
  774. device->netdev = n720_netdev_add(n720->device_name);
  775. if (device->netdev == RT_NULL)
  776. {
  777. LOG_E("add netdev(%s) failed.", n720->device_name);
  778. return -RT_ERROR;
  779. }
  780. /* initialize n720 pin configuration */
  781. if (n720->power_pin != -1)
  782. {
  783. rt_pin_write(n720->power_pin, PIN_LOW);
  784. rt_pin_mode(n720->power_pin, PIN_MODE_OUTPUT);
  785. }
  786. if (n720->power_status_pin != -1)
  787. {
  788. rt_pin_mode(n720->power_status_pin, PIN_MODE_INPUT);
  789. }
  790. if (n720->wakeup_pin != -1)
  791. {
  792. rt_pin_write(n720->wakeup_pin, PIN_LOW);
  793. rt_pin_mode(n720->wakeup_pin, PIN_MODE_OUTPUT);
  794. }
  795. /* initialize n720 device network */
  796. return n720_netdev_set_up(device->netdev);
  797. }
  798. static int n720_deinit(struct at_device *device)
  799. {
  800. RT_ASSERT(device);
  801. return n720_netdev_set_down(device->netdev);
  802. }
  803. static int n720_control(struct at_device *device, int cmd, void *arg)
  804. {
  805. int result = -RT_ERROR;
  806. RT_ASSERT(device);
  807. switch (cmd)
  808. {
  809. case AT_DEVICE_CTRL_SLEEP:
  810. result = n720_sleep(device);
  811. break;
  812. case AT_DEVICE_CTRL_WAKEUP:
  813. result = n720_wakeup(device);
  814. break;
  815. case AT_DEVICE_CTRL_POWER_ON:
  816. case AT_DEVICE_CTRL_POWER_OFF:
  817. case AT_DEVICE_CTRL_RESET:
  818. case AT_DEVICE_CTRL_LOW_POWER:
  819. case AT_DEVICE_CTRL_NET_CONN:
  820. case AT_DEVICE_CTRL_NET_DISCONN:
  821. case AT_DEVICE_CTRL_SET_WIFI_INFO:
  822. case AT_DEVICE_CTRL_GET_SIGNAL:
  823. case AT_DEVICE_CTRL_GET_GPS:
  824. case AT_DEVICE_CTRL_GET_VER:
  825. LOG_W("not support the control command(%d).", cmd);
  826. break;
  827. default:
  828. LOG_E("input error control command(%d).", cmd);
  829. break;
  830. }
  831. return result;
  832. }
  833. const struct at_device_ops n720_device_ops =
  834. {
  835. n720_init,
  836. n720_deinit,
  837. n720_control,
  838. };
  839. static int n720_device_class_register(void)
  840. {
  841. struct at_device_class *class = RT_NULL;
  842. class = (struct at_device_class *) rt_calloc(1, sizeof(struct at_device_class));
  843. if (class == RT_NULL)
  844. {
  845. LOG_E("no memory for device class create.");
  846. return -RT_ENOMEM;
  847. }
  848. /* fill n720 device class object */
  849. #ifdef AT_USING_SOCKET
  850. n720_socket_class_register(class);
  851. #endif
  852. class->device_ops = &n720_device_ops;
  853. return at_device_class_register(class, AT_DEVICE_CLASS_N720);
  854. }
  855. INIT_DEVICE_EXPORT(n720_device_class_register);
  856. #endif /* AT_DEVICE_USING_N720 */