1 /** 2 * @file aiot_ntp_api.h 3 * @brief ntp模块头文件, 提供获取utc时间的能力 4 * 5 * @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited 6 * 7 * @details 8 * 9 * NTP模块用于从阿里云物联网平台上获取UTC时间, API的使用流程如下: 10 * 11 * 1. 首先参考 @ref aiot_mqtt_api.h 的说明, 保证成功建立与物联网平台的`MQTT`连接 12 * 13 * 2. 调用 @ref aiot_ntp_init 初始化ntp会话, 获取会话句柄 14 * 15 * 3. 调用 @ref aiot_ntp_setopt 配置NTP会话的参数, 常用配置项见 @ref aiot_ntp_setopt 的说明 16 * 17 * 4. 调用 @ref aiot_ntp_send_request 发送NTP请求 18 * 19 * 5. 收到的UTC时间经SDK处理后会调用由 @ref aiot_ntp_setopt 配置的 @ref AIOT_NTPOPT_RECV_HANDLER 回调函数, 通知用户当前的时间 20 * 21 */ 22 #ifndef __AIOT_NTP_API_H__ 23 #define __AIOT_NTP_API_H__ 24 25 #if defined(__cplusplus) 26 extern "C" { 27 #endif 28 29 #include <stdint.h> 30 31 /** 32 * @brief -0x1100~-0x11FF表达SDK在ntp模块内的状态码 33 */ 34 #define STATE_NTP_BASE (-0x1100) 35 36 /** 37 * @brief MQTT会话句柄未设置, 请通过 @ref aiot_ntp_setopt 设置MQTT会话句柄 38 */ 39 #define STATE_NTP_MISSING_MQTT_HANDLE (-0x1101) 40 41 /** 42 * @brief ntp模块收到从网络上来的报文时, 通知用户的报文类型 43 */ 44 typedef enum { 45 AIOT_NTPRECV_LOCAL_TIME 46 } aiot_ntp_recv_type_t; 47 48 /** 49 * @brief ntp模块收到从网络上来的报文时, 通知用户的报文内容 50 */ 51 typedef struct { 52 /** 53 * @brief 报文内容所对应的报文类型, 更多信息请参考@ref aiot_ntp_recv_type_t 54 */ 55 aiot_ntp_recv_type_t type; 56 union { 57 /** 58 * @brief utc事件戳以及时区换算后的日期, 以 @ref AIOT_NTPOPT_TIME_ZONE 设置的时区为准 59 */ 60 struct { 61 uint64_t timestamp; 62 uint32_t year; 63 uint32_t mon; 64 uint32_t day; 65 uint32_t hour; 66 uint32_t min; 67 uint32_t sec; 68 uint32_t msec; 69 } local_time; 70 } data; 71 } aiot_ntp_recv_t; 72 73 /** 74 * @brief ntp模块收到从网络上来的报文时, 通知用户所调用的数据回调函数 75 * 76 * @param[in] handle ntp会话句柄 77 * @param[in] packet ntp消息结构体, 存放收到的ntp报文内容 78 * @param[in] userdata 用户上下文 79 * 80 * @return void 81 */ 82 typedef void (* aiot_ntp_recv_handler_t)(void *handle, 83 const aiot_ntp_recv_t *packet, void *userdata); 84 85 /** 86 * @brief ntp内部事件类型 87 */ 88 typedef enum { 89 /** 90 * @brief 收到的ntp应答中字段不合法 91 */ 92 AIOT_NTPEVT_INVALID_RESPONSE, 93 /** 94 * @brief 收到的ntp应答中时间字段格式错误 95 */ 96 AIOT_NTPEVT_INVALID_TIME_FORMAT, 97 } aiot_ntp_event_type_t; 98 99 /** 100 * @brief NTP内部事件 101 */ 102 typedef struct { 103 /** 104 * @brief NTP内部事件类型. 更多信息请参考@ref aiot_ntp_event_type_t 105 * 106 */ 107 aiot_ntp_event_type_t type; 108 } aiot_ntp_event_t; 109 110 /** 111 * @brief ntp事件回调函数 112 * 113 * @details 114 * 115 * 当NTP内部事件被触发时, 调用此函数 116 * 117 */ 118 typedef void (*aiot_ntp_event_handler_t)(void *handle, const aiot_ntp_event_t *event, void *userdata); 119 120 /** 121 * @brief @ref aiot_ntp_setopt 接口的option参数可选值. 122 * 123 * @details 下文每个选项中的数据类型, 指的是@ref aiot_ntp_setopt 中, data参数的数据类型 124 * 125 * 1. data的数据类型是char *时, 以配置@ref AIOT_NTPOPT_MQTT_HANDLE 为例: 126 * 127 * void *mqtt_handle = aiot_mqtt_init(); 128 * aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_MQTT_HANDLE, mqtt_handle); 129 * 130 * 2. data的数据类型是其他数据类型时, 以配置@ref AIOT_NTPOPT_TIME_ZONE 为例: 131 * 132 * int8_t time_zone = 8; 133 * aiot_mqtt_setopt(ntp_handle, AIOT_NTPOPT_TIME_ZONE, (void *)&time_zone); 134 */ 135 typedef enum { 136 /** 137 * @brief ntp会话 需要的MQTT句柄, 需要先建立MQTT连接, 再设置MQTT句柄 138 * 139 * @details 140 * 141 * 数据类型: (void *) 142 */ 143 AIOT_NTPOPT_MQTT_HANDLE, 144 145 /** 146 * @brief ntp会话 获取到utc时间后会根据此时区值转换成本地时间, 再通过 @ref aiot_ntp_recv_handler_t 通知 147 * 148 * @details 149 * 150 * 取值示例: 东8区, 取值为8; 西3区, 取值为-3 151 * 152 * 数据类型: (int8_t *) 153 */ 154 AIOT_NTPOPT_TIME_ZONE, 155 156 /** 157 * @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户 158 * 159 * @details 160 * 161 * 数据类型: ( @ref aiot_ntp_recv_handler_t ) 162 */ 163 AIOT_NTPOPT_RECV_HANDLER, 164 165 /** 166 * @brief ntp内部发生的事件会从此回调函数进行通知 167 * 168 * @details 169 * 170 * 数据类型: ( @ref aiot_ntp_event_handler_t ) 171 */ 172 AIOT_NTPOPT_EVENT_HANDLER, 173 174 /** 175 * @brief 用户需要SDK暂存的上下文 176 * 177 * @details 这个上下文指针会在 AIOT_NTPOPT_RECV_HANDLER 和 AIOT_NTPOPT_EVENT_HANDLER 设置的回调被调用时, 由SDK传给用户 178 * 179 * 数据类型: (void *) 180 */ 181 AIOT_NTPOPT_USERDATA, 182 183 /** 184 * @brief 销毁ntp实例时, 等待其他api执行完毕的时间 185 * 186 * @details 187 * 188 * 当调用@ref aiot_ntp_deinit 销毁NTP实例时, 若继续调用其他aiot_ntp_xxx API, API会返回@ref STATE_USER_INPUT_EXEC_DISABLED 错误 189 * 190 * 此时, 用户应该停止调用其他aiot_ntp_xxx API 191 * 192 * 数据类型: (uint32_t *) 默认值: (2 * 1000) ms 193 */ 194 AIOT_NTPOPT_DEINIT_TIMEOUT_MS, 195 AIOT_NTPOPT_MAX 196 } aiot_ntp_option_t; 197 198 /** 199 * @brief 创建ntp会话实例, 并以默认值配置会话参数 200 * 201 * @return void * 202 * @retval 非NULL ntp实例的句柄 203 * @retval NULL 初始化失败, 一般是内存分配失败导致 204 * 205 */ 206 void *aiot_ntp_init(void); 207 208 /** 209 * @brief 配置ntp会话 210 * 211 * @details 212 * 213 * 常见的配置项如下 214 * 215 * + `AIOT_NTPOPT_MQTT_HANDLE`: 已建立连接的MQTT会话句柄 216 * 217 * + `AIOT_NTPOPT_TIME_ZONE`: 时区设置, SDK会将收到的UTC时间按配置的时区进行转换 218 * 219 * + `AIOT_NTPOPT_RECV_HANDLER`: 时间数据接收回调函数, SDK将UTC时间转换完成后, 通过此回调函数输出 220 * 221 * @param[in] handle ntp会话句柄 222 * @param[in] option 配置选项, 更多信息请参考@ref aiot_ntp_option_t 223 * @param[in] data 配置选项数据, 更多信息请参考@ref aiot_ntp_option_t 224 * 225 * @return int32_t 226 * @retval <STATE_SUCCESS 参数配置失败 227 * @retval >=STATE_SUCCESS 参数配置成功 228 * 229 */ 230 int32_t aiot_ntp_setopt(void *handle, aiot_ntp_option_t option, void *data); 231 232 /** 233 * @brief 结束ntp会话, 销毁实例并回收资源 234 * 235 * @param[in] handle 指向ntp会话句柄的指针 236 * 237 * @return int32_t 238 * @retval <STATE_SUCCESS 执行失败 239 * @retval >=STATE_SUCCESS 执行成功 240 * 241 */ 242 int32_t aiot_ntp_deinit(void **handle); 243 244 /** 245 * @brief 向ntp服务器发送ntp消息请求 246 * 247 * @details 248 * 249 * 发送NTP请求, 然后SDK会调用通过 @ref aiot_ntp_setopt 配置的 @ref AIOT_NTPOPT_RECV_HANDLER 回调函数, 通知用户当前的时间 250 * 251 * @param handle ntp会话句柄 252 * 253 * @return int32_t 254 * @retval <STATE_SUCCESS 请求发送失败 255 * @retval >=STATE_SUCCESS 请求发送成功 256 */ 257 int32_t aiot_ntp_send_request(void *handle); 258 259 #if defined(__cplusplus) 260 } 261 #endif 262 263 #endif /* __AIOT_NTP_API_H__ */ 264 265