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