1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "py/builtin.h"
6 #include "py/obj.h"
7 #include "py/runtime.h"
8 #include "py/stackctrl.h"
9 #include "sntp/sntp.h"
10 #include "ulog/ulog.h"
11 
12 #define LOG_TAG                  "MOD_SNTP"
13 
14 #define SNTP_RCV_TIMEOUT         (5000)
15 #define SNTP_PERSERV_RETRY_TIMES (2)
16 
17 static char *m_sntp_servaddr[] = {
18     "cn.pool.ntp.org",
19     "0.cn.pool.ntp.org",
20     "1.cn.pool.ntp.org",
21 };
22 
23 static int retry_backoff_time[] = { 1, 2, 1, 2, 1, 2, 1, 2 };
24 
sntp_config_servaddr(void)25 static void sntp_config_servaddr(void)
26 {
27     int i = 0;
28     LOGD(LOG_TAG, "sntp config servadd start.");
29     for (i = 0; i < SNTP_MAX_SERVERS; i++) {
30         if (0 != sntp_set_server(i, m_sntp_servaddr[i])) {
31             LOGE(LOG_TAG, "set sntp server:%s failed\n", m_sntp_servaddr[i]);
32         } else {
33             LOGI(LOG_TAG, "set sntp server:%s successfully\n",
34                  m_sntp_servaddr[i]);
35         }
36     }
37     LOGI(LOG_TAG, "sntp config servadd end.");
38 }
39 
sntp_gettime(struct timeval * ntp_time)40 static bool sntp_gettime(struct timeval *ntp_time)
41 {
42     int round = 0;
43     sntp_arg m_sntp_arg = { NULL, SNTP_RCV_TIMEOUT, SNTP_PERSERV_RETRY_TIMES };
44 
45     while (1) {
46         LOGD(LOG_TAG, "sntp getting time.");
47         sntp_config_servaddr();
48         if (0 == sntp_get_time(&m_sntp_arg, ntp_time)) {
49             LOGI(LOG_TAG, "[sntp] OK: sec %ld usec %ld\n", ntp_time->tv_sec,
50                  ntp_time->tv_usec);
51             return true;
52         } else {
53             int retry_time = retry_backoff_time[round];
54             LOGI(LOG_TAG, "[sntp] wait for sntp done...e\n");
55             if (round < sizeof(retry_backoff_time) / sizeof(int) - 1) {
56                 round++;
57             } else {
58                 LOGE(LOG_TAG, "[sntp] Failed to get SNTP from server\n");
59                 return false;
60             }
61             aos_msleep(retry_time * 1000);
62         }
63     }
64 }
65 
mp_sntp_settime(size_t n_args,const mp_obj_t * args)66 STATIC mp_obj_t mp_sntp_settime(size_t n_args, const mp_obj_t *args)
67 {
68     mp_int_t timezone = 8;
69     char *server = "ntp.ntsc.ac.cn";
70 
71     if (n_args == 1) {
72         timezone = mp_obj_get_int(args[0]);
73     } else if (n_args == 2) {
74         timezone = mp_obj_get_int(args[0]);
75         server = (char *)mp_obj_str_get_str(args[1]);
76     }
77 
78     printf("%s, %d, timezone=%d, server=%s\r\n", __func__, __LINE__, timezone,
79            server);
80 
81     struct timeval ntp_time = { 0 };
82     mp_int_t ret = sntp_gettime(&ntp_time);
83 
84     return mp_obj_new_int(ret);
85 }
86 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sntp_settime_obj, 0, 2,
87                                            mp_sntp_settime);
88 
89 STATIC const mp_rom_map_elem_t sntp_module_globals_table[] = {
90     { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sntp) },
91     { MP_OBJ_NEW_QSTR(MP_QSTR_settime), MP_ROM_PTR(&mp_sntp_settime_obj) },
92 };
93 
94 STATIC MP_DEFINE_CONST_DICT(sntp_module_globals, sntp_module_globals_table);
95 
96 const mp_obj_module_t sntp_module = {
97     .base = { &mp_type_module },
98     .globals = (mp_obj_dict_t *)&sntp_module_globals,
99 };
100