EC20模块AT指令MQTT连接阿里云IoT,HTTP接口来实现一型一密动态注册的流程。

5 篇文章 1 订阅

EC20模块AT指令MQTT连接阿里云过程

推荐:

使用移远BC28 模组对接阿里云 MQTT_嵌入式_lx121451的博客-CSDN博客

https://blog.csdn.net/lx121451/article/details/82389559?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-8

stm32f1控制BC26与阿里云通信(二)_嵌入式_Lexingdon的博客-CSDN博客

https://blog.csdn.net/Lexingdon/article/details/102783178?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

//阿里三元组信息
#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

操作步骤

  1. 物联网平台控制台,创建产品。关于创建产品的具体步骤,请参见创建产品
  2. 在已创建产品的产品详情页面,开启动态注册开关。系统将进行短信验证,以确认是您本人操作。

设备获得连接云端所需的设备证书信息:
#define ProductKey "a1YjLdisiey"
#define DeviceName "20173166054"
#define ProductSecret "pjw4PTzWsCTxD5uX"

  1. 在该产品下,添加设备。关于添加设备的具体步骤,请参见批量创建设备单个创建设备

    添加成功的设备状态为未激活。

    因设备激活时会校验DeviceName,建议您采用可以直接从设备中读取到的ID,如设备的MAC地址、IMEI或SN号等,作为DeviceName使用。

  2. 为设备烧录产品证书。

    烧录产品证书操作步骤如下:

    1. 下载设备端SDK。
    2. 初始化设备端SDK,开通设备端SDK一型一密注册。在设备端SDK中,填入产品证书(ProductKey和ProductSecret)。

      开通设备端SDK一型一密注册,请参见Link SDK文档中,各语言SDK的《认证与连接》文档。

    3. 根据实际需求,完成设备端SDK开发,如,OTA开发、子设备接入、设备物模型开发、设备影子开发等。
    4. 在产线上,将已开发完成的设备SDK烧录至设备中。
  3. 设备上电联网后,通过一型一密发起认证请求。
  4. 物联网平台校验通过后,动态下发该设备对应的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工具测试:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值