1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "aiot_dm_api.h"
6 #include "aiot_mqtt_api.h"
7 #include "aiot_state_api.h"
8 #include "aiot_sysdep_api.h"
9 #include "py/builtin.h"
10 #include "py/obj.h"
11 #include "py/runtime.h"
12 #include "py/stackctrl.h"
13
14 /* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
15 extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
16
17 /* 位于external/ali_ca_cert.c中的服务器证书 */
18 extern const char *ali_ca_cert;
19
20 static uint8_t g_mqtt_process_thread_running = 0;
21 static uint8_t g_mqtt_recv_thread_running = 0;
22
23 void *dm_handle = NULL;
24 void *mqtt_handle = NULL;
25
26 #define EXAMPLE_MASTER_DEVID (0)
27
28 #define EXAMPLE_YIELD_TIMEOUT_MS (200)
29
30 #define RETRY_NUM 5
31
32 typedef struct {
33 int master_devid;
34 int cloud_connected;
35 int master_initialized;
36 } user_example_ctx_t;
37
38 typedef enum {
39 ON_CONNECT = 1,
40 ON_DISCONNECT = 3,
41 ON_SERVICE = 5,
42 ON_PROPS = 7,
43 ON_CLOSE = 2,
44 ON_ERROR = 4,
45 } lk_callback_func_t;
46
47 typedef enum {
48 ITE_CONNECT_SUCC = 1,
49 ITE_DISCONNECTED = 3,
50 ITE_SERVICE_REQUEST = 5,
51 ITE_PROPERTY_SET = 7,
52 ITE_REPORT_REPLY = 2,
53 ITE_TRIGGER_EVENT_REPLY = 4,
54 } lk_callback_reg_func_t;
55
56 static user_example_ctx_t g_user_example_ctx;
57
58 static mp_obj_t on_connected;
59 static mp_obj_t on_disconnect;
60 static mp_obj_t on_report_reply;
61 static mp_obj_t on_event_reply;
62 static mp_obj_t on_property_set;
63 static mp_obj_t on_async_service;
64
65 /* 日志回调函数, SDK的日志会从这里输出 */
py_demo_state_logcb(int32_t code,char * message)66 int32_t py_demo_state_logcb(int32_t code, char *message)
67 {
68 printf("%s", message);
69 return 0;
70 }
71
user_service_request_event_handler(const int devid,const char * serviceid,const int serviceid_len,const char * request,const int request_len,char ** response,int * response_len)72 static int user_service_request_event_handler(
73 const int devid, const char *serviceid, const int serviceid_len,
74 const char *request, const int request_len, char **response,
75 int *response_len)
76 {
77 return 0;
78 }
79
80 /** recv property post response message from cloud **/
user_report_reply_event_handler(const int devid,const int msgid,const int code,const char * reply,const int reply_len)81 static int user_report_reply_event_handler(const int devid, const int msgid,
82 const int code, const char *reply,
83 const int reply_len)
84 {
85 return 0;
86 }
87
88 /** recv event post response message from cloud **/
user_trigger_event_reply_event_handler(const int devid,const int msgid,const int code,const char * eventid,const int eventid_len,const char * message,const int message_len)89 static int user_trigger_event_reply_event_handler(
90 const int devid, const int msgid, const int code, const char *eventid,
91 const int eventid_len, const char *message, const int message_len)
92 {
93 return 0;
94 }
95
user_property_set_event_handler(const int devid,const char * request,const int request_len)96 static int user_property_set_event_handler(const int devid, const char *request,
97 const int request_len)
98 {
99 return 0;
100 }
101
102 /* MQTT事件回调函数, 当网络连接/重连/断开时被触发,
103 * 事件定义见core/aiot_mqtt_api.h */
demo_mqtt_event_handler(void * handle,const aiot_mqtt_event_t * event,void * userdata)104 void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event,
105 void *userdata)
106 {
107 switch (event->type) {
108 /* SDK因为用户调用了aiot_mqtt_connect()接口, 与mqtt服务器建立连接已成功
109 */
110 case AIOT_MQTTEVT_CONNECT:
111 {
112 printf("AIOT_MQTTEVT_CONNECT\n");
113 if (mp_obj_is_fun(on_connected)) {
114 mp_call_function_0(on_connected);
115 }
116 }
117 break;
118
119 /* SDK因为网络状况被动断连后, 自动发起重连已成功 */
120 case AIOT_MQTTEVT_RECONNECT:
121 {
122 printf("AIOT_MQTTEVT_RECONNECT\n");
123 }
124 break;
125
126 /* SDK因为网络的状况而被动断开了连接, network是底层读写失败,
127 * heartbeat是没有按预期得到服务端心跳应答 */
128 case AIOT_MQTTEVT_DISCONNECT:
129 {
130 char *cause = (event->data.disconnect ==
131 AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT)
132 ? ("network disconnect")
133 : ("heartbeat disconnect");
134 printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause);
135 }
136 break;
137
138 default:
139 {
140 }
141 }
142 }
143
144 /* 执行aiot_mqtt_process的线程, 包含心跳发送和QoS1消息重发 */
demo_mqtt_process_thread(void * args)145 void *demo_mqtt_process_thread(void *args)
146 {
147 int32_t res = STATE_SUCCESS;
148
149 printf("********aiot_mqtt_process******\r\n");
150
151 while (g_mqtt_process_thread_running) {
152 res = aiot_mqtt_process(args);
153 if (res == STATE_USER_INPUT_EXEC_DISABLED) {
154 break;
155 }
156 aos_msleep(1000);
157 }
158 return NULL;
159 }
160
161 /* 执行aiot_mqtt_recv的线程, 包含网络自动重连和从服务器收取MQTT消息 */
demo_mqtt_recv_thread(void * args)162 void *demo_mqtt_recv_thread(void *args)
163 {
164 int32_t res = STATE_SUCCESS;
165
166 while (g_mqtt_recv_thread_running) {
167 res = aiot_mqtt_recv(args);
168 if (res < STATE_SUCCESS) {
169 if (res == STATE_USER_INPUT_EXEC_DISABLED) {
170 break;
171 }
172 aos_msleep(1000);
173 }
174 }
175 return NULL;
176 }
177
178 /* 用户数据接收处理回调函数 */
demo_dm_recv_handler(void * dm_handle,const aiot_dm_recv_t * recv,void * userdata)179 static void demo_dm_recv_handler(void *dm_handle, const aiot_dm_recv_t *recv,
180 void *userdata)
181 {
182 printf("demo_dm_recv_handler, type = %d\r\n", recv->type);
183
184 switch (recv->type) {
185 /* 属性上报, 事件上报, 获取期望属性值或者删除期望属性值的应答 */
186 case AIOT_DMRECV_GENERIC_REPLY:
187 {
188 printf("msg_id = %d, code = %d, data = %.*s, message = %.*s\r\n",
189 recv->data.generic_reply.msg_id,
190 recv->data.generic_reply.code,
191 recv->data.generic_reply.data_len,
192 recv->data.generic_reply.data,
193 recv->data.generic_reply.message_len,
194 recv->data.generic_reply.message);
195 }
196 break;
197
198 /* 属性设置 */
199 case AIOT_DMRECV_PROPERTY_SET:
200 {
201 printf("msg_id = %ld, params = %.*s\r\n",
202 (unsigned long)recv->data.property_set.msg_id,
203 recv->data.property_set.params_len,
204 recv->data.property_set.params);
205
206 if (mp_obj_is_fun(on_property_set)) {
207 callback_to_python(
208 on_property_set,
209 mp_obj_new_str(recv->data.property_set.params,
210 recv->data.property_set.params_len));
211 } else {
212 printf("on_property_set is not function \r\n");
213 }
214 /* TODO: 以下代码演示如何对来自云平台的属性设置指令进行应答,
215 * 用户可取消注释查看演示效果 */
216
217 {
218 aiot_dm_msg_t msg;
219
220 memset(&msg, 0, sizeof(aiot_dm_msg_t));
221 msg.type = AIOT_DMMSG_PROPERTY_SET_REPLY;
222 msg.data.property_set_reply.msg_id =
223 recv->data.property_set.msg_id;
224 msg.data.property_set_reply.code = 200;
225 msg.data.property_set_reply.data = "{}";
226 int32_t res = aiot_dm_send(dm_handle, &msg);
227 if (res < 0) {
228 printf("aiot_dm_send failed\r\n");
229 }
230 }
231 }
232 break;
233
234 /* 异步服务调用 */
235 case AIOT_DMRECV_ASYNC_SERVICE_INVOKE:
236 {
237 printf("msg_id = %ld, service_id = %s, params = %.*s\r\n",
238 (unsigned long)recv->data.async_service_invoke.msg_id,
239 recv->data.async_service_invoke.service_id,
240 recv->data.async_service_invoke.params_len,
241 recv->data.async_service_invoke.params);
242
243 if (mp_obj_is_fun(on_async_service)) {
244 mp_obj_t dict = mp_obj_new_dict(2);
245 mp_obj_dict_store(
246 dict, MP_OBJ_NEW_QSTR(qstr_from_str("id")),
247 mp_obj_new_strn(
248 recv->data.async_service_invoke.service_id));
249 mp_obj_dict_store(
250 dict, MP_OBJ_NEW_QSTR(qstr_from_str("param")),
251 mp_obj_new_str(recv->data.async_service_invoke.params,
252 recv->data.async_service_invoke.params_len));
253 callback_to_python(on_async_service, dict);
254 }
255
256 /* TODO: 以下代码演示如何对来自云平台的异步服务调用进行应答,
257 * 用户可取消注释查看演示效果
258 *
259 * 注意: 如果用户在回调函数外进行应答, 需要自行保存msg_id,
260 * 因为回调函数入参在退出回调函数后将被SDK销毁, 不可以再访问到
261 */
262
263 /*
264 {
265 aiot_dm_msg_t msg;
266
267 memset(&msg, 0, sizeof(aiot_dm_msg_t));
268 msg.type = AIOT_DMMSG_ASYNC_SERVICE_REPLY;
269 msg.data.async_service_reply.msg_id =
270 recv->data.async_service_invoke.msg_id;
271 msg.data.async_service_reply.code = 200;
272 msg.data.async_service_reply.service_id =
273 "ToggleLightSwitch"; msg.data.async_service_reply.data =
274 "{\"dataA\": 20}"; int32_t res = aiot_dm_send(dm_handle,
275 &msg); if (res < 0) { printf("aiot_dm_send failed\r\n");
276 }
277 }
278 */
279 }
280 break;
281
282 /* 同步服务调用 */
283 case AIOT_DMRECV_SYNC_SERVICE_INVOKE:
284 {
285 printf(
286 "msg_id = %ld, rrpc_id = %s, service_id = %s, params = "
287 "%.*s\r\n",
288 (unsigned long)recv->data.sync_service_invoke.msg_id,
289 recv->data.sync_service_invoke.rrpc_id,
290 recv->data.sync_service_invoke.service_id,
291 recv->data.sync_service_invoke.params_len,
292 recv->data.sync_service_invoke.params);
293
294 /* TODO: 以下代码演示如何对来自云平台的同步服务调用进行应答,
295 * 用户可取消注释查看演示效果
296 *
297 * 注意: 如果用户在回调函数外进行应答,
298 * 需要自行保存msg_id和rrpc_id字符串,
299 * 因为回调函数入参在退出回调函数后将被SDK销毁, 不可以再访问到
300 */
301
302 /*
303 {
304 aiot_dm_msg_t msg;
305
306 memset(&msg, 0, sizeof(aiot_dm_msg_t));
307 msg.type = AIOT_DMMSG_SYNC_SERVICE_REPLY;
308 msg.data.sync_service_reply.rrpc_id =
309 recv->data.sync_service_invoke.rrpc_id;
310 msg.data.sync_service_reply.msg_id =
311 recv->data.sync_service_invoke.msg_id;
312 msg.data.sync_service_reply.code = 200;
313 msg.data.sync_service_reply.service_id =
314 "SetLightSwitchTimer"; msg.data.sync_service_reply.data =
315 "{}"; int32_t res = aiot_dm_send(dm_handle, &msg); if (res <
316 0) { printf("aiot_dm_send failed\r\n");
317 }
318 }
319 */
320 }
321 break;
322
323 /* 下行二进制数据 */
324 case AIOT_DMRECV_RAW_DATA:
325 {
326 printf("raw data len = %d\r\n", recv->data.raw_data.data_len);
327 /* TODO: 以下代码演示如何发送二进制格式数据,
328 * 若使用需要有相应的数据透传脚本部署在云端 */
329 /*
330 {
331 aiot_dm_msg_t msg;
332 uint8_t raw_data[] = {0x01, 0x02};
333
334 memset(&msg, 0, sizeof(aiot_dm_msg_t));
335 msg.type = AIOT_DMMSG_RAW_DATA;
336 msg.data.raw_data.data = raw_data;
337 msg.data.raw_data.data_len = sizeof(raw_data);
338 aiot_dm_send(dm_handle, &msg);
339 }
340 */
341 }
342 break;
343
344 /* 二进制格式的同步服务调用, 比单纯的二进制数据消息多了个rrpc_id */
345 case AIOT_DMRECV_RAW_SYNC_SERVICE_INVOKE:
346 {
347 printf("raw sync service rrpc_id = %s, data_len = %d\r\n",
348 recv->data.raw_service_invoke.rrpc_id,
349 recv->data.raw_service_invoke.data_len);
350 }
351 break;
352
353 default:
354 break;
355 }
356 }
357
358 /* 属性上报函数演示 */
demo_send_property_post(void * dm_handle,char * params)359 int32_t demo_send_property_post(void *dm_handle, char *params)
360 {
361 aiot_dm_msg_t msg;
362
363 memset(&msg, 0, sizeof(aiot_dm_msg_t));
364 msg.type = AIOT_DMMSG_PROPERTY_POST;
365 msg.data.property_post.params = params;
366
367 return aiot_dm_send(dm_handle, &msg);
368 }
369
370 /* 事件上报函数演示 */
demo_send_event_post(void * dm_handle,char * event_id,char * params)371 int32_t demo_send_event_post(void *dm_handle, char *event_id, char *params)
372 {
373 aiot_dm_msg_t msg;
374
375 memset(&msg, 0, sizeof(aiot_dm_msg_t));
376 msg.type = AIOT_DMMSG_EVENT_POST;
377 msg.data.event_post.event_id = event_id;
378 msg.data.event_post.params = params;
379
380 return aiot_dm_send(dm_handle, &msg);
381 }
382
383 /** cloud connected event callback */
user_connected_event_handler(void)384 static int user_connected_event_handler(void)
385 {
386 if (mp_obj_is_fun(on_connected)) {
387 mp_call_function_0(on_connected);
388 } else {
389 printf("Error : on_connected : is not function\n");
390 }
391 g_user_example_ctx.cloud_connected = 1;
392 return 0;
393 }
394
395 /** cloud disconnected event callback */
user_disconnected_event_handler(void)396 static int user_disconnected_event_handler(void)
397 {
398 if (mp_obj_is_fun(on_connected)) {
399 mp_call_function_0(on_disconnect);
400 } else {
401 printf("Error:on_connected : is not function\n");
402 }
403 g_user_example_ctx.cloud_connected = 0;
404 return 0;
405 }
406
linkkit_init(size_t n_args,const mp_obj_t * args)407 STATIC mp_obj_t linkkit_init(size_t n_args, const mp_obj_t *args)
408 {
409 int32_t res = STATE_SUCCESS;
410
411 char *url =
412 "iot-as-mqtt.cn-shanghai.aliyuncs.com"; /* 阿里云平台上海站点的域名后缀
413 */
414 char host[100] = { 0 }; /* 用这个数组拼接设备连接的云平台站点全地址, 规则是
415 ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com */
416 uint16_t port =
417 443; /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
418 aiot_sysdep_network_cred_t
419 cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */
420
421 char *product_key = "a18wPzZJzNG";
422 char *device_name = "data_model_basic_demo";
423 char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxBMTP3TD";
424
425 int ret = -1;
426 if (n_args < 5) {
427 printf("%s: args num is illegal :n_args = %d;\n", __func__, n_args);
428 return mp_const_none;
429 }
430
431 // iot_host_name = mp_obj_str_get_str(args[0]);
432 product_key = mp_obj_str_get_str(args[1]);
433 device_name = mp_obj_str_get_str(args[2]);
434 device_secret = mp_obj_str_get_str(args[3]);
435 // iot_product_sec = mp_obj_str_get_str(args[4]);
436
437 /* 配置SDK的底层依赖 */
438 aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
439 /* 配置SDK的日志输出 */
440 aiot_state_set_logcb(py_demo_state_logcb);
441
442 /* 创建SDK的安全凭据, 用于建立TLS连接 */
443 memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
444 cred.option =
445 AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA证书校验MQTT服务端 */
446 cred.max_tls_fragment =
447 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */
448 cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */
449 cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */
450 cred.x509_server_cert_len =
451 strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */
452
453 /* 创建1个MQTT客户端实例并内部初始化默认参数 */
454 mqtt_handle = aiot_mqtt_init();
455 if (mqtt_handle == NULL) {
456 printf("aiot_mqtt_init failed\n");
457 return -1;
458 }
459
460 snprintf(host, 100, "%s.%s", product_key, url);
461 /* 配置MQTT服务器地址 */
462 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)host);
463 /* 配置MQTT服务器端口 */
464 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port);
465 /* 配置设备productKey */
466 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY,
467 (void *)product_key);
468 /* 配置设备deviceName */
469 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME,
470 (void *)device_name);
471 /* 配置设备deviceSecret */
472 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET,
473 (void *)device_secret);
474 /* 配置网络连接的安全凭据, 上面已经创建好了 */
475 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
476 /* 配置MQTT事件回调函数 */
477 aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER,
478 (void *)demo_mqtt_event_handler);
479
480 /* 创建DATA-MODEL实例 */
481 dm_handle = aiot_dm_init();
482 if (dm_handle == NULL) {
483 printf("aiot_dm_init failed\n");
484 return -1;
485 }
486 /* 配置MQTT实例句柄 */
487 aiot_dm_setopt(dm_handle, AIOT_DMOPT_MQTT_HANDLE, mqtt_handle);
488 /* 配置消息接收处理回调函数 */
489 aiot_dm_setopt(dm_handle, AIOT_DMOPT_RECV_HANDLER,
490 (void *)demo_dm_recv_handler);
491
492 /* 与服务器建立MQTT连接 */
493 res = aiot_mqtt_connect(mqtt_handle);
494 if (res < STATE_SUCCESS) {
495 /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
496 aiot_mqtt_deinit(&mqtt_handle);
497 printf("aiot_mqtt_connect failed: -0x%04X\n", -res);
498 return -1;
499 }
500
501 #ifdef AOS_COMP_UAGENT
502 res = uagent_mqtt_client_set(mqtt_handle);
503 if (res != 0) {
504 printf("uAgent mqtt handle set failed ret = %d\n", res);
505 }
506
507 res = uagent_ext_comm_start(product_key, device_name);
508 if (res != 0) {
509 printf("uAgent ext comm start failed ret = %d\n", res);
510 }
511 #endif
512
513 /* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活,
514 * 以及重发QoS1的未应答报文 */
515 g_mqtt_process_thread_running = 1;
516 res = aos_task_new("demo_mqtt_process", demo_mqtt_process_thread,
517 mqtt_handle, 4096);
518 if (res != 0) {
519 printf("create demo_mqtt_recv_thread failed: %d\n", res);
520 return mp_const_false;
521 }
522
523 /* 创建一个单独的线程用于执行aiot_mqtt_recv,
524 * 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */
525 g_mqtt_recv_thread_running = 1;
526 res = aos_task_new("demo_mqtt_process", demo_mqtt_recv_thread, mqtt_handle,
527 4096);
528 // res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread,
529 // mqtt_handle);
530 if (res != 0) {
531 printf("create demo_mqtt_recv_thread failed: %d\n", res);
532 return mp_const_false;
533 }
534 return mp_const_true;
535 }
536 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(mp_obj_link_init, 5, linkkit_init);
537
register_dyn_dev(void)538 STATIC mp_obj_t register_dyn_dev(void)
539 {
540 return mp_const_true;
541 }
542 MP_DEFINE_CONST_FUN_OBJ_0(mp_obj_register_dyn_dev, register_dyn_dev);
543
connect_lp(void)544 STATIC mp_obj_t connect_lp(void)
545 {
546 return mp_const_none;
547 }
548 MP_DEFINE_CONST_FUN_OBJ_0(mp_obj_connect_lp, connect_lp);
549
register_call_back(mp_obj_t id,mp_obj_t func)550 STATIC mp_obj_t register_call_back(mp_obj_t id, mp_obj_t func)
551 {
552 int callback_id = mp_obj_get_int(id);
553 switch (callback_id) {
554 case ITE_CONNECT_SUCC:
555 on_connected = func;
556 break;
557 case ITE_DISCONNECTED:
558 break;
559 case ITE_SERVICE_REQUEST:
560 on_async_service = func;
561 break;
562 case ITE_PROPERTY_SET:
563 on_property_set = func;
564 break;
565 case ITE_REPORT_REPLY:
566 on_report_reply = func;
567 break;
568 case ITE_TRIGGER_EVENT_REPLY:
569 on_event_reply = func;
570 break;
571
572 default:
573 break;
574 }
575 return mp_const_none;
576 }
577 MP_DEFINE_CONST_FUN_OBJ_2(mp_obj_register_call_back, register_call_back);
578
post_property(mp_obj_t data)579 STATIC mp_obj_t post_property(mp_obj_t data)
580 {
581 size_t len;
582 const char *payload = mp_obj_str_get_data(data, &len);
583 size_t ret = demo_send_property_post(dm_handle, payload);
584 return mp_obj_new_int(ret);
585 }
586 MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_post_property, post_property);
587
post_event(mp_obj_t eventid,mp_obj_t data)588 STATIC mp_obj_t post_event(mp_obj_t eventid, mp_obj_t data)
589 {
590 size_t payload_len;
591 size_t id_len;
592 const char *event_id = mp_obj_str_get_data(eventid, &id_len);
593 const char *payload = mp_obj_str_get_data(data, &payload_len);
594 size_t ret = demo_send_event_post(dm_handle, event_id, payload);
595 return mp_obj_new_int(ret);
596 }
597 MP_DEFINE_CONST_FUN_OBJ_2(mp_obj_post_event, post_event);
598
linkkit_yield(mp_obj_t time)599 STATIC mp_obj_t linkkit_yield(mp_obj_t time)
600 {
601 return mp_const_none;
602 }
603 MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_linkkit_yield, linkkit_yield);
604
linkkit_close()605 STATIC mp_obj_t linkkit_close()
606 {
607 int res = aiot_mqtt_disconnect(mqtt_handle);
608 if (res < STATE_SUCCESS) {
609 aiot_mqtt_deinit(&mqtt_handle);
610 printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
611 return -1;
612 }
613
614 /* 销毁DATA-MODEL实例, 一般不会运行到这里 */
615 res = aiot_dm_deinit(&dm_handle);
616 if (res < STATE_SUCCESS) {
617 printf("aiot_dm_deinit failed: -0x%04X\n", -res);
618 return -1;
619 }
620
621 /* 销毁MQTT实例, 一般不会运行到这里 */
622 res = aiot_mqtt_deinit(&mqtt_handle);
623 if (res < STATE_SUCCESS) {
624 printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
625 return -1;
626 }
627 return mp_const_none;
628 }
629 MP_DEFINE_CONST_FUN_OBJ_0(mp_obj_linkkit_close, linkkit_close);
630
631 STATIC const mp_rom_map_elem_t linkkit_module_globals_table[] = {
632 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__linkkit) },
633 { MP_OBJ_NEW_QSTR(MP_QSTR_init), MP_ROM_PTR(&mp_obj_link_init) },
634 { MP_OBJ_NEW_QSTR(MP_QSTR_register_dyn_dev),
635 MP_ROM_PTR(&mp_obj_register_dyn_dev) },
636 { MP_OBJ_NEW_QSTR(MP_QSTR_connect), MP_ROM_PTR(&mp_obj_connect_lp) },
637 { MP_OBJ_NEW_QSTR(MP_QSTR_register_call_back),
638 MP_ROM_PTR(&mp_obj_register_call_back) },
639 { MP_OBJ_NEW_QSTR(MP_QSTR_post_property),
640 MP_ROM_PTR(&mp_obj_post_property) },
641 { MP_OBJ_NEW_QSTR(MP_QSTR_post_event), MP_ROM_PTR(&mp_obj_post_event) },
642 { MP_OBJ_NEW_QSTR(MP_QSTR_do_yield), MP_ROM_PTR(&mp_obj_linkkit_yield) },
643 { MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_obj_linkkit_close) },
644 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_CONNECT), MP_ROM_INT(ON_CONNECT) },
645 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_DISCONNECT), MP_ROM_INT(ON_DISCONNECT) },
646 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_SERVICE), MP_ROM_INT(ON_SERVICE) },
647 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_PROPS), MP_ROM_INT(ON_PROPS) },
648 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_CLOSE), MP_ROM_INT(ON_CLOSE) },
649 { MP_OBJ_NEW_QSTR(MP_QSTR_ON_ERROR), MP_ROM_INT(ON_ERROR) },
650 };
651
652 STATIC MP_DEFINE_CONST_DICT(linkkit_module_globals,
653 linkkit_module_globals_table);
654
655 const mp_obj_module_t linkkit_module = {
656 .base = { &mp_type_module },
657 .globals = (mp_obj_dict_t *)&linkkit_module_globals,
658 };
659