1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12 #include "nx_azure_iot_adu_agent.h"
13
14 /* ADU Version e.g: AzureRTOS;agent/x.x.x */
15 #define NX_AZURE_IOT_ADU_AGENT_STR(C) #C
16 #define NX_AZURE_IOT_ADU_AGENT_TO_STR(x) NX_AZURE_IOT_ADU_AGENT_STR(x)
17 #define NX_AZURE_IOT_ADU_AGENT_VERSION "AzureRTOS;agent/" \
18 NX_AZURE_IOT_ADU_AGENT_TO_STR(NETXDUO_MAJOR_VERSION) "." \
19 NX_AZURE_IOT_ADU_AGENT_TO_STR(NETXDUO_MINOR_VERSION) "." \
20 NX_AZURE_IOT_ADU_AGENT_TO_STR(NETXDUO_PATCH_VERSION)
21
22 /* Update buffer pointer and buffer size. */
23 #define NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(a, b, c, d) { \
24 (a) = (c); \
25 (c) += (b); \
26 (d) -= (b); \
27 }
28
29 static VOID nx_azure_iot_adu_agent_event_process(VOID *adu_agent, ULONG common_events, ULONG module_own_events);
30 static VOID nx_azure_iot_adu_agent_timer_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
31 static VOID nx_azure_iot_adu_agent_update_check_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
32 static VOID nx_azure_iot_adu_agent_download_install_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
33 static VOID nx_azure_iot_adu_agent_apply_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
34 static UINT nx_azure_iot_adu_agent_manifest_verify(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
35 static UINT nx_azure_iot_adu_agent_jws_split(UCHAR *jws, UINT jws_length,
36 UCHAR **header, UINT *header_length,
37 UCHAR **payload, UINT *payload_length,
38 UCHAR **signature, UINT *signature_length);
39 static UINT nx_azure_iot_adu_agent_service_properties_get(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
40 NX_AZURE_IOT_JSON_READER *json_reader_ptr);
41 static UINT nx_azure_iot_adu_agent_service_update_manifest_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
42 UCHAR *update_manifest,
43 UINT update_manifest_size,
44 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *update_manifest_content,
45 UCHAR *update_manifest_content_buffer,
46 UINT update_manifest_content_buffer_size);
47 static UINT nx_azure_iot_adu_agent_service_reported_properties_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
48 UINT status_code, ULONG version, const CHAR *description,
49 ULONG wait_option);
50 static UINT nx_azure_iot_adu_agent_reported_properties_startup_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT wait_option);
51 static UINT nx_azure_iot_adu_agent_reported_properties_state_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
52 static VOID nx_azure_iot_adu_agent_step_state_update(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT step_state);
53 static UINT nx_azure_iot_adu_agent_file_find(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
54 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *manifest_content,
55 UCHAR *file_id, UINT file_id_length,
56 NX_AZURE_IOT_ADU_AGENT_FILE **file);
57 static UINT nx_azure_iot_adu_agent_method_is_installed(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
58 NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY *compatibility,
59 NX_AZURE_IOT_ADU_AGENT_STEP *step,
60 UINT *is_installed);
61 static UINT nx_azure_iot_adu_agent_method_download(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
62 NX_AZURE_IOT_ADU_AGENT_FILE *file,
63 UINT type, UCHAR *buffer_ptr, UINT buffer_size,
64 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *));
65 static UINT nx_azure_iot_adu_agent_method_install(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
66 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *));
67 static UINT nx_azure_iot_adu_agent_method_apply(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
68 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *));
69 static const NX_AZURE_IOT_ADU_AGENT_RSA_ROOT_KEY *nx_azure_iot_adu_agent_rsa_root_key_find(const UCHAR* kid, UINT kid_size);
70 static UINT nx_azure_iot_adu_agent_sha256_calculate(NX_CRYPTO_METHOD *sha256_method,
71 UCHAR *metadata_ptr, UINT metadata_size,
72 UCHAR *input_ptr, ULONG input_size,
73 UCHAR *output_ptr, ULONG output_size);
74 static UINT nx_azure_iot_adu_agent_rs256_verify(NX_AZURE_IOT_ADU_AGENT_CRYPTO *adu_agent_crypto,
75 UCHAR *input_ptr, ULONG input_size,
76 UCHAR *signature_ptr, ULONG signature_size,
77 UCHAR *n, ULONG n_size,
78 UCHAR *e, ULONG e_size,
79 UCHAR *buffer_ptr, UINT buffer_size);
80 static UINT nx_azure_iot_adu_agent_file_url_parse(UCHAR *file_url, ULONG file_url_length,
81 UCHAR *buffer_ptr, UINT buffer_size,
82 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr);
83 static void nx_azure_iot_adu_agent_dns_query(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
84 static void nx_azure_iot_adu_agent_dns_response_notify(NX_UDP_SOCKET *socket_ptr);
85 static void nx_azure_iot_adu_agent_dns_response_get(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
86 static void nx_azure_iot_adu_agent_http_connect(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
87 static void nx_azure_iot_adu_agent_http_request_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
88 static void nx_azure_iot_adu_agent_http_response_receive(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr);
89 static void nx_azure_iot_adu_agent_http_establish_notify(NX_TCP_SOCKET *socket_ptr);
90 static void nx_azure_iot_adu_agent_http_receive_notify(NX_TCP_SOCKET *socket_ptr);
91 static void nx_azure_iot_adu_agent_download_state_update(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT success);
92 static UINT nx_azure_iot_adu_agent_component_properties_process(VOID *reader_ptr,
93 ULONG version,
94 VOID *args);
95 extern UINT nx_azure_iot_hub_client_component_add_internal(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
96 const UCHAR *component_name_ptr,
97 USHORT component_name_length,
98 UINT (*callback_ptr)(VOID *json_reader_ptr,
99 ULONG version,
100 VOID *args),
101 VOID *callback_args);
102 extern VOID nx_azure_iot_hub_client_properties_component_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
103 NX_PACKET *packet_ptr, UINT message_type);
104
nx_azure_iot_adu_agent_start(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,NX_AZURE_IOT_HUB_CLIENT * iothub_client_ptr,const UCHAR * manufacturer,UINT manufacturer_length,const UCHAR * model,UINT model_length,const UCHAR * installed_criteria,UINT installed_criteria_length,VOID (* adu_agent_update_notify)(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UINT update_state,UCHAR * provider,UINT provider_length,UCHAR * name,UINT name_length,UCHAR * version,UINT version_length),VOID (* adu_agent_update_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))105 UINT nx_azure_iot_adu_agent_start(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
106 NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
107 const UCHAR *manufacturer, UINT manufacturer_length,
108 const UCHAR *model, UINT model_length,
109 const UCHAR *installed_criteria, UINT installed_criteria_length,
110 VOID (*adu_agent_update_notify)(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
111 UINT update_state,
112 UCHAR *provider, UINT provider_length,
113 UCHAR *name, UINT name_length,
114 UCHAR *version, UINT version_length),
115 VOID (*adu_agent_update_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))
116 {
117 UINT i;
118 UINT status;
119 NX_AZURE_IOT *nx_azure_iot_ptr;
120 NX_AZURE_IOT_RESOURCE *resource_ptr;
121 NX_CRYPTO_METHOD *method_sha256 = NX_NULL;
122 NX_CRYPTO_METHOD *method_rsa = NX_NULL;
123 NX_SECURE_TLS_SESSION *tls_session;
124 NX_AZURE_IOT_ADU_AGENT_CRYPTO *adu_agent_crypto;
125 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
126 UINT component_added = NX_FALSE;
127
128 if ((adu_agent_ptr == NX_NULL) || (iothub_client_ptr == NX_NULL) ||
129 (manufacturer == NX_NULL) || (manufacturer_length == 0) ||
130 (model == NX_NULL) || (model_length == 0) ||
131 ((installed_criteria == NX_NULL) && (installed_criteria_length != 0)) ||
132 (adu_agent_update_driver == NX_NULL))
133 {
134 LogError(LogLiteralArgs("ADU agent start fail: INVALID POINTER"));
135 return(NX_AZURE_IOT_INVALID_PARAMETER);
136 }
137
138 /* Check if IoT Hub connected. */
139 if (iothub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
140 {
141 LogError(LogLiteralArgs("ADU agent start fail: IOTHUB NOT CONNECTED"));
142 return(NX_AZURE_IOT_WRONG_STATE);
143 }
144
145 /* Check if properties is enabled. */
146 if (iothub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_enable == NX_NULL)
147 {
148 LogError(LogLiteralArgs("ADU agent start fail: PROPERTIES NOT ENABLED"));
149 return(NX_AZURE_IOT_NOT_ENABLED);
150 }
151
152 memset(adu_agent_ptr, 0, sizeof(NX_AZURE_IOT_ADU_AGENT));
153
154 /* Set iothub client pointer and azure iot pointer. */
155 adu_agent_ptr -> nx_azure_iot_hub_client_ptr = iothub_client_ptr;
156 nx_azure_iot_ptr = iothub_client_ptr -> nx_azure_iot_ptr;
157
158 /* Set component process routine for system component. */
159 iothub_client_ptr -> nx_azure_iot_hub_client_component_properties_process = nx_azure_iot_hub_client_properties_component_process;
160
161 /* Check if the component has been added. */
162 for (i = 0; i < (UINT)iothub_client_ptr -> iot_hub_client_core._internal.options.component_names_length; i++)
163 {
164
165 /* Compare the component. */
166 if ((iothub_client_ptr -> iot_hub_client_core._internal.options.component_names[i]._internal.size == sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1) &&
167 (!memcmp(iothub_client_ptr -> iot_hub_client_core._internal.options.component_names[i]._internal.ptr, NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME, sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1)))
168 {
169 component_added = NX_TRUE;
170 }
171 }
172
173 /* Add ADU component. */
174 if (component_added == NX_FALSE)
175 {
176 if ((status = nx_azure_iot_hub_client_component_add_internal(iothub_client_ptr,
177 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME,
178 sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1,
179 nx_azure_iot_adu_agent_component_properties_process,
180 adu_agent_ptr)))
181 {
182 LogError(LogLiteralArgs("ADU agent start fail: COMPONENT ADD FAIL: %d"), status);
183 return(status);
184 }
185 }
186
187 /* Save the mutex. */
188 adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr = nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr;
189
190 /* Find RSA and SHA256. */
191 resource_ptr = &(iothub_client_ptr -> nx_azure_iot_hub_client_resource);
192 for(i = 0; i < resource_ptr -> resource_crypto_array_size; i++)
193 {
194 if(resource_ptr -> resource_crypto_array[i] -> nx_crypto_algorithm == NX_CRYPTO_HASH_SHA256)
195 {
196 method_sha256 = (NX_CRYPTO_METHOD *)resource_ptr -> resource_crypto_array[i];
197 }
198 else if(resource_ptr -> resource_crypto_array[i] -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_RSA)
199 {
200 method_rsa = (NX_CRYPTO_METHOD *)resource_ptr -> resource_crypto_array[i];
201 }
202
203 if ((method_sha256) && (method_rsa))
204 {
205 break;
206 }
207 }
208
209 /* Check if find the crypto method. */
210 if ((method_sha256 == NX_NULL) ||
211 (method_sha256 -> nx_crypto_operation == NX_NULL) ||
212 (method_rsa == NX_NULL) ||
213 (method_rsa -> nx_crypto_init == NX_NULL) ||
214 (method_rsa -> nx_crypto_operation == NX_NULL) )
215 {
216 LogError(LogLiteralArgs("ADU agent start fail: NO AVAILABLE CIPHER"));
217 return(NX_AZURE_IOT_NO_AVAILABLE_CIPHER);
218 }
219
220 /* Check if the metadata size is enough. */
221 if (method_sha256 -> nx_crypto_metadata_area_size > NX_AZURE_IOT_ADU_AGENT_SHA256_METADATA_SIZE)
222 {
223 LogError(LogLiteralArgs("ADU agent start fail: INSUFFICIENT BUFFER FOR SHA256"));
224 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
225 }
226
227 /* Save the crypto methods (RS256) for verifying update manifest. */
228 adu_agent_crypto = &(adu_agent_ptr -> nx_azure_iot_adu_agent_crypto);
229
230 /* Set RSA crypto, reuse the metadata from tls session. */
231 tls_session = &(iothub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_tls_session);
232 adu_agent_crypto -> method_rsa = method_rsa;
233 adu_agent_crypto -> method_rsa_metadata = tls_session -> nx_secure_public_cipher_metadata_area;
234 adu_agent_crypto -> method_rsa_metadata_size = tls_session -> nx_secure_public_cipher_metadata_size;
235
236 /* Set SHA256 crypto. */
237 adu_agent_crypto -> method_sha256 = method_sha256;
238
239 /* Call the driver to initialize the hardware. */
240 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_INITIALIZE;
241 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
242 (adu_agent_update_driver)(&driver_request);
243
244 /* Check status. */
245 if (driver_request.nx_azure_iot_adu_agent_driver_status)
246 {
247 LogError(LogLiteralArgs("ADU agent start fail: DRIVER ERROR"));
248 return(NX_AZURE_IOT_FAILURE);
249 }
250
251 /* Save the device properties (manufacturer and model). */
252 adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties.manufacturer = manufacturer;
253 adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties.manufacturer_length = manufacturer_length;
254 adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties.model = model;
255 adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties.model_length = model_length;
256
257 /* Save the device properties for compatibility. Compatibility defines the criteria of a device that can install the update. */
258 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].device_properties.manufacturer = manufacturer;
259 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].device_properties.manufacturer_length = manufacturer_length;
260 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].device_properties.model = model;
261 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].device_properties.model_length = model_length;
262 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].installed_criteria = installed_criteria;
263 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].installed_criteria_length = installed_criteria_length;
264
265 /* Save the driver. */
266 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].device_driver_entry = adu_agent_update_driver;
267
268 /* Set the entry as valid. */
269 adu_agent_ptr -> nx_azure_iot_adu_agent_device[0].valid = NX_TRUE;
270
271 /* Send agent startup message. */
272 status = nx_azure_iot_adu_agent_reported_properties_startup_send(adu_agent_ptr, NX_WAIT_FOREVER);
273 if (status)
274 {
275 LogError(LogLiteralArgs("ADU agent start fail: CLIENT REPORTED PROPERTIES SEND FAIL"));
276 return(status);
277 }
278
279 /* Set the state change notification. */
280 adu_agent_ptr -> nx_azure_iot_adu_agent_update_notify = adu_agent_update_notify;
281
282 /* Set the dns pointer. */
283 adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.dns_ptr = nx_azure_iot_ptr -> nx_azure_iot_dns_ptr;
284
285 /* Set the UDP socket receive callback function for non-blocking DNS. */
286 nx_azure_iot_ptr -> nx_azure_iot_dns_ptr -> nx_dns_socket.nx_udp_socket_reserved_ptr = adu_agent_ptr;
287 nx_udp_socket_receive_notify(&(nx_azure_iot_ptr -> nx_azure_iot_dns_ptr -> nx_dns_socket),
288 nx_azure_iot_adu_agent_dns_response_notify);
289
290 /* Register ADU module on cloud helper. */
291 status = nx_cloud_module_register(&(nx_azure_iot_ptr -> nx_azure_iot_cloud),
292 &(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
293 "Azure Device Update Module",
294 (NX_CLOUD_MODULE_AZURE_ADU_EVENT | NX_CLOUD_COMMON_PERIODIC_EVENT),
295 nx_azure_iot_adu_agent_event_process, adu_agent_ptr);
296 if (status)
297 {
298 LogError(LogLiteralArgs("ADU module register fail status: %d"), status);
299 return(status);
300 }
301
302 LogInfo(LogLiteralArgs("ADU agent started successfully!"));
303
304 return(NX_AZURE_IOT_SUCCESS);
305 }
306
nx_azure_iot_adu_agent_stop(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)307 UINT nx_azure_iot_adu_agent_stop(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
308 {
309
310 if ((adu_agent_ptr == NX_NULL) || (adu_agent_ptr -> nx_azure_iot_hub_client_ptr == NX_NULL))
311 {
312 LogError(LogLiteralArgs("ADU agent stop fail: INVALID POINTER"));
313 return(NX_AZURE_IOT_INVALID_PARAMETER);
314 }
315
316 /* Obtain the mutex. */
317 tx_mutex_get(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr, NX_WAIT_FOREVER);
318
319 /* Check if there is downloading socket. */
320 if ((adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_DEPLOYMENT_IN_PROGRESS) &&
321 (adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.state >= NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONNECT))
322 {
323
324 /* Delete http client. */
325 nx_web_http_client_delete(&(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.http_client));
326 }
327
328 /* Release the mutex. */
329 tx_mutex_put(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr);
330
331 /* Deregister ADU module on cloud helper. */
332 nx_cloud_module_deregister(&(adu_agent_ptr -> nx_azure_iot_hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_cloud),
333 &(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module));
334
335 LogInfo(LogLiteralArgs("ADU agent stopped!"));
336
337 return(NX_AZURE_IOT_SUCCESS);
338 }
339
nx_azure_iot_adu_agent_update_download_and_install(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)340 UINT nx_azure_iot_adu_agent_update_download_and_install(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
341 {
342 UINT status;
343
344 if (adu_agent_ptr == NX_NULL)
345 {
346 LogError(LogLiteralArgs("ADU agent download&install fail: INVALID POINTER"));
347 return(NX_AZURE_IOT_INVALID_PARAMETER);
348 }
349
350 /* Reset the step. */
351 adu_agent_ptr -> nx_azure_iot_adu_agent_current_step = NX_NULL;
352
353 /* Set event to download and install update. */
354 status = nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
355 NX_AZURE_IOT_ADU_AGENT_DOWNLOAD_INSTALL_EVENT);
356
357 return(status);
358 }
359
nx_azure_iot_adu_agent_update_apply(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)360 UINT nx_azure_iot_adu_agent_update_apply(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
361 {
362 UINT status;
363
364 if (adu_agent_ptr == NX_NULL)
365 {
366 LogError(LogLiteralArgs("ADU agent apply fail: INVALID POINTER"));
367 return(NX_AZURE_IOT_INVALID_PARAMETER);
368 }
369
370 /* Set event to deploy update. */
371 status = nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
372 NX_AZURE_IOT_ADU_AGENT_APPLY_EVENT);
373
374 return(status);
375 }
376
377 #if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1)
nx_azure_iot_adu_agent_proxy_update_add(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,const UCHAR * manufacturer,UINT manufacturer_length,const UCHAR * model,UINT model_length,const UCHAR * installed_criteria,UINT installed_criteria_length,VOID (* adu_agent_proxy_update_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))378 UINT nx_azure_iot_adu_agent_proxy_update_add(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
379 const UCHAR *manufacturer, UINT manufacturer_length,
380 const UCHAR *model, UINT model_length,
381 const UCHAR *installed_criteria, UINT installed_criteria_length,
382 VOID (*adu_agent_proxy_update_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))
383 {
384 UINT i;
385 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
386
387 if ((adu_agent_ptr == NX_NULL) ||
388 (manufacturer == NX_NULL) || (manufacturer_length == 0) ||
389 (model == NX_NULL) || (model_length == 0) ||
390 ((installed_criteria == NX_NULL) && (installed_criteria_length != 0)) ||
391 (adu_agent_proxy_update_driver == NX_NULL))
392 {
393 LogError(LogLiteralArgs("ADU agent proxy update fail: INVALID POINTER"));
394 return(NX_AZURE_IOT_INVALID_PARAMETER);
395 }
396
397 /* Compatibility defines the criteria of a device that can install the update. It contains device properties (manufacturer and model). */
398
399 /* Obtain the mutex. */
400 tx_mutex_get(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr, NX_WAIT_FOREVER);
401
402 /* Find available entry. */
403 for (i = 0; i < NX_AZURE_IOT_ADU_AGENT_DEVICE_COUNT; i++)
404 {
405 if (adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].valid == NX_FALSE)
406 {
407
408 /* Find available entry. */
409 break;
410 }
411 }
412
413 /* Check if find an available entry. */
414 if (i >= NX_AZURE_IOT_ADU_AGENT_DEVICE_COUNT)
415 {
416
417 /* Release the mutex. */
418 tx_mutex_put(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr);
419 return(NX_AZURE_IOT_NO_MORE_ENTRIES);
420 }
421
422 /* Call the driver to initialize the hardware. */
423 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_INITIALIZE;
424 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
425 (adu_agent_proxy_update_driver)(&driver_request);
426
427 /* Check status. */
428 if (driver_request.nx_azure_iot_adu_agent_driver_status)
429 {
430
431 /* Release the mutex. */
432 tx_mutex_put(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr);
433 LogError(LogLiteralArgs("ADU agent start fail: DRIVER ERROR"));
434 return(NX_AZURE_IOT_FAILURE);
435 }
436
437 /* Setup the driver. */
438 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_driver_entry = adu_agent_proxy_update_driver;
439
440 /* Save the device properties for compatibility. Compatibility defines the criteria of a device that can install the update. */
441 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.manufacturer = manufacturer;
442 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.manufacturer_length = manufacturer_length;
443 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.model = model;
444 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.model_length = model_length;
445 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].installed_criteria = installed_criteria;
446 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].installed_criteria_length = installed_criteria_length;
447
448 /* Set the entry as valid. */
449 adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].valid = NX_TRUE;
450
451 /* Release the mutex. */
452 tx_mutex_put(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr);
453
454 return(NX_AZURE_IOT_SUCCESS);
455 }
456 #endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */
457
nx_azure_iot_adu_agent_component_properties_process(VOID * reader_ptr,ULONG version,VOID * args)458 static UINT nx_azure_iot_adu_agent_component_properties_process(VOID *reader_ptr,
459 ULONG version,
460 VOID *args)
461 {
462 UINT status;
463 NX_AZURE_IOT_JSON_READER *json_reader_ptr = (NX_AZURE_IOT_JSON_READER *)reader_ptr;
464 NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr = (NX_AZURE_IOT_ADU_AGENT *)args;
465
466 /* Check the state. */
467 if (adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_DEPLOYMENT_IN_PROGRESS)
468 {
469
470 /* The JSON reader must be advanced regardless of whether the property
471 is of interest or not. */
472 nx_azure_iot_json_reader_next_token(reader_ptr);
473
474 /* Skip children in case the property value is an object. */
475 if (nx_azure_iot_json_reader_token_type(reader_ptr) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
476 {
477 nx_azure_iot_json_reader_skip_children(reader_ptr);
478 }
479 nx_azure_iot_json_reader_next_token(reader_ptr);
480
481 return(NX_AZURE_IOT_SUCCESS);
482 }
483
484 /* Check "service" property name. */
485 if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
486 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SERVICE,
487 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SERVICE) - 1))
488 {
489
490 /* Get service property value. */
491 status = nx_azure_iot_adu_agent_service_properties_get(adu_agent_ptr, json_reader_ptr);
492 if (status)
493 {
494 LogError(LogLiteralArgs("ADU agent component process fail: SERVICE PROPERTIES GET FAIL"));
495 return(status);
496 }
497
498 /* Send service response. */
499 nx_azure_iot_adu_agent_service_reported_properties_send(adu_agent_ptr,
500 NX_AZURE_IOT_ADU_AGENT_STATUS_SUCCESS, version, "",
501 NX_NO_WAIT);
502
503 /* Check the action. */
504 if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.action == NX_AZURE_IOT_ADU_AGENT_ACTION_CANCEL)
505 {
506
507 /* Reset the state. */
508 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_IDLE;
509
510 /* Report idle state to server. */
511 nx_azure_iot_adu_agent_reported_properties_state_send(adu_agent_ptr);
512
513 LogInfo(LogLiteralArgs("Cancel Command received"));
514 return(NX_AZURE_IOT_SUCCESS);
515 }
516
517 else if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.action != NX_AZURE_IOT_ADU_AGENT_ACTION_APPLY_DEPLOYMENT)
518 {
519 return(NX_AZURE_IOT_FAILURE);
520 }
521
522
523 /* Verify manifest. */
524 if (nx_azure_iot_adu_agent_manifest_verify(adu_agent_ptr) != NX_TRUE)
525 {
526 LogError(LogLiteralArgs("Failed to verify update manifest signature"));
527 return(NX_AZURE_IOT_FAILURE);
528 }
529
530 /* Process deployable update manifest. */
531 if (nx_azure_iot_adu_agent_service_update_manifest_process(adu_agent_ptr,
532 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
533 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_size,
534 &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content),
535 adu_agent_ptr -> nx_azure_iot_adu_agent_buffer,
536 NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE))
537 {
538 LogError(LogLiteralArgs("ADU agent component process fail: UPDATE MANIFEST PROCESS FAIL"));
539 return(NX_AZURE_IOT_FAILURE);
540 }
541
542 /* Reset. */
543 adu_agent_ptr -> nx_azure_iot_adu_agent_current_step = NX_NULL;
544 adu_agent_ptr -> nx_azure_iot_adu_agent_update_flag = NX_FALSE;
545
546 /* Update the state. */
547 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_DEPLOYMENT_IN_PROGRESS;
548
549 /* Set event to start update automatically. */
550 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
551 NX_AZURE_IOT_ADU_AGENT_UPDATE_EVENT);
552 }
553 else
554 {
555 return(NX_AZURE_IOT_FAILURE);
556 }
557
558 return(NX_AZURE_IOT_SUCCESS);
559 }
560
nx_azure_iot_adu_agent_event_process(VOID * adu_agent,ULONG common_events,ULONG module_own_events)561 static VOID nx_azure_iot_adu_agent_event_process(VOID *adu_agent, ULONG common_events, ULONG module_own_events)
562 {
563
564 NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr = (NX_AZURE_IOT_ADU_AGENT *)adu_agent;
565
566 /* Obtain the mutex. */
567 tx_mutex_get(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr, NX_WAIT_FOREVER);
568
569 /* Process common periodic event. */
570 if (common_events & NX_CLOUD_COMMON_PERIODIC_EVENT)
571 {
572
573 /* Process timer event. */
574 nx_azure_iot_adu_agent_timer_event_process(adu_agent_ptr);
575 }
576
577 /* Process events. */
578 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_UPDATE_EVENT)
579 {
580
581 /* Update check. */
582 nx_azure_iot_adu_agent_update_check_event_process(adu_agent_ptr);
583 }
584 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_DOWNLOAD_INSTALL_EVENT)
585 {
586
587 /* Update download and install. */
588 nx_azure_iot_adu_agent_download_install_event_process(adu_agent_ptr);
589 }
590 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_APPLY_EVENT)
591 {
592
593 /* Update apply. */
594 nx_azure_iot_adu_agent_apply_event_process(adu_agent_ptr);
595 }
596 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_DNS_RESPONSE_RECEIVE_EVENT)
597 {
598
599 /* Process DNS response get event. */
600 nx_azure_iot_adu_agent_dns_response_get(adu_agent_ptr);
601 }
602 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_HTTP_CONNECT_DONE_EVENT)
603 {
604
605 /* Process HTTP connect done event. */
606 nx_azure_iot_adu_agent_http_request_send(adu_agent_ptr);
607 }
608 if (module_own_events & NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT)
609 {
610
611 /* Process HTTP receive event. */
612 nx_azure_iot_adu_agent_http_response_receive(adu_agent_ptr);
613 }
614
615 /* Release the mutex. */
616 tx_mutex_put(adu_agent_ptr -> nx_azure_iot_adu_agent_mutex_ptr);
617 }
618
nx_azure_iot_adu_agent_timer_event_process(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)619 static VOID nx_azure_iot_adu_agent_timer_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
620 {
621
622 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
623
624 /* Check the timer for DNS/HTTP. */
625 if (downloader_ptr -> timeout)
626 {
627
628 /* Decrease the timeout. */
629 downloader_ptr -> timeout--;
630
631 /* Check if it is timeout. */
632 if (downloader_ptr -> timeout != 0)
633 {
634 return;
635 }
636
637 /* Check the state. */
638 if (downloader_ptr -> state == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_QUERY)
639 {
640
641 /* DNS query timeout, try to receive dns response, if there is no DNS response. Retry DNS query. */
642 nx_azure_iot_adu_agent_dns_response_get(adu_agent_ptr);
643 }
644 else if ((downloader_ptr -> state == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONNECT) ||
645 (downloader_ptr -> state == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONTENT_GET))
646 {
647 LogError(LogLiteralArgs("Firmware download fail: TIMEOUT"));
648
649 /* Timeout for http connect or http content get. */
650 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
651 }
652 }
653 }
654
nx_azure_iot_adu_agent_update_check_event_process(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)655 static VOID nx_azure_iot_adu_agent_update_check_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
656 {
657 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *update_manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content);
658 NX_AZURE_IOT_ADU_AGENT_STEP *step;
659 NX_AZURE_IOT_ADU_AGENT_FILE *file;
660 UINT is_installed = NX_FALSE;
661 UINT i;
662 #if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1)
663 UCHAR *json_data_ptr;
664 NX_AZURE_IOT_JSON_READER json_reader;
665 UCHAR *proxy_update_manifest_ptr;
666 UINT proxy_update_manifest_size;
667 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *proxy_update_manifest_content;
668 NX_AZURE_IOT_ADU_AGENT_STEP *proxy_step;
669 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
670 #endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */
671
672 /* Check if current step is completed or not. */
673 if ((adu_agent_ptr -> nx_azure_iot_adu_agent_current_step == NX_NULL) ||
674 (adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_STARTED) ||
675 (adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_APPLY_SUCCEEDED))
676 {
677 for (i = 0; i < update_manifest_content -> steps_count; i++)
678 {
679
680 /* Check the state. */
681 if (update_manifest_content -> steps[i].state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_IDLE)
682 {
683 adu_agent_ptr -> nx_azure_iot_adu_agent_current_step = &(update_manifest_content -> steps[i]);
684 break;
685 }
686 }
687
688 /* Check if all steps are checked. */
689 if (i == update_manifest_content -> steps_count)
690 {
691
692 /* Check if all updates are installed. */
693 if (adu_agent_ptr -> nx_azure_iot_adu_agent_update_flag == NX_TRUE)
694 {
695
696 /* If there is a new update, report deployment in progress state to server and start to download. */
697 nx_azure_iot_adu_agent_reported_properties_state_send(adu_agent_ptr);
698
699 /* Check if set the update notify. */
700 if (adu_agent_ptr -> nx_azure_iot_adu_agent_update_notify)
701 {
702
703 /* Notify the user and let users control the update. */
704 adu_agent_ptr -> nx_azure_iot_adu_agent_update_notify(adu_agent_ptr,
705 NX_AZURE_IOT_ADU_AGENT_UPDATE_RECEIVED,
706 (UCHAR *)update_manifest_content -> update_id.provider,
707 update_manifest_content -> update_id.provider_length,
708 (UCHAR *)update_manifest_content -> update_id.name,
709 update_manifest_content -> update_id.name_length,
710 (UCHAR *)update_manifest_content -> update_id.version,
711 update_manifest_content -> update_id.version_length);
712 }
713 else
714 {
715
716 /* Set event to start update automatically. */
717 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
718 NX_AZURE_IOT_ADU_AGENT_DOWNLOAD_INSTALL_EVENT);
719 }
720 }
721 else
722 {
723
724 /* All updates are installed and applied. */
725 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_IDLE;
726
727 /* Send reported properties to notify server. */
728 nx_azure_iot_adu_agent_reported_properties_state_send(adu_agent_ptr);
729 }
730
731 return;
732 }
733 }
734
735 step = adu_agent_ptr -> nx_azure_iot_adu_agent_current_step;
736 switch (step -> state)
737 {
738
739 /* Idle. */
740 case NX_AZURE_IOT_ADU_AGENT_STEP_STATE_IDLE:
741 {
742
743 /* Check the type and handler properties. */
744 if (((step -> type_length != 0) &&
745 (step -> type_length == sizeof(NX_AZURE_IOT_ADU_AGENT_STEP_TYPE_INLINE) - 1) &&
746 (!memcmp(step -> type, NX_AZURE_IOT_ADU_AGENT_STEP_TYPE_INLINE, step -> type_length))) ||
747 ((step -> type_length == 0) &&
748 (step -> handler_length == sizeof(NX_AZURE_IOT_ADU_AGENT_STEP_HANDLER_SWUPDATE) - 1) &&
749 (!memcmp(step -> handler, NX_AZURE_IOT_ADU_AGENT_STEP_HANDLER_SWUPDATE, step -> handler_length))))
750 {
751
752 /* Call method to check if the update is installed. */
753 if (nx_azure_iot_adu_agent_method_is_installed(adu_agent_ptr, &(update_manifest_content -> compatibility), step, &is_installed))
754 {
755 LogError(LogLiteralArgs("Failed to check the update"));
756 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
757 return;
758 }
759
760 if (is_installed == NX_TRUE)
761 {
762 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_APPLY_SUCCEEDED);
763 }
764 else
765 {
766
767 /* Find the new update file and update it into step. */
768 if (nx_azure_iot_adu_agent_file_find(adu_agent_ptr, update_manifest_content, (UCHAR *)step -> file_id, step -> file_id_length, &file))
769 {
770 LogError(LogLiteralArgs("Failed to find update file"));
771 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
772 return;
773 }
774
775 /* Set the file as new update. */
776 step -> file = file;
777 adu_agent_ptr -> nx_azure_iot_adu_agent_update_flag = NX_TRUE;
778
779 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_STARTED);
780 }
781 }
782 #if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1)
783 else if ((step -> type_length == sizeof(NX_AZURE_IOT_ADU_AGENT_STEP_TYPE_REFERENCE) - 1) &&
784 (!memcmp(step -> type, NX_AZURE_IOT_ADU_AGENT_STEP_TYPE_REFERENCE, step -> type_length)))
785 {
786
787 /* Leaf update. */
788
789 /* Find the manifest file. */
790 if (nx_azure_iot_adu_agent_file_find(adu_agent_ptr, update_manifest_content, (UCHAR *)step -> file_id, step -> file_id_length, &file))
791 {
792 LogError(LogLiteralArgs("Failed to find proxy manifest file"));
793 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
794 return;
795 }
796
797 /* Update the state. */
798 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_MANIFEST_DOWNLOAD_STARTED);
799
800 /* Start to download firmware. */
801 if (nx_azure_iot_adu_agent_method_download(adu_agent_ptr, file, NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_MANIFEST,
802 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature,
803 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIGNATURE_SIZE,
804 NX_NULL))
805 {
806 LogError(LogLiteralArgs("Failed to download proxy manifest file"));
807 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
808 }
809
810 return;
811 }
812 #endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */
813
814 break;
815 }
816
817 #if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1)
818 case NX_AZURE_IOT_ADU_AGENT_STEP_STATE_MANIFEST_DOWNLOAD_SUCCEEDED:
819 {
820 json_data_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature;
821 proxy_update_manifest_ptr = json_data_ptr + downloader_ptr -> received_firmware_size;
822 proxy_update_manifest_size = NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIGNATURE_SIZE - downloader_ptr -> received_firmware_size;
823 proxy_update_manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_proxy_update_manifest_content);
824
825 /* There may be 3 BOM bytes (EF BB BF) for UTF-8 json, skip them if exist. */
826 if ((downloader_ptr -> received_firmware_size > 3) &&
827 ((json_data_ptr[0] == 0xEF) && (json_data_ptr[1] == 0xBB) && (json_data_ptr[2] == 0XBF)))
828 {
829 json_data_ptr +=3;
830 downloader_ptr -> received_firmware_size -= 3;
831 }
832
833 /* Initialize the update manifest string as json. */
834 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader,
835 json_data_ptr,
836 downloader_ptr -> received_firmware_size))
837 {
838 LogError(LogLiteralArgs("Failed to initialize proxy update manifest"));
839 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
840 return;
841 }
842
843 /* Skip the first begin object. */
844 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
845 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT) ||
846 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
847 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME) ||
848 (!nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
849 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST,
850 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST) - 1)) ||
851 (nx_azure_iot_json_reader_next_token(&json_reader)) ||
852 (nx_azure_iot_json_reader_token_string_get(&json_reader,
853 proxy_update_manifest_ptr,
854 proxy_update_manifest_size,
855 &proxy_update_manifest_size)))
856 {
857 LogError(LogLiteralArgs("Failed to process proxy update manifest"));
858 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
859 return;
860 }
861
862 /* Process proxy update manifest. */
863 if (nx_azure_iot_adu_agent_service_update_manifest_process(adu_agent_ptr,
864 proxy_update_manifest_ptr,
865 proxy_update_manifest_size,
866 proxy_update_manifest_content,
867 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_sjwk,
868 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SJWK_SIZE))
869 {
870 LogError(LogLiteralArgs("Failed to process proxy update manifest"));
871 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
872 return;
873 }
874
875 if (proxy_update_manifest_content -> steps_count != 1)
876 {
877 LogError(LogLiteralArgs("Failed to process proxy update manifest"));
878 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
879 return;
880 }
881
882 proxy_step = &(proxy_update_manifest_content -> steps[0]);
883
884 /* Update the installed criteria for reference step. */
885 step -> installed_criteria = proxy_step -> installed_criteria;
886 step -> installed_criteria_length = proxy_step -> installed_criteria_length;
887
888 /* Call method to check if the update is installed. */
889 if (nx_azure_iot_adu_agent_method_is_installed(adu_agent_ptr, &(proxy_update_manifest_content -> compatibility), step, &is_installed))
890 {
891 LogError(LogLiteralArgs("Failed to check the update"));
892 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
893 return;
894 }
895
896 if (is_installed == NX_TRUE)
897 {
898 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_APPLY_SUCCEEDED);
899 }
900 else
901 {
902
903 /* Find the new update file and update it into step. */
904 if (nx_azure_iot_adu_agent_file_find(adu_agent_ptr, proxy_update_manifest_content, (UCHAR *)proxy_step -> file_id, proxy_step -> file_id_length, &file))
905 {
906 LogError(LogLiteralArgs("Failed to find update file"));
907 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
908 return;
909 }
910
911 /* Set the file as new update. */
912 step -> file = file;
913 adu_agent_ptr -> nx_azure_iot_adu_agent_update_flag = NX_TRUE;
914
915 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_STARTED);
916 }
917
918 break;
919 }
920 #endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */
921
922 default:
923 {
924 return;
925 }
926 }
927
928 /* Set event for next update check. */
929 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
930 NX_AZURE_IOT_ADU_AGENT_UPDATE_EVENT);
931 }
932
nx_azure_iot_adu_agent_download_install_event_process(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)933 static VOID nx_azure_iot_adu_agent_download_install_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
934 {
935
936 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *update_manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content);
937 NX_AZURE_IOT_ADU_AGENT_STEP *step;
938 UINT i;
939
940 /* Check if current step is completed or not. */
941 if ((adu_agent_ptr -> nx_azure_iot_adu_agent_current_step == NX_NULL) ||
942 (adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_INSTALL_SUCCEEDED) ||
943 (adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_APPLY_SUCCEEDED))
944 {
945
946 /* Find next step to download and install the next firmware. */
947 for (i = 0; i < update_manifest_content -> steps_count; i++)
948 {
949 if (update_manifest_content -> steps[i].state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_STARTED)
950 {
951 break;
952 }
953 }
954
955 if (i < update_manifest_content -> steps_count)
956 {
957
958 /* Update the step to execute. */
959 adu_agent_ptr -> nx_azure_iot_adu_agent_current_step = &(update_manifest_content -> steps[i]);
960 }
961 else
962 {
963
964 /* All updates are downloaded and installed. */
965 if (adu_agent_ptr -> nx_azure_iot_adu_agent_update_notify)
966 {
967
968 /* Notify the user and let users control the update. */
969 adu_agent_ptr -> nx_azure_iot_adu_agent_update_notify(adu_agent_ptr,
970 NX_AZURE_IOT_ADU_AGENT_UPDATE_INSTALLED,
971 (UCHAR *)update_manifest_content -> update_id.provider,
972 update_manifest_content -> update_id.provider_length,
973 (UCHAR *)update_manifest_content -> update_id.name,
974 update_manifest_content -> update_id.name_length,
975 (UCHAR *)update_manifest_content -> update_id.version,
976 update_manifest_content -> update_id.version_length);
977 }
978 else
979 {
980
981 /* Set event to apply update automatically. */
982 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
983 NX_AZURE_IOT_ADU_AGENT_APPLY_EVENT);
984 }
985 return;
986 }
987 }
988
989 step = adu_agent_ptr -> nx_azure_iot_adu_agent_current_step;
990 switch (step -> state)
991 {
992 case NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_STARTED:
993 {
994
995 /* Download firmware. */
996 LogInfo(LogLiteralArgs("Updating firmware..."));
997 LogInfo(LogLiteralArgs("Manufacturer: %s"), step -> device -> device_properties.manufacturer, step -> device -> device_properties.manufacturer_length);
998 LogInfo(LogLiteralArgs("Model: %s"), step -> device -> device_properties.model, step -> device -> device_properties.model_length);
999
1000 /* Start to download firmware for host update. */
1001 if (nx_azure_iot_adu_agent_method_download(adu_agent_ptr, step -> file, NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE,
1002 NX_NULL, 0,
1003 step -> device -> device_driver_entry))
1004 {
1005 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
1006 return;
1007 }
1008
1009 break;
1010 }
1011
1012 case NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_SUCCEEDED:
1013 {
1014
1015 /* Install firmware. */
1016 if (nx_azure_iot_adu_agent_method_install(adu_agent_ptr, step -> device -> device_driver_entry))
1017 {
1018 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
1019 }
1020 else
1021 {
1022 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_INSTALL_SUCCEEDED);
1023 }
1024
1025 break;
1026 }
1027
1028 default:
1029 {
1030 break;
1031 }
1032 }
1033
1034 return;
1035 }
1036
nx_azure_iot_adu_agent_apply_event_process(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)1037 static VOID nx_azure_iot_adu_agent_apply_event_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
1038 {
1039 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content);
1040 NX_AZURE_IOT_ADU_AGENT_STEP *step;
1041 UINT i;
1042 UINT step_fail = NX_FALSE;
1043
1044
1045 /* Loop to apply the updates. */
1046 for (i = 0; i < manifest_content -> steps_count; i++)
1047 {
1048 step = &(manifest_content -> steps[i]);
1049
1050 /* Check the state. */
1051 if (step -> state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_INSTALL_SUCCEEDED)
1052 {
1053 LogInfo(LogLiteralArgs("Applying firmware..."));
1054 LogInfo(LogLiteralArgs("Manufacturer: %s"), step -> device -> device_properties.manufacturer, step -> device -> device_properties.manufacturer_length);
1055 LogInfo(LogLiteralArgs("Model: %s"), step -> device -> device_properties.model, step -> device -> device_properties.model_length);
1056
1057 /* Apply the update. */
1058 nx_azure_iot_adu_agent_method_apply(adu_agent_ptr, manifest_content -> steps[i].device -> device_driver_entry);
1059 }
1060 else if (manifest_content -> steps[i].state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED)
1061 {
1062 step_fail = NX_TRUE;
1063 break;
1064 }
1065 }
1066
1067 /* All steps done, update the state. */
1068 if (step_fail == NX_TRUE)
1069 {
1070 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_FAILED;
1071 }
1072 else
1073 {
1074 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_IDLE;
1075 }
1076
1077 /* Send reported properties to notify server. */
1078 nx_azure_iot_adu_agent_reported_properties_state_send(adu_agent_ptr);
1079 }
1080
nx_azure_iot_adu_agent_manifest_verify(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)1081 static UINT nx_azure_iot_adu_agent_manifest_verify(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
1082 {
1083 UINT status;
1084 UCHAR *header_b64;
1085 UINT header_b64_length;
1086 UCHAR *payload_b64;
1087 UINT payload_b64_length;
1088 UCHAR *signature_b64;
1089 UINT signature_b64_length;
1090 UCHAR *jwk_header_b64;
1091 UINT jwk_header_b64_length;
1092 UCHAR *jwk_payload_b64;
1093 UINT jwk_payload_b64_length;
1094 UCHAR *jwk_signature_b64;
1095 UINT jwk_signature_b64_length;
1096 UCHAR *signature;
1097 UINT signature_length;
1098 UINT sjwk_size = 0;
1099 UCHAR *alg_ptr = NX_NULL;
1100 UINT alg_size = 0;
1101 UCHAR *kid_ptr = NX_NULL;
1102 UINT kid_size = 0;
1103 UCHAR *kty_ptr = NX_NULL;
1104 UINT kty_size = 0;
1105 UCHAR *n_b64_ptr = NX_NULL;
1106 UINT n_b64_size = 0;
1107 UCHAR *e_b64_ptr = NX_NULL;
1108 UINT e_b64_size = 0;
1109 UCHAR *n_ptr = NX_NULL;
1110 UINT n_size = 0;
1111 UCHAR *e_ptr = NX_NULL;
1112 UINT e_size = 0;
1113 UCHAR *buffer_ptr;
1114 UINT buffer_size;
1115 UINT bytes_copied;
1116 NX_AZURE_IOT_ADU_AGENT_RSA_ROOT_KEY *rsa_root_key;
1117 NX_AZURE_IOT_ADU_AGENT_CRYPTO *adu_agent_crypto = &(adu_agent_ptr -> nx_azure_iot_adu_agent_crypto);
1118 NX_AZURE_IOT_JSON_READER json_reader;
1119 UCHAR *sha256_generated_hash_ptr;
1120 UCHAR *sha256_decoded_hash_64_ptr;
1121 UCHAR *sha256_decoded_hash_ptr;
1122
1123 /* The updateManifestSignature is used to ensure that the information contained within the updateManifest
1124 hasn't been tampered with.
1125 https://docs.microsoft.com/en-us/azure/iot-hub-device-update/device-update-security#json-web-signature-jws */
1126
1127 /* JWS value format: BASE64URL(UTF8(header)) + "." + BASE64URL(UTF8(payload) + "." + BASE64URL(signature)). */
1128
1129 /* Step1. Parse JWS data. */
1130
1131 /* Header:
1132 {
1133 "alg": "RS256",
1134 "sjwk": "signed JWK"
1135 }
1136
1137 Payload:
1138 {
1139 "sha256":"xxx...xxx"
1140 }
1141
1142 Signature:
1143 */
1144
1145 /* Initialize. */
1146 alg_size = 0;
1147 sjwk_size = 0;
1148 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_buffer;
1149 buffer_size = NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE;
1150
1151 /* 1.1 Split header, payload and signature. */
1152 if (nx_azure_iot_adu_agent_jws_split(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature,
1153 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature_size,
1154 &header_b64, &header_b64_length,
1155 &payload_b64, &payload_b64_length,
1156 &signature_b64, &signature_b64_length) == NX_FALSE)
1157 {
1158 return(NX_FALSE);
1159 }
1160
1161 /* 1.2 Decode header. */
1162 if (_nx_utility_base64_decode(header_b64, header_b64_length,
1163 buffer_ptr, buffer_size, &bytes_copied))
1164 {
1165 return(NX_FALSE);
1166 }
1167
1168 /* Initialize the header string as json. */
1169 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader, buffer_ptr, bytes_copied))
1170 {
1171 return(NX_FALSE);
1172 }
1173 buffer_ptr += bytes_copied;
1174 buffer_size -= bytes_copied;
1175
1176 /* Skip the first begin object. */
1177 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
1178 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
1179 {
1180 return(NX_FALSE);
1181 }
1182
1183 /* Loop to process all data. */
1184 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
1185 {
1186 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
1187 {
1188
1189 /* Get alg value. */
1190 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"alg", sizeof("alg") - 1))
1191 {
1192 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1193 nx_azure_iot_json_reader_token_string_get(&json_reader,
1194 buffer_ptr,
1195 buffer_size,
1196 &alg_size))
1197 {
1198 return(NX_FALSE);
1199 }
1200 alg_ptr = buffer_ptr;
1201 buffer_ptr += alg_size;
1202 buffer_size -= alg_size;
1203 }
1204
1205 /* Get sjwk value. */
1206 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"sjwk", sizeof("sjwk") - 1))
1207 {
1208 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1209 nx_azure_iot_json_reader_token_string_get(&json_reader,
1210 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_sjwk,
1211 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SJWK_SIZE,
1212 &sjwk_size))
1213 {
1214 return(NX_FALSE);
1215 }
1216 }
1217 else
1218 {
1219 return(NX_FALSE);
1220 }
1221 }
1222 else
1223 {
1224 break;
1225 }
1226 }
1227
1228 /* Check if there are "alg" and "sjwk" properties. */
1229 if ((alg_size == 0) || (sjwk_size == 0))
1230 {
1231 return(NX_FALSE);
1232 }
1233
1234 /* Check if alg is supported. */
1235 if ((alg_size != sizeof("RS256") - 1) || memcmp(alg_ptr, "RS256", alg_size))
1236 {
1237 return(NX_FALSE);
1238 }
1239
1240 /* Step2. Verify signing key is signed by master key. */
1241
1242 /* Header:
1243 {
1244 "alg": "RS256",
1245 "kid": "ADU.200702.R"
1246 }
1247
1248 Payload:
1249 {
1250 "kty": "RSA",
1251 "n": "xxx...xxx",
1252 "e": "AQAB",
1253 "alg": "RS256"
1254 "kid": "ADU.Signing.2020-04-29"
1255 }
1256
1257 Signature:
1258 */
1259
1260 /* Initialize. */
1261 alg_size = 0;
1262 kid_size = 0;
1263 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_buffer;
1264 buffer_size = NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE;
1265
1266 /* 2.1 Split sjwk header, payload and signature. */
1267 if (nx_azure_iot_adu_agent_jws_split(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_sjwk, sjwk_size,
1268 &jwk_header_b64, &jwk_header_b64_length,
1269 &jwk_payload_b64, &jwk_payload_b64_length,
1270 &jwk_signature_b64, &jwk_signature_b64_length) == NX_FALSE)
1271 {
1272 return(NX_FALSE);
1273 }
1274
1275 /* 2.2 Decode sjwk header. */
1276 if (_nx_utility_base64_decode(jwk_header_b64, jwk_header_b64_length,
1277 buffer_ptr, NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE, &bytes_copied))
1278 {
1279 return(NX_FALSE);
1280 }
1281
1282 /* Initialize the header string as json. */
1283 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader, buffer_ptr, bytes_copied))
1284 {
1285 return(NX_FALSE);
1286 }
1287 buffer_ptr += bytes_copied;
1288 buffer_size -= bytes_copied;
1289
1290 /* Skip the first begin object. */
1291 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
1292 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
1293 {
1294 return(NX_FALSE);
1295 }
1296
1297 /* Loop to process all header data. */
1298 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
1299 {
1300 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
1301 {
1302
1303 /* Get alg value. */
1304 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"alg", sizeof("alg") - 1))
1305 {
1306 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1307 nx_azure_iot_json_reader_token_string_get(&json_reader,
1308 buffer_ptr,
1309 buffer_size,
1310 &alg_size))
1311 {
1312 return(NX_FALSE);
1313 }
1314 alg_ptr = buffer_ptr;
1315 buffer_ptr += alg_size;
1316 buffer_size -= alg_size;
1317 }
1318
1319 /* Get kid value. */
1320 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"kid", sizeof("kid") - 1))
1321 {
1322 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1323 nx_azure_iot_json_reader_token_string_get(&json_reader,
1324 buffer_ptr,
1325 buffer_size,
1326 &kid_size))
1327 {
1328 return(NX_FALSE);
1329 }
1330 kid_ptr = buffer_ptr;
1331 buffer_ptr += kid_size;
1332 buffer_size -= kid_size;
1333 }
1334 else
1335 {
1336 return(NX_FALSE);
1337 }
1338 }
1339 else
1340 {
1341 break;
1342 }
1343 }
1344
1345 /* Check if there are "alg" and "kid" properties. */
1346 if ((alg_size == 0) || (kid_size == 0))
1347 {
1348 return(NX_FALSE);
1349 }
1350
1351 /* Check if alg is supported. */
1352 if ((alg_size != sizeof("RS256") - 1) || memcmp(alg_ptr, "RS256", alg_size))
1353 {
1354 return(NX_FALSE);
1355 }
1356
1357 /* Search master key. */
1358 rsa_root_key = (NX_AZURE_IOT_ADU_AGENT_RSA_ROOT_KEY *)nx_azure_iot_adu_agent_rsa_root_key_find(kid_ptr, kid_size);
1359 if (rsa_root_key == NX_NULL)
1360 {
1361 return(NX_FALSE);
1362 }
1363
1364 /* 2.3 Decode sjwk signature. */
1365 signature = adu_agent_ptr -> nx_azure_iot_adu_agent_buffer;
1366 signature_length = NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE;
1367 if (_nx_utility_base64_decode(jwk_signature_b64, jwk_signature_b64_length,
1368 signature, signature_length, &signature_length))
1369 {
1370 return(NX_FALSE);
1371 }
1372
1373 /* 2.4 Verify signature. */
1374 if (nx_azure_iot_adu_agent_rs256_verify(&adu_agent_ptr -> nx_azure_iot_adu_agent_crypto,
1375 jwk_header_b64, (jwk_header_b64_length + 1 + jwk_payload_b64_length),
1376 signature, signature_length,
1377 (UCHAR *)rsa_root_key -> n, rsa_root_key -> n_size,
1378 (UCHAR *)rsa_root_key -> e, rsa_root_key -> e_size,
1379 adu_agent_ptr -> nx_azure_iot_adu_agent_buffer + signature_length,
1380 NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE - signature_length) == NX_FALSE)
1381 {
1382 return(NX_FALSE);
1383 }
1384
1385 /* Step3. Verify distroman signature is signed by the signing key. */
1386
1387 /* Initialize. */
1388 kty_size = 0;
1389 n_size = 0;
1390 e_size = 0;
1391 kid_size = 0;
1392 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_buffer;
1393 buffer_size = NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE;
1394
1395 /* 3.1 Decode sjwk payload to get the signing key. */
1396 if (_nx_utility_base64_decode(jwk_payload_b64, jwk_payload_b64_length,
1397 buffer_ptr, buffer_size, &bytes_copied))
1398 {
1399 return(NX_FALSE);
1400 }
1401
1402 /* Initialize the payload string as json. */
1403 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader, buffer_ptr, bytes_copied))
1404 {
1405 return(NX_FALSE);
1406 }
1407 buffer_ptr += bytes_copied;
1408 buffer_size -= bytes_copied;
1409
1410 /* Skip the first begin object. */
1411 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
1412 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
1413 {
1414 return(NX_FALSE);
1415 }
1416
1417 /* Loop to process all header data. */
1418 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
1419 {
1420 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
1421 {
1422
1423 /* Get kty value. */
1424 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"kty", sizeof("kty") - 1))
1425 {
1426 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1427 nx_azure_iot_json_reader_token_string_get(&json_reader,
1428 buffer_ptr,
1429 buffer_size,
1430 &kty_size))
1431 {
1432 return(NX_FALSE);
1433 }
1434 kty_ptr = buffer_ptr;
1435 buffer_ptr += kty_size;
1436 buffer_size -= kty_size;
1437 }
1438
1439 /* Get n value. */
1440 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"n", sizeof("n") - 1))
1441 {
1442 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1443 nx_azure_iot_json_reader_token_string_get(&json_reader,
1444 buffer_ptr,
1445 buffer_size,
1446 &n_b64_size))
1447 {
1448 return(NX_FALSE);
1449 }
1450 n_b64_ptr = buffer_ptr;
1451 buffer_ptr += n_b64_size;
1452 buffer_size -= n_b64_size;
1453 }
1454
1455 /* Get e value. */
1456 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"e", sizeof("e") - 1))
1457 {
1458 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1459 nx_azure_iot_json_reader_token_string_get(&json_reader,
1460 buffer_ptr,
1461 buffer_size,
1462 &e_b64_size))
1463 {
1464 return(NX_FALSE);
1465 }
1466 e_b64_ptr = buffer_ptr;
1467 buffer_ptr += e_b64_size;
1468 buffer_size -= e_b64_size;
1469 }
1470
1471 /* Get alg value. */
1472 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"alg", sizeof("alg") - 1))
1473 {
1474 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1475 nx_azure_iot_json_reader_token_string_get(&json_reader,
1476 buffer_ptr,
1477 buffer_size,
1478 &alg_size))
1479 {
1480 return(NX_FALSE);
1481 }
1482 alg_ptr = buffer_ptr;
1483 buffer_ptr += alg_size;
1484 buffer_size -= alg_size;
1485 }
1486
1487 /* Get kid value. */
1488 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"kid", sizeof("kid") - 1))
1489 {
1490 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1491 nx_azure_iot_json_reader_token_string_get(&json_reader,
1492 buffer_ptr,
1493 buffer_size,
1494 &kid_size))
1495 {
1496 return(NX_FALSE);
1497 }
1498 kid_ptr = buffer_ptr;
1499 buffer_ptr += kid_size;
1500 buffer_size -= kid_size;
1501 }
1502
1503 else
1504 {
1505 return(NX_FALSE);
1506 }
1507 }
1508 else
1509 {
1510 break;
1511 }
1512 }
1513
1514 /* Check if there are "alg" and "kid" properties. */
1515 if ((kty_size == 0) || (n_b64_size == 0) || (e_b64_size == 0) || (kid_size == 0))
1516 {
1517 return(NX_FALSE);
1518 }
1519
1520 /* Check if alg is supported. */
1521 if ((alg_size != sizeof("RS256") - 1) || memcmp(alg_ptr, "RS256", alg_size))
1522 {
1523 return(NX_FALSE);
1524 }
1525
1526 /* Check if alg is supported. */
1527 if ((kty_size != sizeof("RSA") - 1) || memcmp(kty_ptr, "RSA", kty_size))
1528 {
1529 return(NX_FALSE);
1530 }
1531
1532 /* 3.2 Use sjwk to decode n, e, signature and verify signature. */
1533 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_sjwk;
1534 buffer_size = NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SJWK_SIZE;
1535 n_ptr = buffer_ptr;
1536 n_size = buffer_size;
1537 if (_nx_utility_base64_decode(n_b64_ptr, n_b64_size,
1538 n_ptr, n_size, &n_size))
1539 {
1540 return(NX_FALSE);
1541 }
1542 buffer_ptr += n_size;
1543 buffer_size -= n_size;
1544
1545 e_ptr = buffer_ptr;
1546 e_size = buffer_size;
1547 if (_nx_utility_base64_decode(e_b64_ptr, e_b64_size,
1548 e_ptr, e_size, &e_size))
1549 {
1550 return(NX_FALSE);
1551 }
1552 buffer_ptr += e_size;
1553 buffer_size -= e_size;
1554
1555 signature = buffer_ptr;
1556 signature_length = buffer_size;
1557 if (_nx_utility_base64_decode(signature_b64, signature_b64_length,
1558 signature, signature_length, &signature_length))
1559 {
1560 return(NX_FALSE);
1561 }
1562 buffer_ptr += signature_length;
1563 buffer_size -= signature_length;
1564
1565 /* 3.3 Verify signature. */
1566 if (nx_azure_iot_adu_agent_rs256_verify(&adu_agent_ptr -> nx_azure_iot_adu_agent_crypto,
1567 header_b64, (header_b64_length + 1 + payload_b64_length),
1568 signature, signature_length,
1569 n_ptr, n_size,
1570 e_ptr, e_size,
1571 buffer_ptr, buffer_size) == NX_FALSE)
1572 {
1573 return(NX_FALSE);
1574 }
1575
1576 /* Step4. Verify distroman body digest (update manifest) matches what's in JWS payload section. */
1577
1578 /* Initialize. */
1579 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_buffer;
1580 buffer_size = NX_AZURE_IOT_ADU_AGENT_BUFFER_SIZE;
1581
1582 /* 4.1 Calculate update manifest sha256 value. */
1583 sha256_generated_hash_ptr = buffer_ptr;
1584 status = nx_azure_iot_adu_agent_sha256_calculate(adu_agent_crypto -> method_sha256,
1585 adu_agent_crypto -> method_sha256_metadata,
1586 NX_AZURE_IOT_ADU_AGENT_SHA256_METADATA_SIZE,
1587 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
1588 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_size,
1589 sha256_generated_hash_ptr,
1590 NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE);
1591
1592 /* Check status. */
1593 if (status)
1594 {
1595 return(NX_FALSE);
1596 }
1597 buffer_ptr += NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE;
1598 buffer_size -= NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE;
1599
1600 /* 4.2 Decode the payload to get the sha256 base64 value. */
1601 status = _nx_utility_base64_decode(payload_b64, payload_b64_length,
1602 buffer_ptr, buffer_size, &bytes_copied);
1603
1604 /* Initialize the payload string as json. */
1605 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader, buffer_ptr, bytes_copied))
1606 {
1607 return(NX_FALSE);
1608 }
1609 buffer_ptr += bytes_copied;
1610 buffer_size -= bytes_copied;
1611
1612 /* Skip the first begin object. */
1613 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
1614 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
1615 {
1616 return(NX_FALSE);
1617 }
1618
1619 /* Get the next token. */
1620 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
1621 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME))
1622 {
1623 return(NX_FALSE);
1624 }
1625 sha256_decoded_hash_64_ptr = buffer_ptr;
1626
1627 /* Get sha256 base64 value. */
1628 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, (UCHAR *)"sha256", sizeof("sha256") - 1))
1629 {
1630 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
1631 nx_azure_iot_json_reader_token_string_get(&json_reader,
1632 sha256_decoded_hash_64_ptr,
1633 buffer_size,
1634 &bytes_copied))
1635 {
1636 return(NX_FALSE);
1637 }
1638 }
1639 else
1640 {
1641 return(NX_FALSE);
1642 }
1643 buffer_ptr += bytes_copied;
1644 buffer_size -= bytes_copied;
1645
1646 sha256_decoded_hash_ptr = buffer_ptr;
1647
1648 /* Decode sha256 base64 hash. */
1649 if (_nx_utility_base64_decode(sha256_decoded_hash_64_ptr, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_BASE64_SIZE,
1650 sha256_decoded_hash_ptr, buffer_size, &bytes_copied))
1651 {
1652 return(NX_FALSE);
1653 }
1654
1655 /* Verify the hash value. */
1656 if (memcmp(sha256_generated_hash_ptr, sha256_decoded_hash_ptr, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE))
1657 {
1658 return(NX_FALSE);
1659 }
1660
1661 return(NX_TRUE);
1662 }
1663
nx_azure_iot_adu_agent_jws_split(UCHAR * jws,UINT jws_length,UCHAR ** header,UINT * header_length,UCHAR ** payload,UINT * payload_length,UCHAR ** signature,UINT * signature_length)1664 static UINT nx_azure_iot_adu_agent_jws_split(UCHAR *jws, UINT jws_length,
1665 UCHAR **header, UINT *header_length,
1666 UCHAR **payload, UINT *payload_length,
1667 UCHAR **signature, UINT *signature_length)
1668 {
1669
1670 UCHAR *dot1_pointer;
1671 UCHAR *dot2_pointer;
1672 UINT dot_count = 0;
1673 UINT i = 0;
1674
1675 /* Set the header pointer. */
1676 *header = jws;
1677
1678 /* Loop to find the dots. */
1679 while(i < jws_length)
1680 {
1681 if (*jws == '.')
1682 {
1683 dot_count++;
1684
1685 if (dot_count == 1)
1686 {
1687 dot1_pointer = jws;
1688 }
1689 else if (dot_count == 2)
1690 {
1691 dot2_pointer = jws;
1692 }
1693 else if (dot_count > 2)
1694 {
1695 return(NX_FALSE);
1696 }
1697 }
1698 jws++;
1699 i++;
1700 }
1701
1702 /* Check if the dot count is correct. */
1703 if ((dot_count != 2) || (dot2_pointer >= (*header + jws_length - 1)))
1704 {
1705 return(NX_FALSE);
1706 }
1707
1708 /* Set the header, payload and signature. */
1709 *header_length = (UINT)(dot1_pointer - *header);
1710 *payload = dot1_pointer + 1;
1711 *payload_length = (UINT)(dot2_pointer - *payload);
1712 *signature = dot2_pointer + 1;
1713 *signature_length = (UINT)((*header + jws_length) - *signature);
1714
1715 return(NX_TRUE);
1716 }
1717
nx_azure_iot_adu_agent_step_state_update(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UINT step_state)1718 static VOID nx_azure_iot_adu_agent_step_state_update(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT step_state)
1719 {
1720
1721 /* Update state. */
1722 adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state = step_state;
1723
1724 /* Check the step state. */
1725 if (step_state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED)
1726 {
1727 adu_agent_ptr -> nx_azure_iot_adu_agent_state = NX_AZURE_IOT_ADU_AGENT_STATE_FAILED;
1728
1729 LogError(LogLiteralArgs("Failed to deploy update!"));
1730
1731 /* Report state to server. */
1732 nx_azure_iot_adu_agent_reported_properties_state_send(adu_agent_ptr);
1733 }
1734 else if (step_state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_MANIFEST_DOWNLOAD_SUCCEEDED)
1735 {
1736
1737 /* Set event for update check. */
1738 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
1739 NX_AZURE_IOT_ADU_AGENT_UPDATE_EVENT);
1740 }
1741 else if ((step_state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_DOWNLOAD_SUCCEEDED) ||
1742 (step_state == NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FIRMWARE_INSTALL_SUCCEEDED))
1743 {
1744 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
1745 NX_AZURE_IOT_ADU_AGENT_DOWNLOAD_INSTALL_EVENT);
1746 }
1747 }
1748
nx_azure_iot_adu_agent_file_find(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT * manifest_content,UCHAR * file_id,UINT file_id_length,NX_AZURE_IOT_ADU_AGENT_FILE ** file)1749 static UINT nx_azure_iot_adu_agent_file_find(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
1750 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *manifest_content,
1751 UCHAR *file_id, UINT file_id_length,
1752 NX_AZURE_IOT_ADU_AGENT_FILE **file)
1753 {
1754 UINT i;
1755
1756 *file = NX_NULL;
1757
1758 /* Find file. */
1759 for (i = 0; i < manifest_content -> files_count; i++)
1760 {
1761
1762 /* Check the file id. */
1763 if ((file_id_length == manifest_content -> files[i].file_id_length) &&
1764 (!memcmp(file_id, manifest_content -> files[i].file_id, file_id_length)))
1765 {
1766
1767 /* Find the file. */
1768 *file = &(manifest_content -> files[i]);
1769 break;
1770 }
1771 }
1772
1773 /* Check if find the file. */
1774 if (*file == NX_NULL)
1775 {
1776 return(NX_AZURE_IOT_NOT_FOUND);
1777 }
1778
1779 /* Find the file url. */
1780 for (i = 0; i < adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls_count; i++)
1781 {
1782
1783 /* Check the file id. */
1784 if ((file_id_length == adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls[i].file_id_length) &&
1785 (!memcmp(file_id, adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls[i].file_id, file_id_length)))
1786 {
1787
1788 /* Find the file url. */
1789 (*file) -> file_url = adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls[i].file_url;
1790 (*file) -> file_url_length = adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls[i].file_url_length;
1791 break;
1792 }
1793 }
1794
1795 /* Check if find the file url. */
1796 if (i >= adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls_count)
1797 {
1798 return(NX_AZURE_IOT_NOT_FOUND);
1799 }
1800
1801 return(NX_AZURE_IOT_SUCCESS);
1802 }
1803
nx_azure_iot_adu_agent_method_is_installed(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY * compatibility,NX_AZURE_IOT_ADU_AGENT_STEP * step,UINT * is_installed)1804 static UINT nx_azure_iot_adu_agent_method_is_installed(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
1805 NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY *compatibility,
1806 NX_AZURE_IOT_ADU_AGENT_STEP *step,
1807 UINT *is_installed)
1808 {
1809 UINT i;
1810 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
1811
1812 *is_installed = NX_FALSE;
1813
1814 /* Check if compatibility and installed criteria in step are correct. */
1815 if ((compatibility -> device_manufacturer == NX_NULL) ||
1816 (compatibility -> device_manufacturer_length == 0) ||
1817 (compatibility -> device_model == NX_NULL) ||
1818 (compatibility -> device_model_length == 0) ||
1819 (step -> installed_criteria == NX_NULL) ||
1820 (step -> installed_criteria_length == 0))
1821 {
1822 return(NX_AZURE_IOT_INVALID_PARAMETER);
1823 }
1824
1825 /* Find the device according to compatibility. */
1826 for (i = 0; i < NX_AZURE_IOT_ADU_AGENT_DEVICE_COUNT; i++)
1827 {
1828
1829 /* Check if the device is valid. */
1830 if (adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].valid == NX_FALSE)
1831 {
1832 continue;
1833 }
1834
1835 /* Compare the compatility (manufacturer and model). */
1836 if ((compatibility -> device_manufacturer_length == adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.manufacturer_length) &&
1837 (!memcmp(compatibility -> device_manufacturer, adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.manufacturer, compatibility -> device_manufacturer_length)) &&
1838 (compatibility -> device_model_length == adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.model_length) &&
1839 (!memcmp(compatibility -> device_model, adu_agent_ptr -> nx_azure_iot_adu_agent_device[i].device_properties.model, compatibility -> device_model_length)))
1840 {
1841
1842 /* Set the matching device. */
1843 step -> device = &adu_agent_ptr -> nx_azure_iot_adu_agent_device[i];
1844 break;
1845 }
1846 }
1847
1848 /* Check if device with matching properties. */
1849 if (step -> device == NX_NULL)
1850 {
1851 return(NX_AZURE_IOT_NOT_FOUND);
1852 }
1853
1854 /* Check if agent has the installed criteria. */
1855 if (step -> device -> installed_criteria_length)
1856 {
1857
1858 /* Check if already installed this update. */
1859 if ((step -> installed_criteria_length == step -> device -> installed_criteria_length) &&
1860 (!memcmp(step -> installed_criteria, step -> device -> installed_criteria, step -> installed_criteria_length)))
1861 {
1862 *is_installed = NX_TRUE;
1863 }
1864 else
1865 {
1866 *is_installed = NX_FALSE;
1867 }
1868
1869 }
1870 else
1871 {
1872
1873 /* Call the driver to check if this update is installed. */
1874 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_UPDATE_CHECK;
1875 driver_request.nx_azure_iot_adu_agent_driver_installed_criteria = step -> installed_criteria;
1876 driver_request.nx_azure_iot_adu_agent_driver_installed_criteria_length = step -> installed_criteria_length;
1877 driver_request.nx_azure_iot_adu_agent_driver_return_ptr = (ULONG *)is_installed;
1878 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
1879 (step -> device -> device_driver_entry)(&driver_request);
1880
1881 /* Check status. */
1882 if (driver_request.nx_azure_iot_adu_agent_driver_status)
1883 {
1884 return(NX_AZURE_IOT_FAILURE);
1885 }
1886 }
1887
1888 return(NX_AZURE_IOT_SUCCESS);
1889 }
1890
nx_azure_iot_adu_agent_method_download(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,NX_AZURE_IOT_ADU_AGENT_FILE * file,UINT type,UCHAR * manifest_buffer_ptr,UINT manifest_buffer_size,VOID (* adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))1891 static UINT nx_azure_iot_adu_agent_method_download(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
1892 NX_AZURE_IOT_ADU_AGENT_FILE *file,
1893 UINT type, UCHAR *manifest_buffer_ptr, UINT manifest_buffer_size,
1894 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))
1895 {
1896 UINT status;
1897 UCHAR *buffer_ptr;
1898 UINT buffer_size;
1899 NX_DNS *dns_ptr;
1900 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr;
1901 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
1902
1903
1904 /* Check if include download file. */
1905 if ((file -> file_url == NX_NULL) ||
1906 (file -> file_url_length == 0) ||
1907 (file -> file_sha256 == NX_NULL) ||
1908 (file -> file_sha256_length == 0) ||
1909 (file -> file_size_in_bytes == 0))
1910 {
1911 return(NX_AZURE_IOT_FAILURE);
1912 }
1913
1914 /* Check type. */
1915 if (((type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE) && (adu_agent_driver == NX_NULL)) ||
1916 ((type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_MANIFEST) && ((manifest_buffer_ptr == NX_NULL) || (manifest_buffer_size == 0))))
1917 {
1918 return(NX_AZURE_IOT_FAILURE);
1919 }
1920
1921 /* Initialization. */
1922 downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
1923 dns_ptr = downloader_ptr -> dns_ptr;
1924 memset(downloader_ptr, 0, sizeof(NX_AZURE_IOT_ADU_AGENT_DOWNLOADER));
1925 downloader_ptr -> dns_ptr = dns_ptr;
1926 downloader_ptr -> file = file;
1927 downloader_ptr -> type = type;
1928 downloader_ptr -> manifest_buffer_ptr = manifest_buffer_ptr;
1929 downloader_ptr -> manifest_buffer_size = manifest_buffer_size;
1930 downloader_ptr -> driver_entry = adu_agent_driver;
1931
1932 buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest;
1933 buffer_size = NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIZE;
1934
1935 if (type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE)
1936 {
1937
1938 /* Output info. */
1939 LogInfo(LogLiteralArgs("Firmware downloading..."));
1940
1941 /* Send the preprocess request to the driver. */
1942 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_PREPROCESS;
1943 driver_request.nx_azure_iot_adu_agent_driver_firmware_size = file -> file_size_in_bytes;
1944 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
1945 (downloader_ptr -> driver_entry)(&driver_request);
1946
1947 /* Check status. */
1948 if (driver_request.nx_azure_iot_adu_agent_driver_status)
1949 {
1950 LogError(LogLiteralArgs("Firmware download fail: DRIVER PREPROCESS ERROR"));
1951 return(NX_AZURE_IOT_FAILURE);
1952 }
1953 }
1954
1955 /* Parse the url. */
1956 status = nx_azure_iot_adu_agent_file_url_parse(file -> file_url,
1957 file -> file_url_length,
1958 buffer_ptr, buffer_size, downloader_ptr);
1959
1960 /* Check status. */
1961 if (status)
1962 {
1963 LogError(LogLiteralArgs("Firmware download fail: URL PARSE ERROR"));
1964 return(status);
1965 }
1966
1967 /* Check if start dns query to get the address. */
1968 if (downloader_ptr -> state == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_URL_PARSED)
1969 {
1970
1971 /* Start dns query. */
1972 nx_azure_iot_adu_agent_dns_query(adu_agent_ptr);
1973 }
1974 else if (downloader_ptr -> state == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_DONE)
1975 {
1976
1977 /* Start HTTP connect. */
1978 nx_azure_iot_adu_agent_http_connect(adu_agent_ptr);
1979 }
1980
1981 /* Return. */
1982 return(status);
1983 }
1984
nx_azure_iot_adu_agent_method_install(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,VOID (* adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))1985 static UINT nx_azure_iot_adu_agent_method_install(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
1986 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))
1987 {
1988 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
1989
1990 NX_PARAMETER_NOT_USED(adu_agent_ptr);
1991
1992 /* Output info. */
1993 LogInfo(LogLiteralArgs("Firmware installing..."));
1994
1995 /* Send the firmware install request to the driver. */
1996 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_INSTALL;
1997 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
1998 (adu_agent_driver)(&driver_request);
1999
2000 /* Install firmware. */
2001 if (driver_request.nx_azure_iot_adu_agent_driver_status)
2002 {
2003 LogError(LogLiteralArgs("Firmware install fail: DRIVER ERROR"));
2004 return(NX_AZURE_IOT_FAILURE);
2005 }
2006
2007 /* Output info. */
2008 LogInfo(LogLiteralArgs("Firmware installed"));
2009
2010 return(NX_AZURE_IOT_SUCCESS);
2011 }
2012
nx_azure_iot_adu_agent_method_apply(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,VOID (* adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))2013 static UINT nx_azure_iot_adu_agent_method_apply(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
2014 VOID (*adu_agent_driver)(NX_AZURE_IOT_ADU_AGENT_DRIVER *))
2015 {
2016 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
2017
2018 NX_PARAMETER_NOT_USED(adu_agent_ptr);
2019
2020 /* Applying... */
2021 LogInfo(LogLiteralArgs("Firmware applying..."));
2022
2023 /* Send the firmware apply request to the driver. */
2024 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_APPLY;
2025 (adu_agent_driver)(&driver_request);
2026
2027 /* Install firmware. */
2028 if (driver_request.nx_azure_iot_adu_agent_driver_status)
2029 {
2030 LogError(LogLiteralArgs("Firmware apply fail: DRIVER ERROR"));
2031 return(NX_AZURE_IOT_FAILURE);
2032 }
2033
2034 /* Applying host update will reboot the device and never return. */
2035 LogInfo(LogLiteralArgs("Firmware applied\r\n\r\n"));
2036
2037 return(NX_AZURE_IOT_SUCCESS);
2038 }
2039
nx_azure_iot_adu_agent_service_properties_get(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,NX_AZURE_IOT_JSON_READER * json_reader_ptr)2040 static UINT nx_azure_iot_adu_agent_service_properties_get(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
2041 NX_AZURE_IOT_JSON_READER *json_reader_ptr)
2042 {
2043 UCHAR *file_buffer_ptr;
2044 UINT file_buffer_size;
2045 NX_AZURE_IOT_ADU_AGENT_FILE_URLS *file_urls = &(adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls);
2046 NX_AZURE_IOT_ADU_AGENT_WORKFLOW *workflow = &(adu_agent_ptr -> nx_azure_iot_adu_agent_workflow);
2047
2048
2049 /* Initialization. */
2050 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_size = 0;
2051 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature_size = 0;
2052 memset(file_urls, 0, sizeof (NX_AZURE_IOT_ADU_AGENT_FILE_URLS));
2053 memset(workflow, 0, sizeof (NX_AZURE_IOT_ADU_AGENT_WORKFLOW));
2054
2055 /* Skip service property. */
2056 nx_azure_iot_json_reader_next_token(json_reader_ptr);
2057
2058 /* Next one should be begin object. */
2059 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2060 {
2061 return(NX_NOT_SUCCESSFUL);
2062 }
2063
2064 /* Loop to process all data. */
2065 while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
2066 {
2067 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2068 {
2069
2070 /* Workflow. */
2071 if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2072 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW,
2073 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW) - 1))
2074 {
2075
2076 /* Skip the workflow property name. */
2077 if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
2078 {
2079 return(NX_NOT_SUCCESSFUL);
2080 }
2081
2082 /* Check the token type. */
2083 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2084 {
2085 return(NX_NOT_SUCCESSFUL);
2086 }
2087
2088 /* Loop to process workflow content. */
2089 while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
2090 {
2091 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2092 {
2093 if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2094 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION,
2095 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION) - 1))
2096 {
2097 /* Get action data. */
2098 if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
2099 nx_azure_iot_json_reader_token_int32_get(json_reader_ptr, (int32_t *)&(workflow -> action)))
2100 {
2101 return(NX_NOT_SUCCESSFUL);
2102 }
2103 }
2104
2105 /* Get id. */
2106 else if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2107 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID,
2108 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID) - 1))
2109 {
2110
2111 /* Get id string. */
2112 if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
2113 nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2114 workflow -> id,
2115 NX_AZURE_IOT_ADU_AGENT_WORKFLOW_ID_SIZE,
2116 &(workflow -> id_length)))
2117 {
2118 return(NX_NOT_SUCCESSFUL);
2119 }
2120 }
2121
2122 /* Get retry timestamp. */
2123 else if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2124 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP,
2125 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP) - 1))
2126 {
2127
2128 /* Get retry timestamp string. */
2129 if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
2130 nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2131 workflow -> retry_timestamp,
2132 NX_AZURE_IOT_ADU_AGENT_WORKFLOW_RETRY_TIMESTAMP_SIZE,
2133 &(workflow -> retry_timestamp_length)))
2134 {
2135 return(NX_NOT_SUCCESSFUL);
2136 }
2137 }
2138
2139 /* Skip the unknown properties. */
2140 else
2141 {
2142 if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
2143 {
2144 return(NX_NOT_SUCCESSFUL);
2145 }
2146 }
2147 }
2148 else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2149 {
2150 break;
2151 }
2152 }
2153 }
2154
2155 /* Update manifest. */
2156 if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2157 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST,
2158 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST) - 1))
2159 {
2160
2161 /* Get update manifest string. */
2162 if ((nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_SUCCESS) &&
2163 (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_STRING))
2164 {
2165 if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2166 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
2167 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIZE,
2168 &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_size)))
2169 {
2170 return(NX_NOT_SUCCESSFUL);
2171 }
2172 }
2173 }
2174
2175 /* Update manifest signature. */
2176 else if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2177 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST_SIGNATURE,
2178 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST_SIGNATURE) - 1))
2179 {
2180
2181 /* Get update manifest signature. */
2182 if ((nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_SUCCESS) &&
2183 (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_STRING))
2184 {
2185 if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2186 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature,
2187 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIGNATURE_SIZE,
2188 &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_signature_size)))
2189 {
2190 return(NX_NOT_SUCCESSFUL);
2191 }
2192 }
2193 }
2194
2195 /* File URLs.
2196 Note: 1. file urls property can exist or not.
2197 2. file urls property value can be object. */
2198 else if (nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
2199 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILEURLS,
2200 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILEURLS) - 1))
2201 {
2202
2203 /* Skip the file urls property name. */
2204 if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
2205 {
2206 return(NX_NOT_SUCCESSFUL);
2207 }
2208
2209 /* Check the token type. */
2210 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2211 {
2212
2213 /* Start to parse file array. */
2214 file_buffer_ptr = adu_agent_ptr -> nx_azure_iot_adu_agent_file_urls.file_urls_buffer;
2215 file_buffer_size = NX_AZURE_IOT_ADU_AGENT_FILE_URLS_MAX;
2216
2217 while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
2218 {
2219
2220 /* Check if it is the end object. */
2221 if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2222 {
2223 break;
2224 }
2225
2226 if (file_urls -> file_urls_count < NX_AZURE_IOT_ADU_AGENT_FILES_MAX)
2227 {
2228
2229 /* Store the file number. */
2230 if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2231 file_buffer_ptr,
2232 file_buffer_size,
2233 &(file_urls -> file_urls[file_urls -> file_urls_count].file_id_length)))
2234 {
2235 return(NX_NOT_SUCCESSFUL);
2236 }
2237
2238 /* Set file number pointer and update the buffer size. */
2239 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(file_urls -> file_urls[file_urls -> file_urls_count].file_id,
2240 file_urls -> file_urls[file_urls -> file_urls_count].file_id_length,
2241 file_buffer_ptr, file_buffer_size);
2242
2243 /* Get file url. */
2244 if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
2245 nx_azure_iot_json_reader_token_string_get(json_reader_ptr,
2246 file_buffer_ptr,
2247 file_buffer_size,
2248 &(file_urls -> file_urls[file_urls -> file_urls_count].file_url_length)))
2249 {
2250 return(NX_NOT_SUCCESSFUL);
2251 }
2252
2253 /* Set file url pointer and update the buffer size. */
2254 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(file_urls -> file_urls[file_urls -> file_urls_count].file_url,
2255 file_urls -> file_urls[file_urls -> file_urls_count].file_url_length,
2256 file_buffer_ptr, file_buffer_size);
2257
2258 file_urls -> file_urls_count++;
2259 }
2260 else
2261 {
2262 if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
2263 {
2264 return(NX_NOT_SUCCESSFUL);
2265 }
2266 }
2267 }
2268 }
2269 }
2270
2271 /* Skip the unknown properties. */
2272 else
2273 {
2274 if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
2275 {
2276 return(NX_NOT_SUCCESSFUL);
2277 }
2278 }
2279 }
2280 else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
2281 NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2282 {
2283 break;
2284 }
2285 }
2286
2287 return(NX_AZURE_IOT_SUCCESS);
2288 }
2289
nx_azure_iot_adu_agent_service_update_manifest_process(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UCHAR * update_manifest,UINT update_manifest_size,NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT * update_manifest_content,UCHAR * update_manifest_content_buffer,UINT update_manifest_content_buffer_size)2290 static UINT nx_azure_iot_adu_agent_service_update_manifest_process(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
2291 UCHAR *update_manifest,
2292 UINT update_manifest_size,
2293 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *update_manifest_content,
2294 UCHAR *update_manifest_content_buffer,
2295 UINT update_manifest_content_buffer_size)
2296 {
2297
2298 UCHAR *buffer_ptr = update_manifest_content_buffer;
2299 UINT buffer_size = update_manifest_content_buffer_size;
2300 UINT i = 0;
2301 NX_AZURE_IOT_JSON_READER json_reader;
2302 NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY *compatibility = &(update_manifest_content -> compatibility);
2303
2304 NX_PARAMETER_NOT_USED(adu_agent_ptr);
2305
2306 /* Initialization. */
2307 memset(update_manifest_content, 0, sizeof (NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT));
2308
2309 /* Initialize the update manifest string as json. */
2310 if (nx_azure_iot_json_reader_with_buffer_init(&json_reader, update_manifest, update_manifest_size))
2311 {
2312 return(NX_NOT_SUCCESSFUL);
2313 }
2314
2315 /* Skip the first begin object. */
2316 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2317 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
2318 {
2319 return(NX_NOT_SUCCESSFUL);
2320 }
2321
2322 /* Loop to process all data. */
2323 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2324 {
2325 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2326 {
2327
2328 /* Manifest version. */
2329 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2330 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANIFEST_VERSION,
2331 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANIFEST_VERSION) - 1))
2332 {
2333
2334 /* Get manifest version value. */
2335 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2336 nx_azure_iot_json_reader_token_string_get(&json_reader,
2337 buffer_ptr,
2338 buffer_size,
2339 &(update_manifest_content -> manifest_version_length)))
2340 {
2341 return(NX_NOT_SUCCESSFUL);
2342 }
2343
2344 /* Set file number pointer and update the buffer size. */
2345 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> manifest_version,
2346 update_manifest_content -> manifest_version_length,
2347 buffer_ptr, buffer_size);
2348 }
2349
2350 /* Update id. */
2351 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2352 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_ID,
2353 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_ID) - 1))
2354 {
2355
2356 /* Skip the first begin object. */
2357 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2358 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
2359 {
2360 return(NX_NOT_SUCCESSFUL);
2361 }
2362
2363 /* Loop to process all update id field. */
2364 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2365 {
2366 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2367 {
2368
2369 /* Provider. */
2370 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2371 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER,
2372 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER) - 1))
2373 {
2374
2375 /* Get the provider value. */
2376 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2377 nx_azure_iot_json_reader_token_string_get(&json_reader,
2378 buffer_ptr,
2379 buffer_size,
2380 &(update_manifest_content -> update_id.provider_length)))
2381 {
2382 return(NX_NOT_SUCCESSFUL);
2383 }
2384
2385 /* Set file number pointer and update the buffer size. */
2386 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> update_id.provider,
2387 update_manifest_content -> update_id.provider_length,
2388 buffer_ptr, buffer_size);
2389 }
2390
2391 /* Name. */
2392 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2393 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME,
2394 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME) - 1))
2395 {
2396
2397 /* Get the name value. */
2398 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2399 nx_azure_iot_json_reader_token_string_get(&json_reader,
2400 buffer_ptr,
2401 buffer_size,
2402 &(update_manifest_content -> update_id.name_length)))
2403 {
2404 return(NX_NOT_SUCCESSFUL);
2405 }
2406
2407 /* Set file number pointer and update the buffer size. */
2408 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> update_id.name,
2409 update_manifest_content -> update_id.name_length,
2410 buffer_ptr, buffer_size);
2411 }
2412
2413 /* Version. */
2414 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2415 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION,
2416 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION) - 1))
2417 {
2418
2419 /* Get the version value. */
2420 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2421 nx_azure_iot_json_reader_token_string_get(&json_reader,
2422 buffer_ptr,
2423 buffer_size,
2424 &(update_manifest_content -> update_id.version_length)))
2425 {
2426 return(NX_NOT_SUCCESSFUL);
2427 }
2428
2429 /* Set file number pointer and update the buffer size. */
2430 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> update_id.version,
2431 update_manifest_content -> update_id.version_length,
2432 buffer_ptr, buffer_size);
2433 }
2434
2435 /* Skip the unknown properties. */
2436 else
2437 {
2438 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2439 {
2440 return(NX_NOT_SUCCESSFUL);
2441 }
2442 }
2443 }
2444
2445 else if (nx_azure_iot_json_reader_token_type(&json_reader) ==
2446 NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2447 {
2448 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2449 {
2450 return(NX_NOT_SUCCESSFUL);
2451 }
2452 }
2453 else if (nx_azure_iot_json_reader_token_type(&json_reader) ==
2454 NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2455 {
2456 break;
2457 }
2458 }
2459 }
2460
2461 /* Compatibility. */
2462 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2463 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPATIBILITY,
2464 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPATIBILITY) - 1))
2465 {
2466 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2467 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY) ||
2468 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2469 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
2470 {
2471 return(NX_NOT_SUCCESSFUL);
2472 }
2473
2474 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2475 {
2476 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2477 {
2478
2479 /* Device manufacturer. */
2480 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2481 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER,
2482 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER) - 1))
2483 {
2484 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2485 nx_azure_iot_json_reader_token_string_get(&json_reader,
2486 buffer_ptr,
2487 buffer_size,
2488 &(compatibility -> device_manufacturer_length)))
2489 {
2490 return(NX_NOT_SUCCESSFUL);
2491 }
2492
2493 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(compatibility -> device_manufacturer,
2494 compatibility -> device_manufacturer_length,
2495 buffer_ptr, buffer_size);
2496 }
2497
2498 /* Device model. */
2499 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2500 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL,
2501 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL) - 1))
2502 {
2503 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2504 nx_azure_iot_json_reader_token_string_get(&json_reader,
2505 buffer_ptr,
2506 buffer_size,
2507 &(compatibility -> device_model_length)))
2508 {
2509 return(NX_NOT_SUCCESSFUL);
2510 }
2511
2512 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(compatibility -> device_model,
2513 compatibility -> device_model_length,
2514 buffer_ptr, buffer_size);
2515 }
2516
2517 /* Group. */
2518 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2519 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_GROUP,
2520 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_GROUP) - 1))
2521 {
2522 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2523 nx_azure_iot_json_reader_token_string_get(&json_reader,
2524 buffer_ptr,
2525 buffer_size,
2526 &(compatibility -> group_length)))
2527 {
2528 return(NX_NOT_SUCCESSFUL);
2529 }
2530
2531 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(compatibility -> group,
2532 compatibility -> group_length,
2533 buffer_ptr, buffer_size);
2534 }
2535
2536 /* Skip the unknown properties. */
2537 else
2538 {
2539 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2540 {
2541 return(NX_NOT_SUCCESSFUL);
2542 }
2543 }
2544 }
2545 else if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2546 {
2547 break;
2548 }
2549 }
2550
2551 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2552 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_END_ARRAY))
2553 {
2554 return(NX_NOT_SUCCESSFUL);
2555 }
2556 }
2557
2558 /* Instructions. */
2559 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2560 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTRUCTIONS,
2561 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTRUCTIONS) - 1))
2562 {
2563
2564 /* Skip the first begin object. */
2565 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2566 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT) ||
2567 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2568 (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2569 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEPS,
2570 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEPS) - 1) != NX_TRUE) ||
2571 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2572 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY))
2573 {
2574 return(NX_NOT_SUCCESSFUL);
2575 }
2576
2577 i = 0;
2578
2579 /* Loop to process steps array. */
2580 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2581 {
2582 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_END_ARRAY)
2583 {
2584 break;
2585 }
2586
2587 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2588 {
2589
2590 /* Check if have enough space. */
2591 if (update_manifest_content -> steps_count >= NX_AZURE_IOT_ADU_AGENT_STEPS_MAX)
2592 {
2593 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2594 {
2595 return(NX_NOT_SUCCESSFUL);
2596 }
2597 continue;
2598 }
2599
2600 /* Loop to process properties in step. */
2601 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2602 {
2603 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2604 {
2605
2606 /* Type. */
2607 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2608 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_TYPE,
2609 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_TYPE) - 1))
2610 {
2611
2612 /* Get type value. */
2613 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2614 nx_azure_iot_json_reader_token_string_get(&json_reader,
2615 buffer_ptr,
2616 buffer_size,
2617 &(update_manifest_content -> steps[i].type_length)))
2618 {
2619 return(NX_NOT_SUCCESSFUL);
2620 }
2621
2622 /* Set file number pointer and update the buffer size. */
2623 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> steps[i].type,
2624 update_manifest_content -> steps[i].type_length,
2625 buffer_ptr, buffer_size);
2626 }
2627
2628 /* Handler. */
2629 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2630 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HANDLE,
2631 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HANDLE) - 1))
2632 {
2633
2634 /* Get handle value. */
2635 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2636 nx_azure_iot_json_reader_token_string_get(&json_reader,
2637 buffer_ptr,
2638 buffer_size,
2639 &(update_manifest_content -> steps[i].handler_length)))
2640 {
2641 return(NX_NOT_SUCCESSFUL);
2642 }
2643
2644 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> steps[i].handler,
2645 update_manifest_content -> steps[i].handler_length,
2646 buffer_ptr, buffer_size);
2647 }
2648
2649 /* Handler properties: installedCriteria. */
2650 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2651 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HANDLER_PROPERTIES,
2652 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HANDLER_PROPERTIES) - 1))
2653 {
2654
2655 /* Skip the installedCriteria property name. */
2656 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2657 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT) ||
2658 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2659 (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2660 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CRITERIA,
2661 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CRITERIA) - 1) != NX_TRUE))
2662 {
2663 return(NX_NOT_SUCCESSFUL);
2664 }
2665
2666 /* Get installedCriteria value. */
2667 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2668 nx_azure_iot_json_reader_token_string_get(&json_reader,
2669 buffer_ptr,
2670 buffer_size,
2671 &(update_manifest_content -> steps[i].installed_criteria_length)) ||
2672 (nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2673 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_END_OBJECT))
2674 {
2675 return(NX_NOT_SUCCESSFUL);
2676 }
2677
2678 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> steps[i].installed_criteria,
2679 update_manifest_content -> steps[i].installed_criteria_length,
2680 buffer_ptr, buffer_size);
2681 }
2682
2683 /* Files. */
2684 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2685 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILES,
2686 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILES) - 1))
2687 {
2688
2689 /* Get files value. */
2690 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2691 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY) ||
2692 nx_azure_iot_json_reader_next_token(&json_reader) ||
2693 nx_azure_iot_json_reader_token_string_get(&json_reader,
2694 buffer_ptr,
2695 buffer_size,
2696 &(update_manifest_content -> steps[i].file_id_length)))
2697 {
2698 return(NX_NOT_SUCCESSFUL);
2699 }
2700
2701 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> steps[i].file_id,
2702 update_manifest_content -> steps[i].file_id_length,
2703 buffer_ptr, buffer_size);
2704
2705 /* Skip end array. */
2706 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2707 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_END_ARRAY))
2708 {
2709 return(NX_NOT_SUCCESSFUL);
2710 }
2711 }
2712
2713 /* Detached Manifest File Id. */
2714 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2715 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DETACHED_MANIFEST_FILED,
2716 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DETACHED_MANIFEST_FILED) - 1))
2717 {
2718
2719 /* Get files value. */
2720 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2721 nx_azure_iot_json_reader_token_string_get(&json_reader,
2722 buffer_ptr,
2723 buffer_size,
2724 &(update_manifest_content -> steps[i].file_id_length)))
2725 {
2726 return(NX_NOT_SUCCESSFUL);
2727 }
2728
2729 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> steps[i].file_id,
2730 update_manifest_content -> steps[i].file_id_length,
2731 buffer_ptr, buffer_size);
2732 }
2733
2734 /* Skip the unknown properties. */
2735 else
2736 {
2737 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2738 {
2739 return(NX_NOT_SUCCESSFUL);
2740 }
2741 }
2742 }
2743 else if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2744 {
2745 i++;
2746 update_manifest_content -> steps_count++;
2747 break;
2748 }
2749 }
2750 }
2751 }
2752
2753 /* Skip the end object of steps. */
2754 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2755 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_END_OBJECT))
2756 {
2757 return(NX_NOT_SUCCESSFUL);
2758 }
2759 }
2760
2761 /* Files. */
2762 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2763 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILES,
2764 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILES) - 1))
2765 {
2766 i = 0;
2767 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2768 {
2769 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2770 {
2771 if (update_manifest_content -> files_count >= NX_AZURE_IOT_ADU_AGENT_FILES_MAX)
2772 {
2773 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2774 {
2775 return(NX_NOT_SUCCESSFUL);
2776 }
2777 continue;
2778 }
2779
2780 /* Get the file id. */
2781 if (nx_azure_iot_json_reader_token_string_get(&json_reader,
2782 buffer_ptr,
2783 buffer_size,
2784 &(update_manifest_content -> files[i].file_id_length)))
2785 {
2786 return(NX_NOT_SUCCESSFUL);
2787 }
2788
2789 /* Set file id pointer and update the buffer size. */
2790 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> files[i].file_id,
2791 update_manifest_content -> files[i].file_id_length,
2792 buffer_ptr, buffer_size);
2793
2794 while (nx_azure_iot_json_reader_next_token(&json_reader) == NX_AZURE_IOT_SUCCESS)
2795 {
2796 if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
2797 {
2798
2799 /* Filename. */
2800 if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2801 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILE_NAME,
2802 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_FILE_NAME) - 1))
2803 {
2804
2805 /* Get the file name value. */
2806 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2807 nx_azure_iot_json_reader_token_string_get(&json_reader,
2808 buffer_ptr,
2809 buffer_size,
2810 &(update_manifest_content -> files[i].file_name_length)))
2811 {
2812 return(NX_NOT_SUCCESSFUL);
2813 }
2814
2815 /* Set file name pointer and update the buffer size. */
2816 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> files[i].file_name,
2817 update_manifest_content -> files[i].file_name_length,
2818 buffer_ptr, buffer_size);
2819 }
2820
2821 /* Size in bytes. */
2822 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2823 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SIZE_IN_BYTES,
2824 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SIZE_IN_BYTES) - 1))
2825 {
2826 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2827 nx_azure_iot_json_reader_token_uint32_get(&json_reader,
2828 (uint32_t *)&(update_manifest_content -> files[i].file_size_in_bytes)))
2829 {
2830 return(NX_NOT_SUCCESSFUL);
2831 }
2832 }
2833
2834 /* Hashes. */
2835 else if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2836 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HASHES,
2837 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_HASHES) - 1))
2838 {
2839
2840 /* Skip the begin object of hashes property. */
2841 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2842 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT))
2843 {
2844 return(NX_NOT_SUCCESSFUL);
2845 }
2846
2847 /* sha256. */
2848 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2849 !nx_azure_iot_json_reader_token_is_text_equal(&json_reader,
2850 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SHA256,
2851 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SHA256) - 1))
2852 {
2853 return(NX_NOT_SUCCESSFUL);
2854 }
2855
2856 /* Get the sha256 value value. */
2857 if (nx_azure_iot_json_reader_next_token(&json_reader) ||
2858 nx_azure_iot_json_reader_token_string_get(&json_reader,
2859 buffer_ptr,
2860 buffer_size,
2861 &(update_manifest_content -> files[i].file_sha256_length)))
2862 {
2863 return(NX_NOT_SUCCESSFUL);
2864 }
2865
2866 NX_AZURE_IOT_ADU_AGENT_PTR_UPDATE(update_manifest_content -> files[i].file_sha256,
2867 update_manifest_content -> files[i].file_sha256_length,
2868 buffer_ptr, buffer_size);
2869
2870 /* Skip the end object of hashes property. */
2871 if ((nx_azure_iot_json_reader_next_token(&json_reader) != NX_AZURE_IOT_SUCCESS) ||
2872 (nx_azure_iot_json_reader_token_type(&json_reader) != NX_AZURE_IOT_READER_TOKEN_END_OBJECT))
2873 {
2874 return(NX_NOT_SUCCESSFUL);
2875 }
2876 }
2877
2878 /* Skip the unknown properties. */
2879 else
2880 {
2881 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2882 {
2883 return(NX_NOT_SUCCESSFUL);
2884 }
2885 }
2886 }
2887 else if (nx_azure_iot_json_reader_token_type(&json_reader) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2888 {
2889 i++;
2890 update_manifest_content -> files_count++;
2891 break;
2892 }
2893 }
2894 }
2895 else if (nx_azure_iot_json_reader_token_type(&json_reader) ==
2896 NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2897 {
2898 break;
2899 }
2900 }
2901 }
2902
2903 /* Skip the unknown properties. */
2904 else
2905 {
2906 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2907 {
2908 return(NX_NOT_SUCCESSFUL);
2909 }
2910 }
2911 }
2912
2913 else if (nx_azure_iot_json_reader_token_type(&json_reader) ==
2914 NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
2915 {
2916 if (nx_azure_iot_json_reader_skip_children(&json_reader))
2917 {
2918 return(NX_NOT_SUCCESSFUL);
2919 }
2920 }
2921 else if (nx_azure_iot_json_reader_token_type(&json_reader) ==
2922 NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
2923 {
2924 break;
2925 }
2926 }
2927
2928 return(NX_AZURE_IOT_SUCCESS);
2929 }
2930
2931 /* agent reported properties for startup:
2932 {
2933 "deviceUpdate": {
2934 "__t": "c",
2935 "agent": {
2936 "deviceProperties": {
2937 "manufacturer": "Microsoft",
2938 "model": "MS-Board",
2939 "interfaceId": "dtmi:azure:iot:deviceUpdate;1",
2940 },
2941 "compatPropertyNames": "manufacturer,model",
2942 }
2943 }
2944 }
2945 */
nx_azure_iot_adu_agent_reported_properties_startup_send(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UINT wait_option)2946 static UINT nx_azure_iot_adu_agent_reported_properties_startup_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT wait_option)
2947 {
2948
2949 NX_PACKET *packet_ptr;
2950 NX_AZURE_IOT_JSON_WRITER json_writer;
2951 NX_AZURE_IOT_ADU_AGENT_DEVICE_PROPERTIES *device_properties = &(adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties);
2952 UINT status;
2953 UINT response_status;
2954
2955 /* Create json writer for client reported property. */
2956 status = nx_azure_iot_hub_client_reported_properties_create(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &packet_ptr, wait_option);
2957 if (status)
2958 {
2959 return(status);
2960 }
2961
2962 /* Init json writer. */
2963 status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, wait_option);
2964 if (status)
2965 {
2966 nx_packet_release(packet_ptr);
2967 return(status);
2968 }
2969
2970 /* Append begin object. */
2971 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
2972 {
2973 nx_packet_release(packet_ptr);
2974 return(NX_NOT_SUCCESSFUL);
2975 }
2976
2977 /* Fill the ADU agent component name. */
2978 status = nx_azure_iot_hub_client_reported_properties_component_begin(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
2979 &json_writer,
2980 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME,
2981 sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1);
2982 if (status)
2983 {
2984 nx_packet_release(packet_ptr);
2985 return(status);
2986 }
2987
2988 /* Fill the agent property name. */
2989 if (nx_azure_iot_json_writer_append_property_name(&json_writer,
2990 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT,
2991 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT) - 1))
2992 {
2993 nx_packet_release(packet_ptr);
2994 return(NX_NOT_SUCCESSFUL);
2995 }
2996
2997 /* Start to fill agent property value. */
2998 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
2999 {
3000 nx_packet_release(packet_ptr);
3001 return(NX_NOT_SUCCESSFUL);
3002 }
3003
3004 /* Fill the deviceProperties. */
3005 if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
3006 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DEVICEPROPERTIES,
3007 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DEVICEPROPERTIES) - 1)) ||
3008 (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
3009 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3010 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER,
3011 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER) - 1,
3012 device_properties -> manufacturer, device_properties -> manufacturer_length)) ||
3013 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3014 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL,
3015 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL) - 1,
3016 device_properties -> model, device_properties -> model_length)) ||
3017 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3018 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_CONTRACT_MODEL_ID,
3019 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_CONTRACT_MODEL_ID) - 1,
3020 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_CONTRACT_MODEL_ID,
3021 sizeof(NX_AZURE_IOT_ADU_AGENT_CONTRACT_MODEL_ID) - 1)) ||
3022 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3023 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ADU_VERSION,
3024 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ADU_VERSION) - 1,
3025 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_VERSION,
3026 sizeof(NX_AZURE_IOT_ADU_AGENT_VERSION) - 1)) ||
3027 (nx_azure_iot_json_writer_append_end_object(&json_writer)))
3028 {
3029 nx_packet_release(packet_ptr);
3030 return(NX_NOT_SUCCESSFUL);
3031 }
3032
3033 /* Fill the comatability property. */
3034 if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3035 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPAT_PROPERTY_NAMES,
3036 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPAT_PROPERTY_NAMES) - 1,
3037 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_VALUE_COMPATIBILITY,
3038 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_VALUE_COMPATIBILITY) - 1))
3039 {
3040 nx_packet_release(packet_ptr);
3041 return(NX_NOT_SUCCESSFUL);
3042 }
3043
3044 /* End the client property value. */
3045 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3046 {
3047 nx_packet_release(packet_ptr);
3048 return(NX_NOT_SUCCESSFUL);
3049 }
3050
3051 /* End ADU agent component. */
3052 if (nx_azure_iot_hub_client_reported_properties_component_end(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &json_writer))
3053 {
3054 nx_packet_release(packet_ptr);
3055 return(NX_NOT_SUCCESSFUL);
3056 }
3057
3058 /* End json object. */
3059 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3060 {
3061 nx_packet_release(packet_ptr);
3062 return(NX_NOT_SUCCESSFUL);
3063 }
3064
3065 /* Send agent reported properties startup message to IoT Hub. */
3066 status = nx_azure_iot_hub_client_reported_properties_send(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
3067 packet_ptr,
3068 NX_NULL, &response_status,
3069 NX_NULL, wait_option);
3070 if (status)
3071 {
3072 nx_packet_release(packet_ptr);
3073 return(status);
3074 }
3075
3076 /* Check the response statue for blocking. */
3077 if (wait_option)
3078 {
3079 if ((response_status < 200) || (response_status >= 300))
3080 {
3081 return(NX_NOT_SUCCESSFUL);
3082 }
3083 }
3084
3085 return(NX_AZURE_IOT_SUCCESS);
3086 }
3087
3088 /* agent reported properties state:
3089 {
3090 "deviceUpdate": {
3091 "__t": "c",
3092 "agent": {
3093 "state": 0,
3094 "workflow": {
3095 "action": 3,
3096 "id": "someguid",
3097 "retryTimestamp": "2020-04-22T12:12:12.0000000+00:00"
3098 },
3099 "installedUpdateId": "{\"provider\":\"Microsoft\",\"Name\":\"MS-Board\",\"Version\":\"1.0.0\"}",,
3100 "lastInstallResult": {
3101 "resultCode": 700,
3102 "extendedResultCode": 0,
3103 "resultDetails": "",
3104 "stepResults": {
3105 "step_0": {
3106 "resultCode": 700,
3107 "extendedResultCode": 0,
3108 "resultDetails": ""
3109 }
3110 }
3111 }
3112 }
3113 }
3114 }
3115 */
nx_azure_iot_adu_agent_reported_properties_state_send(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)3116 static UINT nx_azure_iot_adu_agent_reported_properties_state_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
3117 {
3118
3119 NX_PACKET *packet_ptr;
3120 NX_AZURE_IOT_JSON_WRITER json_writer;
3121 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content);
3122 UINT status;
3123 UINT result_code;
3124 UINT i;
3125 /* Prepare the buffer for step name: such as: "step_0", the max name is "step_xxx". */
3126 CHAR step_property_name[8] = "step_";
3127 UINT step_size = sizeof("step_") - 1;
3128 UINT step_property_name_size;
3129 UINT update_id_length;
3130
3131 /* Create json writer for client reported property. */
3132 status = nx_azure_iot_hub_client_reported_properties_create(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &packet_ptr, NX_NO_WAIT);
3133 if (status)
3134 {
3135 return(status);
3136 }
3137
3138 /* Init json writer. */
3139 status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, NX_NO_WAIT);
3140 if (status)
3141 {
3142 nx_packet_release(packet_ptr);
3143 return(status);
3144 }
3145
3146 /* Append begin object. */
3147 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
3148 {
3149 nx_packet_release(packet_ptr);
3150 return(NX_NOT_SUCCESSFUL);
3151 }
3152
3153 /* Fill the ADU agent component name. */
3154 status = nx_azure_iot_hub_client_reported_properties_component_begin(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
3155 &json_writer,
3156 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME,
3157 sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1);
3158 if (status)
3159 {
3160 nx_packet_release(packet_ptr);
3161 return(status);
3162 }
3163
3164 /* Fill the agent property name. */
3165 if (nx_azure_iot_json_writer_append_property_name(&json_writer,
3166 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT,
3167 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT) - 1))
3168 {
3169 nx_packet_release(packet_ptr);
3170 return(NX_NOT_SUCCESSFUL);
3171 }
3172
3173 /* Start to fill agent property value. */
3174 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
3175 {
3176 nx_packet_release(packet_ptr);
3177 return(NX_NOT_SUCCESSFUL);
3178 }
3179
3180 /* Fill the state. */
3181 if (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3182 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STATE,
3183 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STATE) - 1,
3184 (INT)adu_agent_ptr -> nx_azure_iot_adu_agent_state))
3185 {
3186 nx_packet_release(packet_ptr);
3187 return(NX_NOT_SUCCESSFUL);
3188 }
3189
3190 /* Fill the workflow. */
3191 if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id_length)
3192 {
3193 if (nx_azure_iot_json_writer_append_property_name(&json_writer,
3194 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW,
3195 sizeof (NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW) - 1) ||
3196 nx_azure_iot_json_writer_append_begin_object(&json_writer) ||
3197 nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3198 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION,
3199 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION) - 1,
3200 (INT)adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.action) ||
3201 nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3202 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID,
3203 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID) - 1,
3204 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id,
3205 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id_length))
3206 {
3207 nx_packet_release(packet_ptr);
3208 return (NX_NOT_SUCCESSFUL);
3209 }
3210
3211 /* End workflow object. */
3212 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3213 {
3214 nx_packet_release(packet_ptr);
3215 return(NX_NOT_SUCCESSFUL);
3216 }
3217 }
3218
3219 /* Append retry timestamp in workflow if existed. */
3220 if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length)
3221 {
3222 if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3223 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP,
3224 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP) - 1,
3225 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp,
3226 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length))
3227 {
3228 nx_packet_release(packet_ptr);
3229 return (NX_NOT_SUCCESSFUL);
3230 }
3231 }
3232
3233 /* Fill installed update id. */
3234 if ((adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_IDLE) &&
3235 (adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content.steps_count))
3236 {
3237
3238 /* Use nx_azure_iot_adu_agent_update_manifest as temporary buffer to encode the update id as string.*/
3239 update_id_length = (UINT)snprintf((CHAR *)adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
3240 NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIZE,
3241 "{\"%.*s\":\"%.*s\",\"%.*s\":\"%.*s\",\"%.*s\":\"%.*s\"}",
3242 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER) - 1,
3243 NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER,
3244 manifest_content -> update_id.provider_length, manifest_content -> update_id.provider,
3245 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME) - 1,
3246 NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME,
3247 manifest_content -> update_id.name_length, manifest_content -> update_id.name,
3248 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION) - 1,
3249 NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION,
3250 manifest_content -> update_id.version_length, manifest_content -> update_id.version);
3251
3252 if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3253 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CONTENT_ID,
3254 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CONTENT_ID) - 1,
3255 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
3256 update_id_length))
3257 {
3258 nx_packet_release(packet_ptr);
3259 return (NX_NOT_SUCCESSFUL);
3260 }
3261 }
3262
3263 /* Fill the last install result. */
3264 if ((adu_agent_ptr -> nx_azure_iot_adu_agent_state != NX_AZURE_IOT_ADU_AGENT_STATE_DEPLOYMENT_IN_PROGRESS) &&
3265 (adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content.steps_count))
3266 {
3267
3268 /* Check the state. */
3269 if (adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_IDLE)
3270 {
3271 result_code = NX_AZURE_IOT_ADU_AGENT_RESULT_CODE_APPLY_SUCCESS;
3272 }
3273 else
3274 {
3275 result_code = NX_AZURE_IOT_ADU_AGENT_RESULT_CODE_FAILURE;
3276 }
3277
3278 if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
3279 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_LAST_INSTALL_RESULT,
3280 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_LAST_INSTALL_RESULT) - 1)) ||
3281 (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
3282 (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3283 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE,
3284 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE) - 1,
3285 (int32_t)result_code)) ||
3286 (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3287 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE,
3288 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE) - 1,
3289 0)) ||
3290 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3291 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS,
3292 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS) - 1,
3293 NX_NULL, 0)) ||
3294 (nx_azure_iot_json_writer_append_property_name(&json_writer,
3295 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEP_RESULTS,
3296 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEP_RESULTS) - 1)) ||
3297 (nx_azure_iot_json_writer_append_begin_object(&json_writer)))
3298 {
3299 nx_packet_release(packet_ptr);
3300 return(NX_NOT_SUCCESSFUL);
3301 }
3302
3303 /* Loop to fill the step results. */
3304 for (i = 0; i < adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content.steps_count; i++)
3305 {
3306 if ((step_property_name_size = _nx_utility_uint_to_string(i, 10, &step_property_name[step_size], 8 - step_size)) == 0)
3307 {
3308 nx_packet_release(packet_ptr);
3309 return(NX_NOT_SUCCESSFUL);
3310 }
3311 step_property_name_size += step_size;
3312
3313 if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
3314 (const UCHAR *)step_property_name,
3315 step_property_name_size)) ||
3316 (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
3317 (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3318 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE,
3319 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE) - 1,
3320 (int32_t)result_code)) ||
3321 (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3322 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE,
3323 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE) - 1,
3324 0)) ||
3325 (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3326 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS,
3327 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS) - 1,
3328 NX_NULL, 0)) ||
3329 (nx_azure_iot_json_writer_append_end_object(&json_writer)))
3330 {
3331 nx_packet_release(packet_ptr);
3332 return(NX_NOT_SUCCESSFUL);
3333 }
3334 }
3335
3336 if ((nx_azure_iot_json_writer_append_end_object(&json_writer)) ||
3337 (nx_azure_iot_json_writer_append_end_object(&json_writer)))
3338 {
3339 nx_packet_release(packet_ptr);
3340 return(NX_NOT_SUCCESSFUL);
3341 }
3342 }
3343
3344 /* End the client property value. */
3345 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3346 {
3347 nx_packet_release(packet_ptr);
3348 return(NX_NOT_SUCCESSFUL);
3349 }
3350
3351 /* End ADU agent component. */
3352 if (nx_azure_iot_hub_client_reported_properties_component_end(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &json_writer))
3353 {
3354 nx_packet_release(packet_ptr);
3355 return(NX_NOT_SUCCESSFUL);
3356 }
3357
3358 /* End json object. */
3359 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3360 {
3361 nx_packet_release(packet_ptr);
3362 return(NX_NOT_SUCCESSFUL);
3363 }
3364
3365 /* Send device info reported properties message to IoT Hub. */
3366 status = nx_azure_iot_hub_client_reported_properties_send(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
3367 packet_ptr,
3368 NX_NULL, NX_NULL,
3369 NX_NULL, NX_NO_WAIT);
3370 if (status)
3371 {
3372 nx_packet_release(packet_ptr);
3373 return(status);
3374 }
3375
3376 return(NX_AZURE_IOT_SUCCESS);
3377 }
3378
3379 /* service reported properties sample:
3380
3381 {
3382 "azureDeviceUpdateAgent": {
3383 "__t": "c",
3384 "<service>": {
3385 "ac": <status_code>,
3386 "av": <version>,
3387 "ad": "<description>",
3388 "value": <user_value>
3389 }
3390 }
3391 }
3392 */
3393
3394 /**
3395 * @brief Send service reported properties.
3396 *
3397 * @param updateState state to report.
3398 * @param result Result to report (optional, can be NULL).
3399 */
nx_azure_iot_adu_agent_service_reported_properties_send(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UINT status_code,ULONG version,const CHAR * description,ULONG wait_option)3400 static UINT nx_azure_iot_adu_agent_service_reported_properties_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr,
3401 UINT status_code, ULONG version, const CHAR *description,
3402 ULONG wait_option)
3403 {
3404 NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr = adu_agent_ptr -> nx_azure_iot_hub_client_ptr;
3405 NX_AZURE_IOT_JSON_WRITER json_writer;
3406 NX_PACKET *packet_ptr;
3407 UINT status;
3408
3409 /* Create json writer for service reported property. */
3410 status = nx_azure_iot_hub_client_reported_properties_create(iothub_client_ptr, &packet_ptr, wait_option);
3411 if (status)
3412 {
3413 return(status);
3414 }
3415
3416 /* Init json writer. */
3417 status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, wait_option);
3418 if (status)
3419 {
3420 nx_packet_release(packet_ptr);
3421 return(status);
3422 }
3423
3424 /* Append begin object. */
3425 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
3426 {
3427 nx_packet_release(packet_ptr);
3428 return(NX_NOT_SUCCESSFUL);
3429 }
3430
3431 /* Fill the response of writable service properties. */
3432 if (nx_azure_iot_hub_client_reported_properties_component_begin(iothub_client_ptr, &json_writer,
3433 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME,
3434 sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1) ||
3435 nx_azure_iot_hub_client_reported_properties_status_begin(iothub_client_ptr, &json_writer,
3436 (UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SERVICE,
3437 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_SERVICE) - 1,
3438 status_code, version,
3439 (const UCHAR *)description, strlen(description)))
3440 {
3441 nx_packet_release(packet_ptr);
3442 return (NX_NOT_SUCCESSFUL);
3443 }
3444
3445 /* Append begin object to start to fill user value. */
3446 if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
3447 {
3448 nx_packet_release(packet_ptr);
3449 return (NX_NOT_SUCCESSFUL);
3450 }
3451
3452 /* Fill the workflow. */
3453 if (nx_azure_iot_json_writer_append_property_name(&json_writer,
3454 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW,
3455 sizeof (NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW) - 1) ||
3456 nx_azure_iot_json_writer_append_begin_object(&json_writer) ||
3457 nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
3458 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION,
3459 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION) - 1,
3460 (INT)adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.action) ||
3461 nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3462 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID,
3463 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID) - 1,
3464 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id,
3465 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id_length))
3466 {
3467 nx_packet_release(packet_ptr);
3468 return (NX_NOT_SUCCESSFUL);
3469 }
3470
3471 /* Append retry timestamp in workflow if existed. */
3472 if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length)
3473 {
3474 if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3475 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP,
3476 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP) - 1,
3477 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp,
3478 adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length))
3479 {
3480 nx_packet_release(packet_ptr);
3481 return (NX_NOT_SUCCESSFUL);
3482 }
3483 }
3484
3485 /* End workflow object. */
3486 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3487 {
3488 nx_packet_release(packet_ptr);
3489 return(NX_NOT_SUCCESSFUL);
3490 }
3491
3492 /* Fill updateManifest. */
3493 if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
3494 (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST,
3495 sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_UPDATE_MANIFEST) - 1,
3496 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
3497 adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_size))
3498 {
3499 nx_packet_release(packet_ptr);
3500 return (NX_NOT_SUCCESSFUL);
3501 }
3502
3503 /* Append end object. */
3504 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3505 {
3506 nx_packet_release(packet_ptr);
3507 return (NX_NOT_SUCCESSFUL);
3508 }
3509
3510 /* End status and component. */
3511 if (nx_azure_iot_hub_client_reported_properties_status_end(iothub_client_ptr, &json_writer) ||
3512 nx_azure_iot_hub_client_reported_properties_component_end(iothub_client_ptr, &json_writer))
3513 {
3514 nx_packet_release(packet_ptr);
3515 return (NX_NOT_SUCCESSFUL);
3516 }
3517
3518 /* End json object. */
3519 if (nx_azure_iot_json_writer_append_end_object(&json_writer))
3520 {
3521 nx_packet_release(packet_ptr);
3522 return(NX_NOT_SUCCESSFUL);
3523 }
3524
3525 /* Send service reported property. */
3526 status = nx_azure_iot_hub_client_reported_properties_send(iothub_client_ptr,
3527 packet_ptr, NX_NULL,
3528 NX_NULL, NX_NULL,
3529 wait_option);
3530 if(status)
3531 {
3532 nx_packet_release(packet_ptr);
3533 return(status);
3534 }
3535
3536 return(NX_AZURE_IOT_SUCCESS);
3537 }
3538
3539 extern const NX_AZURE_IOT_ADU_AGENT_RSA_ROOT_KEY _nx_azure_iot_adu_agent_rsa_root_key_list[];
3540 extern const UINT _nx_azure_iot_adu_agent_rsa_root_key_list_size;
nx_azure_iot_adu_agent_rsa_root_key_find(const UCHAR * kid,UINT kid_size)3541 static const NX_AZURE_IOT_ADU_AGENT_RSA_ROOT_KEY *nx_azure_iot_adu_agent_rsa_root_key_find(const UCHAR* kid, UINT kid_size)
3542 {
3543
3544 /* Loop to find the root key. */
3545 for (UINT i = 0; i < _nx_azure_iot_adu_agent_rsa_root_key_list_size; i++)
3546 {
3547
3548 /* Check the kid. */
3549 if ((kid_size == _nx_azure_iot_adu_agent_rsa_root_key_list[i].kid_size) &&
3550 (memcmp(kid, _nx_azure_iot_adu_agent_rsa_root_key_list[i].kid, kid_size) == 0))
3551 {
3552
3553 /* Find the root key. */
3554 return(&_nx_azure_iot_adu_agent_rsa_root_key_list[i]);
3555 }
3556 }
3557
3558 return(NX_NULL);
3559 }
3560
3561 /* SHA256. */
nx_azure_iot_adu_agent_sha256_calculate(NX_CRYPTO_METHOD * sha256_method,UCHAR * metadata_ptr,UINT metadata_size,UCHAR * input_ptr,ULONG input_size,UCHAR * output_ptr,ULONG output_size)3562 static UINT nx_azure_iot_adu_agent_sha256_calculate(NX_CRYPTO_METHOD *sha256_method,
3563 UCHAR *metadata_ptr, UINT metadata_size,
3564 UCHAR *input_ptr, ULONG input_size,
3565 UCHAR *output_ptr, ULONG output_size)
3566 {
3567 UINT status;
3568
3569
3570 /* Initialize crypto method. */
3571 if (sha256_method -> nx_crypto_init)
3572 {
3573 status = sha256_method -> nx_crypto_init((NX_CRYPTO_METHOD*)sha256_method,
3574 NX_NULL,
3575 0,
3576 NX_NULL,
3577 metadata_ptr,
3578 metadata_size);
3579
3580 /* Check status. */
3581 if (status)
3582 {
3583 return(status);
3584 }
3585 }
3586
3587 /* Initialize hash. */
3588 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
3589 NX_NULL,
3590 (NX_CRYPTO_METHOD*)sha256_method,
3591 NX_NULL,
3592 0,
3593 NX_NULL,
3594 0,
3595 NX_NULL,
3596 NX_NULL,
3597 0,
3598 metadata_ptr,
3599 metadata_size,
3600 NX_NULL,
3601 NX_NULL);
3602
3603 /* Update hash value for data. */
3604 if (status == NX_SUCCESS)
3605 {
3606 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
3607 NX_NULL,
3608 (NX_CRYPTO_METHOD*)sha256_method,
3609 NX_NULL,
3610 0,
3611 input_ptr,
3612 input_size,
3613 NX_NULL,
3614 NX_NULL,
3615 0,
3616 metadata_ptr,
3617 metadata_size,
3618 NX_NULL,
3619 NX_NULL);
3620 }
3621
3622 /* Calculate the hash value. */
3623 if (status == NX_SUCCESS)
3624 {
3625 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
3626 NX_NULL,
3627 (NX_CRYPTO_METHOD*)sha256_method,
3628 NX_NULL,
3629 0,
3630 NX_NULL,
3631 0,
3632 NX_NULL,
3633 output_ptr,
3634 output_size,
3635 metadata_ptr,
3636 metadata_size,
3637 NX_NULL,
3638 NX_NULL);
3639 }
3640
3641 /* Cleanup. */
3642 if (sha256_method -> nx_crypto_cleanup)
3643 {
3644 sha256_method -> nx_crypto_cleanup(metadata_ptr);
3645 }
3646
3647 return(status);
3648 }
3649
3650
3651 /* RS256. */
nx_azure_iot_adu_agent_rs256_verify(NX_AZURE_IOT_ADU_AGENT_CRYPTO * adu_agent_crypto,UCHAR * input_ptr,ULONG input_size,UCHAR * signature_ptr,ULONG signature_size,UCHAR * n,ULONG n_size,UCHAR * e,ULONG e_size,UCHAR * buffer_ptr,UINT buffer_size)3652 static UINT nx_azure_iot_adu_agent_rs256_verify(NX_AZURE_IOT_ADU_AGENT_CRYPTO *adu_agent_crypto,
3653 UCHAR *input_ptr, ULONG input_size,
3654 UCHAR *signature_ptr, ULONG signature_size,
3655 UCHAR *n, ULONG n_size,
3656 UCHAR *e, ULONG e_size,
3657 UCHAR *buffer_ptr, UINT buffer_size)
3658 {
3659
3660 UINT status;
3661 UCHAR *oid;
3662 UINT oid_length;
3663 UCHAR *decrypted_hash;
3664 UINT decrypted_hash_length;
3665 UCHAR *rsa_buffer = buffer_ptr;
3666 UCHAR *sha_buffer = buffer_ptr + NX_AZURE_IOT_ADU_AGENT_RSA3072_SIZE;
3667
3668 /* Check buffer size. */
3669 if (buffer_size < (NX_AZURE_IOT_ADU_AGENT_RSA3072_SIZE + NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE))
3670 {
3671 return(NX_FALSE);
3672 }
3673
3674 /* Decrypt the signature by RSA. */
3675
3676 /* Initialize. */
3677 status = adu_agent_crypto -> method_rsa -> nx_crypto_init((NX_CRYPTO_METHOD*)adu_agent_crypto -> method_rsa,
3678 n,
3679 n_size << 3,
3680 NX_NULL,
3681 adu_agent_crypto -> method_rsa_metadata,
3682 adu_agent_crypto -> method_rsa_metadata_size);
3683
3684 /* Check status. */
3685 if (status)
3686 {
3687 return(NX_FALSE);
3688 }
3689
3690 /* Decrypt the signature. */
3691 status = adu_agent_crypto -> method_rsa -> nx_crypto_operation(NX_CRYPTO_DECRYPT,
3692 NX_NULL,
3693 (NX_CRYPTO_METHOD*)adu_agent_crypto -> method_rsa,
3694 e,
3695 e_size << 3,
3696 signature_ptr,
3697 signature_size,
3698 NX_NULL,
3699 rsa_buffer,
3700 NX_AZURE_IOT_ADU_AGENT_RSA3072_SIZE,
3701 adu_agent_crypto -> method_rsa_metadata,
3702 adu_agent_crypto -> method_rsa_metadata_size,
3703 NX_NULL,
3704 NX_NULL);
3705
3706 /* Cleanup. */
3707 if (adu_agent_crypto -> method_rsa -> nx_crypto_cleanup)
3708 {
3709 adu_agent_crypto -> method_rsa -> nx_crypto_cleanup(adu_agent_crypto -> method_rsa_metadata);
3710 }
3711
3712 /* Check status. */
3713 if (status)
3714 {
3715 return(NX_FALSE);
3716 }
3717
3718 /* Decode the decrypted signature, which should be in PKCS#7 format. */
3719 status = _nx_secure_x509_pkcs7_decode(rsa_buffer, signature_size,
3720 (const UCHAR **)&oid, &oid_length,
3721 (const UCHAR **)&decrypted_hash, &decrypted_hash_length);
3722
3723 /* Check status. */
3724 if (status)
3725 {
3726 return(NX_FALSE);
3727 }
3728
3729 /* Calculate input by SHA256. */
3730 status = nx_azure_iot_adu_agent_sha256_calculate(adu_agent_crypto -> method_sha256,
3731 adu_agent_crypto -> method_sha256_metadata,
3732 NX_AZURE_IOT_ADU_AGENT_SHA256_METADATA_SIZE,
3733 input_ptr, input_size,
3734 sha_buffer, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE);
3735
3736 /* Check status. */
3737 if (status)
3738 {
3739 return(NX_FALSE);
3740 }
3741
3742 /* Verify. */
3743 if ((decrypted_hash_length != NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE) ||
3744 (memcmp(decrypted_hash, sha_buffer, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE)))
3745 {
3746 return(NX_FALSE);
3747 }
3748
3749 return(NX_TRUE);
3750 }
3751
nx_azure_iot_adu_agent_file_url_parse(UCHAR * file_url,ULONG file_url_length,UCHAR * buffer_ptr,UINT buffer_size,NX_AZURE_IOT_ADU_AGENT_DOWNLOADER * downloader_ptr)3752 static UINT nx_azure_iot_adu_agent_file_url_parse(UCHAR *file_url, ULONG file_url_length,
3753 UCHAR *buffer_ptr, UINT buffer_size,
3754 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr)
3755 {
3756 UINT i;
3757 UINT dot_count = 0;
3758 UINT temp = 0;
3759 ULONG ip_address = 0;
3760 UCHAR address_found = NX_FALSE;
3761 UCHAR port_found = NX_FALSE;
3762
3763
3764 /* Initialize. */
3765 downloader_ptr -> host = NX_NULL;
3766 downloader_ptr -> resource = NX_NULL;
3767
3768 /* Format: http://host:port/resource. */
3769 if (memcmp(file_url, NX_AZURE_IOT_ADU_AGENT_HTTP_PROTOCOL, sizeof(NX_AZURE_IOT_ADU_AGENT_HTTP_PROTOCOL) - 1))
3770 {
3771 return(NX_AZURE_IOT_FAILURE);
3772 }
3773
3774 /* Set the host ptr. */
3775 file_url += (sizeof(NX_AZURE_IOT_ADU_AGENT_HTTP_PROTOCOL) - 1);
3776 file_url_length -= (sizeof(NX_AZURE_IOT_ADU_AGENT_HTTP_PROTOCOL) - 1);
3777
3778 /* Try to detect whether the host is numerical IP address. */
3779 for (i = 0; i < file_url_length; i++)
3780 {
3781 if (file_url[i] >= '0' && file_url[i] <= '9')
3782 {
3783 temp = (UINT)(temp * 10 + (UINT)(file_url[i] - '0'));
3784 if ((temp > 0xFF && port_found == NX_FALSE) ||
3785 (temp > 0xFFFF && port_found == NX_TRUE))
3786 {
3787 break;
3788 }
3789 }
3790 else if (file_url[i] == '.')
3791 {
3792 if (dot_count++ == 3)
3793 {
3794 break;
3795 }
3796 ip_address = (ip_address << 8) + temp;
3797 temp = 0;
3798 }
3799 else if (file_url[i] == ':')
3800 {
3801 if ((dot_count != 3) || (port_found == NX_TRUE))
3802 {
3803 break;
3804 }
3805 ip_address = (ip_address << 8) + temp;
3806
3807 /* Set the address. */
3808 downloader_ptr -> address.nxd_ip_version = NX_IP_VERSION_V4;
3809 downloader_ptr -> address.nxd_ip_address.v4 = ip_address;
3810 address_found = NX_TRUE;
3811
3812 /* Try to reslove the port. */
3813 temp = 0;
3814 port_found = NX_TRUE;
3815 }
3816 else if (file_url[i] == '/')
3817 {
3818 if (dot_count == 3)
3819 {
3820 if (port_found)
3821 {
3822 downloader_ptr -> port = temp;
3823 }
3824 else
3825 {
3826 ip_address = (ip_address << 8) + temp;
3827
3828 /* Set the address. */
3829 downloader_ptr -> address.nxd_ip_version = NX_IP_VERSION_V4;
3830 downloader_ptr -> address.nxd_ip_address.v4 = ip_address;
3831 address_found = NX_TRUE;
3832 }
3833 }
3834 break;
3835 }
3836 else
3837 {
3838 break;
3839 }
3840 }
3841
3842 /* Check if there is enough buffer. */
3843 if (file_url_length >= buffer_size)
3844 {
3845 return(NX_AZURE_IOT_FAILURE);
3846 }
3847
3848 /* Split host and resource url . */
3849 for (; i < file_url_length; i++)
3850 {
3851 if (file_url[i] == '/')
3852 {
3853
3854 /* Store the host ans resource. */
3855 downloader_ptr -> host = buffer_ptr;
3856 memcpy(downloader_ptr -> host, file_url, i); /* Use case of memcpy is verified. */
3857 *(buffer_ptr + i) = NX_NULL;
3858
3859 /* Set the resource url. */
3860 downloader_ptr -> resource = (buffer_ptr + i + 1);
3861 memcpy(downloader_ptr -> resource, &file_url[i + 1], (file_url_length - i - 1)); /* Use case of memcpy is verified. */
3862 *(buffer_ptr + file_url_length) = NX_NULL;
3863
3864 /* Update buffer size. */
3865 buffer_size -= (file_url_length + 1);
3866 break;
3867 }
3868 }
3869
3870 /* Check the host and resource. */
3871 if ((downloader_ptr -> host == NX_NULL) || (downloader_ptr -> resource == NX_NULL))
3872 {
3873 return(NX_AZURE_IOT_FAILURE);
3874 }
3875
3876 /* Update the state. */
3877 if (address_found == NX_FALSE)
3878 {
3879 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_URL_PARSED;
3880 }
3881 else
3882 {
3883 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_DONE;
3884 }
3885
3886 /* Check if found the port. */
3887 if (port_found == NX_FALSE)
3888 {
3889
3890 /* Set tht http port as default. */
3891 downloader_ptr -> port = NX_WEB_HTTP_SERVER_PORT;
3892 }
3893
3894 return(NX_AZURE_IOT_SUCCESS);
3895 }
3896
nx_azure_iot_adu_agent_dns_query(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)3897 static void nx_azure_iot_adu_agent_dns_query(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
3898 {
3899 UINT status;
3900 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
3901
3902
3903 /* Check the state. */
3904 if ((downloader_ptr -> state != NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_URL_PARSED) &&
3905 (downloader_ptr -> state != NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_QUERY))
3906 {
3907 return;
3908 }
3909
3910 /* Check if reach the max retry count. */
3911 if (downloader_ptr -> dns_query_count <= NX_AZURE_IOT_ADU_AGENT_DNS_RETRANSMIT_COUNT)
3912 {
3913
3914 /* Set the timeout. */
3915 downloader_ptr -> timeout = (ULONG)(NX_AZURE_IOT_ADU_AGENT_DNS_INITIAL_TIMEOUT << downloader_ptr -> dns_query_count);
3916
3917 /* Update the query count. */
3918 downloader_ptr -> dns_query_count++;
3919
3920 /* Update state. */
3921 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_QUERY;
3922
3923 /* Resolve the host name by DNS. */
3924 status = nxd_dns_host_by_name_get(downloader_ptr -> dns_ptr,
3925 downloader_ptr -> host,
3926 &(downloader_ptr -> address),
3927 NX_NO_WAIT, NX_IP_VERSION_V4);
3928
3929 /* Check status. */
3930 if (status == NX_SUCCESS)
3931 {
3932
3933 /* Got the address, update the state. */
3934 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_DONE;
3935
3936 /* Start HTTP connect. */
3937 nx_azure_iot_adu_agent_http_connect(adu_agent_ptr);
3938 return;
3939 }
3940 else if (status == NX_IN_PROGRESS)
3941 {
3942
3943 /* Query in progress. */
3944 return;
3945 }
3946 }
3947
3948 LogError(LogLiteralArgs("Firmware download fail: DNS QUERY FAIL"));
3949
3950 /* Send dns query failed or already reach the max retransmission count. */
3951 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
3952 }
3953
nx_azure_iot_adu_agent_dns_response_notify(NX_UDP_SOCKET * socket_ptr)3954 static void nx_azure_iot_adu_agent_dns_response_notify(NX_UDP_SOCKET *socket_ptr)
3955 {
3956 NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr;
3957
3958
3959 /* Set adu agent pointer. */
3960 adu_agent_ptr = (NX_AZURE_IOT_ADU_AGENT *)socket_ptr -> nx_udp_socket_reserved_ptr;
3961
3962 /* Set the DNS response receive event. */
3963 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
3964 NX_AZURE_IOT_ADU_AGENT_DNS_RESPONSE_RECEIVE_EVENT);
3965 }
3966
nx_azure_iot_adu_agent_dns_response_get(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)3967 static void nx_azure_iot_adu_agent_dns_response_get(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
3968 {
3969 UINT status;
3970 UINT record_count;
3971 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
3972
3973
3974 /* Try to get the response. */
3975 status = _nx_dns_response_get(downloader_ptr -> dns_ptr, downloader_ptr -> host,
3976 (UCHAR *)&downloader_ptr -> address.nxd_ip_address.v4, sizeof(ULONG),
3977 &record_count, NX_NO_WAIT);
3978
3979 /* Check status. */
3980 if (status)
3981 {
3982
3983 /* Retry DNS query. */
3984 nx_azure_iot_adu_agent_dns_query(adu_agent_ptr);
3985 }
3986 else
3987 {
3988
3989 /* Set the address version. */
3990 downloader_ptr -> address.nxd_ip_version = NX_IP_VERSION_V4;
3991
3992 /* Update the state. */
3993 adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_ADDRESS_DONE;
3994
3995 /* Start HTTP connect. */
3996 nx_azure_iot_adu_agent_http_connect(adu_agent_ptr);
3997 }
3998 }
3999
nx_azure_iot_adu_agent_http_connect(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)4000 static void nx_azure_iot_adu_agent_http_connect(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
4001 {
4002
4003 UINT status;
4004 NX_IP *ip_ptr;
4005 NX_CRYPTO_METHOD *sha256_method;
4006 UCHAR *sha256_method_metadata;
4007 ULONG sha256_method_metadata_size;
4008 VOID *handler;
4009 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
4010
4011 /* Initialize. */
4012 ip_ptr = adu_agent_ptr -> nx_azure_iot_hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_ip_ptr;
4013 downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
4014
4015 /* Initialize hash for downloading firmware. */
4016 sha256_method = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256;
4017 sha256_method_metadata = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256_metadata;
4018 sha256_method_metadata_size = NX_AZURE_IOT_ADU_AGENT_SHA256_METADATA_SIZE;
4019 handler = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.handler;
4020
4021 /* Initialize the crypto. */
4022 if (sha256_method -> nx_crypto_init)
4023 {
4024 status = sha256_method -> nx_crypto_init((NX_CRYPTO_METHOD*)sha256_method,
4025 NX_NULL,
4026 0,
4027 &handler,
4028 sha256_method_metadata,
4029 sha256_method_metadata_size);
4030
4031 /* Check status. */
4032 if (status)
4033 {
4034 LogError(LogLiteralArgs("Firmware download fail: SHA256 INIT ERROR"));
4035 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4036 return;
4037 }
4038 }
4039
4040 /* Initialize the sha256 for firmware hash. */
4041 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
4042 handler,
4043 (NX_CRYPTO_METHOD*)sha256_method,
4044 NX_NULL,
4045 0,
4046 NX_NULL,
4047 0,
4048 NX_NULL,
4049 NX_NULL,
4050 0,
4051 sha256_method_metadata,
4052 sha256_method_metadata_size,
4053 NX_NULL,
4054 NX_NULL);
4055
4056 /* Check status. */
4057 if (status)
4058 {
4059 LogError(LogLiteralArgs("Firmware download fail: SHA256 INIT ERROR"));
4060 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4061 return;
4062 }
4063
4064 /* Create an HTTP client instance. */
4065 status = nx_web_http_client_create(&(downloader_ptr -> http_client),
4066 "HTTP Client",
4067 ip_ptr, ip_ptr -> nx_ip_default_packet_pool,
4068 NX_AZURE_IOT_ADU_AGENT_HTTP_WINDOW_SIZE);
4069
4070 /* Check status. */
4071 if (status)
4072 {
4073 LogError(LogLiteralArgs("Firmware download fail: CLIENT CREATE FAIL"));
4074 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4075 return;
4076 }
4077
4078 /* Update the state and timeout. */
4079 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONNECT;
4080 downloader_ptr -> timeout = NX_AZURE_IOT_ADU_AGENT_HTTP_CONNECT_TIMEOUT;
4081
4082 /* Set the notify. */
4083 downloader_ptr -> http_client.nx_web_http_client_socket.nx_tcp_socket_reserved_ptr = adu_agent_ptr;
4084 nx_tcp_socket_establish_notify(&(downloader_ptr -> http_client.nx_web_http_client_socket),
4085 nx_azure_iot_adu_agent_http_establish_notify);
4086 nx_tcp_socket_receive_notify(&(downloader_ptr -> http_client.nx_web_http_client_socket),
4087 nx_azure_iot_adu_agent_http_receive_notify);
4088
4089 /* Connect to Server. */
4090 status = nx_web_http_client_connect(&(downloader_ptr -> http_client),
4091 &(downloader_ptr -> address),
4092 downloader_ptr -> port,
4093 NX_NO_WAIT);
4094
4095 /* Check status. */
4096 if (status == NX_SUCCESS)
4097 {
4098
4099 /* Connection established. Start to get file content. */
4100 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
4101 NX_AZURE_IOT_ADU_AGENT_HTTP_CONNECT_DONE_EVENT);
4102 return;
4103 }
4104 else if (status == NX_IN_PROGRESS)
4105 {
4106
4107 /* Query in progress. */
4108 return;
4109 }
4110
4111 LogError(LogLiteralArgs("Firmware download fail: CLIENT CONNECT FAIL"));
4112
4113 /* Failed. */
4114 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4115 return;
4116 }
4117
nx_azure_iot_adu_agent_http_request_send(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)4118 static void nx_azure_iot_adu_agent_http_request_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
4119 {
4120 UINT status;
4121 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
4122
4123
4124 /* Update the state and timeout. */
4125 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONTENT_GET;
4126 downloader_ptr -> timeout = NX_AZURE_IOT_ADU_AGENT_HTTP_DOWNLOAD_TIMEOUT;
4127
4128 /* Use the service to send a GET request to the server . */
4129 status = nx_web_http_client_request_initialize(&(downloader_ptr -> http_client),
4130 NX_WEB_HTTP_METHOD_GET,
4131 (CHAR *)downloader_ptr -> resource,
4132 (CHAR *)downloader_ptr -> host,
4133 0, NX_FALSE, NX_NULL, NX_NULL,
4134 NX_NO_WAIT);
4135
4136 /* Check status. */
4137 if (status)
4138 {
4139 LogError(LogLiteralArgs("Firmware download fail: CLIENT REQUEST INIT FAIL"));
4140 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4141 return;
4142 }
4143
4144 /* Send the HTTP request we just built. */
4145 status = nx_web_http_client_request_send(&(downloader_ptr -> http_client), NX_NO_WAIT);
4146
4147 /* Check status. */
4148 if (status)
4149 {
4150 LogError(LogLiteralArgs("Firmware download fail: CLIENT REQUEST SEND FAIL"));
4151 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4152 return;
4153 }
4154 }
4155
nx_azure_iot_adu_agent_http_response_receive(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr)4156 static void nx_azure_iot_adu_agent_http_response_receive(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr)
4157 {
4158
4159 UINT status;
4160 UINT get_status;
4161 NX_PACKET *received_packet;
4162 NX_PACKET *data_packet;
4163 UINT data_size;
4164 NX_CRYPTO_METHOD *sha256_method = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256;
4165 UCHAR *sha256_method_metadata = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256_metadata;;
4166 ULONG sha256_method_metadata_size = NX_AZURE_IOT_ADU_AGENT_SHA256_METADATA_SIZE;
4167 VOID *handler = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.handler;
4168 UCHAR *generated_hash;
4169 UCHAR *decoded_hash;
4170 UINT bytes_copied;
4171 NX_AZURE_IOT_ADU_AGENT_DRIVER driver_request;
4172 NX_AZURE_IOT_ADU_AGENT_DOWNLOADER *downloader_ptr = &(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader);
4173
4174 /* Check the state. */
4175 if (downloader_ptr -> state != NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONTENT_GET)
4176 {
4177 return;
4178 }
4179
4180 /* Receive response data from the server. Loop until all data is received. */
4181 get_status = NX_SUCCESS;
4182 while ((get_status != NX_WEB_HTTP_GET_DONE) && (downloader_ptr -> received_firmware_size < downloader_ptr -> file -> file_size_in_bytes))
4183 {
4184 get_status = nx_web_http_client_response_body_get(&(downloader_ptr -> http_client), &received_packet, NX_NO_WAIT);
4185
4186 /* Check for error. */
4187 if ((get_status == NX_SUCCESS) || (get_status == NX_WEB_HTTP_GET_DONE) || (get_status == NX_WEB_HTTP_STATUS_CODE_PARTIAL_CONTENT))
4188 {
4189
4190 /* Loop to write the data from packet into flash. */
4191 data_packet = received_packet;
4192 #ifndef NX_DISABLE_PACKET_CHAIN
4193 while(data_packet)
4194 {
4195 #endif /* NX_DISABLE_PACKET_CHAIN */
4196
4197 /* Calculate the data size in current packet. */
4198 data_size = (UINT)(data_packet -> nx_packet_append_ptr - data_packet -> nx_packet_prepend_ptr);
4199
4200 /* Update the hash value for data. */
4201 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
4202 NX_NULL,
4203 (NX_CRYPTO_METHOD*)sha256_method,
4204 NX_NULL,
4205 0,
4206 data_packet -> nx_packet_prepend_ptr,
4207 (ULONG)data_size,
4208 NX_NULL,
4209 NX_NULL,
4210 0,
4211 sha256_method_metadata,
4212 sha256_method_metadata_size,
4213 NX_NULL,
4214 NX_NULL);
4215
4216 /* Check status. */
4217 if (status)
4218 {
4219
4220 /* Release the packet. */
4221 nx_packet_release(received_packet);
4222 LogError(LogLiteralArgs("Firmware download fail: HASH UPDATE ERROR"));
4223 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4224 return;
4225 }
4226
4227 if (downloader_ptr -> type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE)
4228 {
4229
4230 /* Send the firmware write request to the driver. */
4231 driver_request.nx_azure_iot_adu_agent_driver_command = NX_AZURE_IOT_ADU_AGENT_DRIVER_WRITE;
4232 driver_request.nx_azure_iot_adu_agent_driver_firmware_data_offset = downloader_ptr -> received_firmware_size;
4233 driver_request.nx_azure_iot_adu_agent_driver_firmware_data_ptr = data_packet -> nx_packet_prepend_ptr;
4234 driver_request.nx_azure_iot_adu_agent_driver_firmware_data_size = data_size;
4235 driver_request.nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS;
4236 (downloader_ptr -> driver_entry)(&driver_request);
4237
4238 /* Check status. */
4239 if (driver_request.nx_azure_iot_adu_agent_driver_status)
4240 {
4241
4242 /* Release the packet. */
4243 nx_packet_release(received_packet);
4244 LogError(LogLiteralArgs("Firmware download fail: DRIVER WRITE ERROR"));
4245 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4246 return;
4247 }
4248 }
4249 else
4250 {
4251
4252 if ((downloader_ptr -> received_firmware_size + data_size) > downloader_ptr -> manifest_buffer_size)
4253 {
4254
4255 /* Release the packet. */
4256 nx_packet_release(received_packet);
4257 LogError(LogLiteralArgs("Firmware download fail: BUFFER ERROR"));
4258 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4259 return;
4260 }
4261
4262 memcpy(downloader_ptr -> manifest_buffer_ptr + downloader_ptr -> received_firmware_size, /* Use case of memcpy is verified. */
4263 data_packet -> nx_packet_prepend_ptr, data_size);
4264 }
4265
4266 /* Update received firmware size. */
4267 downloader_ptr -> received_firmware_size += data_size;
4268
4269 #ifndef NX_DISABLE_PACKET_CHAIN
4270 data_packet = data_packet -> nx_packet_next;
4271 }
4272 #endif /* NX_DISABLE_PACKET_CHAIN */
4273
4274 /* Release the packet. */
4275 nx_packet_release(received_packet);
4276
4277 if (downloader_ptr -> type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE)
4278 {
4279 LogInfo(LogLiteralArgs("Getting download data... %d"), downloader_ptr -> received_firmware_size);
4280 }
4281 }
4282 else
4283 {
4284 if (get_status != NX_NO_PACKET)
4285 {
4286 LogError(LogLiteralArgs("Firmware download fail: RECEIVE ERROR"));
4287 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4288 }
4289 return;
4290 }
4291 }
4292
4293 /* Output info. */
4294 if (downloader_ptr -> type == NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_TYPE_FIRMWARE)
4295 {
4296 LogInfo(LogLiteralArgs("Firmware downloaded"));
4297 }
4298 downloader_ptr -> state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_DONE;
4299
4300 /* Firmware downloaded. Verify the hash. */
4301
4302 /* Set hash buffer. */
4303 if ((NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIZE - (downloader_ptr -> host_length + 1 + downloader_ptr -> resource_length + 1)) <
4304 ((NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE + 1) << 1))
4305 {
4306 LogError(LogLiteralArgs("Firmware verify fail: INSUFFICIENT BUFFER FOR SHA256"));
4307 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4308 return;
4309 }
4310 generated_hash = adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest +
4311 downloader_ptr -> host_length + 1 + downloader_ptr -> resource_length + 1;
4312 decoded_hash = generated_hash + NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE + 1;
4313
4314 /* Calculate the hash value. */
4315 status = sha256_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
4316 handler,
4317 (NX_CRYPTO_METHOD*)sha256_method,
4318 NX_NULL,
4319 0,
4320 NX_NULL,
4321 0,
4322 NX_NULL,
4323 generated_hash,
4324 NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE,
4325 sha256_method_metadata,
4326 sha256_method_metadata_size,
4327 NX_NULL,
4328 NX_NULL);
4329
4330 /* Check status. */
4331 if (status)
4332 {
4333 LogError(LogLiteralArgs("Firmware verify fail: HASH ERROR"));
4334 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4335 return;
4336 }
4337
4338 /* Decode the file hash (base64). */
4339 if (_nx_utility_base64_decode(downloader_ptr -> file -> file_sha256,
4340 downloader_ptr -> file -> file_sha256_length,
4341 decoded_hash, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE + 1, &bytes_copied))
4342 {
4343 LogError(LogLiteralArgs("Firmware verify fail: HASH ERROR"));
4344 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4345 return;
4346 }
4347
4348 /* Verify the hash value. */
4349 if (memcmp(generated_hash, decoded_hash, NX_AZURE_IOT_ADU_AGENT_SHA256_HASH_SIZE))
4350 {
4351 LogError(LogLiteralArgs("Firmware verify fail: HASH ERROR"));
4352 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_FALSE);
4353 return;
4354 }
4355
4356 /* Update download state. */
4357 nx_azure_iot_adu_agent_download_state_update(adu_agent_ptr, NX_TRUE);
4358 }
4359
nx_azure_iot_adu_agent_http_establish_notify(NX_TCP_SOCKET * socket_ptr)4360 static void nx_azure_iot_adu_agent_http_establish_notify(NX_TCP_SOCKET *socket_ptr)
4361 {
4362 NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr;
4363
4364
4365 /* Set adu agent pointer. */
4366 adu_agent_ptr = (NX_AZURE_IOT_ADU_AGENT *)socket_ptr -> nx_tcp_socket_reserved_ptr;
4367
4368 /* Set the DNS response receive event. */
4369 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
4370 NX_AZURE_IOT_ADU_AGENT_HTTP_CONNECT_DONE_EVENT);
4371 }
4372
nx_azure_iot_adu_agent_http_receive_notify(NX_TCP_SOCKET * socket_ptr)4373 static void nx_azure_iot_adu_agent_http_receive_notify(NX_TCP_SOCKET *socket_ptr)
4374 {
4375 NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr;
4376
4377
4378 /* Set adu agent pointer. */
4379 adu_agent_ptr = (NX_AZURE_IOT_ADU_AGENT *)socket_ptr -> nx_tcp_socket_reserved_ptr;
4380
4381 /* Set the DNS response receive event. */
4382 nx_cloud_module_event_set(&(adu_agent_ptr -> nx_azure_iot_adu_agent_cloud_module),
4383 NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT);
4384 }
4385
nx_azure_iot_adu_agent_download_state_update(NX_AZURE_IOT_ADU_AGENT * adu_agent_ptr,UINT success)4386 static void nx_azure_iot_adu_agent_download_state_update(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT success)
4387 {
4388 NX_CRYPTO_METHOD *sha256_method = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256;
4389 UCHAR *sha256_method_metadata = adu_agent_ptr -> nx_azure_iot_adu_agent_crypto.method_sha256_metadata;
4390
4391 /* Cleanup download socket. */
4392 if (adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.state >= NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_HTTP_CONNECT)
4393 {
4394
4395 /* Delete http client. */
4396 nx_web_http_client_delete(&(adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.http_client));
4397 }
4398
4399 /* Reset the state. */
4400 adu_agent_ptr -> nx_azure_iot_adu_agent_downloader.state = NX_AZURE_IOT_ADU_AGENT_DOWNLOADER_IDLE;
4401
4402 /* Cleanup sha256. */
4403 if (sha256_method -> nx_crypto_cleanup)
4404 {
4405 sha256_method -> nx_crypto_cleanup(sha256_method_metadata);
4406 }
4407
4408 /* Update the state according to the download status. */
4409 if (success == NX_TRUE)
4410 {
4411
4412 /* Download complete, update state to next state. */
4413 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, adu_agent_ptr -> nx_azure_iot_adu_agent_current_step -> state + 1);
4414 }
4415 else
4416 {
4417 nx_azure_iot_adu_agent_step_state_update(adu_agent_ptr, NX_AZURE_IOT_ADU_AGENT_STEP_STATE_FAILED);
4418 }
4419 }
4420