认证与连接

更新时间:2018-10-24 21:04:27

设备身份认证

设备的身份认证分为一机一密以及一型一密两种:

  • 一机一密:
    在设备上烧写设备的ProductKey、DeviceName、DeviceSecret,然后适配相应的HAL并调用SDK提供的连接云端的函数即可,这种方式要求对设备的产线工具进行一定的修改,需要对每个设备烧写不同的DeviceName和DeviceSecret;

  • 一型一密:
    设备上烧写设备的ProductKey、ProductSecret,每个设备需要具备自己的唯一标识并将该标识预先上传到阿里云IoT物联网平台,然后调用SDK提供的函数连接云端。这种方式每个设备上烧写的信息是固定的ProductKey、ProductSecret。

一机一密编程

按照交叉编译中提到的方式去实现下面的三个HAL,用于获取设备三元组。

  • HAL_GetProductKey

  • HAL_GetDeviceName

  • HAL_GetDeviceSecret

在前面章节的基于Linux的MQTT示例程序中让用户直接在代码中填入了设备的三元组数值,然后调用了三个设置三元组的HAL函数将设备三元组进行了记录,然后由SDK连接云端时自动调用了获取三元组的HAL函数。下面是示例代码的片段说明:

  • 定义三元组
#if defined(SUPPORT_ITLS)

    #if defined(ON_DAILY)
        ...
        #define PRODUCT_SECRET          "i11p9cngs22gORO4XLFD4D5AB8EC10B3"
        #define DEVICE_NAME             "000FFFFFAB5F174855956D00"
        #define DEVICE_SECRET           "i11fqFvpJWardIZikyFE3A3F485AAAE5"
    #elif defined(ON_PRE)
        ...
    #else
        ...
    #endif

#else

    #if defined(ON_DAILY)
        ...
    #else
        #define PRODUCT_KEY             "a1IfbZi3oDt"
        #define DEVICE_NAME             "Test1"
        #define DEVICE_SECRET           "kuzVoswkUIdb9uXm4T8ykIJushFym8RL"
    #endif

#endif
  • 保存三元组
int main(int argc, char **argv)
{
    IOT_OpenLog("mqtt");
    IOT_SetLogLevel(IOT_LOG_DEBUG);

    ...

    HAL_SetProductKey(PRODUCT_KEY);
    HAL_SetDeviceName(DEVICE_NAME);
    HAL_SetDeviceSecret(DEVICE_SECRET);
  • 设置认证方式
int main(int argc, char **argv)
{
    IOT_OpenLog("mqtt");
    IOT_SetLogLevel(IOT_LOG_DEBUG);

    ...

    /* Choose Login  Method */
    int dynamic_register = 0;  /*One secret per device*/
    IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);

一型一密编程

一型一密与一机一密的编程方式几乎一样,区别在于:不需要设置DeviceSecret、而是设置ProductSecret,并且调用IOT_Ioctl设置认证IOTX_IOCTL_SET_DYNAMIC_REGISTER时的参数数值为1。下面的代码示例了如何进行一型一密设置:

int main(int argc, char **argv)
{
    IOT_OpenLog("linkkit");
    IOT_SetLogLevel(IOT_LOG_DEBUG);

    ...

    HAL_SetProductKey("a1csED27mp7");
    HAL_SetProductSecret("VuULINCrtTAzCSzp");
    /* HAL_SetDeviceSecret("FcYjzB3GiYiRunsBInIB3fms86UgwuCY"); */

    int dynamic_register = 1;
    IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);

连接云端

服务器地域

阿里云IoT物联网平台在多个国家/地区进行了服务器部署,SDK默认连接的服务器站点是中国的服务器,如果希望连接其他国家/地区的服务器站点,需要对服务器的region进行指定。

使用MQTT连接云端服务器

指定服务器站点

下面的代码示例了将服务器站点设置为中国上海:

int main(int argc, char **argv)
{
    IOT_OpenLog("mqtt");

    ...

    HAL_SetProductKey(PRODUCT_KEY);
    HAL_SetDeviceName(DEVICE_NAME);
    HAL_SetDeviceSecret(DEVICE_SECRET);
#if defined(SUPPORT_ITLS)
    HAL_SetProductSecret(PRODUCT_SECRET);
#endif

    /* Choose Login Server */
    int domain_type = IOTX_CLOUD_DOMAIN_SH;
    IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);

    ...

    return 0;
}

目前可以连接的站点列表:

IOTX_CLOUD_DOMAIN_SH 中国上海
IOTX_CLOUD_DOMAIN_SG 新加坡
IOTX_CLOUD_DOMAIN_JP 日本
IOTX_CLOUD_DOMAIN_US 美国
IOTX_CLOUD_DOMAIN_GER 德国

