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

2023-05-16

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工具测试:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • ZOJ - 2313 Chinese Girls' Amusement

    You must have heard that the Chinese culture is quite different from that of Europe or Russia So some Chinese habits see
  • ROS通信机制与TCP

    http blog exbot net archives 1605 http wiki ros org ROS TCPROS
  • 花两天时间写的stm32f103串口BootLoader(有keil工程)

    因为在论坛和官网都没搜到完全合适的BootLoader xff0c 所以自己移植完成了一个BootLoader工程 另外附APP文件工程 xff0c 可做实验 用良心保证 xff0c 看完后可以做一个成功的实验 上位机选用SecureCrt
  • 信号量与消息队列的区别

    出现信号量与消息队列的原因 xff1a 全局变量可以承载通信的内容 xff0c 但接受方任务需要不断检测此全局变量的值 所以产生了信号量与消息队列 信号量 xff1a 可以通知接收方某个事件的发生 xff0c 但无法传递具体事件内容 xff
  • <Unity>局部坐标(localPosition) && 世界坐标(Position)

    局部坐标 amp amp 世界坐标 的区别 1 官方文档介绍1 1 Transform Position1 2 Transform localPosition 2 问题2 1 Position真的不会受到父物体的影响吗 1 官方文档介绍 1
  • ADRC与Matlab/Similink/C++实现

    写在前面 ADRC控制算法主要分为三部分 xff0c 跟踪微分器TD 观测器ESO和状态误差反馈控制器 xff0c 其中控制器分为线性控制器PD和非线性状态误差反馈控制器NLSEF xff0c 观测器分为线性观测器LESO和非线性观测器NL
  • 状态空间方程MATLAB语句

    1 连续系统 xff08 1 xff09 使用系数矩阵获得传递函数 num den 61 ss2tf A B C D xff08 2 xff09 将传递函数写成因式分解 xff08 零极点 xff09 形式 z p k 61 ss2zp A
  • 力扣刷题

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 H指数 题目介绍一 实现思路方法一 xff1a 排序分析复杂度分析 方法二 xff1a 计数分析算法 复杂度分析 二 使用算法1 pyth
  • [markdown语法]公式篇--整理总结了常用的公式语法全

    一 公式部分 前言 行内公式 xff1a 公式 行间公式 xff1a 公式 1 1 常用符号标注 1 1 1 上下标 数学符号实际效果语法向量 a vec a
  • ubuntu mate18.04+树莓派4B+ROS安装详细教程

    前记 最近项目需要 xff0c 需要给树莓派4B 安装Ubuntu mate xff0c 本来是一件很简单的事情 xff0c 因为Ubuntu mate官网已经开始支持树莓派4B了 xff0c 但是实际操作后 xff0c 才发现烧录官方的桌
  • QGC参数表

    QGC parameters 1 Battery Callbration ParametersDetail含义BAT A PER VBattery current per volt A V 每伏电池电流BAT CAPACITYBattery
  • GAZEBO构建室外环境地图之创建高度图

    GAZEBO构建室外环境地图之创建高度图 前言下载真实地形数据处理下载好的高度图 前言 最近在搭建gazebo的室外仿真环境用于室外机器人的室外建图算法研究 xff0c 发现网上说这方面的文章非常少 xff0c 走dem来创建地形的路 xf
  • [无人机学习]无人机学习概论

    一 无人机简介 1 1 无人机与航空模型分类 机型优点缺点固定翼飞机续航时间长 xff0c 速度快需要跑道 xff0c 不能垂直起降单旋翼飞机可以垂直起降 xff0c 空中悬停续航时间段 xff0c 机械结构复杂 xff0c 操控难度大多旋
  • YOLO使用

    第一步 下载预训练模型 span class token builtin class name cd span darknet span class token function wget span https pjreddie com m
  • CMakeLists.txt文件编写

    重点 1 cmake版本要求 cmake minimum required VERSION 3 15 2 工程名 project algorithm 3 支持C 43 43 11标准 set CMAKE CXX STANDARD 11 4
  • [Eigen]

    Eigen 库学习笔记 参考原文为 xff1a https www cnblogs com rainbow70626 p 8819119 html 为了方便查看 xff0c 以防找不到 xff0c 所以写了这篇博客 目录 Eigen 矩阵定
  • 【1】嵌入式学习

    嵌入式学习 GitHub xff1a https github com Screw888 LearningNote git
  • ubuntu swap分区扩容

    span class token comment 将现有的swap内存移动到主内存 span span class token function sudo span swapoff a span class token comment 创建
  • 强推!!!解决UnicodeEncodeError: ‘gbk‘ codec can‘t encode character.....: illegal multibyte

    解决pycharm编码报错问题 困扰了好几天的编码问题终于得到了解决 xff0c 其实问题很简单 xff0c 当你用pycharm打开一个txt json csv文件时 xff0c 像下面这种 xff1a 明明已经指定了编码方式为utf 8
  • EC20模块AT指令MQTT连接阿里云IoT,HTTP接口来实现一型一密动态注册的流程。

    EC20模块AT指令MQTT连接阿里云过程 推荐 xff1a 使用移远BC28 模组对接阿里云 MQTT 嵌入式 lx121451的博客 CSDN博客 https blog csdn net lx121451 article details