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