认证与连接
更新时间: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函数去获取设备三元组。