1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "linkkit/infra/infra_config.h"
5 
6 #ifdef INFRA_REPORT
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include "linkkit/infra/infra_types.h"
11 #include "linkkit/infra/infra_defs.h"
12 #include "linkkit/infra/infra_string.h"
13 #include "linkkit/infra/infra_report.h"
14 #include "linkkit/wrappers/wrappers.h"
15 
16 #ifdef INFRA_MEM_STATS
17 #include "linkkit/infra/infra_mem_stats.h"
18 #define SYS_REPORT_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "sys.report")
19 #define SYS_REPORT_FREE(ptr)    LITE_free(ptr)
20 #else
21 #define SYS_REPORT_MALLOC(size) HAL_Malloc(size)
22 #define SYS_REPORT_FREE(ptr)    HAL_Free(ptr)
23 #endif
24 
25 #ifdef INFRA_LOG
26 #include "linkkit/infra/infra_log.h"
27 #define VERSION_DEBUG(...) log_debug("version", __VA_ARGS__)
28 #define VERSION_ERR(...)   log_err("version", __VA_ARGS__)
29 #else
30 #define VERSION_DEBUG(...)       \
31     do {                         \
32         HAL_Printf(__VA_ARGS__); \
33         HAL_Printf("\r\n");      \
34     } while (0)
35 #define VERSION_ERR(...)         \
36     do {                         \
37         HAL_Printf(__VA_ARGS__); \
38         HAL_Printf("\r\n");      \
39     } while (0)
40 #endif
41 
42 static unsigned int g_report_id = 0;
43 
iotx_report_id(void)44 int iotx_report_id(void)
45 {
46     return g_report_id++;
47 }
48 
49 static info_report_func_pt info_report_func = NULL;
50 
iotx_set_report_func(info_report_func_pt func)51 void iotx_set_report_func(info_report_func_pt func)
52 {
53     info_report_func = func;
54 }
55 /*  aos will implement this function */
56 #if defined(BUILD_AOS)
57 extern void aos_get_version_hex(unsigned char version[VERSION_NUM_SIZE]);
58 #else
aos_get_version_hex(unsigned char version[VERSION_NUM_SIZE])59 void aos_get_version_hex(unsigned char version[VERSION_NUM_SIZE])
60 {
61     const char *p_version = IOTX_SDK_VERSION;
62     int i = 0, j = 0;
63     unsigned char res = 0;
64 
65     for (j = 0; j < 3; j++) {
66         for (res = 0; p_version[i] <= '9' && p_version[i] >= '0'; i++) {
67             res = res * 10 + p_version[i] - '0';
68         }
69         version[j] = res;
70         i++;
71     }
72     version[3] = 0x00;
73 }
74 #endif
75 
76 /*  aos will implement this function */
77 #if defined(BUILD_AOS)
78 extern void aos_get_mac_hex(unsigned char mac[MAC_ADDRESS_SIZE]);
79 #else
aos_get_mac_hex(unsigned char mac[MAC_ADDRESS_SIZE])80 void aos_get_mac_hex(unsigned char mac[MAC_ADDRESS_SIZE])
81 {
82     memcpy(mac, "\x01\x02\x03\x04\x05\x06\x07\x08", MAC_ADDRESS_SIZE);
83 }
84 #endif
85 
86 /*  aos will implement this function */
87 #if defined(BUILD_AOS)
88 extern void aos_get_chip_code(unsigned char chip_code[CHIP_CODE_SIZE]);
89 #else
aos_get_chip_code(unsigned char chip_code[CHIP_CODE_SIZE])90 void aos_get_chip_code(unsigned char chip_code[CHIP_CODE_SIZE])
91 {
92     memcpy(chip_code, "\x01\x02\x03\x04", CHIP_CODE_SIZE);
93 }
94 #endif
95 
96 const char *DEVICE_INFO_UPDATE_FMT =
97     "{\"id\":\"%d\",\"version\":\"1.0\",\"params\":["
98     "{\"attrKey\":\"SYS_LP_SDK_VERSION\",\"attrValue\":\"%s\",\"domain\":"
99     "\"SYSTEM\"},"
100     "{\"attrKey\":\"SYS_SDK_LANGUAGE\",\"attrValue\":\"C\",\"domain\":"
101     "\"SYSTEM\"}"
102     "],\"method\":\"thing.deviceinfo.update\"}";
103 
iotx_report_devinfo(void * pclient)104 int iotx_report_devinfo(void *pclient)
105 {
106     int ret = 0;
107     char topic_name[IOTX_URI_MAX_LEN + 1] = { 0 };
108     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
109     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
110     char *msg = NULL;
111     int msg_len = 0;
112 
113     if (info_report_func == NULL) {
114         VERSION_ERR("report func not register!");
115         return -1;
116     }
117 
118     HAL_GetProductKey(product_key);
119     HAL_GetDeviceName(device_name);
120     VERSION_DEBUG("devinfo report");
121 
122     /* devinfo update topic name */
123     ret = HAL_Snprintf(topic_name, IOTX_URI_MAX_LEN,
124                        "/sys/%s/%s/thing/deviceinfo/update", product_key,
125                        device_name);
126     if (ret <= 0) {
127         VERSION_ERR("topic generate err");
128         return FAIL_RETURN;
129     }
130     VERSION_DEBUG("devinfo report topic: %s", topic_name);
131 
132     msg_len =
133         strlen(DEVICE_INFO_UPDATE_FMT) + 10 + strlen(IOTX_SDK_VERSION) + 1;
134     msg = (char *)SYS_REPORT_MALLOC(msg_len);
135     if (msg == NULL) {
136         VERSION_ERR("malloc err");
137         return FAIL_RETURN;
138     }
139     memset(msg, 0, msg_len);
140 
141     /* devinfo update message */
142     ret = HAL_Snprintf(msg, msg_len, DEVICE_INFO_UPDATE_FMT, iotx_report_id(),
143                        IOTX_SDK_VERSION);
144     if (ret <= 0) {
145         VERSION_ERR("topic msg generate err");
146         SYS_REPORT_FREE(msg);
147         return FAIL_RETURN;
148     }
149     VERSION_DEBUG("devinfo report data: %s", msg);
150 
151     if (info_report_func != NULL) {
152         info_report_func(pclient, topic_name, 1, msg, strlen(msg));
153     }
154 
155     SYS_REPORT_FREE(msg);
156     if (ret < 0) {
157         VERSION_ERR("publish failed, ret = %d", ret);
158         return FAIL_RETURN;
159     }
160     VERSION_DEBUG("devinfo report succeed");
161 
162     return SUCCESS_RETURN;
163 }
164 
165 /* report Firmware version */
iotx_report_firmware_version(void * pclient)166 int iotx_report_firmware_version(void *pclient)
167 {
168     int ret;
169     char topic_name[IOTX_URI_MAX_LEN + 1] = { 0 };
170     char msg[FIRMWARE_VERSION_MSG_LEN] = { 0 };
171     char version[IOTX_FIRMWARE_VERSION_LEN + 1] = { 0 };
172     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
173     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
174 
175     if (info_report_func == NULL) {
176         VERSION_ERR("report func not register!");
177         return -1;
178     }
179 
180     HAL_GetProductKey(product_key);
181     HAL_GetDeviceName(device_name);
182 
183     ret = HAL_GetFirmwareVersion(version);
184     if (ret <= 0) {
185         VERSION_ERR("firmware version does not implement");
186         return FAIL_RETURN;
187     }
188 
189     VERSION_DEBUG("firmware version report start in MQTT");
190 
191     /* firmware report topic name generate */
192     ret = HAL_Snprintf(topic_name, IOTX_URI_MAX_LEN, "/ota/device/inform/%s/%s",
193                        product_key, device_name);
194     if (ret <= 0) {
195         VERSION_ERR("firmware report topic generate err");
196         return FAIL_RETURN;
197     }
198     VERSION_DEBUG("firmware report topic: %s", topic_name);
199 
200     /* firmware report message json data generate */
201     ret = HAL_Snprintf(msg, FIRMWARE_VERSION_MSG_LEN,
202                        "{\"id\":\"%d\",\"params\":{\"version\":\"%s\"}}",
203                        iotx_report_id(), version);
204     if (ret <= 0) {
205         VERSION_ERR("firmware report message json data generate err");
206         return FAIL_RETURN;
207     }
208     VERSION_DEBUG("firmware report data: %s", msg);
209 
210     ret = info_report_func(pclient, topic_name, 1, msg, strlen(msg));
211 
212     if (ret < 0) {
213         VERSION_ERR("publish failed, ret = %d", ret);
214         return ret;
215     }
216 
217     VERSION_DEBUG("firmware version report finished, iotx_publish() = %d", ret);
218     return SUCCESS_RETURN;
219 }
220 
221 /* report ModuleID */
iotx_report_mid(void * pclient)222 int iotx_report_mid(void *pclient)
223 {
224     return SUCCESS_RETURN;
225 }
226 
227 #ifndef BUILD_AOS
aos_get_version_info(unsigned char version_num[VERSION_NUM_SIZE],unsigned char random_num[RANDOM_NUM_SIZE],unsigned char mac_address[MAC_ADDRESS_SIZE],unsigned char chip_code[CHIP_CODE_SIZE],unsigned char * output_buffer,unsigned int output_buffer_size)228 unsigned int aos_get_version_info(unsigned char version_num[VERSION_NUM_SIZE],
229                                   unsigned char random_num[RANDOM_NUM_SIZE],
230                                   unsigned char mac_address[MAC_ADDRESS_SIZE],
231                                   unsigned char chip_code[CHIP_CODE_SIZE],
232                                   unsigned char *output_buffer,
233                                   unsigned int output_buffer_size)
234 {
235     char *p = (char *)output_buffer;
236 
237     if (output_buffer_size < AOS_ACTIVE_INFO_LEN) {
238         return 1;
239     }
240 
241     memset(p, 0, output_buffer_size);
242 
243     infra_hex2str(version_num, VERSION_NUM_SIZE, p);
244     p += VERSION_NUM_SIZE * 2;
245     infra_hex2str(random_num, RANDOM_NUM_SIZE, p);
246     p += RANDOM_NUM_SIZE * 2;
247     infra_hex2str(mac_address, MAC_ADDRESS_SIZE, p);
248     p += MAC_ADDRESS_SIZE * 2;
249     infra_hex2str(chip_code, CHIP_CODE_SIZE, p);
250     p += CHIP_CODE_SIZE * 2;
251     strcat(p, "1111111111222222222233333333334444444444");
252 
253     return 0;
254 }
255 #endif
256 #endif
257