本文介绍设备签名的使用方法。

背景信息

阿里云物联网平台支持使用MQTT协议作为物联网设备和平台之间的通信协议。MQTT Client在连接阿里云物联网平台时,MQTT的username、password、clientID需要遵守阿里云物联网平台的规定,是物联网设备连接物联网平台时证明自己合法身份的认证信息,统称为设备签名信息。此过程中,功能点dev_sign提供了该签名字段的计算封装,这个功能称为设备签名。

如上图所示:
  • 左边的是该模块的输入参数,设备认证信息(ProductKey、DeviceName、DeviceSecret)和region分别表达设备身份和想要连接的站点所在区域。
    说明 站点所在区域示例:华东2(上海)、亚太东北1(东京)、美国西部1(硅谷)、亚太东南1(新加坡)等,完整内容,请参见地域和可用区
  • 右边的是该模块的返回参数。hostname、port分别是连接服务器的域名和端口,username、password、clientID为设备签名信息。
  • 图示正中间IOT_Sign_MQTT是该模块提供的唯一一个用户接口API。

使用场景

如果需要集成SDK的设备已支持MQTT Client,并且打算使用MQTT Topic直接与物联网平台进行通信,也不使用SDK的其它任何功能,可以调用设备签名API获取MQTT协议连接物联网平台时需要设置的MQTT参数,然后使用该MQTT Client连接物联网平台。

注意 需要确保MQTT Client的KeepAlive机制正常运行。

案例程序讲解

本文以Link SDK 3.2.0版本为例,不同版本Link SDK下载,请参见SDK获取

设备签名的案例程序可参考src/dev_sign/examples/dev_sign_example.c文件。以下对其进行逐段讲解:

  1. 要使用dev_sign功能,需包含它的API头文件dev_sign_api.h
    #include "dev_sign_api.h"
  2. 从物联网平台控制台申请到一台新的物联网设备,记录其设备认证信息:
    #define EXAMPLE_PRODUCT_KEY     "a1X2bEn****"
    #define EXAMPLE_PRODUCT_SECRET  "7jluWm1zql7b****"
    #define EXAMPLE_DEVICE_NAME     "example1"
    #define EXAMPLE_DEVICE_SECRET   "ga7XA6KdlEeiPXQPpRbAjOZXwG******" 
  3. 声明需要用户提供的底层接口:
    说明 功能点dev_sign是零依赖的,不需要用户做任何HAL的适配就可以使用。此处声明了HAL_Printf仅是因为例程可能需要输出字符。
    /* Implenment this HAL or using "printf" of your own system if you want to print something in example*/
    void HAL_Printf(const char *fmt, ...);
  4. 准备出入参结构体,声明需要用户提供的底层接口:
    int main(int argc, char *argv[])
    {
        iotx_mqtt_region_types_t region = IOTX_CLOUD_REGION_SHANGHAI;
        iotx_dev_meta_info_t meta;
        iotx_sign_mqtt_t sign_mqtt;
    
        memset(&meta,0,sizeof(iotx_dev_meta_info_t));
        memcpy(meta.product_key,EXAMPLE_PRODUCT_KEY,strlen(EXAMPLE_PRODUCT_KEY));
        memcpy(meta.product_secret,EXAMPLE_PRODUCT_SECRET,strlen(EXAMPLE_PRODUCT_SECRET));
        memcpy(meta.device_name,EXAMPLE_DEVICE_NAME,strlen(EXAMPLE_DEVICE_NAME));
        memcpy(meta.device_secret,EXAMPLE_DEVICE_SECRET,strlen(EXAMPLE_DEVICE_SECRET));
  5. 准备一个类型为iotx_dev_meta_info_t的结构体变量,把需要计算签名的设备标识信息填入其中。
    然后调用dev_sign功能点唯一的一个用户接口IOT_Sign_MQTT(),计算签名:
    if (IOT_Sign_MQTT(region,&meta,&sign_mqtt) < 0) {
            return -1; 
        }
  6. 结果在输出参数 sign_mqtt 中,它是一个 iotx_sign_mqtt_t 类型的结构体变量。
    选择打印签名结果或者连接MQTT服务器:
    #if 0   /* Uncomment this if you want to show more information */
        HAL_Printf("sign_mqtt.hostname: %s\n",sign_mqtt.hostname);
        HAL_Printf("sign_mqtt.port    : %d\n",sign_mqtt.port);
        HAL_Printf("sign_mqtt.username: %s\n",sign_mqtt.username);
        HAL_Printf("sign_mqtt.password: %s\n",sign_mqtt.password);
        HAL_Printf("sign_mqtt.clientid: %s\n",sign_mqtt.clientid);
    #endif         
说明 为了减轻用户对接实现HAL_Printf的负担,IOT_Sign_MQTT()在执行的过程中不会做任何打印动作,如果想观察结果可打开上述注释。

过程中输出参数的各个成员含义如下:

成员名 含义
sign_mqtt.hostname 可以连接的MQTT服务器域名地址,根据入参region自动计算。
sign_mqtt.port 可以连接的MQTT服务器端口号,根据标准MQTT协议一般是1883或443。
sign_mqtt.username 连接MQTT服务器时将要使用的用户名。
sign_mqtt.password 连接MQTT服务器时将要使用的密码,和用户名一一对应。
sign_mqtt.clientid 连接MQTT服务器时标识设备的自定义ID,服务器对此不做校验,鉴权通过username和password进行。

功能API接口

IOT_Sign_MQTT
  • 原型:
    int32_t IOT_Sign_MQTT(iotx_mqtt_region_types_t region, iotx_dev_meta_info_t *meta, iotx_sign_mqtt_t *signout);
  • 接口说明:调用此接口计算给定的设备签名信息(即设备的身份认证信息),结果将在输出参数signout中返回。
  • 参数说明:
    参数 数据类型 方向 说明
    region iotx_mqtt_region_types_t 输入 表示设备将要工作的区域,例如华东2(上海)、亚太东北1(东京)、美国西部1(硅谷)、亚太东南1(新加坡)等。完整内容,请参见地域和可用区
    meta iotx_dev_meta_info_t * 输入 存放设备的标识字符串,包括ProductKey、DeviceName等。
    signout iotx_sign_mqtt_t * 输出 存放计算好的签名信息,包括MQTT服务器地址和端口,连接时的用户名和密码等。
  • 返回结果:
    返回结果 说明
    =0 成功
    <0 失败

需要对接的HAL接口

功能点dev_sign是零依赖的,无需任何开发动作就可以使用,不需要对接HAL接口。