luat_sntp.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include "luat_base.h"
  2. #include "luat_network_adapter.h"
  3. #include "luat_rtos.h"
  4. #include "luat_msgbus.h"
  5. #include "luat_malloc.h"
  6. #include "luat_rtc.h"
  7. #include "luat_sntp.h"
  8. #define LUAT_LOG_TAG "sntp"
  9. #include "luat_log.h"
  10. #define SNTP_SERVER_COUNT 3
  11. #define SNTP_SERVER_LEN_MAX 32
  12. static char sntp_server[SNTP_SERVER_COUNT][SNTP_SERVER_LEN_MAX] = {
  13. "ntp.aliyun.com",
  14. "ntp1.aliyun.com",
  15. "ntp2.aliyun.com"
  16. };
  17. static unsigned int sntp_server_num = 0;
  18. static const uint8_t sntp_packet[48]={0x1b};
  19. #define NTP_UPDATE 1
  20. #define NTP_ERROR 2
  21. static int l_sntp_event_handle(lua_State* L, void* ptr) {
  22. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  23. if (lua_getglobal(L, "sys_pub") != LUA_TFUNCTION) {
  24. return 0;
  25. };
  26. switch (msg->arg1)
  27. {
  28. case NTP_UPDATE:
  29. lua_pushstring(L, "NTP_UPDATE");
  30. break;
  31. case NTP_ERROR:
  32. lua_pushstring(L, "NTP_ERROR");
  33. break;
  34. default:
  35. return 0;
  36. }
  37. lua_call(L, 1, 0);
  38. return 0;
  39. }
  40. int luat_sntp_connect(network_ctrl_t *sntp_netc){
  41. int ret;
  42. luat_ip_addr_t ip_addr;
  43. #ifdef LUAT_USE_LWIP
  44. ip_addr.type = 0xff;
  45. #else
  46. ip_addr.is_ipv6 = 0xff;
  47. #endif
  48. if (sntp_server_num >= sizeof(sntp_server))
  49. return -1;
  50. #ifdef LUAT_USE_LWIP
  51. ret = network_connect(sntp_netc, sntp_server[sntp_server_num], strlen(sntp_server[sntp_server_num]), (0xff == ip_addr.type)?NULL:&(ip_addr), 123, 1000);
  52. #else
  53. ret = network_connect(sntp_netc, sntp_server[sntp_server_num], strlen(sntp_server[sntp_server_num]), (0xff == ip_addr.is_ipv6)?NULL:&(ip_addr), 123, 1000);
  54. #endif
  55. sntp_server_num++;
  56. // LLOGD("network_connect ret %d", ret);
  57. if (ret < 0) {
  58. network_close(sntp_netc, 0);
  59. return -1;
  60. }
  61. return 0;
  62. }
  63. int luat_sntp_close_socket(network_ctrl_t *sntp_netc){
  64. if (sntp_netc){
  65. network_force_close_socket(sntp_netc);
  66. }
  67. if (sntp_server_num == 0){
  68. #ifdef __LUATOS__
  69. rtos_msg_t msg;
  70. msg.handler = l_sntp_event_handle;
  71. msg.arg1 = NTP_UPDATE;
  72. luat_msgbus_put(&msg, 0);
  73. #endif
  74. network_release_ctrl(sntp_netc);
  75. return 0;
  76. }
  77. if (sntp_server_num < sizeof(sntp_server)){
  78. luat_sntp_connect(sntp_netc);
  79. }else{
  80. network_release_ctrl(sntp_netc);
  81. sntp_server_num = 0;
  82. #ifdef __LUATOS__
  83. rtos_msg_t msg;
  84. msg.handler = l_sntp_event_handle;
  85. msg.arg1 = NTP_ERROR;
  86. luat_msgbus_put(&msg, 0);
  87. #endif
  88. }
  89. return 0;
  90. }
  91. int32_t luat_sntp_callback(void *data, void *param) {
  92. OS_EVENT *event = (OS_EVENT *)data;
  93. network_ctrl_t *sntp_netc =(network_ctrl_t *)param;
  94. int ret = 0;
  95. uint32_t tx_len = 0;
  96. // LLOGD("LINK %d ON_LINE %d EVENT %d TX_OK %d CLOSED %d",EV_NW_RESULT_LINK & 0x0fffffff,EV_NW_RESULT_CONNECT & 0x0fffffff,EV_NW_RESULT_EVENT & 0x0fffffff,EV_NW_RESULT_TX & 0x0fffffff,EV_NW_RESULT_CLOSE & 0x0fffffff);
  97. // LLOGD("network sntp cb %8X %s %8X",event->ID & 0x0ffffffff, event2str(event->ID & 0x0ffffffff) ,event->Param1);
  98. if (event->ID == EV_NW_RESULT_LINK){
  99. return 0; // 这里应该直接返回, 不能往下调用network_wait_event
  100. }else if(event->ID == EV_NW_RESULT_CONNECT){
  101. network_tx(sntp_netc, sntp_packet, sizeof(sntp_packet), 0, NULL, 0, &tx_len, 0);
  102. // LLOGD("luat_sntp_callback tx_len:%d",tx_len);
  103. }else if(event->ID == EV_NW_RESULT_EVENT){
  104. uint32_t total_len = 0;
  105. uint32_t rx_len = 0;
  106. int result = network_rx(sntp_netc, NULL, 0, 0, NULL, NULL, &total_len);
  107. // LLOGD("result:%d total_len:%d",result,total_len);
  108. if (0 == result){
  109. if (total_len>0){
  110. uint8_t* resp_buff = luat_heap_malloc(total_len + 1);
  111. resp_buff[total_len] = 0x00;
  112. next:
  113. result = network_rx(sntp_netc, resp_buff, total_len, 0, NULL, NULL, &rx_len);
  114. // LLOGD("result:%d rx_len:%d",result,rx_len);
  115. // LLOGD("resp_buff:%.*s len:%d",total_len,resp_buff,total_len);
  116. if (result)
  117. goto next;
  118. if (rx_len == 0||result!=0) {
  119. luat_heap_free(resp_buff);
  120. luat_sntp_close_socket(sntp_netc);
  121. return -1;
  122. }
  123. const uint8_t *p = (const uint8_t *)resp_buff+40;
  124. uint32_t time = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
  125. if (time > 0x83AA7E80){
  126. time -= 0x83AA7E80;
  127. }else{
  128. time += 0x7C558180;
  129. }
  130. luat_rtc_set_tamp32(time);
  131. LLOGD("Unix timestamp:%d",time);
  132. sntp_server_num = 0;
  133. luat_sntp_close_socket(sntp_netc);
  134. luat_heap_free(resp_buff);
  135. return 0;
  136. }
  137. }else{
  138. luat_sntp_close_socket(sntp_netc);
  139. return -1;
  140. }
  141. }else if(event->ID == EV_NW_RESULT_TX){
  142. }else if(event->ID == EV_NW_RESULT_CLOSE){
  143. }
  144. if (event->Param1){
  145. // LLOGW("sntp_callback param1 %d, closing socket", event->Param1);
  146. luat_sntp_close_socket(sntp_netc);
  147. }
  148. ret = network_wait_event(sntp_netc, NULL, 0, NULL);
  149. if (ret < 0){
  150. // LLOGW("network_wait_event ret %d, closing socket", ret);
  151. luat_sntp_close_socket(sntp_netc);
  152. return -1;
  153. }
  154. return 0;
  155. }
  156. int ntp_get(void){
  157. int adapter_index = network_get_last_register_adapter();
  158. if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY){
  159. return -1;
  160. }
  161. network_ctrl_t *sntp_netc = network_alloc_ctrl(adapter_index);
  162. if (!sntp_netc){
  163. LLOGE("network_alloc_ctrl fail");
  164. return -1;
  165. }
  166. network_init_ctrl(sntp_netc, NULL, luat_sntp_callback, sntp_netc);
  167. network_set_base_mode(sntp_netc, 0, 10000, 0, 0, 0, 0);
  168. network_set_local_port(sntp_netc, 0);
  169. network_deinit_tls(sntp_netc);
  170. return luat_sntp_connect(sntp_netc);
  171. }
  172. int l_sntp_get(lua_State *L){
  173. size_t len = 0;
  174. if (lua_isstring(L, 1)){
  175. const char * server_addr = luaL_checklstring(L, 1, &len);
  176. if (len < SNTP_SERVER_LEN_MAX){
  177. memcpy(sntp_server[0], server_addr, len);
  178. sntp_server[0][len] = 0x00;
  179. }else{
  180. LLOGE("server_addr too lang");
  181. }
  182. }else if(lua_istable(L, 1)){
  183. size_t count = lua_rawlen(L, 1);
  184. if (count > sizeof(sntp_server)){
  185. count = sizeof(sntp_server);
  186. }
  187. for (size_t i = 0; i < count; i++){
  188. lua_geti(L, 1, i);
  189. const char * server_addr = luaL_checklstring(L, -1, &len);
  190. if (len < SNTP_SERVER_LEN_MAX){
  191. memcpy(sntp_server[i], server_addr, len);
  192. sntp_server[i][len] = 0x00;
  193. }else{
  194. LLOGE("server_addr too lang");
  195. }
  196. lua_pop(L, 1);
  197. }
  198. }
  199. ntp_get();
  200. return 0;
  201. }