注:随着SDK的升级,或者阿里云部署的变化,上面的内容会出现相应变化,请以最新SDK为准。

连接云端

下面的代码片段示例了如何直接使用MQTT连接云端服务器:

int mqtt_client(void)
{
    int rc = 0, msg_len, cnt = 0;
    void *pclient;
    iotx_conn_info_pt pconn_info;
    iotx_mqtt_param_t mqtt_params;
    iotx_mqtt_topic_info_t topic_msg;
    char msg_pub[128];
    char *msg_buf = NULL, *msg_readbuf = NULL;

    if (NULL == (msg_buf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
        EXAMPLE_TRACE("not enough memory");
        rc = -1;
        goto do_exit;
    }

    if (NULL == (msg_readbuf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
        EXAMPLE_TRACE("not enough memory");
        rc = -1;
        goto do_exit;
    }

    HAL_GetProductKey(__product_key);
    HAL_GetDeviceName(__device_name);
    HAL_GetDeviceSecret(__device_secret);

    /* Device AUTH */
    if (0 != IOT_SetupConnInfo(__product_key, __device_name, __device_secret, (void **)&pconn_info)) {
        EXAMPLE_TRACE("AUTH request failed!");
        rc = -1;
        goto do_exit;
    }

    /* Initialize MQTT parameter */
    memset(&mqtt_params, 0x0, sizeof(mqtt_params));

    mqtt_params.port = pconn_info->port;
    mqtt_params.host = pconn_info->host_name;
    mqtt_params.client_id = pconn_info->client_id;
    mqtt_params.username = pconn_info->username;
    mqtt_params.password = pconn_info->password;
    mqtt_params.pub_key = pconn_info->pub_key;

    mqtt_params.request_timeout_ms = 2000;
    mqtt_params.clean_session = 0;
    mqtt_params.keepalive_interval_ms = 60000;
    mqtt_params.pread_buf = msg_readbuf;
    mqtt_params.read_buf_size = MQTT_MSGLEN;
    mqtt_params.pwrite_buf = msg_buf;
    mqtt_params.write_buf_size = MQTT_MSGLEN;

    mqtt_params.handle_event.h_fp = event_handle;
    mqtt_params.handle_event.pcontext = NULL;


    /* Construct a MQTT client with specify parameter */
    pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        EXAMPLE_TRACE("MQTT construct failed");
        rc = -1;
        goto do_exit;
    }

支持物模型的产品连接云端服务器

支持物模型的产品可以使用linkkit_start()函数进行回调函数初始化以及连接云端,如下所示:

int linkkit_example()
{
    sample_context_t sample_ctx = {0};
    int execution_time = 2;
    int exit = 0;
    unsigned long long now = 0;
    unsigned long long prev_sec = 0;
    int get_tsl_from_cloud = 0;                        /* the param of whether it is get tsl from cloud */
    linkkit_ops_t linkkit_ops = {
        .on_connect           = on_connect,            /* connect handler */
        .on_disconnect        = on_disconnect,         /* disconnect handler */
        .raw_data_arrived     = raw_data_arrived,      /* receive raw data handler */
        .thing_create         = thing_create,          /* thing created handler */
        .thing_enable         = thing_enable,          /* thing enabled handler */
        .thing_disable        = thing_disable,         /* thing disabled handler */
        .thing_call_service   = thing_call_service,    /* self-defined service handler */
        .thing_prop_changed   = thing_prop_changed,    /* property set handler */
        .linkit_data_arrived  = linkit_data_arrived,   /* transparent transmission data handler */
    };

    EXAMPLE_TRACE("linkkit start");

    /*
     * linkkit start
     * max_buffered_msg = 16, set the handle msg max numbers.
     *     if it is enough memory, this number can be set bigger.
     * if get_tsl_from_cloud = 0, it will use the default tsl [TSL_STRING]; if get_tsl_from_cloud =1, it will get tsl from cloud.
     */
    if (-1 == linkkit_start(16, get_tsl_from_cloud, linkkit_loglevel_debug, &linkkit_ops, linkkit_cloud_domain_shanghai,
                            &sample_ctx)) {
        EXAMPLE_TRACE("linkkit start fail");
        return -1;
    }

上面的代码示例中指定了连接的服务器region是中国上海,可连接的region包括:

  • linkkit_cloud_domain_shanghai:中国上海

  • linkkit_cloud_domain_singapore:新加坡

  • linkkit_cloud_domain_japan:日本

  • linkkit_cloud_domain_america:美国

  • linkkit_cloud_domain_germany:德国

上面的代码中linkkit_start()的参数中没有要求传入设备三元组,该函数将会调用相应的HAL函数去获取设备三元组。

results matching ""

    No results matching ""