1 /*
2 * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3 */
4
5 #include "amp_platform.h"
6 #include "aos_system.h"
7 #include "amp_defines.h"
8 #include "aiot_state_api.h"
9 #include "aiot_sysdep_api.h"
10 #include "aiot_dynreg_api.h"
11 #include "aiot_mqtt_api.h"
12 #include "module_aiot.h"
13
14 #define MOD_STR "AIOT_DYNREG"
15
16 /* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
17 extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
18
19 /* 位于external/ali_ca_cert.c中的服务器证书 */
20 extern const char *ali_ca_cert;
21
aiot_app_dynreg_recv_handler(void * handle,const aiot_dynreg_recv_t * packet,void * userdata)22 void aiot_app_dynreg_recv_handler(void *handle, const aiot_dynreg_recv_t *packet, void *userdata)
23 {
24 JSValue *js_cb_ref = (JSValue *)userdata;
25 JSContext *ctx = js_get_context();
26 if (packet->type == AIOT_DYNREGRECV_STATUS_CODE) {
27 amp_debug(MOD_STR, "dynreg rsp code = %d", packet->data.status_code.code);
28 } else {
29 if (packet->type == AIOT_DYNREGRECV_DEVICE_INFO) {
30 amp_debug(MOD_STR, "dynreg DS = %s", packet->data.device_info.device_secret);
31 aos_kv_set(AMP_CUSTOMER_DEVICESECRET, packet->data.device_info.device_secret, strlen(packet->data.device_info.device_secret), 1);
32 JSValue sec = JS_NewString(ctx, packet->data.device_info.device_secret);
33 JSValue val = JS_Call(ctx, *js_cb_ref, JS_UNDEFINED, 1, &sec);
34 JS_FreeValue(ctx, val);
35 JS_FreeValue(ctx, sec);
36 JS_FreeValue(ctx, *js_cb_ref);
37 }
38 }
39 }
40
aiot_dynreg_http(JSValue * js_cb_ref)41 int32_t aiot_dynreg_http(JSValue *js_cb_ref)
42 {
43 int32_t res = STATE_SUCCESS;
44 char *auth_url = "iot-auth.cn-shanghai.aliyuncs.com"; /* 阿里云平台上海站点的域名后缀 */
45 char host[100] = {0}; /* 用这个数组拼接设备连接的云平台站点全地址, 规则是 ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com */
46 uint16_t port = 443; /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
47 aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */
48 /* get device tripple info */
49 char product_key[IOTX_PRODUCT_KEY_LEN] = {0};
50 char product_secret[IOTX_PRODUCT_SECRET_LEN] = {0};
51 char device_name[IOTX_DEVICE_NAME_LEN] = {0};
52 char device_secret[IOTX_DEVICE_SECRET_LEN] = {0};
53 int productkey_len = IOTX_PRODUCT_KEY_LEN;
54 int productsecret_len = IOTX_PRODUCT_SECRET_LEN;
55 int devicename_len = IOTX_DEVICE_NAME_LEN;
56 int devicesecret_len = IOTX_DEVICE_SECRET_LEN;
57 aos_kv_get(AMP_CUSTOMER_PRODUCTKEY, product_key, &productkey_len);
58 aos_kv_get(AMP_CUSTOMER_PRODUCTSECRET, product_secret, &productsecret_len);
59 aos_kv_get(AMP_CUSTOMER_DEVICENAME, device_name, &devicename_len);
60 amp_debug(MOD_STR, "dev info pk: %s, ps: %s, dn: %s", product_key, product_secret, device_name);
61 /* end get device tripple info */
62 /* 配置SDK的底层依赖 */
63 aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
64 /* 配置SDK的日志输出 */
65 // aiot_state_set_logcb(demo_state_logcb);
66 /* 创建SDK的安全凭据, 用于建立TLS连接 */
67 memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
68 cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA证书校验MQTT服务端 */
69 cred.max_tls_fragment = 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */
70 cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */
71 cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */
72 cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */
73 aos_kv_get(AMP_CUSTOMER_DEVICESECRET, device_secret, &devicesecret_len);
74 if (device_secret[0] == '\0' || device_secret[IOTX_DEVICE_SECRET_LEN] != '\0') {
75 if (product_secret[0] == '\0' || product_secret[IOTX_PRODUCT_SECRET_LEN] != '\0') {
76 amp_error(MOD_STR, "need dynamic register, product secret is null");
77 return -1;
78 }
79 void *dynreg_handle = NULL;
80 dynreg_handle = aiot_dynreg_init();
81 if (dynreg_handle == NULL) {
82 amp_error(MOD_STR, "dynreg handle is null");
83 aos_task_exit(0);
84 return NULL;
85 }
86 /* 配置网络连接的安全凭据, 上面已经创建好了 */
87 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_NETWORK_CRED, (void *)&cred);
88 /* 配置MQTT服务器地址 */
89 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_HOST, (void *)auth_url);
90 /* 配置MQTT服务器端口 */
91 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_PORT, (void *)&port);
92 /* 配置设备productKey */
93 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_PRODUCT_KEY, (void *)product_key);
94 /* 配置设备productSecret */
95 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_PRODUCT_SECRET, (void *)product_secret);
96 /* 配置设备deviceName */
97 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_DEVICE_NAME, (void *)device_name);
98 /* 配置DYNREG默认消息接收回调函数 */
99 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_RECV_HANDLER, (void *)aiot_app_dynreg_recv_handler);
100 /* 配置DYNREG默认消息接收回调函数参数 */
101 aiot_dynreg_setopt(dynreg_handle, AIOT_DYNREGOPT_USERDATA, js_cb_ref);
102 res = aiot_dynreg_send_request(dynreg_handle);
103 if (res < STATE_SUCCESS) {
104 amp_error(MOD_STR, "dynamic register send fail res = %d\n\r", res);
105 aiot_dynreg_deinit(&dynreg_handle);
106 return -1;
107 }
108 res = aiot_dynreg_recv(dynreg_handle);
109 if (res < STATE_SUCCESS) {
110 amp_error(MOD_STR, "dynamic register recv fail res = %d\n\r", res);
111 aiot_dynreg_deinit(&dynreg_handle);
112 return -1;
113 }
114 aos_kv_get(AMP_CUSTOMER_DEVICESECRET, device_secret, &devicesecret_len);
115 res = aiot_dynreg_deinit(&dynreg_handle);
116 if (res < STATE_SUCCESS) {
117 amp_error(MOD_STR, "dynamic register deinit fail res = %d\n\r", res);
118 return -1;
119 }
120 } else {
121 amp_debug(MOD_STR, "device is already activated");
122 return -1;
123 }
124 return STATE_SUCCESS;
125 }
126