1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "dev_bind_internal.h"
5 
6 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
7 extern "C" {
8 #endif
9 
10 #define AWSS_RESET_PKT_LEN       (256)
11 #define AWSS_RESET_TOPIC_LEN     (128)
12 #define AWSS_RESET_MSG_ID_LEN    (16)
13 
14 #define TOPIC_RESET_REPORT       "/sys/%s/%s/thing/reset"
15 #define TOPIC_RESET_REPORT_REPLY "/sys/%s/%s/thing/reset_reply"
16 #define METHOD_RESET_REPORT      "thing.reset"
17 
18 #define AWSS_RESET_REQ_FMT \
19     "{\"id\":%s, \"version\":\"1.0\", \"method\":\"%s\", \"params\":%s}"
20 
21 #define AWSS_KV_RST "awss.rst"
22 
23 static uint8_t awss_report_reset_suc = 0;
24 static uint16_t awss_report_reset_id = 0;
25 static void *report_reset_timer = NULL;
26 #ifdef DEV_BIND_ENABLED
27 extern int awss_start_bind();
28 #endif
29 
30 int awss_report_reset_to_cloud();
awss_report_reset_reply(void * pcontext,void * pclient,void * mesg)31 void awss_report_reset_reply(void *pcontext, void *pclient, void *mesg)
32 {
33     char rst = 0;
34 
35     iotx_mqtt_event_msg_pt msg = (iotx_mqtt_event_msg_pt)mesg;
36 
37     switch (msg->event_type) {
38     case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
39         break;
40     default:
41         return;
42     }
43 
44     devrst_debug("[RST]", "%s\r\n", __func__);
45 
46     awss_report_reset_suc = 1;
47     HAL_Kv_Set(AWSS_KV_RST, &rst, sizeof(rst), 0);
48 
49     HAL_Timer_Stop(report_reset_timer);
50     HAL_Timer_Delete(report_reset_timer);
51     report_reset_timer = NULL;
52 
53 #ifdef DEV_BIND_ENABLED
54     awss_start_bind();
55 #endif
56 
57 #ifdef INFRA_EVENT
58     iotx_event_post(IOTX_RESET); /* for old version of event */
59     do {                         /* for new version of event */
60         void *cb = NULL;
61         cb = (void *)iotx_event_callback(ITE_AWSS_STATUS);
62         if (cb == NULL) {
63             break;
64         }
65         ((int (*)(int))cb)(IOTX_RESET);
66     } while (0);
67 #endif
68 }
69 
awss_report_reset_to_cloud()70 int awss_report_reset_to_cloud()
71 {
72     int ret = -1;
73     int final_len = 0;
74     char *topic = NULL;
75     char *packet = NULL;
76     int packet_len = AWSS_RESET_PKT_LEN;
77     int topic_len = AWSS_RESET_TOPIC_LEN;
78 
79     if (awss_report_reset_suc) {
80         return 0;
81     }
82 
83     if (report_reset_timer == NULL) {
84         report_reset_timer = HAL_Timer_Create(
85             "report_rst", (void (*)(void *))awss_report_reset_to_cloud, NULL);
86     }
87     HAL_Timer_Stop(report_reset_timer);
88     HAL_Timer_Start(report_reset_timer, 3000);
89     do {
90         char pk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
91         char dn[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
92 
93         HAL_GetProductKey(pk);
94         HAL_GetDeviceName(dn);
95 
96         topic = (char *)devrst_malloc(topic_len + 1);
97         if (topic == NULL) {
98             goto REPORT_RST_ERR;
99         }
100         memset(topic, 0, topic_len + 1);
101 
102         HAL_Snprintf(topic, topic_len, TOPIC_RESET_REPORT_REPLY, pk, dn);
103 
104 #ifdef MQTT_AUTO_SUBSCRIBE
105         ret = IOT_MQTT_Subscribe(
106             NULL, topic, IOTX_MQTT_QOS3_SUB_LOCAL,
107             (iotx_mqtt_event_handle_func_fpt)awss_report_reset_reply, NULL);
108 #else
109         ret = IOT_MQTT_Subscribe(
110             NULL, topic, IOTX_MQTT_QOS0,
111             (iotx_mqtt_event_handle_func_fpt)awss_report_reset_reply, NULL);
112 #endif
113         if (ret < 0) {
114             goto REPORT_RST_ERR;
115         }
116 
117         memset(topic, 0, topic_len + 1);
118         HAL_Snprintf(topic, topic_len, TOPIC_RESET_REPORT, pk, dn);
119     } while (0);
120 
121     packet = devrst_malloc(packet_len + 1);
122     if (packet == NULL) {
123         ret = -1;
124         goto REPORT_RST_ERR;
125     }
126     memset(packet, 0, packet_len + 1);
127 
128     do {
129         char id_str[AWSS_RESET_MSG_ID_LEN + 1] = { 0 };
130         HAL_Snprintf(id_str, AWSS_RESET_MSG_ID_LEN, "\"%u\"",
131                      awss_report_reset_id++);
132         final_len = HAL_Snprintf(packet, packet_len, AWSS_RESET_REQ_FMT, id_str,
133                                  METHOD_RESET_REPORT, "{}");
134     } while (0);
135 
136     devrst_debug("[RST]", "report reset:%s\r\n", packet);
137 
138     ret =
139         IOT_MQTT_Publish_Simple(NULL, topic, IOTX_MQTT_QOS0, packet, final_len);
140     devrst_debug("[RST]", "report reset result:%d\r\n", ret);
141 
142 REPORT_RST_ERR:
143     if (packet) {
144         devrst_free(packet);
145     }
146     if (topic) {
147         devrst_free(topic);
148     }
149     return ret;
150 }
151 
awss_report_reset()152 int awss_report_reset()
153 {
154     char rst = 0x01;
155 
156     awss_report_reset_suc = 0;
157 
158     HAL_Kv_Set(AWSS_KV_RST, &rst, sizeof(rst), 0);
159 
160     return awss_report_reset_to_cloud();
161 }
162 
awss_check_reset()163 int awss_check_reset()
164 {
165     int len = 1;
166     char rst = 0;
167 
168     if (HAL_Kv_Get(AWSS_KV_RST, &rst, &len) < 0) {
169         devrst_err("[RST]", "get reset state err\r\n");
170         return 0;
171     }
172 
173     if (rst != 0x01) { /* reset flag is not set */
174         devrst_debug("[RST]", "no rst\r\n");
175         return 0;
176     }
177 
178     awss_report_reset_suc = 0;
179     log_info("[RST]", "need report rst\r\n");
180 
181     return 1;
182 }
183 
awss_stop_report_reset()184 int awss_stop_report_reset()
185 {
186     if (report_reset_timer == NULL) {
187         return 0;
188     }
189 
190     HAL_Timer_Stop(report_reset_timer);
191     HAL_Timer_Delete(report_reset_timer);
192     report_reset_timer = NULL;
193 
194     return 0;
195 }
196 
197 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
198 }
199 #endif
200