9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
191 lines
5.2 KiB
C
191 lines
5.2 KiB
C
/*
|
|
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
|
*/
|
|
#include "iotx_dm_internal.h"
|
|
|
|
#ifdef DEPRECATED_LINKKIT
|
|
|
|
#include "infra_json_parser.h"
|
|
#include "mqtt_api.h"
|
|
#include "impl_ntp.h"
|
|
|
|
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef INFRA_MEM_STATS
|
|
#include "infra_mem_stats.h"
|
|
#define IMPL_NTP_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "impl.ntp")
|
|
#define IMPL_NTP_FREE(ptr) LITE_free(ptr)
|
|
#else
|
|
#define IMPL_NTP_MALLOC(size) HAL_Malloc(size)
|
|
#define IMPL_NTP_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
|
|
#endif
|
|
|
|
typedef void (*ntp_reply_cb_t)(const char *);
|
|
static ntp_reply_cb_t g_ntp_reply_cb = NULL;
|
|
static char g_ntp_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
|
|
|
|
static void linkkit_ntp_time_reply(void *pcontext, void *pclient, void *mesg)
|
|
{
|
|
#define DEV_TX_TIME "deviceSendTime"
|
|
#define SERVER_RX_TIME "serverRecvTime"
|
|
#define SERVER_TX_TIME "serverSendTime"
|
|
|
|
int len = 0;
|
|
char *elem = NULL;
|
|
char server_rx_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
|
|
char server_tx_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
|
|
uint32_t payload_len;
|
|
char *payload;
|
|
uint32_t tx = 0;
|
|
uint32_t rx = 0;
|
|
uint32_t diff = 0;
|
|
|
|
iotx_mqtt_event_msg_pt msg = (iotx_mqtt_event_msg_pt)mesg;
|
|
iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
|
|
|
|
switch (msg->event_type) {
|
|
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
|
|
payload_len = ptopic_info->payload_len;
|
|
payload = (char *)ptopic_info->payload;
|
|
break;
|
|
default:
|
|
goto NTP_FAIL;
|
|
}
|
|
|
|
if (payload == NULL || payload_len == 0) {
|
|
goto NTP_FAIL;
|
|
}
|
|
|
|
memset(g_ntp_time, 0, sizeof(g_ntp_time));
|
|
log_debug("[ntp]", "ntp reply len:%u, payload:%s\r\n", payload_len, payload);
|
|
|
|
/*
|
|
* get deviceSendTime, serverRecvTime, serverSendTime
|
|
*/
|
|
elem = json_get_value_by_name(payload, payload_len, SERVER_TX_TIME, &len, NULL);
|
|
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
|
|
goto NTP_FAIL;
|
|
}
|
|
|
|
memcpy(server_tx_time, elem, len);
|
|
|
|
elem = json_get_value_by_name(payload, payload_len, SERVER_RX_TIME, &len, NULL);
|
|
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
|
|
goto NTP_FAIL;
|
|
}
|
|
|
|
memcpy(server_rx_time, elem, len);
|
|
|
|
elem = json_get_value_by_name(payload, payload_len, DEV_TX_TIME, &len, NULL);
|
|
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
|
|
goto NTP_FAIL;
|
|
}
|
|
/*
|
|
* atoi fails to convert string to integer
|
|
* so we convert manully
|
|
*/
|
|
while (len -- > 0) {
|
|
tx *= 10;
|
|
tx += elem[0] - '0';
|
|
elem ++;
|
|
}
|
|
rx = HAL_UptimeMs();
|
|
diff = (rx - tx) >> 1;
|
|
if (diff >= 1000000) {
|
|
goto NTP_FAIL;
|
|
}
|
|
|
|
len = strlen(server_tx_time);
|
|
elem = &server_tx_time[len > 9 ? len - 9 : 0];
|
|
tx = atoi(elem);
|
|
tx += diff;
|
|
|
|
if (tx > 999999999) {
|
|
tx = 999999999;
|
|
}
|
|
|
|
if (len > 9) {
|
|
sprintf(elem, "%09u", (unsigned int)tx);
|
|
} else {
|
|
sprintf(elem, "%u", (unsigned int)tx);
|
|
}
|
|
|
|
strncpy(g_ntp_time, (const char *)server_tx_time, sizeof(g_ntp_time) - 1);
|
|
|
|
NTP_FAIL:
|
|
if (g_ntp_reply_cb != NULL) {
|
|
g_ntp_reply_cb(g_ntp_time);
|
|
}
|
|
return;
|
|
}
|
|
|
|
int linkkit_ntp_time_request(void (*ntp_reply)(const char *ntp_offset_time_ms))
|
|
{
|
|
int ret = -1;
|
|
int final_len = 0;
|
|
int packet_len = 64;
|
|
int topic_len = 128;
|
|
char *packet = NULL;
|
|
char *topic = NULL;
|
|
|
|
do {
|
|
char pk[IOTX_PRODUCT_KEY_LEN + 1] = {0};
|
|
char dn[IOTX_DEVICE_NAME_LEN + 1] = {0};
|
|
|
|
IOT_Ioctl(IOTX_IOCTL_GET_PRODUCT_KEY, pk);
|
|
IOT_Ioctl(IOTX_IOCTL_GET_DEVICE_NAME, dn);
|
|
|
|
topic = (char *)IMPL_NTP_MALLOC(topic_len + 1);
|
|
if (topic == NULL) {
|
|
goto NTP_REQ_ERR;
|
|
}
|
|
memset(topic, 0, topic_len + 1);
|
|
|
|
HAL_Snprintf(topic, topic_len, TOPIC_NTP_REPLY, pk, dn);
|
|
#ifdef MQTT_AUTO_SUBSCRIBE
|
|
ret = IOT_MQTT_Subscribe_Sync(NULL, topic, IOTX_MQTT_QOS3_SUB_LOCAL,
|
|
(iotx_mqtt_event_handle_func_fpt)linkkit_ntp_time_reply, NULL, 1000);
|
|
#else
|
|
ret = IOT_MQTT_Subscribe_Sync(NULL, topic, IOTX_MQTT_QOS0,
|
|
(iotx_mqtt_event_handle_func_fpt)linkkit_ntp_time_reply, NULL, 1000);
|
|
#endif
|
|
if (ret < 0) {
|
|
goto NTP_REQ_ERR;
|
|
}
|
|
|
|
memset(topic, 0, topic_len + 1);
|
|
HAL_Snprintf(topic, topic_len, TOPIC_NTP, pk, dn);
|
|
} while (0);
|
|
|
|
packet = (char *)IMPL_NTP_MALLOC(packet_len + 1);
|
|
if (packet == NULL) {
|
|
ret = -1;
|
|
goto NTP_REQ_ERR;
|
|
}
|
|
memset(packet, 0, packet_len + 1);
|
|
|
|
g_ntp_reply_cb = ntp_reply;
|
|
final_len = HAL_Snprintf(packet, packet_len, "{\"deviceSendTime\":\"%u\"}", (unsigned int)(HAL_UptimeMs()));
|
|
|
|
log_debug("[ntp]", "report ntp:%s\r\n", packet);
|
|
|
|
|
|
ret = IOT_MQTT_Publish_Simple(NULL, topic, IOTX_MQTT_QOS0, packet, final_len);
|
|
|
|
NTP_REQ_ERR:
|
|
if (topic) {
|
|
IMPL_NTP_FREE(topic);
|
|
}
|
|
if (packet) {
|
|
IMPL_NTP_FREE(packet);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
|
|
}
|
|
#endif
|
|
#endif
|