EC20模块AT指令MQTT连接阿里云过程
推荐:
使用移远BC28 模组对接阿里云 MQTT_嵌入式_lx121451的博客-CSDN博客
stm32f1控制BC26与阿里云通信(二)_嵌入式_Lexingdon的博客-CSDN博客
//阿里三元组信息
#define ProductKey "a1YjLdisiey"
#define DeviceName "20173166054"
#define DeviceSecret "t8OEnv0zL6Z9C01EYqnztN6OLWXE37nB"
char MQTT_Land(void)
{
char flag=0;
char AT_QISEND[120];
App_Printf("\r\nMQTT 开始配置\r\n");
Comsend_AT("AT+QMTCFG=\"version\",0,3","OK",300); //AT+QMTCFG="version",0,3
Comsend_AT("AT+QMTCFG=\"recv/mode\",0,0,1","OK",300); //AT+QMTCFG="version",0,3
//Configure receiving mode.
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+qmtcfg=\"aliauth\",0,\"%s\",\"%s\",\"%s\"\r\n", ProductKey,DeviceName,DeviceSecret);
Comsend_AT(AT_QISEND,"+QMTCONN",500); //订阅获取模式
//Open a network for MQTT client.
Comsend_AT("AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883","OK",500); //AT+QMTOPEN=0,"iot.elf.one",1883
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+QMTCONN=0,\"ZhiNa%s\"",MAXSensor_Id_Buf);
Comsend_AT(AT_QISEND,"+QMTCONN",500); //订阅获取模式
flag = Comsend_AT("AT+QMTCONN?","+QMTCONN: 0,3",500);// AT+QMTCONN?
if(flag==0)
{
Comsend_AT("AT+QMTDISC=0","OK",300); //关闭服务端
App_Printf("\r\n关闭服务端\r\n");
}
else
{
App_Printf("\r\n订阅主题\r\n");
//Comsend_AT("AT+QMTSUB=?","+QMTSUB",300); //订阅获取模式
sprintf(AT_QISEND,"AT+QMTSUB=0,1,\"/%s/%s/user/set_mode\",2",ProductKey,MAXSensor_Id_Buf);
//Comsend_AT("AT+QMTSUB=0,1,\"/iot/v2/20193168016/set_mode\",0","OK",300); //订阅模式校准
//App_Printf("\r\n QMTSUB=%s\r\n",AT_QISEND);
Comsend_AT(AT_QISEND,"+QMTSUB",300); //订阅获取模式
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+QMTSUB=0,1,\"/%s/%s/user/update_data\",2",ProductKey,MAXSensor_Id_Buf);
//Comsend_AT("AT+QMTSUB=0,1,\"/iot/v2/20193168016/set_mode\",0","OK",300); //订阅远程升级
Comsend_AT(AT_QISEND,"+QMTSUB",300);//订阅远程升级
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+QMTSUB=0,1,\"/%s/%s/user/repeat_info\",2",ProductKey,MAXSensor_Id_Buf);
//Comsend_AT("AT+QMTSUB=0,1,\"/iot/v2/20193168016/set_mode\",0","OK",300); //订阅重复通知
Comsend_AT(AT_QISEND,"+QMTSUB",300);//订阅重复通知
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+QMTSUB=0,1,\"/%s/%s/user/calibrated\",2",ProductKey,MAXSensor_Id_Buf);
//Comsend_AT("AT+QMTSUB=0,1,\"/iot/v2/20193168016/set_mode\",0","OK",300); //订阅校准
Comsend_AT(AT_QISEND,"+QMTSUB",300); //订阅校准
memset(AT_QISEND,0,sizeof(AT_QISEND));
sprintf(AT_QISEND,"AT+QMTSUB=0,1,\"/%s/%s/user/send_workstatus\",2",ProductKey,MAXSensor_Id_Buf);
//Comsend_AT("AT+QMTSUB=0,1,\"/iot/v2/20193168016/set_mode\",0","OK",300); //订阅校准
Comsend_AT(AT_QISEND,"+QMTSUB",300); //订阅校准
memset(AT_QISEND,0,sizeof(AT_QISEND));
//Unsubscribe from topics.
}
return flag;
}
基于MQTT通道设备动态注册
更新时间:2020-04-22 10:25:39
一型一密动态注册
一型一密安全认证方式下,同一产品下所有设备可以烧录相同固件(即烧录ProductKey和ProductSecret)。设备发送激活请求时,物联网平台进行身份确认,认证通过,下发该设备对应的DeviceSecret。
【官网介绍】https://help.aliyun.com/document_detail/74006.html
操作步骤
设备获得连接云端所需的设备证书信息:
#define ProductKey "a1YjLdisiey"
#define DeviceName "20173166054"
#define ProductSecret "pjw4PTzWsCTxD5uX"
- 在该产品下,添加设备。关于添加设备的具体步骤,请参见批量创建设备或单个创建设备。
添加成功的设备状态为未激活。
因设备激活时会校验DeviceName,建议您采用可以直接从设备中读取到的ID,如设备的MAC地址、IMEI或SN号等,作为DeviceName使用。
- 为设备烧录产品证书。
烧录产品证书操作步骤如下:
- 下载设备端SDK。
- 初始化设备端SDK,开通设备端SDK一型一密注册。在设备端SDK中,填入产品证书(ProductKey和ProductSecret)。
开通设备端SDK一型一密注册,请参见Link SDK文档中,各语言SDK的《认证与连接》文档。
- 根据实际需求,完成设备端SDK开发,如,OTA开发、子设备接入、设备物模型开发、设备影子开发等。
- 在产线上,将已开发完成的设备SDK烧录至设备中。
- 设备上电联网后,通过一型一密发起认证请求。
- 物联网平台校验通过后,动态下发该设备对应的DeviceSecret。至此,设备获得连接云端所需的设备证书信息(ProductKey、DeviceName和DeviceSecret),可以与云端建立连接,通过发布消息到Topic和订阅Topic消息,与云端进行数据通信。
https://help.aliyun.com/document_detail/164249.html?spm=a2c4g.11174283.3.2.44d63d6bUD9ght
int32_t _http_dynamic_register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
{
int res = 0, dynamic_register_request_len = 0;
char sign[DYNREG_SIGN_LENGTH] = {0};
char random[DYNREG_RANDOM_KEY_LENGTH + 1] = {0};
const char *dynamic_register_format = "productKey=%s&deviceName=%s&random=%s&sign=%s&signMethod=%s";
char *dynamic_register_request = NULL;
char *dynamic_register_response = NULL;
if (strlen(meta->product_key) > IOTX_PRODUCT_KEY_LEN) {
return STATE_USER_INPUT_PK;
}
if (strlen(meta->product_secret) > IOTX_PRODUCT_SECRET_LEN) {
return STATE_USER_INPUT_PS;
}
if (strlen(meta->device_name) > IOTX_DEVICE_NAME_LEN) {
return STATE_USER_INPUT_DN;
}
/* Calcute Signature */
res = _calc_dynreg_sign(meta->product_key, meta->product_secret, meta->device_name, random, sign);
if (res < STATE_SUCCESS) {
return res;
}
/* Assemble Http Dynamic Register Request Payload */
dynamic_register_request_len = strlen(dynamic_register_format) + strlen(meta->product_key) + strlen(meta->device_name) +
strlen(random) + strlen(sign) + strlen(DYNREG_SIGN_METHOD_HMACSHA256) + 1;
dynamic_register_request = dynreg_malloc(dynamic_register_request_len);
if (dynamic_register_request == NULL) {
return STATE_SYS_DEPEND_MALLOC;
}
memset(dynamic_register_request, 0, dynamic_register_request_len);
HAL_Snprintf(dynamic_register_request, dynamic_register_request_len, dynamic_register_format,
meta->product_key, meta->device_name, random, sign, DYNREG_SIGN_METHOD_HMACSHA256);
dynamic_register_response = dynreg_malloc(HTTP_RESPONSE_PAYLOAD_LEN);
if (dynamic_register_response == NULL) {
dynreg_free(dynamic_register_request);
return STATE_SYS_DEPEND_MALLOC;
}
memset(dynamic_register_response, 0, HTTP_RESPONSE_PAYLOAD_LEN);
/* Send Http Request For Getting Device Secret */
res = _fetch_dynreg_http_resp(dynamic_register_request, dynamic_register_response, region, meta->device_secret);
#ifdef INFRA_LOG_NETWORK_PAYLOAD
dynreg_dbg("Downstream Payload:");
iotx_facility_json_print(dynamic_register_response, LOG_DEBUG_LEVEL, '<');
#endif
dynreg_free(dynamic_register_request);
dynreg_free(dynamic_register_response);
if (res < STATE_SUCCESS) {
return res;
}
return STATE_SUCCESS;
}
代码分析:
/* Calcute Signature */
res = _calc_dynreg_sign(meta->product_key, meta->product_secret, meta->device_name, random, sign);合成信息deviceName、productKey、random生成sign_source:deviceName20173166054productKeya1YjLdisieyrandombf3bb0f015df4c5688e78b3045d206e5
利用utils_hmac_sha256算法生成:Calcute Signature
sign=0C18DC69D34B7A4DE476C2F0A9E047C6792A1A1311BE772D772A3752EA070244
合成信息deviceName、productKey、random、sign、signMethod生成dynamic_register_request:
deviceName=20173166054&productKey=a1YjLdisiey&random=8Ygb7ULYh53B6OA&sign=0C18DC69D34B7A4DE476C2F0A9E047C6792A1A1311BE772D772A3752EA070244&signMethod=HmacSHA256
最后使用HTTP发送请求:
uint8_t HTTP_Get_productKey(void)
{
MAXGPRS_Struct struct_usart2;
char HTTP_pic_url_buf = 0;
char HTTP_url_buf[80] = {0};
char AT_HTTP_url_buf[80] = {0};
char HTTP_POST_buf[230] = {0};
char AT_HTTP_POST_buf[230] = {0};
char sign[HTTP_SIGN_SOURCE_LEN] = {0};
char random[18] = {0};
int res = 0;
/* Calculate Sign */
res = _calc_dynreg_sign(ProductKey, ProductSecret, DeviceName, random, sign);
if (res < 1) {
return res;
}
App_Printf("\r\nHTTP 开始配置\r\n");
Comsend_AT("AT+QHTTPCFG=\"contextid\",1","OK",300);
Comsend_AT("AT+QHTTPCFG=\"requestheader\",0","OK",300);
Comsend_AT("AT+QHTTPCFG=\"contenttype\",0","OK",300);
Comsend_AT("AT+QICSGP=1,1,\"CMNET\",\"\" ,\"\" ,1","OK",300);
memset(HTTP_url_buf,0,sizeof(HTTP_url_buf));
sprintf((char*)HTTP_url_buf,"https://iot-auth.cn-shanghai.aliyuncs.com");
memset(AT_HTTP_url_buf,0,sizeof(AT_HTTP_url_buf));
sprintf((char*)AT_HTTP_url_buf,"AT+QHTTPURL=%d,80",strlen(HTTP_url_buf));//Set the URL which will be accessed.
if(Comsend_AT(AT_HTTP_url_buf,"CONNECT",300))//建立HTTP链接成功
{
Comsend_AT(HTTP_url_buf,"OK",200); //Input URL
//deviceName=20173166054&productKey=a1YjLdisiey&random=8Ygb7ULYh53B6OA&sign=0C18DC69D34B7A4DE476C2F0A9E047C6792A1A1311BE772D772A3752EA070244&signMethod=HmacSHA256
sprintf((char*)HTTP_POST_buf,"deviceName=%s&productKey=%s&random=%s&sign=%s&signMethod=HmacSHA256",DeviceName,ProductKey,random,sign);
App_Printf("\r\n HTTP_POST_buf:%s \r\n",HTTP_POST_buf);
memset(AT_HTTP_POST_buf,0,sizeof(AT_HTTP_POST_buf));
sprintf((char*)AT_HTTP_POST_buf,"AT+QHTTPPOST=%d,80,80",strlen(HTTP_POST_buf));
if(Comsend_AT(AT_HTTP_POST_buf,"CONNECT",300))//Send HTTP POST request.
{
//memset(struct_usart2.USART_BUFF,0,sizeof(struct_usart2.USART_BUFF));
Comsend_AT(HTTP_POST_buf,"OK",200); //Input post body whose length is 20 bytes.
for(int HTTPPOST_delay = 1; HTTPPOST_delay < 50; HTTPPOST_delay++)
{
App_Printf(" HTTPPOST_delay:%d\r\n", HTTPPOST_delay * 3);
//If the HTTP response header contains "CONTENT-LENGTH" information, then the <content_length> information will be reported.
if(strstr((char*)struct_usart2.USART_BUFF, "+QHTTPPOST: 0,200"))
{
break;
}
if(strstr((char*)struct_usart2.USART_BUFF, "+CME ERROR:"))
{
break;
}
vTaskDelay(300);
}
App_Printf("\r\n QHTTPPOST:%s \r\n",struct_usart2.USART_BUFF);
memset(struct_usart2.USART_BUFF,0,sizeof(struct_usart2.USART_BUFF));
Comsend_AT("AT+QHTTPREAD=80","CONNECT",200);//Read HTTP response body and output it via UART.
for(int HTTPPREAD_delay = 1; HTTPPREAD_delay < 50; HTTPPREAD_delay++)
{
App_Printf(" HTTPPREAD_delay:%d\r\n", HTTPPREAD_delay * 3);
if(strstr((char*)struct_usart2.USART_BUFF, "+QHTTPREAD: 0"))//HTTP response body is outputted successfully.
{
break;
}
if(strstr((char*)struct_usart2.USART_BUFF, "+CME ERROR:"))
{
break;
}
vTaskDelay(300);
}
if(strstr((char*)struct_usart2.USART_BUFF, "deviceSecret"))
{
App_Printf("\r\n 获取设备钥匙成功 \r\n");
}
else
{
App_Printf("\r\n 获取设备钥匙失败 \r\n");
}
App_Printf("\r\n QHTTPPOST:%s \r\n",struct_usart2.USART_BUFF);
memset(struct_usart2.USART_BUFF,0,sizeof(struct_usart2.USART_BUFF));
}
else
{
App_Printf("HTTP POST 请求失败 \r\n");
}
}
else
{
App_Printf("HTTP 连接失败 \r\n");
}
//Comsend_AT("AT+QHTTPSTOP","OK",300);
}
HTTP发送请求:
URL模板: https://iot-auth.cn-shanghai.aliyuncs.com/auth/register/device
HTTP方法: POST
请求数据格式:
POST /auth/register/device HTTP/1.1
Host: iot-auth.cn-shanghai.aliyuncs.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 123
deviceName=20173166054&productKey=a1YjLdisiey&random=8Ygb7ULYh53B6OA&sign=0C18DC69D34B7A4DE476C2F0A9E047C6792A1A1311BE772D772A3752EA070244&signMethod=HmacSHA256
响应数据格式:
{
"code": 200,
"data": {
"productKey": "a1YjLdisiey",
"deviceName": "20173166054",
"deviceSecret": "t8OEnv0zL6Z9C01EYqnztN6OLWXE37nB"
},
"message": "success"
}
使用HTTP工具测试: