1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12 #include "nx_azure_iot_hub_client.h"
13
14 #include "azure/core/az_version.h"
15
16
17 #define NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE 10
18 #define NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON "{}"
19 #define NX_AZURE_IOT_HUB_CLIENT_THROTTLE_STATUS_CODE 429
20
21 #ifndef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT
22 #ifndef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_INTERFACE_TYPE
23 #define NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_INTERFACE_TYPE NX_INTERFACE_TYPE_UNKNOWN
24 #define NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_UPDATE
25 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_INTERFACE_TYPE */
26
27 #ifndef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_VENDOR
28 #define NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_VENDOR 0
29 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_VENDOR */
30
31 #ifndef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_TYPE
32 #define NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_TYPE "U"
33 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_TYPE */
34
35 /* Useragent e.g: azsdk-c%2F1.3.0%20%28azrtos%206.1.2%3B0%3B0%3BU%29 */
36 #define NX_AZURE_IOT_HUB_CLIENT_STR(C) #C
37 #define NX_AZURE_IOT_HUB_CLIENT_TO_STR(x) NX_AZURE_IOT_HUB_CLIENT_STR(x)
38 #define NX_AZURE_IOT_HUB_CLIENT_USER_AGENT "azsdk-c%2F" AZ_SDK_VERSION_STRING "%20%28azrtos%20" \
39 NX_AZURE_IOT_HUB_CLIENT_TO_STR(THREADX_MAJOR_VERSION) "." \
40 NX_AZURE_IOT_HUB_CLIENT_TO_STR(THREADX_MINOR_VERSION) "." \
41 NX_AZURE_IOT_HUB_CLIENT_TO_STR(THREADX_PATCH_VERSION) "%3B"\
42 NX_AZURE_IOT_HUB_CLIENT_TO_STR(NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_INTERFACE_TYPE) "%3B"\
43 NX_AZURE_IOT_HUB_CLIENT_TO_STR(NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_VENDOR) "%3B"\
44 NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_DEVICE_TYPE "%29"
45 static UCHAR _nx_azure_iot_hub_client_user_agent[] = NX_AZURE_IOT_HUB_CLIENT_USER_AGENT;
46
47 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT */
48
49 #define NX_AZURE_IOT_HUB_CLIENT_COMPONENT_STRING "$.sub"
50
51 #define NX_AZURE_IOT_HUB_CLIENT_WEB_SOCKET_PATH "/$iothub/websocket"
52
53 static VOID nx_azure_iot_hub_client_received_message_cleanup(NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *message);
54 static UINT nx_azure_iot_hub_client_cloud_message_sub_unsub(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
55 UINT is_subscribe);
56 static UINT nx_azure_iot_hub_client_process_publish_packet(UCHAR *start_ptr,
57 ULONG *topic_offset_ptr,
58 USHORT *topic_length_ptr);
59 static VOID nx_azure_iot_hub_client_mqtt_receive_callback(NXD_MQTT_CLIENT* client_ptr,
60 UINT number_of_messages);
61 static UINT nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
62 NX_PACKET *packet_ptr,
63 ULONG topic_offset,
64 USHORT topic_length);
65 static UINT nx_azure_iot_hub_client_properties_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
66 NX_PACKET *packet_ptr,
67 ULONG topic_offset,
68 USHORT topic_length);
69 static UINT nx_azure_iot_hub_client_device_twin_parse(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
70 NX_PACKET *packet_ptr, ULONG topic_offset,
71 USHORT topic_length, UINT *request_id_ptr,
72 ULONG *version_ptr, UINT *message_type_ptr,
73 UINT *status_ptr);
74 extern UINT _nxd_mqtt_process_publish_packet(NX_PACKET *packet_ptr, ULONG *topic_offset_ptr,
75 USHORT *topic_length_ptr, ULONG *message_offset_ptr,
76 ULONG *message_length_ptr);
77 static VOID nx_azure_iot_hub_client_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr,
78 UINT status, VOID *context);
79 static VOID nx_azure_iot_hub_client_mqtt_disconnect_notify(NXD_MQTT_CLIENT *client_ptr);
80 static VOID nx_azure_iot_hub_client_mqtt_ack_receive_notify(NXD_MQTT_CLIENT *client_ptr, UINT type,
81 USHORT packet_id, NX_PACKET *transmit_packet_ptr,
82 VOID *context);
83 static VOID nx_azure_iot_hub_client_thread_dequeue(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
84 NX_AZURE_IOT_THREAD *thread_list_ptr);
85 static UINT nx_azure_iot_hub_client_sas_token_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
86 ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
87 UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length);
88 static UINT nx_azure_iot_hub_client_messages_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
89 UINT nx_azure_iot_hub_client_adjust_payload(NX_PACKET *packet_ptr);
90 UINT nx_azure_iot_hub_client_component_add_internal(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
91 const UCHAR *component_name_ptr,
92 USHORT component_name_length,
93 UINT (*callback_ptr)(VOID *json_reader_ptr,
94 ULONG version,
95 VOID *args),
96 VOID *callback_args);
97
nx_azure_iot_hub_client_throttle_with_jitter(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)98 static UINT nx_azure_iot_hub_client_throttle_with_jitter(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
99 {
100 UINT jitter;
101 UINT base_delay = NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC;
102 UINT retry_count = hub_client_ptr -> nx_azure_iot_hub_client_throttle_count;
103 uint64_t delay;
104
105 if (retry_count < (sizeof(UINT) * 8 - 1))
106 {
107 retry_count++;
108 delay = (uint64_t)((1 << retry_count) * NX_AZURE_IOT_HUB_CLIENT_INITIAL_BACKOFF_IN_SEC);
109
110 if (delay <= (UINT)(-1))
111 {
112 base_delay = (UINT)delay;
113 }
114 }
115
116 if (base_delay > NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC)
117 {
118 base_delay = NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC;
119 }
120 else
121 {
122 hub_client_ptr -> nx_azure_iot_hub_client_throttle_count = retry_count;
123 }
124
125 jitter = base_delay * NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_JITTER_PERCENT * (NX_RAND() & 0xFF) / 25600;
126 return((UINT)(base_delay + jitter));
127 }
128
nx_azure_iot_hub_client_throttled_check(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)129 static UINT nx_azure_iot_hub_client_throttled_check(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
130 {
131 ULONG current_time;
132 UINT status = NX_AZURE_IOT_SUCCESS;
133
134 if (hub_client_ptr -> nx_azure_iot_hub_client_throttle_count != 0)
135 {
136 if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, ¤t_time)))
137 {
138 LogError(LogLiteralArgs("IoTHub client fail to get unix time: %d"), status);
139 return(status);
140 }
141
142 if (current_time < hub_client_ptr -> nx_azure_iot_hub_client_throttle_end_time)
143 {
144 return(NX_AZURE_IOT_THROTTLED);
145 }
146 }
147
148 return(status);
149 }
150
nx_azure_iot_hub_client_initialize(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_AZURE_IOT * nx_azure_iot_ptr,const UCHAR * host_name,UINT host_name_length,const UCHAR * device_id,UINT device_id_length,const UCHAR * module_id,UINT module_id_length,const NX_CRYPTO_METHOD ** crypto_array,UINT crypto_array_size,const NX_CRYPTO_CIPHERSUITE ** cipher_map,UINT cipher_map_size,UCHAR * metadata_memory,UINT memory_size,NX_SECURE_X509_CERT * trusted_certificate)151 UINT nx_azure_iot_hub_client_initialize(NX_AZURE_IOT_HUB_CLIENT* hub_client_ptr,
152 NX_AZURE_IOT *nx_azure_iot_ptr,
153 const UCHAR *host_name, UINT host_name_length,
154 const UCHAR *device_id, UINT device_id_length,
155 const UCHAR *module_id, UINT module_id_length,
156 const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
157 const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size,
158 UCHAR * metadata_memory, UINT memory_size,
159 NX_SECURE_X509_CERT *trusted_certificate)
160 {
161
162 UINT status;
163 NX_AZURE_IOT_RESOURCE *resource_ptr;
164 az_span hostname_span = az_span_create((UCHAR *)host_name, (INT)host_name_length);
165 az_span device_id_span = az_span_create((UCHAR *)device_id, (INT)device_id_length);
166 az_iot_hub_client_options options = az_iot_hub_client_options_default();
167 az_result core_result;
168
169 if ((nx_azure_iot_ptr == NX_NULL) || (hub_client_ptr == NX_NULL) || (host_name == NX_NULL) ||
170 (device_id == NX_NULL) || (host_name_length == 0) || (device_id_length == 0))
171 {
172 LogError(LogLiteralArgs("IoTHub client initialization fail: INVALID POINTER"));
173 return(NX_AZURE_IOT_INVALID_PARAMETER);
174 }
175
176 memset(hub_client_ptr, 0, sizeof(NX_AZURE_IOT_HUB_CLIENT));
177
178 hub_client_ptr -> nx_azure_iot_ptr = nx_azure_iot_ptr;
179 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_crypto_array = crypto_array;
180 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_crypto_array_size = crypto_array_size;
181 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_cipher_map = cipher_map;
182 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_cipher_map_size = cipher_map_size;
183 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_metadata_ptr = metadata_memory;
184 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_metadata_size = memory_size;
185 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_trusted_certificates[0] = trusted_certificate;
186 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname = host_name;
187 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname_length = host_name_length;
188 options.module_id = az_span_create((UCHAR *)module_id, (INT)module_id_length);
189 options.user_agent = AZ_SPAN_FROM_STR(NX_AZURE_IOT_HUB_CLIENT_USER_AGENT);
190 options.component_names = hub_client_ptr -> nx_azure_iot_hub_client_component_list;
191 options.component_names_length = 0;
192
193 core_result = az_iot_hub_client_init(&hub_client_ptr -> iot_hub_client_core,
194 hostname_span, device_id_span, &options);
195 if (az_result_failed(core_result))
196 {
197 LogError(LogLiteralArgs("IoTHub client failed initialization with error status: %d"), core_result);
198 return(NX_AZURE_IOT_SDK_CORE_ERROR);
199 }
200
201 /* Set resource pointer. */
202 resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
203
204 /* Create MQTT client. */
205 status = _nxd_mqtt_client_cloud_create(&(resource_ptr -> resource_mqtt),
206 (CHAR *)nx_azure_iot_ptr -> nx_azure_iot_name,
207 "", 0,
208 nx_azure_iot_ptr -> nx_azure_iot_ip_ptr,
209 nx_azure_iot_ptr -> nx_azure_iot_pool_ptr,
210 &nx_azure_iot_ptr -> nx_azure_iot_cloud);
211 if (status)
212 {
213 LogError(LogLiteralArgs("IoTHub client initialization fail: MQTT CLIENT CREATE FAIL status: %d"), status);
214 return(status);
215 }
216
217 /* Set mqtt receive notify. */
218 status = nxd_mqtt_client_receive_notify_set(&(resource_ptr -> resource_mqtt),
219 nx_azure_iot_hub_client_mqtt_receive_callback);
220 if (status)
221 {
222 LogError(LogLiteralArgs("IoTHub client set message callback status: %d"), status);
223 nxd_mqtt_client_delete(&(resource_ptr -> resource_mqtt));
224 return(status);
225 }
226
227 /* Obtain the mutex. */
228 tx_mutex_get(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
229
230 /* Link the resource. */
231 resource_ptr -> resource_data_ptr = (VOID *)hub_client_ptr;
232 resource_ptr -> resource_type = NX_AZURE_IOT_RESOURCE_IOT_HUB;
233 nx_azure_iot_resource_add(nx_azure_iot_ptr, resource_ptr);
234
235 /* Release the mutex. */
236 tx_mutex_put(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
237
238 return(NX_AZURE_IOT_SUCCESS);
239 }
240
nx_azure_iot_hub_client_connection_status_callback_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,VOID (* connection_status_cb)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT * client_ptr,UINT status))241 UINT nx_azure_iot_hub_client_connection_status_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
242 VOID (*connection_status_cb)(
243 struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *client_ptr,
244 UINT status))
245 {
246
247 /* Check for invalid input pointers. */
248 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
249 {
250 LogError(LogLiteralArgs("IoTHub client connect callback fail: INVALID POINTER"));
251 return(NX_AZURE_IOT_INVALID_PARAMETER);
252 }
253
254 /* Set callback function for disconnection. */
255 nxd_mqtt_client_disconnect_notify_set(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
256 nx_azure_iot_hub_client_mqtt_disconnect_notify);
257
258 /* Obtain the mutex. */
259 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
260
261 /* Set connection status callback. */
262 hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback = connection_status_cb;
263
264 /* Release the mutex. */
265 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
266
267 /* Return success. */
268 return(NX_AZURE_IOT_SUCCESS);
269
270 }
271
272 #ifdef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_UPDATE
nx_azure_iot_hub_client_user_agent_update(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NXD_ADDRESS * server_address)273 static VOID nx_azure_iot_hub_client_user_agent_update(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, NXD_ADDRESS *server_address)
274 {
275 NX_IP *ip_ptr = hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_ip_ptr;
276 NX_INTERFACE *outgoing_interface = NX_NULL;
277 UINT status;
278 #ifndef NX_DISABLE_IPV4
279 ULONG next_hop_address;
280 #endif /* NX_DISABLE_IPV4 */
281 #ifdef FEATURE_NX_IPV6
282 NXD_IPV6_ADDRESS *ipv6_addr;
283 #endif /* FEATURE_NX_IPV6 */
284 ULONG interface_type;
285 ULONG index;
286
287 /* Make sure the server IP address is accesible. */
288 #ifndef NX_DISABLE_IPV4
289 if (server_address -> nxd_ip_version == NX_IP_VERSION_V4)
290 {
291 if (_nx_ip_route_find(ip_ptr, server_address -> nxd_ip_address.v4, &outgoing_interface, &next_hop_address) != NX_SUCCESS)
292 {
293 return;
294 }
295 }
296 #endif /* !NX_DISABLE_IPV4 */
297
298 #ifdef FEATURE_NX_IPV6
299 /* For IPv6 connections, find a suitable outgoing interface, based on the TCP peer address. */
300 if (server_address -> nxd_ip_version == NX_IP_VERSION_V6)
301 {
302
303 status = _nxd_ipv6_interface_find(ip_ptr, server_address -> nxd_ip_address.v6,
304 &ipv6_addr,
305 NX_NULL);
306
307 if (status != NX_SUCCESS)
308 {
309 return;
310 }
311
312 outgoing_interface = ipv6_addr -> nxd_ipv6_address_attached;
313 }
314 #endif /* FEATURE_NX_IPV6 */
315
316 /* Check if found the outgoing interface. */
317 if (outgoing_interface == NX_NULL)
318 {
319 return;
320 }
321
322 /* Get the interface type. */
323 status = nx_ip_driver_interface_direct_command(ip_ptr, NX_LINK_GET_INTERFACE_TYPE, outgoing_interface -> nx_interface_index, &interface_type);
324
325 /* Check status. */
326 if (status != NX_SUCCESS)
327 {
328 return;
329 }
330
331 /* Check if the interface type is listed in nx_api.h. */
332 if (interface_type > NX_INTERFACE_TYPE_LORAWAN)
333 {
334 interface_type = NX_INTERFACE_TYPE_OTHER;
335 }
336
337 /* Update the interface type in user agent. */
338 for (index = 0; index < sizeof(_nx_azure_iot_hub_client_user_agent) - 3; index++)
339 {
340
341 /* The interface type is after the first semicolon. */
342 if ((_nx_azure_iot_hub_client_user_agent[index] == '%') &&
343 (_nx_azure_iot_hub_client_user_agent[index + 1] == '3') &&
344 (_nx_azure_iot_hub_client_user_agent[index + 2] == 'B'))
345 {
346 _nx_azure_iot_hub_client_user_agent[index + 3] = (UCHAR)(interface_type + '0');
347 hub_client_ptr -> iot_hub_client_core._internal.options.user_agent = AZ_SPAN_FROM_BUFFER(_nx_azure_iot_hub_client_user_agent);
348 return;
349 }
350 }
351 }
352 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_UPDATE */
353
354 #ifdef NXD_MQTT_OVER_WEBSOCKET
nx_azure_iot_hub_client_websocket_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)355 UINT nx_azure_iot_hub_client_websocket_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
356 {
357 NX_AZURE_IOT_RESOURCE *resource_ptr;
358
359 if (hub_client_ptr == NX_NULL)
360 {
361 LogError(LogLiteralArgs("IoTHub WebSocket enable fail: INVALID POINTER"));
362 return(NX_AZURE_IOT_INVALID_PARAMETER);
363 }
364
365 /* Set resource pointer. */
366 resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
367
368 return(nxd_mqtt_client_websocket_set(&(resource_ptr -> resource_mqtt), (UCHAR *)resource_ptr -> resource_hostname, resource_ptr -> resource_hostname_length,
369 (UCHAR *)NX_AZURE_IOT_HUB_CLIENT_WEB_SOCKET_PATH, sizeof(NX_AZURE_IOT_HUB_CLIENT_WEB_SOCKET_PATH) - 1));
370 }
371 #endif /* NXD_MQTT_OVER_WEBSOCKET */
372
nx_azure_iot_hub_client_connect(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT clean_session,UINT wait_option)373 UINT nx_azure_iot_hub_client_connect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
374 UINT clean_session, UINT wait_option)
375 {
376 UINT status;
377 NXD_ADDRESS server_address;
378 NX_AZURE_IOT_RESOURCE *resource_ptr;
379 NXD_MQTT_CLIENT *mqtt_client_ptr;
380 UCHAR *buffer_ptr;
381 UINT buffer_size;
382 VOID *buffer_context;
383 UINT buffer_length;
384 ULONG expiry_time_secs;
385 az_result core_result;
386 UINT server_port;
387
388 /* Check for invalid input pointers. */
389 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
390 {
391 LogError(LogLiteralArgs("IoTHub client connect fail: INVALID POINTER"));
392 return(NX_AZURE_IOT_INVALID_PARAMETER);
393 }
394
395 /* Check for status. */
396 if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
397 {
398 LogError(LogLiteralArgs("IoTHub client already connected"));
399 return(NX_AZURE_IOT_ALREADY_CONNECTED);
400 }
401 else if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING)
402 {
403 LogError(LogLiteralArgs("IoTHub client is connecting"));
404 return(NX_AZURE_IOT_CONNECTING);
405 }
406
407 /* Resolve the host name. */
408 /* Note: always using default dns timeout. */
409 status = nxd_dns_host_by_name_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_dns_ptr,
410 (UCHAR *)hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname,
411 &server_address, NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT, NX_IP_VERSION_V4);
412 if (status)
413 {
414 LogError(LogLiteralArgs("IoTHub client connect fail: DNS RESOLVE FAIL status: %d"), status);
415 return(status);
416 }
417
418 /* Allocate buffer for client id, username and sas token. */
419 status = nx_azure_iot_buffer_allocate(hub_client_ptr -> nx_azure_iot_ptr,
420 &buffer_ptr, &buffer_size, &buffer_context);
421 if (status)
422 {
423 LogError(LogLiteralArgs("IoTHub client failed initialization: BUFFER ALLOCATE FAIL"));
424 return(status);
425 }
426
427 /* Obtain the mutex. */
428 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
429
430 #ifdef NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_UPDATE
431 /* Add the real interface type into the user agent string. */
432 nx_azure_iot_hub_client_user_agent_update(hub_client_ptr, &server_address);
433 #endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT_UPDATE */
434
435 /* Set resource pointer and buffer context. */
436 resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
437
438 /* Build client id. */
439 buffer_length = buffer_size;
440 core_result = az_iot_hub_client_get_client_id(&(hub_client_ptr -> iot_hub_client_core),
441 (CHAR *)buffer_ptr, buffer_length, (size_t *)&buffer_length);
442 if (az_result_failed(core_result))
443 {
444
445 /* Release the mutex. */
446 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
447 nx_azure_iot_buffer_free(buffer_context);
448 LogError(LogLiteralArgs("IoTHub client failed to get clientId with error status: "), core_result);
449 return(NX_AZURE_IOT_SDK_CORE_ERROR);
450 }
451 resource_ptr -> resource_mqtt_client_id = buffer_ptr;
452 resource_ptr -> resource_mqtt_client_id_length = buffer_length;
453
454 /* Update buffer for user name. */
455 buffer_ptr += resource_ptr -> resource_mqtt_client_id_length;
456 buffer_size -= resource_ptr -> resource_mqtt_client_id_length;
457
458 /* Build user name. */
459 buffer_length = buffer_size;
460 core_result = az_iot_hub_client_get_user_name(&hub_client_ptr -> iot_hub_client_core,
461 (CHAR *)buffer_ptr, buffer_length, (size_t *)&buffer_length);
462 if (az_result_failed(core_result))
463 {
464
465 /* Release the mutex. */
466 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
467 nx_azure_iot_buffer_free(buffer_context);
468 LogError(LogLiteralArgs("IoTHub client connect fail, with error status: %d"), core_result);
469 return(NX_AZURE_IOT_SDK_CORE_ERROR);
470 }
471 resource_ptr -> resource_mqtt_user_name = buffer_ptr;
472 resource_ptr -> resource_mqtt_user_name_length = buffer_length;
473
474 /* Build sas token. */
475 resource_ptr -> resource_mqtt_sas_token = buffer_ptr + buffer_length;
476 resource_ptr -> resource_mqtt_sas_token_length = buffer_size - buffer_length;
477
478 /* Check if token refersh is setup. */
479 if (hub_client_ptr -> nx_azure_iot_hub_client_token_refresh)
480 {
481 status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, &expiry_time_secs);
482 if (status)
483 {
484
485 /* Release the mutex. */
486 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
487 nx_azure_iot_buffer_free(buffer_context);
488 LogError(LogLiteralArgs("IoTHub client connect fail: unixtime get failed status: %d"), status);
489 return(status);
490 }
491
492 expiry_time_secs += NX_AZURE_IOT_HUB_CLIENT_TOKEN_CONNECTION_TIMEOUT;
493 status = hub_client_ptr -> nx_azure_iot_hub_client_token_refresh(hub_client_ptr,
494 expiry_time_secs,
495 hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key,
496 hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key_length,
497 resource_ptr -> resource_mqtt_sas_token,
498 resource_ptr -> resource_mqtt_sas_token_length,
499 &(resource_ptr -> resource_mqtt_sas_token_length));
500 if (status)
501 {
502
503 /* Release the mutex. */
504 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
505 nx_azure_iot_buffer_free(buffer_context);
506 LogError(LogLiteralArgs("IoTHub client connect fail: Token generation failed status: %d"), status);
507 return(status);
508 }
509 hub_client_ptr -> nx_azure_iot_hub_client_sas_token_expiry_time = expiry_time_secs;
510 }
511 else
512 {
513 resource_ptr -> resource_mqtt_sas_token = NX_NULL;
514 resource_ptr -> resource_mqtt_sas_token_length = 0;
515 }
516
517 /* Set azure IoT and MQTT client. */
518 mqtt_client_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt);
519
520 /* Update client id. */
521 mqtt_client_ptr -> nxd_mqtt_client_id = (CHAR *)resource_ptr -> resource_mqtt_client_id;
522 mqtt_client_ptr -> nxd_mqtt_client_id_length = resource_ptr -> resource_mqtt_client_id_length;
523
524 /* Set login info. */
525 status = nxd_mqtt_client_login_set(&(resource_ptr -> resource_mqtt),
526 (CHAR *)resource_ptr -> resource_mqtt_user_name,
527 resource_ptr -> resource_mqtt_user_name_length,
528 (CHAR *)resource_ptr -> resource_mqtt_sas_token,
529 resource_ptr -> resource_mqtt_sas_token_length);
530 if (status)
531 {
532
533 /* Release the mutex. */
534 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
535 nx_azure_iot_buffer_free(buffer_context);
536 LogError(LogLiteralArgs("IoTHub client connect fail: MQTT CLIENT LOGIN SET FAIL status: %d"), status);
537 return(status);
538 }
539
540 /* Set connect notify for non-blocking mode. */
541 if (wait_option == 0)
542 {
543 mqtt_client_ptr -> nxd_mqtt_connect_notify = nx_azure_iot_hub_client_mqtt_connect_notify;
544 mqtt_client_ptr -> nxd_mqtt_connect_context = hub_client_ptr;
545 }
546
547 /* Save the resource buffer. */
548 resource_ptr -> resource_mqtt_buffer_context = buffer_context;
549 resource_ptr -> resource_mqtt_buffer_size = buffer_size;
550
551 /* Release the mutex. */
552 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
553
554 #ifdef NXD_MQTT_OVER_WEBSOCKET
555 if (mqtt_client_ptr -> nxd_mqtt_client_use_websocket == NX_TRUE)
556 {
557 server_port = NXD_MQTT_OVER_WEBSOCKET_TLS_PORT;
558 }
559 else
560 {
561 server_port = NXD_MQTT_TLS_PORT;
562 }
563 #else
564 server_port = NXD_MQTT_TLS_PORT;
565 #endif /* NXD_MQTT_OVER_WEBSOCKET */
566
567 /* Start MQTT connection. */
568 status = nxd_mqtt_client_secure_connect(mqtt_client_ptr, &server_address, server_port,
569 nx_azure_iot_mqtt_tls_setup, NX_AZURE_IOT_MQTT_KEEP_ALIVE,
570 clean_session, wait_option);
571
572 /* Obtain the mutex. */
573 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
574
575 /* Check status for non-blocking mode. */
576 if ((wait_option == 0) && (status == NX_IN_PROGRESS))
577 {
578 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING;
579
580 /* Release the mutex. */
581 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
582
583 /* Return in-progress completion status. */
584 return(NX_AZURE_IOT_CONNECTING);
585 }
586
587 /* Release the mqtt connection resource. */
588 if (resource_ptr -> resource_mqtt_buffer_context)
589 {
590 nx_azure_iot_buffer_free(resource_ptr -> resource_mqtt_buffer_context);
591 resource_ptr -> resource_mqtt_buffer_context = NX_NULL;
592 }
593
594 /* Check status. */
595 if (status != NX_AZURE_IOT_SUCCESS)
596 {
597 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
598 LogError(LogLiteralArgs("IoTHub client connect fail: MQTT CONNECT FAIL status: %d"), status);
599 }
600 else
601 {
602
603 /* Connected to IoT Hub. */
604 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED;
605 }
606
607 if (status == NX_AZURE_IOT_SUCCESS)
608 {
609 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
610
611 status = nx_azure_iot_hub_client_messages_enable(hub_client_ptr);
612
613 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
614
615 if (status)
616 {
617 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
618 LogError(LogLiteralArgs("IoTHub client connect fail: MQTT SUBSCRIBE FAIL status: %d"), status);
619 }
620 }
621
622 /* Call connection notify if it is set. */
623 if (hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback)
624 {
625 hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback(hub_client_ptr, status);
626 }
627
628 /* Release the mutex. */
629 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
630
631 return(status);
632 }
633
nx_azure_iot_hub_client_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT * client_ptr,UINT status,VOID * context)634 static VOID nx_azure_iot_hub_client_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr,
635 UINT status, VOID *context)
636 {
637
638 NX_AZURE_IOT_HUB_CLIENT *iot_hub_client = (NX_AZURE_IOT_HUB_CLIENT*)context;
639
640
641 NX_PARAMETER_NOT_USED(client_ptr);
642
643 /* Obtain the mutex. */
644 tx_mutex_get(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
645
646 /* Release the mqtt connection resource. */
647 if (iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context)
648 {
649 nx_azure_iot_buffer_free(iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context);
650 iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context = NX_NULL;
651 }
652
653 /* Update hub client status. */
654 if (status == NXD_MQTT_SUCCESS)
655 {
656 iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED;
657 }
658 else
659 {
660 iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
661 }
662
663 if (status == NXD_MQTT_SUCCESS)
664 {
665 tx_mutex_put(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
666
667 status = nx_azure_iot_hub_client_messages_enable(iot_hub_client);
668
669 tx_mutex_get(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
670
671 if (status)
672 {
673 iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
674 LogError(LogLiteralArgs("IoTHub client connect fail: MQTT SUBSCRIBE FAIL status: %d"), status);
675 }
676 }
677
678 /* Call connection notify if it is set. */
679 if (iot_hub_client -> nx_azure_iot_hub_client_connection_status_callback)
680 {
681 iot_hub_client -> nx_azure_iot_hub_client_connection_status_callback(iot_hub_client, status);
682 }
683
684 /* Release the mutex. */
685 tx_mutex_put(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
686 }
687
nx_azure_iot_hub_client_mqtt_disconnect_notify(NXD_MQTT_CLIENT * client_ptr)688 static VOID nx_azure_iot_hub_client_mqtt_disconnect_notify(NXD_MQTT_CLIENT *client_ptr)
689 {
690 NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
691 NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = NX_NULL;
692 NX_AZURE_IOT_THREAD *thread_list_ptr;
693 ULONG current_time = 0;
694
695 /* This function is protected by MQTT mutex. */
696
697 if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
698 {
699 hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource -> resource_data_ptr;
700 }
701
702 if (hub_client_ptr == NX_NULL)
703 {
704 return;
705 }
706
707 /* Wake up all threads. */
708 for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
709 thread_list_ptr;
710 thread_list_ptr = thread_list_ptr -> thread_next)
711 {
712 tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
713 }
714
715 /* Do not call callback if not connected, as at our layer connected means : mqtt connect + subscribe messages topic. */
716 if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
717 {
718 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
719
720 /* Call connection notify if it is set. */
721 if (hub_client_ptr && hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback)
722 {
723 if (hub_client_ptr -> nx_azure_iot_hub_client_token_refresh &&
724 (nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr,
725 ¤t_time) == NX_AZURE_IOT_SUCCESS) &&
726 (current_time > hub_client_ptr -> nx_azure_iot_hub_client_sas_token_expiry_time))
727 {
728 hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback(hub_client_ptr,
729 NX_AZURE_IOT_SAS_TOKEN_EXPIRED);
730 }
731 else
732 {
733 hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback(hub_client_ptr,
734 NX_AZURE_IOT_DISCONNECTED);
735 }
736
737 }
738 }
739 }
740
nx_azure_iot_hub_client_disconnect(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)741 UINT nx_azure_iot_hub_client_disconnect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
742 {
743 UINT status;
744 NX_AZURE_IOT_THREAD *thread_list_ptr;
745
746
747 /* Check for invalid input pointers. */
748 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
749 {
750 LogError(LogLiteralArgs("IoTHub client disconnect fail: INVALID POINTER"));
751 return(NX_AZURE_IOT_INVALID_PARAMETER);
752 }
753
754 /* Disconnect. */
755 status = nxd_mqtt_client_disconnect(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt));
756 if (status)
757 {
758 LogError(LogLiteralArgs("IoTHub client disconnect fail status: %d"), status);
759 return(status);
760 }
761
762 /* Obtain the mutex. */
763 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
764
765 /* Release the mqtt connection resource. */
766 if (hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context)
767 {
768 nx_azure_iot_buffer_free(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context);
769 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context = NX_NULL;
770 }
771
772 /* Wakeup all suspend threads. */
773 for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
774 thread_list_ptr;
775 thread_list_ptr = thread_list_ptr -> thread_next)
776 {
777 tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
778 }
779
780 /* Cleanup received messages. */
781 nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message));
782 nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_properties_message));
783 nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message));
784 nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_command_message));
785
786 hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
787
788 /* Release the mutex. */
789 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
790
791 return(NX_AZURE_IOT_SUCCESS);
792 }
793
nx_azure_iot_hub_client_received_message_cleanup(NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE * message)794 static VOID nx_azure_iot_hub_client_received_message_cleanup(NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *message)
795 {
796 NX_PACKET *current_ptr;
797 NX_PACKET *next_ptr;
798
799 for (current_ptr = message -> message_head; current_ptr; current_ptr = next_ptr)
800 {
801
802 /* Get next packet in queue. */
803 next_ptr = current_ptr -> nx_packet_queue_next;
804
805 /* Release current packet. */
806 current_ptr -> nx_packet_queue_next = NX_NULL;
807 nx_packet_release(current_ptr);
808 }
809
810 /* Reset received messages. */
811 message -> message_head = NX_NULL;
812 message -> message_tail = NX_NULL;
813 }
814
nx_azure_iot_hub_client_messages_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)815 static UINT nx_azure_iot_hub_client_messages_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
816 {
817 UINT status = NX_AZURE_IOT_SUCCESS;
818
819 if (status == NX_AZURE_IOT_SUCCESS &&
820 (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process != NX_NULL))
821 {
822 status = hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_enable(hub_client_ptr);
823 }
824
825 if (status == NX_AZURE_IOT_SUCCESS &&
826 (hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_process != NX_NULL))
827 {
828 status = hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_enable(hub_client_ptr);
829 }
830
831 if (status == NX_AZURE_IOT_SUCCESS &&
832 (hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process != NX_NULL))
833 {
834 status = hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_enable(hub_client_ptr);
835 }
836
837 return(status);
838 }
839
nx_azure_iot_hub_client_deinitialize(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)840 UINT nx_azure_iot_hub_client_deinitialize(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
841 {
842 UINT status;
843
844 /* Check for invalid input pointers. */
845 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
846 {
847 LogError(LogLiteralArgs("IoTHub client deinitialize fail: INVALID POINTER"));
848 return(NX_AZURE_IOT_INVALID_PARAMETER);
849 }
850
851 nx_azure_iot_hub_client_disconnect(hub_client_ptr);
852
853 status = nxd_mqtt_client_delete(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt));
854 if (status)
855 {
856 LogError(LogLiteralArgs("IoTHub client delete fail status: %d"), status);
857 return(status);
858 }
859
860 /* Obtain the mutex. */
861 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
862
863 /* Remove resource from list. */
864 status = nx_azure_iot_resource_remove(hub_client_ptr -> nx_azure_iot_ptr,
865 &(hub_client_ptr -> nx_azure_iot_hub_client_resource));
866 if (status)
867 {
868
869 /* Release the mutex. */
870 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
871 LogError(LogLiteralArgs("IoTHub client handle not found"));
872 return(status);
873 }
874
875 /* Release the mutex. */
876 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
877
878 return(NX_AZURE_IOT_SUCCESS);
879 }
880
nx_azure_iot_hub_client_trusted_cert_add(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_SECURE_X509_CERT * trusted_certificate)881 UINT nx_azure_iot_hub_client_trusted_cert_add(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
882 NX_SECURE_X509_CERT *trusted_certificate)
883 {
884 UINT i;
885 NX_AZURE_IOT_RESOURCE *resource_ptr;
886
887 if ((hub_client_ptr == NX_NULL) ||
888 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
889 (trusted_certificate == NX_NULL))
890 {
891 LogError(LogLiteralArgs("IoTHub device certificate set fail: INVALID POINTER"));
892 return(NX_AZURE_IOT_INVALID_PARAMETER);
893 }
894
895 /* Obtain the mutex. */
896 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
897
898 resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
899 for (i = 0; i < NX_AZURE_IOT_ARRAY_SIZE(resource_ptr -> resource_trusted_certificates); i++)
900 {
901 if (resource_ptr -> resource_trusted_certificates[i] == NX_NULL)
902 {
903 resource_ptr -> resource_trusted_certificates[i] = trusted_certificate;
904 break;
905 }
906 }
907
908 /* Release the mutex. */
909 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
910
911 if (i < NX_AZURE_IOT_ARRAY_SIZE(resource_ptr -> resource_trusted_certificates))
912 {
913 return(NX_AZURE_IOT_SUCCESS);
914 }
915 else
916 {
917
918 /* No more space to store trusted certificate. */
919 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
920 }
921 }
922
nx_azure_iot_hub_client_device_cert_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_SECURE_X509_CERT * device_certificate)923 UINT nx_azure_iot_hub_client_device_cert_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
924 NX_SECURE_X509_CERT *device_certificate)
925 {
926 UINT i;
927 NX_AZURE_IOT_RESOURCE *resource_ptr;
928
929 if ((hub_client_ptr == NX_NULL) ||
930 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
931 (device_certificate == NX_NULL))
932 {
933 LogError(LogLiteralArgs("IoTHub device certificate set fail: INVALID POINTER"));
934 return(NX_AZURE_IOT_INVALID_PARAMETER);
935 }
936
937 /* Obtain the mutex. */
938 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
939
940 resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
941 for (i = 0; i < NX_AZURE_IOT_ARRAY_SIZE(resource_ptr -> resource_device_certificates); i++)
942 {
943 if (resource_ptr -> resource_device_certificates[i] == NX_NULL)
944 {
945 resource_ptr -> resource_device_certificates[i] = device_certificate;
946 break;
947 }
948 }
949
950 /* Release the mutex. */
951 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
952
953 if (i < NX_AZURE_IOT_ARRAY_SIZE(resource_ptr -> resource_device_certificates))
954 {
955 return(NX_AZURE_IOT_SUCCESS);
956 }
957 else
958 {
959
960 /* No more space to store device certificate. */
961 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
962 }
963 }
964
nx_azure_iot_hub_client_symmetric_key_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * symmetric_key,UINT symmetric_key_length)965 UINT nx_azure_iot_hub_client_symmetric_key_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
966 const UCHAR *symmetric_key, UINT symmetric_key_length)
967 {
968 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
969 (symmetric_key == NX_NULL) || (symmetric_key_length == 0))
970 {
971 LogError(LogLiteralArgs("IoTHub client symmetric key fail: Invalid argument"));
972 return(NX_AZURE_IOT_INVALID_PARAMETER);
973 }
974
975 /* Obtain the mutex. */
976 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
977
978 hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key = symmetric_key;
979 hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key_length = symmetric_key_length;
980
981 hub_client_ptr -> nx_azure_iot_hub_client_token_refresh = nx_azure_iot_hub_client_sas_token_get;
982
983 /* Release the mutex. */
984 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
985
986 return(NX_AZURE_IOT_SUCCESS);
987 }
988
nx_azure_iot_hub_client_model_id_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * model_id_ptr,UINT model_id_length)989 UINT nx_azure_iot_hub_client_model_id_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
990 const UCHAR *model_id_ptr, UINT model_id_length)
991 {
992 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
993 (model_id_ptr == NX_NULL) || (model_id_length == 0))
994 {
995 LogError(LogLiteralArgs("IoTHub client model Id fail: Invalid argument"));
996 return(NX_AZURE_IOT_INVALID_PARAMETER);
997 }
998
999 /* Obtain the mutex. */
1000 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1001
1002 /* Had no way to update option, so had to access the internal fields of iot_hub_client_core. */
1003 hub_client_ptr -> iot_hub_client_core._internal.options.model_id =
1004 az_span_create((UCHAR *)model_id_ptr, (INT)model_id_length);
1005
1006 /* Release the mutex. */
1007 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1008
1009 return(NX_AZURE_IOT_SUCCESS);
1010 }
1011
nx_azure_iot_hub_client_component_add(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * component_name_ptr,USHORT component_name_length)1012 UINT nx_azure_iot_hub_client_component_add(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1013 const UCHAR *component_name_ptr,
1014 USHORT component_name_length)
1015 {
1016 return(nx_azure_iot_hub_client_component_add_internal(hub_client_ptr, component_name_ptr, component_name_length, NX_NULL, NX_NULL));
1017 }
1018
nx_azure_iot_hub_client_component_add_internal(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * component_name_ptr,USHORT component_name_length,UINT (* callback_ptr)(VOID * json_reader_ptr,ULONG version,VOID * args),VOID * callback_args)1019 UINT nx_azure_iot_hub_client_component_add_internal(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1020 const UCHAR *component_name_ptr,
1021 USHORT component_name_length,
1022 UINT (*callback_ptr)(VOID *json_reader_ptr,
1023 ULONG version,
1024 VOID *args),
1025 VOID *callback_args)
1026 {
1027 UINT length_of_componet_list;
1028
1029 if ((hub_client_ptr == NX_NULL) ||
1030 (component_name_ptr == NX_NULL) ||
1031 (component_name_length == NX_NULL))
1032 {
1033 LogError(LogLiteralArgs("IoT Hub add component fail: INVALID POINTER"));
1034 return(NX_AZURE_IOT_INVALID_PARAMETER);
1035 }
1036
1037 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1038
1039 length_of_componet_list =
1040 (UINT)hub_client_ptr -> iot_hub_client_core._internal.options.component_names_length;
1041
1042 if (length_of_componet_list >= NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST)
1043 {
1044 LogError(LogLiteralArgs("IoT Hub fail due to buffer insufficient"));
1045 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1046 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
1047 }
1048
1049 /* Using internal fields for faster update */
1050 hub_client_ptr -> nx_azure_iot_hub_client_component_list[length_of_componet_list] =
1051 az_span_create((UCHAR *)component_name_ptr, (INT)component_name_length);
1052 hub_client_ptr -> iot_hub_client_core._internal.options.component_names_length++;
1053 hub_client_ptr -> nx_azure_iot_hub_client_component_callback[length_of_componet_list] = callback_ptr;
1054 hub_client_ptr -> nx_azure_iot_hub_client_component_callback_args[length_of_componet_list] = callback_args;
1055
1056 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1057
1058 return(NX_AZURE_IOT_SUCCESS);
1059 }
1060
nx_azure_iot_hub_client_telemetry_message_create(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)1061 UINT nx_azure_iot_hub_client_telemetry_message_create(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1062 NX_PACKET **packet_pptr, UINT wait_option)
1063 {
1064 NX_PACKET *packet_ptr;
1065 UINT topic_length;
1066 UINT status;
1067 az_result core_result;
1068
1069 if ((hub_client_ptr == NX_NULL) ||
1070 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
1071 (packet_pptr == NX_NULL))
1072 {
1073 LogError(LogLiteralArgs("IoTHub telemetry message create fail: INVALID POINTER"));
1074 return(NX_AZURE_IOT_INVALID_PARAMETER);
1075 }
1076
1077 status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
1078 &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1079 &packet_ptr, wait_option);
1080 if (status)
1081 {
1082 LogError(LogLiteralArgs("Create telemetry data fail"));
1083 return(status);
1084 }
1085
1086 topic_length = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
1087 core_result = az_iot_hub_client_telemetry_get_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
1088 NULL, (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
1089 topic_length, (size_t *)&topic_length);
1090 if (az_result_failed(core_result))
1091 {
1092 LogError(LogLiteralArgs("IoTHub client telemetry message create fail with error status: %d"), core_result);
1093 nx_packet_release(packet_ptr);
1094 return(NX_AZURE_IOT_SDK_CORE_ERROR);
1095 }
1096
1097 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
1098 packet_ptr -> nx_packet_length = topic_length;
1099 *packet_pptr = packet_ptr;
1100 return(NX_AZURE_IOT_SUCCESS);
1101 }
1102
nx_azure_iot_hub_client_telemetry_message_delete(NX_PACKET * packet_ptr)1103 UINT nx_azure_iot_hub_client_telemetry_message_delete(NX_PACKET *packet_ptr)
1104 {
1105 return(nx_packet_release(packet_ptr));
1106 }
1107
nx_azure_iot_hub_client_telemetry_component_set(NX_PACKET * packet_ptr,const UCHAR * component_name_ptr,USHORT component_name_length,UINT wait_option)1108 UINT nx_azure_iot_hub_client_telemetry_component_set(NX_PACKET *packet_ptr,
1109 const UCHAR *component_name_ptr,
1110 USHORT component_name_length,
1111 UINT wait_option)
1112 {
1113 UINT status;
1114
1115 if ((packet_ptr == NX_NULL) ||
1116 (component_name_ptr == NX_NULL) ||
1117 (component_name_length == 0))
1118 {
1119 LogError(LogLiteralArgs("IoTHub telemetry component set fail: INVALID POINTER"));
1120 return(NX_AZURE_IOT_INVALID_PARAMETER);
1121 }
1122
1123 status = nx_azure_iot_hub_client_telemetry_property_add(packet_ptr,
1124 (const UCHAR*)NX_AZURE_IOT_HUB_CLIENT_COMPONENT_STRING,
1125 sizeof(NX_AZURE_IOT_HUB_CLIENT_COMPONENT_STRING) - 1,
1126 component_name_ptr, component_name_length,
1127 wait_option);
1128 if (status)
1129 {
1130 LogError(LogLiteralArgs("Telemetry component append fail: error status: %d"), status);
1131 return(status);
1132 }
1133
1134 return(NX_AZURE_IOT_SUCCESS);
1135 }
1136
nx_azure_iot_hub_client_telemetry_property_add(NX_PACKET * packet_ptr,const UCHAR * property_name,USHORT property_name_length,const UCHAR * property_value,USHORT property_value_length,UINT wait_option)1137 UINT nx_azure_iot_hub_client_telemetry_property_add(NX_PACKET *packet_ptr,
1138 const UCHAR *property_name, USHORT property_name_length,
1139 const UCHAR *property_value, USHORT property_value_length,
1140 UINT wait_option)
1141 {
1142 UINT status;
1143
1144 if ((packet_ptr == NX_NULL) ||
1145 (property_name == NX_NULL) ||
1146 (property_value == NX_NULL))
1147 {
1148 LogError(LogLiteralArgs("IoTHub telemetry property add fail: INVALID POINTER"));
1149 return(NX_AZURE_IOT_INVALID_PARAMETER);
1150 }
1151
1152 if (*(packet_ptr -> nx_packet_append_ptr - 1) != '/')
1153 {
1154 status = nx_packet_data_append(packet_ptr, "&", 1,
1155 packet_ptr -> nx_packet_pool_owner,
1156 wait_option);
1157 if (status)
1158 {
1159 LogError(LogLiteralArgs("Telemetry data append fail"));
1160 return(status);
1161 }
1162 }
1163
1164 status = nx_packet_data_append(packet_ptr, (VOID *)property_name, (UINT)property_name_length,
1165 packet_ptr -> nx_packet_pool_owner, wait_option);
1166 if (status)
1167 {
1168 LogError(LogLiteralArgs("Telemetry data append fail"));
1169 return(status);
1170 }
1171
1172 status = nx_packet_data_append(packet_ptr, "=", 1,
1173 packet_ptr -> nx_packet_pool_owner,
1174 wait_option);
1175 if (status)
1176 {
1177 LogError(LogLiteralArgs("Telemetry data append fail"));
1178 return(status);
1179 }
1180
1181 status = nx_packet_data_append(packet_ptr, (VOID *)property_value, (UINT)property_value_length,
1182 packet_ptr -> nx_packet_pool_owner, wait_option);
1183 if (status)
1184 {
1185 LogError(LogLiteralArgs("Telemetry data append fail"));
1186 return(status);
1187 }
1188
1189 return(NX_AZURE_IOT_SUCCESS);
1190 }
1191
nx_azure_iot_hub_client_telemetry_send(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,const UCHAR * telemetry_data,UINT data_size,UINT wait_option)1192 UINT nx_azure_iot_hub_client_telemetry_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1193 NX_PACKET *packet_ptr, const UCHAR *telemetry_data,
1194 UINT data_size, UINT wait_option)
1195 {
1196 UINT status;
1197 UINT topic_len;
1198 UCHAR packet_id[2];
1199
1200 if ((hub_client_ptr == NX_NULL) || (packet_ptr == NX_NULL))
1201 {
1202 LogError(LogLiteralArgs("IoTHub telemetry send fail: INVALID POINTER"));
1203 return(NX_AZURE_IOT_INVALID_PARAMETER);
1204 }
1205
1206 topic_len = packet_ptr -> nx_packet_length;
1207
1208 status = nx_azure_iot_mqtt_packet_id_get(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1209 packet_id);
1210 if (status)
1211 {
1212 LogError(LogLiteralArgs("Failed to get packet id"));
1213 return(status);
1214 }
1215
1216 /* Append packet identifier. */
1217 status = nx_packet_data_append(packet_ptr, packet_id, sizeof(packet_id),
1218 packet_ptr -> nx_packet_pool_owner,
1219 wait_option);
1220 if (status)
1221 {
1222 LogError(LogLiteralArgs("Telemetry append fail"));
1223 return(status);
1224 }
1225
1226 if (telemetry_data && (data_size != 0))
1227 {
1228
1229 /* Append payload. */
1230 status = nx_packet_data_append(packet_ptr, (VOID *)telemetry_data, data_size,
1231 packet_ptr -> nx_packet_pool_owner,
1232 wait_option);
1233 if (status)
1234 {
1235 LogError(LogLiteralArgs("Telemetry data append fail"));
1236 return(status);
1237 }
1238 }
1239
1240 status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1241 packet_ptr, topic_len, packet_id, NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS,
1242 wait_option);
1243 if (status)
1244 {
1245 LogError(LogLiteralArgs("IoTHub client send fail: PUBLISH FAIL status: %d"), status);
1246 return(status);
1247 }
1248
1249 return(NX_AZURE_IOT_SUCCESS);
1250 }
1251
nx_azure_iot_hub_client_receive_callback_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT message_type,VOID (* callback_ptr)(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,VOID * args),VOID * callback_args)1252 UINT nx_azure_iot_hub_client_receive_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1253 UINT message_type,
1254 VOID (*callback_ptr)(
1255 NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1256 VOID *args),
1257 VOID *callback_args)
1258 {
1259 if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
1260 {
1261 LogError(LogLiteralArgs("IoTHub receive callback set fail: INVALID POINTER"));
1262 return(NX_AZURE_IOT_INVALID_PARAMETER);
1263 }
1264
1265 /* Obtain the mutex. */
1266 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1267
1268 if (message_type == NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE)
1269 {
1270 hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_callback = callback_ptr;
1271 hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_callback_args = callback_args;
1272 }
1273 else if (message_type == NX_AZURE_IOT_HUB_PROPERTIES)
1274 {
1275 hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_callback = callback_ptr;
1276 hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_callback_args = callback_args;
1277 }
1278 else if (message_type == NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES)
1279 {
1280 hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_callback = callback_ptr;
1281 hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_callback_args = callback_args;
1282 }
1283 else if (message_type == NX_AZURE_IOT_HUB_COMMAND)
1284 {
1285 hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_callback = callback_ptr;
1286 hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_callback_args = callback_args;
1287 }
1288 else
1289 {
1290
1291 /* Release the mutex. */
1292 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1293 return(NX_AZURE_IOT_NOT_SUPPORTED);
1294 }
1295
1296 /* Release the mutex. */
1297 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1298
1299 return(NX_AZURE_IOT_SUCCESS);
1300 }
1301
nx_azure_iot_hub_client_cloud_message_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)1302 UINT nx_azure_iot_hub_client_cloud_message_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
1303 {
1304
1305 if (hub_client_ptr == NX_NULL)
1306 {
1307 LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: INVALID POINTER"));
1308 return(NX_AZURE_IOT_INVALID_PARAMETER);
1309 }
1310
1311 return(nx_azure_iot_hub_client_cloud_message_sub_unsub(hub_client_ptr, NX_TRUE));
1312 }
1313
nx_azure_iot_hub_client_cloud_message_disable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)1314 UINT nx_azure_iot_hub_client_cloud_message_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
1315 {
1316 if (hub_client_ptr == NX_NULL)
1317 {
1318 LogError(LogLiteralArgs("IoTHub cloud message unsubscribe fail: INVALID POINTER"));
1319 return(NX_AZURE_IOT_INVALID_PARAMETER);
1320 }
1321
1322 return(nx_azure_iot_hub_client_cloud_message_sub_unsub(hub_client_ptr, NX_FALSE));
1323 }
1324
nx_azure_iot_hub_client_process_publish_packet(UCHAR * start_ptr,ULONG * topic_offset_ptr,USHORT * topic_length_ptr)1325 static UINT nx_azure_iot_hub_client_process_publish_packet(UCHAR *start_ptr,
1326 ULONG *topic_offset_ptr,
1327 USHORT *topic_length_ptr)
1328 {
1329 UCHAR *byte = start_ptr;
1330 UINT byte_count = 0;
1331 UINT multiplier = 1;
1332 UINT remaining_length = 0;
1333 UINT topic_length;
1334
1335 /* Validate packet start contains fixed header. */
1336 do
1337 {
1338 if (byte_count >= 4)
1339 {
1340 LogError(LogLiteralArgs("Invalid mqtt packet start position"));
1341 return(NX_AZURE_IOT_INVALID_PACKET);
1342 }
1343
1344 byte++;
1345 remaining_length += (((*byte) & 0x7F) * multiplier);
1346 multiplier = multiplier << 7;
1347 byte_count++;
1348 } while ((*byte) & 0x80);
1349
1350 if (remaining_length < 2)
1351 {
1352 return(NX_AZURE_IOT_INVALID_PACKET);
1353 }
1354
1355 /* Retrieve topic length. */
1356 byte++;
1357 topic_length = (UINT)(*(byte) << 8) | (*(byte + 1));
1358
1359 if (topic_length > remaining_length - 2u)
1360 {
1361 return(NX_AZURE_IOT_INVALID_PACKET);
1362 }
1363
1364 *topic_offset_ptr = (ULONG)((byte + 2) - start_ptr);
1365 *topic_length_ptr = (USHORT)topic_length;
1366
1367 /* Return. */
1368 return(NX_AZURE_IOT_SUCCESS);
1369 }
1370
nx_azure_iot_hub_client_message_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT message_type,NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE * receive_message,NX_PACKET ** packet_pptr,UINT wait_option)1371 static UINT nx_azure_iot_hub_client_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT message_type,
1372 NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *receive_message,
1373 NX_PACKET **packet_pptr, UINT wait_option)
1374 {
1375 NX_PACKET *packet_ptr = NX_NULL;
1376 UINT old_threshold;
1377 NX_AZURE_IOT_THREAD thread_list;
1378
1379 if ((hub_client_ptr == NX_NULL) ||
1380 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
1381 (packet_pptr == NX_NULL))
1382 {
1383 LogError(LogLiteralArgs("IoTHub message receive fail: INVALID POINTER"));
1384 return(NX_AZURE_IOT_INVALID_PARAMETER);
1385 }
1386
1387 if (receive_message -> message_process == NX_NULL)
1388 {
1389 LogError(LogLiteralArgs("IoTHub message receive fail: NOT ENABLED"));
1390 return(NX_AZURE_IOT_NOT_ENABLED);
1391 }
1392
1393 /* Obtain the mutex. */
1394 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1395
1396 if (receive_message -> message_head)
1397 {
1398 packet_ptr = receive_message -> message_head;
1399 if (receive_message -> message_tail == packet_ptr)
1400 {
1401 receive_message -> message_tail = NX_NULL;
1402 }
1403 receive_message -> message_head = packet_ptr -> nx_packet_queue_next;
1404 }
1405 else if (wait_option)
1406 {
1407 thread_list.thread_message_type = message_type;
1408 thread_list.thread_ptr = tx_thread_identify();
1409 thread_list.thread_received_message = NX_NULL;
1410 thread_list.thread_expected_id = 0;
1411 thread_list.thread_next = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
1412 hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = &thread_list;
1413
1414 /* Disable preemption. */
1415 tx_thread_preemption_change(tx_thread_identify(), 0, &old_threshold);
1416
1417 /* Release the mutex. */
1418 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1419
1420 tx_thread_sleep(wait_option);
1421
1422 /* Obtain the mutex. */
1423 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1424
1425 nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
1426
1427 /* Restore preemption. */
1428 tx_thread_preemption_change(tx_thread_identify(), old_threshold, &old_threshold);
1429 packet_ptr = thread_list.thread_received_message;
1430 }
1431
1432 /* Release the mutex. */
1433 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1434
1435 if (packet_ptr == NX_NULL)
1436 {
1437 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
1438 {
1439 LogError(LogLiteralArgs("IoTHub message receive fail: IoTHub client not connected"));
1440 return(NX_AZURE_IOT_DISCONNECTED);
1441 }
1442
1443 return(NX_AZURE_IOT_NO_PACKET);
1444 }
1445
1446 *packet_pptr = packet_ptr;
1447
1448 return(NX_AZURE_IOT_SUCCESS);
1449 }
1450
nx_azure_iot_hub_client_adjust_payload(NX_PACKET * packet_ptr)1451 UINT nx_azure_iot_hub_client_adjust_payload(NX_PACKET *packet_ptr)
1452 {
1453 UINT status;
1454 ULONG topic_offset;
1455 USHORT topic_length;
1456 ULONG message_offset;
1457 ULONG message_length;
1458
1459 status = _nxd_mqtt_process_publish_packet(packet_ptr, &topic_offset,
1460 &topic_length, &message_offset,
1461 &message_length);
1462 if (status)
1463 {
1464 nx_packet_release(packet_ptr);
1465 return(status);
1466 }
1467
1468 packet_ptr -> nx_packet_length = message_length;
1469
1470 /* Adjust packet to pointer to message payload. */
1471 while (packet_ptr)
1472 {
1473 if ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > message_offset)
1474 {
1475
1476 /* This packet contains message payload. */
1477 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + message_offset;
1478 break;
1479 }
1480
1481 message_offset -= (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
1482
1483 /* Set current packet to empty. */
1484 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_append_ptr;
1485
1486 /* Move to next packet. */
1487 packet_ptr = packet_ptr -> nx_packet_next;
1488 }
1489
1490 return(NX_AZURE_IOT_SUCCESS);
1491 }
1492
nx_azure_iot_hub_client_cloud_message_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)1493 UINT nx_azure_iot_hub_client_cloud_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1494 NX_PACKET **packet_pptr, UINT wait_option)
1495 {
1496 UINT status;
1497
1498 if ((hub_client_ptr == NX_NULL) ||
1499 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
1500 (packet_pptr == NX_NULL))
1501 {
1502 LogError(LogLiteralArgs("IoTHub cloud message receive fail: INVALID POINTER"));
1503 return(NX_AZURE_IOT_INVALID_PARAMETER);
1504 }
1505
1506 status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
1507 &(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message),
1508 packet_pptr, wait_option);
1509 if (status)
1510 {
1511 return(status);
1512 }
1513
1514 return(nx_azure_iot_hub_client_adjust_payload(*packet_pptr));
1515 }
1516
nx_azure_iot_hub_client_cloud_message_property_get(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,const UCHAR * property_name,USHORT property_name_length,const UCHAR ** property_value,USHORT * property_value_length)1517 UINT nx_azure_iot_hub_client_cloud_message_property_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1518 NX_PACKET *packet_ptr, const UCHAR *property_name,
1519 USHORT property_name_length, const UCHAR **property_value,
1520 USHORT *property_value_length)
1521 {
1522 USHORT topic_size;
1523 UINT status;
1524 ULONG topic_offset;
1525 UCHAR *topic_name;
1526 az_iot_hub_client_c2d_request request;
1527 az_span receive_topic;
1528 az_result core_result;
1529 az_span span;
1530
1531 if (packet_ptr == NX_NULL ||
1532 property_name == NX_NULL ||
1533 property_value == NX_NULL ||
1534 property_value_length == NX_NULL)
1535 {
1536 LogError(LogLiteralArgs("IoTHub cloud message get property fail: INVALID POINTER"));
1537 return(NX_AZURE_IOT_INVALID_PARAMETER);
1538 }
1539
1540 status = nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_data_start,
1541 &topic_offset, &topic_size);
1542 if (status)
1543 {
1544 return(status);
1545 }
1546
1547 topic_name = packet_ptr -> nx_packet_data_start + topic_offset;
1548
1549 /* NOTE: Current implementation does not support topic to span multiple packets. */
1550 if ((ULONG)(packet_ptr -> nx_packet_append_ptr - topic_name) < (ULONG)topic_size)
1551 {
1552 LogError(LogLiteralArgs("IoTHub cloud message get property fail: topic out of boundaries of single packet"));
1553 return(NX_AZURE_IOT_TOPIC_TOO_LONG);
1554 }
1555
1556 receive_topic = az_span_create(topic_name, (INT)topic_size);
1557 core_result = az_iot_hub_client_c2d_parse_received_topic(&hub_client_ptr -> iot_hub_client_core,
1558 receive_topic, &request);
1559 if (az_result_failed(core_result))
1560 {
1561 LogError(LogLiteralArgs("IoTHub cloud message get property fail: parsing error"));
1562 return(NX_AZURE_IOT_SDK_CORE_ERROR);
1563 }
1564
1565 span = az_span_create((UCHAR *)property_name, property_name_length);
1566 core_result = az_iot_message_properties_find(&request.properties, span, &span);
1567 if (az_result_failed(core_result))
1568 {
1569 if (core_result == AZ_ERROR_ITEM_NOT_FOUND)
1570 {
1571 status = NX_AZURE_IOT_NOT_FOUND;
1572 }
1573 else
1574 {
1575 LogError(LogLiteralArgs("IoTHub cloud message get property fail: property find"));
1576 status = NX_AZURE_IOT_SDK_CORE_ERROR;
1577 }
1578
1579 return(status);
1580 }
1581
1582 *property_value = (UCHAR *)az_span_ptr(span);
1583 *property_value_length = (USHORT)az_span_size(span);
1584
1585 return(NX_AZURE_IOT_SUCCESS);
1586 }
1587
nx_azure_iot_hub_client_mqtt_ack_receive_notify(NXD_MQTT_CLIENT * client_ptr,UINT type,USHORT packet_id,NX_PACKET * transmit_packet_ptr,VOID * context)1588 static VOID nx_azure_iot_hub_client_mqtt_ack_receive_notify(NXD_MQTT_CLIENT *client_ptr, UINT type,
1589 USHORT packet_id, NX_PACKET *transmit_packet_ptr,
1590 VOID *context)
1591 {
1592
1593 NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)context;
1594 UCHAR buffer[sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1];
1595 ULONG bytes_copied;
1596
1597
1598 NX_PARAMETER_NOT_USED(client_ptr);
1599 NX_PARAMETER_NOT_USED(packet_id);
1600 NX_PARAMETER_NOT_USED(context);
1601
1602 /* Monitor subscribe ack. */
1603 if (type == MQTT_CONTROL_PACKET_TYPE_SUBACK)
1604 {
1605
1606 /* Get the topic. */
1607 if (nx_packet_data_extract_offset(transmit_packet_ptr,
1608 NX_AZURE_IOT_MQTT_SUBSCRIBE_TOPIC_OFFSET,
1609 buffer, sizeof(buffer), &bytes_copied))
1610 {
1611 return;
1612 }
1613
1614 /* Compare the topic. */
1615 if ((bytes_copied == sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1) &&
1616 (!memcmp(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
1617 buffer, sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1)))
1618 {
1619 hub_client_ptr -> nx_azure_iot_hub_client_properties_subscribe_ack = NX_TRUE;
1620 }
1621 }
1622 }
1623
nx_azure_iot_hub_client_properties_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)1624 UINT nx_azure_iot_hub_client_properties_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
1625 {
1626 UINT status;
1627 NXD_MQTT_CLIENT *client_ptr;
1628
1629 if (hub_client_ptr == NX_NULL)
1630 {
1631 LogError(LogLiteralArgs("IoTHub client properties subscribe fail: INVALID POINTER"));
1632 return(NX_AZURE_IOT_INVALID_PARAMETER);
1633 }
1634
1635 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1636
1637 /* Atomically update the handler as we need to serialize the handler with incoming messages. */
1638 hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process =
1639 nx_azure_iot_hub_client_properties_process;
1640 hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_process =
1641 nx_azure_iot_hub_client_properties_process;
1642 hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_enable =
1643 nx_azure_iot_hub_client_properties_enable;
1644 hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_enable =
1645 nx_azure_iot_hub_client_properties_enable;
1646
1647 /* Register callbacks even if not connect and when connect complete subscribe for topics. */
1648 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
1649 {
1650 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1651 return(NX_AZURE_IOT_SUCCESS);
1652 }
1653
1654 /* Initialize variables. */
1655 hub_client_ptr -> nx_azure_iot_hub_client_properties_subscribe_ack = NX_FALSE;
1656
1657 /* Set ack receive notify for subscribe ack. */
1658 client_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt);
1659 client_ptr -> nxd_mqtt_ack_receive_notify = nx_azure_iot_hub_client_mqtt_ack_receive_notify;
1660 client_ptr -> nxd_mqtt_ack_receive_context = hub_client_ptr;
1661
1662 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1663
1664 status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1665 AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
1666 sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1,
1667 NX_AZURE_IOT_MQTT_QOS_0);
1668 if (status)
1669 {
1670
1671 /* Clean ack receive notify. */
1672 client_ptr -> nxd_mqtt_ack_receive_notify = NX_NULL;
1673 LogError(LogLiteralArgs("IoTHub client device twin subscribe fail status: %d"), status);
1674 return(status);
1675 }
1676
1677 status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1678 AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC,
1679 sizeof(AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC) - 1,
1680 NX_AZURE_IOT_MQTT_QOS_0);
1681 if (status)
1682 {
1683
1684 /* Clean ack receive notify. */
1685 client_ptr -> nxd_mqtt_ack_receive_notify = NX_NULL;
1686 LogError(LogLiteralArgs("IoTHub client device twin subscribe fail status: %d"), status);
1687 return(status);
1688 }
1689
1690 return(NX_AZURE_IOT_SUCCESS);
1691 }
1692
nx_azure_iot_hub_client_properties_disable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)1693 UINT nx_azure_iot_hub_client_properties_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
1694 {
1695 UINT status;
1696
1697 if (hub_client_ptr == NX_NULL)
1698 {
1699 LogError(LogLiteralArgs("IoTHub client properties unsubscribe fail: INVALID POINTER"));
1700 return(NX_AZURE_IOT_INVALID_PARAMETER);
1701 }
1702
1703 status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1704 AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
1705 sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1);
1706 if (status)
1707 {
1708 LogError(LogLiteralArgs("IoTHub client device twin unsubscribe fail status: %d"), status);
1709 return(status);
1710 }
1711
1712 status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1713 AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC,
1714 sizeof(AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC) - 1);
1715 if (status)
1716 {
1717 LogError(LogLiteralArgs("IoTHub client device twin unsubscribe fail status: %d"), status);
1718 return(status);
1719 }
1720
1721 hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process = NX_NULL;
1722 hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message.message_process = NX_NULL;
1723
1724 return(NX_AZURE_IOT_SUCCESS);
1725 }
1726
nx_azure_iot_hub_client_reported_properties_response_callback_set(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,VOID (* callback_ptr)(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT request_id,UINT response_status,ULONG version,VOID * args),VOID * callback_args)1727 UINT nx_azure_iot_hub_client_reported_properties_response_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1728 VOID (*callback_ptr)(
1729 NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1730 UINT request_id,
1731 UINT response_status,
1732 ULONG version,
1733 VOID *args),
1734 VOID *callback_args)
1735 {
1736 if (hub_client_ptr == NX_NULL)
1737 {
1738 LogError(LogLiteralArgs("IoTHub client device twin set callback fail: INVALID POINTER"));
1739 return(NX_AZURE_IOT_INVALID_PARAMETER);
1740 }
1741
1742 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1743
1744 hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback = callback_ptr;
1745 hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback_args = callback_args;
1746
1747 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1748
1749 return(NX_AZURE_IOT_SUCCESS);
1750 }
1751
nx_azure_iot_hub_client_properties_request_id_get(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UCHAR * buffer_ptr,UINT buffer_len,az_span * request_id_span_ptr,UINT * request_id_ptr,UINT odd_seq)1752 static UINT nx_azure_iot_hub_client_properties_request_id_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1753 UCHAR *buffer_ptr, UINT buffer_len,
1754 az_span *request_id_span_ptr,
1755 UINT *request_id_ptr, UINT odd_seq)
1756 {
1757 az_span span;
1758
1759 /* Obtain the mutex. */
1760 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1761
1762 /* Check if current request_id is even and new requested is also even or
1763 current request_id is odd and new requested is also odd. */
1764 if ((hub_client_ptr -> nx_azure_iot_hub_client_request_id & 0x1) == odd_seq)
1765 {
1766 hub_client_ptr -> nx_azure_iot_hub_client_request_id += 2;
1767 }
1768 else
1769 {
1770 hub_client_ptr -> nx_azure_iot_hub_client_request_id += 1;
1771 }
1772
1773 if (hub_client_ptr -> nx_azure_iot_hub_client_request_id == 0)
1774 {
1775 hub_client_ptr -> nx_azure_iot_hub_client_request_id = 2;
1776 }
1777
1778 *request_id_ptr = hub_client_ptr -> nx_azure_iot_hub_client_request_id;
1779 span = az_span_create(buffer_ptr, (INT)buffer_len);
1780 if (az_result_failed(az_span_u32toa(span, *request_id_ptr, &span)))
1781 {
1782
1783 /* Release the mutex. */
1784 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1785 LogError(LogLiteralArgs("IoTHub client device failed to u32toa"));
1786 return(NX_AZURE_IOT_SDK_CORE_ERROR);
1787 }
1788
1789 *request_id_span_ptr = az_span_create(buffer_ptr, (INT)(buffer_len - (UINT)az_span_size(span)));
1790
1791 /* Release the mutex. */
1792 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1793
1794 return(NX_AZURE_IOT_SUCCESS);
1795 }
1796
nx_azure_iot_hub_client_properties_subscribe_status_check(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT wait_option)1797 static UINT nx_azure_iot_hub_client_properties_subscribe_status_check(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT wait_option)
1798 {
1799
1800 /* Wait for subscribe ack of topic "$iothub/twin/res/#". */
1801 while (1)
1802 {
1803 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1804
1805 /* Check if it is still in connected status. */
1806 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
1807 {
1808
1809 /* Clean ack receive notify. */
1810 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
1811 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1812 return(NX_AZURE_IOT_DISCONNECTED);
1813 }
1814
1815 /* Check if receive the subscribe ack. */
1816 if (hub_client_ptr -> nx_azure_iot_hub_client_properties_subscribe_ack == NX_TRUE)
1817 {
1818
1819 /* Clean ack receive notify. */
1820 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
1821 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1822 break;
1823 }
1824
1825 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1826
1827 /* Update wait time. */
1828 if (wait_option != NX_WAIT_FOREVER)
1829 {
1830 if (wait_option > 0)
1831 {
1832 wait_option--;
1833 }
1834 else
1835 {
1836 return(NX_AZURE_IOT_NO_SUBSCRIBE_ACK);
1837 }
1838 }
1839
1840 tx_thread_sleep(1);
1841 }
1842
1843 return(NX_AZURE_IOT_SUCCESS);
1844 }
1845
nx_azure_iot_hub_client_properties_request_response(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT request_id,NX_PACKET * packet_ptr,ULONG topic_length,const UCHAR * message_buffer,UINT message_length,UINT message_type,NX_PACKET ** response_packet_pptr,UINT wait_option)1846 static UINT nx_azure_iot_hub_client_properties_request_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1847 UINT request_id, NX_PACKET *packet_ptr, ULONG topic_length,
1848 const UCHAR *message_buffer, UINT message_length, UINT message_type,
1849 NX_PACKET **response_packet_pptr, UINT wait_option)
1850 {
1851 NX_AZURE_IOT_THREAD thread_list;
1852 UINT status;
1853
1854 if ((message_buffer != NX_NULL) && (message_length != 0))
1855 {
1856
1857 /* Append payload. */
1858 status = nx_packet_data_append(packet_ptr, (VOID *)message_buffer, message_length,
1859 packet_ptr -> nx_packet_pool_owner,
1860 wait_option);
1861 if (status)
1862 {
1863 LogError(LogLiteralArgs("IoTHub client reported state send fail: append failed"));
1864 return(status);
1865 }
1866 }
1867
1868 /* Obtain the mutex. */
1869 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1870
1871 thread_list.thread_message_type = message_type;
1872 thread_list.thread_ptr = tx_thread_identify();
1873 thread_list.thread_expected_id = request_id;
1874 thread_list.thread_received_message = NX_NULL;
1875 thread_list.thread_next = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
1876 hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = &thread_list;
1877
1878 /* Release the mutex. */
1879 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1880
1881 status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1882 packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
1883 wait_option);
1884
1885 if (status)
1886 {
1887
1888 /* Remove thread from waiting suspend queue. */
1889 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1890 nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
1891 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1892
1893 LogError(LogLiteralArgs("IoTHub transport send: PUBLISH FAIL status: %d"), status);
1894 return(status);
1895 }
1896
1897 if ((thread_list.thread_received_message) == NX_NULL && wait_option)
1898 {
1899 tx_thread_sleep(wait_option);
1900 }
1901
1902 /* Obtain the mutex. */
1903 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
1904
1905 nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
1906 *response_packet_pptr = thread_list.thread_received_message;
1907
1908 /* Release the mutex. */
1909 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
1910
1911 return(NX_AZURE_IOT_SUCCESS);
1912 }
1913
nx_azure_iot_hub_client_reported_properties_create(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)1914 UINT nx_azure_iot_hub_client_reported_properties_create(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1915 NX_PACKET **packet_pptr,
1916 UINT wait_option)
1917 {
1918 UINT status;
1919 NX_PACKET *packet_ptr;
1920 UINT request_id;
1921 UCHAR *buffer_ptr;
1922 ULONG buffer_size;
1923 az_span request_id_span;
1924 az_result core_result;
1925 UINT topic_length;
1926
1927 if ((hub_client_ptr == NX_NULL) ||
1928 (packet_pptr == NX_NULL))
1929 {
1930 LogError(LogLiteralArgs("IoTHub reported properties create fail: INVALID POINTER"));
1931 return(NX_AZURE_IOT_INVALID_PARAMETER);
1932 }
1933
1934 status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
1935 &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
1936 &packet_ptr, wait_option);
1937 if (status)
1938 {
1939 LogError(LogLiteralArgs("IoTHub client reported properties create fail: BUFFER ALLOCATE FAIL"));
1940 return(status);
1941 }
1942
1943 buffer_size = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
1944 if (buffer_size <= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE)
1945 {
1946 LogError(LogLiteralArgs("IoTHub client reported properties create fail: BUFFER INSUFFICENT"));
1947 nx_packet_release(packet_ptr);
1948 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
1949 }
1950
1951 buffer_size -= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE;
1952
1953 /* Generate odd request id for reported properties send */
1954 status = nx_azure_iot_hub_client_properties_request_id_get(hub_client_ptr,
1955 (UCHAR *)(packet_ptr -> nx_packet_data_end -
1956 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE),
1957 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE,
1958 &request_id_span, &request_id, NX_TRUE);
1959
1960 if (status)
1961 {
1962 LogError(LogLiteralArgs("IoTHub client reported properties create fail: get request id failed"));
1963 nx_packet_release(packet_ptr);
1964 return(status);
1965 }
1966
1967 core_result = az_iot_hub_client_properties_get_reported_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
1968 request_id_span,
1969 (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
1970 buffer_size, &topic_length);
1971 if (az_result_failed(core_result))
1972 {
1973 LogError(LogLiteralArgs("IoTHub client reported properties create fail: NX_AZURE_IOT_PNP_CLIENT_TOPIC_SIZE is too small."));
1974 nx_packet_release(packet_ptr);
1975 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
1976 }
1977
1978 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
1979 packet_ptr -> nx_packet_length = topic_length;
1980
1981 /* Set the buffer pointer. */
1982 buffer_ptr = packet_ptr -> nx_packet_prepend_ptr - NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET;
1983
1984 /* encode topic length */
1985 buffer_ptr[5] = (UCHAR)(packet_ptr -> nx_packet_length >> 8);
1986 buffer_ptr[6] = (UCHAR)(packet_ptr -> nx_packet_length & 0xFF);
1987
1988 /* encode request id */
1989 buffer_ptr[4] = (UCHAR)((request_id & 0xFF));
1990 request_id >>= 8;
1991 buffer_ptr[3] = (UCHAR)((request_id & 0xFF));
1992 request_id >>= 8;
1993 buffer_ptr[2] = (UCHAR)((request_id & 0xFF));
1994 request_id >>= 8;
1995 buffer_ptr[1] = (UCHAR)(request_id & 0xFF);
1996
1997 *packet_pptr = packet_ptr;
1998
1999 return(NX_AZURE_IOT_SUCCESS);
2000 }
2001
nx_azure_iot_hub_client_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,UINT * request_id_ptr,UINT * response_status_ptr,ULONG * version_ptr,UINT wait_option)2002 UINT nx_azure_iot_hub_client_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2003 NX_PACKET *packet_ptr,
2004 UINT *request_id_ptr, UINT *response_status_ptr,
2005 ULONG *version_ptr, UINT wait_option)
2006 {
2007 NX_PACKET *response_packet_ptr;
2008 UINT topic_length;
2009 UINT request_id = 0;
2010 ULONG topic_offset;
2011 USHORT length;
2012 UCHAR *buffer_ptr;
2013 UINT status;
2014
2015 if ((hub_client_ptr == NX_NULL) ||
2016 (packet_ptr == NX_NULL))
2017 {
2018 LogError(LogLiteralArgs("IoTHub client reported properties send fail: INVALID POINTER"));
2019 return(NX_AZURE_IOT_INVALID_PARAMETER);
2020 }
2021
2022 /* Check if properties is subscribed */
2023 if ((status = nx_azure_iot_hub_client_properties_subscribe_status_check(hub_client_ptr, wait_option)))
2024 {
2025 LogError(LogLiteralArgs("IoTHub client reported properties send fail with error %d"), status);
2026 return(status);
2027 }
2028
2029 /* Check if the last request was throttled and if the next need to be throttled. */
2030 if ((status = nx_azure_iot_hub_client_throttled_check(hub_client_ptr)))
2031 {
2032 LogError(LogLiteralArgs("IoTHub client reported properties send fail with error %d"), status);
2033 return(status);
2034 }
2035
2036 /* Steps.
2037 * 1. Publish message to topic "$iothub/twin/PATCH/properties/reported/?$rid={request id}"
2038 * 2. Wait for the response if required.
2039 * 3. Return result if present.
2040 * */
2041
2042 buffer_ptr = packet_ptr -> nx_packet_prepend_ptr - NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET;
2043
2044 topic_length = (UINT)((buffer_ptr[5] << 8) | buffer_ptr[6]);
2045
2046 request_id += (buffer_ptr[1] & 0xFF);
2047 request_id <<= 8;
2048 request_id += (buffer_ptr[2] & 0xFF);
2049 request_id <<= 8;
2050 request_id += (buffer_ptr[3] & 0xFF);
2051 request_id <<= 8;
2052 request_id += (buffer_ptr[4] & 0xFF);
2053
2054 status = nx_azure_iot_hub_client_properties_request_response(hub_client_ptr,
2055 request_id, packet_ptr, topic_length, NX_NULL, 0,
2056 NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE,
2057 &response_packet_ptr, wait_option);
2058 if (status)
2059 {
2060 LogError(LogLiteralArgs("IoTHub client reported properties send fail: append failed"));
2061 return(status);
2062 }
2063
2064 /* The packet of reported properties has been sent out successfully,
2065 next the return value should be NX_AZURE_IOT_SUCCESS. */
2066
2067 /* Continue to process response and the caller can check the response status to see if iothub accept the properties or not,
2068 the reponse status is available only when the return status is NX_AZURE_IOT_SUCCESS. */
2069 if (request_id_ptr)
2070 {
2071 *request_id_ptr = request_id;
2072 }
2073
2074 if (response_status_ptr)
2075 {
2076 *response_status_ptr = 0;
2077 }
2078
2079 if (response_packet_ptr)
2080 {
2081 if(nx_azure_iot_hub_client_process_publish_packet(response_packet_ptr -> nx_packet_prepend_ptr,
2082 &topic_offset, &length) == NX_AZURE_IOT_SUCCESS)
2083 {
2084 nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr,
2085 response_packet_ptr, topic_offset, length,
2086 NX_NULL, version_ptr, NX_NULL,
2087 response_status_ptr);
2088 }
2089
2090 nx_packet_release(response_packet_ptr);
2091 }
2092
2093 return(NX_AZURE_IOT_SUCCESS);
2094 }
2095
nx_azure_iot_hub_client_properties_request(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT wait_option)2096 UINT nx_azure_iot_hub_client_properties_request(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2097 UINT wait_option)
2098 {
2099 UINT status;
2100 UINT topic_length;
2101 UINT buffer_size;
2102 NX_PACKET *packet_ptr;
2103 az_span request_id_span;
2104 UINT request_id;
2105 az_result core_result;
2106
2107 if (hub_client_ptr == NX_NULL)
2108 {
2109 LogError(LogLiteralArgs("IoTHub client properties request failed: INVALID POINTER"));
2110 return(NX_AZURE_IOT_INVALID_PARAMETER);
2111 }
2112
2113 if ((status = nx_azure_iot_hub_client_properties_subscribe_status_check(hub_client_ptr, wait_option)))
2114 {
2115 LogError(LogLiteralArgs("IoTHub client properties request failed with error %d"), status);
2116 return(status);
2117 }
2118
2119 /* Check if the last request was throttled and if the next need to be throttled. */
2120 if ((status = nx_azure_iot_hub_client_throttled_check(hub_client_ptr)))
2121 {
2122 LogError(LogLiteralArgs("IoTHub client properties request failed with error %d"), status);
2123 return(status);
2124 }
2125
2126 /* Steps.
2127 * 1. Publish message to topic "$iothub/twin/GET/?$rid={request id}"
2128 * */
2129 status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
2130 &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
2131 &packet_ptr, wait_option);
2132 if (status)
2133 {
2134 LogError(LogLiteralArgs("IoTHub client properties request failed: BUFFER ALLOCATE FAIL"));
2135 return(status);
2136 }
2137
2138 buffer_size = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
2139 if (buffer_size <= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE)
2140 {
2141 LogError(LogLiteralArgs("IoTHub client device twin publish fail: BUFFER ALLOCATE FAIL"));
2142 nx_packet_release(packet_ptr);
2143 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
2144 }
2145
2146 buffer_size -= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE;
2147
2148 /* Generate even request id for properties request. */
2149 status = nx_azure_iot_hub_client_properties_request_id_get(hub_client_ptr,
2150 (UCHAR *)(packet_ptr -> nx_packet_data_end -
2151 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE),
2152 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE,
2153 &request_id_span, &request_id, NX_FALSE);
2154 if (status)
2155 {
2156 LogError(LogLiteralArgs("IoTHub client device twin failed to get request id"));
2157 nx_packet_release(packet_ptr);
2158 return(status);
2159 }
2160
2161 core_result = az_iot_hub_client_properties_document_get_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
2162 request_id_span, (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
2163 buffer_size, (size_t *)&topic_length);
2164 if (az_result_failed(core_result))
2165 {
2166 LogError(LogLiteralArgs("IoTHub client device twin get topic fail."));
2167 nx_packet_release(packet_ptr);
2168 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
2169 }
2170
2171 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
2172 packet_ptr -> nx_packet_length = topic_length;
2173
2174 status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
2175 packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
2176 wait_option);
2177 if (status)
2178 {
2179 LogError(LogLiteralArgs("IoTHub client device twin: PUBLISH FAIL status: %d"), status);
2180 nx_packet_release(packet_ptr);
2181 return(status);
2182 }
2183
2184 return(NX_AZURE_IOT_SUCCESS);
2185 }
2186
nx_azure_iot_hub_client_properties_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)2187 UINT nx_azure_iot_hub_client_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2188 NX_PACKET **packet_pptr,
2189 UINT wait_option)
2190 {
2191 UINT status;
2192 ULONG topic_offset;
2193 USHORT topic_length;
2194 az_result core_result;
2195 az_span topic_span;
2196 az_iot_hub_client_properties_message out_message;
2197 NX_PACKET *packet_ptr;
2198
2199 if ((hub_client_ptr == NX_NULL) || (packet_pptr == NX_NULL))
2200 {
2201 LogError(LogLiteralArgs("IoTHub client properties receive failed: INVALID POINTER"));
2202 return(NX_AZURE_IOT_INVALID_PARAMETER);
2203 }
2204
2205 /* Steps.
2206 * 1. Check if the properties document is available to receive from linklist.
2207 * 2. If present check the response.
2208 * 3. Return the payload of the response.
2209 * */
2210 status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_PROPERTIES,
2211 &(hub_client_ptr -> nx_azure_iot_hub_client_properties_message),
2212 &packet_ptr, wait_option);
2213 if (status)
2214 {
2215 LogError(LogLiteralArgs("IoTHub client device twin receive failed status: %d"), status);
2216 return(status);
2217 }
2218
2219 if (nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset, &topic_length))
2220 {
2221
2222 /* Message not supported. It will be released. */
2223 nx_packet_release(packet_ptr);
2224 return(NX_AZURE_IOT_INVALID_PACKET);
2225 }
2226
2227 topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), (INT)topic_length);
2228 core_result = az_iot_hub_client_properties_parse_received_topic(&(hub_client_ptr -> iot_hub_client_core),
2229 topic_span, &out_message);
2230 if (az_result_failed(core_result))
2231 {
2232
2233 /* Topic name does not match properties format. */
2234 nx_packet_release(packet_ptr);
2235 return(NX_AZURE_IOT_SDK_CORE_ERROR);
2236 }
2237
2238 if ((out_message.status < 200) || (out_message.status >= 300))
2239 {
2240 nx_packet_release(packet_ptr);
2241 return(NX_AZURE_IOT_SERVER_RESPONSE_ERROR);
2242 }
2243
2244 if ((status = nx_azure_iot_hub_client_adjust_payload(packet_ptr)))
2245 {
2246 nx_packet_release(packet_ptr);
2247 return(status);
2248 }
2249
2250 *packet_pptr = packet_ptr;
2251
2252 return(NX_AZURE_IOT_SUCCESS);
2253 }
2254
nx_azure_iot_hub_client_writable_properties_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)2255 UINT nx_azure_iot_hub_client_writable_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2256 NX_PACKET **packet_pptr,
2257 UINT wait_option)
2258 {
2259 UINT status;
2260 NX_PACKET *packet_ptr;
2261
2262 if ((hub_client_ptr == NX_NULL) ||
2263 (packet_pptr == NX_NULL))
2264 {
2265 LogError(LogLiteralArgs("IoTHub client receive properties failed: INVALID POINTER"));
2266 return(NX_AZURE_IOT_INVALID_PARAMETER);
2267 }
2268
2269 /* Steps.
2270 * 1. Check if the writable properties document is available to receive from linklist.
2271 * 2. Parse result if present.
2272 * 3. Return parse result.
2273 * */
2274 status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES,
2275 &(hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message),
2276 &packet_ptr, wait_option);
2277 if (status)
2278 {
2279 LogError(LogLiteralArgs("IoTHub client device twin receive failed status: %d"), status);
2280 return(status);
2281 }
2282
2283 if ((status = nx_azure_iot_hub_client_adjust_payload(packet_ptr)))
2284 {
2285 nx_packet_release(packet_ptr);
2286 return(status);
2287 }
2288
2289 *packet_pptr = packet_ptr;
2290
2291 return(NX_AZURE_IOT_SUCCESS);
2292 }
2293
2294
nx_azure_iot_hub_client_device_twin_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)2295 UINT nx_azure_iot_hub_client_device_twin_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
2296 {
2297
2298 if (hub_client_ptr == NX_NULL)
2299 {
2300 LogError(LogLiteralArgs("IoTHub client device twin subscribe fail: INVALID POINTER"));
2301 return(NX_AZURE_IOT_INVALID_PARAMETER);
2302 }
2303
2304 return(nx_azure_iot_hub_client_properties_enable(hub_client_ptr));
2305 }
2306
nx_azure_iot_hub_client_device_twin_disable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)2307 UINT nx_azure_iot_hub_client_device_twin_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
2308 {
2309
2310 if (hub_client_ptr == NX_NULL)
2311 {
2312 LogError(LogLiteralArgs("IoTHub client device twin unsubscribe fail: INVALID POINTER"));
2313 return(NX_AZURE_IOT_INVALID_PARAMETER);
2314 }
2315
2316 return(nx_azure_iot_hub_client_properties_disable(hub_client_ptr));
2317 }
2318
2319
nx_azure_iot_hub_client_device_twin_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * message_buffer,UINT message_length,UINT * request_id_ptr,UINT * response_status_ptr,ULONG * version_ptr,UINT wait_option)2320 UINT nx_azure_iot_hub_client_device_twin_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2321 const UCHAR *message_buffer, UINT message_length,
2322 UINT *request_id_ptr, UINT *response_status_ptr,
2323 ULONG *version_ptr, UINT wait_option)
2324 {
2325 UINT status;
2326 UINT buffer_size;
2327 NX_PACKET *packet_ptr;
2328 UINT topic_length;
2329 UINT request_id;
2330 az_span request_id_span;
2331 az_result core_result;
2332 ULONG topic_offset;
2333 USHORT length;
2334 NX_PACKET *response_packet_ptr;
2335
2336 if (hub_client_ptr == NX_NULL)
2337 {
2338 LogError(LogLiteralArgs("IoTHub client reported state send fail: INVALID POINTER"));
2339 return(NX_AZURE_IOT_INVALID_PARAMETER);
2340 }
2341
2342 if ((status = nx_azure_iot_hub_client_properties_subscribe_status_check(hub_client_ptr, wait_option)))
2343 {
2344 LogError(LogLiteralArgs("IoTHub client reported state send fail with error %d"), status);
2345 return(status);
2346 }
2347
2348 /* Check if the last request was throttled and if the next need to be throttled. */
2349 if ((status = nx_azure_iot_hub_client_throttled_check(hub_client_ptr)))
2350 {
2351 LogError(LogLiteralArgs("IoTHub client reported state send fail with error %d"), status);
2352 return(status);
2353 }
2354
2355 /* Steps.
2356 * 1. Publish message to topic "$iothub/twin/PATCH/properties/reported/?$rid={request id}"
2357 * 2. Wait for the response if required.
2358 * 3. Return result if present.
2359 * */
2360 if (hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process == NX_NULL)
2361 {
2362 LogError(LogLiteralArgs("IoTHub client reported state send fail: NOT ENABLED"));
2363 return(NX_AZURE_IOT_NOT_ENABLED);
2364 }
2365
2366 status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
2367 &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
2368 &packet_ptr, wait_option);
2369 if (status)
2370 {
2371 LogError(LogLiteralArgs("IoTHub client reported state send fail: BUFFER ALLOCATE FAIL"));
2372 return(status);
2373 }
2374
2375 buffer_size = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
2376 if (buffer_size <= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE)
2377 {
2378 LogError(LogLiteralArgs("IoTHub client reported state send fail: BUFFER INSUFFICENT"));
2379 nx_packet_release(packet_ptr);
2380 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
2381 }
2382
2383 buffer_size -= NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE;
2384
2385 /* Generate odd request id for reported properties send. */
2386 status = nx_azure_iot_hub_client_properties_request_id_get(hub_client_ptr,
2387 (UCHAR *)(packet_ptr -> nx_packet_data_end -
2388 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE),
2389 NX_AZURE_IOT_HUB_CLIENT_U32_MAX_BUFFER_SIZE,
2390 &request_id_span, &request_id, NX_TRUE);
2391
2392 if (status)
2393 {
2394 LogError(LogLiteralArgs("IoTHub client reported state send failed to get request id"));
2395 nx_packet_release(packet_ptr);
2396 return(status);
2397 }
2398
2399 core_result = az_iot_hub_client_twin_patch_get_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
2400 request_id_span, (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
2401 buffer_size, (size_t *)&topic_length);
2402 if (az_result_failed(core_result))
2403 {
2404 LogError(LogLiteralArgs("IoTHub client reported state send fail: NX_AZURE_IOT_HUB_CLIENT_TOPIC_SIZE is too small."));
2405 nx_packet_release(packet_ptr);
2406 return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
2407 }
2408
2409 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
2410 packet_ptr -> nx_packet_length = topic_length;
2411
2412 status = nx_azure_iot_hub_client_properties_request_response(hub_client_ptr,
2413 request_id, packet_ptr, topic_length, message_buffer, message_length,
2414 NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE,
2415 &response_packet_ptr, wait_option);
2416 if (status)
2417 {
2418 LogError(LogLiteralArgs("IoTHub client reported state send fail: append failed"));
2419 nx_packet_release(packet_ptr);
2420 return(status);
2421 }
2422
2423 if (request_id_ptr)
2424 {
2425 *request_id_ptr = request_id;
2426 }
2427
2428 if (response_packet_ptr == NX_NULL)
2429 {
2430 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
2431 {
2432 return(NX_AZURE_IOT_DISCONNECTED);
2433 }
2434 return(NX_AZURE_IOT_NO_PACKET);
2435 }
2436
2437 if ((status = nx_azure_iot_hub_client_process_publish_packet(response_packet_ptr -> nx_packet_prepend_ptr,
2438 &topic_offset, &length)))
2439 {
2440 nx_packet_release(response_packet_ptr);
2441 return(status);
2442 }
2443
2444 if ((status = nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr,
2445 response_packet_ptr, topic_offset, length,
2446 NX_NULL, version_ptr, NX_NULL,
2447 response_status_ptr)))
2448 {
2449 nx_packet_release(response_packet_ptr);
2450 return(status);
2451 }
2452
2453 /* Release message block. */
2454 nx_packet_release(response_packet_ptr);
2455
2456 return(NX_AZURE_IOT_SUCCESS);
2457 }
2458
nx_azure_iot_hub_client_device_twin_properties_request(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT wait_option)2459 UINT nx_azure_iot_hub_client_device_twin_properties_request(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2460 UINT wait_option)
2461 {
2462
2463 if (hub_client_ptr == NX_NULL)
2464 {
2465 LogError(LogLiteralArgs("IoTHub client device twin properties request failed: INVALID POINTER"));
2466 return(NX_AZURE_IOT_INVALID_PARAMETER);
2467 }
2468
2469 return(nx_azure_iot_hub_client_properties_request(hub_client_ptr, wait_option));
2470 }
2471
nx_azure_iot_hub_client_device_twin_properties_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)2472 UINT nx_azure_iot_hub_client_device_twin_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2473 NX_PACKET **packet_pptr, UINT wait_option)
2474 {
2475
2476 if (hub_client_ptr == NX_NULL || packet_pptr == NX_NULL)
2477 {
2478 LogError(LogLiteralArgs("IoTHub client device twin properties receive failed: INVALID POINTER"));
2479 return(NX_AZURE_IOT_INVALID_PARAMETER);
2480 }
2481
2482 return(nx_azure_iot_hub_client_properties_receive(hub_client_ptr, packet_pptr, wait_option));
2483 }
2484
nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET ** packet_pptr,UINT wait_option)2485 UINT nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2486 NX_PACKET **packet_pptr, UINT wait_option)
2487 {
2488
2489 if (hub_client_ptr == NX_NULL || packet_pptr == NX_NULL)
2490 {
2491 LogError(LogLiteralArgs("IoTHub client device twin desired properties receive failed: INVALID POINTER"));
2492 return(NX_AZURE_IOT_INVALID_PARAMETER);
2493 }
2494
2495 return(nx_azure_iot_hub_client_writable_properties_receive(hub_client_ptr, packet_pptr, wait_option));
2496 }
2497
nx_azure_iot_hub_client_cloud_message_sub_unsub(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT is_subscribe)2498 static UINT nx_azure_iot_hub_client_cloud_message_sub_unsub(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT is_subscribe)
2499 {
2500 UINT status;
2501
2502 if (is_subscribe)
2503 {
2504 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
2505
2506 /* Atomically update the handler as we need to serialize the handler with incoming messages. */
2507 hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process = nx_azure_iot_hub_client_c2d_process;
2508 hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_enable = nx_azure_iot_hub_client_cloud_message_enable;
2509
2510 /* Register callbacks even if not connect and when connect complete subscribe for topics. */
2511 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
2512 {
2513 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
2514 return(NX_AZURE_IOT_SUCCESS);
2515 }
2516
2517 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
2518
2519 status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
2520 AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC, sizeof(AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC) - 1,
2521 NX_AZURE_IOT_MQTT_QOS_1);
2522 if (status)
2523 {
2524 LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: status: %d"), status);
2525 return(status);
2526 }
2527 }
2528 else
2529 {
2530 status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
2531 AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC, sizeof(AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC) - 1);
2532 if (status)
2533 {
2534 LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: status: %d"), status);
2535 return(status);
2536 }
2537
2538 hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process = NX_NULL;
2539 }
2540
2541 return(NX_AZURE_IOT_SUCCESS);
2542 }
2543
nx_azure_iot_hub_client_mqtt_receive_callback(NXD_MQTT_CLIENT * client_ptr,UINT number_of_messages)2544 static VOID nx_azure_iot_hub_client_mqtt_receive_callback(NXD_MQTT_CLIENT* client_ptr,
2545 UINT number_of_messages)
2546 {
2547 NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
2548 NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = NX_NULL;
2549 NX_PACKET *packet_ptr;
2550 NX_PACKET *packet_next_ptr;
2551 ULONG topic_offset;
2552 USHORT topic_length;
2553
2554 /* This function is protected by MQTT mutex. */
2555
2556 NX_PARAMETER_NOT_USED(number_of_messages);
2557
2558 if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
2559 {
2560 hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource -> resource_data_ptr;
2561 }
2562
2563 if (hub_client_ptr)
2564 {
2565 for (packet_ptr = client_ptr -> message_receive_queue_head;
2566 packet_ptr;
2567 packet_ptr = packet_next_ptr)
2568 {
2569
2570 /* Store next packet in case current packet is consumed. */
2571 packet_next_ptr = packet_ptr -> nx_packet_queue_next;
2572
2573 /* Adjust packet to simply process logic. */
2574 nx_azure_iot_mqtt_packet_adjust(packet_ptr);
2575
2576 if (nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
2577 &topic_length))
2578 {
2579
2580 /* Message not supported. It will be released. */
2581 nx_packet_release(packet_ptr);
2582 continue;
2583 }
2584
2585 if ((topic_offset + topic_length) >
2586 (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr))
2587 {
2588
2589 /* Only process topic in the first packet since the fixed topic is short enough to fit into one packet. */
2590 topic_length = (USHORT)(((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) -
2591 topic_offset) & 0xFFFF);
2592 }
2593
2594 if (hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_process &&
2595 (hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_process(hub_client_ptr, packet_ptr,
2596 topic_offset,
2597 topic_length) == NX_AZURE_IOT_SUCCESS))
2598 {
2599
2600 /* Direct method message is processed. */
2601 continue;
2602 }
2603
2604 if (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process &&
2605 (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process(hub_client_ptr, packet_ptr,
2606 topic_offset,
2607 topic_length) == NX_AZURE_IOT_SUCCESS))
2608 {
2609
2610 /* Could to Device message is processed. */
2611 continue;
2612 }
2613
2614 if ((hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process) &&
2615 (hub_client_ptr -> nx_azure_iot_hub_client_properties_message.message_process(hub_client_ptr,
2616 packet_ptr, topic_offset,
2617 topic_length) == NX_AZURE_IOT_SUCCESS))
2618 {
2619
2620 /* Device Twin message is processed. */
2621 continue;
2622 }
2623
2624 /* Message not supported. It will be released. */
2625 nx_packet_release(packet_ptr);
2626 }
2627
2628 /* Clear all message from MQTT receive queue. */
2629 client_ptr -> message_receive_queue_head = NX_NULL;
2630 client_ptr -> message_receive_queue_tail = NX_NULL;
2631 client_ptr -> message_receive_queue_depth = 0;
2632 }
2633 }
2634
nx_azure_iot_hub_client_message_notify(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE * receive_message,NX_PACKET * packet_ptr)2635 static VOID nx_azure_iot_hub_client_message_notify(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2636 NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *receive_message,
2637 NX_PACKET *packet_ptr)
2638 {
2639 if (receive_message -> message_tail)
2640 {
2641 receive_message -> message_tail -> nx_packet_queue_next = packet_ptr;
2642 }
2643 else
2644 {
2645 receive_message -> message_head = packet_ptr;
2646 }
2647 receive_message -> message_tail = packet_ptr;
2648
2649 /* Check for user callback function. */
2650 if (receive_message -> message_callback)
2651 {
2652 receive_message -> message_callback(hub_client_ptr, receive_message -> message_callback_args);
2653 }
2654 }
2655
nx_azure_iot_hub_client_receive_thread_find(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,UINT message_type,UINT request_id,NX_AZURE_IOT_THREAD ** thread_list_pptr)2656 static UINT nx_azure_iot_hub_client_receive_thread_find(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2657 NX_PACKET *packet_ptr, UINT message_type,
2658 UINT request_id, NX_AZURE_IOT_THREAD **thread_list_pptr)
2659 {
2660 NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
2661 NX_AZURE_IOT_THREAD *thread_list_ptr;
2662
2663 /* Search thread waiting for message type. */
2664 for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
2665 thread_list_ptr;
2666 thread_list_ptr = thread_list_ptr -> thread_next)
2667 {
2668 if ((thread_list_ptr -> thread_message_type == message_type) &&
2669 (request_id == thread_list_ptr -> thread_expected_id))
2670 {
2671
2672 /* Found a thread waiting for message type. */
2673 if (thread_list_prev == NX_NULL)
2674 {
2675 hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = thread_list_ptr -> thread_next;
2676 }
2677 else
2678 {
2679 thread_list_prev -> thread_next = thread_list_ptr -> thread_next;
2680 }
2681 thread_list_ptr -> thread_received_message = packet_ptr;
2682 *thread_list_pptr = thread_list_ptr;
2683 return(NX_AZURE_IOT_SUCCESS);
2684 }
2685
2686 thread_list_prev = thread_list_ptr;
2687 }
2688
2689 return(NX_AZURE_IOT_NOT_FOUND);
2690 }
2691
nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,ULONG topic_offset,USHORT topic_length)2692 static UINT nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2693 NX_PACKET *packet_ptr,
2694 ULONG topic_offset,
2695 USHORT topic_length)
2696 {
2697 UCHAR *topic_name;
2698 az_iot_hub_client_c2d_request request;
2699 az_span receive_topic;
2700 az_result core_result;
2701 UINT status;
2702 NX_AZURE_IOT_THREAD *thread_list_ptr;
2703
2704 /* This function is protected by MQTT mutex. */
2705
2706 /* Check message type first. */
2707 topic_name = &(packet_ptr -> nx_packet_prepend_ptr[topic_offset]);
2708
2709 /* NOTE: Current implementation does not support topic to span multiple packets. */
2710 if ((ULONG)(packet_ptr -> nx_packet_append_ptr - topic_name) < topic_length)
2711 {
2712 LogError(LogLiteralArgs("topic out of boundaries of single packet"));
2713 return(NX_AZURE_IOT_TOPIC_TOO_LONG);
2714 }
2715
2716 receive_topic = az_span_create(topic_name, topic_length);
2717 core_result = az_iot_hub_client_c2d_parse_received_topic(&hub_client_ptr -> iot_hub_client_core,
2718 receive_topic, &request);
2719 if (az_result_failed(core_result))
2720 {
2721
2722 /* Topic name does not match C2D format. */
2723 return(NX_AZURE_IOT_NOT_FOUND);
2724 }
2725
2726 status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
2727 packet_ptr,
2728 NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
2729 0, &thread_list_ptr);
2730 if (status == NX_AZURE_IOT_SUCCESS)
2731 {
2732 tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
2733 return(NX_AZURE_IOT_SUCCESS);
2734 }
2735
2736 /* No thread is waiting for C2D message yet. */
2737 nx_azure_iot_hub_client_message_notify(hub_client_ptr,
2738 &(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message),
2739 packet_ptr);
2740
2741 return(NX_AZURE_IOT_SUCCESS);
2742 }
2743
nx_azure_iot_hub_client_command_process(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,ULONG topic_offset,USHORT topic_length)2744 static UINT nx_azure_iot_hub_client_command_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2745 NX_PACKET *packet_ptr,
2746 ULONG topic_offset,
2747 USHORT topic_length)
2748 {
2749 UCHAR *topic_name;
2750 az_iot_hub_client_command_request request;
2751 az_span receive_topic;
2752 az_result core_result;
2753 UINT status;
2754 NX_AZURE_IOT_THREAD *thread_list_ptr;
2755
2756 /* This function is protected by MQTT mutex. */
2757
2758 /* Check message type first. */
2759 topic_name = &(packet_ptr -> nx_packet_prepend_ptr[topic_offset]);
2760
2761 /* NOTE: Current implementation does not support topic to span multiple packets. */
2762 if ((ULONG)(packet_ptr -> nx_packet_append_ptr - topic_name) < topic_length)
2763 {
2764 LogError(LogLiteralArgs("topic out of boundaries of single packet"));
2765 return(NX_AZURE_IOT_TOPIC_TOO_LONG);
2766 }
2767
2768 receive_topic = az_span_create(topic_name, topic_length);
2769 core_result = az_iot_hub_client_commands_parse_received_topic(&(hub_client_ptr -> iot_hub_client_core),
2770 receive_topic, &request);
2771 if (az_result_failed(core_result))
2772 {
2773
2774 /* Topic name does not match direct method format. */
2775 return(NX_AZURE_IOT_NOT_FOUND);
2776 }
2777
2778 status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
2779 packet_ptr,
2780 NX_AZURE_IOT_HUB_COMMAND,
2781 0, &thread_list_ptr);
2782 if (status == NX_AZURE_IOT_SUCCESS)
2783 {
2784 tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
2785 return(NX_AZURE_IOT_SUCCESS);
2786 }
2787
2788 /* No thread is waiting for direct method message yet. */
2789 nx_azure_iot_hub_client_message_notify(hub_client_ptr,
2790 &(hub_client_ptr -> nx_azure_iot_hub_client_command_message),
2791 packet_ptr);
2792 return(NX_AZURE_IOT_SUCCESS);
2793 }
2794
nx_azure_iot_hub_client_properties_message_type_get(UINT core_message_type,UINT request_id)2795 static UINT nx_azure_iot_hub_client_properties_message_type_get(UINT core_message_type, UINT request_id)
2796 {
2797 UINT message_type;
2798
2799 switch (core_message_type)
2800 {
2801 case AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_GET_RESPONSE :
2802
2803 /* Fall through. */
2804
2805 case AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_ACKNOWLEDGEMENT :
2806 {
2807
2808 /* Odd requests are of reported properties and even of twin properties. */
2809 message_type = request_id % 2 == 0 ? NX_AZURE_IOT_HUB_PROPERTIES : NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE;
2810 }
2811 break;
2812
2813 case AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_WRITABLE_UPDATED :
2814 {
2815 message_type = NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES;
2816 }
2817 break;
2818
2819 default :
2820 {
2821 message_type = NX_AZURE_IOT_HUB_NONE;
2822 }
2823 }
2824
2825 return message_type;
2826 }
2827
nx_azure_iot_hub_client_device_twin_parse(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,ULONG topic_offset,USHORT topic_length,UINT * request_id_ptr,ULONG * version_ptr,UINT * message_type_ptr,UINT * status_ptr)2828 static UINT nx_azure_iot_hub_client_device_twin_parse(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2829 NX_PACKET *packet_ptr, ULONG topic_offset,
2830 USHORT topic_length, UINT *request_id_ptr,
2831 ULONG *version_ptr, UINT *message_type_ptr,
2832 UINT *status_ptr)
2833 {
2834 az_result core_result;
2835 az_span topic_span;
2836 az_iot_hub_client_twin_response out_twin_response;
2837 uint32_t request_id = 0;
2838 uint32_t version;
2839
2840 topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), (INT)topic_length);
2841 core_result = az_iot_hub_client_twin_parse_received_topic(&(hub_client_ptr -> iot_hub_client_core),
2842 topic_span, &out_twin_response);
2843 if (az_result_failed(core_result))
2844 {
2845 return(NX_AZURE_IOT_SDK_CORE_ERROR);
2846 }
2847
2848 if (version_ptr != NX_NULL && az_span_ptr(out_twin_response.version))
2849 {
2850 core_result = az_span_atou32(out_twin_response.version, &version);
2851 if (az_result_failed(core_result))
2852 {
2853 return(NX_AZURE_IOT_SDK_CORE_ERROR);
2854 }
2855
2856 *version_ptr = (ULONG)version;
2857 }
2858
2859 if (az_span_ptr(out_twin_response.request_id))
2860 {
2861 core_result = az_span_atou32(out_twin_response.request_id, &request_id);
2862 if (az_result_failed(core_result))
2863 {
2864 return(NX_AZURE_IOT_SDK_CORE_ERROR);
2865 }
2866 }
2867
2868 if (request_id_ptr)
2869 {
2870 *request_id_ptr = (UINT)request_id;
2871 }
2872
2873 if (message_type_ptr)
2874 {
2875 *message_type_ptr = nx_azure_iot_hub_client_properties_message_type_get((UINT)out_twin_response.response_type,
2876 (UINT)request_id);
2877 }
2878
2879 if (status_ptr)
2880 {
2881 *status_ptr = (UINT)out_twin_response.status;
2882 }
2883
2884 return(NX_AZURE_IOT_SUCCESS);
2885 }
2886
nx_azure_iot_hub_client_properties_process(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_PACKET * packet_ptr,ULONG topic_offset,USHORT topic_length)2887 static UINT nx_azure_iot_hub_client_properties_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
2888 NX_PACKET *packet_ptr,
2889 ULONG topic_offset,
2890 USHORT topic_length)
2891 {
2892 NX_AZURE_IOT_THREAD *thread_list_ptr;
2893 UINT message_type;
2894 UINT response_status;
2895 UINT request_id = 0;
2896 ULONG version = 0;
2897 UINT correlation_id;
2898 UINT status;
2899 ULONG current_time;
2900
2901 /* This function is protected by MQTT mutex. */
2902 if ((status = nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr, packet_ptr,
2903 topic_offset, topic_length,
2904 &request_id, &version,
2905 &message_type, &response_status)))
2906 {
2907 return(status);
2908 }
2909
2910 if (response_status == NX_AZURE_IOT_HUB_CLIENT_THROTTLE_STATUS_CODE)
2911 {
2912 if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, ¤t_time)))
2913 {
2914 LogError(LogLiteralArgs("IoTHub client fail to get unix time: %d"), status);
2915 return(status);
2916 }
2917
2918 hub_client_ptr -> nx_azure_iot_hub_client_throttle_end_time =
2919 current_time + nx_azure_iot_hub_client_throttle_with_jitter(hub_client_ptr);
2920 }
2921 else
2922 {
2923 hub_client_ptr -> nx_azure_iot_hub_client_throttle_count = 0;
2924 hub_client_ptr -> nx_azure_iot_hub_client_throttle_end_time = 0;
2925 }
2926
2927 if (message_type == NX_AZURE_IOT_HUB_NONE)
2928 {
2929 LogError(LogLiteralArgs("IoTHub client fail to parse device twin: %d"), NX_AZURE_IOT_SERVER_RESPONSE_ERROR);
2930 return(NX_AZURE_IOT_SERVER_RESPONSE_ERROR);
2931 }
2932 else if (message_type == NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE)
2933 {
2934
2935 /* Only requested thread should be woken. */
2936 correlation_id = request_id;
2937 }
2938 else
2939 {
2940
2941 /* Any thread can be woken. */
2942 correlation_id = 0;
2943
2944 /* Process system component. */
2945 if ((hub_client_ptr -> nx_azure_iot_hub_client_component_properties_process) &&
2946 ((response_status >= 200) && (response_status < 300)))
2947 {
2948 hub_client_ptr -> nx_azure_iot_hub_client_component_properties_process(hub_client_ptr, packet_ptr, message_type);
2949 }
2950 }
2951
2952 status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
2953 packet_ptr,
2954 message_type,
2955 correlation_id, &thread_list_ptr);
2956 if (status == NX_AZURE_IOT_SUCCESS)
2957 {
2958 tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
2959 return(NX_AZURE_IOT_SUCCESS);
2960 }
2961
2962 switch(message_type)
2963 {
2964 case NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE :
2965 {
2966 if (hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback)
2967 {
2968 hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback(hub_client_ptr,
2969 request_id,
2970 response_status,
2971 version,
2972 hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback_args);
2973 }
2974
2975 nx_packet_release(packet_ptr);
2976 }
2977 break;
2978
2979 case NX_AZURE_IOT_HUB_PROPERTIES :
2980 {
2981
2982 /* No thread is waiting for device twin message yet. */
2983 nx_azure_iot_hub_client_message_notify(hub_client_ptr,
2984 &(hub_client_ptr -> nx_azure_iot_hub_client_properties_message),
2985 packet_ptr);
2986 }
2987 break;
2988
2989 case NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES :
2990 {
2991
2992 /* No thread is waiting for device twin message yet. */
2993 nx_azure_iot_hub_client_message_notify(hub_client_ptr,
2994 &(hub_client_ptr -> nx_azure_iot_hub_client_writable_properties_message),
2995 packet_ptr);
2996 }
2997 break;
2998
2999 default :
3000 nx_packet_release(packet_ptr);
3001 }
3002
3003 return(NX_AZURE_IOT_SUCCESS);
3004 }
3005
nx_azure_iot_hub_client_thread_dequeue(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,NX_AZURE_IOT_THREAD * thread_list_ptr)3006 static VOID nx_azure_iot_hub_client_thread_dequeue(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3007 NX_AZURE_IOT_THREAD *thread_list_ptr)
3008 {
3009 NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
3010 NX_AZURE_IOT_THREAD *thread_list_current;
3011
3012 for (thread_list_current = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
3013 thread_list_current;
3014 thread_list_current = thread_list_current -> thread_next)
3015 {
3016 if (thread_list_current == thread_list_ptr)
3017 {
3018
3019 /* Found the thread to dequeue. */
3020 if (thread_list_prev == NX_NULL)
3021 {
3022 hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = thread_list_current -> thread_next;
3023 }
3024 else
3025 {
3026 thread_list_prev -> thread_next = thread_list_current -> thread_next;
3027 }
3028 break;
3029 }
3030
3031 thread_list_prev = thread_list_current;
3032 }
3033 }
3034
nx_azure_iot_hub_client_sas_token_get(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,ULONG expiry_time_secs,const UCHAR * key,UINT key_len,UCHAR * sas_buffer,UINT sas_buffer_len,UINT * sas_length)3035 static UINT nx_azure_iot_hub_client_sas_token_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3036 ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
3037 UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length)
3038 {
3039 UCHAR *buffer_ptr;
3040 UINT buffer_size;
3041 VOID *buffer_context;
3042 az_span span = az_span_create(sas_buffer, (INT)sas_buffer_len);
3043 az_span buffer_span;
3044 UINT status;
3045 UCHAR *output_ptr;
3046 UINT output_len;
3047 az_result core_result;
3048
3049 status = nx_azure_iot_buffer_allocate(hub_client_ptr -> nx_azure_iot_ptr, &buffer_ptr, &buffer_size, &buffer_context);
3050 if (status)
3051 {
3052 LogError(LogLiteralArgs("IoTHub client sas token fail: BUFFER ALLOCATE FAIL"));
3053 return(status);
3054 }
3055
3056 core_result = az_iot_hub_client_sas_get_signature(&(hub_client_ptr -> iot_hub_client_core),
3057 expiry_time_secs, span, &span);
3058 if (az_result_failed(core_result))
3059 {
3060 LogError(LogLiteralArgs("IoTHub failed failed to get signature with error status: %d"), core_result);
3061 nx_azure_iot_buffer_free(buffer_context);
3062 return(NX_AZURE_IOT_SDK_CORE_ERROR);
3063 }
3064
3065 status = nx_azure_iot_base64_hmac_sha256_calculate(&(hub_client_ptr -> nx_azure_iot_hub_client_resource),
3066 key, key_len, az_span_ptr(span), (UINT)az_span_size(span),
3067 buffer_ptr, buffer_size, &output_ptr, &output_len);
3068 if (status)
3069 {
3070 LogError(LogLiteralArgs("IoTHub failed to encoded hash"));
3071 nx_azure_iot_buffer_free(buffer_context);
3072 return(status);
3073 }
3074
3075 buffer_span = az_span_create(output_ptr, (INT)output_len);
3076 core_result= az_iot_hub_client_sas_get_password(&(hub_client_ptr -> iot_hub_client_core),
3077 expiry_time_secs, buffer_span, AZ_SPAN_EMPTY,
3078 (CHAR *)sas_buffer, sas_buffer_len, (size_t *)&sas_buffer_len);
3079 if (az_result_failed(core_result))
3080 {
3081 LogError(LogLiteralArgs("IoTHub failed to generate token with error status: %d"), core_result);
3082 nx_azure_iot_buffer_free(buffer_context);
3083 return(NX_AZURE_IOT_SDK_CORE_ERROR);
3084 }
3085
3086 *sas_length = sas_buffer_len;
3087 nx_azure_iot_buffer_free(buffer_context);
3088
3089 return(NX_AZURE_IOT_SUCCESS);
3090 }
3091
nx_azure_iot_hub_client_command_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)3092 UINT nx_azure_iot_hub_client_command_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
3093 {
3094 UINT status;
3095
3096 if (hub_client_ptr == NX_NULL)
3097 {
3098 LogError(LogLiteralArgs("IoTHub client command subscribe fail: INVALID POINTER"));
3099 return(NX_AZURE_IOT_INVALID_PARAMETER);
3100 }
3101
3102 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
3103
3104 /* Atomically update the handler as we need to serialize the handler with incoming messages. */
3105 hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_process = nx_azure_iot_hub_client_command_process;
3106 hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_enable = nx_azure_iot_hub_client_command_enable;
3107
3108 /* Register callbacks even if not connect and when connect complete subscribe for topics. */
3109 if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
3110 {
3111 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
3112 return(NX_AZURE_IOT_SUCCESS);
3113 }
3114
3115 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
3116
3117 status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
3118 AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC,
3119 sizeof(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC) - 1,
3120 NX_AZURE_IOT_MQTT_QOS_0);
3121 if (status)
3122 {
3123 LogError(LogLiteralArgs("IoTHub client command subscribe fail %d"), status);
3124 return(status);
3125 }
3126
3127 return(NX_AZURE_IOT_SUCCESS);
3128 }
3129
nx_azure_iot_hub_client_command_disable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)3130 UINT nx_azure_iot_hub_client_command_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
3131 {
3132 UINT status;
3133
3134 if (hub_client_ptr == NX_NULL)
3135 {
3136 LogError(LogLiteralArgs("IoTHub client command unsubscribe fail: INVALID POINTER"));
3137 return(NX_AZURE_IOT_INVALID_PARAMETER);
3138 }
3139
3140 status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
3141 AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC,
3142 sizeof(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC) - 1);
3143 if (status)
3144 {
3145 LogError(LogLiteralArgs("IoTHub client command unsubscribe fail status: %d"), status);
3146 return(status);
3147 }
3148
3149 hub_client_ptr -> nx_azure_iot_hub_client_command_message.message_process = NX_NULL;
3150
3151 return(NX_AZURE_IOT_SUCCESS);
3152 }
3153
nx_azure_iot_hub_client_command_message_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR ** component_name_pptr,USHORT * component_name_length_ptr,const UCHAR ** command_name_pptr,USHORT * command_name_length_ptr,VOID ** context_pptr,USHORT * context_length_ptr,NX_PACKET ** packet_pptr,UINT wait_option)3154 UINT nx_azure_iot_hub_client_command_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3155 const UCHAR **component_name_pptr, USHORT *component_name_length_ptr,
3156 const UCHAR **command_name_pptr, USHORT *command_name_length_ptr,
3157 VOID **context_pptr, USHORT *context_length_ptr,
3158 NX_PACKET **packet_pptr, UINT wait_option)
3159 {
3160
3161 UINT status;
3162 ULONG topic_offset = 0;
3163 USHORT topic_length = 0;
3164 az_span topic_span;
3165 NX_PACKET *packet_ptr = NX_NULL;
3166 az_result core_result;
3167 az_iot_hub_client_command_request request;
3168
3169 if ((hub_client_ptr == NX_NULL) ||
3170 (command_name_pptr == NX_NULL) ||
3171 (command_name_length_ptr == NX_NULL) ||
3172 (context_pptr == NX_NULL) ||
3173 (context_length_ptr == NX_NULL) ||
3174 (packet_pptr == NX_NULL))
3175 {
3176 LogError(LogLiteralArgs("IoT PnP client command receive fail: INVALID POINTER"));
3177 return(NX_AZURE_IOT_INVALID_PARAMETER);
3178 }
3179
3180 status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_COMMAND,
3181 &(hub_client_ptr -> nx_azure_iot_hub_client_command_message),
3182 &packet_ptr, wait_option);
3183 if (status)
3184 {
3185 return(status);
3186 }
3187
3188 status = nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset, &topic_length);
3189 if (status)
3190 {
3191 nx_packet_release(packet_ptr);
3192 return(status);
3193 }
3194
3195 topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), topic_length);
3196 core_result = az_iot_hub_client_commands_parse_received_topic(&(hub_client_ptr -> iot_hub_client_core),
3197 topic_span, &request);
3198 if (az_result_failed(core_result))
3199 {
3200 nx_packet_release(packet_ptr);
3201 return(NX_AZURE_IOT_SDK_CORE_ERROR);
3202 }
3203
3204 if ((status = nx_azure_iot_hub_client_adjust_payload(packet_ptr)))
3205 {
3206 nx_packet_release(packet_ptr);
3207 return(status);
3208 }
3209
3210 *packet_pptr = packet_ptr;
3211 if ((component_name_pptr) && (component_name_length_ptr))
3212 {
3213 *component_name_pptr = (const UCHAR *)az_span_ptr(request.component_name);
3214 *component_name_length_ptr = (USHORT)az_span_size(request.component_name);
3215 }
3216 *command_name_pptr = (const UCHAR *)az_span_ptr(request.command_name);
3217 *command_name_length_ptr = (USHORT)az_span_size(request.command_name);
3218 *context_pptr = (VOID*)az_span_ptr(request.request_id);
3219 *context_length_ptr = (USHORT)az_span_size(request.request_id);
3220
3221 return(NX_AZURE_IOT_SUCCESS);
3222 }
3223
nx_azure_iot_hub_client_command_message_response(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT status_code,VOID * context_ptr,USHORT context_length,const UCHAR * payload,UINT payload_length,UINT wait_option)3224 UINT nx_azure_iot_hub_client_command_message_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3225 UINT status_code, VOID *context_ptr,
3226 USHORT context_length, const UCHAR *payload,
3227 UINT payload_length, UINT wait_option)
3228 {
3229 NX_PACKET *packet_ptr;
3230 UINT topic_length;
3231 az_span request_id_span;
3232 UINT status;
3233 az_result core_result;
3234
3235 if ((hub_client_ptr == NX_NULL) ||
3236 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
3237 (context_ptr == NX_NULL) ||
3238 (context_length == 0))
3239 {
3240 LogError(LogLiteralArgs("IoTHub client command response fail: INVALID POINTER"));
3241 return(NX_AZURE_IOT_INVALID_PARAMETER);
3242 }
3243
3244 /* Prepare response packet. */
3245 status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
3246 &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
3247 &packet_ptr, wait_option);
3248 if (status)
3249 {
3250 LogError(LogLiteralArgs("Create response data fail"));
3251 return(status);
3252 }
3253
3254 topic_length = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
3255 request_id_span = az_span_create((UCHAR*)context_ptr, (INT)context_length);
3256 core_result = az_iot_hub_client_commands_response_get_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
3257 request_id_span, (USHORT)status_code,
3258 (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
3259 topic_length, (size_t *)&topic_length);
3260 if (az_result_failed(core_result))
3261 {
3262 LogError(LogLiteralArgs("Failed to create the command response topic"));
3263 nx_packet_release(packet_ptr);
3264 return(NX_AZURE_IOT_SDK_CORE_ERROR);
3265 }
3266
3267 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
3268 packet_ptr -> nx_packet_length = topic_length;
3269
3270 if (payload && (payload_length != 0))
3271 {
3272
3273 /* Append payload. */
3274 status = nx_packet_data_append(packet_ptr, (VOID *)payload, payload_length,
3275 packet_ptr -> nx_packet_pool_owner,
3276 wait_option);
3277 if (status)
3278 {
3279 LogError(LogLiteralArgs("Command response data append fail"));
3280 nx_packet_release(packet_ptr);
3281 return(status);
3282 }
3283 }
3284 else
3285 {
3286
3287 /* Append payload. */
3288 status = nx_packet_data_append(packet_ptr, NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON,
3289 sizeof(NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON) - 1,
3290 packet_ptr -> nx_packet_pool_owner,
3291 wait_option);
3292 if (status)
3293 {
3294 LogError(LogLiteralArgs("Adding empty json failed."));
3295 nx_packet_release(packet_ptr);
3296 return(status);
3297 }
3298 }
3299
3300 status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
3301 packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
3302 wait_option);
3303 if (status)
3304 {
3305 LogError(LogLiteralArgs("IoTHub client command response fail: PUBLISH FAIL status: %d"), status);
3306 nx_packet_release(packet_ptr);
3307 return(status);
3308 }
3309
3310 return(NX_AZURE_IOT_SUCCESS);
3311 }
3312
nx_azure_iot_hub_client_direct_method_enable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)3313 UINT nx_azure_iot_hub_client_direct_method_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
3314 {
3315
3316 if (hub_client_ptr == NX_NULL)
3317 {
3318 LogError(LogLiteralArgs("IoTHub client direct method subscribe fail: INVALID POINTER"));
3319 return(NX_AZURE_IOT_INVALID_PARAMETER);
3320 }
3321
3322 return(nx_azure_iot_hub_client_command_enable(hub_client_ptr));
3323 }
3324
nx_azure_iot_hub_client_direct_method_disable(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)3325 UINT nx_azure_iot_hub_client_direct_method_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
3326 {
3327
3328 if (hub_client_ptr == NX_NULL)
3329 {
3330 LogError(LogLiteralArgs("IoTHub client direct method unsubscribe fail: INVALID POINTER"));
3331 return(NX_AZURE_IOT_INVALID_PARAMETER);
3332 }
3333
3334 return(nx_azure_iot_hub_client_command_disable(hub_client_ptr));
3335 }
3336
nx_azure_iot_hub_client_direct_method_message_receive(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR ** method_name_pptr,USHORT * method_name_length_ptr,VOID ** context_pptr,USHORT * context_length_ptr,NX_PACKET ** packet_pptr,UINT wait_option)3337 UINT nx_azure_iot_hub_client_direct_method_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3338 const UCHAR **method_name_pptr, USHORT *method_name_length_ptr,
3339 VOID **context_pptr, USHORT *context_length_ptr,
3340 NX_PACKET **packet_pptr, UINT wait_option)
3341 {
3342
3343 if ((hub_client_ptr == NX_NULL) ||
3344 (method_name_pptr == NX_NULL) ||
3345 (method_name_length_ptr == NX_NULL) ||
3346 (context_pptr == NX_NULL) ||
3347 (context_length_ptr == NX_NULL) ||
3348 (packet_pptr == NX_NULL))
3349 {
3350 LogError(LogLiteralArgs("IoTHub client direct method receive fail: INVALID POINTER"));
3351 return(NX_AZURE_IOT_INVALID_PARAMETER);
3352 }
3353
3354 return(nx_azure_iot_hub_client_command_message_receive(hub_client_ptr, NX_NULL, NX_NULL,
3355 method_name_pptr, method_name_length_ptr,
3356 context_pptr, context_length_ptr,
3357 packet_pptr, wait_option));
3358 }
3359
nx_azure_iot_hub_client_direct_method_message_response(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT status_code,VOID * context_ptr,USHORT context_length,const UCHAR * payload,UINT payload_length,UINT wait_option)3360 UINT nx_azure_iot_hub_client_direct_method_message_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
3361 UINT status_code, VOID *context_ptr,
3362 USHORT context_length, const UCHAR *payload,
3363 UINT payload_length, UINT wait_option)
3364 {
3365
3366 if ((hub_client_ptr == NX_NULL) ||
3367 (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
3368 (context_ptr == NX_NULL) ||
3369 (context_length == 0))
3370 {
3371 LogError(LogLiteralArgs("IoTHub direct method response fail: INVALID POINTER"));
3372 return(NX_AZURE_IOT_INVALID_PARAMETER);
3373 }
3374
3375 return(nx_azure_iot_hub_client_command_message_response(hub_client_ptr, status_code,
3376 context_ptr, context_length,
3377 payload, payload_length,
3378 wait_option));
3379 }
3380