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