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