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