#include "stm32f10x.h" #include #include #include #include #include "Aliyuniot.h" #include "CoAP_Util.h" #include "mbedtls_util.h" #include "cJSON.h" #include "Log_Module.h" #include "Common_Util.h" /** 阿里云连接参数 **/ static char ProductKey[20] = "k0g9w9xRhhi"; static char DeviceName[20] = "3738393435363738"; static char DeviceSecret[40] = "9b59c75bc0044b0de06f3a3355ce94ee"; static char ClientID[60]; static uint16_t Port = 5682; static char Host[60]; static uint32_t SeqOffset = 65534; static char Random[20]; static char Token[50]; static void initClientIdAndHost(void); // 打印参数 void aliyuniot_printf_params(void) { Log_Printf("------aliyun start------\r\n"); Log_Printf("ProductKey=%s\r\n", ProductKey); Log_Printf("DeviceName=%s\r\n", DeviceName); Log_Printf("DeviceSecret=%s\r\n", DeviceSecret); Log_Printf("Token=%s\r\n", Token); Log_Printf("Random=%s\r\n", Random); Log_Printf("SeqOffset=%d\r\n", SeqOffset); Log_Printf("------aliyun end------\r\n"); } // 获取host char * aliyuniot_get_host(void) { initClientIdAndHost(); return Host; } // 获取port uint16_t aliyuniot_get_port(void) { return Port; } // 判断是否认证 uint8_t aliyuniot_is_authentication(void) { if(strlen(Token) > 0) // 已认证 { return 1; } else { return 0; } } // 设置阿里云连接参数 void aliyuniot_set_device_params(char * prodect_key, char * device_name, char * device_secret) { memset(ProductKey, 0, sizeof(ProductKey)); strcpy(ProductKey, prodect_key); memset(DeviceName, 0, sizeof(DeviceName)); strcpy(DeviceName, device_name); memset(DeviceSecret, 0, sizeof(DeviceSecret)); strcpy(DeviceSecret, device_secret); } // 设置Token static void set_token(char * token) { memset(Token, 0, sizeof(Token)); strcpy(Token, token); } static void set_random(char * random) { memset(Random, 0, sizeof(Random)); strcpy(Random, random); } static void set_seqOffset(uint32_t seqOffset) { SeqOffset = seqOffset; } void aliyuniot_set_device_token(char * token, char * random, uint32_t seqOffset) { set_token(token); set_random(random); set_seqOffset(seqOffset); } // 初始化Host和clientID static void initClientIdAndHost(void) { // 设置host memset(Host, 0, sizeof(Host)); strcat(Host, ProductKey); strcat(Host, ".coap.cn-shanghai.link.aliyuncs.com"); // 设置clientid memset(ClientID, 0, sizeof(ClientID)); strcat(ClientID, ProductKey); strcat(ClientID, "&"); strcat(ClientID, DeviceName); } // 拼接认证报文 static char StrForSignature[100]; static char sign[50]; static uint8_t payload[256]; void aliyuniot_get_auth_message(uint8_t * coap_message, uint16_t * coap_message_length) { // 先初始化clientID和Host initClientIdAndHost(); // CoAP协议 CoAP_Init(coap_message); CoAP_Set_T(0); CoAP_Set_Code(2); CoAP_Set_MessageID(SeqOffset); // option // host CoAP_Set_Option_Str(3, Host); // port CoAP_Set_Option_Short(7, Port); // path CoAP_Set_Option_Str(11, "auth"); // content-format CoAP_Set_Option_Short(12, 50); // accept CoAP_Set_Option_Short(17, 50); // 待签名数据 // 签名相关 memset(StrForSignature, 0, sizeof(StrForSignature)); sprintf(StrForSignature, "clientId%sdeviceName%sproductKey%sseq%d", ClientID, DeviceName, ProductKey, SeqOffset); // Log_Printf_Debug("认证报文StrForSignature:%s\r\n", StrForSignature); // 签名 memset(sign, 0, sizeof(sign)); utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, DeviceSecret, strlen(DeviceSecret)); // payload memset(payload, 0, sizeof(payload)); sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%d\"}", ClientID, sign, ProductKey, DeviceName, SeqOffset); // 设置payload CoAP_Set_Payload_Str((char *)payload); // 生成报文 * coap_message_length = CoAP_Get_Length(); } // 拼接数据报文 // aes cbc static uint8_t aes_key[16] = {0}; static char iv[] = "543yhjy97ae7fyfg"; static char out[80]; static char sha256_source[100]; static char Rand2089[10] = {'\0'}; static uint8_t Opt2089[20]; void aliyuniot_get_data_message(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length) { // aliyuniot_printf_params(); // 先初始化clientID和Host initClientIdAndHost(); SeqOffset++; // Log_Printf_Debug("STEP: 拼接数据报文,seqOffset=%d\r\n", SeqOffset); // 获取密钥 memset(sha256_source, 0, sizeof(sha256_source)); snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,DeviceSecret ,Random); memset(out, 0, sizeof(out)); utils_sha256(sha256_source, strlen(sha256_source), out); memset(aes_key, 0, sizeof(aes_key)); memcpy(aes_key, out+8, 16); //获取key // CoAP协议 CoAP_Init(coap_message); CoAP_Set_T(0); CoAP_Set_Code(2); CoAP_Set_MessageID(SeqOffset); // option // host CoAP_Set_Option_Str(3, Host); // port CoAP_Set_Option_Short(7, Port); // path CoAP_Set_Option_Str(11, "topic"); CoAP_Set_Option_Str(11, "sys"); CoAP_Set_Option_Str(11, ProductKey); CoAP_Set_Option_Str(11, DeviceName); CoAP_Set_Option_Str(11, "thing"); CoAP_Set_Option_Str(11, "model"); CoAP_Set_Option_Str(11, "up_raw"); // content-format CoAP_Set_Option_Short(12, 50); // accept CoAP_Set_Option_Short(17, 50); // 2088 CoAP_Set_Option_Str(2088, Token); // 2089 memset(Rand2089, 0, sizeof(Rand2089)); memset(Opt2089, 0, sizeof(Opt2089)); my_itoa(SeqOffset, Rand2089, 10); int Opt2089_Length = utils_aes128_cbc_enc_with_length(aes_key, iv, (uint8_t *)Rand2089, strlen(Rand2089), Opt2089); CoAP_Set_Option(2089,Opt2089_Length, Opt2089); // payload memset(payload, 0, sizeof(payload)); int payload_length = utils_aes128_cbc_enc_with_length(aes_key, iv, data, data_length, payload); CoAP_Set_Payload(payload, payload_length); // 生成报文 * coap_message_length = CoAP_Get_Length(); } // 接收数据处理 static uint8_t plaintext[256]; // 明文 uint8_t aliyuniot_recv_data_handle(uint8_t * coap_message, uint16_t coap_message_length) { memset(payload, 0, sizeof(payload)); uint16_t payload_length = CoAP_Get_Payload(coap_message, coap_message_length, payload); Log_Printf_Debug("payload长度: %d\r\n", payload_length); // 判断是认证返回,还是数据发送返回 if(payload_length == 0) // 无返回 { // 清空Token,重新认证 memset(Token, '\0', sizeof(Token)); return 0; } else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回 { // 解析json cJSON * cjson = cJSON_Parse((char * )payload); // Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload); if(cJSON_HasObjectItem(cjson, "random")) { char * random = cJSON_GetObjectItem(cjson, "random")->valuestring; set_random(random); } if(cJSON_HasObjectItem(cjson, "seqOffset")) { uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint; set_seqOffset(seqOffset); } if(cJSON_HasObjectItem(cjson, "token")) { char * token = cJSON_GetObjectItem(cjson, "token")->valuestring; set_token(token); } cJSON_Delete(cjson);//清除结构体 return 1; } else { // 数据发送成功返回 memset(plaintext, 0, sizeof(plaintext)); uint16_t plaintext_length = utils_aes128_cbc_dec(aes_key, iv, (char * )payload, payload_length, (char * )plaintext); Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext); return 2; } }