1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include "iotx_ota_internal.h"
6 
otalib_JsonValueOf(const char * json,uint32_t json_len,const char * key,uint32_t * val_len)7 const char *otalib_JsonValueOf(const char *json, uint32_t json_len,
8                                const char *key, uint32_t *val_len)
9 {
10     int length;
11     const char *val;
12     val = json_get_value_by_name((char *)json, json_len, (char *)key, &length,
13                                  NULL);
14     if (NULL != val) {
15         *val_len = (uint32_t)length;
16     }
17     return val;
18 }
19 
otalib_MD5Init(void)20 void *otalib_MD5Init(void)
21 {
22     iot_md5_context *ctx = OTA_MALLOC(sizeof(iot_md5_context));
23     if (NULL == ctx) {
24         return NULL;
25     }
26 
27     utils_md5_init(ctx);
28     utils_md5_starts(ctx);
29 
30     return ctx;
31 }
32 
otalib_MD5Update(void * md5,const char * buf,size_t buf_len)33 void otalib_MD5Update(void *md5, const char *buf, size_t buf_len)
34 {
35     utils_md5_update(md5, (unsigned char *)buf, buf_len);
36 }
37 
otalib_MD5Finalize(void * md5,char * output_str)38 void otalib_MD5Finalize(void *md5, char *output_str)
39 {
40     int i;
41     unsigned char buf_out[16];
42     utils_md5_finish(md5, buf_out);
43 
44     for (i = 0; i < 16; ++i) {
45         output_str[i * 2] = infra_hex2char(buf_out[i] >> 4);
46         output_str[i * 2 + 1] = infra_hex2char(buf_out[i]);
47     }
48     output_str[32] = '\0';
49 }
50 
otalib_MD5Deinit(void * md5)51 void otalib_MD5Deinit(void *md5)
52 {
53     if (NULL != md5) {
54         OTA_FREE(md5);
55     }
56 }
57 
otalib_Sha256Init(void)58 void *otalib_Sha256Init(void)
59 {
60     iot_sha256_context *ctx = OTA_MALLOC(sizeof(iot_sha256_context));
61     if (NULL == ctx) {
62         return NULL;
63     }
64 
65     utils_sha256_init(ctx);
66     utils_sha256_starts(ctx);
67 
68     return ctx;
69 }
70 
otalib_Sha256Update(void * sha256,const char * buf,size_t buf_len)71 void otalib_Sha256Update(void *sha256, const char *buf, size_t buf_len)
72 {
73     utils_sha256_update(sha256, (unsigned char *)buf, buf_len);
74 }
75 
otalib_Sha256Finalize(void * sha256,char * output_str)76 void otalib_Sha256Finalize(void *sha256, char *output_str)
77 {
78     int i;
79     unsigned char buf_out[32];
80     utils_sha256_finish(sha256, buf_out);
81 
82     for (i = 0; i < 32; ++i) {
83         output_str[i * 2] = infra_hex2char(buf_out[i] >> 4);
84         output_str[i * 2 + 1] = infra_hex2char(buf_out[i]);
85     }
86     output_str[64] = '\0';
87 }
88 
otalib_Sha256Deinit(void * sha256)89 void otalib_Sha256Deinit(void *sha256)
90 {
91     utils_sha256_free(sha256);
92     if (NULL != sha256) {
93         OTA_FREE(sha256);
94     }
95 }
96 /* Get the specific @key value, and copy to @dest */
97 /* 0, successful; -1, failed */
otalib_GetFirmwareFixlenPara(const char * json_doc,size_t json_doc_len,const char * key,char * dest,size_t dest_len)98 int otalib_GetFirmwareFixlenPara(const char *json_doc, size_t json_doc_len,
99                                  const char *key, char *dest, size_t dest_len)
100 {
101     const char *pvalue;
102     uint32_t val_len;
103 
104     pvalue = otalib_JsonValueOf(json_doc, json_doc_len, key, &val_len);
105     if (pvalue == NULL) {
106         OTA_LOG_ERROR("Not '%s' key in json doc of OTA", key);
107         return -1;
108     }
109 
110     if (val_len > dest_len) {
111         OTA_LOG_ERROR("value length of the key is too long");
112         return -1;
113     }
114 
115     memcpy(dest, pvalue, val_len);
116 
117     return 0;
118 }
119 
120 /* Get variant length parameter of firmware, and copy to @dest */
121 /* 0, successful; -1, failed */
otalib_GetFirmwareVarlenPara(const char * json_doc,size_t json_doc_len,const char * key,char ** dest)122 int otalib_GetFirmwareVarlenPara(const char *json_doc, size_t json_doc_len,
123                                  const char *key, char **dest)
124 {
125     const char *pvalue;
126     uint32_t val_len;
127 
128     pvalue = otalib_JsonValueOf(json_doc, json_doc_len, key, &val_len);
129     if (pvalue == NULL) {
130         OTA_LOG_ERROR("Not %s key in json doc of OTA", key);
131         return -1;
132     }
133 
134     *dest = OTA_MALLOC(val_len + 1);
135     if (*dest == NULL) {
136         OTA_LOG_ERROR("allocate for dest failed");
137         return -1;
138     }
139 
140     memcpy(*dest, pvalue, val_len);
141     (*dest)[val_len] = '\0';
142 
143     return 0;
144 }
145 
otalib_GetParams(const char * json_doc,uint32_t json_len,char ** url,char ** version,char * md5,uint32_t * file_size)146 int otalib_GetParams(const char *json_doc, uint32_t json_len, char **url,
147                      char **version, char *md5, uint32_t *file_size)
148 {
149 #define OTA_FILESIZE_STR_LEN (16)
150     char file_size_str[OTA_FILESIZE_STR_LEN + 1] = { 0 };
151 
152     /* get version */
153     if (0 !=
154         otalib_GetFirmwareVarlenPara(json_doc, json_len, "version", version)) {
155         OTA_LOG_ERROR("get value of version key failed");
156         return -1;
157     }
158 
159     /* get URL */
160     if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "url", url)) {
161         OTA_LOG_ERROR("get value of url key failed");
162         return -1;
163     }
164 
165     /* get md5 */
166     if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "md5", md5, 32)) {
167         OTA_LOG_ERROR("get value of md5 key failed");
168         return -1;
169     }
170 
171     /* get file size */
172     if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "size",
173                                           file_size_str,
174                                           OTA_FILESIZE_STR_LEN)) {
175         OTA_LOG_ERROR("get value of size key failed");
176         return -1;
177     }
178     file_size_str[OTA_FILESIZE_STR_LEN] = '\0';
179     *file_size = atoi(file_size_str);
180 
181     return 0;
182 
183 #undef OTA_FILESIZE_STR_LEN
184 }
185 
otalib_GetConfigParams(const char * json_doc,uint32_t json_len,char ** configId,uint32_t * configSize,char ** sign,char ** signMethod,char ** url,char ** getType)186 int otalib_GetConfigParams(const char *json_doc, uint32_t json_len,
187                            char **configId, uint32_t *configSize, char **sign,
188                            char **signMethod, char **url, char **getType)
189 {
190 #define OTA_FILESIZE_STR_LEN (16)
191     char file_size_str[OTA_FILESIZE_STR_LEN + 1];
192 
193     /* get configId */
194     if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "configId",
195                                           configId)) {
196         OTA_LOG_ERROR("get value of configId key failed");
197         return -1;
198     }
199 
200     /* get configSize */
201     if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "configSize",
202                                           file_size_str,
203                                           OTA_FILESIZE_STR_LEN)) {
204         OTA_LOG_ERROR("get value of size key failed");
205         return -1;
206     }
207     file_size_str[OTA_FILESIZE_STR_LEN] = '\0';
208     *configSize = atoi(file_size_str);
209 
210     /* get sign */
211     if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "sign", sign)) {
212         OTA_LOG_ERROR("get value of sign key failed");
213         return -1;
214     }
215 
216     /* get signMethod */
217     if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "signMethod",
218                                           signMethod)) {
219         OTA_LOG_ERROR("get value of signMethod key failed");
220         return -1;
221     }
222 
223     /* get url */
224     if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "url", url)) {
225         OTA_LOG_ERROR("get value of url key failed");
226         return -1;
227     }
228 
229     /* get getType */
230     if (0 !=
231         otalib_GetFirmwareVarlenPara(json_doc, json_len, "getType", getType)) {
232         OTA_LOG_ERROR("get value of getType key failed");
233         return -1;
234     }
235     return 0;
236 
237 #undef OTA_FILESIZE_STR_LEN
238 }
239 
240 /* Generate firmware information according to @id, @version */
241 /* and then copy to @buf. */
242 /* 0, successful; -1, failed */
otalib_GenInfoMsg(char * buf,size_t buf_len,uint32_t id,const char * version)243 int otalib_GenInfoMsg(char *buf, size_t buf_len, uint32_t id,
244                       const char *version)
245 {
246     int ret;
247     ret = HAL_Snprintf(buf, buf_len,
248                        "{\"id\":%d,\"params\":{\"version\":\"%s\"}}", id,
249                        version);
250 
251     if (ret < 0) {
252         OTA_LOG_ERROR("HAL_Snprintf failed");
253         return -1;
254     }
255 
256     return 0;
257 }
258 
259 /* Generate report information according to @id, @msg */
260 /* and then copy to @buf. */
261 /* 0, successful; -1, failed */
otalib_GenReportMsg(char * buf,size_t buf_len,uint32_t id,int progress,const char * msg_detail)262 int otalib_GenReportMsg(char *buf, size_t buf_len, uint32_t id, int progress,
263                         const char *msg_detail)
264 {
265     int ret;
266     if (NULL == msg_detail) {
267         ret = HAL_Snprintf(
268             buf, buf_len,
269             "{\"id\":%d,\"params\":{\"step\":\"%d\",\"desc\":\"\"}}", id,
270             progress);
271     } else {
272         ret = HAL_Snprintf(
273             buf, buf_len,
274             "{\"id\":%d,\"params\":{\"step\":\"%d\",\"desc\":\"%s\"}}", id,
275             progress, msg_detail);
276     }
277 
278     if (ret < 0) {
279         OTA_LOG_ERROR("HAL_Snprintf failed");
280         return -1;
281     } else if (ret >= buf_len) {
282         OTA_LOG_ERROR("msg is too long");
283         return IOT_OTAE_STR_TOO_LONG;
284     }
285 
286     return 0;
287 }
288