758 lines
22 KiB
C
758 lines
22 KiB
C
#include "system/includes.h"
|
||
#include "json_c/json_object.h"
|
||
#include "common/base64.h"
|
||
#include "common/aes.h"
|
||
#include "sock_api/sock_api.h"
|
||
#include "lwip.h"
|
||
#include "wifi/wifi_connect.h"
|
||
#include "mbedtls/aes.h"
|
||
#include "mbedtls/dhm.h"
|
||
#include "mbedtls/rsa.h"
|
||
#include "mbedtls/sha1.h"
|
||
#include "mbedtls/entropy.h"
|
||
#include "mbedtls/ctr_drbg.h"
|
||
|
||
#include "time.h"
|
||
#include <stdlib.h>
|
||
|
||
#if 1
|
||
#define log_info(x, ...) printf("\n\n>>>>>>[aplink_test]" x " ", ## __VA_ARGS__)
|
||
#else
|
||
#define log_info(...)
|
||
#endif
|
||
|
||
#define DH_INFO "{\"type\":\"dh\",\"sequence\":2,\"data\":{\"dh_key\":\"%s\",\"dh_p\":\"%s\",\"dh_g\":\"%s\"}}"
|
||
#define KEYNGREQ 0x01
|
||
#define DH 0x02
|
||
#define QPLINK 0x03
|
||
#define ACK 0x04
|
||
#define ELINK_SRV_PORT 32769 //服务器端口
|
||
#define IOT_SSID "ChinaIOT-%s-%02X%02X" //ssid格式
|
||
#define IOT_PWD "" //AP模式下登录密码,这里不设置密码
|
||
#define VENDOR "Vendor" //设备厂商
|
||
|
||
extern struct json_object *json_tokener_parse(const char *str);
|
||
const static int iot_device_send_keyngack(char *buf, int buf_len);
|
||
const static int iot_device_send_dh(char *buf, int buf_len);
|
||
const static int iot_device_send_aplinkget(char *buf, int buf_len);
|
||
static int dh_base64_decode(const unsigned char *input, unsigned char *output);
|
||
static int ap_elink_start(void);
|
||
void Hex2Str(const unsigned char *hex, char *str, int len);
|
||
static int dh_base64_encode(const unsigned char *input, const int len, unsigned char *output);
|
||
static int calculate_common_key(mbedtls_dhm_context *context, unsigned char *srv_pub, char *out_put);
|
||
static void iot_interact_to_app(void *client_sock);
|
||
static int aes_cbc_encode(unsigned char *input_buf, unsigned int input_len, unsigned char *key, unsigned char *encode_buf);
|
||
static int aes_cbc_decode(unsigned char *input_buf, unsigned int input_len, unsigned char *key, unsigned char *decode_buf);
|
||
static int iot_device_rec_handle(const char *object);
|
||
static int aplink_sock_write(void *sockhdl, const char *buf, size_t n);
|
||
extern int elink_aplink_set_ssid_pwd(const char *ssid, const char *pwd);
|
||
extern void get_wifi_mac_addr(u8 *mac_addr);
|
||
static void iot_device_enter_ap_mode(void);
|
||
static int flag;
|
||
|
||
typedef enum {
|
||
aplink_idel_state = 1,
|
||
aplink_wait_keyngreq,
|
||
aplink_wait_dh_info,
|
||
aplink_wait_aplink_info,
|
||
aplink_wait_ack,
|
||
aplink_qlink_finish,
|
||
} aplink_state;
|
||
|
||
typedef enum {
|
||
aplink_receive_keyngreq = 1,
|
||
aplink_receive_dh_info,
|
||
aplink_receive_aplink_info,
|
||
aplink_receive_ack,
|
||
} aplink_event;
|
||
|
||
typedef struct {
|
||
aplink_state curState;
|
||
aplink_event event;
|
||
const int (*aplink_action)(char *, int);
|
||
aplink_state nextState;
|
||
} aplink_state_change;
|
||
|
||
typedef struct {
|
||
aplink_state curState;
|
||
int stuNum;
|
||
aplink_state_change *form;
|
||
} elink_aplink;
|
||
|
||
typedef struct _iot_device_info {
|
||
unsigned char common_key[16];
|
||
char ssid[32];
|
||
char pwd[32];
|
||
unsigned char dh_key[36];
|
||
unsigned char dh_p[36];
|
||
unsigned char dh_g[12];
|
||
mbedtls_dhm_context dhm_cli;
|
||
elink_aplink e_aplink;
|
||
aplink_event e_event;
|
||
int protected;
|
||
} iot_device_info;
|
||
|
||
typedef struct _iot_rec_type {
|
||
char *rec_string;
|
||
uint8_t type;
|
||
} iot_rec_type;
|
||
|
||
static iot_device_info iot_device_local;
|
||
static mbedtls_ctr_drbg_context ctr_drbg;
|
||
static const char aplink_ver[] = "V1.0";
|
||
|
||
static void *ap_elink_sock = NULL;
|
||
static void *cli_sock = NULL;
|
||
static int aplink_get_ssid_pwd_success = 0;
|
||
static int local_pid = 0;
|
||
|
||
static iot_rec_type type_table[] = {
|
||
{"keyngreq", KEYNGREQ},
|
||
{"dh", DH},
|
||
{"aplink", QPLINK},
|
||
{"ack", ACK},
|
||
{NULL, 0}
|
||
};
|
||
|
||
//State Table : 当前状态 激发事件 回调函数 下一个状态
|
||
static aplink_state_change aplink_table[] = {
|
||
{aplink_idel_state, aplink_receive_keyngreq, iot_device_send_keyngack, aplink_wait_dh_info},
|
||
{aplink_wait_dh_info, aplink_receive_dh_info, iot_device_send_dh, aplink_wait_aplink_info},
|
||
{aplink_wait_aplink_info, aplink_receive_aplink_info, iot_device_send_aplinkget, aplink_wait_ack},
|
||
{aplink_wait_ack, aplink_receive_ack, NULL, aplink_qlink_finish},
|
||
};
|
||
|
||
const char *aplink_version(void)
|
||
{
|
||
return aplink_ver;
|
||
}
|
||
|
||
void Hex2Str(const unsigned char *hex, char *str, int len)
|
||
{
|
||
int i;
|
||
char temp[3];
|
||
|
||
for (i = 0; i < len; i++) {
|
||
sprintf(temp, "%02X", (unsigned char)hex[i]);
|
||
memcpy(&str[i * 2], temp, 2);
|
||
}
|
||
|
||
str[2 * len] = '\0';
|
||
}
|
||
|
||
static void aplink_state_transFer(elink_aplink *aplink, aplink_state state)
|
||
{
|
||
aplink->curState = state;
|
||
}
|
||
|
||
static int aplink_sock_write(void *sockhdl, const char *buf, size_t n)
|
||
{
|
||
size_t nLeft = n;
|
||
size_t nWrite = 0;
|
||
int ret;
|
||
|
||
while (nLeft > 0) {
|
||
ret = sock_send(sockhdl, buf + nWrite, nLeft, 0);
|
||
if (ret != nLeft) {
|
||
log_info("aplink_sock_write error occurred:%d\n", sock_get_error(sockhdl));
|
||
break;
|
||
} else {
|
||
nLeft -= ret;
|
||
nWrite += ret;
|
||
}
|
||
}
|
||
return nWrite == n ? n : -1;
|
||
}
|
||
|
||
static int aplink_eventHandle(elink_aplink *aqlink, const aplink_event event, void *parm)
|
||
{
|
||
aplink_state_change *changeTable = aqlink->form;
|
||
const int (*aplink_action)(char *, int) = NULL;
|
||
aplink_state nextState;
|
||
aplink_state curState = aqlink->curState;
|
||
unsigned something_happen = 0;
|
||
unsigned int i;
|
||
unsigned int ret;
|
||
char send_buf[512];
|
||
unsigned int len;
|
||
void *cli_sock = parm;
|
||
|
||
for (i = 0; i < aqlink->stuNum; i++) {
|
||
if (event == changeTable[i].event && curState == changeTable[i].curState) {
|
||
aplink_action = changeTable[i].aplink_action;
|
||
nextState = changeTable[i].nextState;
|
||
something_happen = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (something_happen) {
|
||
if (aplink_action != NULL) {
|
||
len = aplink_action(send_buf, sizeof(send_buf));
|
||
if (len == -1) {
|
||
return -1;
|
||
}
|
||
|
||
os_time_dly(50);
|
||
|
||
ret = aplink_sock_write(cli_sock, send_buf, len);
|
||
if (ret == -1) {
|
||
log_info("sock_sendto err!!!");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
aplink_state_transFer(aqlink, nextState);
|
||
something_happen = 0;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
static void aplink_init(elink_aplink *aqlink, aplink_state curState, const int num, aplink_state_change *form)
|
||
{
|
||
aqlink->form = form;
|
||
aqlink->stuNum = num;
|
||
aqlink->curState = curState;
|
||
return;
|
||
}
|
||
|
||
static int dh_calculate_public_key(mbedtls_dhm_context *context, const char *p, const char *g, unsigned char *public)
|
||
{
|
||
int ret = 0;
|
||
const char *pers = "aplink";
|
||
unsigned char cli_pub[16];
|
||
mbedtls_entropy_context entropy;
|
||
|
||
mbedtls_dhm_init(context);
|
||
mbedtls_entropy_init(&entropy);
|
||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||
|
||
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
||
(const unsigned char *) pers,
|
||
strlen(pers))) != 0) {
|
||
|
||
mbedtls_printf("error!!! mbedtls_ctr_drbg_seed returned %d\n", ret);
|
||
goto EXIT;
|
||
}
|
||
|
||
mbedtls_mpi_read_string(&(context->P), 16, p);
|
||
mbedtls_mpi_read_string(&(context->G), 10, g);
|
||
context->len = mbedtls_mpi_size(&(context->P));
|
||
|
||
ret = mbedtls_dhm_make_public(context, 16, cli_pub, sizeof(cli_pub), mbedtls_ctr_drbg_random, &ctr_drbg);
|
||
if (ret != 0) {
|
||
mbedtls_printf(" error!!! mbedtls_dhm_make_public %d\n", ret);
|
||
goto EXIT;
|
||
}
|
||
|
||
memcpy(public, cli_pub, sizeof(cli_pub));
|
||
|
||
mbedtls_entropy_free(&entropy);
|
||
/* mbedtls_ctr_drbg_free(&ctr_drbg); */
|
||
return 0;
|
||
|
||
EXIT:
|
||
mbedtls_dhm_free(context);
|
||
mbedtls_entropy_free(&entropy);
|
||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||
return -1;
|
||
}
|
||
|
||
void aplink_cfg_start(void)
|
||
{
|
||
iot_device_enter_ap_mode();
|
||
}
|
||
|
||
static void wifi_set_lan_setting_info(void)
|
||
{
|
||
struct lan_setting lan_setting_info = {
|
||
|
||
.WIRELESS_IP_ADDR0 = 192,
|
||
.WIRELESS_IP_ADDR1 = 168,
|
||
.WIRELESS_IP_ADDR2 = 1,
|
||
.WIRELESS_IP_ADDR3 = 1,
|
||
|
||
.WIRELESS_NETMASK0 = 255,
|
||
.WIRELESS_NETMASK1 = 255,
|
||
.WIRELESS_NETMASK2 = 255,
|
||
.WIRELESS_NETMASK3 = 0,
|
||
|
||
.WIRELESS_GATEWAY0 = 192,
|
||
.WIRELESS_GATEWAY1 = 168,
|
||
.WIRELESS_GATEWAY2 = 1,
|
||
.WIRELESS_GATEWAY3 = 1,
|
||
|
||
.SERVER_IPADDR1 = 192,
|
||
.SERVER_IPADDR2 = 168,
|
||
.SERVER_IPADDR3 = 1,
|
||
.SERVER_IPADDR4 = 1,
|
||
|
||
.CLIENT_IPADDR1 = 192,
|
||
.CLIENT_IPADDR2 = 168,
|
||
.CLIENT_IPADDR3 = 1,
|
||
.CLIENT_IPADDR4 = 2,
|
||
|
||
.SUB_NET_MASK1 = 255,
|
||
.SUB_NET_MASK2 = 255,
|
||
.SUB_NET_MASK3 = 255,
|
||
.SUB_NET_MASK4 = 0,
|
||
};
|
||
net_set_lan_info(&lan_setting_info);
|
||
}
|
||
|
||
static void iot_device_enter_ap_mode(void)
|
||
{
|
||
u8 mac[6];
|
||
char device_mac[32];
|
||
|
||
wifi_get_mac(mac);
|
||
|
||
sprintf(device_mac, IOT_SSID, VENDOR, mac[0], mac[1]);
|
||
|
||
log_info("aplink ssid: %s", device_mac);
|
||
|
||
wifi_set_lan_setting_info(); //STA转AP模式,需要重新配置一下IP信息和DHCP池起始分配地址
|
||
wifi_enter_ap_mode(device_mac, IOT_PWD);
|
||
|
||
ap_elink_start();
|
||
}
|
||
|
||
/* void iot_device_enter_sta_mode(const char *ssid, const char *pwd) */
|
||
void iot_device_enter_sta_mode(char *ssid, char *pwd)
|
||
{
|
||
wifi_set_sta_connect_timeout(0);
|
||
wifi_enter_sta_mode(ssid, pwd);
|
||
wifi_store_mode_info(STA_MODE, ssid, pwd);
|
||
}
|
||
|
||
static void ap_elink_tcp_init(void *priv)
|
||
{
|
||
struct sockaddr_in client_addr;
|
||
socklen_t socketLength = sizeof(struct sockaddr_in);
|
||
|
||
ap_elink_sock = sock_reg(AF_INET, SOCK_STREAM, 0, NULL, NULL);
|
||
if (ap_elink_sock == NULL) {
|
||
log_info("ap_elink_tcp_init socket error");
|
||
goto EXIT;
|
||
}
|
||
|
||
if (sock_set_reuseaddr(ap_elink_sock)) {
|
||
log_info("sock_set_reuseaddr error");
|
||
goto EXIT;
|
||
}
|
||
|
||
struct sockaddr _ss;
|
||
struct sockaddr_in *dest_addr = (struct sockaddr_in *)&_ss;
|
||
dest_addr->sin_family = AF_INET;
|
||
dest_addr->sin_addr.s_addr = htonl(INADDR_ANY);
|
||
dest_addr->sin_port = htons(ELINK_SRV_PORT);
|
||
|
||
if (sock_bind(ap_elink_sock, (struct sockaddr *)&_ss, sizeof(_ss))) {
|
||
log_info("ap_elink_tcp_init bind error");
|
||
goto EXIT;
|
||
}
|
||
|
||
if (sock_listen(ap_elink_sock, 5)) {
|
||
log_info("ap_elink_tcp_init sock_listen error");
|
||
goto EXIT;
|
||
}
|
||
|
||
log_info("sock_accept starting......................");
|
||
cli_sock = sock_accept(ap_elink_sock, (struct sockaddr *)&client_addr, &socketLength, NULL, NULL);
|
||
flag = 0;
|
||
if (cli_sock == NULL) {
|
||
log_info("ap_elink_tcp_init sock_accept error");
|
||
goto EXIT;
|
||
}
|
||
|
||
log_info("Successfully connected. Network configuration is starting!!!.....................");
|
||
|
||
memset(&iot_device_local, 0, sizeof(iot_device_info));
|
||
|
||
aplink_init(&(iot_device_local.e_aplink), aplink_idel_state, sizeof(aplink_table) / sizeof(aplink_state_change), aplink_table);
|
||
|
||
extern int wifi_is_on(void);
|
||
while (wifi_is_on() == 0) {
|
||
os_time_dly(1);
|
||
}
|
||
|
||
iot_interact_to_app(cli_sock);
|
||
|
||
if (ap_elink_sock) {
|
||
sock_unreg(ap_elink_sock);
|
||
ap_elink_sock = NULL;
|
||
}
|
||
|
||
EXIT:
|
||
if (ap_elink_sock) {
|
||
sock_unreg(ap_elink_sock);
|
||
ap_elink_sock = NULL;
|
||
}
|
||
}
|
||
|
||
static int ap_elink_start(void)
|
||
{
|
||
if (thread_fork("ap_elink_tcp_init", 17, 2024, 0, &local_pid, ap_elink_tcp_init, NULL) != OS_NO_ERR) {
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static void iot_interact_to_app(void *client_sock)
|
||
{
|
||
int recv_len = 0;
|
||
unsigned char recv_buf[1024] = {0};
|
||
unsigned char decode_buf[512] = {0};
|
||
int decode_len = 0;
|
||
int err = 0;
|
||
|
||
for (;;) {
|
||
recv_len = sock_recvfrom(client_sock, recv_buf, sizeof(recv_buf), 0, NULL, NULL);
|
||
if ((recv_len != -1) && (recv_len != 0)) {
|
||
if (iot_device_local.protected) {
|
||
/* put_buf(recv_buf, recv_len); */
|
||
|
||
decode_len = aes_cbc_decode(recv_buf + 8, recv_len - 8, iot_device_local.common_key, decode_buf);
|
||
decode_buf[decode_len] = '\0';
|
||
/* put_buf(iot_device_local.common_key, 16); */
|
||
log_info("recv string : %s", decode_buf);
|
||
err = iot_device_rec_handle((char *)decode_buf);
|
||
if (err == -1) {
|
||
log_info("iot_device_rec_handle err!!!\n");
|
||
goto EXIT;
|
||
}
|
||
} else {
|
||
recv_buf[recv_len] = '\0';
|
||
log_info("recv string : %s", recv_buf + 8);
|
||
err = iot_device_rec_handle((char *)(recv_buf + 8));
|
||
if (err == -1) {
|
||
log_info("iot_device_rec_handle err!!!\n");
|
||
goto EXIT;
|
||
}
|
||
}
|
||
|
||
memset(recv_buf, 0, sizeof(recv_buf));
|
||
|
||
os_time_dly(30);
|
||
} else {
|
||
log_info("sock_recvfrom err!!!");
|
||
goto EXIT;
|
||
}
|
||
|
||
err = aplink_eventHandle(&(iot_device_local.e_aplink), iot_device_local.e_event, client_sock);
|
||
if (err == -1) {
|
||
log_info("aplink_eventHandle err!!!\n");
|
||
goto EXIT;
|
||
}
|
||
|
||
/* if(iot_device_local.e_aplink.curState == aplink_qlink_finish) */
|
||
if (iot_device_local.e_aplink.curState == aplink_wait_ack) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
aplink_get_ssid_pwd_success = 1;
|
||
log_info("Successfully obtained distribution network information.Connecting to network..........");
|
||
log_info("get ssid: %s, pwd: %s", iot_device_local.ssid, iot_device_local.pwd);
|
||
|
||
elink_aplink_set_ssid_pwd(iot_device_local.ssid, iot_device_local.pwd);
|
||
|
||
EXIT:
|
||
/* sock_unreg(client_sock); */
|
||
|
||
if (!aplink_get_ssid_pwd_success) {
|
||
log_info("Failed to connect to the Internet, please help me connect to the Internet again");
|
||
}
|
||
|
||
aplink_get_ssid_pwd_success = 0;
|
||
}
|
||
|
||
const static uint8_t check_rec_type(const char *string)
|
||
{
|
||
iot_rec_type *type_t = type_table;
|
||
while (type_t->rec_string) {
|
||
if (0 == strcmp(string, type_t->rec_string)) {
|
||
return type_t->type;
|
||
}
|
||
|
||
type_t++;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
static int iot_device_rec_handle(const char *object)
|
||
{
|
||
json_object *json = NULL;
|
||
json_object *result = NULL;
|
||
char *type = NULL;
|
||
int len = 0;
|
||
char dh_key[32];
|
||
unsigned char dh_cli_key[32];
|
||
unsigned char dh_ap_key[32];
|
||
char dh_p[64];
|
||
char dh_g[12];
|
||
unsigned char rec_buf[64];
|
||
|
||
if (NULL == object) {
|
||
log_info("Input is empty");
|
||
return -1;
|
||
}
|
||
|
||
json = json_tokener_parse(object);
|
||
if (NULL == json) {
|
||
log_info("Parsing error");
|
||
return -1;
|
||
}
|
||
|
||
type = (char *)json_object_get_string(json_object_object_get(json, "type"));
|
||
|
||
switch (check_rec_type(type)) {
|
||
case KEYNGREQ :
|
||
log_info("%s\n", object);
|
||
result = json_object_array_get_idx(json_object_object_get(json, "keymodelist"), 0);
|
||
log_info("the keymode is :%s\n", json_object_get_string(json_object_object_get(result, "keymode")));
|
||
iot_device_local.protected = 0;
|
||
iot_device_local.e_event = aplink_receive_keyngreq;
|
||
break;
|
||
|
||
case DH :
|
||
log_info("DH");
|
||
log_info("%s\n", object);
|
||
json_object_object_get_ex(json, "data", &result);
|
||
log_info("dh_key : %s\n", json_object_get_string(json_object_object_get(result, "dh_key")));
|
||
|
||
strcpy((char *)iot_device_local.dh_p, json_object_get_string(json_object_object_get(result, "dh_p")));
|
||
strcpy((char *)iot_device_local.dh_g, json_object_get_string(json_object_object_get(result, "dh_g")));
|
||
log_info("dh_p : %s\n", iot_device_local.dh_p);
|
||
log_info("dh_g : %s\n", iot_device_local.dh_g);
|
||
|
||
len = dh_base64_decode(iot_device_local.dh_p, rec_buf);
|
||
Hex2Str(rec_buf, dh_p, len);
|
||
log_info("dh_p : %s", dh_p);
|
||
|
||
len = dh_base64_decode((unsigned char *)iot_device_local.dh_g, rec_buf);
|
||
Hex2Str(rec_buf, dh_g, len);
|
||
log_info("dh_g : %s", dh_g);
|
||
|
||
dh_calculate_public_key(&(iot_device_local.dhm_cli), dh_p, dh_g, dh_ap_key);
|
||
|
||
dh_base64_encode(dh_ap_key, 16, iot_device_local.dh_key);
|
||
log_info("public_key encode : %s", iot_device_local.dh_key);
|
||
|
||
len = dh_base64_decode((unsigned char *)json_object_get_string(json_object_object_get(result, "dh_key")), dh_cli_key);
|
||
calculate_common_key(&(iot_device_local.dhm_cli), dh_cli_key, (char *)iot_device_local.common_key);
|
||
/* put_buf(iot_device_local.common_key, 16); */
|
||
|
||
iot_device_local.protected = 1;
|
||
iot_device_local.e_event = aplink_receive_dh_info;
|
||
os_time_dly(30);
|
||
break;
|
||
|
||
case QPLINK :
|
||
log_info("QPLINK");
|
||
log_info("%s\n", object);
|
||
if (0 != strcmp(json_object_get_string(json_object_object_get(json, "result")), "allow")) {
|
||
log_info("Failed to obtain information");
|
||
break;
|
||
}
|
||
|
||
json_object_object_get_ex(json, "wifi", &result);
|
||
|
||
strcpy(iot_device_local.ssid, json_object_get_string(json_object_object_get(result, "ssid")));
|
||
strcpy(iot_device_local.pwd, json_object_get_string(json_object_object_get(result, "password")));
|
||
log_info("ssid : %s\n", iot_device_local.ssid);
|
||
log_info("password : %s\n", iot_device_local.pwd);
|
||
iot_device_local.protected = 0;
|
||
iot_device_local.e_event = aplink_receive_aplink_info;
|
||
break;
|
||
|
||
case ACK :
|
||
log_info("ACK");
|
||
log_info("%s\n", object);
|
||
iot_device_local.e_event = aplink_receive_ack;
|
||
break;
|
||
|
||
default:
|
||
log_info("Data is not defined");
|
||
break;
|
||
}
|
||
|
||
json_object_put(json);
|
||
|
||
return 0;
|
||
}
|
||
|
||
static int dh_p_base64_encode(const unsigned char *p, const int p_len, unsigned char *output)
|
||
{
|
||
int out_len;
|
||
|
||
memcpy(output, base64_encode(p, p_len, &out_len), out_len);
|
||
*(output + out_len) = '\0';
|
||
|
||
return out_len;
|
||
}
|
||
|
||
static int dh_base64_encode(const unsigned char *input, const int len, unsigned char *output)
|
||
{
|
||
int out_len;
|
||
|
||
memcpy(output, base64_encode(input, len, &out_len), out_len);
|
||
*(output + out_len) = '\0';
|
||
|
||
return out_len;
|
||
}
|
||
|
||
static int dh_g_base64_encode(const unsigned char *g, const int g_len, unsigned char *output)
|
||
{
|
||
int out_len;
|
||
|
||
memcpy(output, base64_encode(g, g_len, &out_len), out_len);
|
||
*(output + out_len) = '\0';
|
||
|
||
return out_len;
|
||
}
|
||
|
||
static int calculate_common_key(mbedtls_dhm_context *context, unsigned char *srv_pub, char *out_put)
|
||
{
|
||
unsigned char secret[16];
|
||
int ret;
|
||
size_t n = 0;
|
||
|
||
/* mbedtls_ctr_drbg_context ctr_drbg; */
|
||
|
||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||
|
||
ret = mbedtls_dhm_read_public(context, srv_pub, 16);
|
||
|
||
ret = mbedtls_dhm_calc_secret(context, secret, sizeof(secret), &n, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||
if (ret != 0) {
|
||
mbedtls_printf(" failed\n! mbedtls_dhm_calc_secret %d\n", ret);
|
||
return -1;
|
||
}
|
||
|
||
memcpy(out_put, secret, 16);
|
||
|
||
mbedtls_dhm_free(context);
|
||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||
|
||
return 0;
|
||
}
|
||
|
||
static int dh_base64_decode(const unsigned char *input, unsigned char *output)
|
||
{
|
||
int out_len;
|
||
|
||
memcpy(output, base64_decode(input, strlen((char *)input), &out_len), out_len);
|
||
/* put_buf(output, out_len); */
|
||
|
||
return out_len;
|
||
}
|
||
|
||
static int aes_cbc_encode(unsigned char *input_buf, unsigned int input_len, unsigned char *key, unsigned char *encode_buf)
|
||
{
|
||
|
||
unsigned char iv[16] = {0};
|
||
unsigned int encode_len;
|
||
|
||
CT_AES_CBC_Encrypt(input_buf, input_len, key, 16, iv, 16, encode_buf, &encode_len);
|
||
return encode_len;
|
||
}
|
||
|
||
static int aes_cbc_decode(unsigned char *input_buf, unsigned int input_len, unsigned char *key, unsigned char *decode_buf)
|
||
{
|
||
unsigned char iv[16] = {0};
|
||
unsigned int decode_len;
|
||
|
||
CT_AES_CBC_Decrypt(input_buf, input_len, key, 16, iv, 16, decode_buf, &decode_len);
|
||
return decode_len;
|
||
}
|
||
|
||
static int aqlink_package_assembly(char *data, int data_len, char *package, int package_buf_len)
|
||
{
|
||
if (data == NULL || data_len <= 0 || package == NULL || (data_len + 8) > package_buf_len) {
|
||
return -1;
|
||
}
|
||
|
||
package[0] = 0x3f;
|
||
package[1] = 0x72;
|
||
package[2] = 0x1f;
|
||
package[3] = 0xb5;
|
||
|
||
package[4] = (u8)(((u32)data_len >> 24) & 0x00ff);
|
||
package[5] = (u8)(((u32)data_len >> 16) & 0x00ff);
|
||
package[6] = (u8)(((u32)data_len >> 8) & 0x00ff);
|
||
package[7] = (u8)(((u32)data_len >> 0) & 0x00ff);
|
||
|
||
memcpy(package + 8, data, data_len);
|
||
|
||
return (data_len + 8);
|
||
}
|
||
|
||
const static int iot_device_send_keyngack(char *buf, int buf_len)
|
||
{
|
||
char temp_buf[512];
|
||
unsigned int len;
|
||
|
||
char *keyngack = "{\"type\":\"keyngack\",\"sequence\":1,\"keymode\":\"dh\"}";
|
||
|
||
len = aqlink_package_assembly(keyngack, strlen(keyngack), buf, buf_len);
|
||
|
||
return len;
|
||
}
|
||
|
||
const static int iot_device_send_dh(char *buf, int buf_len)
|
||
{
|
||
char temp_buf[256];
|
||
char key[64];
|
||
char dh_p[64];
|
||
char dh_g[64];
|
||
unsigned int len;
|
||
|
||
snprintf(temp_buf, sizeof(temp_buf), DH_INFO,
|
||
iot_device_local.dh_key,
|
||
iot_device_local.dh_p,
|
||
iot_device_local.dh_g);
|
||
|
||
log_info("iot_device_send_dh : %s", temp_buf);
|
||
|
||
len = aqlink_package_assembly(temp_buf, strlen(temp_buf), buf, buf_len);
|
||
|
||
return len;
|
||
}
|
||
|
||
const static int iot_device_send_aplinkget(char *buf, int buf_len)
|
||
{
|
||
unsigned int len;
|
||
unsigned char encode_buf[512];
|
||
int encode_len;
|
||
|
||
char *aplinkget = "{\"type\":\"aplinkget\",\"sequence\":3,\"result\":\"get\"}";
|
||
|
||
encode_len = aes_cbc_encode((unsigned char *)aplinkget, strlen((char *)aplinkget), iot_device_local.common_key, encode_buf);
|
||
|
||
len = aqlink_package_assembly((char *)encode_buf, encode_len, buf, buf_len);
|
||
|
||
/* char decode_buf[256]; */
|
||
/* int decode_len; */
|
||
/* decode_len = aes_cbc_decode(encode_buf, encode_len, iot_device_local.common_key, decode_buf); */
|
||
/* decode_buf[decode_len] = '\0'; */
|
||
/* log_info("aplinkget decode: %s", decode_buf); */
|
||
|
||
return len;
|
||
}
|
||
|
||
void qlink_cfg_stop(void)
|
||
{
|
||
if (ap_elink_sock) {
|
||
flag = 1;
|
||
sock_set_quit(ap_elink_sock);
|
||
while (flag) {
|
||
os_time_dly(20);
|
||
}
|
||
sock_unreg(ap_elink_sock);
|
||
ap_elink_sock = NULL;
|
||
}
|
||
}
|