luat_sntp.c 7.2 KB

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