当前位置:网站首页>STM32 Alibaba cloud mqtt esp8266 at command
STM32 Alibaba cloud mqtt esp8266 at command
2022-07-26 10:34:00 【Neo Wordsworth】
stm32 adopt esp8266 AT Command to connect Alibaba cloud Internet of things . Do not reference libraries , Write the protocol data yourself to understand MQTT
For the convenience of debugging , Upper computer AT Orders can be made through stm32 Send to esp8266,
1、 Look at the effect
Send in sequence AT Command to connect to Alibaba cloud
Finally, set every 60 Seconds to send heartbeat
Alibaba cloud can see online devices
2、 Connection address
The format of the connection address is
${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com
{YourProductKey} It's an alicloud product key
{YourRegionId} Is the region code , Refer to Alibaba cloud 【 Area and availability area 】
3、MQTT Of CONNECT part
That string 16 Hexadecimal data ( This string of data passes through the following c Language generation , The generated is 16 Base string ):
#define MYCLIENT_ID "xxxxx"
#define MYCLIENT_ID_Full "xxxxx|securemode=3,signmethod=hmacsha1|"
#define DEVICE_NAME "yyyyy"
#define PRODUCT_KEY "jjjjj"
#define USER_NAME "yyyyy&jjjjj"
#define DEVICE_SECRET "zzzzzzzzzzzz"
#define USER_PASSWORD "6A3026C603CA534335512514F596A5F87DE2B542"
xxxx: It is the client MCU's own id, Random filling ( No timestamp is used timestamp)
yyyyyy: Alibaba cloud device name
zzzzzzzzzzzz: Alibaba cloud device key
jjjjjjj: It's an alicloud product key
#define Append(x,y) memcpy(x + strlen(x),y,strlen(y))
#define AppendU16(x,y) AppendNum(x,y,4)
#define AppendU8(x,y) AppendNum(x,y,2)
const char *gEncode = "0123456789ABCDEF";
void AppendNum(char* datas,u16 lenth,u8 size) {
char len[4];
u8 i;
u8 move;
move=(size-1)<<2;
for(i=0;i<size;i++,move-=4){
len[i]=gEncode[(lenth >> move) & 0xf];
}
len[i]='\0';
Append(datas,len);
}
void AppendStr(char* datas,const char* str) {
char temp[512];
u16 i=0;
while(*str){
temp[i++]=gEncode[((*str)>>4) & 0xf];
temp[i++]=gEncode[(*str) & 0xf];
str++;
}
temp[i]='\0';
if(datas[0])
Append(datas,temp);
else
memcpy(datas,temp,strlen(temp));
}
void test3() {
char datas[1024];
u16 lenth;
lenth=strlen(MYCLIENT_ID_Full)+strlen(USER_NAME)+strlen(USER_PASSWORD)+2*3+10;
memset(datas,0,1024);
// type (×)
Append(datas,"10");
// The length of the remaining data ( My data is no more than 128, So just 1 individual byte)
AppendU8(datas,lenth);
// Protocol type 、 length 、 Version, etc. (×)
Append(datas,"00044d51545404c2003c");
// Client MCU ID length
AppendU16(datas,strlen(MYCLIENT_ID_Full));
// Client MCU ID
AppendStr(datas,MYCLIENT_ID_Full);
// User name length
AppendU16(datas,strlen(USER_NAME));
// user name
AppendStr(datas,USER_NAME);
// Password length
AppendU16(datas,strlen(USER_PASSWORD));
// password
AppendStr(datas,USER_PASSWORD);
printf("%s\r\n",datas);
}
4、USER_PASSWORD User password generation
4.1、 Using Alibaba cloud's “Password Generate gadgets ”( Open the page , Search the tool name )
4.2、 use C Language computing
void test4() {
char datas[1024];
char sign_hex[100];
char res[100];
memset(datas, 0, 1024);
Append(datas,"clientId");
Append(datas,MYCLIENT_ID);
Append(datas,"deviceName");
Append(datas,DEVICE_NAME);
Append(datas,"productKey");
Append(datas,PRODUCT_KEY);
//Append(datas,"timestamp");
//Append(datas,TIMESTAMP);
memset(sign_hex, 0, 100);
hmac_sha1((u8*)DEVICE_SECRET,strlen(DEVICE_SECRET), (u8*)datas, strlen(datas),
sign_hex);
memset(res, 0, 100);
AppendStr(res,sign_hex);
printf("%s\r\n",res);
}
Reference to sha1 file
#include "hmacsha1.h"
#define MAX_MESSAGE_LENGTH 1000
/*****************************/
/**** Function Prototypes ****/
/*****************************/
unsigned long int ft(
int t,
unsigned long int x,
unsigned long int y,
unsigned long int z
);
int get_testcase( int test_case,
unsigned char *plaintext,
unsigned char *key,
int *key_length_ptr);
void sha1 (
unsigned char *message,
int message_length,
unsigned char *digest
);
/**************************/
/* Debug out */
/**************************/
#ifdef HMAC_DEBUG
debug_out(
unsigned char *label,
unsigned char *data,
int data_length
)
{
int i,j;
int num_blocks;
int block_remainder;
num_blocks = data_length / 16;
block_remainder = data_length % 16;
printf("%s\n",label);
for (i=0; i< num_blocks;i++)
{
printf("\t");
for (j=0; j< 16;j++)
{
printf("%02x ", data[j + (i*16)]);
}
printf("\n");
}
if (block_remainder > 0)
{
printf("\t");
for (j=0; j<block_remainder; j++)
{
printf("%02x ", data[j+(num_blocks*16)]);
}
printf("\n");
}
}
#endif
/****************************************/
/* sha1() */
/* Performs the NIST SHA-1 algorithm */
/****************************************/
unsigned long int ft(
int t,
unsigned long int x,
unsigned long int y,
unsigned long int z
)
{
unsigned long int a,b,c;
if (t < 20)
{
a = x & y;
b = (~x) & z;
c = a ^ b;
}
else if (t < 40)
{
c = x ^ y ^ z;
}
else if (t < 60)
{
a = x & y;
b = a ^ (x & z);
c = b ^ (y & z);
}
else if (t < 80)
{
c = (x ^ y) ^ z;
}
return c;
}
unsigned long int k(int t)
{
unsigned long int c;
if (t < 20)
{
c = 0x5a827999;
}
else if (t < 40)
{
c = 0x6ed9eba1;
}
else if (t < 60)
{
c = 0x8f1bbcdc;
}
else if (t < 80)
{
c = 0xca62c1d6;
}
return c;
}
unsigned long int rotr(int bits, unsigned long int a)
{
unsigned long int c,d,e,f,g;
c = (0x0001 << bits)-1;
d = ~c;
e = (a & d) >> bits;
f = (a & c) << (32 - bits);
g = e | f;
return (g & 0xffffffff );
}
unsigned long int rotl(int bits, unsigned long int a)
{
unsigned long int c,d,e,f,g;
c = (0x0001 << (32-bits))-1;
d = ~c;
e = (a & c) << bits;
f = (a & d) >> (32 - bits);
g = e | f;
return (g & 0xffffffff );
}
void sha1 (
unsigned char *message,
int message_length,
unsigned char *digest
)
{
int i;
int num_blocks;
int block_remainder;
int padded_length;
unsigned long int l;
unsigned long int t;
unsigned long int h[5];
unsigned long int a,b,c,d,e;
unsigned long int w[80];
unsigned long int temp;
#ifdef SHA1_DEBUG
int x,y;
#endif
/* Calculate the number of 512 bit blocks */
padded_length = message_length + 8; /* Add length for l */
padded_length = padded_length + 1; /* Add the 0x01 bit postfix */
l = message_length * 8;
num_blocks = padded_length / 64;
block_remainder = padded_length % 64;
if (block_remainder > 0)
{
num_blocks++;
}
padded_length = padded_length + (64 - block_remainder);
/* clear the padding field */
for (i = message_length; i < (num_blocks * 64); i++)
{
message[i] = 0x00;
}
/* insert b1 padding bit */
message[message_length] = 0x80;
/* Insert l */
message[(num_blocks*64)-1] = (unsigned char)( l & 0xff);
message[(num_blocks*64)-2] = (unsigned char)((l >> 8) & 0xff);
message[(num_blocks*64)-3] = (unsigned char)((l >> 16) & 0xff);
message[(num_blocks*64)-4] = (unsigned char)((l >> 24) & 0xff);
/* Set initial hash state */
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
h[3] = 0x10325476;
h[4] = 0xc3d2e1f0;
#ifdef SHA1_DEBUG
printf("INITIAL message_length = %d\n", message_length);
printf("INITIAL padded_length = %d\n", padded_length);
printf("INITIAL num_blocks = %d\n", num_blocks);
for (x=0;x<num_blocks; x++)
{
printf("\t\t");
for (y=0; y<16;y++)
{
printf("%02x ",message[y + (x*64)]);
}
printf("\n");
printf("\t\t");
for (y=0; y<16;y++)
{
printf("%02x ",message[16 + y + (x*64)]);
}
printf("\n");
printf("\t\t");
for (y=0; y<16;y++)
{
printf("%02x ",message[32 + y + (x*64)]);
}
printf("\n");
printf("\t\t");
for (y=0; y<16;y++)
{
printf("%02x ",message[48 + y + (x*64)]);
}
printf("\n");
}
#endif
for (i = 0; i < num_blocks; i++)
{
/* Prepare the message schedule */
for (t=0; t < 80; t++)
{
if (t < 16)
{
w[t] = (256*256*256) * message[(i*64)+(t*4)];
w[t] += (256*256 ) * message[(i*64)+(t*4) + 1];
w[t] += (256 ) * message[(i*64)+(t*4) + 2];
w[t] += message[(i*64)+(t*4) + 3];
}
else if (t < 80)
{
w[t] = rotl(1,(w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]));
}
}
#ifdef SHA1_DEBUG
printf("\tW(0) = %08lX \t W(9) = %08lX \n", w[0], w[8]);
printf("\tW(1) = %08lX \t W(10) = %08lX \n", w[1], w[9]);
printf("\tW(2) = %08lX \t W(11) = %08lX \n", w[2], w[10]);
printf("\tW(3) = %08lX \t W(12) = %08lX \n", w[3], w[11]);
printf("\tW(4) = %08lX \t W(13) = %08lX \n", w[4], w[12]);
printf("\tW(5) = %08lX \t W(14) = %08lX \n", w[5], w[13]);
printf("\tW(6) = %08lX \t W(15) = %08lX \n", w[6], w[14]);
printf("\tW(7) = %08lX \t W(16) = %08lX \n\n", w[7], w[15]);
#endif
/* Initialize the five working variables */
a = h[0];
b = h[1];
c = h[2];
d = h[3];
e = h[4];
/* iterate a-e 80 times */
for (t = 0; t < 80; t++)
{
temp = (rotl(5,a) + ft(t,b,c,d)) & 0xffffffff;
temp = (temp + e) & 0xffffffff;
temp = (temp + k(t)) & 0xffffffff;
temp = (temp + w[t]) & 0xffffffff;
e = d;
d = c;
c = rotl(30,b);
b = a;
a = temp;
#ifdef SHA1_DEBUG
printf("t = %2ld\t %08lx, %08lx, %08lx, %08lx, %08lx\n", t,a,b,c,d,e);
#endif
}
/* compute the ith intermediate hash value */
#ifdef SHA1_DEBUG
printf(" + \t %08lx, %08lx, %08lx, %08lx, %08lx\n", h[0],h[1],h[2],h[3],h[4]);
#endif
h[0] = (a + h[0]) & 0xffffffff;
h[1] = (b + h[1]) & 0xffffffff;
h[2] = (c + h[2]) & 0xffffffff;
h[3] = (d + h[3]) & 0xffffffff;
h[4] = (e + h[4]) & 0xffffffff;
#ifdef SHA1_DEBUG
printf(" = \t %08lx, %08lx, %08lx, %08lx, %08lx\n", h[0],h[1],h[2],h[3],h[4]);
#endif
}
digest[3] = (unsigned char) ( h[0] & 0xff);
digest[2] = (unsigned char) ((h[0] >> 8) & 0xff);
digest[1] = (unsigned char) ((h[0] >> 16) & 0xff);
digest[0] = (unsigned char) ((h[0] >> 24) & 0xff);
digest[7] = (unsigned char) ( h[1] & 0xff);
digest[6] = (unsigned char) ((h[1] >> 8) & 0xff);
digest[5] = (unsigned char) ((h[1] >> 16) & 0xff);
digest[4] = (unsigned char) ((h[1] >> 24) & 0xff);
digest[11] = (unsigned char) ( h[2] & 0xff);
digest[10] = (unsigned char) ((h[2] >> 8) & 0xff);
digest[9] = (unsigned char) ((h[2] >> 16) & 0xff);
digest[8] = (unsigned char) ((h[2] >> 24) & 0xff);
digest[15] = (unsigned char) ( h[3] & 0xff);
digest[14] = (unsigned char) ((h[3] >> 8) & 0xff);
digest[13] = (unsigned char) ((h[3] >> 16) & 0xff);
digest[12] = (unsigned char) ((h[3] >> 24) & 0xff);
digest[19] = (unsigned char) ( h[4] & 0xff);
digest[18] = (unsigned char) ((h[4] >> 8) & 0xff);
digest[17] = (unsigned char) ((h[4] >> 16) & 0xff);
digest[16] = (unsigned char) ((h[4] >> 24) & 0xff);
}
/******************************************************/
/* hmac-sha1() */
/* Performs the hmac-sha1 keyed secure hash algorithm */
/******************************************************/
void hmac_sha1(unsigned char *key,
int key_length,
unsigned char *data,
int data_length,
unsigned char *digest)
{
int b = 64; /* blocksize */
unsigned char ipad = 0x36;
unsigned char opad = 0x5c;
unsigned char k0[64];
unsigned char k0xorIpad[64];
unsigned char step7data[64];
unsigned char step5data[MAX_MESSAGE_LENGTH+128];
unsigned char step8data[64+20];
int i;
for (i=0; i<64; i++)
{
k0[i] = 0x00;
}
if (key_length != b) /* Step 1 */
{
/* Step 2 */
if (key_length > b)
{
sha1(key, key_length, digest);
for (i=0;i<20;i++)
{
k0[i]=digest[i];
}
}
else if (key_length < b) /* Step 3 */
{
for (i=0; i<key_length; i++)
{
k0[i] = key[i];
}
}
}
else
{
for (i=0;i<b;i++)
{
k0[i] = key[i];
}
}
#ifdef HMAC_DEBUG
debug_out("k0",k0,64);
#endif
/* Step 4 */
for (i=0; i<64; i++)
{
k0xorIpad[i] = k0[i] ^ ipad;
}
#ifdef HMAC_DEBUG
debug_out("k0 xor ipad",k0xorIpad,64);
#endif
/* Step 5 */
for (i=0; i<64; i++)
{
step5data[i] = k0xorIpad[i];
}
for (i=0;i<data_length;i++)
{
step5data[i+64] = data[i];
}
#ifdef HMAC_DEBUG
debug_out("(k0 xor ipad) || text",step5data,data_length+64);
#endif
/* Step 6 */
sha1(step5data, data_length+b, digest);
#ifdef HMAC_DEBUG
debug_out("Hash((k0 xor ipad) || text)",digest,20);
#endif
/* Step 7 */
for (i=0; i<64; i++)
{
step7data[i] = k0[i] ^ opad;
}
#ifdef HMAC_DEBUG
debug_out("(k0 xor opad)",step7data,64);
#endif
/* Step 8 */
for (i=0;i<64;i++)
{
step8data[i] = step7data[i];
}
for (i=0;i<20;i++)
{
step8data[i+64] = digest[i];
}
#ifdef HMAC_DEBUG
debug_out("(k0 xor opad) || Hash((k0 xor ipad) || text)",step8data,20+64);
#endif
/* Step 9 */
sha1(step8data, b+20, digest);
#ifdef HMAC_DEBUG
debug_out("HASH((k0 xor opad) || Hash((k0 xor ipad) || text))",digest,20);
#endif
}
边栏推荐
- Google与Pixar开发Draco支持USD格式 加速3D对象传输&lt;转发&gt;
- Listening freely, the next stop of online text traffic competition?
- uniapp使用简单方法signalR(仅用于web调试,无法打包app)
- 议程速递 | 7月27日分论坛议程一览
- [socket] the three handshakes are completed in listen, and accept only takes out one connection from the queue that completes the connection
- 卸载魅族应用商店
- PTA class a 1001
- 码云,正式支持 Pages 功能,可以部署静态页面
- Review of database -- 1. Overview
- 关于函数模板描述错误的是(链接格式错误怎么解决)
猜你喜欢
[leetcode每日一题2021/4/29]403. 青蛙过河
Uniapp uses the simple method signalr (only for web debugging, cannot package apps)
Navicat15连接本地虚拟机的Mysql(Centos7)
[Halcon vision] affine transformation
.NET 开源框架在工业生产中的应用
抓包工具fiddler和wireshark对比
Review of database -- 3. SQL language
Redis Docker实例与数据结构
【dectectron2】跟着官方demo一起做
3.1 leetcode daily question 6
随机推荐
What is wrong about the description of function templates (how to solve link format errors)
centos8(liunx)部署WTM(ASP.NET 5)使用pgsql
【Halcon视觉】图像灰度变化
【dectectron2】跟着官方demo一起做
Comparison of packet capturing tools fiddler and Wireshark
String null to empty string (what does empty string mean)
Summary of common skills in H5 development of mobile terminal
Agenda express | list of sub forum agenda on July 27
Redis特殊数据类型使用场景
Navicat15 MySQL (centos7) connected to local virtual machine
Unit test, what is unit test and why is it so difficult to write a single test
Asynctask < T> decoration and await are not used in synchronous methods to obtain asynchronous return values (asynchronous methods are called in synchronous methods)
[socket] the three handshakes are completed in listen, and accept only takes out one connection from the queue that completes the connection
.NET操作Redis List列表
[Halcon vision] affine transformation
Introduction to data analysis | kaggle Titanic mission (I) - > data loading and preliminary observation
PTA class a 1001
Listening freely, the next stop of online text traffic competition?
异常的概念与处理
[leetcode每日一题2021/2/13]448. 找到所有数组中消失的数字