Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+948
@@ -0,0 +1,948 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "string.h"
|
||||
#include "infra_state.h"
|
||||
#include "infra_compat.h"
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
#include "infra_string.h"
|
||||
#include "infra_httpc.h"
|
||||
#include "infra_sha256.h"
|
||||
#include "dynreg_internal.h"
|
||||
#include "dynreg_api.h"
|
||||
#ifdef MQTT_DYNAMIC_REGISTER
|
||||
#include "dev_sign_api.h"
|
||||
#include "mqtt_api.h"
|
||||
#endif
|
||||
|
||||
#define HTTP_RESPONSE_PAYLOAD_LEN (256)
|
||||
|
||||
#define DYNREG_RANDOM_KEY_LENGTH (15)
|
||||
#define DYNREG_SIGN_LENGTH (65)
|
||||
#define DYNREG_SIGN_METHOD_HMACSHA256 "hmacsha256"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *payload;
|
||||
int payload_len;
|
||||
} dynreg_http_response_t;
|
||||
|
||||
static int dynamic_register = 0;
|
||||
static int dynamic_register_region = 0;
|
||||
|
||||
#if !defined(MQTT_DYNAMIC_REGISTER)
|
||||
static int _parse_string_value(char *payload, int *pos, int *start, int *end)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
for (idx = *pos + 1; idx < strlen(payload); idx++)
|
||||
{
|
||||
if (payload[idx] == '\"')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*start = *pos + 1;
|
||||
*end = idx - 1;
|
||||
*pos = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _parse_dynreg_value(char *payload, char *key, int *pos, int *start, int *end)
|
||||
{
|
||||
int idx = 0;
|
||||
/* printf("=====%s\n",&payload[*pos]); */
|
||||
|
||||
if (memcmp(key, "code", strlen("code")) == 0)
|
||||
{
|
||||
for (idx = *pos; idx < strlen(payload); idx++)
|
||||
{
|
||||
if (payload[idx] < '0' || payload[idx] > '9')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*start = *pos;
|
||||
*end = idx - 1;
|
||||
*pos = *end;
|
||||
return 0;
|
||||
}
|
||||
else if (memcmp(key, "data", strlen("data")) == 0)
|
||||
{
|
||||
int bracket_cnt = 0;
|
||||
if (payload[*pos] != '{')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
for (idx = *pos; idx < strlen(payload); idx++)
|
||||
{
|
||||
if (payload[idx] == '{')
|
||||
{
|
||||
bracket_cnt++;
|
||||
}
|
||||
else if (payload[idx] == '}')
|
||||
{
|
||||
bracket_cnt--;
|
||||
}
|
||||
if (bracket_cnt == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*start = *pos;
|
||||
*end = idx;
|
||||
*pos = *end;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (payload[*pos] != '\"')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return _parse_string_value(payload, pos, start, end);
|
||||
}
|
||||
|
||||
/* return -1; */
|
||||
}
|
||||
|
||||
static int _parse_dynreg_result(char *payload, char *key, int *start, int *end)
|
||||
{
|
||||
int res = 0, idx = 0, pos = 0;
|
||||
|
||||
for (idx = 0; idx < strlen(payload); idx++)
|
||||
{
|
||||
/* printf("loop start: %s\n",&payload[idx]); */
|
||||
if (payload[idx] == '\"')
|
||||
{
|
||||
for (pos = idx + 1; pos < strlen(payload); pos++)
|
||||
{
|
||||
if (payload[pos] == '\"')
|
||||
{
|
||||
/* printf("key: %.*s\n",pos - idx - 1, &payload[idx+1]); */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == strlen(payload) || payload[pos + 1] != ':')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += 2;
|
||||
res = _parse_dynreg_value(payload, key, &pos, start, end);
|
||||
if (res == 0 && memcmp(key, &payload[idx + 1], strlen(key)) == 0)
|
||||
{
|
||||
/* printf("value: %.*s\n",*end - *start + 1,&payload[*start]); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = pos;
|
||||
}
|
||||
}
|
||||
|
||||
printf("exit 4\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _calc_dynreg_sign(
|
||||
char product_key[IOTX_PRODUCT_KEY_LEN],
|
||||
char product_secret[IOTX_PRODUCT_SECRET_LEN],
|
||||
char device_name[IOTX_DEVICE_NAME_LEN],
|
||||
char random[DYNREG_RANDOM_KEY_LENGTH + 1],
|
||||
char sign[DYNREG_SIGN_LENGTH])
|
||||
{
|
||||
int sign_source_len = 0;
|
||||
uint8_t signnum[32];
|
||||
uint8_t *sign_source = NULL;
|
||||
const char *dynamic_register_sign_fmt = "deviceName%sproductKey%srandom%s";
|
||||
|
||||
/* Start Dynamic Register */
|
||||
memset(random, 0, DYNREG_RANDOM_KEY_LENGTH + 1);
|
||||
memcpy(random, "8Ygb7ULYh53B6OA", strlen("8Ygb7ULYh53B6OA"));
|
||||
dynreg_info("Random Key: %s", random);
|
||||
|
||||
/* Calculate SHA256 Value */
|
||||
sign_source_len = strlen(dynamic_register_sign_fmt) + strlen(device_name) + strlen(product_key) + strlen(random) + 1;
|
||||
sign_source = dynreg_malloc(sign_source_len);
|
||||
if (sign_source == NULL)
|
||||
{
|
||||
dynreg_err("Memory Not Enough");
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(sign_source, 0, sign_source_len);
|
||||
HAL_Snprintf((char *)sign_source, sign_source_len, dynamic_register_sign_fmt, device_name, product_key, random);
|
||||
|
||||
utils_hmac_sha256(sign_source, strlen((const char *)sign_source), (uint8_t *)product_secret, strlen(product_secret),
|
||||
signnum);
|
||||
infra_hex2str(signnum, 32, sign);
|
||||
dynreg_free(sign_source);
|
||||
dynreg_info("Sign: %s", sign);
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static int _recv_callback(char *ptr, int length, int total_length, void *userdata)
|
||||
{
|
||||
dynreg_http_response_t *response = (dynreg_http_response_t *)userdata;
|
||||
if (strlen(response->payload) + length > response->payload_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(response->payload + strlen(response->payload), ptr, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static int _fetch_dynreg_http_resp(char *request_payload, char *response_payload,
|
||||
iotx_http_region_types_t region, char device_secret[IOTX_DEVICE_SECRET_LEN])
|
||||
{
|
||||
int res = 0;
|
||||
const char *domain = NULL;
|
||||
const char *url_format = "http://%s/auth/register/device";
|
||||
char *url = NULL;
|
||||
int url_len = 0;
|
||||
const char *pub_key = NULL;
|
||||
void *http_handle = NULL;
|
||||
int port = 443;
|
||||
iotx_http_method_t method = IOTX_HTTP_POST;
|
||||
int timeout_ms = 10000;
|
||||
char *header = "Accept: text/xml,text/javascript,text/html,application/json\r\n"
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
int http_recv_maxlen = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
dynreg_http_response_t response;
|
||||
int start = 0, end = 0, data_start = 0, data_end = 0;
|
||||
|
||||
domain = g_infra_http_domain[region];
|
||||
if (NULL == domain)
|
||||
{
|
||||
return STATE_USER_INPUT_HTTP_DOMAIN;
|
||||
}
|
||||
url_len = strlen(url_format) + strlen(domain) + 1;
|
||||
url = (char *)dynreg_malloc(url_len);
|
||||
if (NULL == url)
|
||||
{
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(url, 0, url_len);
|
||||
HAL_Snprintf(url, url_len, url_format, domain);
|
||||
|
||||
memset(&response, 0, sizeof(dynreg_http_response_t));
|
||||
response.payload = response_payload;
|
||||
response.payload_len = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
#ifdef SUPPORT_TLS
|
||||
{
|
||||
// extern const char *iotx_ca_crt;
|
||||
// pub_key = iotx_ca_crt;
|
||||
}
|
||||
#endif
|
||||
|
||||
http_handle = wrapper_http_init();
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_URL, (void *)url);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_PORT, (void *)&port);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_METHOD, (void *)&method);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_HEADER, (void *)header);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_CERT, (void *)pub_key);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_TIMEOUT, (void *)&timeout_ms);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCALLBACK, (void *)_recv_callback);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVMAXLEN, (void *)&http_recv_maxlen);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCONTEXT, (void *)&response);
|
||||
|
||||
res = wrapper_http_perform(http_handle, request_payload, strlen(request_payload));
|
||||
wrapper_http_deinit(&http_handle);
|
||||
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
dynreg_free(url);
|
||||
return res;
|
||||
}
|
||||
dynreg_free(url);
|
||||
dynreg_info("Http Response Payload: %s", response_payload);
|
||||
|
||||
_parse_dynreg_result(response_payload, "errorCode", &start, &end);
|
||||
dynreg_info("Dynamic Register errorcode: %.*s", end - start + 1, &response_payload[start]);
|
||||
|
||||
if (memcmp(&response_payload[start], "200", strlen("200")) != 0)
|
||||
{
|
||||
iotx_state_event(ITE_STATE_HTTP_COMM, STATE_HTTP_DYNREG_FAIL_RESP, &response_payload[start]);
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
}
|
||||
|
||||
_parse_dynreg_result(response_payload, "data", &data_start, &data_end);
|
||||
/* dynreg_info("value: %.*s\n",data_end - data_start + 1,&response_payload[data_start]); */
|
||||
|
||||
_parse_dynreg_result(&response_payload[data_start + 1], "deviceSecret", &start, &end);
|
||||
dynreg_info("Dynamic Register Device Secret: %.*s", end - start + 1, &response_payload[data_start + 1 + start]);
|
||||
|
||||
if (end - start + 1 > IOTX_DEVICE_SECRET_LEN)
|
||||
{
|
||||
return STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
|
||||
memcpy(device_secret, &response_payload[data_start + 1 + start], end - start + 1);
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static int _fetch_custom_reg_http_resp(char *request_payload, char *response_payload,
|
||||
iotx_http_region_types_t region, char product_key[IOTX_PRODUCT_KEY_LEN], char device_name[IOTX_DEVICE_NAME_LEN], char device_secret[IOTX_DEVICE_SECRET_LEN])
|
||||
{
|
||||
int res = 0;
|
||||
int port = 0;
|
||||
const char *domain = NULL;
|
||||
char url_format[128] = {0};
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_FORMAL) // 生产环境
|
||||
{
|
||||
memcpy(url_format, "http://10.111.186.1/asset-web-api/registerService/getCertificateInfo", strlen("http://10.111.186.1/asset-web-api/registerService/getCertificateInfo"));
|
||||
port = 11901;
|
||||
}
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_DEBUG) // 接入环境
|
||||
{
|
||||
memcpy(url_format, "http://121.196.185.161/api/access/pile/getCertificateInfo", strlen("http://121.196.185.161/api/access/pile/getCertificateInfo"));
|
||||
port = 8081;
|
||||
}
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_TEST) // 测试环境
|
||||
{
|
||||
memcpy(url_format, "http://124.126.19.5/asset-web-serv-v5.3.0/registerService/getCertificateInfo", strlen("http://124.126.19.5/asset-web-serv-v5.3.0/registerService/getCertificateInfo"));
|
||||
port = 19849;
|
||||
}
|
||||
|
||||
char *url = NULL;
|
||||
int url_len = 0;
|
||||
const char *pub_key = NULL;
|
||||
void *http_handle = NULL;
|
||||
|
||||
iotx_http_method_t method = IOTX_HTTP_POST;
|
||||
int timeout_ms = 10000;
|
||||
char *header = "Accept: text/xml,text/javascript,text/html,application/json\r\n"
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
int http_recv_maxlen = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
dynreg_http_response_t response;
|
||||
int start = 0, end = 0, data_start = 0, data_end = 0;
|
||||
|
||||
memset(&response, 0, sizeof(dynreg_http_response_t));
|
||||
response.payload = response_payload;
|
||||
response.payload_len = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
#ifdef SUPPORT_TLS
|
||||
{
|
||||
// extern const char *iotx_ca_crt;
|
||||
// pub_key = iotx_ca_crt;
|
||||
}
|
||||
#endif
|
||||
|
||||
http_handle = wrapper_http_init();
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_URL, (void *)url_format);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_PORT, (void *)&port);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_METHOD, (void *)&method);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_HEADER, (void *)header);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_CERT, (void *)pub_key);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_TIMEOUT, (void *)&timeout_ms);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCALLBACK, (void *)_recv_callback);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVMAXLEN, (void *)&http_recv_maxlen);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCONTEXT, (void *)&response);
|
||||
|
||||
res = wrapper_http_perform(http_handle, request_payload, strlen(request_payload));
|
||||
wrapper_http_deinit(&http_handle);
|
||||
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
dynreg_free(url);
|
||||
return res;
|
||||
}
|
||||
dynreg_free(url);
|
||||
dynreg_info("Http Response Payload: %s", response_payload);
|
||||
|
||||
_parse_dynreg_result(response_payload, "code", &start, &end);
|
||||
dynreg_info("Dynamic Register code: %.*s", end - start + 1, &response_payload[start]);
|
||||
|
||||
if (memcmp(&response_payload[start], "200", strlen("200")) != 0)
|
||||
{
|
||||
iotx_state_event(ITE_STATE_HTTP_COMM, STATE_HTTP_DYNREG_FAIL_RESP, &response_payload[start]);
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
}
|
||||
|
||||
_parse_dynreg_result(response_payload, "data", &data_start, &data_end);
|
||||
/* dynreg_info("value: %.*s\n",data_end - data_start + 1,&response_payload[data_start]); */
|
||||
|
||||
if (_parse_dynreg_result(&response_payload[data_start + 1], "productKey", &start, &end) < 0)
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
dynreg_info("Dynamic Register Product Key: %.*s", end - start + 1, &response_payload[data_start + 1 + start]);
|
||||
if (end - start + 1 > IOTX_PRODUCT_KEY_LEN)
|
||||
{
|
||||
return STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
memcpy(product_key, &response_payload[data_start + 1 + start], end - start + 1);
|
||||
|
||||
if (_parse_dynreg_result(&response_payload[data_start + 1], "deviceName", &start, &end) < 0)
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
dynreg_info("Dynamic Register Device Name: %.*s", end - start + 1, &response_payload[data_start + 1 + start]);
|
||||
if (end - start + 1 > IOTX_DEVICE_NAME_LEN)
|
||||
{
|
||||
return STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
memcpy(device_name, &response_payload[data_start + 1 + start], end - start + 1);
|
||||
|
||||
if (_parse_dynreg_result(&response_payload[data_start + 1], "deviceSecret", &start, &end) < 0)
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
dynreg_info("Dynamic Register Device Secret: %.*s", end - start + 1, &response_payload[data_start + 1 + start]);
|
||||
if (end - start + 1 > IOTX_DEVICE_SECRET_LEN)
|
||||
{
|
||||
return STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
memcpy(device_secret, &response_payload[data_start + 1 + start], end - start + 1);
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
static int _fetch_get_reg_code_http_resp(char *request_payload, char *response_payload,
|
||||
iotx_http_region_types_t region, char reg_code[IOTX_DEVICE_REG_CODE_LEN])
|
||||
{
|
||||
int res = 0;
|
||||
int port = 0;
|
||||
const char *domain = NULL;
|
||||
char url_format[128] = {0};
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_FORMAL) // 生产环境
|
||||
{
|
||||
memcpy(url_format, "http://10.111.186.1/asset-web-api/registerService/getRegisterCode", strlen("http://10.111.186.1/asset-web-api/registerService/getRegisterCode"));
|
||||
port = 11901;
|
||||
}
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_DEBUG) // 接入环境
|
||||
{
|
||||
memcpy(url_format, "http://121.196.185.161/api/access/pile/getRegisterCode", strlen("http://121.196.185.161/api/access/pile/getRegisterCode"));
|
||||
port = 8081;
|
||||
}
|
||||
|
||||
if (dynamic_register_region == ACCESS_IS_TEST) // 测试环境
|
||||
{
|
||||
memcpy(url_format, "http://124.126.19.5/asset-web-serv-v5.3.0/registerService/getRegisterCode", strlen("http://124.126.19.5/asset-web-serv-v5.3.0/registerService/getRegisterCode"));
|
||||
port = 19849;
|
||||
}
|
||||
|
||||
char *url = NULL;
|
||||
int url_len = 0;
|
||||
const char *pub_key = NULL;
|
||||
void *http_handle = NULL;
|
||||
|
||||
iotx_http_method_t method = IOTX_HTTP_POST;
|
||||
int timeout_ms = 10000;
|
||||
char *header = "Accept: text/xml,text/javascript,text/html,application/json\r\n"
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
int http_recv_maxlen = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
dynreg_http_response_t response;
|
||||
int start = 0, end = 0, data_start = 0, data_end = 0;
|
||||
|
||||
memset(&response, 0, sizeof(dynreg_http_response_t));
|
||||
response.payload = response_payload;
|
||||
response.payload_len = HTTP_RESPONSE_PAYLOAD_LEN;
|
||||
#ifdef SUPPORT_TLS
|
||||
{
|
||||
// extern const char *iotx_ca_crt;
|
||||
// pub_key = iotx_ca_crt;
|
||||
}
|
||||
#endif
|
||||
|
||||
http_handle = wrapper_http_init();
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_URL, (void *)url_format);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_PORT, (void *)&port);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_METHOD, (void *)&method);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_HEADER, (void *)header);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_CERT, (void *)pub_key);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_TIMEOUT, (void *)&timeout_ms);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCALLBACK, (void *)_recv_callback);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVMAXLEN, (void *)&http_recv_maxlen);
|
||||
wrapper_http_setopt(http_handle, IOTX_HTTPOPT_RECVCONTEXT, (void *)&response);
|
||||
|
||||
res = wrapper_http_perform(http_handle, request_payload, strlen(request_payload));
|
||||
wrapper_http_deinit(&http_handle);
|
||||
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
dynreg_free(url);
|
||||
return res;
|
||||
}
|
||||
dynreg_free(url);
|
||||
dynreg_info("Http Response Payload: %s", response_payload);
|
||||
|
||||
_parse_dynreg_result(response_payload, "code", &start, &end);
|
||||
dynreg_info("Dynamic Register code: %.*s", end - start + 1, &response_payload[start]);
|
||||
|
||||
if (memcmp(&response_payload[start], "200", strlen("200")) != 0)
|
||||
{
|
||||
iotx_state_event(ITE_STATE_HTTP_COMM, STATE_HTTP_DYNREG_FAIL_RESP, &response_payload[start]);
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
}
|
||||
|
||||
_parse_dynreg_result(response_payload, "data", &data_start, &data_end);
|
||||
/* dynreg_info("value: %.*s\n",data_end - data_start + 1,&response_payload[data_start]); */
|
||||
|
||||
if (_parse_dynreg_result(&response_payload[data_start + 1], "registerCode", &start, &end) < 0)
|
||||
return STATE_HTTP_DYNREG_FAIL_RESP;
|
||||
dynreg_info("device code get registerCode is: %.*s", end - start + 1, &response_payload[data_start + 1 + start]);
|
||||
if (end - start + 1 > IOTX_DEVICE_REG_CODE_LEN)
|
||||
{
|
||||
return STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
memcpy(reg_code, &response_payload[data_start + 1 + start], end - start + 1);
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int32_t _http_custom_register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
|
||||
{
|
||||
int res = 0, custom_register_request_len = 0;
|
||||
// char sign[DYNREG_SIGN_LENGTH] = {0};
|
||||
// char random[DYNREG_RANDOM_KEY_LENGTH + 1] = {0};
|
||||
const char *custom_register_format = "deviceCode=%s®isterCode=%s&gunNo=%s";
|
||||
char *custom_register_request = NULL;
|
||||
char *custom_register_response = NULL;
|
||||
const char *deviceCode = "";
|
||||
const char *gunNo = "";
|
||||
|
||||
if (strlen(meta->device_reg_code) > IOTX_DEVICE_REG_CODE_LEN)
|
||||
{
|
||||
return STATE_USER_INPUT_DR;
|
||||
}
|
||||
custom_register_request_len = strlen(custom_register_format) + strlen(meta->device_reg_code) + strlen(deviceCode) + strlen(gunNo) + 1;
|
||||
custom_register_request = dynreg_malloc(custom_register_request_len);
|
||||
if (custom_register_request == NULL)
|
||||
{
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(custom_register_request, 0, custom_register_request_len);
|
||||
HAL_Snprintf(custom_register_request, custom_register_request_len, custom_register_format, deviceCode,
|
||||
meta->device_reg_code, gunNo);
|
||||
|
||||
custom_register_response = dynreg_malloc(HTTP_RESPONSE_PAYLOAD_LEN);
|
||||
if (custom_register_response == NULL)
|
||||
{
|
||||
dynreg_free(custom_register_request);
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(custom_register_response, 0, HTTP_RESPONSE_PAYLOAD_LEN);
|
||||
|
||||
/* Send Http Request For Getting Device Secret */
|
||||
res = _fetch_custom_reg_http_resp(custom_register_request, custom_register_response, region, meta->product_key, meta->device_name, meta->device_secret);
|
||||
#ifdef INFRA_LOG_NETWORK_PAYLOAD
|
||||
dynreg_dbg("Downstream Payload:");
|
||||
iotx_facility_json_print(custom_register_response, LOG_DEBUG_LEVEL, '<');
|
||||
#endif
|
||||
|
||||
dynreg_free(custom_register_request);
|
||||
dynreg_free(custom_register_response);
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t _http_get_regcode(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
|
||||
{
|
||||
int res = 0, custom_register_request_len = 0;
|
||||
// char sign[DYNREG_SIGN_LENGTH] = {0};
|
||||
// char random[DYNREG_RANDOM_KEY_LENGTH + 1] = {0};
|
||||
const char *custom_register_format = "deviceCode=%s";
|
||||
char *custom_register_request = NULL;
|
||||
char *custom_register_response = NULL;
|
||||
const char *deviceCode = "1";
|
||||
|
||||
if (strlen(deviceCode) > IOTX_DEVICE_UID_LEN)
|
||||
{
|
||||
return STATE_USER_INPUT_DR;
|
||||
}
|
||||
custom_register_request_len = strlen(custom_register_format) + strlen(meta->device_asset) + 1;
|
||||
custom_register_request = dynreg_malloc(custom_register_request_len);
|
||||
if (custom_register_request == NULL)
|
||||
{
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(custom_register_request, 0, custom_register_request_len);
|
||||
HAL_Snprintf(custom_register_request, custom_register_request_len, custom_register_format, meta->device_asset);
|
||||
|
||||
custom_register_response = dynreg_malloc(HTTP_RESPONSE_PAYLOAD_LEN);
|
||||
if (custom_register_response == NULL)
|
||||
{
|
||||
dynreg_free(custom_register_request);
|
||||
return STATE_SYS_DEPEND_MALLOC;
|
||||
}
|
||||
memset(custom_register_response, 0, HTTP_RESPONSE_PAYLOAD_LEN);
|
||||
|
||||
/* Send Http Request For Getting Device Secret */
|
||||
// res = _fetch_custom_reg_http_resp(custom_register_request, custom_register_response, region, meta->product_key,meta->device_name,meta->device_secret);
|
||||
res = _fetch_get_reg_code_http_resp(custom_register_request, custom_register_response, region, meta->device_reg_code);
|
||||
#ifdef INFRA_LOG_NETWORK_PAYLOAD
|
||||
dynreg_dbg("Downstream Payload:");
|
||||
iotx_facility_json_print(custom_register_response, LOG_DEBUG_LEVEL, '<');
|
||||
#endif
|
||||
|
||||
dynreg_free(custom_register_request);
|
||||
dynreg_free(custom_register_response);
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static int _mqtt_dynreg_sign_password(iotx_dev_meta_info_t *meta_info, iotx_sign_mqtt_t *signout, char *rand)
|
||||
{
|
||||
char signsource[DEV_SIGN_SOURCE_MAXLEN] = {0};
|
||||
uint16_t signsource_len = 0;
|
||||
const char sign_fmt[] = "deviceName%sproductKey%srandom%s";
|
||||
uint8_t sign_hex[32] = {0};
|
||||
|
||||
signsource_len = strlen(sign_fmt) + strlen(meta_info->device_name) + 1 + strlen(meta_info->product_key) + strlen(rand) + 1;
|
||||
if (signsource_len >= DEV_SIGN_SOURCE_MAXLEN)
|
||||
{
|
||||
return STATE_MQTT_SIGN_SOURCE_BUF_SHORT;
|
||||
}
|
||||
memset(signsource, 0, signsource_len);
|
||||
memcpy(signsource, "deviceName", strlen("deviceName"));
|
||||
memcpy(signsource + strlen(signsource), meta_info->device_name, strlen(meta_info->device_name));
|
||||
memcpy(signsource + strlen(signsource), "productKey", strlen("productKey"));
|
||||
memcpy(signsource + strlen(signsource), meta_info->product_key, strlen(meta_info->product_key));
|
||||
memcpy(signsource + strlen(signsource), "random", strlen("random"));
|
||||
memcpy(signsource + strlen(signsource), rand, strlen(rand));
|
||||
|
||||
utils_hmac_sha256((const uint8_t *)signsource, strlen(signsource), (uint8_t *)meta_info->product_secret,
|
||||
strlen(meta_info->product_secret), sign_hex);
|
||||
infra_hex2str(sign_hex, 32, signout->password);
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t _mqtt_dynreg_sign_clientid(iotx_dev_meta_info_t *meta_info, iotx_sign_mqtt_t *signout, char *rand)
|
||||
{
|
||||
const char *clientid1 = "|authType=register,random=";
|
||||
const char *clientid2 = ",signmethod=hmacsha256,securemode=2|";
|
||||
uint32_t clientid_len = 0;
|
||||
|
||||
clientid_len = strlen(meta_info->product_key) + 1 + strlen(meta_info->device_name) +
|
||||
strlen(clientid1) + strlen(rand) + strlen(clientid2) + 1;
|
||||
if (clientid_len >= DEV_SIGN_CLIENT_ID_MAXLEN)
|
||||
{
|
||||
return ERROR_DEV_SIGN_CLIENT_ID_TOO_SHORT;
|
||||
}
|
||||
memset(signout->clientid, 0, clientid_len);
|
||||
memcpy(signout->clientid, meta_info->product_key, strlen(meta_info->product_key));
|
||||
memcpy(signout->clientid + strlen(signout->clientid), ".", strlen("."));
|
||||
memcpy(signout->clientid + strlen(signout->clientid), meta_info->device_name, strlen(meta_info->device_name));
|
||||
memcpy(signout->clientid + strlen(signout->clientid), clientid1, strlen(clientid1));
|
||||
memcpy(signout->clientid + strlen(signout->clientid), rand, strlen(rand));
|
||||
memcpy(signout->clientid + strlen(signout->clientid), clientid2, strlen(clientid2));
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
void _mqtt_dynreg_topic_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
|
||||
{
|
||||
int32_t res = 0;
|
||||
char *ds = (char *)pcontext;
|
||||
iotx_mqtt_topic_info_t *topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
|
||||
const char *asterisk = "**********************";
|
||||
|
||||
switch (msg->event_type)
|
||||
{
|
||||
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
|
||||
{
|
||||
/* print topic name and topic message */
|
||||
char *device_secret = NULL;
|
||||
uint32_t device_secret_len = 0;
|
||||
|
||||
if (memcmp(topic_info->ptopic, "/ext/register", strlen("/ext/register")))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse secret */
|
||||
res = infra_json_value((char *)topic_info->payload, topic_info->payload_len, "deviceSecret", strlen("deviceSecret"),
|
||||
&device_secret, &device_secret_len);
|
||||
if (res == STATE_SUCCESS)
|
||||
{
|
||||
memcpy(ds, device_secret + 1, device_secret_len - 2);
|
||||
memcpy(device_secret + 1 + 5, asterisk, strlen(asterisk));
|
||||
dynreg_info("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
|
||||
dynreg_info("Payload: %.*s", topic_info->payload_len, topic_info->payload);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t _mqtt_dynamic_register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
|
||||
{
|
||||
void *pClient = NULL;
|
||||
iotx_mqtt_param_t mqtt_params;
|
||||
int32_t res = 0;
|
||||
uint32_t length = 0, rand = 0;
|
||||
char rand_str[9] = {0};
|
||||
iotx_sign_mqtt_t signout;
|
||||
uint64_t timestart = 0, timenow = 0;
|
||||
char device_secret[IOTX_DEVICE_SECRET_LEN + 1] = {0};
|
||||
|
||||
memset(&signout, 0, sizeof(iotx_sign_mqtt_t));
|
||||
|
||||
/* setup hostname */
|
||||
if (IOTX_HTTP_REGION_CUSTOM == region)
|
||||
{
|
||||
if (g_infra_mqtt_domain[region] == NULL)
|
||||
{
|
||||
return STATE_USER_INPUT_MQTT_DOMAIN;
|
||||
}
|
||||
|
||||
length = strlen(g_infra_mqtt_domain[region]) + 1;
|
||||
if (length >= DEV_SIGN_HOSTNAME_MAXLEN)
|
||||
{
|
||||
return STATE_MQTT_SIGN_HOSTNAME_BUF_SHORT;
|
||||
}
|
||||
|
||||
memset(signout.hostname, 0, DEV_SIGN_HOSTNAME_MAXLEN);
|
||||
memcpy(signout.hostname, g_infra_mqtt_domain[region], strlen(g_infra_mqtt_domain[region]));
|
||||
}
|
||||
else
|
||||
{
|
||||
length = strlen(meta->product_key) + strlen(g_infra_mqtt_domain[region]) + 2;
|
||||
if (length >= DEV_SIGN_HOSTNAME_MAXLEN)
|
||||
{
|
||||
return STATE_MQTT_SIGN_HOSTNAME_BUF_SHORT;
|
||||
}
|
||||
memset(signout.hostname, 0, DEV_SIGN_HOSTNAME_MAXLEN);
|
||||
memcpy(signout.hostname, meta->product_key, strlen(meta->product_key));
|
||||
memcpy(signout.hostname + strlen(signout.hostname), ".", strlen("."));
|
||||
memcpy(signout.hostname + strlen(signout.hostname), g_infra_mqtt_domain[region],
|
||||
strlen(g_infra_mqtt_domain[region]));
|
||||
}
|
||||
|
||||
/* setup port */
|
||||
signout.port = 443;
|
||||
|
||||
/* setup username */
|
||||
length = strlen(meta->device_name) + strlen(meta->product_key) + 2;
|
||||
if (length >= DEV_SIGN_USERNAME_MAXLEN)
|
||||
{
|
||||
return STATE_MQTT_SIGN_USERNAME_BUF_SHORT;
|
||||
}
|
||||
memset(signout.username, 0, DEV_SIGN_USERNAME_MAXLEN);
|
||||
memcpy(signout.username, meta->device_name, strlen(meta->device_name));
|
||||
memcpy(signout.username + strlen(signout.username), "&", strlen("&"));
|
||||
memcpy(signout.username + strlen(signout.username), meta->product_key, strlen(meta->product_key));
|
||||
|
||||
/* password */
|
||||
rand = HAL_Random(0xffffffff);
|
||||
infra_hex2str((unsigned char *)&rand, 4, rand_str);
|
||||
res = _mqtt_dynreg_sign_password(meta, &signout, rand_str);
|
||||
if (res < 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
/* client id */
|
||||
res = _mqtt_dynreg_sign_clientid(meta, &signout, rand_str);
|
||||
if (res < 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
memset(&mqtt_params, 0, sizeof(iotx_mqtt_param_t));
|
||||
mqtt_params.host = signout.hostname;
|
||||
mqtt_params.port = signout.port;
|
||||
mqtt_params.username = signout.username;
|
||||
mqtt_params.password = signout.password;
|
||||
mqtt_params.client_id = signout.clientid;
|
||||
mqtt_params.request_timeout_ms = 5000;
|
||||
mqtt_params.clean_session = 1;
|
||||
mqtt_params.keepalive_interval_ms = 60000;
|
||||
mqtt_params.read_buf_size = 1000;
|
||||
mqtt_params.write_buf_size = 1000;
|
||||
mqtt_params.handle_event.h_fp = _mqtt_dynreg_topic_handle;
|
||||
mqtt_params.handle_event.pcontext = device_secret;
|
||||
|
||||
#ifdef SUPPORT_TLS
|
||||
{
|
||||
// extern const char *iotx_ca_crt;
|
||||
// mqtt_params.pub_key = iotx_ca_crt;
|
||||
}
|
||||
#endif
|
||||
|
||||
pClient = wrapper_mqtt_init(&mqtt_params);
|
||||
if (pClient == NULL)
|
||||
{
|
||||
return STATE_MQTT_WRAPPER_INIT_FAIL;
|
||||
}
|
||||
|
||||
res = wrapper_mqtt_connect(pClient);
|
||||
if (res < STATE_SUCCESS)
|
||||
{
|
||||
wrapper_mqtt_release(&pClient);
|
||||
return res;
|
||||
}
|
||||
|
||||
timestart = HAL_UptimeMs();
|
||||
while (1)
|
||||
{
|
||||
timenow = HAL_UptimeMs();
|
||||
if (timenow < timestart)
|
||||
{
|
||||
timestart = timenow;
|
||||
}
|
||||
|
||||
if (timestart - timenow >= MQTT_DYNREG_TIMEOUT_MS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
wrapper_mqtt_yield(pClient, 200);
|
||||
|
||||
if (strlen(device_secret) > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(device_secret) > 0)
|
||||
{
|
||||
res = STATE_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = STATE_HTTP_DYNREG_INVALID_DS;
|
||||
}
|
||||
|
||||
wrapper_mqtt_release(&pClient);
|
||||
|
||||
memcpy(meta->device_secret, device_secret, strlen(device_secret));
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t IOT_Dynamic_Register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
|
||||
{
|
||||
#ifdef MQTT_DYNAMIC_REGISTER
|
||||
return _mqtt_dynamic_register(region, meta);
|
||||
#else
|
||||
// return _http_dynamic_register(region, meta);
|
||||
return _http_custom_register(region, meta);
|
||||
#endif
|
||||
}
|
||||
// 设备唯一码换取注册码
|
||||
int32_t IOT_Get_Regcode(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta)
|
||||
{
|
||||
#ifdef MQTT_DYNAMIC_REGISTER
|
||||
return _mqtt_dynamic_register(region, meta);
|
||||
#else
|
||||
// return _http_dynamic_register(region, meta);
|
||||
return _http_get_regcode(region, meta);
|
||||
#endif
|
||||
}
|
||||
|
||||
int IOCTL_FUNC(IOTX_IOCTL_SET_DYNAMIC_REGISTER, void *data)
|
||||
{
|
||||
if (data == NULL)
|
||||
{
|
||||
return FAIL_RETURN;
|
||||
}
|
||||
dynamic_register = *(int *)data;
|
||||
return SUCCESS_RETURN;
|
||||
}
|
||||
|
||||
int IOCTL_FUNC(IOTX_IOCTL_GET_DYNAMIC_REGISTER, void *data)
|
||||
{
|
||||
if (data == NULL)
|
||||
{
|
||||
return FAIL_RETURN;
|
||||
}
|
||||
|
||||
*(int *)data = dynamic_register;
|
||||
return SUCCESS_RETURN;
|
||||
}
|
||||
|
||||
int IOCTL_FUNC(IOTX_IOCTL_SET_REGISTER_REGION, void *data)
|
||||
{
|
||||
if (data == NULL)
|
||||
{
|
||||
return FAIL_RETURN;
|
||||
}
|
||||
dynamic_register_region = *(int *)data;
|
||||
return SUCCESS_RETURN;
|
||||
}
|
||||
Reference in New Issue
Block a user