本文以C Link SDK中的Demo文件./demos/ntp_posix_demo.c为例,介绍如何调用Link SDK的API,使设备从物联网平台获取UTC时间。

背景信息

  • NTP服务功能的更多信息,请参见概述

  • NTP服务功能基于MQTT接入,开发过程中涉及MQTT接入的代码说明,请参见MQTT接入

步骤一:初始化

  1. 添加头文件。
    ……
    ……
    
    #include "aiot_ntp_api.h"
  2. 配置底层依赖和日志输出。
        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. 调用aiot_ntp_init,创建NTP客户端实例,并初始化默认参数。
        ntp_handle = aiot_ntp_init();
        if (ntp_handle == NULL) {
            demo_mqtt_stop(&mqtt_handle);
            printf("aiot_ntp_init failed\n");
            return -1;
        }

步骤二:配置功能

调用aiot_ntp_setopt,配置以下功能。

  1. 关联MQTT连接的句柄。
    注意 配置NTP服务参数前,请确保已配置设备认证信息等相关参数。具体操作,请参见MQTT配置连接参数
    • 示例代码:
          aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_MQTT_HANDLE, mqtt_handle);
    • 相关参数:
      配置项 示例 说明
      AIOT_NTPOPT_MQTT_HANDLE mqtt_handle NTP服务功能的请求基于MQTT连接,通过该配置项,关联MQTT连接句柄。
  2. 设置时区。
    • 示例代码:
          int8_t      time_zone = 8;
          ……
          ……
          aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_TIME_ZONE, (int8_t *)&time_zone);
    • 相关参数:
      配置项 示例 说明
      AIOT_NTPOPT_TIME_ZONE time_zone 设备所在时区。

      示例代码定义的时区为time_zone=8,设置设备的时区为东八区,即北京时间。

      通过设置time_zone的值,设置设备所在的时区。取值范围:-12~12。例如,-3为西三区。

  3. 配置消息回调
    • 示例代码:
          aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_RECV_HANDLER, (void *)demo_ntp_recv_handler);
    • 相关参数:
      配置项 示例值 说明
      AIOT_NTPOPT_RECV_HANDLER demo_ntp_recv_handler 接收到NTP服务消息时,调用该函数。
  4. 配置状态监控
    1. 定义状态监控回调函数。
      void demo_ntp_event_handler(void *handle, const aiot_ntp_event_t *event, void *userdata)
      {
          switch (event->type) {
              case AIOT_NTPEVT_INVALID_RESPONSE: {
                  printf("AIOT_NTPEVT_INVALID_RESPONSE\n");
              }
              break;
              case AIOT_NTPEVT_INVALID_TIME_FORMAT: {
                  printf("AIOT_NTPEVT_INVALID_TIME_FORMAT\n");
              }
              break;
              default: {
      
              }
          }
      }
    2. 配置状态监控的回调函数。
      • 示例代码:
            aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_EVENT_HANDLER, (void *)demo_ntp_event_handler);
      • 相关参数:
        配置项 示例值 说明
        AIOT_NTPOPT_EVENT_HANDLER demo_ntp_event_handler 当设备连接状态发生变化时,根据该函数的设置,执行对应的处理。

步骤三:发送请求

调用aiot_ntp_send_request,根据上一步配置的参数,通过Topic /ext/ntp/${YourProductKey}/${YourDeviceName}/request,向服务器发送一条包含设备当前时间的请求消息。

Link SDK通过系统接口,自动上报设备当前时间。

    res = aiot_ntp_send_request(ntp_handle);
    if (res < STATE_SUCCESS) {
        aiot_ntp_deinit(&ntp_handle);
        demo_mqtt_stop(&mqtt_handle);
        return -1;
    }

步骤四:接收应答

设备接收NTP服务消息后,触发回调函数demo_ntp_recv_handler,根据回调函数的设置,执行对应处理。

您可以参考以下内容,编写回调函数的处理逻辑:
  • 物联网平台通过Topic /ext/ntp/${YourProductKey}/${YourDeviceName}/response向设备发回一条包含时间内容的消息。

  • 时间消息的数据结构类型为aiot_ntp_recv_t,可参考示例代码获取时间。
  • 本文示例代码对返回的消息解析处理后,通过packet传递,打印该时间消息。

void demo_ntp_recv_handler(void *handle, const aiot_ntp_recv_t *packet, void *userdata)
{
    switch (packet->type) {
        /* TODO: 含当前时区下, 年月日时分秒的数值, 可在这里把它们解析储存起来 */
        case AIOT_NTPRECV_LOCAL_TIME: {
            printf("local time: %llu, %02d/%02d/%02d-%02d:%02d:%02d:%d\n",
                   (long long unsigned int)packet->data.local_time.timestamp,
                   packet->data.local_time.year,
                   packet->data.local_time.mon, packet->data.local_time.day, packet->data.local_time.hour, packet->data.local_time.min,
                   packet->data.local_time.sec, packet->data.local_time.msec);
        }
        break;

        default: {

        }
    }
}

步骤五:退出程序

调用aiot_ntp_deinit,销毁NTP客户端实例,释放资源。

    res = aiot_ntp_deinit(&ntp_handle);
    if (res < STATE_SUCCESS) {
        demo_mqtt_stop(&mqtt_handle);
        printf("aiot_ntp_deinit failed: -0x%04X\n", -res);
        return -1;
    }

后续步骤

  • 例程文件配置完成后,需进行编译,生成可执行文件./demos/ntp-posix-demo

    更多信息,请参见编译与运行

  • 关于运行结果的详细说明,请参见运行日志