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