summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--addons/CMakeLists.txt2
m---------addons/azure_iot/azure-sdk-for-c0
-rw-r--r--addons/azure_iot/azure_iot_security_module/nx_azure_iot_security_module.c4
-rw-r--r--addons/azure_iot/nx_azure_iot.c65
-rw-r--r--addons/azure_iot/nx_azure_iot.h19
-rw-r--r--addons/azure_iot/nx_azure_iot_hub_client.c1912
-rw-r--r--addons/azure_iot/nx_azure_iot_hub_client.h79
-rw-r--r--addons/azure_iot/nx_azure_iot_hub_transport.c1439
-rw-r--r--addons/azure_iot/nx_azure_iot_hub_transport.h216
-rw-r--r--addons/azure_iot/nx_azure_iot_json_reader.c68
-rw-r--r--addons/azure_iot/nx_azure_iot_json_reader.h6
-rw-r--r--addons/azure_iot/nx_azure_iot_json_writer.c6
-rw-r--r--addons/azure_iot/nx_azure_iot_json_writer.h3
-rw-r--r--addons/azure_iot/nx_azure_iot_pnp_client.c1588
-rw-r--r--addons/azure_iot/nx_azure_iot_pnp_client.h677
-rw-r--r--addons/azure_iot/nx_azure_iot_provisioning_client.c2
-rw-r--r--addons/azure_iot/nx_azure_iot_provisioning_client.h2
-rw-r--r--addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.c443
-rw-r--r--addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.h125
-rw-r--r--addons/azure_iot/samples/sample_azure_iot_embedded_sdk_pnp.c503
-rw-r--r--addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.c58
-rw-r--r--addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.h4
-rw-r--r--addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_temperature_controller.c521
-rw-r--r--addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.c183
-rw-r--r--addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.h14
26 files changed, 4946 insertions, 2995 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68d3c8be..3f74c006 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,7 +29,7 @@ endif()
if(NXD_ENABLE_AZURE_IOT)
message(STATUS "NXD_ENABLE_AZURE_IOT - defined")
- target_link_libraries(${PROJECT_NAME} PUBLIC az_iot_hub az_iot_provisioning)
+ target_link_libraries(${PROJECT_NAME} PUBLIC az_iot_pnp az_iot_hub az_iot_provisioning)
if(NOT NX_AZURE_DISABLE_IOT_SECURITY_MODULE)
target_link_libraries(${PROJECT_NAME} PUBLIC iot_security_module)
endif()
diff --git a/addons/CMakeLists.txt b/addons/CMakeLists.txt
index cfe60389..941cb38a 100644
--- a/addons/CMakeLists.txt
+++ b/addons/CMakeLists.txt
@@ -52,6 +52,8 @@ if(NXD_ENABLE_AZURE_IOT)
${CMAKE_CURRENT_LIST_DIR}/azure_iot/nx_azure_iot_json_reader.c
${CMAKE_CURRENT_LIST_DIR}/azure_iot/nx_azure_iot_json_writer.c
${CMAKE_CURRENT_LIST_DIR}/azure_iot/nx_azure_iot_provisioning_client.c
+ ${CMAKE_CURRENT_LIST_DIR}/azure_iot/nx_azure_iot_pnp_client.c
+ ${CMAKE_CURRENT_LIST_DIR}/azure_iot/nx_azure_iot_hub_transport.c
)
set(ENV{AZ_SDK_C_NO_SAMPLES} TRUE)
set(NX_AZURE_DISABLE_IOT_SECURITY_MODULE OFF CACHE BOOL "Disable Azure IoT Security Module (default is OFF)")
diff --git a/addons/azure_iot/azure-sdk-for-c b/addons/azure_iot/azure-sdk-for-c
-Subproject 5e9d7b96dbd98ce7125e4beed385959a32b4c6c
+Subproject c305408ce67e98e1417bb7518ae2743b8c397ec
diff --git a/addons/azure_iot/azure_iot_security_module/nx_azure_iot_security_module.c b/addons/azure_iot/azure_iot_security_module/nx_azure_iot_security_module.c
index 9e44ac83..c71225d7 100644
--- a/addons/azure_iot/azure_iot_security_module/nx_azure_iot_security_module.c
+++ b/addons/azure_iot/azure_iot_security_module/nx_azure_iot_security_module.c
@@ -346,7 +346,7 @@ NX_AZURE_IOT_RESOURCE *resource_ptr;
NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource_ptr->resource_data_ptr;
/* Filter only connected IoT Hubs. */
- if (hub_client_ptr->nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
+ if (hub_client_ptr->nx_azure_iot_hub_client_transport.nx_azure_iot_hub_transport_state == NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
{
exists_connected_iot_hub = true;
@@ -583,7 +583,7 @@ NX_AZURE_IOT_RESOURCE *resource_ptr;
NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource_ptr->resource_data_ptr;
/* Check IoT Hub client connectivity. */
- if (hub_client_ptr->nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
+ if (hub_client_ptr->nx_azure_iot_hub_client_transport.nx_azure_iot_hub_transport_state == NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
{
return true;
}
diff --git a/addons/azure_iot/nx_azure_iot.c b/addons/azure_iot/nx_azure_iot.c
index 698ed5b0..677d4ed7 100644
--- a/addons/azure_iot/nx_azure_iot.c
+++ b/addons/azure_iot/nx_azure_iot.c
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
#include "nx_azure_iot.h"
#ifndef NX_AZURE_DISABLE_IOT_SECURITY_MODULE
@@ -170,14 +170,6 @@ static VOID nx_azure_iot_log_listener(az_log_classification classification, az_s
VOID nx_azure_iot_log_init(VOID(*log_callback)(az_log_classification classification, UCHAR *msg, UINT msg_len))
{
-static az_log_classification const classifications[] = {AZ_LOG_IOT_AZURERTOS,
- AZ_LOG_MQTT_RECEIVED_TOPIC,
- AZ_LOG_MQTT_RECEIVED_PAYLOAD,
- AZ_LOG_IOT_RETRY,
- AZ_LOG_IOT_SAS_TOKEN,
- _az_LOG_END_OF_LIST};
-
- _az_log_set_classifications(classifications);
_nx_azure_iot_log_callback = log_callback;
az_log_set_message_callback(nx_azure_iot_log_listener);
}
@@ -1026,3 +1018,58 @@ UINT binary_key_buf_size;
return(NX_AZURE_IOT_SUCCESS);
}
+
+UINT nx_azure_iot_topic_property_append(NX_PACKET *packet_ptr,
+ const UCHAR *property_name, USHORT property_name_length,
+ const UCHAR *property_value, USHORT property_value_length,
+ UINT wait_option)
+{
+UINT status;
+
+ if ((packet_ptr == NX_NULL) ||
+ (property_name == NX_NULL) ||
+ (property_value == NX_NULL))
+ {
+ LogError(LogLiteralArgs("Property append failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if (*(packet_ptr -> nx_packet_append_ptr - 1) != '/')
+ {
+ status = nx_packet_data_append(packet_ptr, "&", 1,
+ packet_ptr -> nx_packet_pool_owner,
+ wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Property append of & failed"));
+ return(status);
+ }
+ }
+
+ status = nx_packet_data_append(packet_ptr, (VOID *)property_name, (UINT)property_name_length,
+ packet_ptr -> nx_packet_pool_owner, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Property name append failed"));
+ return(status);
+ }
+
+ status = nx_packet_data_append(packet_ptr, "=", 1,
+ packet_ptr -> nx_packet_pool_owner,
+ wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Property append of = failed"));
+ return(status);
+ }
+
+ status = nx_packet_data_append(packet_ptr, (VOID *)property_value, (UINT)property_value_length,
+ packet_ptr -> nx_packet_pool_owner, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Property value append failed"));
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
diff --git a/addons/azure_iot/nx_azure_iot.h b/addons/azure_iot/nx_azure_iot.h
index d4229d2f..fa0a00a6 100644
--- a/addons/azure_iot/nx_azure_iot.h
+++ b/addons/azure_iot/nx_azure_iot.h
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
/**
* @file nx_azure_iot.h
@@ -128,9 +128,12 @@ UINT nx_azure_iot_log(UCHAR *type_ptr, UINT type_len, UCHAR *msg_ptr, UINT msg_l
#define NX_AZURE_IOT_NO_SUBSCRIBE_ACK 0x20014
#define NX_AZURE_IOT_THROTTLED 0x20015
+#define NX_AZURE_IOT_EMPTY_JSON 0x20016
+
/* Resource type managed by AZ_IOT. */
#define NX_AZURE_IOT_RESOURCE_IOT_HUB 0x1
#define NX_AZURE_IOT_RESOURCE_IOT_PROVISIONING 0x2
+#define NX_AZURE_IOT_RESOURCE_IOT_PNP 0x3
/* Define the packet buffer for THREADX TLS. */
#ifndef NX_AZURE_IOT_TLS_PACKET_BUFFER_SIZE
@@ -198,6 +201,15 @@ typedef struct NX_AZURE_IOT_STRUCT
UINT (*nx_azure_iot_unix_time_get)(ULONG *unix_time);
} NX_AZURE_IOT;
+typedef struct NX_AZURE_IOT_THREAD_STRUCT
+{
+ TX_THREAD *thread_ptr;
+ struct NX_AZURE_IOT_THREAD_STRUCT *thread_next;
+ UINT thread_message_type;
+ UINT thread_expected_id; /* Used by device twin. */
+ NX_PACKET *thread_received_message;
+} NX_AZURE_IOT_THREAD;
+
/**
* @brief Create the Azure IoT subsystem
*
@@ -297,7 +309,10 @@ UINT nx_azure_iot_base64_hmac_sha256_calculate(NX_AZURE_IOT_RESOURCE *resource_p
const UCHAR *message_ptr, UINT message_size,
UCHAR *buffer_ptr, UINT buffer_len,
UCHAR **output_ptr, UINT *output_len_ptr);
-
+UINT nx_azure_iot_topic_property_append(NX_PACKET *packet_ptr,
+ const UCHAR *property_name, USHORT property_name_length,
+ const UCHAR *property_value, USHORT property_value_length,
+ UINT wait_option);
#ifdef __cplusplus
}
diff --git a/addons/azure_iot/nx_azure_iot_hub_client.c b/addons/azure_iot/nx_azure_iot_hub_client.c
index 3cdff666..752c2626 100644
--- a/addons/azure_iot/nx_azure_iot_hub_client.c
+++ b/addons/azure_iot/nx_azure_iot_hub_client.c
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
#include "nx_azure_iot_hub_client.h"
@@ -32,36 +32,23 @@
NX_AZURE_IOT_HUB_CLIENT_TO_STR(THREADX_MINOR_VERSION) "%29"
#endif /* NX_AZURE_IOT_HUB_CLIENT_USER_AGENT */
-static VOID nx_azure_iot_hub_client_received_message_cleanup(NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *message);
-static UINT nx_azure_iot_hub_client_cloud_message_sub_unsub(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- UINT is_subscribe);
-static UINT nx_azure_iot_hub_client_process_publish_packet(UCHAR *start_ptr,
- ULONG *topic_offset_ptr,
- USHORT *topic_length_ptr);
-static VOID nx_azure_iot_hub_client_mqtt_receive_callback(NXD_MQTT_CLIENT* client_ptr,
- UINT number_of_messages);
-static UINT 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);
-static UINT nx_azure_iot_hub_client_device_twin_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_PACKET *packet_ptr,
- ULONG topic_offset,
- USHORT topic_length);
+/* Queue index used in transport to receive the messages */
+#define NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX 0
+#define NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX 1
+#define NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX 2
+#define NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES_QUEUE_INDEX 3
+#define NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX 4
+
extern UINT _nxd_mqtt_process_publish_packet(NX_PACKET *packet_ptr, ULONG *topic_offset_ptr,
USHORT *topic_length_ptr, ULONG *message_offset_ptr,
ULONG *message_length_ptr);
-static VOID nx_azure_iot_hub_client_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr,
- UINT status, VOID *context);
-static VOID nx_azure_iot_hub_client_mqtt_disconnect_notify(NXD_MQTT_CLIENT *client_ptr);
-static VOID nx_azure_iot_hub_client_thread_dequeue(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_AZURE_IOT_THREAD *thread_list_ptr);
-static UINT 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);
-static UINT nx_azure_iot_hub_client_messages_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
-static VOID nx_azure_iot_hub_client_device_twin_ack_notify(NXD_MQTT_CLIENT *client_ptr, UINT type,
- USHORT packet_id, NX_PACKET *transmit_packet_ptr, VOID *context);
+
+static UINT nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset,
+ USHORT topic_length);
+static UINT nx_azure_iot_hub_client_device_twin_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset,
+ USHORT topic_length);
static UINT 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,
@@ -106,7 +93,7 @@ UINT status = NX_AZURE_IOT_SUCCESS;
if (hub_client_ptr -> nx_azure_iot_hub_client_throttle_count != 0)
{
- if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, &current_time)))
+ if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr, &current_time)))
{
LogError(LogLiteralArgs("IoTHub client fail to get unix time: %d"), status);
return(status);
@@ -121,624 +108,303 @@ UINT status = NX_AZURE_IOT_SUCCESS;
return(status);
}
-UINT 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)
+static UINT nx_azure_iot_hub_client_mesg_type_to_queue_index(UINT message_type)
{
+UINT queue_index;
-UINT status;
-NX_AZURE_IOT_RESOURCE *resource_ptr;
-az_span hostname_span = az_span_create((UCHAR *)host_name, (INT)host_name_length);
-az_span device_id_span = az_span_create((UCHAR *)device_id, (INT)device_id_length);
-az_iot_hub_client_options options = az_iot_hub_client_options_default();
-az_result core_result;
-
- if ((nx_azure_iot_ptr == NX_NULL) || (hub_client_ptr == NX_NULL) || (host_name == NX_NULL) ||
- (device_id == NX_NULL) || (host_name_length == 0) || (device_id_length == 0))
+ switch (message_type)
{
- LogError(LogLiteralArgs("IoTHub client initialization fail: INVALID POINTER"));
- return(NX_AZURE_IOT_INVALID_PARAMETER);
- }
+ case NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE :
+ {
+ queue_index = NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX;
+ }
+ break;
- memset(hub_client_ptr, 0, sizeof(NX_AZURE_IOT_HUB_CLIENT));
+ case NX_AZURE_IOT_HUB_DIRECT_METHOD :
+ {
+ queue_index = NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX;
+ }
+ break;
- hub_client_ptr -> nx_azure_iot_ptr = nx_azure_iot_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_crypto_array = crypto_array;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_crypto_array_size = crypto_array_size;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_cipher_map = cipher_map;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_cipher_map_size = cipher_map_size;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_metadata_ptr = metadata_memory;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_metadata_size = memory_size;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_trusted_certificate = trusted_certificate;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname = host_name;
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname_length = host_name_length;
- options.module_id = az_span_create((UCHAR *)module_id, (INT)module_id_length);
- options.user_agent = AZ_SPAN_FROM_STR(NX_AZURE_IOT_HUB_CLIENT_USER_AGENT);
+ case NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES :
+ {
+ queue_index = NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX;
+ }
+ break;
- core_result = az_iot_hub_client_init(&hub_client_ptr -> iot_hub_client_core,
- hostname_span, device_id_span, &options);
- if (az_result_failed(core_result))
- {
- LogError(LogLiteralArgs("IoTHub client failed initialization with error status: %d"), core_result);
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
+ case NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES :
+ {
+ queue_index = NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES_QUEUE_INDEX;
+ }
+ break;
- /* Set resource pointer. */
- resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
+ case NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE :
+ {
+ queue_index = NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX;
+ }
+ break;
- /* Create MQTT client. */
- status = _nxd_mqtt_client_cloud_create(&(resource_ptr -> resource_mqtt),
- (CHAR *)nx_azure_iot_ptr -> nx_azure_iot_name,
- "", 0,
- nx_azure_iot_ptr -> nx_azure_iot_ip_ptr,
- nx_azure_iot_ptr -> nx_azure_iot_pool_ptr,
- &nx_azure_iot_ptr -> nx_azure_iot_cloud);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client initialization fail: MQTT CLIENT CREATE FAIL status: %d"), status);
- return(status);
+ default :
+ {
+ /* no queue */
+ queue_index = NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE;
+ }
+ break;
}
- /* Set mqtt receive notify. */
- status = nxd_mqtt_client_receive_notify_set(&(resource_ptr -> resource_mqtt),
- nx_azure_iot_hub_client_mqtt_receive_callback);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client set message callback status: %d"), status);
- nxd_mqtt_client_delete(&(resource_ptr -> resource_mqtt));
- return(status);
- }
+ return(queue_index);
+}
- /* Obtain the mutex. */
- tx_mutex_get(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+static az_result nx_azure_iot_hub_client_client_id_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
- /* Link the resource. */
- resource_ptr -> resource_data_ptr = (VOID *)hub_client_ptr;
- resource_ptr -> resource_type = NX_AZURE_IOT_RESOURCE_IOT_HUB;
- nx_azure_iot_resource_add(nx_azure_iot_ptr, resource_ptr);
+ return(az_iot_hub_client_get_client_id(&(hub_client_ptr -> iot_hub_client_core),
+ (CHAR *)buffer, buffer_len, bytes_copied));
+}
- /* Release the mutex. */
- tx_mutex_put(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+static az_result nx_azure_iot_hub_client_username_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
- return(NX_AZURE_IOT_SUCCESS);
+ return(az_iot_hub_client_get_user_name(&hub_client_ptr -> iot_hub_client_core,
+ (CHAR *)buffer, buffer_len, bytes_copied));
}
-UINT 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))
+static az_result nx_azure_iot_hub_client_signature_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span buffer, az_span *out_buffer)
{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
- /* Check for invalid input pointers. */
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
- {
- LogError(LogLiteralArgs("IoTHub client connect callback fail: INVALID POINTER"));
- return(NX_AZURE_IOT_INVALID_PARAMETER);
- }
+ return(az_iot_hub_client_sas_get_signature(&(hub_client_ptr -> iot_hub_client_core),
+ expiry_time_secs, buffer, out_buffer));
+}
- /* Set callback function for disconnection. */
- nxd_mqtt_client_disconnect_notify_set(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- nx_azure_iot_hub_client_mqtt_disconnect_notify);
+static az_result nx_azure_iot_hub_client_password_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span hash_buffer, az_span key_name,
+ UCHAR *out_buffer, UINT out_buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+ return(az_iot_hub_client_sas_get_password(&(hub_client_ptr -> iot_hub_client_core),
+ expiry_time_secs, hash_buffer, key_name,
+ (CHAR *)out_buffer, out_buffer_len, bytes_copied));
+}
- /* Set connection status callback. */
- hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback = connection_status_cb;
+static VOID nx_azure_iot_hub_client_receive_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1,
+ VOID *arg2)
+{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ ((VOID (*)(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *args))arg1)(hub_client_ptr, arg2);
+}
- /* Return success. */
- return(NX_AZURE_IOT_SUCCESS);
+static VOID nx_azure_iot_hub_client_connection_status_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT status, NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg)
+{
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+ ((VOID (*)(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status))arg)(hub_client_ptr, status);
}
-UINT nx_azure_iot_hub_client_connect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- UINT clean_session, UINT wait_option)
+static VOID nx_azure_iot_hub_client_reported_property_receive_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1,
+ VOID *arg2)
{
-UINT status;
-NXD_ADDRESS server_address;
-NX_AZURE_IOT_RESOURCE *resource_ptr;
-NXD_MQTT_CLIENT *mqtt_client_ptr;
-UCHAR *buffer_ptr;
-UINT buffer_size;
-VOID *buffer_context;
-UINT buffer_length;
-ULONG expiry_time_secs;
-az_result core_result;
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+UINT status;
+NX_PACKET *packet_ptr;
+ULONG topic_offset;
+USHORT topic_length;
+UINT request_id;
+UINT response_status;
+ULONG version = 0;
- /* Check for invalid input pointers. */
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
+ if ((status = nx_azure_iot_hub_transport_message_receive(hub_trans_ptr,
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX, 0,
+ &packet_ptr, NX_NO_WAIT)))
{
- LogError(LogLiteralArgs("IoTHub client connect fail: INVALID POINTER"));
- return(NX_AZURE_IOT_INVALID_PARAMETER);
+ LogError(LogLiteralArgs("IoTHub failed to find reported property: %d"), status);
+ return;
}
- /* Check for status. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
{
- LogError(LogLiteralArgs("IoTHub client already connected"));
- return(NX_AZURE_IOT_ALREADY_CONNECTED);
- }
- else if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING)
- {
- LogError(LogLiteralArgs("IoTHub client is connecting"));
- return(NX_AZURE_IOT_CONNECTING);
- }
- /* Resolve the host name. */
- /* Note: always using default dns timeout. */
- status = nxd_dns_host_by_name_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_dns_ptr,
- (UCHAR *)hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_hostname,
- &server_address, NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT, NX_IP_VERSION_V4);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client connect fail: DNS RESOLVE FAIL status: %d"), status);
- return(status);
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ return;
}
- /* Allocate buffer for client id, username and sas token. */
- status = nx_azure_iot_buffer_allocate(hub_client_ptr -> nx_azure_iot_ptr,
- &buffer_ptr, &buffer_size, &buffer_context);
- if (status)
+ if ((status = nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr, packet_ptr,
+ topic_offset, topic_length,
+ &request_id, &version,
+ NX_NULL, &response_status)))
{
- LogError(LogLiteralArgs("IoTHub client failed initialization: BUFFER ALLOCATE FAIL"));
- return(status);
+ nx_packet_release(packet_ptr);
+ return;
}
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Set resource pointer and buffer context. */
- resource_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource);
-
- /* Build client id. */
- buffer_length = buffer_size;
- core_result = az_iot_hub_client_get_client_id(&(hub_client_ptr -> iot_hub_client_core),
- (CHAR *)buffer_ptr, buffer_length, &buffer_length);
- if (az_result_failed(core_result))
- {
+ ((VOID (*)(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
+ UINT request_id, UINT response_status,
+ ULONG version, VOID *arg))arg1)(hub_client_ptr,
+ request_id,
+ response_status,
+ version,
+ arg2);
+ nx_packet_release(packet_ptr);
+}
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- nx_azure_iot_buffer_free(buffer_context);
- LogError(LogLiteralArgs("IoTHub client failed to get clientId with error status: "), core_result);
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
- resource_ptr -> resource_mqtt_client_id = buffer_ptr;
- resource_ptr -> resource_mqtt_client_id_length = buffer_length;
+UINT 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)
+{
- /* Update buffer for user name. */
- buffer_ptr += resource_ptr -> resource_mqtt_client_id_length;
- buffer_size -= resource_ptr -> resource_mqtt_client_id_length;
+UINT status;
+az_span hostname_span = az_span_create((UCHAR *)host_name, (INT)host_name_length);
+az_span device_id_span = az_span_create((UCHAR *)device_id, (INT)device_id_length);
+az_iot_hub_client_options options = az_iot_hub_client_options_default();
+az_result core_result;
- /* Build user name. */
- buffer_length = buffer_size;
- core_result = az_iot_hub_client_get_user_name(&hub_client_ptr -> iot_hub_client_core,
- (CHAR *)buffer_ptr, buffer_length, &buffer_length);
- if (az_result_failed(core_result))
+ if ((nx_azure_iot_ptr == NX_NULL) || (hub_client_ptr == NX_NULL) || (host_name == NX_NULL) ||
+ (device_id == NX_NULL) || (host_name_length == 0) || (device_id_length == 0))
{
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- nx_azure_iot_buffer_free(buffer_context);
- LogError(LogLiteralArgs("IoTHub client connect fail, with error status: %d"), core_result);
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ LogError(LogLiteralArgs("IoTHub client initialization fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- resource_ptr -> resource_mqtt_user_name = buffer_ptr;
- resource_ptr -> resource_mqtt_user_name_length = buffer_length;
- /* Build sas token. */
- resource_ptr -> resource_mqtt_sas_token = buffer_ptr + buffer_length;
- resource_ptr -> resource_mqtt_sas_token_length = buffer_size - buffer_length;
-
- /* Check if token refersh is setup. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_token_refresh)
- {
- status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, &expiry_time_secs);
- if (status)
- {
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- nx_azure_iot_buffer_free(buffer_context);
- LogError(LogLiteralArgs("IoTHub client connect fail: unixtime get failed status: %d"), status);
- return(status);
- }
+ memset(hub_client_ptr, 0, sizeof(NX_AZURE_IOT_HUB_CLIENT));
- expiry_time_secs += NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY;
- status = hub_client_ptr -> nx_azure_iot_hub_client_token_refresh(hub_client_ptr,
- expiry_time_secs,
- hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key,
- hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key_length,
- resource_ptr -> resource_mqtt_sas_token,
- resource_ptr -> resource_mqtt_sas_token_length,
- &(resource_ptr -> resource_mqtt_sas_token_length));
- if (status)
- {
+ options.module_id = az_span_create((UCHAR *)module_id, (INT)module_id_length);
+ options.user_agent = AZ_SPAN_FROM_STR(NX_AZURE_IOT_HUB_CLIENT_USER_AGENT);
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- nx_azure_iot_buffer_free(buffer_context);
- LogError(LogLiteralArgs("IoTHub client connect fail: Token generation failed status: %d"), status);
- return(status);
- }
- }
- else
+ core_result = az_iot_hub_client_init(&hub_client_ptr -> iot_hub_client_core,
+ hostname_span, device_id_span, &options);
+ if (az_result_failed(core_result))
{
- resource_ptr -> resource_mqtt_sas_token_length = 0;
+ LogError(LogLiteralArgs("IoTHub client failed initialization with error status: %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
}
- /* Set azure IoT and MQTT client. */
- mqtt_client_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt);
-
- /* Update client id. */
- mqtt_client_ptr -> nxd_mqtt_client_id = (CHAR *)resource_ptr -> resource_mqtt_client_id;
- mqtt_client_ptr -> nxd_mqtt_client_id_length = resource_ptr -> resource_mqtt_client_id_length;
-
- /* Set login info. */
- status = nxd_mqtt_client_login_set(&(resource_ptr -> resource_mqtt),
- (CHAR *)resource_ptr -> resource_mqtt_user_name,
- resource_ptr -> resource_mqtt_user_name_length,
- (CHAR *)resource_ptr -> resource_mqtt_sas_token,
- resource_ptr -> resource_mqtt_sas_token_length);
+ status = nx_azure_iot_hub_transport_initialize(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ nx_azure_iot_ptr, host_name, host_name_length,
+ nx_azure_iot_hub_client_client_id_get,
+ nx_azure_iot_hub_client_username_get,
+ crypto_array, crypto_array_size,
+ cipher_map, cipher_map_size,
+ metadata_memory, memory_size,
+ trusted_certificate, (VOID *)hub_client_ptr);
if (status)
{
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- nx_azure_iot_buffer_free(buffer_context);
- LogError(LogLiteralArgs("IoTHub client connect fail: MQTT CLIENT LOGIN SET FAIL status: %d"), status);
+ LogError(LogLiteralArgs("IoTHub client failed to initialization transport with error status: %d"), core_result);
return(status);
}
- /* Set connect notify for non-blocking mode. */
- if (wait_option == 0)
- {
- mqtt_client_ptr -> nxd_mqtt_connect_notify = nx_azure_iot_hub_client_mqtt_connect_notify;
- mqtt_client_ptr -> nxd_mqtt_connect_context = hub_client_ptr;
- }
-
- /* Save the resource buffer. */
- resource_ptr -> resource_mqtt_buffer_context = buffer_context;
- resource_ptr -> resource_mqtt_buffer_size = buffer_size;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- /* Start MQTT connection. */
- status = nxd_mqtt_client_secure_connect(mqtt_client_ptr, &server_address, NXD_MQTT_TLS_PORT,
- nx_azure_iot_mqtt_tls_setup, NX_AZURE_IOT_MQTT_KEEP_ALIVE,
- clean_session, wait_option);
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Check status for non-blocking mode. */
- if ((wait_option == 0) && (status == NX_IN_PROGRESS))
- {
- hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- /* Return in-progress completion status. */
- return(NX_AZURE_IOT_CONNECTING);
- }
-
- /* Release the mqtt connection resource. */
- if (resource_ptr -> resource_mqtt_buffer_context)
- {
- nx_azure_iot_buffer_free(resource_ptr -> resource_mqtt_buffer_context);
- resource_ptr -> resource_mqtt_buffer_context = NX_NULL;
- }
-
- /* Check status. */
- if (status != NX_AZURE_IOT_SUCCESS)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
- LogError(LogLiteralArgs("IoTHub client connect fail: MQTT CONNECT FAIL status: %d"), status);
- }
- else
- {
-
- /* Connected to IoT Hub. */
- hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED;
- }
-
- if (status == NX_AZURE_IOT_SUCCESS)
- {
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nx_azure_iot_hub_client_messages_enable(hub_client_ptr);
-
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- if (status)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
- LogError(LogLiteralArgs("IoTHub client connect fail: MQTT SUBSCRIBE FAIL status: %d"), status);
- }
- }
-
- /* Call connection notify if it is set. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback(hub_client_ptr, status);
- }
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(status);
+ return(NX_AZURE_IOT_SUCCESS);
}
-static VOID nx_azure_iot_hub_client_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr,
- UINT status, VOID *context)
+UINT 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))
{
-NX_AZURE_IOT_HUB_CLIENT *iot_hub_client = (NX_AZURE_IOT_HUB_CLIENT*)context;
-
-
- NX_PARAMETER_NOT_USED(client_ptr);
-
- /* Obtain the mutex. */
- tx_mutex_get(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Release the mqtt connection resource. */
- if (iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context)
- {
- nx_azure_iot_buffer_free(iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context);
- iot_hub_client -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context = NX_NULL;
- }
-
- /* Update hub client status. */
- if (status == NXD_MQTT_SUCCESS)
- {
- iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED;
- }
- else
- {
- iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
- }
-
- if (status == NXD_MQTT_SUCCESS)
- {
- tx_mutex_put(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nx_azure_iot_hub_client_messages_enable(iot_hub_client);
-
- tx_mutex_get(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- if (status)
- {
- iot_hub_client -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
- LogError(LogLiteralArgs("IoTHub client connect fail: MQTT SUBSCRIBE FAIL status: %d"), status);
- }
- }
-
- /* Call connection notify if it is set. */
- if (iot_hub_client -> nx_azure_iot_hub_client_connection_status_callback)
+ /* Check for invalid input pointers. */
+ if (hub_client_ptr == NX_NULL)
{
- iot_hub_client -> nx_azure_iot_hub_client_connection_status_callback(iot_hub_client, status);
+ LogError(LogLiteralArgs("IoTHub client connect callback fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Release the mutex. */
- tx_mutex_put(iot_hub_client -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ return(nx_azure_iot_hub_transport_connection_callback_set(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ nx_azure_iot_hub_client_connection_status_callback,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)connection_status_cb));
}
-static VOID nx_azure_iot_hub_client_mqtt_disconnect_notify(NXD_MQTT_CLIENT *client_ptr)
+UINT nx_azure_iot_hub_client_connect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
+ UINT clean_session, UINT wait_option)
{
-NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
-NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = NX_NULL;
-NX_AZURE_IOT_THREAD *thread_list_ptr;
-
- /* This function is protected by MQTT mutex. */
-
- if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
- {
- hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource -> resource_data_ptr;
- }
- else
- {
- return;
- }
-
- NX_ASSERT(hub_client_ptr != NX_NULL);
- /* Wake up all threads. */
- for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- thread_list_ptr;
- thread_list_ptr = thread_list_ptr -> thread_next)
+ /* Check for invalid input pointers. */
+ if (hub_client_ptr == NX_NULL)
{
- tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
+ LogError(LogLiteralArgs("IoTHub client connect fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Do not call callback if not connected, as at our layer connected means : mqtt connect + subscribe messages topic. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state == NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED;
-
- /* Call connection notify if it is set. */
- if (hub_client_ptr && hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_connection_status_callback(hub_client_ptr,
- NX_AZURE_IOT_DISCONNECTED);
- }
- }
+ return(nx_azure_iot_hub_transport_connect(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ clean_session, wait_option));
}
UINT nx_azure_iot_hub_client_disconnect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
-UINT status;
-NX_AZURE_IOT_THREAD *thread_list_ptr;
-
/* Check for invalid input pointers. */
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
+ if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client disconnect fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Disconnect. */
- status = nxd_mqtt_client_disconnect(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt));
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client disconnect fail status: %d"), status);
- return(status);
- }
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Release the mqtt connection resource. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context)
- {
- nx_azure_iot_buffer_free(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context);
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt_buffer_context = NX_NULL;
- }
-
- /* Wakeup all suspend threads. */
- for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- thread_list_ptr;
- thread_list_ptr = thread_list_ptr -> thread_next)
- {
- tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
- }
-
- /* Cleanup received messages. */
- nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message));
- nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message));
- nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message));
- nx_azure_iot_hub_client_received_message_cleanup(&(hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message));
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-static VOID nx_azure_iot_hub_client_received_message_cleanup(NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE *message)
-{
-NX_PACKET *current_ptr;
-NX_PACKET *next_ptr;
-
- for (current_ptr = message -> message_head; current_ptr; current_ptr = next_ptr)
- {
-
- /* Get next packet in queue. */
- next_ptr = current_ptr -> nx_packet_queue_next;
-
- /* Release current packet. */
- current_ptr -> nx_packet_queue_next = NX_NULL;
- nx_packet_release(current_ptr);
- }
-
- /* Reset received messages. */
- message -> message_head = NX_NULL;
- message -> message_tail = NX_NULL;
+ return(nx_azure_iot_hub_transport_disconnect(&(hub_client_ptr -> nx_azure_iot_hub_client_transport)));
}
UINT nx_azure_iot_hub_client_deinitialize(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
-UINT status;
/* Check for invalid input pointers. */
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
+ if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client deinitialize fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- nx_azure_iot_hub_client_disconnect(hub_client_ptr);
-
- status = nxd_mqtt_client_delete(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt));
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client delete fail status: %d"), status);
- return(status);
- }
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Remove resource from list. */
- status = nx_azure_iot_resource_remove(hub_client_ptr -> nx_azure_iot_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_resource));
- if (status)
- {
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- LogError(LogLiteralArgs("IoTHub client handle not found"));
- return(status);
- }
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_deinitialize(&(hub_client_ptr -> nx_azure_iot_hub_client_transport)));
}
UINT nx_azure_iot_hub_client_device_cert_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
NX_SECURE_X509_CERT *device_certificate)
{
-
- if ((hub_client_ptr == NX_NULL) ||
- (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
- (device_certificate == NX_NULL))
+ if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub device certificate set fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_device_certificate = device_certificate;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_device_cert_set(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ device_certificate));
}
UINT nx_azure_iot_hub_client_symmetric_key_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
const UCHAR *symmetric_key, UINT symmetric_key_length)
{
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
- (symmetric_key == NX_NULL) || (symmetric_key_length == 0))
+ if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client symmetric key fail: Invalid argument"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key = symmetric_key;
- hub_client_ptr -> nx_azure_iot_hub_client_symmetric_key_length = symmetric_key_length;
-
- hub_client_ptr -> nx_azure_iot_hub_client_token_refresh = nx_azure_iot_hub_client_sas_token_get;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_symmetric_key_auth_set(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ nx_azure_iot_hub_client_signature_get,
+ nx_azure_iot_hub_client_password_get,
+ symmetric_key, symmetric_key_length));
}
UINT 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)
{
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
+ if ((hub_client_ptr == NX_NULL) ||
+ (hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr == NX_NULL) ||
(model_id_ptr == NX_NULL) || (model_id_length == 0))
{
LogError(LogLiteralArgs("IoTHub client model Id fail: Invalid argument"));
@@ -746,14 +412,14 @@ UINT nx_azure_iot_hub_client_model_id_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_pt
}
/* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+ tx_mutex_get(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
/* Had no way to update option, so had to access the internal fields of iot_hub_client_core. */
hub_client_ptr -> iot_hub_client_core._internal.options.model_id =
az_span_create((UCHAR *)model_id_ptr, (INT)model_id_length);
/* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ tx_mutex_put(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
return(NX_AZURE_IOT_SUCCESS);
}
@@ -767,16 +433,14 @@ UINT status;
az_result core_result;
if ((hub_client_ptr == NX_NULL) ||
- (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
(packet_pptr == NX_NULL))
{
LogError(LogLiteralArgs("IoTHub telemetry message create fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- &packet_ptr, wait_option);
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ &packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("Create telemetry data fail"));
@@ -784,7 +448,7 @@ az_result core_result;
}
topic_length = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
- core_result = az_iot_hub_client_telemetry_get_publish_topic(&hub_client_ptr -> iot_hub_client_core,
+ core_result = az_iot_hub_client_telemetry_get_publish_topic(&(hub_client_ptr -> iot_hub_client_core),
NULL, (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
topic_length, &topic_length);
if (az_result_failed(core_result))
@@ -810,114 +474,22 @@ UINT nx_azure_iot_hub_client_telemetry_property_add(NX_PACKET *packet_ptr,
const UCHAR *property_value, USHORT property_value_length,
UINT wait_option)
{
-UINT status;
-
- if ((packet_ptr == NX_NULL) ||
- (property_name == NX_NULL) ||
- (property_value == NX_NULL))
- {
- LogError(LogLiteralArgs("IoTHub telemetry property add fail: INVALID POINTER"));
- return(NX_AZURE_IOT_INVALID_PARAMETER);
- }
-
- if (*(packet_ptr -> nx_packet_append_ptr - 1) != '/')
- {
- status = nx_packet_data_append(packet_ptr, "&", 1,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry data append fail"));
- return(status);
- }
- }
-
- status = nx_packet_data_append(packet_ptr, (VOID *)property_name, (UINT)property_name_length,
- packet_ptr -> nx_packet_pool_owner, wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry data append fail"));
- return(status);
- }
-
- status = nx_packet_data_append(packet_ptr, "=", 1,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry data append fail"));
- return(status);
- }
-
- status = nx_packet_data_append(packet_ptr, (VOID *)property_value, (UINT)property_value_length,
- packet_ptr -> nx_packet_pool_owner, wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry data append fail"));
- return(status);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_topic_property_append(packet_ptr, property_name, property_name_length,
+ property_value, property_value_length, wait_option));
}
UINT 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)
{
-UINT status;
-UINT topic_len;
-UCHAR packet_id[2];
-
- if ((hub_client_ptr == NX_NULL) || (packet_ptr == NX_NULL))
+ if ((hub_client_ptr == NX_NULL))
{
LogError(LogLiteralArgs("IoTHub telemetry send fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- topic_len = packet_ptr -> nx_packet_length;
-
- status = nx_azure_iot_mqtt_packet_id_get(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- packet_id, wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Failed to get packet id"));
- return(status);
- }
-
- /* Append packet identifier. */
- status = nx_packet_data_append(packet_ptr, packet_id, sizeof(packet_id),
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry append fail"));
- return(status);
- }
-
- if (telemetry_data && (data_size != 0))
- {
-
- /* Append payload. */
- status = nx_packet_data_append(packet_ptr, (VOID *)telemetry_data, data_size,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Telemetry data append fail"));
- return(status);
- }
- }
-
- status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- packet_ptr, topic_len, packet_id, NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client send fail: PUBLISH FAIL status: %d"), status);
- return(status);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_publish(&(hub_client_ptr -> nx_azure_iot_hub_client_transport), packet_ptr,
+ telemetry_data, data_size, NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS, wait_option));
}
UINT nx_azure_iot_hub_client_receive_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -927,241 +499,69 @@ UINT nx_azure_iot_hub_client_receive_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_c
VOID *args),
VOID *callback_args)
{
- if ((hub_client_ptr == NX_NULL) || (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL))
+UINT message_queue_index;
+
+ if ((hub_client_ptr == NX_NULL))
{
LogError(LogLiteralArgs("IoTHub receive callback set fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- if (message_type == NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_callback = callback_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_callback_args = callback_args;
- }
- else if (message_type == NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_callback = callback_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_callback_args = callback_args;
- }
- else if (message_type == NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message.message_callback = callback_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message.message_callback_args = callback_args;
- }
- else if (message_type == NX_AZURE_IOT_HUB_DIRECT_METHOD)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_callback = callback_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_callback_args = callback_args;
- }
- else
- {
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- return(NX_AZURE_IOT_NOT_SUPPORTED);
- }
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ message_queue_index = nx_azure_iot_hub_client_mesg_type_to_queue_index(message_type);
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_callback_set(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ message_queue_index,
+ callback_ptr != NX_NULL ? nx_azure_iot_hub_client_receive_callback : NX_NULL,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)callback_ptr, callback_args));
}
UINT nx_azure_iot_hub_client_cloud_message_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
- return(nx_azure_iot_hub_client_cloud_message_sub_unsub(hub_client_ptr, NX_TRUE));
-}
-
-UINT nx_azure_iot_hub_client_cloud_message_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
-{
- return(nx_azure_iot_hub_client_cloud_message_sub_unsub(hub_client_ptr, NX_FALSE));
-}
-
-static UINT nx_azure_iot_hub_client_process_publish_packet(UCHAR *start_ptr,
- ULONG *topic_offset_ptr,
- USHORT *topic_length_ptr)
-{
-UCHAR *byte = start_ptr;
-UINT byte_count = 0;
-UINT multiplier = 1;
-UINT remaining_length = 0;
-UINT topic_length;
-
- /* Validate packet start contains fixed header. */
- do
- {
- if (byte_count >= 4)
- {
- LogError(LogLiteralArgs("Invalid mqtt packet start position"));
- return(NX_AZURE_IOT_INVALID_PACKET);
- }
-
- byte++;
- remaining_length += (((*byte) & 0x7F) * multiplier);
- multiplier = multiplier << 7;
- byte_count++;
- } while ((*byte) & 0x80);
-
- if (remaining_length < 2)
- {
- return(NX_AZURE_IOT_INVALID_PACKET);
- }
-
- /* Retrieve topic length. */
- byte++;
- topic_length = (UINT)(*(byte) << 8) | (*(byte + 1));
-
- if (topic_length > remaining_length - 2u)
+ if (hub_client_ptr == NX_NULL)
{
- return(NX_AZURE_IOT_INVALID_PACKET);
+ LogError(LogLiteralArgs("IoTHub cloud message enable fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- *topic_offset_ptr = (ULONG)((byte + 2) - start_ptr);
- *topic_length_ptr = (USHORT)topic_length;
-
- /* Return. */
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_enable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC) - 1,
+ nx_azure_iot_hub_client_c2d_process));
}
-static UINT 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)
+UINT nx_azure_iot_hub_client_cloud_message_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
-NX_PACKET *packet_ptr = NX_NULL;
-UINT old_threshold;
-NX_AZURE_IOT_THREAD thread_list;
-
- if ((hub_client_ptr == NX_NULL) ||
- (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
- (packet_pptr == NX_NULL))
+ if (hub_client_ptr == NX_NULL)
{
- LogError(LogLiteralArgs("IoTHub message receive fail: INVALID POINTER"));
+ LogError(LogLiteralArgs("IoTHub cloud message disable fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- if (receive_message -> message_process == NX_NULL)
- {
- LogError(LogLiteralArgs("IoTHub message receive fail: NOT ENABLED"));
- return(NX_AZURE_IOT_NOT_ENABLED);
- }
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- if (receive_message -> message_head)
- {
- packet_ptr = receive_message -> message_head;
- if (receive_message -> message_tail == packet_ptr)
- {
- receive_message -> message_tail = NX_NULL;
- }
- receive_message -> message_head = packet_ptr -> nx_packet_queue_next;
- }
- else if (wait_option)
- {
- thread_list.thread_message_type = message_type;
- thread_list.thread_ptr = tx_thread_identify();
- thread_list.thread_received_message = NX_NULL;
- thread_list.thread_expected_id = 0;
- thread_list.thread_next = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = &thread_list;
-
- /* Disable preemption. */
- tx_thread_preemption_change(tx_thread_identify(), 0, &old_threshold);
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- tx_thread_sleep(wait_option);
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
-
- /* Restore preemption. */
- tx_thread_preemption_change(tx_thread_identify(), old_threshold, &old_threshold);
- packet_ptr = thread_list.thread_received_message;
- }
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- if (packet_ptr == NX_NULL)
- {
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
- {
- LogError(LogLiteralArgs("IoTHub message receive fail: IoTHub client not connected"));
- return(NX_AZURE_IOT_DISCONNECTED);
- }
-
- return(NX_AZURE_IOT_NO_PACKET);
- }
-
- *packet_pptr = packet_ptr;
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_disable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX));
}
-static UINT nx_azure_iot_hub_client_adjust_payload(NX_PACKET *packet_ptr)
+UINT nx_azure_iot_hub_client_cloud_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
+ NX_PACKET **packet_pptr, UINT wait_option)
{
UINT status;
-ULONG topic_offset;
-USHORT topic_length;
-ULONG message_offset;
-ULONG message_length;
-
- status = _nxd_mqtt_process_publish_packet(packet_ptr, &topic_offset,
- &topic_length, &message_offset,
- &message_length);
- if (status)
- {
- nx_packet_release(packet_ptr);
- return(status);
- }
-
- packet_ptr -> nx_packet_length = message_length;
- /* Adjust packet to pointer to message payload. */
- while (packet_ptr)
+ if (hub_client_ptr == NX_NULL)
{
- if ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > message_offset)
- {
-
- /* This packet contains message payload. */
- packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + message_offset;
- break;
- }
-
- message_offset -= (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
-
- /* Set current packet to empty. */
- packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_append_ptr;
-
- /* Move to next packet. */
- packet_ptr = packet_ptr -> nx_packet_next;
+ LogError(LogLiteralArgs("IoTHub cloud message receive fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-UINT nx_azure_iot_hub_client_cloud_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_PACKET **packet_pptr, UINT wait_option)
-{
-UINT status;
-
- status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
- &(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message),
- packet_pptr, wait_option);
+ status = nx_azure_iot_hub_transport_message_receive(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX, 0,
+ packet_pptr, wait_option);
if (status)
{
return(status);
}
- return(nx_azure_iot_hub_client_adjust_payload(*packet_pptr));
+ return(nx_azure_iot_hub_transport_adjust_payload(*packet_pptr));
}
UINT nx_azure_iot_hub_client_cloud_message_property_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -1187,8 +587,8 @@ az_span span;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- status = nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_data_start,
- &topic_offset, &topic_size);
+ status = nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_data_start,
+ &topic_offset, &topic_size);
if (status)
{
return(status);
@@ -1235,45 +635,9 @@ az_span span;
return(NX_AZURE_IOT_SUCCESS);
}
-static VOID nx_azure_iot_hub_client_device_twin_ack_notify(NXD_MQTT_CLIENT *client_ptr, UINT type,
- USHORT packet_id, NX_PACKET *transmit_packet_ptr, VOID *context)
-{
-
-NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)context;
-UCHAR buffer[sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1];
-ULONG bytes_copied;
-
-
- NX_PARAMETER_NOT_USED(client_ptr);
- NX_PARAMETER_NOT_USED(packet_id);
- NX_PARAMETER_NOT_USED(context);
-
- /* Mointor subscribe ack. */
- if (type == MQTT_CONTROL_PACKET_TYPE_SUBACK)
- {
-
- /* Get the topic. */
- if (nx_packet_data_extract_offset(transmit_packet_ptr,
- NX_AZURE_IOT_MQTT_SUBSCRIBE_TOPIC_OFFSET,
- buffer, sizeof(buffer), &bytes_copied))
- {
- return;
- }
-
- /* Compare the topic. */
- if ((bytes_copied == sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1) &&
- (!memcmp(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
- buffer, sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1)))
- {
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_response_subscribe_ack = NX_TRUE;
- }
- }
-}
-
UINT nx_azure_iot_hub_client_device_twin_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
UINT status;
-NXD_MQTT_CLIENT *client_ptr;
if (hub_client_ptr == NX_NULL)
{
@@ -1281,57 +645,33 @@ NXD_MQTT_CLIENT *client_ptr;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Atomically update the handler as we need to serialize the handler with incoming messages. */
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process =
- nx_azure_iot_hub_client_device_twin_process;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message.message_process =
- nx_azure_iot_hub_client_device_twin_process;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_enable =
- nx_azure_iot_hub_client_device_twin_enable;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message.message_enable =
- nx_azure_iot_hub_client_device_twin_enable;
-
- /* Register callbacks even if not connect and when connect complete subscribe for topics. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
+ status = nx_azure_iot_hub_transport_receive_message_enable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1,
+ nx_azure_iot_hub_client_device_twin_process);
+ if (status)
{
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- return(NX_AZURE_IOT_SUCCESS);
+ LogError(LogLiteralArgs("IoTHub client device twin subscribe fail status: %d"), status);
+ return(status);
}
- /* Initialize variables. */
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_response_subscribe_ack = NX_FALSE;
-
- /* Set ack receive notify for subscribe ack. */
- client_ptr = &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt);
- client_ptr -> nxd_mqtt_ack_receive_notify = nx_azure_iot_hub_client_device_twin_ack_notify;
- client_ptr -> nxd_mqtt_ack_receive_context = hub_client_ptr;
-
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1,
- NX_AZURE_IOT_MQTT_QOS_0);
+ status = nx_azure_iot_hub_transport_receive_message_enable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC) - 1,
+ NX_NULL);
if (status)
{
-
- /* Clean ack receive notify. */
- client_ptr -> nxd_mqtt_ack_receive_notify = NX_NULL;
LogError(LogLiteralArgs("IoTHub client device twin subscribe fail status: %d"), status);
return(status);
}
- status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC) - 1,
- NX_AZURE_IOT_MQTT_QOS_0);
+ status = nx_azure_iot_hub_transport_receive_message_enable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ NX_NULL, 0, NX_NULL);
if (status)
{
-
- /* Clean ack receive notify. */
- client_ptr -> nxd_mqtt_ack_receive_notify = NX_NULL;
LogError(LogLiteralArgs("IoTHub client device twin subscribe fail status: %d"), status);
return(status);
}
@@ -1349,27 +689,22 @@ UINT status;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC) - 1);
+ status = nx_azure_iot_hub_transport_receive_message_disable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX);
if (status)
{
LogError(LogLiteralArgs("IoTHub client device twin unsubscribe fail status: %d"), status);
return(status);
}
- status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC) - 1);
+ status = nx_azure_iot_hub_transport_receive_message_disable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES_QUEUE_INDEX);
if (status)
{
LogError(LogLiteralArgs("IoTHub client device twin unsubscribe fail status: %d"), status);
return(status);
}
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process = NX_NULL;
- hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message.message_process = NX_NULL;
-
return(NX_AZURE_IOT_SUCCESS);
}
@@ -1388,10 +723,10 @@ UINT nx_azure_iot_hub_client_report_properties_response_callback_set(NX_AZURE_IO
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback = callback_ptr;
- hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback_args = callback_args;
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_callback_set(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ callback_ptr != NX_NULL ? nx_azure_iot_hub_client_reported_property_receive_callback : NX_NULL,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)callback_ptr, callback_args));
}
static UINT nx_azure_iot_hub_client_twin_request_id_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -1402,7 +737,7 @@ static UINT nx_azure_iot_hub_client_twin_request_id_get(NX_AZURE_IOT_HUB_CLIENT
az_span span;
/* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+ tx_mutex_get(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
/* Check if current request_id is even and new requested is also even or
current request_id is odd and new requested is also odd. */
@@ -1426,7 +761,7 @@ az_span span;
{
/* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ tx_mutex_put(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
LogError(LogLiteralArgs("IoTHub client device failed to u32toa"));
return(NX_AZURE_IOT_SDK_CORE_ERROR);
}
@@ -1434,56 +769,7 @@ az_span span;
*request_id_span_ptr = az_span_create(buffer_ptr, (INT)(buffer_len - (UINT)az_span_size(span)));
/* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-static UINT nx_azure_iot_hub_client_device_twin_reponse_topic_status(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT wait_option)
-{
-
- /* Wait for subscribe ack of topic "$iothub/twin/res/#". */
- while (1)
- {
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Check if it is still in connected status. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
- {
-
- /* Clean ack receive notify. */
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- return(NX_AZURE_IOT_DISCONNECTED);
- }
-
- /* Check if receive the subscribe ack. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_device_twin_response_subscribe_ack == NX_TRUE)
- {
-
- /* Clean ack receive notify. */
- hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- break;
- }
-
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- /* Update wait time. */
- if (wait_option != NX_WAIT_FOREVER)
- {
- if (wait_option > 0)
- {
- wait_option--;
- }
- else
- {
- return(NX_AZURE_IOT_NO_SUBSCRIBE_ACK);
- }
- }
-
- tx_thread_sleep(1);
- }
+ tx_mutex_put(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
return(NX_AZURE_IOT_SUCCESS);
}
@@ -1499,10 +785,10 @@ NX_PACKET *packet_ptr;
UINT topic_length;
UINT request_id;
az_span request_id_span;
-NX_AZURE_IOT_THREAD thread_list;
az_result core_result;
ULONG topic_offset;
USHORT length;
+NX_PACKET *response_packet_ptr;
if (hub_client_ptr == NX_NULL)
{
@@ -1510,7 +796,10 @@ USHORT length;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- if ((status = nx_azure_iot_hub_client_device_twin_reponse_topic_status(hub_client_ptr, wait_option)))
+ /* Check if twin response is subscribed */
+ if ((status = nx_azure_iot_hub_transport_receive_message_is_subscribed(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX,
+ wait_option)))
{
LogError(LogLiteralArgs("IoTHub client reported state send fail with error %d"), status);
return(status);
@@ -1528,15 +817,8 @@ USHORT length;
* 2. Wait for the response if required.
* 3. Return result if present.
* */
- if (hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process == NX_NULL)
- {
- LogError(LogLiteralArgs("IoTHub client reported state send fail: NOT ENABLED"));
- return(NX_AZURE_IOT_NOT_ENABLED);
- }
-
- status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- &packet_ptr, wait_option);
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ &packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client reported state send fail: BUFFER ALLOCATE FAIL"));
@@ -1580,10 +862,10 @@ USHORT length;
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
packet_ptr -> nx_packet_length = topic_length;
- /* Append payload. */
- status = nx_packet_data_append(packet_ptr, (VOID *)message_buffer, message_length,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
+ status = nx_azure_iot_hub_transport_request_response(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ request_id, packet_ptr, topic_length, message_buffer, message_length,
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ &response_packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client reported state send fail: append failed"));
@@ -1591,60 +873,16 @@ USHORT length;
return(status);
}
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- thread_list.thread_message_type = NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE;
- thread_list.thread_ptr = tx_thread_identify();
- thread_list.thread_expected_id = request_id;
- thread_list.thread_received_message = NX_NULL;
- thread_list.thread_next = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = &thread_list;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
- wait_option);
-
- if (status)
- {
- nx_packet_release(packet_ptr);
-
- /* remove thread from waiting suspend queue. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
- nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- LogError(LogLiteralArgs("IoTHub client reported state send: PUBLISH FAIL status: %d"), status);
- return(status);
- }
- LogDebug(LogLiteralArgs("request_id: %d"), request_id);
-
- if ((thread_list.thread_received_message) == NX_NULL && wait_option)
- {
- tx_thread_sleep(wait_option);
- }
-
- /* Obtain the mutex. */
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- nx_azure_iot_hub_client_thread_dequeue(hub_client_ptr, &thread_list);
- packet_ptr = thread_list.thread_received_message;
-
- /* Release the mutex. */
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
if (request_id_ptr)
{
*request_id_ptr = request_id;
}
- if (packet_ptr == NX_NULL)
+ if (response_packet_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client reported state not responded"));
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
+ if (hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_hub_transport_state !=
+ NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
{
return(NX_AZURE_IOT_DISCONNECTED);
}
@@ -1652,24 +890,24 @@ USHORT length;
return(NX_AZURE_IOT_NO_PACKET);
}
- if ((status = nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr,
- &topic_offset, &length)))
+ if ((status = nx_azure_iot_hub_transport_process_publish_packet(response_packet_ptr -> nx_packet_prepend_ptr,
+ &topic_offset, &length)))
{
- nx_packet_release(packet_ptr);
+ nx_packet_release(response_packet_ptr);
return(status);
}
if ((status = nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr,
- packet_ptr, topic_offset, length,
+ response_packet_ptr, topic_offset, length,
NX_NULL, version_ptr, NX_NULL,
response_status_ptr)))
{
- nx_packet_release(packet_ptr);
+ nx_packet_release(response_packet_ptr);
return(status);
}
/* Release message block. */
- nx_packet_release(packet_ptr);
+ nx_packet_release(response_packet_ptr);
return(NX_AZURE_IOT_SUCCESS);
}
@@ -1691,7 +929,9 @@ az_result core_result;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- if ((status = nx_azure_iot_hub_client_device_twin_reponse_topic_status(hub_client_ptr, wait_option)))
+ if ((status = nx_azure_iot_hub_transport_receive_message_is_subscribed(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX,
+ wait_option)))
{
LogError(LogLiteralArgs("IoTHub client device twin publish fail with error %d"), status);
return(status);
@@ -1707,9 +947,8 @@ az_result core_result;
/* Steps.
* 1. Publish message to topic "$iothub/twin/GET/?$rid={request id}"
* */
- status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- &packet_ptr, wait_option);
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ &packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client device twin publish fail: BUFFER ALLOCATE FAIL"));
@@ -1752,9 +991,8 @@ az_result core_result;
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
packet_ptr -> nx_packet_length = topic_length;
- status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
- wait_option);
+ status = nx_azure_iot_hub_transport_publish(&(hub_client_ptr -> nx_azure_iot_hub_client_transport), packet_ptr,
+ NX_NULL, 0, NX_AZURE_IOT_MQTT_QOS_0, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client device twin: PUBLISH FAIL status: %d"), status);
@@ -1776,7 +1014,8 @@ az_span topic_span;
az_iot_hub_client_twin_response out_twin_response;
NX_PACKET *packet_ptr;
- if (hub_client_ptr == NX_NULL || packet_pptr == NX_NULL)
+ if ((hub_client_ptr == NX_NULL) ||
+ (packet_pptr == NX_NULL))
{
LogError(LogLiteralArgs("IoTHub client device twin receive failed: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
@@ -1787,17 +1026,17 @@ NX_PACKET *packet_ptr;
* 2. If present check the response.
* 3. Return the payload of the response.
* */
- status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES,
- &(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message),
- &packet_ptr, wait_option);
+ status = nx_azure_iot_hub_transport_message_receive(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES_QUEUE_INDEX, 0,
+ &packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client device twin receive failed status: %d"), status);
return(status);
}
- if (nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
- &topic_length))
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
{
/* Message not supported. It will be released. */
@@ -1824,7 +1063,7 @@ NX_PACKET *packet_ptr;
*packet_pptr = packet_ptr;
- return(nx_azure_iot_hub_client_adjust_payload(*packet_pptr));
+ return(nx_azure_iot_hub_transport_adjust_payload(*packet_pptr));
}
UINT nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -1832,7 +1071,8 @@ UINT nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_AZURE_IOT
{
UINT status;
- if (hub_client_ptr == NX_NULL || packet_pptr == NX_NULL)
+ if ((hub_client_ptr == NX_NULL) ||
+ (packet_pptr == NX_NULL))
{
LogError(LogLiteralArgs("IoTHub client device twin receive properties failed: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
@@ -1842,228 +1082,26 @@ UINT status;
* 1. Check if the desired properties document is available to receive from linklist.
* 2. Return result if present.
* */
- status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES,
- &(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message),
- packet_pptr, wait_option);
+ status = nx_azure_iot_hub_transport_message_receive(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES_QUEUE_INDEX, 0,
+ packet_pptr, wait_option);
if (status)
{
return(status);
}
- return(nx_azure_iot_hub_client_adjust_payload(*packet_pptr));
-}
-
-static UINT nx_azure_iot_hub_client_cloud_message_sub_unsub(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT is_subscribe)
-{
-UINT status;
-
- if (hub_client_ptr == NX_NULL)
- {
- LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: INVALID POINTER"));
- return(NX_AZURE_IOT_INVALID_PARAMETER);
- }
-
- if (is_subscribe)
- {
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Atomically update the handler as we need to serialize the handler with incoming messages. */
- hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process = nx_azure_iot_hub_client_c2d_process;
- hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_enable = nx_azure_iot_hub_client_cloud_message_enable;
-
- /* Register callbacks even if not connect and when connect complete subscribe for topics. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
- {
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC, sizeof(AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC) - 1,
- NX_AZURE_IOT_MQTT_QOS_1);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: status: %d"), status);
- return(status);
- }
- }
- else
- {
- status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC, sizeof(AZ_IOT_HUB_CLIENT_C2D_SUBSCRIBE_TOPIC) - 1);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub cloud message subscribe fail: status: %d"), status);
- return(status);
- }
-
- hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process = NX_NULL;
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-static VOID nx_azure_iot_hub_client_mqtt_receive_callback(NXD_MQTT_CLIENT* client_ptr,
- UINT number_of_messages)
-{
-NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
-NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = NX_NULL;
-NX_PACKET *packet_ptr;
-NX_PACKET *packet_next_ptr;
-ULONG topic_offset;
-USHORT topic_length;
-
- /* This function is protected by MQTT mutex. */
-
- NX_PARAMETER_NOT_USED(number_of_messages);
-
- if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
- {
- hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)resource -> resource_data_ptr;
- }
-
- if (hub_client_ptr)
- {
- for (packet_ptr = client_ptr -> message_receive_queue_head;
- packet_ptr;
- packet_ptr = packet_next_ptr)
- {
-
- /* Store next packet in case current packet is consumed. */
- packet_next_ptr = packet_ptr -> nx_packet_queue_next;
-
- /* Adjust packet to simply process logic. */
- nx_azure_iot_mqtt_packet_adjust(packet_ptr);
-
- if (nx_azure_iot_hub_client_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
- &topic_length))
- {
-
- /* Message not supported. It will be released. */
- nx_packet_release(packet_ptr);
- continue;
- }
-
- if ((topic_offset + topic_length) >
- (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr))
- {
-
- /* Only process topic in the first packet since the fixed topic is short enough to fit into one packet. */
- topic_length = (USHORT)(((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) -
- topic_offset) & 0xFFFF);
- }
-
- if (hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_process &&
- (hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_process(hub_client_ptr, packet_ptr,
- topic_offset,
- topic_length) == NX_AZURE_IOT_SUCCESS))
- {
-
- /* Direct method message is processed. */
- continue;
- }
-
- if (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process &&
- (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process(hub_client_ptr, packet_ptr,
- topic_offset,
- topic_length) == NX_AZURE_IOT_SUCCESS))
- {
-
- /* Could to Device message is processed. */
- continue;
- }
-
- if ((hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process) &&
- (hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process(hub_client_ptr,
- packet_ptr, topic_offset,
- topic_length) == NX_AZURE_IOT_SUCCESS))
- {
-
- /* Device Twin message is processed. */
- continue;
- }
-
- /* Message not supported. It will be released. */
- nx_packet_release(packet_ptr);
- }
-
- /* Clear all message from MQTT receive queue. */
- client_ptr -> message_receive_queue_head = NX_NULL;
- client_ptr -> message_receive_queue_tail = NX_NULL;
- client_ptr -> message_receive_queue_depth = 0;
- }
-}
-
-static VOID 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)
-{
- if (receive_message -> message_tail)
- {
- receive_message -> message_tail -> nx_packet_queue_next = packet_ptr;
- }
- else
- {
- receive_message -> message_head = packet_ptr;
- }
- receive_message -> message_tail = packet_ptr;
-
- /* Check for user callback function. */
- if (receive_message -> message_callback)
- {
- receive_message -> message_callback(hub_client_ptr, receive_message -> message_callback_args);
- }
+ return(nx_azure_iot_hub_transport_adjust_payload(*packet_pptr));
}
-static UINT 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)
-{
-NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
-NX_AZURE_IOT_THREAD *thread_list_ptr;
-
- /* Search thread waiting for message type. */
- for (thread_list_ptr = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- thread_list_ptr;
- thread_list_ptr = thread_list_ptr -> thread_next)
- {
- if ((thread_list_ptr -> thread_message_type == message_type) &&
- (request_id == thread_list_ptr -> thread_expected_id))
- {
-
- /* Found a thread waiting for message type. */
- if (thread_list_prev == NX_NULL)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = thread_list_ptr -> thread_next;
- }
- else
- {
- thread_list_prev -> thread_next = thread_list_ptr -> thread_next;
- }
- thread_list_ptr -> thread_received_message = packet_ptr;
- *thread_list_pptr = thread_list_ptr;
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- thread_list_prev = thread_list_ptr;
- }
-
- return(NX_AZURE_IOT_NOT_FOUND);
-}
-
-static UINT nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_PACKET *packet_ptr,
- ULONG topic_offset,
+static UINT nx_azure_iot_hub_client_c2d_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset,
USHORT topic_length)
{
UCHAR *topic_name;
az_iot_hub_client_c2d_request request;
az_span receive_topic;
az_result core_result;
-UINT status;
-NX_AZURE_IOT_THREAD *thread_list_ptr;
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
/* This function is protected by MQTT mutex. */
@@ -2087,35 +1125,19 @@ NX_AZURE_IOT_THREAD *thread_list_ptr;
return(NX_AZURE_IOT_NOT_FOUND);
}
- status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
- packet_ptr,
- NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
- 0, &thread_list_ptr);
- if (status == NX_AZURE_IOT_SUCCESS)
- {
- tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- /* No thread is waiting for C2D message yet. */
- nx_azure_iot_hub_client_message_notify(hub_client_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_c2d_message),
- packet_ptr);
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_notify(hub_trans_ptr, packet_ptr,
+ NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_QUEUE_INDEX, 0));
}
-static UINT nx_azure_iot_hub_client_direct_method_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_PACKET *packet_ptr,
- ULONG topic_offset,
+static UINT nx_azure_iot_hub_client_direct_method_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset,
USHORT topic_length)
{
UCHAR *topic_name;
az_iot_hub_client_method_request request;
az_span receive_topic;
az_result core_result;
-UINT status;
-NX_AZURE_IOT_THREAD *thread_list_ptr;
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
/* This function is protected by MQTT mutex. */
@@ -2139,27 +1161,14 @@ NX_AZURE_IOT_THREAD *thread_list_ptr;
return(NX_AZURE_IOT_NOT_FOUND);
}
- status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
- packet_ptr,
- NX_AZURE_IOT_HUB_DIRECT_METHOD,
- 0, &thread_list_ptr);
- if (status == NX_AZURE_IOT_SUCCESS)
- {
- tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- /* No thread is waiting for direct method message yet. */
- nx_azure_iot_hub_client_message_notify(hub_client_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message),
- packet_ptr);
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_notify(hub_trans_ptr, packet_ptr,
+ NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX, 0));
}
static UINT nx_azure_iot_hub_client_device_twin_message_type_get(az_iot_hub_client_twin_response *out_twin_response_ptr,
UINT request_id)
{
-UINT mesg_type;
+UINT message_type;
switch (out_twin_response_ptr -> response_type)
{
@@ -2171,24 +1180,24 @@ UINT mesg_type;
{
/* Odd requests are of reported properties and even of twin properties. */
- mesg_type = request_id % 2 == 0 ? NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES :
- NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE;
+ message_type = request_id % 2 == 0 ? NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES :
+ NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE;
}
break;
case AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_TYPE_DESIRED_PROPERTIES :
{
- mesg_type = NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES;
+ message_type = NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES;
}
break;
default :
{
- mesg_type = NX_AZURE_IOT_HUB_NONE;
+ message_type = NX_AZURE_IOT_HUB_NONE;
}
}
- return mesg_type;
+ return message_type;
}
static UINT nx_azure_iot_hub_client_device_twin_parse(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -2250,12 +1259,10 @@ uint32_t version;
return(NX_AZURE_IOT_SUCCESS);
}
-static UINT nx_azure_iot_hub_client_device_twin_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_PACKET *packet_ptr,
- ULONG topic_offset,
+static UINT nx_azure_iot_hub_client_device_twin_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset,
USHORT topic_length)
{
-NX_AZURE_IOT_THREAD *thread_list_ptr;
UINT message_type;
UINT response_status;
UINT request_id = 0;
@@ -2263,6 +1270,8 @@ ULONG version = 0;
UINT correlation_id;
UINT status;
ULONG current_time;
+NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr = (NX_AZURE_IOT_HUB_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+UINT message_queue_index;
/* This function is protected by MQTT mutex. */
if ((status = nx_azure_iot_hub_client_device_twin_parse(hub_client_ptr, packet_ptr,
@@ -2275,7 +1284,7 @@ ULONG current_time;
if (response_status == NX_AZURE_IOT_HUB_CLIENT_THROTTLE_STATUS_CODE)
{
- if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_ptr, &current_time)))
+ if ((status = nx_azure_iot_unix_time_get(hub_client_ptr -> nx_azure_iot_hub_client_transport.nx_azure_iot_ptr, &current_time)))
{
LogError(LogLiteralArgs("IoTHub client fail to get unix time: %d"), status);
return(status);
@@ -2303,206 +1312,38 @@ ULONG current_time;
correlation_id = 0;
}
- status = nx_azure_iot_hub_client_receive_thread_find(hub_client_ptr,
- packet_ptr,
- message_type,
- correlation_id, &thread_list_ptr);
- if (status == NX_AZURE_IOT_SUCCESS)
- {
- tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
- return(NX_AZURE_IOT_SUCCESS);
- }
+ message_queue_index = nx_azure_iot_hub_client_mesg_type_to_queue_index(message_type);
+ status = nx_azure_iot_hub_transport_receive_notify(hub_trans_ptr, packet_ptr,
+ message_queue_index, correlation_id);
- switch(message_type)
- {
- case NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE :
- {
- if (hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback(hub_client_ptr,
- request_id,
- response_status,
- version,
- hub_client_ptr -> nx_azure_iot_hub_client_report_properties_response_callback_args);
- }
-
- nx_packet_release(packet_ptr);
- }
- break;
-
- case NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES :
- {
-
- /* No thread is waiting for device twin message yet. */
- nx_azure_iot_hub_client_message_notify(hub_client_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message),
- packet_ptr);
- }
- break;
-
- case NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES :
- {
-
- /* No thread is waiting for device twin message yet. */
- nx_azure_iot_hub_client_message_notify(hub_client_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_device_twin_desired_properties_message),
- packet_ptr);
- }
- break;
-
- default :
- nx_packet_release(packet_ptr);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-static VOID nx_azure_iot_hub_client_thread_dequeue(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
- NX_AZURE_IOT_THREAD *thread_list_ptr)
-{
-NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
-NX_AZURE_IOT_THREAD *thread_list_current;
-
- for (thread_list_current = hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended;
- thread_list_current;
- thread_list_current = thread_list_current -> thread_next)
- {
- if (thread_list_current == thread_list_ptr)
- {
-
- /* Found the thread to dequeue. */
- if (thread_list_prev == NX_NULL)
- {
- hub_client_ptr -> nx_azure_iot_hub_client_thread_suspended = thread_list_current -> thread_next;
- }
- else
- {
- thread_list_prev -> thread_next = thread_list_current -> thread_next;
- }
- break;
- }
-
- thread_list_prev = thread_list_current;
- }
-}
-
-static UINT 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)
-{
-UCHAR *buffer_ptr;
-UINT buffer_size;
-VOID *buffer_context;
-az_span span = az_span_create(sas_buffer, (INT)sas_buffer_len);
-az_span buffer_span;
-UINT status;
-UCHAR *output_ptr;
-UINT output_len;
-az_result core_result;
-
- status = nx_azure_iot_buffer_allocate(hub_client_ptr -> nx_azure_iot_ptr, &buffer_ptr, &buffer_size, &buffer_context);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client sas token fail: BUFFER ALLOCATE FAIL"));
- return(status);
- }
-
- core_result = az_iot_hub_client_sas_get_signature(&(hub_client_ptr -> iot_hub_client_core),
- expiry_time_secs, span, &span);
- if (az_result_failed(core_result))
- {
- LogError(LogLiteralArgs("IoTHub failed failed to get signature with error status: %d"), core_result);
- nx_azure_iot_buffer_free(buffer_context);
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
-
- status = nx_azure_iot_base64_hmac_sha256_calculate(&(hub_client_ptr -> nx_azure_iot_hub_client_resource),
- key, key_len, az_span_ptr(span), (UINT)az_span_size(span),
- buffer_ptr, buffer_size, &output_ptr, &output_len);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub failed to encoded hash"));
- nx_azure_iot_buffer_free(buffer_context);
- return(status);
- }
-
- buffer_span = az_span_create(output_ptr, (INT)output_len);
- core_result= az_iot_hub_client_sas_get_password(&(hub_client_ptr -> iot_hub_client_core),
- expiry_time_secs, buffer_span, AZ_SPAN_EMPTY,
- (CHAR *)sas_buffer, sas_buffer_len, &sas_buffer_len);
- if (az_result_failed(core_result))
- {
- LogError(LogLiteralArgs("IoTHub failed to generate token with error status: %d"), core_result);
- nx_azure_iot_buffer_free(buffer_context);
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
-
- *sas_length = sas_buffer_len;
- nx_azure_iot_buffer_free(buffer_context);
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(status);
}
UINT nx_azure_iot_hub_client_direct_method_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
-UINT status;
-
if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client direct method subscribe fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
-
- /* Atomically update the handler as we need to serialize the handler with incoming messages. */
- hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_process = nx_azure_iot_hub_client_direct_method_process;
- hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_enable = nx_azure_iot_hub_client_direct_method_enable;
-
- /* Register callbacks even if not connect and when connect complete subscribe for topics. */
- if (hub_client_ptr -> nx_azure_iot_hub_client_state != NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED)
- {
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
-
- status = nxd_mqtt_client_subscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC) - 1,
- NX_AZURE_IOT_MQTT_QOS_0);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client direct method subscribe fail %d"), status);
- return(status);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_enable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC) - 1,
+ nx_azure_iot_hub_client_direct_method_process));
}
UINT nx_azure_iot_hub_client_direct_method_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
{
-UINT status;
-
if (hub_client_ptr == NX_NULL)
{
LogError(LogLiteralArgs("IoTHub client direct method unsubscribe fail: INVALID POINTER"));
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- status = nxd_mqtt_client_unsubscribe(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC,
- sizeof(AZ_IOT_HUB_CLIENT_METHODS_SUBSCRIBE_TOPIC) - 1);
- if (status)
- {
- LogError(LogLiteralArgs("IoTHub client direct method unsubscribe fail status: %d"), status);
- return(status);
- }
-
- hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_process = NX_NULL;
-
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_hub_transport_receive_message_disable(&(hub_client_ptr ->nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX));
}
UINT nx_azure_iot_hub_client_direct_method_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
@@ -2531,9 +1372,9 @@ az_iot_hub_client_method_request request;
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- status = nx_azure_iot_hub_client_message_receive(hub_client_ptr, NX_AZURE_IOT_HUB_DIRECT_METHOD,
- &(hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message),
- packet_pptr, wait_option);
+ status = nx_azure_iot_hub_transport_message_receive(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ NX_AZURE_IOT_HUB_DIRECT_METHOD_QUEUE_INDEX, 0,
+ packet_pptr, wait_option);
if (status)
{
return(status);
@@ -2599,7 +1440,6 @@ UINT status;
az_result core_result;
if ((hub_client_ptr == NX_NULL) ||
- (hub_client_ptr -> nx_azure_iot_ptr == NX_NULL) ||
(context_ptr == NX_NULL) ||
(context_length == 0))
{
@@ -2608,9 +1448,8 @@ az_result core_result;
}
/* Prepare response packet. */
- status = nx_azure_iot_publish_packet_get(hub_client_ptr -> nx_azure_iot_ptr,
- &(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- &packet_ptr, wait_option);
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(hub_client_ptr -> nx_azure_iot_hub_client_transport),
+ &packet_ptr, wait_option);
if (status)
{
LogError(LogLiteralArgs("Create response data fail"));
@@ -2630,43 +1469,17 @@ az_result core_result;
return(NX_AZURE_IOT_SDK_CORE_ERROR);
}
-
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
packet_ptr -> nx_packet_length = topic_length;
- if (payload && (payload_length != 0))
+ if ((payload == NX_NULL) || (payload_length == 0))
{
-
- /* Append payload. */
- status = nx_packet_data_append(packet_ptr, (VOID *)payload, payload_length,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Method reponse data append fail"));
- nx_packet_release(packet_ptr);
- return(status);
- }
- }
- else
- {
-
- /* Append payload. */
- status = nx_packet_data_append(packet_ptr, NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON,
- sizeof(NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON) - 1,
- packet_ptr -> nx_packet_pool_owner,
- wait_option);
- if (status)
- {
- LogError(LogLiteralArgs("Adding empty json failed."));
- nx_packet_release(packet_ptr);
- return(status);
- }
+ payload = (const UCHAR *)NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON;
+ payload_length = sizeof(NX_AZURE_IOT_HUB_CLIENT_EMPTY_JSON) - 1;
}
- status = nx_azure_iot_publish_mqtt_packet(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt),
- packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
- wait_option);
+ status = nx_azure_iot_hub_transport_publish(&(hub_client_ptr -> nx_azure_iot_hub_client_transport), packet_ptr,
+ payload, payload_length, NX_AZURE_IOT_MQTT_QOS_0, wait_option);
if (status)
{
LogError(LogLiteralArgs("IoTHub client method response fail: PUBLISH FAIL status: %d"), status);
@@ -2676,28 +1489,3 @@ az_result core_result;
return(NX_AZURE_IOT_SUCCESS);
}
-
-static UINT nx_azure_iot_hub_client_messages_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
-{
-UINT status = NX_AZURE_IOT_SUCCESS;
-
- if (status == NX_AZURE_IOT_SUCCESS &&
- (hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_process != NX_NULL))
- {
- status = hub_client_ptr -> nx_azure_iot_hub_client_c2d_message.message_enable(hub_client_ptr);
- }
-
- if (status == NX_AZURE_IOT_SUCCESS &&
- (hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_process != NX_NULL))
- {
- status = hub_client_ptr -> nx_azure_iot_hub_client_direct_method_message.message_enable(hub_client_ptr);
- }
-
- if (status == NX_AZURE_IOT_SUCCESS &&
- (hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_process != NX_NULL))
- {
- status = hub_client_ptr -> nx_azure_iot_hub_client_device_twin_message.message_enable(hub_client_ptr);
- }
-
- return(status);
-} \ No newline at end of file
diff --git a/addons/azure_iot/nx_azure_iot_hub_client.h b/addons/azure_iot/nx_azure_iot_hub_client.h
index a510bb81..dcbce16a 100644
--- a/addons/azure_iot/nx_azure_iot_hub_client.h
+++ b/addons/azure_iot/nx_azure_iot_hub_client.h
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
/**
* @file nx_azure_iot_hub_client.h
@@ -28,11 +28,10 @@ extern "C" {
#endif
#include "azure/iot/az_iot_hub_client.h"
+#include "nx_azure_iot_hub_transport.h"
#include "nx_azure_iot.h"
#include "nx_api.h"
#include "nx_cloud.h"
-#include "nxd_dns.h"
-#include "nxd_mqtt_client.h"
/**< Value denoting a message is of "None" type */
#define NX_AZURE_IOT_HUB_NONE 0x00000000
@@ -55,16 +54,6 @@ extern "C" {
/**< Value denoting a message is a device reported properties response */
#define NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE 0x00000010
-/* Set the default timeout for DNS query. */
-#ifndef NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT
-#define NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT (5 * NX_IP_PERIODIC_RATE)
-#endif /* NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT */
-
-/* Set the default token expiry in secs. */
-#ifndef NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY
-#define NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY (3600)
-#endif /* NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY */
-
#ifndef NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC
#define NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC (10 * 60)
#endif /* NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC */
@@ -79,80 +68,32 @@ extern "C" {
/* Define AZ IoT Hub Client state. */
/**< The client is not connected */
-#define NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED 0
+#define NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED
/**< The client is connecting */
-#define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING 1
+#define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTING
/**< The client is connected */
-#define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED 2
+#define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED
/* Default TELEMETRY QoS is QoS1 */
#ifndef NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS
#define NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS NX_AZURE_IOT_MQTT_QOS_1
#endif /* NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS */
-typedef struct NX_AZURE_IOT_THREAD_STRUCT
-{
- TX_THREAD *thread_ptr;
- struct NX_AZURE_IOT_THREAD_STRUCT *thread_next;
- UINT thread_message_type;
- UINT thread_expected_id; /* Used by device twin. */
- NX_PACKET *thread_received_message;
-} NX_AZURE_IOT_THREAD;
-
-/* Forward declration*/
-struct NX_AZURE_IOT_HUB_CLIENT_STRUCT;
-
-typedef struct NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE_STRUCT
-{
- NX_PACKET *message_head;
- NX_PACKET *message_tail;
- VOID (*message_callback)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, VOID *args);
- VOID *message_callback_args;
- UINT (*message_process)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
- NX_PACKET *packet_ptr, ULONG topic_offset, USHORT topic_length);
- UINT (*message_enable)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr);
-} NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE;
-
/**
* @brief Azure IoT Hub Client struct
*
*/
typedef struct NX_AZURE_IOT_HUB_CLIENT_STRUCT
{
- NX_AZURE_IOT *nx_azure_iot_ptr;
-
- UINT nx_azure_iot_hub_client_state;
- NX_AZURE_IOT_THREAD *nx_azure_iot_hub_client_thread_suspended;
- NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_c2d_message;
- NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_device_twin_message;
- NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_device_twin_desired_properties_message;
- NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_direct_method_message;
- VOID (*nx_azure_iot_hub_client_report_properties_response_callback)(
- struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
- UINT request_id, UINT response_status, ULONG version, VOID *args);
- VOID *nx_azure_iot_hub_client_report_properties_response_callback_args;
-
- VOID (*nx_azure_iot_hub_client_connection_status_callback)(
- struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
- UINT status);
- UINT (*nx_azure_iot_hub_client_token_refresh)(
- struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
- ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
- UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length);
-
- UINT nx_azure_iot_hub_client_request_id;
- const UCHAR *nx_azure_iot_hub_client_symmetric_key;
- UINT nx_azure_iot_hub_client_symmetric_key_length;
- NX_AZURE_IOT_RESOURCE nx_azure_iot_hub_client_resource;
+ NX_AZURE_IOT_HUB_TRANSPORT nx_azure_iot_hub_client_transport;
- volatile UCHAR nx_azure_iot_hub_client_device_twin_response_subscribe_ack;
- UCHAR reserved[3];
+ UINT nx_azure_iot_hub_client_request_id;
- az_iot_hub_client iot_hub_client_core;
- UINT nx_azure_iot_hub_client_throttle_count;
- ULONG nx_azure_iot_hub_client_throttle_end_time;
+ az_iot_hub_client iot_hub_client_core;
+ UINT nx_azure_iot_hub_client_throttle_count;
+ ULONG nx_azure_iot_hub_client_throttle_end_time;
} NX_AZURE_IOT_HUB_CLIENT;
diff --git a/addons/azure_iot/nx_azure_iot_hub_transport.c b/addons/azure_iot/nx_azure_iot_hub_transport.c
new file mode 100644
index 00000000..26238971
--- /dev/null
+++ b/addons/azure_iot/nx_azure_iot_hub_transport.c
@@ -0,0 +1,1439 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/* Version: 6.1 PnP Preview 1 */
+
+#include "nx_azure_iot_hub_transport.h"
+
+#include "azure/core/az_version.h"
+
+
+#define NX_AZURE_IOT_HUB_U32_MAX_BUFFER_SIZE 10
+#define NX_AZURE_IOT_HUB_EMPTY_JSON "{}"
+#define NX_AZURE_IOT_HUB_THROTTLE_STATUS_CODE 429
+
+
+extern UINT _nxd_mqtt_process_publish_packet(NX_PACKET *packet_ptr, ULONG *topic_offset_ptr,
+ USHORT *topic_length_ptr, ULONG *message_offset_ptr,
+ ULONG *message_length_ptr);
+extern UINT _nxd_mqtt_client_sub_unsub(NXD_MQTT_CLIENT *client_ptr, UINT op,
+ CHAR *topic_name, UINT topic_name_length,
+ USHORT *packet_id_ptr, UINT QoS);
+
+static VOID nx_azure_iot_hub_transport_sub_ack_notify(NXD_MQTT_CLIENT *client_ptr, UINT type,
+ USHORT packet_id, NX_PACKET *transmit_packet_ptr, VOID *context)
+{
+NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr = (NX_AZURE_IOT_HUB_TRANSPORT *)context;
+UINT pending_subscribe_ack = hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack;
+
+ NX_PARAMETER_NOT_USED(client_ptr);
+ NX_PARAMETER_NOT_USED(transmit_packet_ptr);
+
+ /* Mointor subscribe ack. */
+ if (type == MQTT_CONTROL_PACKET_TYPE_SUBACK)
+ {
+
+ if (pending_subscribe_ack == 0)
+ {
+ return;
+ }
+
+ /* Compare the topic. */
+ for (UINT index = 0; index < NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE; index++)
+ {
+ if ((pending_subscribe_ack & (UINT)(0x1 << index)) &&
+ (hub_transport_ptr -> nx_azure_iot_hub_transport_message[index].message_sub_packet_id == packet_id))
+ {
+ pending_subscribe_ack &= ~((UINT)(0x1 << index));
+ break;
+ }
+ }
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack = pending_subscribe_ack;
+ }
+}
+
+static UINT nx_azure_iot_hub_transport_message_subscribe(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr, UINT queue_index)
+{
+UINT status;
+
+ if ((hub_transport_ptr -> nx_azure_iot_hub_transport_message[queue_index].message_topic_ptr == NX_NULL) ||
+ (hub_transport_ptr -> nx_azure_iot_hub_transport_message[queue_index].message_topic_length == 0))
+ {
+ /* Nothing to subscribe */
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack |= (UINT)(0x1 << queue_index);
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = nx_azure_iot_hub_transport_sub_ack_notify;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt.nxd_mqtt_ack_receive_context = hub_transport_ptr;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ status = _nxd_mqtt_client_sub_unsub(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ (MQTT_CONTROL_PACKET_TYPE_SUBSCRIBE << 4) | 0x02,
+ (CHAR *)hub_transport_ptr -> nx_azure_iot_hub_transport_message[queue_index].message_topic_ptr,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[queue_index].message_topic_length,
+ &(hub_transport_ptr -> nx_azure_iot_hub_transport_message[queue_index].message_sub_packet_id),
+ NX_AZURE_IOT_MQTT_QOS_0);
+
+ if (status)
+ {
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Reset the pending subscribe */
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack &= ~(UINT)(0x1 << queue_index);
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ }
+
+ return(status);
+}
+
+static UINT nx_azure_iot_hub_transport_messages_enable(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr)
+{
+UINT status = NX_AZURE_IOT_SUCCESS;
+UINT index = 0;
+
+ for (index = 0; index < NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE; index++)
+ {
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_message[index].message_topic_ptr != NX_NULL)
+ {
+ status = nx_azure_iot_hub_transport_message_subscribe(hub_transport_ptr, index);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Failed to enable message type: %d"), index);
+ LogError(LogLiteralArgs("Enable status: %d"), status);
+ break;
+ }
+ }
+ }
+
+ return(status);
+}
+
+static VOID nx_azure_iot_hub_transport_mqtt_receive_callback(NXD_MQTT_CLIENT* client_ptr,
+ UINT number_of_messages)
+{
+NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
+NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr = NX_NULL;
+NX_PACKET *packet_ptr;
+NX_PACKET *packet_next_ptr;
+ULONG topic_offset;
+USHORT topic_length;
+UINT index = 0;
+
+ /* This function is protected by MQTT mutex. */
+
+ NX_PARAMETER_NOT_USED(number_of_messages);
+
+ if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
+ {
+ hub_transport_ptr = (NX_AZURE_IOT_HUB_TRANSPORT *)resource -> resource_data_ptr;
+ }
+
+ if (hub_transport_ptr)
+ {
+ for (packet_ptr = client_ptr -> message_receive_queue_head;
+ packet_ptr;
+ packet_ptr = packet_next_ptr)
+ {
+
+ /* Store next packet in case current packet is consumed. */
+ packet_next_ptr = packet_ptr -> nx_packet_queue_next;
+
+ /* Adjust packet to simply process logic. */
+ nx_azure_iot_mqtt_packet_adjust(packet_ptr);
+
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
+ {
+
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ continue;
+ }
+
+ if ((topic_offset + topic_length) >
+ (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr))
+ {
+
+ /* Message with topic spaning multiple packet is not supported. It will be released. */
+ LogDebug(LogLiteralArgs("IoTHub packet receive fail as topic span multiple packet"));
+ nx_packet_release(packet_ptr);
+ continue;
+ }
+
+ for (index = 0; index < NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE; index++)
+ {
+ if ((hub_transport_ptr -> nx_azure_iot_hub_transport_message[index].message_process != NX_NULL) &&
+ (hub_transport_ptr -> nx_azure_iot_hub_transport_message[index].message_process(hub_transport_ptr,
+ packet_ptr, topic_offset,
+ topic_length) == NX_AZURE_IOT_SUCCESS))
+ {
+ break;
+ }
+ }
+
+ if (index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE)
+ {
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ }
+ }
+
+ /* Clear all message from MQTT receive queue. */
+ client_ptr -> message_receive_queue_head = NX_NULL;
+ client_ptr -> message_receive_queue_tail = NX_NULL;
+ client_ptr -> message_receive_queue_depth = 0;
+ }
+}
+
+static VOID nx_azure_iot_hub_transport_mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr,
+ UINT status, VOID *context)
+{
+NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr = (NX_AZURE_IOT_HUB_TRANSPORT *)context;
+
+
+ NX_PARAMETER_NOT_USED(client_ptr);
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Release the mqtt connection resource. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context)
+ {
+ nx_azure_iot_buffer_free(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context);
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context = NX_NULL;
+ }
+
+ /* Update hub client status. */
+ if (status == NXD_MQTT_SUCCESS)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED;
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ status = nx_azure_iot_hub_transport_messages_enable(hub_transport_ptr);
+
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ if (status)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED;
+ LogError(LogLiteralArgs("IoTHub connect fail: MQTT SUBSCRIBE FAIL status: %d"), status);
+ }
+ }
+ else
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED;
+ }
+
+ /* Call connection notify if it is set. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback(hub_transport_ptr, status,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback_arg);
+ }
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+}
+
+static VOID nx_azure_iot_hub_transport_mqtt_disconnect_notify(NXD_MQTT_CLIENT *client_ptr)
+{
+NX_AZURE_IOT_RESOURCE *resource = nx_azure_iot_resource_search(client_ptr);
+NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr = NX_NULL;
+NX_AZURE_IOT_THREAD *thread_list_ptr;
+
+ /* This function is protected by MQTT mutex. */
+
+ if (resource && (resource -> resource_type == NX_AZURE_IOT_RESOURCE_IOT_HUB))
+ {
+ hub_transport_ptr = (NX_AZURE_IOT_HUB_TRANSPORT *)resource -> resource_data_ptr;
+ }
+
+ if (hub_transport_ptr == NX_NULL)
+ {
+ return;
+ }
+
+ /* Wake up all threads. */
+ for (thread_list_ptr = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ thread_list_ptr;
+ thread_list_ptr = thread_list_ptr -> thread_next)
+ {
+ tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
+ }
+
+ /* Do not call callback if not connected, as at our layer connected means : mqtt connect + subscribe messages topic. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_state == NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED;
+
+ /* Call connection notify if it is set. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback(hub_transport_ptr,
+ NX_AZURE_IOT_DISCONNECTED,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback_arg);
+ }
+ }
+}
+
+static UINT nx_azure_iot_hub_transport_sas_token_get(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
+ UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length)
+{
+UCHAR *buffer_ptr;
+UINT buffer_size;
+VOID *buffer_context;
+UINT bytes_used;
+UINT status;
+UCHAR *output_ptr;
+UINT output_len;
+az_span span;
+az_result core_result;
+
+ status = nx_azure_iot_buffer_allocate(hub_transport_ptr -> nx_azure_iot_ptr, &buffer_ptr, &buffer_size, &buffer_context);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub sas token fail: BUFFER ALLOCATE FAIL"));
+ return(status);
+ }
+
+ span = az_span_create(sas_buffer, (INT)sas_buffer_len);
+ core_result = hub_transport_ptr -> nx_azure_iot_hub_transport_sas_signature(hub_transport_ptr,
+ expiry_time_secs, span, &span);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoTHub failed failed to get signature with error status: %d"), status);
+ nx_azure_iot_buffer_free(buffer_context);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ bytes_used = (UINT)az_span_size(span);
+ status = nx_azure_iot_base64_hmac_sha256_calculate(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource),
+ key, key_len, sas_buffer, bytes_used,
+ buffer_ptr, buffer_size, &output_ptr, &output_len);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub failed to encoded hash"));
+ nx_azure_iot_buffer_free(buffer_context);
+ return(status);
+ }
+
+ span = az_span_create(output_ptr, (INT)output_len);
+ core_result = hub_transport_ptr -> nx_azure_iot_hub_transport_sas_password(hub_transport_ptr,
+ expiry_time_secs, span,
+ AZ_SPAN_EMPTY,
+ sas_buffer, sas_buffer_len,
+ &bytes_used);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoTHub failed to generate token with error status: %d"), core_result);
+ nx_azure_iot_buffer_free(buffer_context);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ *sas_length = bytes_used;
+ nx_azure_iot_buffer_free(buffer_context);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+static VOID nx_azure_iot_hub_transport_thread_dequeue(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_AZURE_IOT_THREAD *thread_list_ptr)
+{
+NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
+NX_AZURE_IOT_THREAD *thread_list_current;
+
+ for (thread_list_current = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ thread_list_current;
+ thread_list_current = thread_list_current -> thread_next)
+ {
+ if (thread_list_current == thread_list_ptr)
+ {
+
+ /* Found the thread to dequeue. */
+ if (thread_list_prev == NX_NULL)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended = thread_list_current -> thread_next;
+ }
+ else
+ {
+ thread_list_prev -> thread_next = thread_list_current -> thread_next;
+ }
+ break;
+ }
+
+ thread_list_prev = thread_list_current;
+ }
+}
+
+static UINT nx_azure_iot_hub_transport_message_receive_internal(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT message_queue_index, UINT expected_id,
+ NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE *receive_message,
+ NX_PACKET **packet_pptr, UINT wait_option)
+{
+NX_PACKET *packet_ptr = NX_NULL;
+UINT old_threshold;
+NX_AZURE_IOT_THREAD thread_list;
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ if (receive_message -> message_head)
+ {
+ packet_ptr = receive_message -> message_head;
+ if (receive_message -> message_tail == packet_ptr)
+ {
+ receive_message -> message_tail = NX_NULL;
+ }
+
+ receive_message -> message_head = packet_ptr -> nx_packet_queue_next;
+ packet_ptr -> nx_packet_queue_next = NX_NULL;
+ }
+ else if (wait_option)
+ {
+ thread_list.thread_message_type = message_queue_index;
+ thread_list.thread_ptr = tx_thread_identify();
+ thread_list.thread_received_message = NX_NULL;
+ thread_list.thread_expected_id = expected_id;
+ thread_list.thread_next = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended = &thread_list;
+
+ /* Disable preemption. */
+ tx_thread_preemption_change(tx_thread_identify(), 0, &old_threshold);
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ tx_thread_sleep(wait_option);
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ nx_azure_iot_hub_transport_thread_dequeue(hub_transport_ptr, &thread_list);
+
+ /* Restore preemption. */
+ tx_thread_preemption_change(tx_thread_identify(), old_threshold, &old_threshold);
+ packet_ptr = thread_list.thread_received_message;
+ }
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ if (packet_ptr == NX_NULL)
+ {
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_state != NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+ LogError(LogLiteralArgs("IoTHub transport message receive fail: IoTHub client not connected"));
+ return(NX_AZURE_IOT_DISCONNECTED);
+ }
+
+ return(NX_AZURE_IOT_NO_PACKET);
+ }
+
+ *packet_pptr = packet_ptr;
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+static VOID nx_azure_iot_hub_transport_received_message_cleanup(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr)
+{
+NX_PACKET *current_ptr;
+NX_PACKET *next_ptr;
+NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE *message_queue_ptr;
+
+ for (UINT index = 0; index < NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE; index++)
+ {
+ message_queue_ptr = &(hub_transport_ptr -> nx_azure_iot_hub_transport_message[index]);
+ for (current_ptr = message_queue_ptr -> message_head; current_ptr; current_ptr = next_ptr)
+ {
+
+ /* Get next packet in queue. */
+ next_ptr = current_ptr -> nx_packet_queue_next;
+
+ /* Release current packet. */
+ current_ptr -> nx_packet_queue_next = NX_NULL;
+ nx_packet_release(current_ptr);
+ }
+
+ /* Reset received messages. */
+ message_queue_ptr -> message_head = NX_NULL;
+ message_queue_ptr -> message_tail = NX_NULL;
+ }
+
+}
+
+UINT nx_azure_iot_hub_transport_initialize(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_AZURE_IOT *nx_azure_iot_ptr,
+ const UCHAR *host_name, UINT host_name_length,
+ const NX_AZURE_IOT_HUB_TRANSPORT_CLIENT_ID_GET_FN client_id_get,
+ const NX_AZURE_IOT_HUB_TRANSPORT_USERNAME_GET_FN username_get,
+ 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,
+ VOID *client_context)
+{
+UINT status;
+NX_AZURE_IOT_RESOURCE *resource_ptr;
+
+ if ((nx_azure_iot_ptr == NX_NULL) || (hub_transport_ptr == NX_NULL) || (host_name == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub initialization fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ memset(hub_transport_ptr, 0, sizeof(NX_AZURE_IOT_HUB_TRANSPORT));
+
+ hub_transport_ptr -> nx_azure_iot_ptr = nx_azure_iot_ptr;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_crypto_array = crypto_array;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_crypto_array_size = crypto_array_size;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_cipher_map = cipher_map;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_cipher_map_size = cipher_map_size;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_metadata_ptr = metadata_memory;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_metadata_size = memory_size;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_trusted_certificate = trusted_certificate;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_hostname = host_name;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_hostname_length = host_name_length;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_client_context = client_context;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_client_id_get = client_id_get;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_username_get = username_get;
+
+ /* Set resource pointer. */
+ resource_ptr = &(hub_transport_ptr -> nx_azure_iot_hub_transport_resource);
+
+ /* Create MQTT client. */
+ status = _nxd_mqtt_client_cloud_create(&(resource_ptr -> resource_mqtt),
+ (CHAR *)nx_azure_iot_ptr -> nx_azure_iot_name,
+ "", 0,
+ nx_azure_iot_ptr -> nx_azure_iot_ip_ptr,
+ nx_azure_iot_ptr -> nx_azure_iot_pool_ptr,
+ &nx_azure_iot_ptr -> nx_azure_iot_cloud);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub initialization fail: MQTT CLIENT CREATE FAIL status: %d"), status);
+ return(status);
+ }
+
+ /* Set mqtt receive notify. */
+ status = nxd_mqtt_client_receive_notify_set(&(resource_ptr -> resource_mqtt),
+ nx_azure_iot_hub_transport_mqtt_receive_callback);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub set message callback status: %d"), status);
+ nxd_mqtt_client_delete(&(resource_ptr -> resource_mqtt));
+ return(status);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Link the resource. */
+ resource_ptr -> resource_data_ptr = (VOID *)hub_transport_ptr;
+ resource_ptr -> resource_type = NX_AZURE_IOT_RESOURCE_IOT_HUB;
+ nx_azure_iot_resource_add(nx_azure_iot_ptr, resource_ptr);
+
+ /* Release the mutex. */
+ tx_mutex_put(nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_deinitialize(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr)
+{
+UINT status;
+
+ /* Check for invalid input pointers. */
+ if ((hub_transport_ptr == NX_NULL) || (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub deinitialize fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ nx_azure_iot_hub_transport_disconnect(hub_transport_ptr);
+
+ status = nxd_mqtt_client_delete(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt));
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub client delete fail status: %d"), status);
+ return(status);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Remove resource from list. */
+ status = nx_azure_iot_resource_remove(hub_transport_ptr -> nx_azure_iot_ptr,
+ &(hub_transport_ptr -> nx_azure_iot_hub_transport_resource));
+ if (status)
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ LogError(LogLiteralArgs("IoTHub client handle not found"));
+ return(status);
+ }
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_device_cert_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_SECURE_X509_CERT *device_certificate)
+{
+ if ((hub_transport_ptr == NX_NULL) ||
+ (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL) ||
+ (device_certificate == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub device certificate set fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_device_certificate = device_certificate;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_symmetric_key_auth_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ const NX_AZURE_IOT_HUB_TRANSPORT_SIGNATURE_GET_FN sas_signature_get,
+ const NX_AZURE_IOT_HUB_TRANSPORT_PASSWORD_GET_FN sas_password_get,
+ const UCHAR *symmetric_key, UINT symmetric_key_length)
+{
+ if ((hub_transport_ptr == NX_NULL) || (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL) ||
+ (symmetric_key == NX_NULL) || (symmetric_key_length == 0))
+ {
+ LogError(LogLiteralArgs("IoTHub symmetric key fail: Invalid argument"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_symmetric_key = symmetric_key;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_symmetric_key_length = symmetric_key_length;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_sas_signature = sas_signature_get;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_sas_password = sas_password_get;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_token_refresh = nx_azure_iot_hub_transport_sas_token_get;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_connection_callback_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_CONNECTION_STATUS_CB connection_cb,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg)
+{
+ if ((hub_transport_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub set connection cb fail: Invalid argument"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Set callback function for disconnection. */
+ nxd_mqtt_client_disconnect_notify_set(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ nx_azure_iot_hub_transport_mqtt_disconnect_notify);
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback = connection_cb;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_connection_status_callback_arg = arg;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_connect(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT clean_session, UINT wait_option)
+{
+UINT status;
+NXD_ADDRESS server_address;
+NX_AZURE_IOT_RESOURCE *resource_ptr;
+NXD_MQTT_CLIENT *mqtt_client_ptr;
+UCHAR *buffer_ptr;
+UINT buffer_size;
+VOID *buffer_context;
+UINT buffer_length;
+ULONG expiry_time_secs;
+az_result core_result;
+
+ /* Check for invalid input pointers. */
+ if ((hub_transport_ptr == NX_NULL) || (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub connect fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Check for status. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_state == NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+ LogError(LogLiteralArgs("IoTHub already connected"));
+ return(NX_AZURE_IOT_ALREADY_CONNECTED);
+ }
+ else if (hub_transport_ptr -> nx_azure_iot_hub_transport_state == NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTING)
+ {
+ LogError(LogLiteralArgs("IoTHub is connecting"));
+ return(NX_AZURE_IOT_CONNECTING);
+ }
+
+ /* Resolve the host name. */
+ /* Note: always using default dns timeout. */
+ status = nxd_dns_host_by_name_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_dns_ptr,
+ (UCHAR *)hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_hostname,
+ &server_address, NX_AZURE_IOT_HUB_TRANSPORT_DNS_TIMEOUT, NX_IP_VERSION_V4);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub connect fail: DNS RESOLVE FAIL status: %d"), status);
+ return(status);
+ }
+
+ /* Allocate buffer for client id, username and sas token. */
+ status = nx_azure_iot_buffer_allocate(hub_transport_ptr -> nx_azure_iot_ptr,
+ &buffer_ptr, &buffer_size, &buffer_context);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub failed initialization: BUFFER ALLOCATE FAIL"));
+ return(status);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Set resource pointer and buffer context. */
+ resource_ptr = &(hub_transport_ptr -> nx_azure_iot_hub_transport_resource);
+
+ /* Build client id. */
+ buffer_length = buffer_size;
+ core_result = hub_transport_ptr -> nx_azure_iot_hub_transport_client_id_get(hub_transport_ptr,
+ buffer_ptr, buffer_length,
+ &buffer_length);
+ if (az_result_failed(core_result))
+ {
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ nx_azure_iot_buffer_free(buffer_context);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ resource_ptr -> resource_mqtt_client_id = buffer_ptr;
+ resource_ptr -> resource_mqtt_client_id_length = buffer_length;
+
+ /* Update buffer for user name. */
+ buffer_ptr += resource_ptr -> resource_mqtt_client_id_length;
+ buffer_size -= resource_ptr -> resource_mqtt_client_id_length;
+
+ /* Build user name. */
+ buffer_length = buffer_size;
+ core_result = hub_transport_ptr -> nx_azure_iot_hub_transport_username_get(hub_transport_ptr,
+ buffer_ptr, buffer_length,
+ &buffer_length);
+ if (az_result_failed(core_result))
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ nx_azure_iot_buffer_free(buffer_context);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ resource_ptr -> resource_mqtt_user_name = buffer_ptr;
+ resource_ptr -> resource_mqtt_user_name_length = buffer_length;
+
+ /* Build sas token. */
+ resource_ptr -> resource_mqtt_sas_token = buffer_ptr + buffer_length;
+ resource_ptr -> resource_mqtt_sas_token_length = buffer_size - buffer_length;
+
+ /* Check if token refersh is setup. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_token_refresh)
+ {
+ status = nx_azure_iot_unix_time_get(hub_transport_ptr -> nx_azure_iot_ptr, &expiry_time_secs);
+ if (status)
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ nx_azure_iot_buffer_free(buffer_context);
+ LogError(LogLiteralArgs("IoTHub connect fail: unixtime get failed status: %d"), status);
+ return(status);
+ }
+
+ expiry_time_secs += NX_AZURE_IOT_HUB_TRANSPORT_TOKEN_EXPIRY;
+ if ((status = hub_transport_ptr -> nx_azure_iot_hub_transport_token_refresh(hub_transport_ptr,
+ expiry_time_secs,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_symmetric_key,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_symmetric_key_length,
+ resource_ptr -> resource_mqtt_sas_token,
+ resource_ptr -> resource_mqtt_sas_token_length,
+ &(resource_ptr -> resource_mqtt_sas_token_length))))
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ nx_azure_iot_buffer_free(buffer_context);
+ LogError(LogLiteralArgs("IoTHub connect fail: Token generation failed status: %d"), status);
+ return(status);
+ }
+ }
+ else
+ {
+ resource_ptr -> resource_mqtt_sas_token_length = 0;
+ }
+
+ mqtt_client_ptr = &(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt);
+
+ /* Update client id. */
+ mqtt_client_ptr -> nxd_mqtt_client_id = (CHAR *)resource_ptr -> resource_mqtt_client_id;
+ mqtt_client_ptr -> nxd_mqtt_client_id_length = resource_ptr -> resource_mqtt_client_id_length;
+
+ /* Set login info. */
+ status = nxd_mqtt_client_login_set(&(resource_ptr -> resource_mqtt),
+ (CHAR *)resource_ptr -> resource_mqtt_user_name,
+ resource_ptr -> resource_mqtt_user_name_length,
+ (CHAR *)resource_ptr -> resource_mqtt_sas_token,
+ resource_ptr -> resource_mqtt_sas_token_length);
+ if (status)
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ nx_azure_iot_buffer_free(buffer_context);
+ LogError(LogLiteralArgs("IoTHub connect fail: MQTT CLIENT LOGIN SET FAIL status: %d"), status);
+ return(status);
+ }
+
+ /* Set connect notify for non-blocking mode. */
+ if (wait_option == 0)
+ {
+ mqtt_client_ptr -> nxd_mqtt_connect_notify = nx_azure_iot_hub_transport_mqtt_connect_notify;
+ mqtt_client_ptr -> nxd_mqtt_connect_context = hub_transport_ptr;
+ }
+
+ /* Save the resource buffer. */
+ resource_ptr -> resource_mqtt_buffer_context = buffer_context;
+ resource_ptr -> resource_mqtt_buffer_size = buffer_size;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ /* Start MQTT connection. */
+ status = nxd_mqtt_client_secure_connect(mqtt_client_ptr, &server_address, NXD_MQTT_TLS_PORT,
+ nx_azure_iot_mqtt_tls_setup, NX_AZURE_IOT_MQTT_KEEP_ALIVE,
+ clean_session, wait_option);
+
+ /* Check status for non-blocking mode. */
+ if ((wait_option == 0) && (status == NX_IN_PROGRESS))
+ {
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTING;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ /* Return in-progress completion status. */
+ return(NX_AZURE_IOT_CONNECTING);
+ }
+
+ /* Call notify in synchronous way */
+ nx_azure_iot_hub_transport_mqtt_connect_notify(mqtt_client_ptr, status, (VOID *)hub_transport_ptr);
+
+ return(status);
+}
+
+UINT nx_azure_iot_hub_transport_disconnect(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr)
+{
+UINT status;
+NX_AZURE_IOT_THREAD *thread_list_ptr;
+
+ /* Check for invalid input pointers. */
+ if ((hub_transport_ptr == NX_NULL) || (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub client disconnect fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Disconnect. */
+ status = nxd_mqtt_client_disconnect(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt));
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub disconnect fail status: %d"), status);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Release the mqtt connection resource. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context)
+ {
+ nx_azure_iot_buffer_free(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context);
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt_buffer_context = NX_NULL;
+ }
+
+ /* Wakeup all suspend threads. */
+ for (thread_list_ptr = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ thread_list_ptr;
+ thread_list_ptr = thread_list_ptr -> thread_next)
+ {
+ tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
+ }
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_state = NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED;
+
+ /* cleanup all the queues */
+ nx_azure_iot_hub_transport_received_message_cleanup(hub_transport_ptr);
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(status);
+}
+
+UINT nx_azure_iot_hub_transport_receive_message_enable(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr, UINT message_queue_index,
+ const UCHAR *message_topic_ptr, UINT message_topic_length,
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_PROCESS_FN message_process)
+{
+UINT status;
+
+ if ((hub_transport_ptr == NX_NULL) ||
+ (message_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive message process fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_ptr = message_topic_ptr;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_length = message_topic_length;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_process = message_process;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_control_flag |= NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE;
+
+ /* Register callbacks even if not connect and when connect complete subscribe for topics. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_state != NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ status = nx_azure_iot_hub_transport_message_subscribe(hub_transport_ptr, message_queue_index);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive subscribe fail: %d"), status);
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_receive_message_disable(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT message_queue_index)
+{
+UINT status;
+
+ if ((hub_transport_ptr == NX_NULL) ||
+ (message_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive message process fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_ptr == NX_NULL)
+ {
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ status = nxd_mqtt_client_unsubscribe(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ (CHAR *)hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_ptr,
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_length);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive topic unsubscribe fail status: %d"), status);
+ return(status);
+ }
+
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_sub_packet_id = 0;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack &= ~(UINT)(0x1 << message_queue_index);
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_ptr = NX_NULL;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_topic_length = 0;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_process = NX_NULL;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_control_flag &= (USHORT)(~NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE);
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_receive_message_callback_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr, UINT message_queue_index,
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_CB_FN message_callback,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1, VOID *arg2)
+{
+ if ((hub_transport_ptr == NX_NULL) ||
+ (message_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE) ||
+ (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive message set callback fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_callback = message_callback;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_callback_arg1 = arg1;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_callback_arg2 = arg2;
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_receive_message_is_subscribed(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT message_queue_index, UINT wait_option)
+{
+ if ((hub_transport_ptr == NX_NULL) ||
+ (message_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive message is subscribed fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Wait for subscribe ack. */
+ while (1)
+ {
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ if (!(hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_control_flag &
+ NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive message is subscribed fail: not enabled"));
+ return(NX_AZURE_IOT_NOT_ENABLED);
+ }
+
+ /* Check if it is still in connected status. */
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_state != NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+
+ /* Clean ack receive notify. */
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ return(NX_AZURE_IOT_DISCONNECTED);
+ }
+
+ if (hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack == 0)
+ {
+ /* Clean ack receive notify. */
+ hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt.nxd_mqtt_ack_receive_notify = NX_NULL;
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ break;
+ }
+
+ /* Check if receive the subscribe ack. */
+ if ((hub_transport_ptr -> nx_azure_iot_hub_transport_message_pending_subscribe_ack & (UINT)(0x1 << message_queue_index)) == 0)
+ {
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ break;
+ }
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ /* Update wait time. */
+ if (wait_option != NX_WAIT_FOREVER)
+ {
+ if (wait_option > 0)
+ {
+ wait_option--;
+ }
+ else
+ {
+ return(NX_AZURE_IOT_NO_SUBSCRIBE_ACK);
+ }
+ }
+
+ tx_thread_sleep(1);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_message_receive(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT message_queue_index, UINT expected_id,
+ NX_PACKET **packet_pptr, UINT wait_option)
+{
+UINT status;
+
+ if ((hub_transport_ptr == NX_NULL) ||
+ (packet_pptr == NX_NULL) ||
+ (message_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport argument: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if ((hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index].message_control_flag &
+ NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE))
+ {
+ status = nx_azure_iot_hub_transport_message_receive_internal(hub_transport_ptr, message_queue_index, expected_id,
+ &(hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index]),
+ packet_pptr, wait_option);
+ }
+ else
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive queue not enabled for message_queue_index : %d"), message_queue_index);
+ status = NX_AZURE_IOT_NOT_ENABLED;
+ }
+
+ return(status);
+}
+
+UINT nx_azure_iot_hub_transport_receive_notify(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_PACKET *packet_ptr, UINT message_queue_index,
+ UINT correlation_id)
+{
+NX_AZURE_IOT_THREAD *thread_list_prev = NX_NULL;
+NX_AZURE_IOT_THREAD *thread_list_ptr;
+NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE *receive_message = NX_NULL;
+
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Search thread waiting for message type. */
+ for (thread_list_ptr = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ thread_list_ptr;
+ thread_list_ptr = thread_list_ptr -> thread_next)
+ {
+
+ /* Each queue point to messages of particular type */
+ if ((thread_list_ptr -> thread_message_type == message_queue_index) &&
+ (correlation_id == thread_list_ptr -> thread_expected_id))
+ {
+
+ /* Found a thread waiting for message type. */
+ if (thread_list_prev == NX_NULL)
+ {
+ hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended = thread_list_ptr -> thread_next;
+ }
+ else
+ {
+ thread_list_prev -> thread_next = thread_list_ptr -> thread_next;
+ }
+
+ thread_list_ptr -> thread_received_message = packet_ptr;
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ tx_thread_wait_abort(thread_list_ptr -> thread_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ thread_list_prev = thread_list_ptr;
+ }
+
+ /* Check if queue exist for this message type and then notify using callback if present */
+ if (message_queue_index < NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE)
+ {
+ receive_message = &(hub_transport_ptr -> nx_azure_iot_hub_transport_message[message_queue_index]);
+
+ if (receive_message -> message_tail)
+ {
+ receive_message -> message_tail -> nx_packet_queue_next = packet_ptr;
+ }
+ else
+ {
+ receive_message -> message_head = packet_ptr;
+ }
+ receive_message -> message_tail = packet_ptr;
+
+ /* Check for user callback function. */
+ if (receive_message -> message_callback)
+ {
+ receive_message -> message_callback(hub_transport_ptr,
+ receive_message -> message_callback_arg1,
+ receive_message -> message_callback_arg2);
+ }
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_NOT_FOUND);
+}
+
+UINT nx_azure_iot_hub_transport_request_response(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT request_id, NX_PACKET *packet_ptr, ULONG topic_length,
+ const UCHAR *message_buffer, UINT message_length, UINT response_queue_index,
+ NX_PACKET **response_packet_pptr, UINT wait_option)
+{
+NX_AZURE_IOT_THREAD thread_list;
+UINT status;
+
+ if ((hub_transport_ptr == NX_NULL) ||
+ (response_queue_index >= NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport request response argument: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if (!(hub_transport_ptr -> nx_azure_iot_hub_transport_message[response_queue_index].message_control_flag &
+ NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE))
+ {
+ LogError(LogLiteralArgs("IoTHub transport receive queue not enabled for response_queue_index : %d"), response_queue_index);
+ return(NX_AZURE_IOT_NOT_ENABLED);
+ }
+
+ if ((message_buffer != NX_NULL) && (message_length != 0))
+ {
+
+ /* Append payload. */
+ status = nx_packet_data_append(packet_ptr, (VOID *)message_buffer, message_length,
+ packet_ptr -> nx_packet_pool_owner,
+ wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub client reported state send fail: append failed"));
+ return(status);
+ }
+ }
+
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ thread_list.thread_message_type = response_queue_index;
+ thread_list.thread_ptr = tx_thread_identify();
+ thread_list.thread_expected_id = request_id;
+ thread_list.thread_received_message = NX_NULL;
+ thread_list.thread_next = hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended;
+ hub_transport_ptr -> nx_azure_iot_hub_transport_thread_suspended = &thread_list;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ status = nx_azure_iot_publish_mqtt_packet(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ packet_ptr, topic_length, NX_NULL, NX_AZURE_IOT_MQTT_QOS_0,
+ wait_option);
+
+ if (status)
+ {
+ /* remove thread from waiting suspend queue. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+ nx_azure_iot_hub_transport_thread_dequeue(hub_transport_ptr, &thread_list);
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ LogError(LogLiteralArgs("IoTHub transport send: PUBLISH FAIL status: %d"), status);
+ return(status);
+ }
+
+ if ((thread_list.thread_received_message) == NX_NULL && wait_option)
+ {
+ tx_thread_sleep(wait_option);
+ }
+
+ /* Obtain the mutex. */
+ tx_mutex_get(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ nx_azure_iot_hub_transport_thread_dequeue(hub_transport_ptr, &thread_list);
+ *response_packet_pptr = thread_list.thread_received_message;
+
+ /* Release the mutex. */
+ tx_mutex_put(hub_transport_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_publish(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr, NX_PACKET *packet_ptr,
+ const UCHAR *data, UINT data_size, UINT qos, UINT wait_option)
+{
+UINT status;
+UINT topic_len;
+UCHAR packet_id[2];
+
+ if ((hub_transport_ptr == NX_NULL) || (packet_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub transport publish fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ topic_len = packet_ptr -> nx_packet_length;
+
+ if (qos != 0)
+ {
+ status = nx_azure_iot_mqtt_packet_id_get(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ packet_id, wait_option);
+
+ if (status)
+ {
+ LogError(LogLiteralArgs("Failed to get packet id"));
+ return(status);
+ }
+
+ /* Append packet identifier. */
+ status = nx_packet_data_append(packet_ptr, packet_id, sizeof(packet_id),
+ packet_ptr -> nx_packet_pool_owner,
+ wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("packet id append fail"));
+ return(status);
+ }
+ }
+
+ if (data && (data_size != 0))
+ {
+
+ /* Append payload. */
+ status = nx_packet_data_append(packet_ptr, (VOID *)data, data_size,
+ packet_ptr -> nx_packet_pool_owner,
+ wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("data append fail"));
+ return(status);
+ }
+ }
+
+ status = nx_azure_iot_publish_mqtt_packet(&(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ packet_ptr, topic_len, packet_id, qos, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTHub transport send fail: PUBLISH FAIL status: %d"), status);
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_process_publish_packet(UCHAR *start_ptr, ULONG *topic_offset_ptr,
+ USHORT *topic_length_ptr)
+{
+UCHAR *byte = start_ptr;
+UINT byte_count = 0;
+UINT multiplier = 1;
+UINT remaining_length = 0;
+UINT topic_length;
+
+ /* Validate packet start contains fixed header. */
+ do
+ {
+ if (byte_count >= 4)
+ {
+ LogError(LogLiteralArgs("Invalid mqtt packet start position"));
+ return(NX_AZURE_IOT_INVALID_PACKET);
+ }
+
+ byte++;
+ remaining_length += (((*byte) & 0x7F) * multiplier);
+ multiplier = multiplier << 7;
+ byte_count++;
+ } while ((*byte) & 0x80);
+
+ if (remaining_length < 2)
+ {
+ return(NX_AZURE_IOT_INVALID_PACKET);
+ }
+
+ /* Retrieve topic length. */
+ byte++;
+ topic_length = (UINT)(*(byte) << 8) | (*(byte + 1));
+
+ if (topic_length > remaining_length - 2u)
+ {
+ return(NX_AZURE_IOT_INVALID_PACKET);
+ }
+
+ *topic_offset_ptr = (ULONG)((byte + 2) - start_ptr);
+ *topic_length_ptr = (USHORT)topic_length;
+
+ /* Return. */
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_adjust_payload(NX_PACKET *packet_ptr)
+{
+UINT status;
+ULONG topic_offset;
+USHORT topic_length;
+ULONG message_offset;
+ULONG message_length;
+
+ status = _nxd_mqtt_process_publish_packet(packet_ptr, &topic_offset,
+ &topic_length, &message_offset,
+ &message_length);
+ if (status)
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ packet_ptr -> nx_packet_length = message_length;
+
+ /* Adjust packet to pointer to message payload. */
+ while (packet_ptr)
+ {
+ if ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > message_offset)
+ {
+
+ /* This packet contains message payload. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + message_offset;
+ break;
+ }
+
+ message_offset -= (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
+
+ /* Set current packet to empty. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_append_ptr;
+
+ /* Move to next packet. */
+ packet_ptr = packet_ptr -> nx_packet_next;
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_hub_transport_publish_packet_get(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ NX_PACKET **packet_pptr, UINT wait_option)
+{
+ if ((hub_transport_ptr == NX_NULL) ||
+ (hub_transport_ptr -> nx_azure_iot_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTHub transport publish packet get: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_publish_packet_get(hub_transport_ptr -> nx_azure_iot_ptr,
+ &(hub_transport_ptr -> nx_azure_iot_hub_transport_resource.resource_mqtt),
+ packet_pptr, wait_option));
+}
diff --git a/addons/azure_iot/nx_azure_iot_hub_transport.h b/addons/azure_iot/nx_azure_iot_hub_transport.h
new file mode 100644
index 00000000..685e3399
--- /dev/null
+++ b/addons/azure_iot/nx_azure_iot_hub_transport.h
@@ -0,0 +1,216 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/* Version: 6.1 PnP Preview 1 */
+
+/**
+ * @file nx_azure_iot_hub_transport.h
+ *
+ *
+ */
+
+#ifndef NX_AZURE_IOT_HUB_TRANSPORT_H
+#define NX_AZURE_IOT_HUB_TRANSPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "azure/core/az_result.h"
+#include "azure/core/az_span.h"
+#include "nx_azure_iot.h"
+#include "nx_api.h"
+#include "nx_cloud.h"
+#include "nxd_dns.h"
+#include "nxd_mqtt_client.h"
+
+#define NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE 5
+
+/* Set the default timeout for DNS query. */
+#ifndef NX_AZURE_IOT_HUB_TRANSPORT_DNS_TIMEOUT
+#ifndef NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT
+#define NX_AZURE_IOT_HUB_TRANSPORT_DNS_TIMEOUT (5 * NX_IP_PERIODIC_RATE)
+#else
+#define NX_AZURE_IOT_HUB_TRANSPORT_DNS_TIMEOUT NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT
+#endif /* NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT */
+#endif /* NX_AZURE_IOT_HUB_TRANSPORT_DNS_TIMEOUT */
+
+
+/* Set the default token expiry in secs. */
+#ifndef NX_AZURE_IOT_HUB_TRANSPORT_TOKEN_EXPIRY
+#ifndef NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY
+#define NX_AZURE_IOT_HUB_TRANSPORT_TOKEN_EXPIRY (3600)
+#else
+#define NX_AZURE_IOT_HUB_TRANSPORT_TOKEN_EXPIRY NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY
+#endif /* NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY */
+#endif /* NX_AZURE_IOT_HUB_TRANSPORT_TOKEN_EXPIRY */
+
+/* Define AZ IoT Hub Client state. */
+/**< The client is not connected */
+#define NX_AZURE_IOT_HUB_TRANSPORT_STATUS_NOT_CONNECTED 0
+
+/**< The client is connecting */
+#define NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTING 1
+
+/**< The client is connected */
+#define NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED 2
+
+/* Default TELEMETRY QoS is QoS1 */
+#ifndef NX_AZURE_IOT_HUB_TRANSPORT_TELEMETRY_QOS
+#define NX_AZURE_IOT_HUB_TRANSPORT_TELEMETRY_QOS NX_AZURE_IOT_MQTT_QOS_1
+#endif /* NX_AZURE_IOT_HUB_TRANSPORT_TELEMETRY_QOS */
+
+#define NZ_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE (0x0001)
+
+/* Forward declaration */
+struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT;
+
+typedef VOID (*NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)(VOID);
+typedef VOID (*NX_AZURE_IOT_HUB_TRANSPORT_CONNECTION_STATUS_CB)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UINT status, NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg);
+typedef az_result (*NX_AZURE_IOT_HUB_TRANSPORT_CLIENT_ID_GET_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied);
+typedef az_result (*NX_AZURE_IOT_HUB_TRANSPORT_USERNAME_GET_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied);
+typedef az_result (*NX_AZURE_IOT_HUB_TRANSPORT_SIGNATURE_GET_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span buffer, az_span *out_buffer);
+typedef az_result (*NX_AZURE_IOT_HUB_TRANSPORT_PASSWORD_GET_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span hash_buffer, az_span key_name,
+ UCHAR *out_buffer, UINT out_buffer_len, UINT *bytes_copied);
+
+typedef VOID (*NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_CB_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1,
+ VOID *arg2);
+typedef UINT (*NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_PROCESS_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, ULONG topic_offset, USHORT topic_length);
+typedef UINT (*NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_ENABLE_FN)(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr);
+
+typedef struct NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE_STRUCT
+{
+ NX_PACKET *message_head;
+ NX_PACKET *message_tail;
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_CB_FN message_callback;
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN message_callback_arg1;
+ VOID *message_callback_arg2;
+ const UCHAR *message_topic_ptr;
+ UINT message_topic_length;
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_PROCESS_FN message_process;
+ USHORT message_sub_packet_id;
+ USHORT message_control_flag;
+} NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE;
+
+/**
+ * @brief Azure IoT Hub transport struct
+ *
+ */
+typedef struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT
+{
+ NX_AZURE_IOT *nx_azure_iot_ptr;
+
+ UINT nx_azure_iot_hub_transport_state;
+
+ UINT nx_azure_iot_hub_transport_request_id;
+ const UCHAR *nx_azure_iot_hub_transport_symmetric_key;
+ UINT nx_azure_iot_hub_transport_symmetric_key_length;
+ NX_AZURE_IOT_RESOURCE nx_azure_iot_hub_transport_resource;
+
+ VOID *nx_azure_iot_hub_transport_client_context;
+
+ NX_AZURE_IOT_HUB_TRANSPORT_CONNECTION_STATUS_CB nx_azure_iot_hub_transport_connection_status_callback;
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN nx_azure_iot_hub_transport_connection_status_callback_arg;
+ UINT (*nx_azure_iot_hub_transport_token_refresh)(
+ struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
+ UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length);
+
+ NX_AZURE_IOT_HUB_TRANSPORT_CLIENT_ID_GET_FN nx_azure_iot_hub_transport_client_id_get;
+ NX_AZURE_IOT_HUB_TRANSPORT_USERNAME_GET_FN nx_azure_iot_hub_transport_username_get;
+ NX_AZURE_IOT_HUB_TRANSPORT_SIGNATURE_GET_FN nx_azure_iot_hub_transport_sas_signature;
+ NX_AZURE_IOT_HUB_TRANSPORT_PASSWORD_GET_FN nx_azure_iot_hub_transport_sas_password;
+
+
+ NX_AZURE_IOT_THREAD *nx_azure_iot_hub_transport_thread_suspended;
+ NX_AZURE_IOT_HUB_TRANSPORT_RECEIVE_MESSAGE nx_azure_iot_hub_transport_message[NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE];
+ volatile UINT nx_azure_iot_hub_transport_message_pending_subscribe_ack;
+} NX_AZURE_IOT_HUB_TRANSPORT;
+
+
+UINT nx_azure_iot_hub_transport_initialize(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT *nx_azure_iot_ptr,
+ const UCHAR *host_name, UINT host_name_length,
+ const NX_AZURE_IOT_HUB_TRANSPORT_CLIENT_ID_GET_FN client_id_get,
+ const NX_AZURE_IOT_HUB_TRANSPORT_USERNAME_GET_FN username_get,
+ 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,
+ VOID *client_context);
+
+UINT nx_azure_iot_hub_transport_deinitialize(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr);
+
+UINT nx_azure_iot_hub_transport_device_cert_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_SECURE_X509_CERT *device_certificate);
+
+UINT nx_azure_iot_hub_transport_symmetric_key_auth_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ const NX_AZURE_IOT_HUB_TRANSPORT_SIGNATURE_GET_FN sas_signature_get,
+ const NX_AZURE_IOT_HUB_TRANSPORT_PASSWORD_GET_FN sas_password_get,
+ const UCHAR *symmetric_key, UINT symmetric_key_length);
+
+UINT nx_azure_iot_hub_transport_connection_callback_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_CONNECTION_STATUS_CB connection_cb,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg);
+
+UINT nx_azure_iot_hub_transport_connect(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT clean_session, UINT wait_option);
+
+UINT nx_azure_iot_hub_transport_disconnect(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr);
+
+UINT nx_azure_iot_hub_transport_receive_message_enable(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr, UINT message_queue_index,
+ const UCHAR *message_topic_ptr, UINT message_topic_length,
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_PROCESS_FN message_process);
+
+UINT nx_azure_iot_hub_transport_receive_message_disable(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT message_queue_index);
+
+UINT nx_azure_iot_hub_transport_receive_message_callback_set(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr, UINT message_queue_index,
+ NX_AZURE_IOT_HUB_TRANSPORT_MESSAGE_CB_FN message_callback,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1, VOID *arg2);
+
+UINT nx_azure_iot_hub_transport_receive_message_is_subscribed(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT message_queue_index, UINT wait_option);
+
+UINT nx_azure_iot_hub_transport_message_receive(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT message_queue_index, UINT expected_id,
+ NX_PACKET **packet_pptr, UINT wait_option);
+
+UINT nx_azure_iot_hub_transport_receive_notify(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr, UINT message_queue_index,
+ UINT correlation_id);
+
+UINT nx_azure_iot_hub_transport_request_response(NX_AZURE_IOT_HUB_TRANSPORT *hub_transport_ptr,
+ UINT request_id, NX_PACKET *packet_ptr, ULONG topic_length,
+ const UCHAR *message_buffer, UINT message_length, UINT response_queue_index,
+ NX_PACKET **response_packet_pptr, UINT wait_option);
+
+UINT nx_azure_iot_hub_transport_publish(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr, NX_PACKET *packet_ptr,
+ const UCHAR *data, UINT data_size, UINT qos, UINT wait_option);
+
+UINT nx_azure_iot_hub_transport_process_publish_packet(UCHAR *start_ptr, ULONG *topic_offset_ptr,
+ USHORT *topic_length_ptr);
+
+UINT nx_azure_iot_hub_transport_adjust_payload(NX_PACKET *packet_ptr);
+
+UINT nx_azure_iot_hub_transport_publish_packet_get(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET **packet_pptr, UINT wait_option);
+#ifdef __cplusplus
+}
+#endif
+#endif /* NX_AZURE_IOT_HUB_TRANSPORT_H */
diff --git a/addons/azure_iot/nx_azure_iot_json_reader.c b/addons/azure_iot/nx_azure_iot_json_reader.c
index cd480db3..0e5713c8 100644
--- a/addons/azure_iot/nx_azure_iot_json_reader.c
+++ b/addons/azure_iot/nx_azure_iot_json_reader.c
@@ -9,25 +9,56 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
#include "nx_azure_iot_json_reader.h"
#include "nx_azure_iot.h"
+static UINT nx_azure_iot_json_reader_translate_error_code(NX_AZURE_IOT_JSON_READER *reader_ptr,
+ az_result core_result)
+{
+ if (az_result_failed(core_result))
+ {
+ if (core_result == AZ_ERROR_JSON_READER_DONE)
+ {
+ return(NX_AZURE_IOT_NOT_FOUND);
+ }
+
+ if (reader_ptr -> json_length == 0)
+ {
+ return(NX_AZURE_IOT_EMPTY_JSON);
+ }
+
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
UINT nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
const UCHAR *buffer_ptr, UINT buffer_len)
{
az_span span = az_span_create((UCHAR *)buffer_ptr, (INT)buffer_len);
if ((reader_ptr == NX_NULL) ||
- (buffer_ptr == NX_NULL) || (buffer_len == 0))
+ (buffer_ptr == NX_NULL))
{
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
memset(reader_ptr, 0, sizeof(NX_AZURE_IOT_JSON_READER));
+ /* Allow initializing with zero size buffer, as any futher call will fail for empty JSON */
+ if (buffer_len == 0)
+ {
+ reader_ptr -> json_reader.token.kind = AZ_JSON_TOKEN_NONE;
+
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ reader_ptr -> json_length = (ULONG)buffer_len;
+
if (az_result_failed(az_json_reader_init(&(reader_ptr -> json_reader),
span, NX_NULL)))
{
@@ -43,8 +74,7 @@ UINT nx_azure_iot_json_reader_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
UINT count = 0;
if ((reader_ptr == NX_NULL) ||
- (packet_ptr == NX_NULL) ||
- (packet_ptr -> nx_packet_length == 0))
+ (packet_ptr == NX_NULL))
{
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
@@ -53,6 +83,16 @@ UINT count = 0;
reader_ptr -> packet_ptr = packet_ptr;
+ /* Allow initializing with zero size packet, as any futher call will fail for empty JSON */
+ if (packet_ptr -> nx_packet_length == 0)
+ {
+ reader_ptr -> json_reader.token.kind = AZ_JSON_TOKEN_NONE;
+
+ return(NX_AZURE_IOT_SUCCESS);
+ }
+
+ reader_ptr -> json_length = packet_ptr -> nx_packet_length;
+
while (packet_ptr != NX_NULL)
{
if (count >= NX_AZURE_IOT_READER_MAX_LIST)
@@ -110,32 +150,30 @@ az_span span = az_span_create(value_ptr, (INT)value_len);
UINT nx_azure_iot_json_reader_next_token(NX_AZURE_IOT_JSON_READER *reader_ptr)
{
+az_result core_result;
+
if ((reader_ptr == NX_NULL))
{
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- if (az_result_failed(az_json_reader_next_token(&(reader_ptr -> json_reader))))
- {
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
+ core_result = az_json_reader_next_token(&(reader_ptr -> json_reader));
+
+ return(nx_azure_iot_json_reader_translate_error_code(reader_ptr, core_result));
}
UINT nx_azure_iot_json_reader_skip_children(NX_AZURE_IOT_JSON_READER *reader_ptr)
{
+az_result core_result;
+
if ((reader_ptr == NX_NULL))
{
return(NX_AZURE_IOT_INVALID_PARAMETER);
}
- if (az_result_failed(az_json_reader_skip_children(&(reader_ptr -> json_reader))))
- {
- return(NX_AZURE_IOT_SDK_CORE_ERROR);
- }
+ core_result = az_json_reader_skip_children(&(reader_ptr -> json_reader));
- return(NX_AZURE_IOT_SUCCESS);
+ return(nx_azure_iot_json_reader_translate_error_code(reader_ptr, core_result));
}
UINT nx_azure_iot_json_reader_token_bool_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
diff --git a/addons/azure_iot/nx_azure_iot_json_reader.h b/addons/azure_iot/nx_azure_iot_json_reader.h
index 7fefa51d..dbb1ecaa 100644
--- a/addons/azure_iot/nx_azure_iot_json_reader.h
+++ b/addons/azure_iot/nx_azure_iot_json_reader.h
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
/**
* @file nx_azure_iot_json_reader.h
@@ -54,6 +54,7 @@ typedef struct NX_AZURE_IOT_READER_STRUCT
NX_PACKET *packet_ptr;
az_json_reader json_reader;
az_span span_list[NX_AZURE_IOT_READER_MAX_LIST];
+ ULONG json_length;
} NX_AZURE_IOT_JSON_READER;
/**
@@ -68,7 +69,6 @@ typedef struct NX_AZURE_IOT_READER_STRUCT
* @retval #NX_AZURE_IOT_SUCCESS The #NX_AZURE_IOT_JSON_READER is initialized successfully.
* @retval other Initialization failed.
*
- * @remarks The provided json buffer must not be empty, as that is invalid JSON.
*/
UINT nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
const UCHAR *buffer_ptr, UINT buffer_len);
@@ -83,8 +83,6 @@ UINT nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER *reader_
* @retval #NX_AZURE_IOT_SUCCESS The #NX_AZURE_IOT_JSON_READER is initialized successfully.
* @retval other Initialization failed.
*
- * @remarks The provided json buffer must not be empty, as that is invalid JSON.
- *
* @remarks Ownership of #NX_PACKET is taken by the reader.
*/
UINT nx_azure_iot_json_reader_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
diff --git a/addons/azure_iot/nx_azure_iot_json_writer.c b/addons/azure_iot/nx_azure_iot_json_writer.c
index eb4e3c43..4b3f3be3 100644
--- a/addons/azure_iot/nx_azure_iot_json_writer.c
+++ b/addons/azure_iot/nx_azure_iot_json_writer.c
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
#include "nx_azure_iot_json_writer.h"
@@ -344,8 +344,6 @@ UINT nx_azure_iot_json_writer_append_begin_object(NX_AZURE_IOT_JSON_WRITER *json
return(NX_AZURE_IOT_SDK_CORE_ERROR);
}
- json_writer_ptr -> object_depth++;
-
nx_azure_iot_json_writer_packet_update(json_writer_ptr);
return(NX_AZURE_IOT_SUCCESS);
@@ -382,8 +380,6 @@ UINT nx_azure_iot_json_writer_append_end_object(NX_AZURE_IOT_JSON_WRITER *json_w
return(NX_AZURE_IOT_SDK_CORE_ERROR);
}
- json_writer_ptr -> object_depth--;
-
nx_azure_iot_json_writer_packet_update(json_writer_ptr);
return(NX_AZURE_IOT_SUCCESS);
diff --git a/addons/azure_iot/nx_azure_iot_json_writer.h b/addons/azure_iot/nx_azure_iot_json_writer.h
index e40b999f..0228f0b1 100644
--- a/addons/azure_iot/nx_azure_iot_json_writer.h
+++ b/addons/azure_iot/nx_azure_iot_json_writer.h
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
/**
* @file nx_azure_iot_json_writer.h
@@ -38,7 +38,6 @@ typedef struct NX_AZURE_IOT_JSON_WRITER_STRUCT
{
NX_PACKET *packet_ptr;
az_json_writer json_writer;
- UINT object_depth;
UINT wait_option;
ULONG nx_tail_packet_offset;
ULONG nx_packet_init_length;
diff --git a/addons/azure_iot/nx_azure_iot_pnp_client.c b/addons/azure_iot/nx_azure_iot_pnp_client.c
new file mode 100644
index 00000000..66f9fbab
--- /dev/null
+++ b/addons/azure_iot/nx_azure_iot_pnp_client.c
@@ -0,0 +1,1588 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/* Version: 6.1 PnP Preview 1 */
+
+#include "nx_azure_iot_pnp_client.h"
+
+#include "azure/core/az_version.h"
+
+#define NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE 10
+#define NX_AZURE_IOT_PNP_CLIENT_EMPTY_JSON "{}"
+#define NX_AZURE_IOT_PNP_CLIENT_THROTTLE_STATUS_CODE 429
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_USER_AGENT
+
+/* Useragent e.g: DeviceClientType=c%2F1.0.0-preview.1%20%28nx%206.0%3Bazrtos%206.0%29 */
+#define NX_AZURE_IOT_PNP_CLIENT_STR(C) #C
+#define NX_AZURE_IOT_PNP_CLIENT_TO_STR(x) NX_AZURE_IOT_PNP_CLIENT_STR(x)
+#define NX_AZURE_IOT_PNP_CLIENT_USER_AGENT "DeviceClientType=c%2F" AZ_SDK_VERSION_STRING "%20%28nx%20" \
+ NX_AZURE_IOT_PNP_CLIENT_TO_STR(NETXDUO_MAJOR_VERSION) "." \
+ NX_AZURE_IOT_PNP_CLIENT_TO_STR(NETXDUO_MINOR_VERSION) "%3Bazrtos%20"\
+ NX_AZURE_IOT_PNP_CLIENT_TO_STR(THREADX_MAJOR_VERSION) "." \
+ NX_AZURE_IOT_PNP_CLIENT_TO_STR(THREADX_MINOR_VERSION) "%29"
+#endif /* NX_AZURE_IOT_PNP_CLIENT_USER_AGENT */
+
+/* Queue index used in transport to receive the messages */
+#define NX_AZURE_IOT_PNP_COMMAND_QUEUE_INDEX 0
+#define NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX 1
+#define NX_AZURE_IOT_PNP_DESIRED_PROPERTIES_QUEUE_INDEX 2
+#define NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX 3
+
+extern UINT _nxd_mqtt_process_publish_packet(NX_PACKET *packet_ptr, ULONG *topic_offset_ptr,
+ USHORT *topic_length_ptr, ULONG *message_offset_ptr,
+ ULONG *message_length_ptr);
+
+static UINT nx_azure_iot_pnp_client_mesg_type_to_queue_index(UINT message_type)
+{
+UINT queue_index;
+
+ switch (message_type)
+ {
+ case NX_AZURE_IOT_PNP_COMMAND :
+ {
+ queue_index = NX_AZURE_IOT_PNP_COMMAND_QUEUE_INDEX;
+ }
+ break;
+
+ case NX_AZURE_IOT_PNP_PROPERTIES :
+ {
+ queue_index = NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX;
+ }
+ break;
+
+ case NX_AZURE_IOT_PNP_DESIRED_PROPERTIES :
+ {
+ queue_index = NX_AZURE_IOT_PNP_DESIRED_PROPERTIES_QUEUE_INDEX;
+ }
+ break;
+
+ case NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE :
+ {
+ queue_index = NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX;
+ }
+ break;
+
+ default :
+ {
+ /* no queue */
+ queue_index = NX_AZURE_IOT_HUB_TRANSPORT_MAX_NUM_RECEIVE_QUEUE;
+ }
+ break;
+ }
+
+ return(queue_index);
+}
+
+static UINT nx_azure_iot_pnp_client_command_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr,
+ ULONG topic_offset,
+ USHORT topic_length)
+{
+UCHAR *topic_name;
+az_iot_pnp_client_command_request request;
+az_span receive_topic;
+az_result core_result;
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ /* This function is protected by MQTT mutex. */
+
+ /* Check message type first. */
+ topic_name = &(packet_ptr -> nx_packet_prepend_ptr[topic_offset]);
+
+ /* NOTE: Current implementation does not support topic to span multiple packets. */
+ if ((ULONG)(packet_ptr -> nx_packet_append_ptr - topic_name) < topic_length)
+ {
+ LogError(LogLiteralArgs("topic out of boundaries of single packet"));
+ return(NX_AZURE_IOT_TOPIC_TOO_LONG);
+ }
+
+ receive_topic = az_span_create(topic_name, topic_length);
+ core_result = az_iot_pnp_client_commands_parse_received_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ receive_topic, &request);
+ if (az_result_failed(core_result))
+ {
+
+ /* Topic name does not match command format. */
+ return(NX_AZURE_IOT_NOT_FOUND);
+ }
+
+ return(nx_azure_iot_hub_transport_receive_notify(hub_trans_ptr, packet_ptr,
+ NX_AZURE_IOT_PNP_COMMAND_QUEUE_INDEX, 0));
+}
+
+static UINT nx_azure_iot_pnp_client_twin_request_id_get(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UCHAR *buffer_ptr, UINT buffer_len,
+ az_span *request_id_span_ptr,
+ UINT *request_id_ptr, UINT odd_seq)
+{
+az_span span;
+
+ /* Obtain the mutex. */
+ tx_mutex_get(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ /* Check if current request_id is even and new requested is also even or
+ current request_id is odd and new requested is also odd. */
+ if ((pnp_client_ptr -> nx_azure_iot_pnp_client_request_id & 0x1) == odd_seq)
+ {
+ pnp_client_ptr -> nx_azure_iot_pnp_client_request_id += 2;
+ }
+ else
+ {
+ pnp_client_ptr -> nx_azure_iot_pnp_client_request_id += 1;
+ }
+
+ if (pnp_client_ptr -> nx_azure_iot_pnp_client_request_id == 0)
+ {
+ pnp_client_ptr -> nx_azure_iot_pnp_client_request_id = 2;
+ }
+
+ *request_id_ptr = pnp_client_ptr -> nx_azure_iot_pnp_client_request_id;
+ span = az_span_create(buffer_ptr, (INT)buffer_len);
+ if (az_result_failed(az_span_u32toa(span, *request_id_ptr, &span)))
+ {
+
+ /* Release the mutex. */
+ tx_mutex_put(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ LogError(LogLiteralArgs("IoT PnP client device failed to u32toa"));
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ *request_id_span_ptr = az_span_create(buffer_ptr, (INT)(buffer_len - (UINT)az_span_size(span)));
+
+ /* Release the mutex. */
+ tx_mutex_put(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+static UINT nx_azure_iot_pnp_client_device_twin_message_type_get(az_iot_pnp_client_property_response *out_twin_response_ptr,
+ UINT request_id)
+{
+UINT message_type;
+
+ switch (out_twin_response_ptr -> response_type)
+ {
+ case AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_GET :
+
+ /* Fall through. */
+
+ case AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_REPORTED_PROPERTIES :
+ {
+
+ /* Odd requests are of reported properties and even of twin properties. */
+ message_type = request_id % 2 == 0 ? NX_AZURE_IOT_PNP_PROPERTIES :
+ NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE;
+ }
+ break;
+
+ case AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_DESIRED_PROPERTIES :
+ {
+ message_type = NX_AZURE_IOT_PNP_DESIRED_PROPERTIES;
+ }
+ break;
+
+ default :
+ {
+ message_type = NX_AZURE_IOT_PNP_NONE;
+ }
+ }
+
+ return message_type;
+}
+
+static UINT nx_azure_iot_pnp_client_device_twin_parse(NX_AZURE_IOT_PNP_CLIENT *pnp_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)
+{
+az_result core_result;
+az_span topic_span;
+az_iot_pnp_client_property_response out_twin_response;
+uint32_t request_id = 0;
+uint32_t version;
+
+ topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), (INT)topic_length);
+ core_result = az_iot_pnp_client_property_parse_received_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ topic_span, &out_twin_response);
+ if (az_result_failed(core_result))
+ {
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ if (version_ptr != NX_NULL && az_span_ptr(out_twin_response.version))
+ {
+ core_result = az_span_atou32(out_twin_response.version, &version);
+ if (az_result_failed(core_result))
+ {
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ *version_ptr = (ULONG)version;
+ }
+
+ if (az_span_ptr(out_twin_response.request_id))
+ {
+ core_result = az_span_atou32(out_twin_response.request_id, &request_id);
+ if (az_result_failed(core_result))
+ {
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+ }
+
+ if (request_id_ptr)
+ {
+ *request_id_ptr = (UINT)request_id;
+ }
+
+ if (message_type_ptr)
+ {
+ *message_type_ptr = nx_azure_iot_pnp_client_device_twin_message_type_get(&out_twin_response,
+ (UINT)request_id);
+ }
+
+ if (status_ptr)
+ {
+ *status_ptr = (UINT)out_twin_response.status;
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+static UINT nx_azure_iot_pnp_client_throttle_with_jitter(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr)
+{
+UINT jitter;
+UINT base_delay = NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC;
+UINT retry_count = pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_count;
+uint64_t delay;
+
+ if (retry_count < (sizeof(UINT) * 8 - 1))
+ {
+ retry_count++;
+ delay = (uint64_t)((1 << retry_count) * NX_AZURE_IOT_PNP_CLIENT_INITIAL_BACKOFF_IN_SEC);
+
+ if (delay <= (UINT)(-1))
+ {
+ base_delay = (UINT)delay;
+ }
+ }
+
+ if (base_delay > NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC)
+ {
+ base_delay = NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC;
+ }
+ else
+ {
+ pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_count = retry_count;
+ }
+
+ jitter = base_delay * NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_JITTER_PERCENT * (NX_RAND() & 0xFF) / 25600;
+ return((UINT)(base_delay + jitter));
+}
+
+static UINT nx_azure_iot_pnp_client_throttled_check(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr)
+{
+ULONG current_time;
+UINT status = NX_AZURE_IOT_SUCCESS;
+
+ if (pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_count != 0)
+ {
+ if ((status = nx_azure_iot_unix_time_get(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr, &current_time)))
+ {
+ LogError(LogLiteralArgs("IoT PnP client fail to get unix time: %d"), status);
+ return(status);
+ }
+
+ if (current_time < pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_end_time)
+ {
+ return(NX_AZURE_IOT_THROTTLED);
+ }
+ }
+
+ return(status);
+}
+
+static UINT nx_azure_iot_pnp_client_device_twin_process(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_PACKET *packet_ptr,
+ ULONG topic_offset,
+ USHORT topic_length)
+{
+UINT message_type;
+UINT response_status;
+UINT request_id = 0;
+ULONG version = 0;
+UINT correlation_id;
+UINT status;
+ULONG current_time;
+UINT message_queue_index;
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context ;
+
+ /* This function is protected by MQTT mutex. */
+ if ((status = nx_azure_iot_pnp_client_device_twin_parse(pnp_client_ptr, packet_ptr,
+ topic_offset, topic_length,
+ &request_id, &version,
+ &message_type, &response_status)))
+ {
+ return(status);
+ }
+
+ if (response_status == NX_AZURE_IOT_PNP_CLIENT_THROTTLE_STATUS_CODE)
+ {
+ if ((status = nx_azure_iot_unix_time_get(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr, &current_time)))
+ {
+ LogError(LogLiteralArgs("IoT PnP client fail to get unix time: %d"), status);
+ return(status);
+ }
+
+ pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_end_time =
+ current_time + nx_azure_iot_pnp_client_throttle_with_jitter(pnp_client_ptr);
+ }
+ else
+ {
+ pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_count = 0;
+ pnp_client_ptr -> nx_azure_iot_pnp_client_throttle_end_time = 0;
+ }
+
+ if (message_type == NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE)
+ {
+
+ /* Only requested thread should be woken. */
+ correlation_id = request_id;
+ }
+ else
+ {
+
+ /* Any thread can be woken. */
+ correlation_id = 0;
+ }
+
+ message_queue_index = nx_azure_iot_pnp_client_mesg_type_to_queue_index(message_type);
+ status = nx_azure_iot_hub_transport_receive_notify(hub_trans_ptr, packet_ptr,
+ message_queue_index, correlation_id);
+
+ return(status);
+}
+
+static az_result nx_azure_iot_pnp_client_client_id_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ return(az_iot_pnp_client_get_client_id(&(pnp_client_ptr -> iot_pnp_client_core),
+ (CHAR *)buffer, buffer_len, bytes_copied));
+}
+
+static az_result nx_azure_iot_pnp_client_username_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ UCHAR *buffer, UINT buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ return(az_iot_pnp_client_get_user_name(&pnp_client_ptr -> iot_pnp_client_core,
+ (CHAR *)buffer, buffer_len, bytes_copied));
+}
+
+static az_result nx_azure_iot_pnp_client_signature_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span buffer, az_span *out_buffer)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ return(az_iot_pnp_client_sas_get_signature(&(pnp_client_ptr -> iot_pnp_client_core),
+ expiry_time_secs, buffer, out_buffer));
+}
+
+static az_result nx_azure_iot_pnp_client_password_get(struct NX_AZURE_IOT_HUB_TRANSPORT_STRUCT *hub_trans_ptr,
+ ULONG expiry_time_secs, az_span hash_buffer, az_span key_name,
+ UCHAR *out_buffer, UINT out_buffer_len, UINT *bytes_copied)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ return(az_iot_pnp_client_sas_get_password(&(pnp_client_ptr -> iot_pnp_client_core),
+ expiry_time_secs, hash_buffer, key_name,
+ (CHAR *)out_buffer, out_buffer_len, bytes_copied));
+}
+
+static VOID nx_azure_iot_pnp_client_receive_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1,
+ VOID *arg2)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ ((VOID (*)(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr, VOID *args))arg1)(pnp_client_ptr, arg2);
+}
+
+static VOID nx_azure_iot_pnp_client_connection_status_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ UINT status, NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+
+ ((VOID (*)(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr, UINT status))arg)(pnp_client_ptr, status);
+}
+
+static VOID nx_azure_iot_pnp_client_reported_property_receive_callback(NX_AZURE_IOT_HUB_TRANSPORT *hub_trans_ptr,
+ NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN arg1,
+ VOID *arg2)
+{
+NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr = (NX_AZURE_IOT_PNP_CLIENT *)hub_trans_ptr -> nx_azure_iot_hub_transport_client_context;
+UINT status;
+NX_PACKET *packet_ptr;
+ULONG topic_offset;
+USHORT topic_length;
+UINT request_id;
+UINT response_status;
+ULONG version = 0;
+
+ if ((status = nx_azure_iot_hub_transport_message_receive(hub_trans_ptr,
+ NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX, 0,
+ &packet_ptr, NX_NO_WAIT)))
+ {
+ LogError(LogLiteralArgs("IoTHub failed to find reported property: %d"), status);
+ return;
+ }
+
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
+ {
+
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ return;
+ }
+
+ if ((status = nx_azure_iot_pnp_client_device_twin_parse(pnp_client_ptr, packet_ptr,
+ topic_offset, topic_length,
+ &request_id, &version,
+ NX_NULL, &response_status)))
+ {
+ nx_packet_release(packet_ptr);
+ return;
+ }
+
+ ((VOID (*)(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT request_id, UINT response_status,
+ ULONG version, VOID *arg))arg1)(pnp_client_ptr,
+ request_id,
+ response_status,
+ version,
+ arg2);
+ nx_packet_release(packet_ptr);
+}
+
+UINT nx_azure_iot_pnp_client_initialize(NX_AZURE_IOT_PNP_CLIENT *pnp_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 UCHAR *model_id, UINT model_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)
+{
+
+UINT status;
+az_span hostname_span = az_span_create((UCHAR *)host_name, (INT)host_name_length);
+az_span device_id_span = az_span_create((UCHAR *)device_id, (INT)device_id_length);
+az_span model_id_span = az_span_create((UCHAR *)model_id, (INT)model_id_length);
+az_iot_pnp_client_options options = az_iot_pnp_client_options_default();
+az_result core_result;
+
+ if ((nx_azure_iot_ptr == NX_NULL) || (pnp_client_ptr == NX_NULL) || (host_name == NX_NULL) ||
+ (device_id == NX_NULL) || (host_name_length == 0) || (device_id_length == 0) ||
+ (model_id == NX_NULL) || (model_id_length == 0))
+ {
+ LogError(LogLiteralArgs("IoT PnP client initialization fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ memset(pnp_client_ptr, 0, sizeof(NX_AZURE_IOT_PNP_CLIENT));
+
+ options.module_id = az_span_create((UCHAR *)module_id, (INT)module_id_length);
+ options.user_agent = AZ_SPAN_FROM_STR(NX_AZURE_IOT_PNP_CLIENT_USER_AGENT);
+ options.component_names = pnp_client_ptr -> nx_azure_iot_pnp_client_component_list;
+ options.component_names_length = 0;
+
+ core_result = az_iot_pnp_client_init(&pnp_client_ptr -> iot_pnp_client_core,
+ hostname_span, device_id_span, model_id_span, &options);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP client failed initialization with error status: %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ status = nx_azure_iot_hub_transport_initialize(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ nx_azure_iot_ptr, host_name, host_name_length,
+ nx_azure_iot_pnp_client_client_id_get,
+ nx_azure_iot_pnp_client_username_get,
+ crypto_array, crypto_array_size,
+ cipher_map, cipher_map_size,
+ metadata_memory, memory_size,
+ trusted_certificate, (VOID *)pnp_client_ptr);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTPnP client failed to initialization transport with error status: %d"), core_result);
+ return(status);
+ }
+
+ /* Enable all the features */
+ if ((status = nx_azure_iot_hub_transport_receive_message_enable(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_COMMAND_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_PNP_CLIENT_COMMANDS_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_PNP_CLIENT_COMMANDS_SUBSCRIBE_TOPIC) - 1,
+ nx_azure_iot_pnp_client_command_process)) ||
+ (status = nx_azure_iot_hub_transport_receive_message_enable(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_SUBSCRIBE_TOPIC) - 1,
+ nx_azure_iot_pnp_client_device_twin_process)) ||
+ (status = nx_azure_iot_hub_transport_receive_message_enable(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES_QUEUE_INDEX,
+ (const UCHAR *)AZ_IOT_PNP_CLIENT_PROPERTY_PATCH_SUBSCRIBE_TOPIC,
+ sizeof(AZ_IOT_PNP_CLIENT_PROPERTY_PATCH_SUBSCRIBE_TOPIC) - 1,
+ NX_NULL)) ||
+ (status = nx_azure_iot_hub_transport_receive_message_enable(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ NX_NULL, 0,
+ NX_NULL)))
+ {
+ LogError(LogLiteralArgs("IoTPnP client failed to enable pnp features : %d"), status);
+ nx_azure_iot_hub_transport_deinitialize(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport));
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_deinitialize(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr)
+{
+
+ /* Check for invalid input pointers. */
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client deinitialize fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_deinitialize(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport)));
+}
+
+UINT nx_azure_iot_pnp_client_component_add(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length)
+{
+UINT length_of_componet_list;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (component_name_ptr == NX_NULL) ||
+ (component_name_length == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP add component fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ tx_mutex_get(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, TX_WAIT_FOREVER);
+
+ length_of_componet_list =
+ (UINT)pnp_client_ptr -> iot_pnp_client_core._internal.options.component_names_length;
+
+ if (length_of_componet_list >= NX_AZURE_IOT_PNP_CLIENT_MAX_PNP_COMPONENT_LIST)
+ {
+ LogError(LogLiteralArgs("IoT PnP fail due to buffer insufficient"));
+ tx_mutex_put(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+ return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
+ }
+
+ /* Using internal fields for faster update */
+ pnp_client_ptr -> nx_azure_iot_pnp_client_component_list[length_of_componet_list] =
+ az_span_create((UCHAR *)component_name_ptr, (INT)component_name_length);
+ pnp_client_ptr -> iot_pnp_client_core._internal.options.component_names_length++;
+
+ tx_mutex_put(pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_device_cert_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_SECURE_X509_CERT *device_certificate)
+{
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP device certificate set fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_device_cert_set(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ device_certificate));
+}
+
+UINT nx_azure_iot_pnp_client_symmetric_key_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *symmetric_key, UINT symmetric_key_length)
+{
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client symmetric key fail: Invalid argument"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_symmetric_key_auth_set(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ nx_azure_iot_pnp_client_signature_get,
+ nx_azure_iot_pnp_client_password_get,
+ symmetric_key, symmetric_key_length));
+}
+
+UINT nx_azure_iot_pnp_client_connect(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT clean_session, UINT wait_option)
+{
+
+ /* Check for invalid input pointers. */
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client connect fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_connect(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ clean_session, wait_option));
+}
+
+UINT nx_azure_iot_pnp_client_disconnect(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr)
+{
+
+ /* Check for invalid input pointers. */
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client disconnect fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_disconnect(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport)));
+}
+
+UINT nx_azure_iot_pnp_client_connection_status_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID (*connection_status_cb)(
+ struct NX_AZURE_IOT_PNP_CLIENT_STRUCT *client_ptr,
+ UINT status))
+{
+
+ /* Check for invalid input pointers. */
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client connect callback fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_connection_callback_set(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ nx_azure_iot_pnp_client_connection_status_callback,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)connection_status_cb));
+}
+
+UINT nx_azure_iot_pnp_client_receive_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT message_type,
+ VOID (*callback_ptr)(
+ NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID *args),
+ VOID *callback_args)
+{
+UINT message_queue_index;
+
+ if ((pnp_client_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTPnP receive callback set fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ message_queue_index = nx_azure_iot_pnp_client_mesg_type_to_queue_index(message_type);
+
+ return(nx_azure_iot_hub_transport_receive_message_callback_set(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ message_queue_index,
+ callback_ptr != NX_NULL ? nx_azure_iot_pnp_client_receive_callback : NX_NULL,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)callback_ptr, callback_args));
+}
+
+UINT nx_azure_iot_pnp_client_telemetry_message_create(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length,
+ NX_PACKET **packet_pptr,
+ UINT wait_option)
+{
+NX_PACKET *packet_ptr;
+UINT topic_length;
+UINT status;
+az_result core_result;
+az_span component_name = az_span_create((UCHAR *)component_name_ptr, (INT)component_name_length);
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (packet_pptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP telemetry message create fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Create telemetry data fail"));
+ return(status);
+ }
+
+ topic_length = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
+ core_result = az_iot_pnp_client_telemetry_get_publish_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ component_name, NULL,
+ (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
+ topic_length, &topic_length);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP client telemetry message create fail with error status: %d"), core_result);
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
+ packet_ptr -> nx_packet_length = topic_length;
+ *packet_pptr = packet_ptr;
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_telemetry_message_delete(NX_PACKET *packet_ptr)
+{
+ return(nx_packet_release(packet_ptr));
+}
+
+UINT nx_azure_iot_pnp_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)
+{
+ return(nx_azure_iot_topic_property_append(packet_ptr, property_name, property_name_length,
+ property_value, property_value_length, wait_option));
+}
+
+UINT nx_azure_iot_pnp_client_telemetry_send(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_PACKET *packet_ptr,
+ const UCHAR *telemetry_data,
+ UINT data_size, UINT wait_option)
+{
+ if ((pnp_client_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoTPnP telemetry send fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_publish(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport), packet_ptr,
+ telemetry_data, data_size, NX_AZURE_IOT_PNP_CLIENT_TELEMETRY_QOS, wait_option));
+}
+
+UINT nx_azure_iot_pnp_client_command_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR **component_name_pptr, UINT *component_name_length_ptr,
+ const UCHAR **pnp_command_name_pptr, UINT *pnp_command_name_length_ptr,
+ VOID **context_pptr, USHORT *context_length_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr, UINT wait_option)
+{
+UINT status;
+ULONG topic_offset;
+USHORT topic_length;
+az_span topic_span;
+ULONG message_offset;
+ULONG message_length;
+NX_PACKET *start_packet_ptr;
+NX_PACKET *packet_ptr;
+az_result core_result;
+az_iot_pnp_client_command_request request;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (component_name_pptr == NX_NULL) ||
+ (component_name_length_ptr == NX_NULL) ||
+ (pnp_command_name_pptr == NX_NULL) ||
+ (pnp_command_name_length_ptr == NX_NULL) ||
+ (context_pptr == NX_NULL) ||
+ (context_length_ptr == NX_NULL) ||
+ (reader_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP client command receive fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ status = nx_azure_iot_hub_transport_message_receive(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_COMMAND_QUEUE_INDEX, 0,
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ return(status);
+ }
+
+ status = _nxd_mqtt_process_publish_packet(packet_ptr, &topic_offset, &topic_length, &message_offset, &message_length);
+ if (status)
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), topic_length);
+ core_result = az_iot_pnp_client_commands_parse_received_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ topic_span, &request);
+ if (az_result_failed(core_result))
+ {
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ packet_ptr -> nx_packet_length = message_length;
+ start_packet_ptr = packet_ptr;
+
+ /* Adjust packet to pointer to message payload. */
+ while (packet_ptr)
+ {
+ if ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > message_offset)
+ {
+
+ /* This packet contains message payload. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + message_offset;
+ break;
+ }
+
+ message_offset -= (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
+
+ /* Set current packet to empty. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_append_ptr;
+
+ /* Move to next packet. */
+ packet_ptr = packet_ptr -> nx_packet_next;
+ }
+
+ if ((status = nx_azure_iot_json_reader_init(reader_ptr, start_packet_ptr)))
+ {
+ nx_packet_release(start_packet_ptr);
+ return(status);
+ }
+
+ *component_name_pptr = (const UCHAR *)az_span_ptr(request.component_name);
+ *component_name_length_ptr = (UINT)az_span_size(request.component_name);
+ *pnp_command_name_pptr = (const UCHAR *)az_span_ptr(request.command_name);
+ *pnp_command_name_length_ptr = (UINT)az_span_size(request.command_name);
+ *context_pptr = (VOID*)az_span_ptr(request.request_id);
+ *context_length_ptr = (USHORT)az_span_size(request.request_id);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_command_message_response(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT status_code, VOID *context_ptr,
+ USHORT context_length, const UCHAR *payload_ptr,
+ UINT payload_length, UINT wait_option)
+{
+NX_PACKET *packet_ptr;
+UINT topic_length;
+az_span request_id_span;
+UINT status;
+az_result core_result;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (context_ptr == NX_NULL) ||
+ (context_length == 0))
+ {
+ LogError(LogLiteralArgs("IoT PnP command response fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Prepare response packet. */
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("Create response data fail"));
+ return(status);
+ }
+
+ topic_length = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
+ request_id_span = az_span_create((UCHAR*)context_ptr, (INT)context_length);
+ core_result = az_iot_pnp_client_commands_response_get_publish_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ request_id_span, (USHORT)status_code,
+ (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
+ topic_length, &topic_length);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("Failed to create the command response topic"));
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
+ packet_ptr -> nx_packet_length = topic_length;
+
+ if ((payload_ptr == NX_NULL) || (payload_length == 0))
+ {
+ payload_ptr = (const UCHAR *)NX_AZURE_IOT_PNP_CLIENT_EMPTY_JSON;
+ payload_length = sizeof(NX_AZURE_IOT_PNP_CLIENT_EMPTY_JSON) - 1;
+ }
+
+ status = nx_azure_iot_hub_transport_publish(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport), packet_ptr,
+ payload_ptr, payload_length, NX_AZURE_IOT_MQTT_QOS_0, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTPnP client command response fail: PUBLISH FAIL status: %d"), status);
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_reported_properties_create(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ UINT wait_option)
+{
+UINT status;
+NX_PACKET *packet_ptr;
+UINT request_id;
+UCHAR *buffer_ptr;
+ULONG buffer_size;
+az_span request_id_span;
+az_result core_result;
+UINT topic_length;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP reported property create fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail: BUFFER ALLOCATE FAIL"));
+ return(status);
+ }
+
+ buffer_size = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
+ if (buffer_size <= NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE)
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail: BUFFER INSUFFICENT"));
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
+ }
+
+ buffer_size -= NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE;
+
+ /* Generate odd request id for reported properties send */
+ status = nx_azure_iot_pnp_client_twin_request_id_get(pnp_client_ptr,
+ (UCHAR *)(packet_ptr -> nx_packet_data_end -
+ NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE),
+ NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE,
+ &request_id_span, &request_id, NX_TRUE);
+
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send failed to get request id"));
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ core_result = az_iot_pnp_client_property_patch_get_publish_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ request_id_span,
+ (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
+ buffer_size, &topic_length);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail: NX_AZURE_IOT_PNP_CLIENT_TOPIC_SIZE is too small."));
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
+ }
+
+ packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
+ packet_ptr -> nx_packet_length = topic_length;
+
+ /* todo: use the macro for this magic number, possibly share it with nx_azure_iot.h */
+ buffer_ptr = packet_ptr -> nx_packet_prepend_ptr - 7;
+
+ /* encode topic length */
+ buffer_ptr[5] = (UCHAR)(packet_ptr -> nx_packet_length >> 8);
+ buffer_ptr[6] = (UCHAR)(packet_ptr -> nx_packet_length & 0xFF);
+
+ /* encode request id */
+ buffer_ptr[4] = (UCHAR)((request_id & 0xFF));
+ request_id >>= 8;
+ buffer_ptr[3] = (UCHAR)((request_id & 0xFF));
+ request_id >>= 8;
+ buffer_ptr[2] = (UCHAR)((request_id & 0xFF));
+ request_id >>= 8;
+ buffer_ptr[1] = (UCHAR)(request_id & 0xFF);
+
+ if ((status = nx_azure_iot_json_writer_init(writer_ptr, packet_ptr, wait_option)) ||
+ (status = nx_azure_iot_json_writer_append_begin_object(writer_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_reported_property_component_begin(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length)
+{
+az_result core_result;
+az_span component_name = az_span_create((UCHAR *)component_name_ptr, (INT)component_name_length);
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP reported property begin fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ core_result = az_iot_pnp_client_property_builder_begin_component(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(writer_ptr -> json_writer), component_name);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP failed to append component, core error : %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_reported_property_component_end(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr)
+{
+az_result core_result;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP reported property end fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ core_result = az_iot_pnp_client_property_builder_end_component(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(writer_ptr -> json_writer));
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP failed to append component, core error : %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_reported_property_status_begin(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ const UCHAR *property_name_ptr, UINT property_name_length,
+ UINT ack_code, ULONG ack_version,
+ const UCHAR *ack_description_ptr, UINT ack_description_length)
+{
+az_span property_name;
+az_span description;
+az_result core_result;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL) ||
+ (property_name_ptr == NX_NULL) ||
+ (property_name_length == 0) )
+ {
+ LogError(LogLiteralArgs("IoT PnP client begin reported status failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ property_name = az_span_create((UCHAR *)property_name_ptr, (INT)property_name_length);
+ description = az_span_create((UCHAR *)ack_description_ptr, (INT)ack_description_length);
+
+ core_result = az_iot_pnp_client_property_builder_begin_reported_status(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(writer_ptr -> json_writer),
+ property_name, (int32_t)ack_code,
+ (int32_t)ack_version, description);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("Failed to prefix data with core error : %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_reported_property_status_end(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr)
+{
+az_result core_result;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP client end reported status failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ core_result = az_iot_pnp_client_property_builder_end_reported_status(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(writer_ptr -> json_writer));
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("Failed to suffix data with core error : %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_report_properties_response_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID (*callback_ptr)(
+ NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT request_id,
+ UINT response_status,
+ ULONG version,
+ VOID *args),
+ VOID *callback_args)
+{
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoTPnP client device twin set callback fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ return(nx_azure_iot_hub_transport_receive_message_callback_set(&(pnp_client_ptr ->nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ callback_ptr != NX_NULL ? nx_azure_iot_pnp_client_reported_property_receive_callback : NX_NULL,
+ (NX_AZURE_IOT_HUB_TRANSPORT_GENERIC_FN)callback_ptr, callback_args));
+}
+
+UINT nx_azure_iot_pnp_client_reported_properties_send(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ UINT *request_id_ptr, UINT *response_status_ptr,
+ ULONG *version_ptr, UINT wait_option)
+{
+NX_PACKET *packet_ptr;
+NX_PACKET *response_packet_ptr;
+UINT topic_length;
+UINT request_id = 0;
+ULONG topic_offset;
+USHORT length;
+UCHAR *buffer_ptr;
+UINT status;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (writer_ptr == NX_NULL) ||
+ (writer_ptr -> packet_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Check if twin response is subscribed */
+ if ((status = nx_azure_iot_hub_transport_receive_message_is_subscribed(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX,
+ wait_option)))
+ {
+ LogError(LogLiteralArgs("IoTPnP client reported state send fail with error %d"), status);
+ return(status);
+ }
+
+ /* Check if the last request was throttled and if the next need to be throttled. */
+ if ((status = nx_azure_iot_pnp_client_throttled_check(pnp_client_ptr)))
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail with error %d"), status);
+ return(status);
+ }
+
+ if (writer_ptr -> json_writer._internal.bit_stack._internal.current_depth > 1)
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail with JSON wrong state"));
+ return(NX_AZURE_IOT_WRONG_STATE);
+ }
+
+ /* TODO: Need public api to get object depth */
+ if (writer_ptr -> json_writer._internal.bit_stack._internal.current_depth > 0)
+ {
+ if ((status = nx_azure_iot_json_writer_append_end_object(writer_ptr)))
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state send fail to close object with error %d"), status);
+ return(status);
+ }
+ }
+
+ /* Steps.
+ * 1. Publish message to topic "$iothub/twin/PATCH/properties/reported/?$rid={request id}"
+ * 2. Wait for the response if required.
+ * 3. Return result if present.
+ * */
+
+ packet_ptr = writer_ptr -> packet_ptr;
+ buffer_ptr = packet_ptr -> nx_packet_prepend_ptr - 7;
+
+ topic_length = (UINT)((buffer_ptr[5] << 8) | buffer_ptr[6]);
+
+ request_id += (buffer_ptr[1] & 0xFF);
+ request_id <<= 8;
+ request_id += (buffer_ptr[2] & 0xFF);
+ request_id <<= 8;
+ request_id += (buffer_ptr[3] & 0xFF);
+ request_id <<= 8;
+ request_id += (buffer_ptr[4] & 0xFF);
+
+ status = nx_azure_iot_hub_transport_request_response(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ request_id, packet_ptr, topic_length, NX_NULL, 0,
+ NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE_QUEUE_INDEX,
+ &response_packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTPnP client reported state send fail: append failed"));
+ return(status);
+ }
+
+ /* Ownership of packet is taken by MQTT stack */
+ writer_ptr -> packet_ptr = NX_NULL;
+
+ if (request_id_ptr)
+ {
+ *request_id_ptr = request_id;
+ }
+
+ if (response_packet_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoT PnP client reported state not responded"));
+ if (pnp_client_ptr -> nx_azure_iot_pnp_client_transport.nx_azure_iot_hub_transport_state !=
+ NX_AZURE_IOT_HUB_TRANSPORT_STATUS_CONNECTED)
+ {
+ return(NX_AZURE_IOT_DISCONNECTED);
+ }
+
+ return(NX_AZURE_IOT_NO_PACKET);
+ }
+
+ if ((status = nx_azure_iot_hub_transport_process_publish_packet(response_packet_ptr -> nx_packet_prepend_ptr,
+ &topic_offset, &length)))
+ {
+ nx_packet_release(response_packet_ptr);
+ return(status);
+ }
+
+ if ((status = nx_azure_iot_pnp_client_device_twin_parse(pnp_client_ptr,
+ response_packet_ptr, topic_offset, length,
+ NX_NULL, version_ptr, NX_NULL,
+ response_status_ptr)))
+ {
+ nx_packet_release(response_packet_ptr);
+ return(status);
+ }
+
+ /* Release message block. */
+ nx_packet_release(response_packet_ptr);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_properties_request(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT wait_option)
+{
+UINT status;
+UINT topic_length;
+UINT buffer_size;
+NX_PACKET *packet_ptr;
+az_span request_id_span;
+UINT request_id;
+az_result core_result;
+
+ if (pnp_client_ptr == NX_NULL)
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin get request fail: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if ((status = nx_azure_iot_hub_transport_receive_message_is_subscribed(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX,
+ wait_option)))
+ {
+ LogError(LogLiteralArgs("IoTPnP client device twin publish fail with error %d"), status);
+ return(status);
+ }
+
+ /* Check if the last request was throttled and if the next need to be throttled. */
+ if ((status = nx_azure_iot_pnp_client_throttled_check(pnp_client_ptr)))
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin get request failed with error %d"), status);
+ return(status);
+ }
+
+ /* Steps.
+ * 1. Publish message to topic "$iothub/twin/GET/?$rid={request id}"
+ * */
+ status = nx_azure_iot_hub_transport_publish_packet_get(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin get request fail: BUFFER ALLOCATE FAIL"));
+ return(status);
+ }
+
+ buffer_size = (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr);
+ if (buffer_size <= NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE)
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin get request fail: BUFFER ALLOCATE FAIL"));
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
+ }
+
+ buffer_size -= NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE;
+
+ /* Generate even request id for twin properties request. */
+ status = nx_azure_iot_pnp_client_twin_request_id_get(pnp_client_ptr,
+ (UCHAR *)(packet_ptr -> nx_packet_data_end -
+ NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE),
+ NX_AZURE_IOT_PNP_CLIENT_U32_MAX_BUFFER_SIZE,
+ &request_id_span, &request_id, NX_FALSE);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin failed to get request id"));
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ core_result = az_iot_pnp_client_property_document_get_publish_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ request_id_span, (CHAR *)packet_ptr -> nx_packet_prepend_ptr,
+ buffer_size, &topic_length);
+ if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin get topic fail."));
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
+ }
+
+ packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + topic_length;
+ packet_ptr -> nx_packet_length = topic_length;
+
+ status = nx_azure_iot_hub_transport_publish(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport), packet_ptr,
+ NX_NULL, 0, NX_AZURE_IOT_MQTT_QOS_0, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoTPnP client device twin: PUBLISH FAIL status: %d"), status);
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_properties_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr,
+ ULONG *desired_properties_version_ptr,
+ UINT wait_option)
+{
+UINT status;
+ULONG topic_offset;
+USHORT topic_length;
+az_result core_result;
+az_span topic_span;
+az_iot_pnp_client_property_response out_twin_response;
+NX_PACKET *packet_ptr;
+int32_t version;
+
+ if ((pnp_client_ptr == NX_NULL) || (reader_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin receive failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Steps.
+ * 1. Check if the twin document is available to receive from linklist.
+ * 2. If present check the response.
+ * 3. Return the payload of the response.
+ * */
+ status = nx_azure_iot_hub_transport_message_receive(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_PROPERTIES_QUEUE_INDEX, 0,
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin receive failed status: %d"), status);
+ return(status);
+ }
+
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
+ {
+
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INVALID_PACKET);
+ }
+
+ topic_span = az_span_create(&(packet_ptr -> nx_packet_prepend_ptr[topic_offset]), (INT)topic_length);
+ core_result = az_iot_pnp_client_property_parse_received_topic(&(pnp_client_ptr -> iot_pnp_client_core),
+ topic_span, &out_twin_response);
+ if (az_result_failed(core_result))
+ {
+
+ /* Topic name does not match device twin format. */
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ if ((out_twin_response.status < 200) || (out_twin_response.status >= 300))
+ {
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_SERVER_RESPONSE_ERROR);
+ }
+
+ if ((status = nx_azure_iot_hub_transport_adjust_payload(packet_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ if ((status = nx_azure_iot_json_reader_init(reader_ptr, packet_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ if (desired_properties_version_ptr)
+ {
+ core_result = az_iot_pnp_client_property_get_property_version(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(reader_ptr -> json_reader),
+ AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_GET,
+ &version);
+ if (az_result_failed(core_result))
+ {
+ nx_azure_iot_json_reader_deinit(reader_ptr);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ /* Re-initialize the JSON reader state */
+ if ((status = nx_azure_iot_json_reader_init(reader_ptr, packet_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ *desired_properties_version_ptr = (ULONG)version;
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_desired_properties_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr,
+ ULONG *properties_version_ptr,
+ UINT wait_option)
+{
+UINT status;
+NX_PACKET *packet_ptr;
+ULONG topic_offset;
+USHORT topic_length;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (reader_ptr == NX_NULL))
+ {
+ LogError(LogLiteralArgs("IoT PnP client device twin receive properties failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Steps.
+ * 1. Check if the desired properties document is available to receive from linklist.
+ * 2. Parse result if present.
+ * 3. Return parse result.
+ * */
+ status = nx_azure_iot_hub_transport_message_receive(&(pnp_client_ptr -> nx_azure_iot_pnp_client_transport),
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES_QUEUE_INDEX, 0,
+ &packet_ptr, wait_option);
+ if (status)
+ {
+ return(status);
+ }
+
+ if (nx_azure_iot_hub_transport_process_publish_packet(packet_ptr -> nx_packet_prepend_ptr, &topic_offset,
+ &topic_length))
+ {
+
+ /* Message not supported. It will be released. */
+ nx_packet_release(packet_ptr);
+ return(NX_AZURE_IOT_INVALID_PACKET);
+ }
+
+ if ((status = nx_azure_iot_pnp_client_device_twin_parse(pnp_client_ptr, packet_ptr,
+ topic_offset, topic_length,
+ NX_NULL, properties_version_ptr,
+ NX_NULL, NX_NULL)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ if ((status = nx_azure_iot_hub_transport_adjust_payload(packet_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ if ((status = nx_azure_iot_json_reader_init(reader_ptr, packet_ptr)))
+ {
+ nx_packet_release(packet_ptr);
+ return(status);
+ }
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
+
+UINT nx_azure_iot_pnp_client_desired_component_property_value_next(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr, UINT message_type,
+ const UCHAR **component_pptr, UINT *component_len_ptr,
+ NX_AZURE_IOT_JSON_READER *name_value_reader_ptr)
+{
+az_span component_name;
+az_iot_pnp_client_property_response_type type;
+az_result core_result;
+
+ if ((pnp_client_ptr == NX_NULL) ||
+ (reader_ptr == NX_NULL) ||
+ (component_pptr == NX_NULL) ||
+ (component_len_ptr == NX_NULL) )
+ {
+ LogError(LogLiteralArgs("IoT PnP client desired component next property failed: INVALID POINTER"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ if ((message_type != NX_AZURE_IOT_PNP_DESIRED_PROPERTIES) &&
+ (message_type != NX_AZURE_IOT_PNP_PROPERTIES))
+ {
+ LogError(LogLiteralArgs("Invalid message type passed"));
+ return(NX_AZURE_IOT_INVALID_PARAMETER);
+ }
+
+ /* Copy reader control block but do not give NX_PACKET ownership */
+ *name_value_reader_ptr = *reader_ptr;
+ name_value_reader_ptr -> packet_ptr = NX_NULL;
+ type = (message_type == NX_AZURE_IOT_PNP_DESIRED_PROPERTIES) ? AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_DESIRED_PROPERTIES :
+ AZ_IOT_PNP_CLIENT_PROPERTY_RESPONSE_TYPE_GET;
+
+ core_result = az_iot_pnp_client_property_get_next_component_property(&(pnp_client_ptr -> iot_pnp_client_core),
+ &(reader_ptr -> json_reader),
+ type, &component_name,
+ &(name_value_reader_ptr -> json_reader));
+ if (core_result == AZ_ERROR_IOT_END_OF_PROPERTIES)
+ {
+ return(NX_AZURE_IOT_NOT_FOUND);
+ }
+ else if (az_result_failed(core_result))
+ {
+ LogError(LogLiteralArgs("Failed to parse document with core error : %d"), core_result);
+ return(NX_AZURE_IOT_SDK_CORE_ERROR);
+ }
+
+ *component_pptr = az_span_ptr(component_name);
+ *component_len_ptr = (UINT)az_span_size(component_name);
+
+ return(NX_AZURE_IOT_SUCCESS);
+}
diff --git a/addons/azure_iot/nx_azure_iot_pnp_client.h b/addons/azure_iot/nx_azure_iot_pnp_client.h
new file mode 100644
index 00000000..dfe8e341
--- /dev/null
+++ b/addons/azure_iot/nx_azure_iot_pnp_client.h
@@ -0,0 +1,677 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/* Version: 6.1 PnP Preview 1 */
+
+/**
+ * @file nx_azure_iot_pnp_client.h
+ *
+ * @brief Definition for the Azure IoT PnP client.
+ *
+ */
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_H
+#define NX_AZURE_IOT_PNP_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "azure/iot/az_iot_pnp_client.h"
+#include "nx_azure_iot_hub_transport.h"
+#include "nx_azure_iot.h"
+#include "nx_azure_iot_json_reader.h"
+#include "nx_azure_iot_json_writer.h"
+#include "nx_api.h"
+#include "nx_cloud.h"
+
+/**< Value denoting a message is of "None" type */
+#define NX_AZURE_IOT_PNP_NONE 0x00000000
+
+/**< Value denoting a message is of "all" type */
+#define NX_AZURE_IOT_PNP_ALL_MESSAGE 0xFFFFFFFF
+
+/**< Value denoting a message is a command */
+#define NX_AZURE_IOT_PNP_COMMAND 0x00000002
+
+/**< Value denoting a message is a all properties message */
+#define NX_AZURE_IOT_PNP_PROPERTIES 0x00000004
+
+/**< Value denoting a message is a desired properties message */
+#define NX_AZURE_IOT_PNP_DESIRED_PROPERTIES 0x00000008
+
+/**< Value denoting a message is a reported properties response */
+#define NX_AZURE_IOT_PNP_REPORTED_PROPERTIES_RESPONSE 0x00000010
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC
+#define NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC (10 * 60)
+#endif /* NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_IN_SEC */
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_INITIAL_BACKOFF_IN_SEC
+#define NX_AZURE_IOT_PNP_CLIENT_INITIAL_BACKOFF_IN_SEC (3)
+#endif /* NX_AZURE_IOT_PNP_CLIENT_INITIAL_BACKOFF_IN_SEC */
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_JITTER_PERCENT
+#define NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_JITTER_PERCENT (60)
+#endif /* NX_AZURE_IOT_PNP_CLIENT_MAX_BACKOFF_JITTER_PERCENT */
+
+#ifndef NX_AZURE_IOT_PNP_CLIENT_MAX_PNP_COMPONENT_LIST
+#define NX_AZURE_IOT_PNP_CLIENT_MAX_PNP_COMPONENT_LIST (4)
+#endif /* NX_AZURE_IOT_PNP_CLIENT_MAX_PNP_COMPONENT_LIST */
+
+/* Default TELEMETRY QoS is QoS1 */
+#ifndef NX_AZURE_IOT_PNP_CLIENT_TELEMETRY_QOS
+#define NX_AZURE_IOT_PNP_CLIENT_TELEMETRY_QOS NX_AZURE_IOT_MQTT_QOS_1
+#endif /* NX_AZURE_IOT_PNP_CLIENT_TELEMETRY_QOS */
+
+/**
+ * @brief Azure IoT PnP Client struct
+ *
+ */
+typedef struct NX_AZURE_IOT_PNP_CLIENT_STRUCT
+{
+ NX_AZURE_IOT_HUB_TRANSPORT nx_azure_iot_pnp_client_transport;
+
+ UINT nx_azure_iot_pnp_client_request_id;
+
+ az_iot_pnp_client iot_pnp_client_core;
+ az_span nx_azure_iot_pnp_client_component_list[NX_AZURE_IOT_PNP_CLIENT_MAX_PNP_COMPONENT_LIST];
+ UINT nx_azure_iot_pnp_client_throttle_count;
+ ULONG nx_azure_iot_pnp_client_throttle_end_time;
+} NX_AZURE_IOT_PNP_CLIENT;
+
+/**
+ * @brief Initialize Azure IoT PnP instance
+ *
+ * @param pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param nx_azure_iot_ptr A pointer to a #NX_AZURE_IOT.
+ * @param host_name A `UCHAR` pointer to IoTHub hostname. Must be `NULL` terminated.
+ * @param[in] host_name_length Length of `host_name`. Does not include the `NULL` terminator.
+ * @param[in] device_id A `UCHAR` pointer to the device ID.
+ * @param[in] device_id_length Length of the `device_id`. Does not include the `NULL` terminator.
+ * @param[in] module_id A `UCHAR` pointer to the module ID.
+ * @param[in] module_id_length Length of the `module_id`. Does not include the `NULL` terminator.
+ * @param[in] model_id A `UCHAR` pointer to the model ID.
+ * @param[in] model_id_length Length of the `model_id`. Does not include the `NULL` terminator.
+ * @param[in] crypto_array A pointer to an array of `NX_CRYPTO_METHOD`.
+ * @param[in] crypto_array_size Size of `crypto_array`.
+ * @param[in] cipher_map A pointer to an array of `NX_CRYPTO_CIPHERSUITE`.
+ * @param[in] cipher_map_size Size of `cipher_map`.
+ * @param[in] metadata_memory A `UCHAR` pointer to metadata memory buffer.
+ * @param[in] memory_size Size of `metadata_memory`.
+ * @param[in] trusted_certificate A pointer to `NX_SECURE_X509_CERT`, which are the server side certs.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successfully initialized the Azure IoT PnP client.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to initialize the Azure IoT PnP client due to invalid parameter.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to initialize the Azure IoT PnP client due to SDK core error.
+ */
+UINT nx_azure_iot_pnp_client_initialize(NX_AZURE_IOT_PNP_CLIENT *pnp_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 UCHAR *model_id, UINT model_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);
+
+/**
+ * @brief Deinitialize the Azure IoT PnP instance.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successfully de-initialized the Azure IoT PnP client.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to deinitialize the Azure IoT PnP client due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_deinitialize(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr);
+
+
+/**
+ * @brief Add component name to IoT PnP client.
+ * @note This routine should be called for all the component in the PnP model.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] component_name_ptr A pointer to component, that is part of PnP model.
+ * @param[in] component_name_length Length of the `component_name_ptr`.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successfully add the component name to the PnP client.
+ * @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to add the component name due to out of memory.
+ */
+UINT nx_azure_iot_pnp_client_component_add(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length);
+
+/**
+ * @brief Set the client certificate in the IoT PnP client.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] device_certificate A pointer to a `NX_SECURE_X509_CERT`, which is the device certificate.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successfully set device certificate to AZ IoT PnP Instance.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set device certificate to AZ IoT PnP Instance due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_device_cert_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_SECURE_X509_CERT *device_certificate);
+
+/**
+ * @brief Set symmetric key in the IoT PnP client.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] symmetric_key A pointer to a symmetric key.
+ * @param[in] symmetric_key_length Length of `symmetric_key`.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successfully set symmetric key to IoT PnP client.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set symmetric key to IoT PnP client due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_symmetric_key_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *symmetric_key, UINT symmetric_key_length);
+
+/**
+ * @brief Connect to IoT Hub.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] clean_session Can be set to `0` to re-use current session, or `1` to start new session
+ * @param[in] wait_option Number of ticks to wait for internal resources to be available.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if connected to Azure IoT Hub.
+ * @retval #NX_AZURE_IOT_CONNECTING Successfully started connection but not yet completed.
+ * @retval #NX_AZURE_IOT_ALREADY_CONNECTED Already connected to Azure IoT Hub.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to connect to Azure IoT Hub due to invalid parameter.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to connect to Azure IoT Hub due to SDK core error.
+ * @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to connect to Azure IoT Hub due to buffer size is too small.
+ * @retval NX_DNS_QUERY_FAILED Fail to connect to Azure IoT Hub due to hostname can not be resolved.
+ * @retval NX_NO_PACKET Fail to connect to Azure IoT Hub due to no available packet in pool.
+ * @retval NX_INVALID_PARAMETERS Fail to connect to Azure IoT Hub due to invalid parameters.
+ * @retval NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE Fail to connect to Azure IoT Hub due to insufficient metadata space.
+ * @retval NX_SECURE_TLS_UNSUPPORTED_CIPHER Fail to connect to Azure IoT Hub due to unsupported cipher.
+ * @retval NXD_MQTT_ALREADY_CONNECTED Fail to connect to Azure IoT Hub due to MQTT session is not disconnected.
+ * @retval NXD_MQTT_CONNECT_FAILURE Fail to connect to Azure IoT Hub due to TCP/TLS connect error.
+ * @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to connect to Azure IoT Hub due to MQTT connect error.
+ * @retval NXD_MQTT_ERROR_SERVER_UNAVAILABLE Fail to connect to Azure IoT Hub due to server unavailable.
+ * @retval NXD_MQTT_ERROR_NOT_AUTHORIZED Fail to connect to Azure IoT Hub due to authentication error.
+ */
+UINT nx_azure_iot_pnp_client_connect(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT clean_session, UINT wait_option);
+
+/**
+ * @brief Disconnect from IoT Hub.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if client disconnects.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disconnect due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_disconnect(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr);
+
+/**
+ * @brief Sets connection status callback function
+ * @details This routine sets the connection status callback. This callback function is
+ * invoked when PnP client status is changed, such as when the client is connected to IoT Hub.
+ * The different statuses include:
+ *
+ * - #NX_AZURE_IOT_SUCCESS
+ * - NX_SECURE_TLS_ALERT_RECEIVED
+ * - NX_SECURE_TLS_NO_SUPPORTED_CIPHERS
+ * - NX_SECURE_X509_CHAIN_VERIFY_FAILURE
+ * - NXD_MQTT_CONNECT_FAILURE
+ * - NXD_MQTT_ERROR_SERVER_UNAVAILABLE
+ * - NXD_MQTT_ERROR_NOT_AUTHORIZED
+ * - NX_AZURE_IOT_DISCONNECTED
+ *
+ * Setting the callback function to `NULL` disables the callback function.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] connection_status_cb Pointer to a callback function invoked on connection status is changed.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if connection status callback is set.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set connection status callback due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_connection_status_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID (*connection_status_cb)(
+ struct NX_AZURE_IOT_PNP_CLIENT_STRUCT *pnp_client_ptr,
+ UINT status));
+
+/**
+ * @brief Sets receive callback function
+ * @details This routine sets the IoT PnP receive callback function. This callback
+ * function is invoked when a message is received from Azure IoT hub. Setting the
+ * callback function to `NULL` disables the callback function. Message types can be:
+ *
+ * - #NX_AZURE_IOT_PNP_COMMAND
+ * - #NX_AZURE_IOT_PNP_PROPERTIES
+ * - #NX_AZURE_IOT_PNP_DESIRED_PROPERTIES
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] message_type Message type of callback function.
+ * @param[in] callback_ptr Pointer to a callback function invoked if the specified message type is received.
+ * @param[in] callback_args Pointer to an argument passed to callback function.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if callback function is set.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set receive callback due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NOT_SUPPORTED Fail to set receive callback due to message_type not supported.
+ */
+UINT nx_azure_iot_pnp_client_receive_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT message_type,
+ VOID (*callback_ptr)(
+ NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID *args),
+ VOID *callback_args);
+
+/**
+ * @brief Creates PnP telemetry message.
+ * @details This routine prepares a packet for sending telemetry data. After the packet is properly created,
+ * application owns the `NX_PACKET` and can add additional user-defined properties before sending out.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] component_name_ptr A pointer to a component name.
+ * @param[in] component_name_length Length of `component_name_ptr`. Does not include the `NULL` terminator.
+ * @param[out] packet_pptr Returned allocated `NX_PACKET` on success. Caller owns the `NX_PACKET` memory.
+ * @param[in] wait_option Ticks to wait if no packet is available.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if a packet is allocated.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to allocate telemetry message due to invalid parameter.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to allocate telemetry message due to SDK core error.
+ * @retval NX_NO_PACKET Fail to allocate telemetry message due to no available packet in pool.
+ */
+UINT nx_azure_iot_pnp_client_telemetry_message_create(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length,
+ NX_PACKET **packet_pptr,
+ UINT wait_option);
+
+/**
+ * @brief Deletes PnP telemetry message
+ *
+ * @param[in] packet_ptr The `NX_PACKET` to release.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if a packet is deallocated.
+ */
+UINT nx_azure_iot_pnp_client_telemetry_message_delete(NX_PACKET *packet_ptr);
+
+/**
+ * @brief Add property to telemetry message
+ * @details This routine allows an application to add user-defined properties to a telemetry message
+ * before it is being sent. This routine can be called multiple times to add all the properties to
+ * the message. The properties are stored in the sequence which the routine is being called.
+ * The property must be added after a telemetry packet is created, and before the telemetry
+ * message is being sent.
+ *
+ * @param[in] packet_ptr A pointer to telemetry property packet.
+ * @param[in] property_name Pointer to property name.
+ * @param[in] property_name_length Length of property name.
+ * @param[in] property_value Pointer to property value.
+ * @param[in] property_value_length Length of property value.
+ * @param[in] wait_option Ticks to wait if packet needs to be expanded.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if property is added.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to add property due to invalid parameter.
+ * @retval NX_NO_PACKET Fail to add property due to no available packet in pool.
+ */
+UINT nx_azure_iot_pnp_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);
+
+/**
+ * @brief Sends PnP telemetry message to IoTHub.
+ * @details This routine sends PnP telemetry to IoTHub, with `packet_ptr` containing all the properties.
+ * On successful return of this function, ownership of `NX_PACKET` is released.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] packet_ptr A pointer to telemetry property packet.
+ * @param[in] telemetry_data Pointer to telemetry data.
+ * @param[in] data_size Size of telemetry data.
+ * @param[in] wait_option Ticks to wait for message to be sent.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if telemetry message is sent out.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send telemetry message due to invalid parameter.
+ * @retval #NX_AZURE_IOT_INVALID_PACKET Fail to send telemetry message due to packet is invalid.
+ * @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to send telemetry message due to no available packet in pool.
+ * @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to send telemetry message due to TCP/TLS error.
+ * @retval NX_NO_PACKET Fail to send telemetry message due to no available packet in pool.
+ */
+UINT nx_azure_iot_pnp_client_telemetry_send(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_PACKET *packet_ptr,
+ const UCHAR *telemetry_data,
+ UINT data_size, UINT wait_option);
+
+/**
+ * @brief Receives receiving PnP command message from IoTHub
+ * @details This routine receives PnP command message from IoT Hub. If there are no
+ * messages in the receive queue, this routine can block. The amount of time it waits for a
+ * message is determined by the `wait_option` parameter.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[out] component_name_pptr Return a pointer to PnP component name on success.
+ * @param[out] component_name_length_ptr Return length of `*component_name_pptr` on success.
+ * @param[out] pnp_command_name_pptr Return a pointer to PnP command name on success.
+ * @param[out] pnp_command_name_length_ptr Return length of `*pnp_command_name_pptr` on success.
+ * @param[out] context_pptr Return a pointer to the context pointer on success.
+ * @param[out] context_length_ptr Return length of `context` on success.
+ * @param[out] reader_ptr Return `NX_AZURE_IOT_JSON_READER` containing the method payload on success.
+ * @param[in] wait_option Ticks to wait for message to arrive.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if PnP command message is received.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive PnP command message due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive PnP command message due to it is not enabled.
+ * @retval #NX_AZURE_IOT_NO_PACKET Fail to receive PnP command message due to timeout.
+ * @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive PnP command message due to invalid packet.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive PnP command message due to SDK core error.
+ * @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive PnP command message due to disconnect.
+ */
+UINT nx_azure_iot_pnp_client_command_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ const UCHAR **component_name_pptr, UINT *component_name_length_ptr,
+ const UCHAR **pnp_command_name_pptr, UINT *pnp_command_name_length_ptr,
+ VOID **context_pptr, USHORT *context_length_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr, UINT wait_option);
+
+/**
+ * @brief Return response to PnP command message from IoTHub
+ * @details This routine returns response to the PnP command message from IoT Hub.
+ * @note request_id ties the correlation between PnP command message receive and response.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] status_code Status code for PnP command.
+ * @param[in] context_ptr Pointer to context return from nx_azure_iot_pnp_client_command_receive().
+ * @param[in] context_length Length of context.
+ * @param[in] payload Pointer to `UCHAR` containing the payload for the PnP command response. Payload is in JSON format.
+ * @param[in] payload_length Length of `payload`
+ * @param[in] wait_option Ticks to wait for message to send.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if PnP command response is send.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send PnP command response due to invalid parameter.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send PnP command response due to SDK core error.
+ * @retval NX_NO_PACKET Fail send PnP command response due to no available packet in pool.
+ */
+UINT nx_azure_iot_pnp_client_command_message_response(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT status_code, VOID *context_ptr,
+ USHORT context_length, const UCHAR *payload_ptr,
+ UINT payload_length, UINT wait_option);
+
+/**
+ * @brief Creates PnP reported property message writer.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT
+ * @param[out] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ * @param[in] wait_option Ticks to wait for writer creation
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if a message writer is created.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to create message writer due to invalid parameter.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to create message writer due to SDK core error.
+ * @retval NX_NO_PACKET Fail to create message writer due to no available packet in pool.
+ */
+UINT nx_azure_iot_pnp_client_reported_properties_create(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ UINT wait_option);
+
+/**
+ * @brief Append the necessary characters to a reported property JSON payload belonging to a
+ * subcomponent.
+ *
+ * The payload will be of the form:
+ *
+ * @code
+ * "reported": {
+ * "<component_name>": {
+ * "__t": "c",
+ * "temperature": 23
+ * }
+ * }
+ * @endcode
+ *
+ * @note This API should be used in conjunction with
+ * nx_azure_iot_pnp_client_reported_property_component_end().
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT
+ * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ * @param[in] component_name_ptr A pointer to a component name
+ * @param[in] component_name_length Length of `component_name_ptr`
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if JSON payload was prefixed successfully.
+ */
+UINT nx_azure_iot_pnp_client_reported_property_component_begin(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ const UCHAR *component_name_ptr,
+ UINT component_name_length);
+
+/**
+ * @brief Append the necessary characters to end a reported property JSON payload belonging to a
+ * subcomponent.
+ *
+ * @note This API should be used in conjunction with
+ * nx_azure_iot_pnp_client_reported_property_component_begin().
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT
+ * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS The JSON payload was suffixed successfully.
+ */
+UINT nx_azure_iot_pnp_client_reported_property_component_end(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr);
+
+/**
+ * @brief Begin a property response payload with confirmation status.
+ *
+ * This API should be used in response to an incoming desired property. More details can be found
+ * here:
+ *
+ * https://docs.microsoft.com/en-us/azure/iot-pnp/concepts-convention#writable-properties
+ *
+ * The payload will be of the form:
+ *
+ * **Without component**
+ * @code
+ * //{
+ * // "<property_name>":{
+ * // "ac": <ack_code>,
+ * // "av": <ack_version>,
+ * // "ad": "<ack_description>",
+ * // "value": <user_value>
+ * // }
+ * //}
+ * @endcode
+ *
+ * To send a status for a property belonging to a component, first call the
+ * nx_azure_iot_pnp_client_reported_property_status_begin() API to prefix the payload with the
+ * necessary identification. The API call flow would look like the following with the listed JSON
+ * payload being generated.
+ *
+ * **With component**
+ * @code
+ *
+ * nx_azure_iot_pnp_client_reported_property_component_begin()
+ * nx_azure_iot_pnp_client_reported_property_status_begin()
+ * // Append user value here (<user_value>)
+ * nx_azure_iot_pnp_client_reported_property_status_end()
+ * nx_azure_iot_pnp_client_reported_property_component_end()
+ *
+ * //{
+ * // "<component_name>": {
+ * // "__t": "c",
+ * // "<property_name>": {
+ * // "ac": <ack_code>,
+ * // "av": <ack_version>,
+ * // "ad": "<ack_description>",
+ * // "value": <user_value>
+ * // }
+ * // }
+ * //}
+ * @endcode
+ *
+ * @note This API should be used in conjunction with
+ * nx_azure_iot_pnp_client_reported_property_status_end().
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ * @param[in] property_name_ptr A pointer to property name.
+ * @param[in] property_name_length Length of `property_name_ptr`.
+ * @param[in] ack_code The HTTP-like status code to respond with.
+ * @param[in] ack_version The version of the property the application is acknowledging.
+ * @param[in] ack_description_ptr An optional pointer to description detailing the context or any details about
+ * the acknowledgement. This can be empty string.
+ * @param[in] ack_description_length Length of ack_description_ptr
+ *
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful appended JSON prefix.
+ */
+UINT nx_azure_iot_pnp_client_reported_property_status_begin(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr,
+ const UCHAR *property_name_ptr, UINT property_name_length,
+ UINT ack_code, ULONG ack_version,
+ const UCHAR *ack_description_ptr, UINT ack_description_length);
+
+/**
+ * @brief End a property response payload with confirmation status.
+ *
+ * @note This API should be used in conjunction with
+ * nx_azure_iot_pnp_client_reported_property_status_begin().
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ *
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful appended JSON suffix.
+ */
+UINT nx_azure_iot_pnp_client_reported_property_status_end(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *writer_ptr);
+
+/**
+ * @brief Sets reported properties response callback function
+ * @details This routine sets the reponse receive callback function for reported properties. This callback
+ * function is invoked when a response is received from Azure IoT hub for reported properties and no
+ * thread is waiting for response. Setting the callback function to `NULL` disables the callback
+ * function.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] callback_ptr Pointer to a callback function invoked.
+ * @param[in] callback_args Pointer to an argument passed to callback function.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if callback function is set.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set callback due to invalid parameter.
+ */
+UINT nx_azure_iot_pnp_client_report_properties_response_callback_set(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ VOID (*callback_ptr)(
+ NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT request_id,
+ UINT response_status,
+ ULONG version,
+ VOID *args),
+ VOID *callback_args);
+
+/**
+ * @brief Sends PnP reported properties message to IoTHub.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER
+ * @param[out] request_id_ptr Request Id assigned to the request.
+ * @param[out] response_status_ptr Status return for successful send of reported properties.
+ * @param[out] version_ptr Version return for successful send of reported properties.
+ * @param[in] wait_option Ticks to wait for message to send.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if reported properties is sent.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send reported properties due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NOT_ENABLED Fail to send reported properties due to device twin is not enabled.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send reported properties due to SDK core error.
+ * @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to send reported properties due to buffer size is too small.
+ * @retval #NX_AZURE_IOT_NO_PACKET Fail to send reported properties due to no packet available.
+ * @retval NX_NO_PACKET Fail to send reported properties due to no packet available.
+ * @retval #NX_AZURE_IOT_DISCONNECTED Fail to send reported properties due to disconnect.
+ */
+UINT nx_azure_iot_pnp_client_reported_properties_send(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_WRITER *reported_property_message,
+ UINT *request_id_ptr, UINT *response_status_ptr,
+ ULONG *version_ptr, UINT wait_option);
+
+/**
+ * @brief Request complete to get all properties
+ * @details This routine requests all properties.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] wait_option Ticks to wait for request to send.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if request get all properties is sent.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to request get all properties due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NO_SUBSCRIBE_ACK Fail to request get all properties due to no subscribe ack.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to request get all properties due to SDK core error.
+ * @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to request get all properties due to buffer size is too small.
+ * @retval #NX_AZURE_IOT_NO_PACKET Fail to request get all properties due to no packet available.
+ * @retval NX_NO_PACKET Fail to request get all properties due to no packet available.
+ */
+UINT nx_azure_iot_pnp_client_properties_request(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ UINT wait_option);
+
+/**
+ * @brief Receive all the properties
+ * @details This routine receives all the properties.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[out] reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing all the properties
+ * @param[out] desired_properties_version_ptr A pointer to `ULONG`, containing version of desired properties
+ * @param[in] wait_option Ticks to wait for message to receive.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if all properties is received.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive all properties due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive all properties due to it is not enabled.
+ * @retval #NX_AZURE_IOT_NO_PACKET Fail to receive all properties due to timeout.
+ * @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive all properties due to invalid packet.
+ * @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive all properties due to SDK core error.
+ * @retval #NX_AZURE_IOT_SERVER_RESPONSE_ERROR Response code from server is not 2xx.
+ * @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive all properties due to disconnect.
+ */
+UINT nx_azure_iot_pnp_client_properties_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr,
+ ULONG *desired_properties_version_ptr,
+ UINT wait_option);
+
+/**
+ * @brief Receive desired properties form IoTHub
+ * @details This routine receives desired properties from IoTHub.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[out] reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing desired properties
+ * @param[out] desired_properties_version_ptr A pointer to `ULONG`, containing version of properties
+ * @param[in] wait_option Ticks to wait for message to receive.
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if desired properties is received.
+ * @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive desired properties due to invalid parameter.
+ * @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive desired properties due to it is not enabled.
+ * @retval #NX_AZURE_IOT_NO_PACKET Fail to receive desired properties due to timeout.
+ * @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive desired properties due to invalid packet.
+ * @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive desired properties due to disconnect.
+ */
+UINT nx_azure_iot_pnp_client_desired_properties_receive(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr,
+ ULONG *properties_version_ptr,
+ UINT wait_option);
+
+/**
+ * @brief Return the next desired property in the property document passed.
+ *
+ * @param[in] pnp_client_ptr A pointer to a #NX_AZURE_IOT_PNP_CLIENT.
+ * @param[in] reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing properties document
+ * @param[in] message_type Type of document, only valid value are NX_AZURE_IOT_PNP_DESIRED_PROPERTIES or NX_AZURE_IOT_PNP_PROPERTIES
+ * @param[out] component_pptr A pointer to component name for the property returned using name_value_reader_ptr
+ * @param[out] component_len_ptr Length of the component name
+ * @param[out] name_value_reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing property name and value
+ * @return A `UINT` with the result of the API.
+ * @retval #NX_AZURE_IOT_SUCCESS Successful if next desired property is found.
+ */
+UINT nx_azure_iot_pnp_client_desired_component_property_value_next(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *reader_ptr, UINT message_type,
+ const UCHAR **component_pptr, UINT *component_len_ptr,
+ NX_AZURE_IOT_JSON_READER *name_value_reader_ptr);
+#ifdef __cplusplus
+}
+#endif
+#endif /* NX_AZURE_IOT_PNP_CLIENT_H */
diff --git a/addons/azure_iot/nx_azure_iot_provisioning_client.c b/addons/azure_iot/nx_azure_iot_provisioning_client.c
index 78a4d014..134d7f6c 100644
--- a/addons/azure_iot/nx_azure_iot_provisioning_client.c
+++ b/addons/azure_iot/nx_azure_iot_provisioning_client.c
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
#include "nx_azure_iot_provisioning_client.h"
diff --git a/addons/azure_iot/nx_azure_iot_provisioning_client.h b/addons/azure_iot/nx_azure_iot_provisioning_client.h
index cba71332..6b552413 100644
--- a/addons/azure_iot/nx_azure_iot_provisioning_client.h
+++ b/addons/azure_iot/nx_azure_iot_provisioning_client.h
@@ -9,7 +9,7 @@
/* */
/**************************************************************************/
-/* Version: 6.1 */
+/* Version: 6.1 PnP Preview 1 */
/**
* @file nx_azure_iot_provisioning_client.h
diff --git a/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.c b/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.c
deleted file mode 100644
index 167195ef..00000000
--- a/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-#include "nx_azure_iot_pnp_helpers.h"
-
-#include <stdio.h>
-
-#include "azure/core/az_json.h"
-#include "nx_api.h"
-
-/* Telemetry message property used to indicate the message's component. */
-static const CHAR sample_pnp_telemetry_component_property[] = "$.sub";
-
-/* Reported property response property keys. */
-static const CHAR sample_pnp_component_type_property_name[] = "__t";
-static const CHAR reported_component_type_value[] = "c";
-static const CHAR reported_value_property_name[] = "value";
-static const CHAR reported_status_property_name[] = "ac";
-static const CHAR reported_version_property_name[] = "av";
-static const CHAR reported_description_property_name[] = "ad";
-
-/* PnP command seperator. */
-static const az_span command_separator = AZ_SPAN_LITERAL_FROM_STR("*");
-
-/* Device twin keys */
-static const CHAR sample_iot_hub_twin_desired_version[] = "$version";
-static const CHAR sample_iot_hub_twin_desired[] = "desired";
-
-/* Move reader to the value of property name. */
-static UINT sample_json_child_token_move(NX_AZURE_IOT_JSON_READER *json_reader_ptr,
- UCHAR *property_name_ptr, UINT property_name_len)
-{
- while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
- {
- if ((nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME) &&
- nx_azure_iot_json_reader_token_is_text_equal(json_reader_ptr,
- property_name_ptr,
- property_name_len))
- {
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
- {
- printf("Failed to read next token\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
- {
- if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
- {
- printf("Failed to skip child of complex object\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
- {
- return(NX_AZURE_IOT_NOT_FOUND);
- }
- }
-
- return(NX_AZURE_IOT_NOT_FOUND);
-}
-
-/* Visit component property Object and call callback on each property of that component. */
-static UINT visit_component_properties(UCHAR *component_name_ptr, UINT component_name_len,
- NX_AZURE_IOT_JSON_READER *json_reader_ptr, UINT version,
- UCHAR *scratch_buf, UINT scratch_buf_len,
- VOID (*sample_desired_property_callback)(UCHAR *component_name_ptr,
- UINT component_name_len,
- UCHAR *property_name_ptr, UINT property_name_len,
- NX_AZURE_IOT_JSON_READER property_value_reader, UINT version,
- VOID *userContextCallback), VOID *context_ptr)
-{
-UINT len;
-
- while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
- {
- if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
- {
- if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr, scratch_buf, scratch_buf_len, &len))
- {
- printf("Failed to get string property value\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
- {
- printf("Failed to get next token\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if ((len == sizeof(sample_pnp_component_type_property_name) - 1) &&
- (memcmp((VOID *)scratch_buf, (VOID *)sample_pnp_component_type_property_name, len) == 0))
- {
- continue;
- }
-
- if ((len == sizeof(sample_iot_hub_twin_desired_version) - 1) &&
- (memcmp((VOID *)scratch_buf, (VOID *)sample_iot_hub_twin_desired_version, len) == 0))
- {
- continue;
- }
-
- sample_desired_property_callback(component_name_ptr, component_name_len,
- scratch_buf, len, *json_reader_ptr, version, context_ptr);
-
- }
-
- if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
- {
- if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
- {
- printf("Failed to skip children of object\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
- {
- break;
- }
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-/* Check if component is part of component list. */
-static UINT is_component_in_model(UCHAR *component_name_ptr, UINT component_name_len,
- CHAR **sample_components_ptr, UINT sample_components_num,
- UINT *out_index)
-{
-UINT index = 0;
-
- if (component_name_ptr == NX_NULL || component_name_len == 0)
- {
- return(NX_NOT_SUCCESSFUL);
- }
-
- while (index < sample_components_num)
- {
- if ((component_name_len == strlen(sample_components_ptr[index])) &&
- (memcmp((VOID *)component_name_ptr, (VOID *)sample_components_ptr[index], component_name_len) == 0))
- {
- *out_index = index;
- return(NX_AZURE_IOT_SUCCESS);
- }
-
- index++;
- }
-
- return(NX_AZURE_IOT_NOT_FOUND);
-}
-
-/* Parse PnP command names. */
-UINT nx_azure_iot_pnp_helper_command_name_parse(const UCHAR *method_name_ptr, UINT method_name_length,
- const UCHAR **component_name_pptr, UINT *component_name_length_ptr,
- const UCHAR **pnp_command_name_pptr, UINT *pnp_command_name_length_ptr)
-{
-INT index;
-az_span method_name = az_span_create((UCHAR *)method_name_ptr, (INT)method_name_length);
-
- if ((index = az_span_find(method_name, command_separator)) != -1)
- {
- /* If a separator character is present in the device method name, then a command on a subcomponent of
- the model is being targeted (e.g. thermostat1*getMaxMinReport). */
- *component_name_pptr = method_name_ptr;
- *component_name_length_ptr = (UINT)index;
- *pnp_command_name_pptr = method_name_ptr + index + 1;
- *pnp_command_name_length_ptr = method_name_length - (UINT)index - 1;
- }
- else
- {
- /* The separator character is optional. If it is not present, it indicates a command of the root
- component and not a subcomponent (e.g. "reboot"). */
- *component_name_pptr = NULL;
- *component_name_length_ptr = 0;
- *pnp_command_name_pptr = method_name_ptr;
- *pnp_command_name_length_ptr = method_name_length;
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-/* Parse twin data and call callback on each desired property. */
-UINT nx_azure_iot_pnp_helper_twin_data_parse(NX_AZURE_IOT_JSON_READER *json_reader_ptr, UINT is_partial,
- CHAR **sample_components_ptr, UINT sample_components_num,
- UCHAR *scratch_buf, UINT scratch_buf_len,
- VOID (*sample_desired_property_callback)(UCHAR *component_name_ptr,
- UINT component_name_len, UCHAR *property_name_ptr,
- UINT property_name_len,
- NX_AZURE_IOT_JSON_READER property_value_reader, UINT version,
- VOID *userContextCallback),
- VOID *context_ptr)
-{
-NX_AZURE_IOT_JSON_READER copy_json_reader;
-UINT version;
-UINT len;
-UINT index;
-UINT status;
-
- if ((status = nx_azure_iot_json_reader_next_token(json_reader_ptr)))
- {
- printf("Failed to initialize json reader: error %d\r\n", status);
- return(status);
- }
-
- if (!is_partial && sample_json_child_token_move(json_reader_ptr,
- (UCHAR *)sample_iot_hub_twin_desired,
- sizeof(sample_iot_hub_twin_desired) - 1))
- {
- printf("Failed to get desired property\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- copy_json_reader = *json_reader_ptr;
- if (sample_json_child_token_move(&copy_json_reader,
- (UCHAR *)sample_iot_hub_twin_desired_version,
- sizeof(sample_iot_hub_twin_desired_version) - 1) ||
- nx_azure_iot_json_reader_token_int32_get(&copy_json_reader, (int32_t *)&version))
- {
- printf("Failed to get version\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- while (nx_azure_iot_json_reader_next_token(json_reader_ptr) == NX_AZURE_IOT_SUCCESS)
- {
- if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME)
- {
- if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr, scratch_buf,
- scratch_buf_len, &len))
- {
- printf("Failed to string value for property name\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
- {
- printf("Failed to next token\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if ((len == sizeof(sample_iot_hub_twin_desired_version) - 1) &&
- (memcmp((VOID *)sample_iot_hub_twin_desired_version, (VOID *)scratch_buf, len) == 0))
- {
- continue;
- }
-
- if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT &&
- sample_components_ptr != NX_NULL &&
- (is_component_in_model(scratch_buf, len,
- sample_components_ptr, sample_components_num,
- &index) == NX_AZURE_IOT_SUCCESS))
- {
- if (visit_component_properties((UCHAR *)sample_components_ptr[index],
- strlen(sample_components_ptr[index]),
- json_reader_ptr, version, scratch_buf, scratch_buf_len,
- sample_desired_property_callback, context_ptr))
- {
- printf("Failed to visit component properties\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- else
- {
- sample_desired_property_callback(NX_NULL, 0, scratch_buf, len,
- *json_reader_ptr, version, context_ptr);
-
- if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
- {
- if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
- {
- printf("Failed to skip children of object\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- }
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
- {
- if (nx_azure_iot_json_reader_skip_children(json_reader_ptr))
- {
- printf("Failed to skip children of object\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader_ptr) ==
- NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
- {
- break;
- }
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
-
-/* Create PnP telemetry message. */
-UINT nx_azure_iot_pnp_helper_telemetry_message_create(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
- UCHAR *component_name, UINT component_name_len,
- NX_PACKET **packet_pptr, UINT wait_option)
-{
-UINT status;
-
- /* Create a telemetry message packet. */
- if ((status = nx_azure_iot_hub_client_telemetry_message_create(iothub_client_ptr, packet_pptr, wait_option)))
- {
- printf("Telemetry message create failed!: error code = 0x%08x\r\n", status);
- }
-
- /* If the component will be used, then specify this as a property of the message. */
- else if ((component_name != NULL) &&
- (status = nx_azure_iot_hub_client_telemetry_property_add(*packet_pptr,
- (UCHAR *)sample_pnp_telemetry_component_property,
- (USHORT)sizeof(sample_pnp_telemetry_component_property) - 1,
- component_name, (USHORT)component_name_len,
- NX_WAIT_FOREVER)) != NX_AZURE_IOT_SUCCESS)
- {
- printf("nx_azure_iot_hub_client_telemetry_property_add=%s failed, error=%d",
- sample_pnp_telemetry_component_property, status);
- nx_azure_iot_hub_client_telemetry_message_delete(*packet_pptr);
- }
- else
- {
- status = NX_AZURE_IOT_SUCCESS;
- }
-
- return(status);
-}
-
-/* Build PnP reported property into user provided buffer. */
-UINT nx_azure_iot_pnp_helper_build_reported_property(UCHAR *component_name_ptr, UINT component_name_len,
- UINT (*append_reported_property)(NX_AZURE_IOT_JSON_WRITER *json_builder_ptr,
- VOID *context),
- VOID *context, NX_AZURE_IOT_JSON_WRITER *json_builder_ptr)
-{
-UINT status;
-
- if (nx_azure_iot_json_writer_append_begin_object(json_builder_ptr) ||
- (component_name_ptr != NX_NULL &&
- (nx_azure_iot_json_writer_append_property_name(json_builder_ptr,
- component_name_ptr,
- component_name_len) ||
- nx_azure_iot_json_writer_append_begin_object(json_builder_ptr) ||
- nx_azure_iot_json_writer_append_property_with_string_value(json_builder_ptr,
- (UCHAR *)sample_pnp_component_type_property_name,
- sizeof(sample_pnp_component_type_property_name) - 1,
- (UCHAR *)reported_component_type_value,
- sizeof(reported_component_type_value) - 1))) ||
- (append_reported_property(json_builder_ptr, context) != NX_AZURE_IOT_SUCCESS) ||
- (component_name_ptr != NX_NULL && nx_azure_iot_json_writer_append_end_object(json_builder_ptr)) ||
- nx_azure_iot_json_writer_append_end_object(json_builder_ptr))
- {
- printf("Failed to build reported property\r\n");
- status = NX_NOT_SUCCESSFUL;
- }
- else
- {
- status = NX_AZURE_IOT_SUCCESS;
- }
-
- return(status);
-}
-
-/* Build reported property with status. */
-UINT nx_azure_iot_pnp_helper_build_reported_property_with_status(UCHAR *component_name_ptr, UINT component_name_len,
- UCHAR *property_name_ptr, UINT property_name_len,
- UINT (*append_value)(NX_AZURE_IOT_JSON_WRITER *builder,
- VOID *context),
- VOID *context,
- INT result, UCHAR *description_ptr,
- UINT description_len,
- UINT ack_version,
- NX_AZURE_IOT_JSON_WRITER *json_builder_ptr)
-{
- if (nx_azure_iot_json_writer_append_begin_object(json_builder_ptr))
- {
- printf("Failed initializing json writer \r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if (component_name_ptr != NX_NULL &&
- (nx_azure_iot_json_writer_append_property_name(json_builder_ptr,
- component_name_ptr,
- component_name_len) ||
- nx_azure_iot_json_writer_append_begin_object(json_builder_ptr) ||
- nx_azure_iot_json_writer_append_property_with_string_value(json_builder_ptr,
- (UCHAR *)sample_pnp_component_type_property_name,
- sizeof(sample_pnp_component_type_property_name) - 1,
- (UCHAR *)reported_component_type_value,
- sizeof(reported_component_type_value) - 1)))
- {
- printf("Failed build reported property with status message \r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if (nx_azure_iot_json_writer_append_property_name(json_builder_ptr,
- property_name_ptr, property_name_len) ||
- nx_azure_iot_json_writer_append_begin_object(json_builder_ptr) ||
- nx_azure_iot_json_writer_append_property_name(json_builder_ptr,
- (UCHAR *)reported_value_property_name,
- sizeof(reported_value_property_name) - 1) ||
- (append_value(json_builder_ptr, context) != NX_AZURE_IOT_SUCCESS) ||
- nx_azure_iot_json_writer_append_property_with_int32_value(json_builder_ptr,
- (UCHAR *)reported_status_property_name,
- sizeof(reported_status_property_name) - 1,
- result) ||
- nx_azure_iot_json_writer_append_property_with_string_value(json_builder_ptr,
- (UCHAR *)reported_description_property_name,
- sizeof(reported_description_property_name) - 1,
- description_ptr, description_len) ||
- nx_azure_iot_json_writer_append_property_with_int32_value(json_builder_ptr,
- (UCHAR *)reported_version_property_name,
- sizeof(reported_version_property_name) - 1,
- (INT)ack_version) ||
- nx_azure_iot_json_writer_append_end_object(json_builder_ptr) ||
- nx_azure_iot_json_writer_append_end_object(json_builder_ptr))
- {
- printf("Failed build reported property with status message\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- if (component_name_ptr != NX_NULL &&
- nx_azure_iot_json_writer_append_end_object(json_builder_ptr))
- {
- printf("Failed build reported property with status message\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
-}
diff --git a/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.h b/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.h
deleted file mode 100644
index ba6ffb7e..00000000
--- a/addons/azure_iot/samples/common/nx_azure_iot_pnp_helpers.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-#ifndef NX_AZURE_IOT_PNP_HELPERS_H
-#define NX_AZURE_IOT_PNP_HELPERS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "nx_azure_iot_json_reader.h"
-#include "nx_azure_iot_json_writer.h"
-#include "nx_azure_iot_hub_client.h"
-#include "nx_api.h"
-
-/**
- * @brief Parse PnP command name
- *
- * @param[in] method_name_ptr Pointer to method name
- * @param[in] method_name_length Length of method name
- * @param[out] component_name_pptr Pointer to component pointer
- * @param[out] component_name_length_ptr Pointer to length of component name length
- * @param[out] pnp_command_name_pptr Pointer to command name pointer
- * @param[out] pnp_command_name_length_ptr Pointer to length of command name
- * @return A `UINT` with the result of the API.
- * @retval #NX_AZURE_IOT_SUCCESS Successful if successful parsed command name.
- */
-UINT nx_azure_iot_pnp_helper_command_name_parse(const UCHAR *method_name_ptr, UINT method_name_length,
- const UCHAR **component_name_pptr, UINT *component_name_length_ptr,
- const UCHAR **pnp_command_name_pptr, UINT *pnp_command_name_length_ptr);
-
-/**
- * @brief Parse twin data and call callback on each desired property
- *
- * @param[in] json_reader_ptr `NX_AZURE_IOT_JSON_READER` pointer containing the twin data
- * @param[in] is_partial 1 if twin data is patch else 0 if full twin document
- * @param[in] sample_components_ptr Pointer to list of all components name pointers
- * @param[in] sample_components_num Size of component list
- * @param[in] scratch_buf Temporary buffer used for staging property names out of the JSON document
- * @param[in] scratch_buf_len Temporary buffer length size
- * @param[in] sample_desired_property_callback Callback called with each desired property
- * @param[in] context_ptr Context passed to the callback
- * @return A `UINT` with the result of the API.
- * @retval #NX_AZURE_IOT_SUCCESS Successful if successful parsed twin data.
- */
-UINT nx_azure_iot_pnp_helper_twin_data_parse(NX_AZURE_IOT_JSON_READER *json_reader_ptr, UINT is_partial,
- CHAR **sample_components_ptr, UINT sample_components_num,
- UCHAR *scratch_buf, UINT scratch_buf_len,
- VOID (*sample_desired_property_callback)(UCHAR *component_name_ptr,
- UINT component_name_len, UCHAR *property_name_ptr,
- UINT property_name_len,
- NX_AZURE_IOT_JSON_READER property_value_reader, UINT version,
- VOID *userContextCallback),
- VOID *context_ptr);
-
-/**
- * @brief Create PnP telemetry message
- *
- * @param[in] iothub_client_ptr Pointer to `NX_AZURE_IOT_HUB_CLIENT`
- * @param[in] component_name Pointer to component name
- * @param[in] component_name_len Length of component name
- * @param[out] packet_pptr `NX_PACKET` return via the API.
- * @param[in] wait_option Ticks to wait if no packet is available.
- * @return A `UINT` with the result of the API.
- * @retval #NX_AZURE_IOT_SUCCESS Successful if successful created NX_PACKET.
- */
-UINT nx_azure_iot_pnp_helper_telemetry_message_create(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
- UCHAR *component_name, UINT component_name_len,
- NX_PACKET **packet_pptr, UINT wait_option);
-
-/**
- * @brief Build PnP reported property into user provided buffer
- *
- * @param[in] component_name_ptr Pointer to component name
- * @param[in] component_name_len Length of component name
- * @param[in] append_reported_property Callback to add reported property
- * @param[in] context Context pass to callback
- * @param[out] json_builder_ptr Pointer to `NX_AZURE_IOT_JSON_WRITER`, containing the json reported property
- * @return A `UINT` with the result of the API.
- * @retval #NX_AZURE_IOT_SUCCESS Successful if successful created reported property message.
- */
-UINT nx_azure_iot_pnp_helper_build_reported_property(UCHAR *component_name_ptr, UINT component_name_len,
- UINT (*append_reported_property)(NX_AZURE_IOT_JSON_WRITER *json_builder_ptr,
- VOID *context),
- VOID *context, NX_AZURE_IOT_JSON_WRITER *json_builder_ptr);
-
-/**
- * @brief Build reported property with status
- *
- * @param[in] component_name_ptr Pointer to component name
- * @param[in] component_name_len Length of component name
- * @param[in] property_name_ptr Pointer to property name
- * @param[in] property_name_len Length of property name
- * @param[in] append_value Callback to add property value
- * @param[in] context Context pass to callback
- * @param[in] result Status for reported property
- * @param[in] description Pointer to description
- * @param[in] description_len Length of description
- * @param[in] ack_version ack version
- * @param[out] json_builder_ptr Pointer to `NX_AZURE_IOT_JSON_WRITER`, containing the json reported property
- * @return A `UINT` with the result of the API.
- * @retval #NX_AZURE_IOT_SUCCESS Successful if successful created reported property message.
- */
-UINT nx_azure_iot_pnp_helper_build_reported_property_with_status(UCHAR *component_name_ptr, UINT component_name_len,
- UCHAR *property_name_ptr, UINT property_name_len,
- UINT (*append_value)(NX_AZURE_IOT_JSON_WRITER *builder,
- VOID *context),
- VOID *context,
- INT result, UCHAR *description_ptr,
- UINT description_len,
- UINT ack_version,
- NX_AZURE_IOT_JSON_WRITER *json_builder_ptr);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* NX_AZURE_IOT_PNP_HELPERS_H */ \ No newline at end of file
diff --git a/addons/azure_iot/samples/sample_azure_iot_embedded_sdk_pnp.c b/addons/azure_iot/samples/sample_azure_iot_embedded_sdk_pnp.c
index 7b4faac4..908287a0 100644
--- a/addons/azure_iot/samples/sample_azure_iot_embedded_sdk_pnp.c
+++ b/addons/azure_iot/samples/sample_azure_iot_embedded_sdk_pnp.c
@@ -12,7 +12,7 @@
#include <stdio.h>
#include "nx_api.h"
-#include "nx_azure_iot_hub_client.h"
+#include "nx_azure_iot_pnp_client.h"
#include "nx_azure_iot_json_reader.h"
#include "nx_azure_iot_json_writer.h"
#include "nx_azure_iot_provisioning_client.h"
@@ -42,11 +42,11 @@
#define SAMPLE_ALL_EVENTS ((ULONG)0xFFFFFFFF)
#define SAMPLE_CONNECT_EVENT ((ULONG)0x00000001)
#define SAMPLE_INITIALIZATION_EVENT ((ULONG)0x00000002)
-#define SAMPLE_METHOD_MESSAGE_EVENT ((ULONG)0x00000004)
-#define SAMPLE_DEVICE_TWIN_GET_EVENT ((ULONG)0x00000008)
-#define SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT ((ULONG)0x00000010)
+#define SAMPLE_COMMAND_MESSAGE_EVENT ((ULONG)0x00000004)
+#define SAMPLE_DEVICE_PROPERTIES_GET_EVENT ((ULONG)0x00000008)
+#define SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT ((ULONG)0x00000010)
#define SAMPLE_TELEMETRY_SEND_EVENT ((ULONG)0x00000020)
-#define SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT ((ULONG)0x00000040)
+#define SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT ((ULONG)0x00000040)
#define SAMPLE_DISCONNECT_EVENT ((ULONG)0x00000080)
#define SAMPLE_RECONNECT_EVENT ((ULONG)0x00000100)
#define SAMPLE_CONNECTED_EVENT ((ULONG)0x00000200)
@@ -83,13 +83,13 @@ typedef struct SAMPLE_CONTEXT_STRUCT
NOTE: If user can not make sure sharing memory is safe, IoTHub Client and DPS Client must be defined seperately. */
union SAMPLE_CLIENT_UNION
{
- NX_AZURE_IOT_HUB_CLIENT iothub_client;
+ NX_AZURE_IOT_PNP_CLIENT iotpnp_client;
#ifdef ENABLE_DPS_SAMPLE
NX_AZURE_IOT_PROVISIONING_CLIENT prov_client;
#endif /* ENABLE_DPS_SAMPLE */
} client;
-#define iothub_client client.iothub_client
+#define iotpnp_client client.iotpnp_client
#ifdef ENABLE_DPS_SAMPLE
#define prov_client client.prov_client
#endif /* ENABLE_DPS_SAMPLE */
@@ -136,12 +136,10 @@ static UINT exponential_retry_count;
static const CHAR telemetry_name[] = "temperature";
/* Device command. */
-static const CHAR report_method_name[] = "getMaxMinReport";
+static const CHAR report_command_name[] = "getMaxMinReport";
-/* Twin properties. */
+/* Device properties. */
static const CHAR desired_temp_property_name[] = "targetTemperature";
-static const CHAR desired_property_name[] = "desired";
-static const CHAR desired_version_property_name[] = "$version";
static const CHAR reported_max_temp_since_last_reboot[] = "maxTempSinceLastReboot";
static const CHAR report_max_temp_name[] = "maxTemp";
static const CHAR report_min_temp_name[] = "minTemp";
@@ -149,10 +147,6 @@ static const CHAR report_avg_temp_name[] = "avgTemp";
static const CHAR report_start_time_name[] = "startTime";
static const CHAR report_end_time_name[] = "endTime";
static const CHAR reported_temp_property_name[] = "targetTemperature";
-static const CHAR reported_value_property_name[] = "value";
-static const CHAR reported_status_property_name[] = "ac";
-static const CHAR reported_version_property_name[] = "av";
-static const CHAR reported_description_property_name[] = "ad";
static const CHAR temp_response_description[] = "success";
/* Fake device data. */
@@ -167,163 +161,83 @@ static double device_min_temp = SAMPLE_DEAFULT_START_TEMP_CELSIUS;
static double device_avg_temp = SAMPLE_DEAFULT_START_TEMP_CELSIUS;
static UCHAR scratch_buffer[256];
-/* Move reader to the value of property name. */
-static UINT sample_json_child_token_move(NX_AZURE_IOT_JSON_READER *json_reader,
- UCHAR *property_name_ptr, UINT property_name_len)
-{
- while (nx_azure_iot_json_reader_next_token(json_reader) == NX_AZURE_IOT_SUCCESS)
- {
- if ((nx_azure_iot_json_reader_token_type(json_reader) == NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME) &&
- nx_azure_iot_json_reader_token_is_text_equal(json_reader,
- property_name_ptr,
- property_name_len))
- {
- if (nx_azure_iot_json_reader_next_token(json_reader))
- {
- printf("Failed to read next token\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
-
- return(NX_AZURE_IOT_SUCCESS);
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT)
- {
- if (nx_azure_iot_json_reader_skip_children(json_reader))
- {
- printf("Failed to skip child of complex object\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
- }
- else if (nx_azure_iot_json_reader_token_type(json_reader) == NX_AZURE_IOT_READER_TOKEN_END_OBJECT)
- {
- return(NX_AZURE_IOT_NOT_FOUND);
- }
- }
-
- return(NX_AZURE_IOT_NOT_FOUND);
-}
-
-/* Build reported property JSON. */
-static UINT sample_build_reported_property(NX_AZURE_IOT_JSON_WRITER *json_builder_ptr, double temp)
-{
-UINT ret;
-
- if (nx_azure_iot_json_writer_append_begin_object(json_builder_ptr) ||
- nx_azure_iot_json_writer_append_property_with_double_value(json_builder_ptr,
- (UCHAR *)reported_max_temp_since_last_reboot,
- sizeof(reported_max_temp_since_last_reboot) - 1,
- temp, DOUBLE_DECIMAL_PLACE_DIGITS) ||
- nx_azure_iot_json_writer_append_end_object(json_builder_ptr))
- {
- ret = 1;
- printf("Failed to build reported property\r\n");
- }
- else
- {
- ret = 0;
- }
-
- return(ret);
-}
-
/* Send desired property response as reported property. */
static VOID sample_send_target_temperature_report(SAMPLE_CONTEXT *context, double current_device_temp_value,
- UINT status, UINT version, UCHAR *description_ptr,
+ UINT status, ULONG version, UCHAR *description_ptr,
UINT description_len)
{
NX_AZURE_IOT_JSON_WRITER json_builder;
-UINT bytes_copied;
UINT response_status;
UINT request_id;
-ULONG reported_property_version;
- if (nx_azure_iot_json_writer_with_buffer_init(&json_builder, scratch_buffer, sizeof(scratch_buffer)))
+ if (nx_azure_iot_pnp_client_reported_properties_create(&(context -> iotpnp_client),
+ &json_builder, NX_WAIT_FOREVER))
{
printf("Failed to build reported response\r\n");
return;
}
- if (nx_azure_iot_json_writer_append_begin_object(&json_builder) ||
- nx_azure_iot_json_writer_append_property_name(&json_builder,
- (UCHAR *)reported_temp_property_name,
- sizeof(reported_temp_property_name) - 1) ||
- nx_azure_iot_json_writer_append_begin_object(&json_builder) ||
- nx_azure_iot_json_writer_append_property_with_double_value(&json_builder,
- (UCHAR *)reported_value_property_name,
- sizeof(reported_value_property_name) - 1,
- current_device_temp_value, DOUBLE_DECIMAL_PLACE_DIGITS) ||
- nx_azure_iot_json_writer_append_property_with_int32_value(&json_builder,
- (UCHAR *)reported_status_property_name,
- sizeof(reported_status_property_name) - 1,
- (int32_t)status) ||
- nx_azure_iot_json_writer_append_property_with_int32_value(&json_builder,
- (UCHAR *)reported_version_property_name,
- sizeof(reported_version_property_name) - 1,
- (int32_t)version) ||
- nx_azure_iot_json_writer_append_property_with_string_value(&json_builder,
- (UCHAR *)reported_description_property_name,
- sizeof(reported_description_property_name) - 1,
- description_ptr, description_len) ||
- nx_azure_iot_json_writer_append_end_object(&json_builder) ||
- nx_azure_iot_json_writer_append_end_object(&json_builder))
+ if (nx_azure_iot_pnp_client_reported_property_status_begin(&(context -> iotpnp_client),
+ &json_builder, (const UCHAR *)reported_temp_property_name,
+ sizeof(reported_temp_property_name) - 1,
+ status, version,
+ description_ptr, description_len) ||
+ nx_azure_iot_json_writer_append_double(&json_builder,
+ current_device_temp_value,
+ DOUBLE_DECIMAL_PLACE_DIGITS) ||
+ nx_azure_iot_pnp_client_reported_property_status_end(&(context -> iotpnp_client), &json_builder))
{
nx_azure_iot_json_writer_deinit(&json_builder);
printf("Failed to build reported response\r\n");
}
else
{
- bytes_copied = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
- if (nx_azure_iot_hub_client_device_twin_reported_properties_send(&(context -> iothub_client),
- scratch_buffer, bytes_copied,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE)))
+ if (nx_azure_iot_pnp_client_reported_properties_send(&(context -> iotpnp_client),
+ &json_builder, &request_id,
+ &response_status, NX_NULL,
+ (5 * NX_IP_PERIODIC_RATE)))
{
printf("Failed to send reported response\r\n");
}
+
nx_azure_iot_json_writer_deinit(&json_builder);
}
}
-/* Parses device twin document. */
+/* Parses device properties document. */
static UINT sample_parse_desired_temp_property(SAMPLE_CONTEXT *context,
NX_AZURE_IOT_JSON_READER *json_reader_ptr,
- UINT is_partial)
+ UINT message_type, ULONG version)
{
double parsed_value;
-UINT version;
-NX_AZURE_IOT_JSON_READER copy_json_reader;
-
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr))
- {
- printf("Failed to move to next token\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
+UINT status;
+const UCHAR *component_ptr;
+UINT component_len;
+NX_AZURE_IOT_JSON_READER name_value_reader;
- if (!is_partial && sample_json_child_token_move(json_reader_ptr,
- (UCHAR *)desired_property_name,
- sizeof(desired_property_name) - 1))
+ while ((status = nx_azure_iot_pnp_client_desired_component_property_value_next(&(context -> iotpnp_client),
+ json_reader_ptr,
+ message_type,
+ &component_ptr, &component_len,
+ &name_value_reader)) == NX_AZURE_IOT_SUCCESS)
{
- printf("Failed to get desired property\r\n");
- return(NX_NOT_SUCCESSFUL);
- }
+ if (nx_azure_iot_json_reader_token_is_text_equal(&name_value_reader,
+ (UCHAR *)desired_temp_property_name,
+ sizeof(desired_temp_property_name) - 1))
+ {
+ if ((status = nx_azure_iot_json_reader_next_token(&name_value_reader)) ||
+ (status = nx_azure_iot_json_reader_token_double_get(&name_value_reader, &parsed_value)))
+ {
+ return(status);
+ }
- copy_json_reader = *json_reader_ptr;
- if (sample_json_child_token_move(&copy_json_reader,
- (UCHAR *)desired_version_property_name,
- sizeof(desired_version_property_name) - 1) ||
- nx_azure_iot_json_reader_token_int32_get(&copy_json_reader, (int32_t *)&version))
- {
- printf("Failed to get version\r\n");
- return(NX_NOT_SUCCESSFUL);
+ break;
+ }
}
- if (sample_json_child_token_move(json_reader_ptr,
- (UCHAR *)desired_temp_property_name,
- sizeof(desired_temp_property_name) - 1) ||
- nx_azure_iot_json_reader_token_double_get(json_reader_ptr, &parsed_value))
+ if (status)
{
- return(NX_NOT_SUCCESSFUL);
+ return(status);
}
current_device_temp = parsed_value;
@@ -343,13 +257,13 @@ NX_AZURE_IOT_JSON_READER copy_json_reader;
device_avg_temp = device_temperature_avg_total / device_temperature_avg_count;
sample_send_target_temperature_report(context, current_device_temp, 200,
- (UINT)version, (UCHAR *)temp_response_description,
+ version, (UCHAR *)temp_response_description,
sizeof(temp_response_description) - 1);
return(NX_AZURE_IOT_SUCCESS);
}
-/* sample direct method implementation. */
+/* sample direct command implementation. */
static UINT sample_get_maxmin_report(NX_AZURE_IOT_JSON_READER *json_reader_ptr,
NX_AZURE_IOT_JSON_WRITER *out_json_builder_ptr)
{
@@ -358,10 +272,10 @@ UCHAR *start_time = (UCHAR *)fake_start_report_time;
UINT start_time_len = sizeof(fake_start_report_time) - 1;
UCHAR time_buf[32];
- if (json_reader_ptr != NX_NULL)
+ /* Check for start time if present */
+ if ((status = nx_azure_iot_json_reader_next_token(json_reader_ptr)) == NX_AZURE_IOT_SUCCESS)
{
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
- nx_azure_iot_json_reader_token_string_get(json_reader_ptr, time_buf,
+ if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr, time_buf,
sizeof(time_buf), &start_time_len))
{
return(NX_NOT_SUCCESSFUL);
@@ -369,7 +283,14 @@ UCHAR time_buf[32];
start_time = time_buf;
}
-
+ else
+ {
+ if (status != NX_AZURE_IOT_EMPTY_JSON)
+ {
+ return(NX_NOT_SUCCESSFUL);
+ }
+ }
+
if (nx_azure_iot_json_writer_append_begin_object(out_json_builder_ptr) ||
nx_azure_iot_json_writer_append_property_with_double_value(out_json_builder_ptr,
(UCHAR *)report_max_temp_name,
@@ -405,16 +326,6 @@ UCHAR time_buf[32];
return(status);
}
-static VOID printf_packet(NX_PACKET *packet_ptr)
-{
- while (packet_ptr != NX_NULL)
- {
- printf("%.*s", (INT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr),
- (CHAR *)packet_ptr -> nx_packet_prepend_ptr);
- packet_ptr = packet_ptr -> nx_packet_next;
- }
-}
-
static UINT exponential_backoff_with_jitter()
{
double jitter_percent = (SAMPLE_MAX_EXPONENTIAL_BACKOFF_JITTER_PERCENT / 100.0) * (rand() / ((double)RAND_MAX));
@@ -447,7 +358,7 @@ static VOID exponential_backoff_reset()
exponential_retry_count = 0;
}
-static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status)
+static VOID connection_status_callback(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, UINT status)
{
NX_PARAMETER_NOT_USED(hub_client_ptr);
@@ -466,31 +377,31 @@ static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
}
}
-static VOID message_receive_callback_twin(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_properties(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_DEVICE_TWIN_GET_EVENT, TX_OR);
+ SAMPLE_DEVICE_PROPERTIES_GET_EVENT, TX_OR);
}
-static VOID message_receive_callback_method(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_command(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_METHOD_MESSAGE_EVENT, TX_OR);
+ SAMPLE_COMMAND_MESSAGE_EVENT, TX_OR);
}
-static VOID message_receive_callback_desire_property(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_desire_property(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT, TX_OR);
+ SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT, TX_OR);
}
static VOID sample_connect_action(SAMPLE_CONTEXT *context)
@@ -500,7 +411,8 @@ static VOID sample_connect_action(SAMPLE_CONTEXT *context)
return;
}
- context -> action_result = nx_azure_iot_hub_client_connect(&(context -> iothub_client), NX_FALSE, SAMPLE_WAIT_OPTION);
+ context -> action_result = nx_azure_iot_pnp_client_connect(&(context -> iotpnp_client),
+ NX_FALSE, SAMPLE_WAIT_OPTION);
if (context -> action_result == NX_AZURE_IOT_CONNECTING)
{
@@ -516,7 +428,8 @@ static VOID sample_connect_action(SAMPLE_CONTEXT *context)
context -> state = SAMPLE_STATE_CONNECTED;
context -> action_result =
- nx_azure_iot_hub_client_device_twin_properties_request(&(context -> iothub_client), NX_WAIT_FOREVER);
+ nx_azure_iot_pnp_client_properties_request(&(context -> iotpnp_client),
+ NX_WAIT_FOREVER);
}
}
@@ -528,7 +441,7 @@ static VOID sample_disconnect_action(SAMPLE_CONTEXT *context)
return;
}
- context -> action_result = nx_azure_iot_hub_client_disconnect(&(context -> iothub_client));
+ context -> action_result = nx_azure_iot_pnp_client_disconnect(&(context -> iotpnp_client));
context -> state = SAMPLE_STATE_DISCONNECTED;
}
@@ -542,7 +455,7 @@ static VOID sample_connected_action(SAMPLE_CONTEXT *context)
context -> state = SAMPLE_STATE_CONNECTED;
context -> action_result =
- nx_azure_iot_hub_client_device_twin_properties_request(&(context -> iothub_client), NX_WAIT_FOREVER);
+ nx_azure_iot_pnp_client_properties_request(&(context -> iotpnp_client), NX_WAIT_FOREVER);
}
static VOID sample_initialize_iothub(SAMPLE_CONTEXT *context)
@@ -559,7 +472,7 @@ UCHAR *iothub_device_id = (UCHAR *)DEVICE_ID;
UINT iothub_hostname_length = sizeof(HOST_NAME) - 1;
UINT iothub_device_id_length = sizeof(DEVICE_ID) - 1;
#endif /* ENABLE_DPS_SAMPLE */
-NX_AZURE_IOT_HUB_CLIENT* iothub_client_ptr = &(context -> iothub_client);
+NX_AZURE_IOT_PNP_CLIENT* iotpnp_client_ptr = &(context -> iotpnp_client);
if (context -> state != SAMPLE_STATE_INIT)
{
@@ -582,10 +495,11 @@ NX_AZURE_IOT_HUB_CLIENT* iothub_client_ptr = &(context -> iothub_client);
iothub_hostname_length, iothub_hostname, iothub_device_id_length, iothub_device_id);
/* Initialize IoTHub client. */
- if ((status = nx_azure_iot_hub_client_initialize(iothub_client_ptr, &nx_azure_iot,
+ if ((status = nx_azure_iot_pnp_client_initialize(iotpnp_client_ptr, &nx_azure_iot,
iothub_hostname, iothub_hostname_length,
iothub_device_id, iothub_device_id_length,
- (UCHAR *)MODULE_ID, sizeof(MODULE_ID) - 1,
+ (const UCHAR *)MODULE_ID, sizeof(MODULE_ID) - 1,
+ (const UCHAR *)SAMPLE_PNP_MODEL_ID, sizeof(SAMPLE_PNP_MODEL_ID) - 1,
_nx_azure_iot_tls_supported_crypto,
_nx_azure_iot_tls_supported_crypto_size,
_nx_azure_iot_tls_ciphersuite_map,
@@ -594,7 +508,7 @@ NX_AZURE_IOT_HUB_CLIENT* iothub_client_ptr = &(context -> iothub_client);
sizeof(nx_azure_iot_tls_metadata_buffer),
&root_ca_cert)))
{
- printf("Failed on nx_azure_iot_hub_client_initialize!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_initialize!: error code = 0x%08x\r\n", status);
context -> action_result = status;
return;
}
@@ -612,64 +526,52 @@ NX_AZURE_IOT_HUB_CLIENT* iothub_client_ptr = &(context -> iothub_client);
}
/* Set device certificate. */
- else if ((status = nx_azure_iot_hub_client_device_cert_set(iothub_client_ptr, &device_certificate)))
+ else if ((status = nx_azure_iot_pnp_client_device_cert_set(iotpnp_client_ptr, &device_certificate)))
{
- printf("Failed on nx_azure_iot_hub_client_device_cert_set!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_device_cert_set!: error code = 0x%08x\r\n", status);
}
#else
/* Set symmetric key. */
- if ((status = nx_azure_iot_hub_client_symmetric_key_set(iothub_client_ptr,
+ if ((status = nx_azure_iot_pnp_client_symmetric_key_set(iotpnp_client_ptr,
(UCHAR *)DEVICE_SYMMETRIC_KEY,
sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
{
- printf("Failed on nx_azure_iot_hub_client_symmetric_key_set!\r\n");
+ printf("Failed on nx_azure_iot_pnp_client_symmetric_key_set!\r\n");
}
#endif /* USE_DEVICE_CERTIFICATE */
/* Set connection status callback. */
- else if ((status = nx_azure_iot_hub_client_connection_status_callback_set(iothub_client_ptr,
+ else if ((status = nx_azure_iot_pnp_client_connection_status_callback_set(iotpnp_client_ptr,
connection_status_callback)))
{
printf("Failed on connection_status_callback!\r\n");
}
- else if ((status = nx_azure_iot_hub_client_direct_method_enable(iothub_client_ptr)))
- {
- printf("Direct method receive enable failed!: error code = 0x%08x\r\n", status);
- }
- else if ((status = nx_azure_iot_hub_client_device_twin_enable(iothub_client_ptr)))
- {
- printf("device twin enabled failed!: error code = 0x%08x\r\n", status);
- }
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES,
- message_receive_callback_twin,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_PROPERTIES,
+ message_receive_callback_properties,
(VOID *)context)))
{
- printf("device twin callback set!: error code = 0x%08x\r\n", status);
+ printf("device properties callback set!: error code = 0x%08x\r\n", status);
}
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DIRECT_METHOD,
- message_receive_callback_method,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_COMMAND,
+ message_receive_callback_command,
(VOID *)context)))
{
- printf("device method callback set!: error code = 0x%08x\r\n", status);
+ printf("device command callback set!: error code = 0x%08x\r\n", status);
}
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES,
message_receive_callback_desire_property,
(VOID *)context)))
{
- printf("device twin desired property callback set!: error code = 0x%08x\r\n", status);
- }
- else if ((status = nx_azure_iot_hub_client_model_id_set(iothub_client_ptr, (UCHAR *)SAMPLE_PNP_MODEL_ID, sizeof(SAMPLE_PNP_MODEL_ID) - 1)))
- {
- printf("digital twin modelId set!: error code = 0x%08x\r\n", status);
+ printf("device desired property callback set!: error code = 0x%08x\r\n", status);
}
if (status)
{
- nx_azure_iot_hub_client_deinitialize(iothub_client_ptr);
+ nx_azure_iot_pnp_client_deinitialize(iotpnp_client_ptr);
}
context -> action_result = status;
@@ -703,7 +605,7 @@ static VOID sample_connection_error_recover(SAMPLE_CONTEXT *context)
printf("re-initializing iothub connection, after backoff\r\n");
tx_thread_sleep(exponential_backoff_with_jitter());
- nx_azure_iot_hub_client_deinitialize(&(context -> iothub_client));
+ nx_azure_iot_pnp_client_deinitialize(&(context -> iotpnp_client));
context -> state = SAMPLE_STATE_INIT;
}
break;
@@ -741,7 +643,7 @@ static VOID sample_trigger_action(SAMPLE_CONTEXT *context)
{
context -> last_periodic_action_tick = tx_time_get();
tx_event_flags_set(&(context -> sample_events), SAMPLE_TELEMETRY_SEND_EVENT, TX_OR);
- tx_event_flags_set(&(context -> sample_events), SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT, TX_OR);
+ tx_event_flags_set(&(context -> sample_events), SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT, TX_OR);
}
}
break;
@@ -754,18 +656,18 @@ static VOID sample_trigger_action(SAMPLE_CONTEXT *context)
}
}
-static void sample_direct_method_action(SAMPLE_CONTEXT *sample_context_ptr)
+static void sample_command_action(SAMPLE_CONTEXT *sample_context_ptr)
{
-NX_PACKET *packet_ptr;
UINT status = 0;
-USHORT method_name_length;
-const UCHAR *method_name_ptr;
+const UCHAR *component_name_ptr;
+UINT component_name_length;
+const UCHAR *command_name_ptr;
+UINT command_name_length;
USHORT context_length;
VOID *context_ptr;
UINT dm_status = 404;
UINT response_payload = 0;
NX_AZURE_IOT_JSON_READER json_reader;
-NX_AZURE_IOT_JSON_READER *json_reader_ptr = NX_NULL;
NX_AZURE_IOT_JSON_WRITER json_builder;
if (sample_context_ptr -> state != SAMPLE_STATE_CONNECTED)
@@ -773,54 +675,33 @@ NX_AZURE_IOT_JSON_WRITER json_builder;
return;
}
- if ((status = nx_azure_iot_hub_client_direct_method_message_receive(&(sample_context_ptr -> iothub_client),
- &method_name_ptr, &method_name_length,
- &context_ptr, &context_length,
- &packet_ptr, NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_command_receive(&(sample_context_ptr -> iotpnp_client),
+ &component_name_ptr, &component_name_length,
+ &command_name_ptr, &command_name_length,
+ &context_ptr, &context_length,
+ &json_reader, NX_WAIT_FOREVER)))
{
- printf("Direct method receive failed!: error code = 0x%08x\r\n", status);
+ printf("Command receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Receive method call: %.*s, with payload:", (INT)method_name_length, (CHAR *)method_name_ptr);
- printf_packet(packet_ptr);
+ printf("Received command: %.*s", (INT)command_name_length, (CHAR *)command_name_ptr);
printf("\r\n");
- if ((method_name_length == (sizeof(report_method_name) - 1)) &&
- (memcmp((VOID *)method_name_ptr, (VOID *)report_method_name, sizeof(report_method_name) - 1) == 0))
+ if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_builder,
+ scratch_buffer,
+ sizeof(scratch_buffer))))
{
- if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_builder,
- scratch_buffer,
- sizeof(scratch_buffer))))
- {
- printf("Failed to initalize json builder response \r\n");
- nx_packet_release(packet_ptr);
- return;
- }
-
- if (packet_ptr ->nx_packet_length != 0)
- {
- if ((status = nx_azure_iot_json_reader_init(&json_reader, packet_ptr)))
- {
- printf("Failed to init json reader!: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
- }
- else
- {
- json_reader_ptr = &json_reader;
- }
- }
- else
- {
- nx_packet_release(packet_ptr);
- status = NX_AZURE_IOT_SUCCESS;
- }
+ printf("Failed to initialize json builder response \r\n");
+ nx_azure_iot_json_reader_deinit(&json_reader);
+ return;
+ }
- if (status != NX_AZURE_IOT_SUCCESS)
- {
- dm_status = SAMPLE_COMMAND_ERROR_STATUS;
- }
- else if (sample_get_maxmin_report(json_reader_ptr, &json_builder) != NX_AZURE_IOT_SUCCESS)
+ if ((command_name_length == (sizeof(report_command_name) - 1)) &&
+ (memcmp((VOID *)command_name_ptr, (VOID *)report_command_name,
+ sizeof(report_command_name) - 1) == 0))
+ {
+ if (sample_get_maxmin_report(&json_reader, &json_builder) != NX_AZURE_IOT_SUCCESS)
{
dm_status = SAMPLE_COMMAND_ERROR_STATUS;
}
@@ -829,57 +710,45 @@ NX_AZURE_IOT_JSON_WRITER json_builder;
dm_status = SAMPLE_COMMAND_SUCCESS_STATUS;
response_payload = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
}
+ }
- if (json_reader_ptr)
- {
- nx_azure_iot_json_reader_deinit(json_reader_ptr);
- }
+ nx_azure_iot_json_reader_deinit(&json_reader);
- nx_azure_iot_json_writer_deinit(&json_builder);
- }
- else
+ if ((status = nx_azure_iot_pnp_client_command_message_response(&(sample_context_ptr -> iotpnp_client), dm_status,
+ context_ptr, context_length, scratch_buffer,
+ response_payload, NX_WAIT_FOREVER)))
{
- nx_packet_release(packet_ptr);
+ printf("Command response failed!: error code = 0x%08x\r\n", status);
}
- if ((status = nx_azure_iot_hub_client_direct_method_message_response(&(sample_context_ptr -> iothub_client), dm_status,
- context_ptr, context_length, scratch_buffer,
- response_payload, NX_WAIT_FOREVER)))
- {
- printf("Direct method response failed!: error code = 0x%08x\r\n", status);
- }
+ nx_azure_iot_json_writer_deinit(&json_builder);
}
-static void sample_device_twin_desired_property_action(SAMPLE_CONTEXT *context)
+static void sample_device_desired_property_action(SAMPLE_CONTEXT *context)
{
-NX_PACKET *packet_ptr;
UINT status = 0;
NX_AZURE_IOT_JSON_READER json_reader;
+ULONG properties_version;
if (context -> state != SAMPLE_STATE_CONNECTED)
{
return;
}
- if ((status = nx_azure_iot_hub_client_device_twin_desired_properties_receive(&(context -> iothub_client), &packet_ptr,
- NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_desired_properties_receive(&(context -> iotpnp_client),
+ &json_reader, &properties_version,
+ NX_WAIT_FOREVER)))
{
printf("Receive desired property receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Receive desired property: ");
- printf_packet(packet_ptr);
+ printf("Received desired property");
printf("\r\n");
- if (nx_azure_iot_json_reader_init(&json_reader, packet_ptr))
- {
- printf("Failed to initialize json reader\r\n");
- nx_packet_release(packet_ptr);
- return;
- }
-
- if (sample_parse_desired_temp_property(context, &json_reader, NX_TRUE) != NX_AZURE_IOT_SUCCESS)
+ status = sample_parse_desired_temp_property(context, &json_reader,
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES, properties_version);
+ if (status && (status != NX_AZURE_IOT_NOT_FOUND))
{
printf("Failed to parse value\r\n");
}
@@ -887,12 +756,11 @@ NX_AZURE_IOT_JSON_READER json_reader;
nx_azure_iot_json_reader_deinit(&json_reader);
}
-static void sample_device_twin_reported_property_action(SAMPLE_CONTEXT *context)
+static void sample_device_reported_property_action(SAMPLE_CONTEXT *context)
{
UINT status = 0;
UINT response_status;
UINT request_id;
-UINT reported_properties_length;
NX_AZURE_IOT_JSON_WRITER json_builder;
ULONG reported_property_version;
@@ -907,28 +775,30 @@ ULONG reported_property_version;
return;
}
- if (nx_azure_iot_json_writer_with_buffer_init(&json_builder, scratch_buffer, sizeof(scratch_buffer)))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_create(&(context -> iotpnp_client),
+ &json_builder, NX_WAIT_FOREVER)))
{
- printf("Failed to init json writer \r\n");
+ printf("Failed create reported properties: error code = 0x%08x\r\n", status);
return;
}
- if ((status = sample_build_reported_property(&json_builder, device_max_temp)))
+ if ((status = nx_azure_iot_json_writer_append_property_with_double_value(&json_builder,
+ (const UCHAR *)reported_max_temp_since_last_reboot,
+ sizeof(reported_max_temp_since_last_reboot) - 1,
+ device_max_temp, DOUBLE_DECIMAL_PLACE_DIGITS)))
{
printf("Build reported property failed: error code = 0x%08x\r\n", status);
nx_azure_iot_json_writer_deinit(&json_builder);
return;
}
- reported_properties_length = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
- if ((status = nx_azure_iot_hub_client_device_twin_reported_properties_send(&(context -> iothub_client),
- scratch_buffer,
- reported_properties_length,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_send(&(context -> iotpnp_client),
+ &json_builder,
+ &request_id, &response_status,
+ &reported_property_version,
+ (5 * NX_IP_PERIODIC_RATE))))
{
- printf("Device twin reported properties failed!: error code = 0x%08x\r\n", status);
+ printf("Reported properties failed!: error code = 0x%08x\r\n", status);
nx_azure_iot_json_writer_deinit(&json_builder);
return;
}
@@ -937,43 +807,39 @@ ULONG reported_property_version;
if ((response_status < 200) || (response_status >= 300))
{
- printf("device twin report properties failed with code : %d\r\n", response_status);
+ printf("Reported properties failed with code : %d\r\n", response_status);
return;
}
last_device_max_tem_reported = device_max_temp;
}
-static void sample_device_twin_get_action(SAMPLE_CONTEXT *context)
+static void sample_device_properties_get_action(SAMPLE_CONTEXT *context)
{
UINT status = 0;
-NX_PACKET *packet_ptr;
NX_AZURE_IOT_JSON_READER json_reader;
+ULONG desired_properties_version;
if (context -> state != SAMPLE_STATE_CONNECTED)
{
return;
}
- if ((status = nx_azure_iot_hub_client_device_twin_properties_receive(&(context -> iothub_client), &packet_ptr,
- NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_properties_receive(&(context -> iotpnp_client),
+ &json_reader,
+ &desired_properties_version,
+ NX_WAIT_FOREVER)))
{
- printf("Twin receive failed!: error code = 0x%08x\r\n", status);
+ printf("Get all properties receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Receive twin properties: ");
- printf_packet(packet_ptr);
+ printf("Received all properties");
printf("\r\n");
- if (nx_azure_iot_json_reader_init(&json_reader, packet_ptr))
- {
- printf("Failed to initialize json reader\r\n");
- nx_packet_release(packet_ptr);
- return;
- }
-
- if (sample_parse_desired_temp_property(context, &json_reader, NX_FALSE) != NX_AZURE_IOT_SUCCESS)
+ status = sample_parse_desired_temp_property(context, &json_reader,
+ NX_AZURE_IOT_PNP_PROPERTIES, desired_properties_version);
+ if (status && (status != NX_AZURE_IOT_NOT_FOUND))
{
printf("Failed to parse value\r\n");
}
@@ -994,7 +860,9 @@ UINT buffer_length;
}
/* Create a telemetry message packet. */
- if ((status = nx_azure_iot_hub_client_telemetry_message_create(&(context -> iothub_client), &packet_ptr, NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_telemetry_message_create(&(context -> iotpnp_client),
+ NX_NULL, 0, &packet_ptr,
+ NX_WAIT_FOREVER)))
{
printf("Telemetry message create failed!: error code = 0x%08x\r\n", status);
return;
@@ -1004,7 +872,7 @@ UINT buffer_length;
if(nx_azure_iot_json_writer_with_buffer_init(&json_builder, scratch_buffer, sizeof(scratch_buffer)))
{
printf("Telemetry message failed to build message\r\n");
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return;
}
@@ -1018,17 +886,18 @@ UINT buffer_length;
{
printf("Telemetry message failed to build message\r\n");
nx_azure_iot_json_writer_deinit(&json_builder);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return;
}
buffer_length = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
nx_azure_iot_json_writer_deinit(&json_builder);
- if ((status = nx_azure_iot_hub_client_telemetry_send(&(context -> iothub_client), packet_ptr,
- (UCHAR *)scratch_buffer, buffer_length, SAMPLE_WAIT_OPTION)))
+ if ((status = nx_azure_iot_pnp_client_telemetry_send(&(context -> iotpnp_client), packet_ptr,
+ (UCHAR *)scratch_buffer, buffer_length,
+ SAMPLE_WAIT_OPTION)))
{
printf("Telemetry message send failed!: error code = 0x%08x\r\n", status);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return;
}
@@ -1085,7 +954,7 @@ UINT status;
if ((status = nx_azure_iot_provisioning_client_symmetric_key_set(prov_client_ptr, (UCHAR *)DEVICE_SYMMETRIC_KEY,
sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
{
- printf("Failed on nx_azure_iot_hub_client_symmetric_key_set!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_symmetric_key_set!: error code = 0x%08x\r\n", status);
}
#endif /* USE_DEVICE_CERTIFICATE */
else if ((status = nx_azure_iot_provisioning_client_registration_payload_set(prov_client_ptr, (UCHAR *)SAMPLE_PNP_DPS_PAYLOAD,
@@ -1129,8 +998,8 @@ UINT status;
* | | INIT | | | | | |
* | | SUCCESS | | | | | +--------+
* | INIT | | CONNECT | | CONNECTING | | CONNECTED | | (TELEMETRY |
- * | +-----------> +----->+ +-------> | | METHOD |
- * | | | | | | | <--------+ DEVICETWIN)
+ * | +-----------> +----->+ +-------> | | COMMAND |
+ * | | | | | | | <--------+ PROPERTIES)
* | | | | | | | |
* +-----+--------+ +----+---+-----+ +------+-------+ +--------+-----+
* ^ ^ | | |
@@ -1181,19 +1050,19 @@ UINT loop = NX_TRUE;
sample_initialize_iothub(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_GET_EVENT)
+ if (app_events & SAMPLE_DEVICE_PROPERTIES_GET_EVENT)
{
- sample_device_twin_get_action(context);
+ sample_device_properties_get_action(context);
}
- if (app_events & SAMPLE_METHOD_MESSAGE_EVENT)
+ if (app_events & SAMPLE_COMMAND_MESSAGE_EVENT)
{
- sample_direct_method_action(context);
+ sample_command_action(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT)
+ if (app_events & SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT)
{
- sample_device_twin_desired_property_action(context);
+ sample_device_desired_property_action(context);
}
if (app_events & SAMPLE_TELEMETRY_SEND_EVENT)
@@ -1201,9 +1070,9 @@ UINT loop = NX_TRUE;
sample_telemetry_action(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT)
+ if (app_events & SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT)
{
- sample_device_twin_reported_property_action(context);
+ sample_device_reported_property_action(context);
}
if (app_events & SAMPLE_DISCONNECT_EVENT)
diff --git a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.c b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.c
index bb53737a..26208459 100644
--- a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.c
+++ b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.c
@@ -11,8 +11,6 @@
#include "sample_pnp_deviceinfo_component.h"
-#include "nx_azure_iot_pnp_helpers.h"
-
#define DOUBLE_DECIMAL_PLACE_DIGITS (2)
/* Reported property keys and values. */
@@ -33,14 +31,10 @@ static const double sample_pnp_device_info_total_storage_property_value = 1024.0
static const CHAR sample_pnp_device_info_total_memory_property_name[] = "totalMemory";
static const double sample_pnp_device_info_total_memory_property_value = 128;
-static UCHAR scratch_buffer[512];
-
-static UINT append_properties(NX_AZURE_IOT_JSON_WRITER *json_writer, VOID *context)
+static UINT append_properties(NX_AZURE_IOT_JSON_WRITER *json_writer)
{
UINT status;
- NX_PARAMETER_NOT_USED(context);
-
if (nx_azure_iot_json_writer_append_property_with_string_value(json_writer,
(UCHAR *)sample_pnp_device_info_manufacturer_property_name,
sizeof(sample_pnp_device_info_manufacturer_property_name) - 1,
@@ -92,50 +86,48 @@ UINT status;
}
UINT sample_pnp_deviceinfo_report_all_properties(UCHAR *component_name_ptr, UINT component_name_len,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr)
{
-UINT reported_properties_length;
UINT status;
-UINT response_status;
-UINT request_id;
-NX_AZURE_IOT_JSON_WRITER json_builder;
-ULONG reported_property_version;
+UINT response_status = 0;
+NX_AZURE_IOT_JSON_WRITER json_writer;
- if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_builder,
- scratch_buffer,
- sizeof(scratch_buffer))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_create(iotpnp_client_ptr,
+ &json_writer, NX_WAIT_FOREVER)))
{
- printf("Failed to initialize json writer\r\n");
- return(NX_NOT_SUCCESSFUL);
+ printf("Failed create reported properties: error code = 0x%08x\r\n", status);
+ return(status);
}
- if ((status = nx_azure_iot_pnp_helper_build_reported_property(component_name_ptr, component_name_len,
- append_properties, NX_NULL,
- &json_builder)))
+ if ((status = nx_azure_iot_pnp_client_reported_property_component_begin(iotpnp_client_ptr,
+ &json_writer,
+ component_name_ptr,
+ component_name_len)) ||
+ (status = append_properties(&json_writer)) ||
+ (status = nx_azure_iot_pnp_client_reported_property_component_end(iotpnp_client_ptr,
+ &json_writer)))
{
printf("Failed to build reported property!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- reported_properties_length = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
- if ((status = nx_azure_iot_hub_client_device_twin_reported_properties_send(iothub_client_ptr,
- scratch_buffer,
- reported_properties_length,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_send(iotpnp_client_ptr,
+ &json_writer,
+ NX_NULL, &response_status,
+ NX_NULL,
+ (5 * NX_IP_PERIODIC_RATE))))
{
- printf("Device twin reported properties failed!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ printf("Reported properties send failed!: error code = 0x%08x\r\n", status);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
if ((response_status < 200) || (response_status >= 300))
{
- printf("device twin report properties failed with code : %d\r\n", response_status);
+ printf("Reported properties send failed with code : %d\r\n", response_status);
return(NX_NOT_SUCCESSFUL);
}
diff --git a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.h b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.h
index 2de2bbe5..539811f8 100644
--- a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.h
+++ b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_deviceinfo_component.h
@@ -16,11 +16,11 @@
extern "C" {
#endif
-#include "nx_azure_iot_hub_client.h"
+#include "nx_azure_iot_pnp_client.h"
#include "nx_api.h"
UINT sample_pnp_deviceinfo_report_all_properties(UCHAR *component_name_ptr, UINT component_name_len,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr);
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr);
#ifdef __cplusplus
}
diff --git a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_temperature_controller.c b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_temperature_controller.c
index 54d245e8..e2caf044 100644
--- a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_temperature_controller.c
+++ b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_temperature_controller.c
@@ -12,7 +12,7 @@
#include <stdio.h>
#include "nx_api.h"
-#include "nx_azure_iot_hub_client.h"
+#include "nx_azure_iot_pnp_client.h"
#include "nx_azure_iot_provisioning_client.h"
/* These are sample files, user can build their own certificate and ciphersuites. */
@@ -20,7 +20,6 @@
#include "nx_azure_iot_ciphersuites.h"
#include "sample_config.h"
#include "sample_pnp_deviceinfo_component.h"
-#include "nx_azure_iot_pnp_helpers.h"
#include "sample_pnp_thermostat_component.h"
#ifndef SAMPLE_MAX_EXPONENTIAL_BACKOFF_IN_SEC
@@ -43,11 +42,11 @@
#define SAMPLE_ALL_EVENTS ((ULONG)0xFFFFFFFF)
#define SAMPLE_CONNECT_EVENT ((ULONG)0x00000001)
#define SAMPLE_INITIALIZATION_EVENT ((ULONG)0x00000002)
-#define SAMPLE_METHOD_MESSAGE_EVENT ((ULONG)0x00000004)
-#define SAMPLE_DEVICE_TWIN_GET_EVENT ((ULONG)0x00000008)
-#define SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT ((ULONG)0x00000010)
+#define SAMPLE_COMMAND_MESSAGE_EVENT ((ULONG)0x00000004)
+#define SAMPLE_DEVICE_PROPERTIES_GET_EVENT ((ULONG)0x00000008)
+#define SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT ((ULONG)0x00000010)
#define SAMPLE_TELEMETRY_SEND_EVENT ((ULONG)0x00000020)
-#define SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT ((ULONG)0x00000040)
+#define SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT ((ULONG)0x00000040)
#define SAMPLE_DISCONNECT_EVENT ((ULONG)0x00000080)
#define SAMPLE_RECONNECT_EVENT ((ULONG)0x00000100)
#define SAMPLE_CONNECTED_EVENT ((ULONG)0x00000200)
@@ -84,13 +83,13 @@ typedef struct SAMPLE_CONTEXT_STRUCT
NOTE: If user can not make sure sharing memory is safe, IoTHub Client and DPS Client must be defined seperately. */
union SAMPLE_CLIENT_UNION
{
- NX_AZURE_IOT_HUB_CLIENT iothub_client;
+ NX_AZURE_IOT_PNP_CLIENT iotpnp_client;
#ifdef ENABLE_DPS_SAMPLE
NX_AZURE_IOT_PROVISIONING_CLIENT prov_client;
#endif /* ENABLE_DPS_SAMPLE */
} client;
-#define iothub_client client.iothub_client
+#define iotpnp_client client.iotpnp_client
#ifdef ENABLE_DPS_SAMPLE
#define prov_client client.prov_client
#endif /* ENABLE_DPS_SAMPLE */
@@ -143,10 +142,6 @@ static double sample_thermostat_2_last_device_max_tem_reported;
static const CHAR sample_device_info_component[] = "deviceInformation";
static UINT sample_device_info_sent;
static UINT sample_device_serial_info_sent;
-static const CHAR *sample_components[] = { sample_thermostat_1_component,
- sample_thermostat_2_component,
- sample_device_info_component };
-static UINT sample_components_num = sizeof(sample_components) / sizeof(sample_components[0]);
/* Name of the serial number property as defined in this component's DTML. */
static const CHAR sample_serial_number_property_name[] = "serialNumber";
@@ -162,7 +157,7 @@ static const CHAR rebootCommand[] = "reboot";
static const INT working_set_minimum = 1000;
static const INT working_set_random_modulo = 500;
-static UCHAR scratch_buffer[512];
+static UCHAR scratch_buffer[256];
static UINT sample_pnp_temp_controller_reboot_command(NX_AZURE_IOT_JSON_READER *json_reader_ptr,
NX_AZURE_IOT_JSON_WRITER *out_json_builder_ptr)
@@ -171,24 +166,16 @@ INT delay;
NX_PARAMETER_NOT_USED(out_json_builder_ptr);
- if (json_reader_ptr == NX_NULL)
+ if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
+ nx_azure_iot_json_reader_token_int32_get(json_reader_ptr, (int32_t *)&delay))
{
- printf("Payload found to be null for reboot command\r\n");
return(NX_NOT_SUCCESSFUL);
}
- else
- {
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
- nx_azure_iot_json_reader_token_int32_get(json_reader_ptr, (int32_t *)&delay))
- {
- return(NX_NOT_SUCCESSFUL);
- }
- }
return(NX_AZURE_IOT_SUCCESS);
}
-static UINT sample_pnp_temp_controller_telemetry_send(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
+static UINT sample_pnp_temp_controller_telemetry_send(NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr)
{
UINT status;
NX_PACKET *packet_ptr;
@@ -199,7 +186,7 @@ INT working_set_value;
working_set_value = working_set_minimum + (rand() % working_set_random_modulo);
/* Create a telemetry message packet. */
- if ((status = nx_azure_iot_pnp_helper_telemetry_message_create(iothub_client_ptr, NX_NULL, 0,
+ if ((status = nx_azure_iot_pnp_client_telemetry_message_create(iotpnp_client_ptr, NX_NULL, 0,
&packet_ptr, NX_WAIT_FOREVER)))
{
printf("Telemetry message create failed!: error code = 0x%08x\r\n", status);
@@ -210,7 +197,7 @@ INT working_set_value;
if (nx_azure_iot_json_writer_with_buffer_init(&json_writer, scratch_buffer, sizeof(scratch_buffer)))
{
printf("Telemetry message failed to build message\r\n");
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(NX_NOT_SUCCESSFUL);
}
@@ -223,17 +210,17 @@ INT working_set_value;
{
printf("Telemetry message failed to build message\r\n");
nx_azure_iot_json_writer_deinit(&json_writer);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(NX_NOT_SUCCESSFUL);
}
buffer_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
- if ((status = nx_azure_iot_hub_client_telemetry_send(iothub_client_ptr, packet_ptr,
+ if ((status = nx_azure_iot_pnp_client_telemetry_send(iotpnp_client_ptr, packet_ptr,
(UCHAR *)scratch_buffer, buffer_length, NX_WAIT_FOREVER)))
{
printf("Telemetry message send failed!: error code = 0x%08x\r\n", status);
nx_azure_iot_json_writer_deinit(&json_writer);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(status);
}
@@ -258,7 +245,8 @@ UINT dm_status;
if (pnp_command_name_length != (sizeof(rebootCommand) - 1) ||
strncmp((CHAR *)pnp_command_name_ptr, (CHAR *)rebootCommand, pnp_command_name_length) != 0)
{
- printf("PnP command=%.*s is not supported on thermostat component", pnp_command_name_length, pnp_command_name_ptr);
+ printf("PnP command=%.*s is not supported on thermostat component",
+ pnp_command_name_length, pnp_command_name_ptr);
dm_status = SAMPLE_COMMAND_NOT_FOUND_STATUS;
}
else
@@ -278,76 +266,52 @@ UINT dm_status;
return(NX_AZURE_IOT_SUCCESS);
}
-static UINT append_serial_number(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, VOID *context)
+static UINT sample_pnp_temp_controller_report_serial_number_property(NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr)
{
- NX_PARAMETER_NOT_USED(context);
-
- return(nx_azure_iot_json_writer_append_property_with_string_value(json_writer_ptr,
- (UCHAR *)sample_serial_number_property_name,
- sizeof(sample_serial_number_property_name) - 1,
- (UCHAR *)sample_serial_number_property_value,
- sizeof(sample_serial_number_property_value) - 1));
-}
-
-static UINT sample_pnp_temp_controller_report_serial_number_property(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
-{
-UINT reported_properties_length;
UINT status;
-UINT response_status;
-UINT request_id;
-NX_AZURE_IOT_JSON_WRITER json_builder;
-ULONG reported_property_version;
+UINT response_status = 0;
+NX_AZURE_IOT_JSON_WRITER json_writer;
- if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_builder,
- scratch_buffer,
- sizeof(scratch_buffer))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_create(iotpnp_client_ptr,
+ &json_writer, NX_WAIT_FOREVER)))
{
- printf("Failed to initialize json writer\r\n");
- return(NX_NOT_SUCCESSFUL);
+ printf("Failed create reported properties: error code = 0x%08x\r\n", status);
+ return(status);
}
- if ((status = nx_azure_iot_pnp_helper_build_reported_property(NX_NULL, 0, append_serial_number, NX_NULL,
- &json_builder)))
+ if ((status = nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
+ (UCHAR *)sample_serial_number_property_name,
+ sizeof(sample_serial_number_property_name) - 1,
+ (UCHAR *)sample_serial_number_property_value,
+ sizeof(sample_serial_number_property_value) - 1)))
{
printf("Failed to build reported property!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- reported_properties_length = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
- if ((status = nx_azure_iot_hub_client_device_twin_reported_properties_send(iothub_client_ptr,
- scratch_buffer,
- reported_properties_length,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_send(iotpnp_client_ptr,
+ &json_writer,
+ NX_NULL, &response_status,
+ NX_NULL,
+ (5 * NX_IP_PERIODIC_RATE))))
{
- printf("Device twin reported properties failed!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ printf("Reported properties send failed!: error code = 0x%08x\r\n", status);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
if ((response_status < 200) || (response_status >= 300))
{
- printf("device twin report properties failed with code : %d\r\n", response_status);
+ printf("Reported properties send failed with code : %d\r\n", response_status);
return(NX_NOT_SUCCESSFUL);
}
return(status);
}
-static VOID printf_packet(NX_PACKET *packet_ptr)
-{
- while (packet_ptr != NX_NULL)
- {
- printf("%.*s", (INT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr),
- (CHAR *)packet_ptr -> nx_packet_prepend_ptr);
- packet_ptr = packet_ptr -> nx_packet_next;
- }
-}
-
static UINT exponential_backoff_with_jitter()
{
double jitter_percent = (SAMPLE_MAX_EXPONENTIAL_BACKOFF_JITTER_PERCENT / 100.0) * (rand() / ((double)RAND_MAX));
@@ -380,7 +344,7 @@ static VOID exponential_backoff_reset()
exponential_retry_count = 0;
}
-static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status)
+static VOID connection_status_callback(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, UINT status)
{
NX_PARAMETER_NOT_USED(hub_client_ptr);
@@ -399,31 +363,31 @@ static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
}
}
-static VOID message_receive_callback_twin(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_properties(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_DEVICE_TWIN_GET_EVENT, TX_OR);
+ SAMPLE_DEVICE_PROPERTIES_GET_EVENT, TX_OR);
}
-static VOID message_receive_callback_method(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_command(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_METHOD_MESSAGE_EVENT, TX_OR);
+ SAMPLE_COMMAND_MESSAGE_EVENT, TX_OR);
}
-static VOID message_receive_callback_desired_property(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context)
+static VOID message_receive_callback_desired_property(NX_AZURE_IOT_PNP_CLIENT *hub_client_ptr, VOID *context)
{
SAMPLE_CONTEXT *sample_ctx = (SAMPLE_CONTEXT *)context;
NX_PARAMETER_NOT_USED(hub_client_ptr);
tx_event_flags_set(&(sample_ctx -> sample_events),
- SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT, TX_OR);
+ SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT, TX_OR);
}
static VOID sample_connect_action(SAMPLE_CONTEXT *context)
@@ -433,7 +397,8 @@ static VOID sample_connect_action(SAMPLE_CONTEXT *context)
return;
}
- context -> action_result = nx_azure_iot_hub_client_connect(&(context -> iothub_client), NX_FALSE, SAMPLE_WAIT_OPTION);
+ context -> action_result = nx_azure_iot_pnp_client_connect(&(context -> iotpnp_client),
+ NX_FALSE, SAMPLE_WAIT_OPTION);
if (context -> action_result == NX_AZURE_IOT_CONNECTING)
{
@@ -449,7 +414,7 @@ static VOID sample_connect_action(SAMPLE_CONTEXT *context)
context -> state = SAMPLE_STATE_CONNECTED;
context -> action_result =
- nx_azure_iot_hub_client_device_twin_properties_request(&(context -> iothub_client), NX_WAIT_FOREVER);
+ nx_azure_iot_pnp_client_properties_request(&(context -> iotpnp_client), NX_WAIT_FOREVER);
}
}
@@ -461,7 +426,7 @@ static VOID sample_disconnect_action(SAMPLE_CONTEXT *context)
return;
}
- context -> action_result = nx_azure_iot_hub_client_disconnect(&(context -> iothub_client));
+ context -> action_result = nx_azure_iot_pnp_client_disconnect(&(context -> iotpnp_client));
context -> state = SAMPLE_STATE_DISCONNECTED;
}
@@ -475,7 +440,7 @@ static VOID sample_connected_action(SAMPLE_CONTEXT *context)
context -> state = SAMPLE_STATE_CONNECTED;
context -> action_result =
- nx_azure_iot_hub_client_device_twin_properties_request(&(context -> iothub_client), NX_WAIT_FOREVER);
+ nx_azure_iot_pnp_client_properties_request(&(context -> iotpnp_client), NX_WAIT_FOREVER);
}
static VOID sample_initialize_iothub(SAMPLE_CONTEXT *context)
@@ -492,7 +457,7 @@ UCHAR *iothub_device_id = (UCHAR *)DEVICE_ID;
UINT iothub_hostname_length = sizeof(HOST_NAME) - 1;
UINT iothub_device_id_length = sizeof(DEVICE_ID) - 1;
#endif /* ENABLE_DPS_SAMPLE */
-NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr = &(context -> iothub_client);
+NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr = &(context -> iotpnp_client);
if (context -> state != SAMPLE_STATE_INIT)
{
@@ -515,10 +480,11 @@ NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr = &(context -> iothub_client);
iothub_hostname_length, iothub_hostname, iothub_device_id_length, iothub_device_id);
/* Initialize IoTHub client. */
- if ((status = nx_azure_iot_hub_client_initialize(iothub_client_ptr, &nx_azure_iot,
+ if ((status = nx_azure_iot_pnp_client_initialize(iotpnp_client_ptr, &nx_azure_iot,
iothub_hostname, iothub_hostname_length,
iothub_device_id, iothub_device_id_length,
- (UCHAR *)MODULE_ID, sizeof(MODULE_ID) - 1,
+ (const UCHAR *)MODULE_ID, sizeof(MODULE_ID) - 1,
+ (const UCHAR *)SAMPLE_PNP_MODEL_ID, sizeof(SAMPLE_PNP_MODEL_ID) - 1,
_nx_azure_iot_tls_supported_crypto,
_nx_azure_iot_tls_supported_crypto_size,
_nx_azure_iot_tls_ciphersuite_map,
@@ -527,7 +493,7 @@ NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr = &(context -> iothub_client);
sizeof(nx_azure_iot_tls_metadata_buffer),
&root_ca_cert)))
{
- printf("Failed on nx_azure_iot_hub_client_initialize!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_initialize!: error code = 0x%08x\r\n", status);
context -> action_result = status;
return;
}
@@ -545,64 +511,64 @@ NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr = &(context -> iothub_client);
}
/* Set device certificate. */
- else if ((status = nx_azure_iot_hub_client_device_cert_set(iothub_client_ptr, &device_certificate)))
+ else if ((status = nx_azure_iot_pnp_client_device_cert_set(iotpnp_client_ptr, &device_certificate)))
{
- printf("Failed on nx_azure_iot_hub_client_device_cert_set!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_device_cert_set!: error code = 0x%08x\r\n", status);
}
#else
/* Set symmetric key. */
- if ((status = nx_azure_iot_hub_client_symmetric_key_set(iothub_client_ptr,
+ if ((status = nx_azure_iot_pnp_client_symmetric_key_set(iotpnp_client_ptr,
(UCHAR *)DEVICE_SYMMETRIC_KEY,
sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
{
- printf("Failed on nx_azure_iot_hub_client_symmetric_key_set! error: 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_symmetric_key_set! error: 0x%08x\r\n", status);
}
#endif /* USE_DEVICE_CERTIFICATE */
/* Set connection status callback. */
- else if ((status = nx_azure_iot_hub_client_connection_status_callback_set(iothub_client_ptr,
+ else if ((status = nx_azure_iot_pnp_client_connection_status_callback_set(iotpnp_client_ptr,
connection_status_callback)))
{
printf("Failed on connection_status_callback!\r\n");
}
- else if ((status = nx_azure_iot_hub_client_direct_method_enable(iothub_client_ptr)))
- {
- printf("Direct method receive enable failed!: error code = 0x%08x\r\n", status);
- }
- else if ((status = nx_azure_iot_hub_client_device_twin_enable(iothub_client_ptr)))
- {
- printf("device twin enabled failed!: error code = 0x%08x\r\n", status);
- }
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES,
- message_receive_callback_twin,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_PROPERTIES,
+ message_receive_callback_properties,
(VOID *)context)))
{
- printf("device twin callback set!: error code = 0x%08x\r\n", status);
+ printf("device properties callback set!: error code = 0x%08x\r\n", status);
}
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DIRECT_METHOD,
- message_receive_callback_method,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_COMMAND,
+ message_receive_callback_command,
(VOID *)context)))
{
- printf("device method callback set!: error code = 0x%08x\r\n", status);
+ printf("device command callback set!: error code = 0x%08x\r\n", status);
}
- else if ((status = nx_azure_iot_hub_client_receive_callback_set(iothub_client_ptr,
- NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES,
+ else if ((status = nx_azure_iot_pnp_client_receive_callback_set(iotpnp_client_ptr,
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES,
message_receive_callback_desired_property,
(VOID *)context)))
{
- printf("device twin desired property callback set!: error code = 0x%08x\r\n", status);
+ printf("device desired property callback set!: error code = 0x%08x\r\n", status);
}
- else if ((status = nx_azure_iot_hub_client_model_id_set(iothub_client_ptr, (UCHAR *)SAMPLE_PNP_MODEL_ID, sizeof(SAMPLE_PNP_MODEL_ID) - 1)))
+ else if ((status = nx_azure_iot_pnp_client_component_add(iotpnp_client_ptr,
+ (const UCHAR *)sample_thermostat_1_component,
+ sizeof(sample_thermostat_1_component) - 1)) ||
+ (status = nx_azure_iot_pnp_client_component_add(iotpnp_client_ptr,
+ (const UCHAR *)sample_thermostat_2_component,
+ sizeof(sample_thermostat_2_component) - 1)) ||
+ (status = nx_azure_iot_pnp_client_component_add(iotpnp_client_ptr,
+ (const UCHAR *)sample_device_info_component,
+ sizeof(sample_device_info_component) - 1)))
{
- printf("digital twin modelId set!: error code = 0x%08x\r\n", status);
+ printf("Failed to add component to pnp client!: error code = 0x%08x\r\n", status);
}
if (status)
{
- nx_azure_iot_hub_client_deinitialize(iothub_client_ptr);
+ nx_azure_iot_pnp_client_deinitialize(iotpnp_client_ptr);
}
context -> action_result = status;
@@ -636,7 +602,7 @@ static VOID sample_connection_error_recover(SAMPLE_CONTEXT *context)
printf("re-initializing iothub connection, after backoff\r\n");
tx_thread_sleep(exponential_backoff_with_jitter());
- nx_azure_iot_hub_client_deinitialize(&(context -> iothub_client));
+ nx_azure_iot_pnp_client_deinitialize(&(context -> iotpnp_client));
context -> state = SAMPLE_STATE_INIT;
}
break;
@@ -674,7 +640,7 @@ static VOID sample_trigger_action(SAMPLE_CONTEXT *context)
{
context -> last_periodic_action_tick = tx_time_get();
tx_event_flags_set(&(context -> sample_events), SAMPLE_TELEMETRY_SEND_EVENT, TX_OR);
- tx_event_flags_set(&(context -> sample_events), SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT, TX_OR);
+ tx_event_flags_set(&(context -> sample_events), SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT, TX_OR);
}
}
break;
@@ -687,12 +653,9 @@ static VOID sample_trigger_action(SAMPLE_CONTEXT *context)
}
}
-static VOID sample_direct_method_action(SAMPLE_CONTEXT *sample_context_ptr)
+static VOID sample_command_action(SAMPLE_CONTEXT *sample_context_ptr)
{
-NX_PACKET *packet_ptr;
UINT status;
-USHORT method_name_length;
-const UCHAR *method_name_ptr;
USHORT context_length;
VOID *context_ptr;
UINT component_name_length;
@@ -701,7 +664,6 @@ UINT pnp_command_name_length;
const UCHAR *pnp_command_name_ptr;
NX_AZURE_IOT_JSON_WRITER json_writer;
NX_AZURE_IOT_JSON_READER json_reader;
-NX_AZURE_IOT_JSON_READER *json_reader_ptr;
UINT status_code;
UINT response_length;
@@ -710,179 +672,153 @@ UINT response_length;
return;
}
- if ((status = nx_azure_iot_hub_client_direct_method_message_receive(&(sample_context_ptr -> iothub_client),
- &method_name_ptr, &method_name_length,
- &context_ptr, &context_length,
- &packet_ptr, NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_command_receive(&(sample_context_ptr -> iotpnp_client),
+ &component_name_ptr, &component_name_length,
+ &pnp_command_name_ptr, &pnp_command_name_length,
+ &context_ptr, &context_length,
+ &json_reader, NX_WAIT_FOREVER)))
{
- printf("Direct method receive failed!: error code = 0x%08x\r\n", status);
+ printf("Command receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Receive method call: %.*s, with payload:", (INT)method_name_length, (CHAR *)method_name_ptr);
- printf_packet(packet_ptr);
+ if (component_name_ptr != NX_NULL)
+ {
+ printf("Received component: %.*s ", component_name_length, component_name_ptr);
+ }
+ else
+ {
+ printf("Received component: root component ");
+ }
+
+ printf("command: %.*s", pnp_command_name_length, (CHAR *)pnp_command_name_ptr);
printf("\r\n");
- if ((status = nx_azure_iot_pnp_helper_command_name_parse(method_name_ptr, method_name_length,
- &component_name_ptr, &component_name_length,
- &pnp_command_name_ptr,
- &pnp_command_name_length)) != NX_AZURE_IOT_SUCCESS)
+ if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_writer,
+ scratch_buffer,
+ sizeof(scratch_buffer))))
+ {
+ printf("Failed to initialize json builder response \r\n");
+ nx_azure_iot_json_reader_deinit(&json_reader);
+ return;
+ }
+
+ if ((status = sample_pnp_thermostat_process_command(&sample_thermostat_1, component_name_ptr,
+ component_name_length, pnp_command_name_ptr,
+ pnp_command_name_length, &json_reader,
+ &json_writer, &status_code)) == NX_AZURE_IOT_SUCCESS)
{
- printf("Failed to parse command name: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
+ printf("Successfully executed command %.*s on thermostat 1\r\n", pnp_command_name_length, pnp_command_name_ptr);
+ response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
}
- else if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_writer,
- scratch_buffer,
- sizeof(scratch_buffer))))
+ else if ((status = sample_pnp_thermostat_process_command(&sample_thermostat_2, component_name_ptr,
+ component_name_length, pnp_command_name_ptr,
+ pnp_command_name_length, &json_reader,
+ &json_writer, &status_code)) == NX_AZURE_IOT_SUCCESS)
{
- printf("Failed to initialize json writer: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
+ printf("Successfully executed command %.*s on thermostat 2\r\n", pnp_command_name_length, pnp_command_name_ptr);
+ response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
}
- else if ((packet_ptr ->nx_packet_length != 0) &&
- (status = nx_azure_iot_json_reader_init(&json_reader, packet_ptr)))
+ else if((status = sample_pnp_temp_controller_process_command(component_name_ptr, component_name_length,
+ pnp_command_name_ptr, pnp_command_name_length,
+ &json_reader, &json_writer,
+ &status_code)) == NX_AZURE_IOT_SUCCESS)
{
- printf("Failed to initialize json reader: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
+ printf("Successfully executed command %.*s controller \r\n", pnp_command_name_length, pnp_command_name_ptr);
+ response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
}
else
{
- if (packet_ptr ->nx_packet_length == 0)
- {
- nx_packet_release(packet_ptr);
- json_reader_ptr = NX_NULL;
- }
- else
- {
- json_reader_ptr = &json_reader;
- }
+ printf("Failed to find any handler for command %.*s\r\n", pnp_command_name_length, pnp_command_name_ptr);
+ status_code = SAMPLE_COMMAND_NOT_FOUND_STATUS;
+ response_length = 0;
+ }
- if ((status = sample_pnp_thermostat_process_command(&sample_thermostat_1, component_name_ptr,
- component_name_length, pnp_command_name_ptr,
- pnp_command_name_length, json_reader_ptr,
- &json_writer, &status_code)) == NX_AZURE_IOT_SUCCESS)
- {
- printf("Successfully executed command %.*s on thermostat 1\r\n", method_name_length, method_name_ptr);
- response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
- }
- else if ((status = sample_pnp_thermostat_process_command(&sample_thermostat_2, component_name_ptr,
- component_name_length, pnp_command_name_ptr,
- pnp_command_name_length, json_reader_ptr,
- &json_writer, &status_code)) == NX_AZURE_IOT_SUCCESS)
+ nx_azure_iot_json_reader_deinit(&json_reader);
+
+ if ((status = nx_azure_iot_pnp_client_command_message_response(&(sample_context_ptr -> iotpnp_client), status_code,
+ context_ptr, context_length, scratch_buffer,
+ response_length, NX_WAIT_FOREVER)))
+ {
+ printf("Command response failed!: error code = 0x%08x\r\n", status);
+ }
+
+ nx_azure_iot_json_writer_deinit(&json_writer);
+}
+
+static VOID sample_desired_properties_parse(NX_AZURE_IOT_PNP_CLIENT *pnp_client_ptr,
+ NX_AZURE_IOT_JSON_READER *json_reader_ptr,
+ UINT message_type, ULONG version)
+{
+const UCHAR *component_ptr = NX_NULL;
+UINT component_len = 0;
+NX_AZURE_IOT_JSON_READER name_value_reader;
+
+ while (nx_azure_iot_pnp_client_desired_component_property_value_next(pnp_client_ptr,
+ json_reader_ptr, message_type,
+ &component_ptr, &component_len,
+ &name_value_reader) == NX_AZURE_IOT_SUCCESS)
+ {
+ if (sample_pnp_thermostat_process_property_update(&sample_thermostat_1,
+ pnp_client_ptr,
+ component_ptr, component_len,
+ &name_value_reader, version) == NX_AZURE_IOT_SUCCESS)
{
- printf("Successfully executed command %.*s on thermostat 2\r\n", method_name_length, method_name_ptr);
- response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
+ printf("property updated of thermostat 1\r\n");
}
- else if((status = sample_pnp_temp_controller_process_command(component_name_ptr, component_name_length,
- pnp_command_name_ptr, pnp_command_name_length,
- json_reader_ptr, &json_writer,
- &status_code)) == NX_AZURE_IOT_SUCCESS)
+ else if (sample_pnp_thermostat_process_property_update(&sample_thermostat_2,
+ pnp_client_ptr,
+ component_ptr, component_len,
+ &name_value_reader, version) == NX_AZURE_IOT_SUCCESS)
{
- printf("Successfully executed command %.*s controller \r\n", method_name_length, method_name_ptr);
- response_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
+ printf("property updated of thermostat 2\r\n");
}
else
{
- printf("Failed to find any handler for method %.*s\r\n", method_name_length, method_name_ptr);
- status_code = SAMPLE_COMMAND_NOT_FOUND_STATUS;
- response_length = 0;
- }
-
- if (json_reader_ptr)
- {
- nx_azure_iot_json_reader_deinit(json_reader_ptr);
- }
-
- if ((status = nx_azure_iot_hub_client_direct_method_message_response(&(sample_context_ptr -> iothub_client),
- status_code, context_ptr, context_length,
- scratch_buffer, response_length, NX_WAIT_FOREVER)))
- {
- printf("Direct method response failed!: error code = 0x%08x\r\n", status);
+ if (component_ptr)
+ {
+ printf("Component=%.*s is not implemented by the Controller\r\n", component_len, component_ptr);
+ }
+ else
+ {
+ printf("Root component is not implemented by the Controller\r\n");
+ }
}
-
- nx_azure_iot_json_writer_deinit(&json_writer);
}
}
-static VOID sample_desired_property_callback(UCHAR *component_name_ptr, UINT component_name_len,
- UCHAR *property_name_ptr, UINT property_name_len,
- NX_AZURE_IOT_JSON_READER property_value_reader, UINT version,
- VOID *userContextCallback)
+static VOID sample_device_desired_property_action(SAMPLE_CONTEXT *context)
{
- if (component_name_ptr == NULL || component_name_len == 0)
- {
- /* The PnP protocol does not define a mechanism to report errors such as this to IoTHub, so
- the best we can do here is to log for diagnostics purposes. */
- printf("Property=%.*s arrived for Control component itself. This does not support\
- writeable properties on it (all properties are on subcomponents)", property_name_len, property_name_ptr);
- }
- else if (sample_pnp_thermostat_process_property_update(&sample_thermostat_1,
- (NX_AZURE_IOT_HUB_CLIENT *)userContextCallback,
- component_name_ptr, component_name_len,
- property_name_ptr, property_name_len,
- &property_value_reader, version) == NX_AZURE_IOT_SUCCESS)
- {
- printf("property updated of thermostat 1\r\n");
- }
- else if (sample_pnp_thermostat_process_property_update(&sample_thermostat_2,
- (NX_AZURE_IOT_HUB_CLIENT *)userContextCallback,
- component_name_ptr, component_name_len,
- property_name_ptr, property_name_len,
- &property_value_reader, version) == NX_AZURE_IOT_SUCCESS)
- {
- printf("property updated of thermostat 2\r\n");
- }
- else
- {
- printf("Component=%.*s is not implemented by the Controller\r\n", component_name_len, component_name_ptr);
- }
-}
-
-static VOID sample_device_twin_desired_property_action(SAMPLE_CONTEXT *context)
-{
-NX_PACKET *packet_ptr;
-UINT status;
+UINT status = 0;
NX_AZURE_IOT_JSON_READER json_reader;
+ULONG desired_properties_version;
if (context -> state != SAMPLE_STATE_CONNECTED)
{
return;
}
- if ((status = nx_azure_iot_hub_client_device_twin_desired_properties_receive(&(context -> iothub_client),
- &packet_ptr,
- NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_desired_properties_receive(&(context -> iotpnp_client),
+ &json_reader,
+ &desired_properties_version,
+ NX_WAIT_FOREVER)))
{
- printf("Receive desired property receive failed!: error code = 0x%08x\r\n", status);
+ printf("desired properties receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Receive desired property: ");
- printf_packet(packet_ptr);
+ printf("Received desired property");
printf("\r\n");
- if ((status = nx_azure_iot_json_reader_init(&json_reader, packet_ptr)))
- {
- printf("Failed to initialize json reader: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
- }
- else
- {
- if ((status = nx_azure_iot_pnp_helper_twin_data_parse(&json_reader, NX_TRUE,
- (CHAR **)sample_components,
- sample_components_num,
- scratch_buffer, sizeof(scratch_buffer),
- sample_desired_property_callback,
- (VOID *)&(context -> iothub_client))))
- {
- printf("Failed to parse twin data!: error code = 0x%08x\r\n", status);
- }
+ sample_desired_properties_parse(&(context -> iotpnp_client), &json_reader,
+ NX_AZURE_IOT_PNP_DESIRED_PROPERTIES,
+ desired_properties_version);
- nx_azure_iot_json_reader_deinit(&json_reader);
- }
+ nx_azure_iot_json_reader_deinit(&json_reader);
}
-static VOID sample_device_twin_reported_property_action(SAMPLE_CONTEXT *context)
+static VOID sample_device_reported_property_action(SAMPLE_CONTEXT *context)
{
UINT status;
@@ -894,7 +830,7 @@ UINT status;
/* Only report once. */
if (sample_device_serial_info_sent == 0)
{
- if ((status = sample_pnp_temp_controller_report_serial_number_property(&(context -> iothub_client))))
+ if ((status = sample_pnp_temp_controller_report_serial_number_property(&(context -> iotpnp_client))))
{
printf("Failed sample_pnp_temp_controller_report_serial_number_property: error code = 0x%08x\r\n", status);
}
@@ -904,13 +840,12 @@ UINT status;
}
}
-
/* Only report once. */
if (sample_device_info_sent == 0)
{
if ((status = sample_pnp_deviceinfo_report_all_properties((UCHAR *)sample_device_info_component,
sizeof(sample_device_info_component) - 1,
- &(context -> iothub_client))))
+ &(context -> iotpnp_client))))
{
printf("Failed sample_pnp_deviceinfo_report_all_properties: error code = 0x%08x\r\n", status);
}
@@ -925,7 +860,7 @@ UINT status;
((sample_thermostat_1_last_device_max_temp_reported + 0.01) > sample_thermostat_1.maxTemperature)))
{
if ((status = sample_pnp_thermostat_report_max_temp_since_last_reboot_property(&sample_thermostat_1,
- &(context -> iothub_client))))
+ &(context -> iotpnp_client))))
{
printf("Failed sample_pnp_thermostat_report_max_temp_since_last_reboot_property: error code = 0x%08x\r\n", status);
}
@@ -940,7 +875,7 @@ UINT status;
((sample_thermostat_2_last_device_max_tem_reported + 0.01) > sample_thermostat_2.maxTemperature)))
{
if ((status = sample_pnp_thermostat_report_max_temp_since_last_reboot_property(&sample_thermostat_2,
- &(context -> iothub_client))))
+ &(context -> iotpnp_client))))
{
printf("Failed sample_pnp_thermostat_report_max_temp_since_last_reboot_property: error code = 0x%08x\r\n", status);
}
@@ -951,46 +886,34 @@ UINT status;
}
}
-static VOID sample_device_twin_get_action(SAMPLE_CONTEXT *context)
+static VOID sample_device_properties_get_action(SAMPLE_CONTEXT *context)
{
-NX_PACKET *packet_ptr;
-UINT status;
+UINT status = 0;
NX_AZURE_IOT_JSON_READER json_reader;
+ULONG desired_properties_version;
if (context -> state != SAMPLE_STATE_CONNECTED)
{
return;
}
- if ((status = nx_azure_iot_hub_client_device_twin_properties_receive(&(context -> iothub_client), &packet_ptr,
- NX_WAIT_FOREVER)))
+ if ((status = nx_azure_iot_pnp_client_properties_receive(&(context -> iotpnp_client),
+ &json_reader,
+ &desired_properties_version,
+ NX_WAIT_FOREVER)))
{
- printf("Twin receive failed!: error code = 0x%08x\r\n", status);
+ printf("Get all properties receive failed!: error code = 0x%08x\r\n", status);
return;
}
- printf("Received twin properties: ");
- printf_packet(packet_ptr);
+ printf("Received all properties");
printf("\r\n");
- if ((status = nx_azure_iot_json_reader_init(&json_reader, packet_ptr)))
- {
- printf("Failed to initialize json reader: error code = 0x%08x\r\n", status);
- nx_packet_release(packet_ptr);
- }
- else
- {
- if ((status = nx_azure_iot_pnp_helper_twin_data_parse(&json_reader, NX_FALSE,
- (CHAR **)sample_components, sample_components_num,
- scratch_buffer, sizeof(scratch_buffer),
- sample_desired_property_callback,
- (VOID *)&(context -> iothub_client))))
- {
- printf("Failed to parse twin data!: error code = 0x%08x\r\n", status);
- }
+ sample_desired_properties_parse(&(context -> iotpnp_client), &json_reader,
+ NX_AZURE_IOT_PNP_PROPERTIES,
+ desired_properties_version);
- nx_azure_iot_json_reader_deinit(&json_reader);
- }
+ nx_azure_iot_json_reader_deinit(&json_reader);
}
static VOID sample_telemetry_action(SAMPLE_CONTEXT *context)
@@ -1002,19 +925,19 @@ UINT status;
return;
}
- if ((status = sample_pnp_temp_controller_telemetry_send(&(context -> iothub_client))) != NX_AZURE_IOT_SUCCESS)
+ if ((status = sample_pnp_temp_controller_telemetry_send(&(context -> iotpnp_client))) != NX_AZURE_IOT_SUCCESS)
{
printf("Failed to send sample_pnp__telemetry_send, error: %d", status);
}
if ((status = sample_pnp_thermostat_telemetry_send(&sample_thermostat_1,
- &(context -> iothub_client))) != NX_AZURE_IOT_SUCCESS)
+ &(context -> iotpnp_client))) != NX_AZURE_IOT_SUCCESS)
{
printf("Failed to send sample_pnp_thermostat_telemetry_send, error: %d", status);
}
if ((status = sample_pnp_thermostat_telemetry_send(&sample_thermostat_2,
- &(context -> iothub_client))) != NX_AZURE_IOT_SUCCESS)
+ &(context -> iotpnp_client))) != NX_AZURE_IOT_SUCCESS)
{
printf("Failed to send sample_pnp_thermostat_telemetry_send, error: %d", status);
}
@@ -1070,7 +993,7 @@ UINT status;
if ((status = nx_azure_iot_provisioning_client_symmetric_key_set(prov_client_ptr, (UCHAR *)DEVICE_SYMMETRIC_KEY,
sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
{
- printf("Failed on nx_azure_iot_hub_client_symmetric_key_set!: error code = 0x%08x\r\n", status);
+ printf("Failed on nx_azure_iot_pnp_client_symmetric_key_set!: error code = 0x%08x\r\n", status);
}
#endif /* USE_DEVICE_CERTIFICATE */
else if ((status = nx_azure_iot_provisioning_client_registration_payload_set(prov_client_ptr, (UCHAR *)SAMPLE_PNP_DPS_PAYLOAD,
@@ -1115,8 +1038,8 @@ UINT status;
* | | INIT | | | | | |
* | | SUCCESS | | | | | +--------+
* | INIT | | CONNECT | | CONNECTING | | CONNECTED | | (TELEMETRY |
- * | +-----------> +----->+ +-------> | | METHOD |
- * | | | | | | | <--------+ DEVICETWIN)
+ * | +-----------> +----->+ +-------> | | COMMAND |
+ * | | | | | | | <--------+ PROPERTIES)
* | | | | | | | |
* +-----+--------+ +----+---+-----+ +------+-------+ +--------+-----+
* ^ ^ | | |
@@ -1167,19 +1090,19 @@ UINT loop = NX_TRUE;
sample_initialize_iothub(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_GET_EVENT)
+ if (app_events & SAMPLE_DEVICE_PROPERTIES_GET_EVENT)
{
- sample_device_twin_get_action(context);
+ sample_device_properties_get_action(context);
}
- if (app_events & SAMPLE_METHOD_MESSAGE_EVENT)
+ if (app_events & SAMPLE_COMMAND_MESSAGE_EVENT)
{
- sample_direct_method_action(context);
+ sample_command_action(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_DESIRED_PROPERTY_EVENT)
+ if (app_events & SAMPLE_DEVICE_DESIRED_PROPERTIES_EVENT)
{
- sample_device_twin_desired_property_action(context);
+ sample_device_desired_property_action(context);
}
if (app_events & SAMPLE_TELEMETRY_SEND_EVENT)
@@ -1187,9 +1110,9 @@ UINT loop = NX_TRUE;
sample_telemetry_action(context);
}
- if (app_events & SAMPLE_DEVICE_TWIN_REPORTED_PROPERTY_EVENT)
+ if (app_events & SAMPLE_DEVICE_REPORTED_PROPERTIES_EVENT)
{
- sample_device_twin_reported_property_action(context);
+ sample_device_reported_property_action(context);
}
if (app_events & SAMPLE_DISCONNECT_EVENT)
diff --git a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.c b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.c
index 79ce96d6..004ffa70 100644
--- a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.c
+++ b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.c
@@ -11,8 +11,6 @@
#include "sample_pnp_thermostat_component.h"
-#include "nx_azure_iot_pnp_helpers.h"
-
#define SAMPLE_DEAFULT_START_TEMP_CELSIUS (22)
#define DOUBLE_DECIMAL_PLACE_DIGITS (2)
#define SAMPLE_COMMAND_SUCCESS_STATUS (200)
@@ -44,17 +42,17 @@ static UCHAR scratch_buffer[256];
/* sample direct method implementation */
static UINT sample_get_maxmin_report(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
NX_AZURE_IOT_JSON_READER *json_reader_ptr,
- NX_AZURE_IOT_JSON_WRITER *out_json_builder_ptr)
+ NX_AZURE_IOT_JSON_WRITER *out_json_writer_ptr)
{
UINT status;
UCHAR *start_time = (UCHAR *)fake_start_report_time;
UINT start_time_len = sizeof(fake_start_report_time) - 1;
UCHAR time_buf[32];
- if (json_reader_ptr != NX_NULL)
+ /* Check for start time if present */
+ if ((status = nx_azure_iot_json_reader_next_token(json_reader_ptr)) == NX_AZURE_IOT_SUCCESS)
{
- if (nx_azure_iot_json_reader_next_token(json_reader_ptr) ||
- nx_azure_iot_json_reader_token_string_get(json_reader_ptr, time_buf,
+ if (nx_azure_iot_json_reader_token_string_get(json_reader_ptr, time_buf,
sizeof(time_buf), &start_time_len))
{
return(NX_NOT_SUCCESSFUL);
@@ -62,34 +60,41 @@ UCHAR time_buf[32];
start_time = time_buf;
}
+ else
+ {
+ if (status != NX_AZURE_IOT_EMPTY_JSON)
+ {
+ return(NX_NOT_SUCCESSFUL);
+ }
+ }
/* Build the method response payload */
- if (nx_azure_iot_json_writer_append_begin_object(out_json_builder_ptr) ||
- nx_azure_iot_json_writer_append_property_with_double_value(out_json_builder_ptr,
+ if (nx_azure_iot_json_writer_append_begin_object(out_json_writer_ptr) ||
+ nx_azure_iot_json_writer_append_property_with_double_value(out_json_writer_ptr,
(UCHAR *)report_max_temp_name,
sizeof(report_max_temp_name) - 1,
handle -> maxTemperature,
DOUBLE_DECIMAL_PLACE_DIGITS) ||
- nx_azure_iot_json_writer_append_property_with_double_value(out_json_builder_ptr,
+ nx_azure_iot_json_writer_append_property_with_double_value(out_json_writer_ptr,
(UCHAR *)report_min_temp_name,
sizeof(report_min_temp_name) - 1,
handle -> minTemperature,
DOUBLE_DECIMAL_PLACE_DIGITS) ||
- nx_azure_iot_json_writer_append_property_with_double_value(out_json_builder_ptr,
+ nx_azure_iot_json_writer_append_property_with_double_value(out_json_writer_ptr,
(UCHAR *)report_avg_temp_name,
sizeof(report_avg_temp_name) - 1,
handle -> avgTemperature,
DOUBLE_DECIMAL_PLACE_DIGITS) ||
- nx_azure_iot_json_writer_append_property_with_string_value(out_json_builder_ptr,
+ nx_azure_iot_json_writer_append_property_with_string_value(out_json_writer_ptr,
(UCHAR *)report_start_time_name,
sizeof(report_start_time_name) - 1,
(UCHAR *)start_time, start_time_len) ||
- nx_azure_iot_json_writer_append_property_with_string_value(out_json_builder_ptr,
+ nx_azure_iot_json_writer_append_property_with_string_value(out_json_writer_ptr,
(UCHAR *)report_end_time_name,
sizeof(report_end_time_name) - 1,
(UCHAR *)fake_end_report_time,
sizeof(fake_end_report_time) - 1) ||
- nx_azure_iot_json_writer_append_end_object(out_json_builder_ptr))
+ nx_azure_iot_json_writer_append_end_object(out_json_writer_ptr))
{
status = NX_NOT_SUCCESSFUL;
}
@@ -101,64 +106,48 @@ UCHAR time_buf[32];
return(status);
}
-static UINT append_temp(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, VOID *context)
-{
- return(nx_azure_iot_json_writer_append_double(json_writer_ptr,
- *(double *)context,
- DOUBLE_DECIMAL_PLACE_DIGITS));
-}
-
-static UINT append_max_temp(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, VOID *context)
-{
-SAMPLE_PNP_THERMOSTAT_COMPONENT *handle = (SAMPLE_PNP_THERMOSTAT_COMPONENT *)context;
-
- return(nx_azure_iot_json_writer_append_property_with_double_value(json_writer_ptr,
- (UCHAR *)reported_max_temp_since_last_reboot,
- sizeof(reported_max_temp_since_last_reboot) - 1,
- handle -> maxTemperature,
- DOUBLE_DECIMAL_PLACE_DIGITS));
-}
-
static VOID sample_send_target_temperature_report(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, double temp,
- INT status_code, UINT version, const CHAR *description)
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr, double temp,
+ UINT status_code, ULONG version, const CHAR *description)
{
-UINT bytes_copied;
UINT response_status;
-UINT request_id;
NX_AZURE_IOT_JSON_WRITER json_writer;
-ULONG reported_property_version;
- /* Build telemetry JSON payload */
- if (nx_azure_iot_json_writer_with_buffer_init(&json_writer, scratch_buffer, sizeof(scratch_buffer)))
+ if (nx_azure_iot_pnp_client_reported_properties_create(iotpnp_client_ptr,
+ &json_writer, NX_WAIT_FOREVER))
{
- printf("Failed to create json writer\r\n");
+ printf("Failed to build reported response\r\n");
return;
}
- if (nx_azure_iot_pnp_helper_build_reported_property_with_status(handle -> component_name_ptr, handle -> component_name_length,
- (UCHAR *)target_temp_property_name,
- sizeof(target_temp_property_name) - 1,
- append_temp, (VOID *)&temp, status_code,
- (UCHAR *)description,
- strlen(description), version, &json_writer))
+ if (nx_azure_iot_pnp_client_reported_property_component_begin(iotpnp_client_ptr, &json_writer,
+ handle ->component_name_ptr,
+ handle -> component_name_length) ||
+ nx_azure_iot_pnp_client_reported_property_status_begin(iotpnp_client_ptr,
+ &json_writer, (UCHAR *)target_temp_property_name,
+ sizeof(target_temp_property_name) - 1,
+ status_code, version,
+ (const UCHAR *)description, strlen(description)) ||
+ nx_azure_iot_json_writer_append_double(&json_writer,
+ temp, DOUBLE_DECIMAL_PLACE_DIGITS) ||
+ nx_azure_iot_pnp_client_reported_property_status_end(iotpnp_client_ptr, &json_writer) ||
+ nx_azure_iot_pnp_client_reported_property_component_end(iotpnp_client_ptr, &json_writer))
{
- printf("Failed to create reported response\r\n");
+ nx_azure_iot_json_writer_deinit(&json_writer);
+ printf("Failed to build reported response\r\n");
}
else
{
- bytes_copied = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
- if (nx_azure_iot_hub_client_device_twin_reported_properties_send(iothub_client_ptr,
- scratch_buffer, bytes_copied,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE)))
+ if (nx_azure_iot_pnp_client_reported_properties_send(iotpnp_client_ptr,
+ &json_writer, NX_NULL,
+ &response_status, NX_NULL,
+ (5 * NX_IP_PERIODIC_RATE)))
{
printf("Failed to send reported response\r\n");
}
- }
- nx_azure_iot_json_writer_deinit(&json_writer);
+ nx_azure_iot_json_writer_deinit(&json_writer);
+ }
}
UINT sample_pnp_thermostat_init(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
@@ -224,7 +213,8 @@ UINT dm_status;
return(NX_AZURE_IOT_SUCCESS);
}
-UINT sample_pnp_thermostat_telemetry_send(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle, NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
+UINT sample_pnp_thermostat_telemetry_send(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr)
{
UINT status;
NX_PACKET *packet_ptr;
@@ -237,7 +227,7 @@ UINT buffer_length;
}
/* Create a telemetry message packet. */
- if ((status = nx_azure_iot_pnp_helper_telemetry_message_create(iothub_client_ptr, handle -> component_name_ptr,
+ if ((status = nx_azure_iot_pnp_client_telemetry_message_create(iotpnp_client_ptr, handle -> component_name_ptr,
handle -> component_name_length,
&packet_ptr, NX_WAIT_FOREVER)))
{
@@ -249,7 +239,7 @@ UINT buffer_length;
if (nx_azure_iot_json_writer_with_buffer_init(&json_writer, scratch_buffer, sizeof(scratch_buffer)))
{
printf("Telemetry message failed to build message\r\n");
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(NX_NOT_SUCCESSFUL);
}
@@ -263,17 +253,17 @@ UINT buffer_length;
{
printf("Telemetry message failed to build message\r\n");
nx_azure_iot_json_writer_deinit(&json_writer);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(NX_NOT_SUCCESSFUL);
}
buffer_length = nx_azure_iot_json_writer_get_bytes_used(&json_writer);
- if ((status = nx_azure_iot_hub_client_telemetry_send(iothub_client_ptr, packet_ptr,
+ if ((status = nx_azure_iot_pnp_client_telemetry_send(iotpnp_client_ptr, packet_ptr,
(UCHAR *)scratch_buffer, buffer_length, NX_WAIT_FOREVER)))
{
printf("Telemetry message send failed!: error code = 0x%08x\r\n", status);
nx_azure_iot_json_writer_deinit(&json_writer);
- nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
+ nx_azure_iot_pnp_client_telemetry_message_delete(packet_ptr);
return(status);
}
@@ -285,47 +275,48 @@ UINT buffer_length;
}
UINT sample_pnp_thermostat_report_max_temp_since_last_reboot_property(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr)
{
-UINT reported_properties_length;
UINT status;
-UINT response_status;
-UINT request_id;
-NX_AZURE_IOT_JSON_WRITER json_builder;
-ULONG reported_property_version;
+UINT response_status = 0;
+NX_AZURE_IOT_JSON_WRITER json_writer;
- if ((status = nx_azure_iot_json_writer_with_buffer_init(&json_builder,
- scratch_buffer,
- sizeof(scratch_buffer))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_create(iotpnp_client_ptr,
+ &json_writer, NX_WAIT_FOREVER)))
{
- printf("Failed to initialize json writer\r\n");
- return(NX_NOT_SUCCESSFUL);
+ printf("Failed create reported properties: error code = 0x%08x\r\n", status);
+ return(status);
}
- if ((status = nx_azure_iot_pnp_helper_build_reported_property(handle -> component_name_ptr,
- handle -> component_name_length,
- append_max_temp, (VOID *)handle,
- &json_builder)))
+ if ((status = nx_azure_iot_pnp_client_reported_property_component_begin(iotpnp_client_ptr,
+ &json_writer,
+ handle -> component_name_ptr,
+ handle -> component_name_length)) ||
+ (status = nx_azure_iot_json_writer_append_property_with_double_value(&json_writer,
+ (const UCHAR *)reported_max_temp_since_last_reboot,
+ sizeof(reported_max_temp_since_last_reboot) - 1,
+ handle -> maxTemperature,
+ DOUBLE_DECIMAL_PLACE_DIGITS)) ||
+ (status = nx_azure_iot_pnp_client_reported_property_component_end(iotpnp_client_ptr,
+ &json_writer)))
{
printf("Failed to build reported property!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- reported_properties_length = nx_azure_iot_json_writer_get_bytes_used(&json_builder);
- if ((status = nx_azure_iot_hub_client_device_twin_reported_properties_send(iothub_client_ptr,
- scratch_buffer,
- reported_properties_length,
- &request_id, &response_status,
- &reported_property_version,
- (5 * NX_IP_PERIODIC_RATE))))
+ if ((status = nx_azure_iot_pnp_client_reported_properties_send(iotpnp_client_ptr,
+ &json_writer,
+ NX_NULL, &response_status,
+ NX_NULL,
+ (5 * NX_IP_PERIODIC_RATE))))
{
printf("Device twin reported properties failed!: error code = 0x%08x\r\n", status);
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
return(status);
}
- nx_azure_iot_json_writer_deinit(&json_builder);
+ nx_azure_iot_json_writer_deinit(&json_writer);
if ((response_status < 200) || (response_status >= 300))
{
@@ -337,13 +328,12 @@ ULONG reported_property_version;
}
UINT sample_pnp_thermostat_process_property_update(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
- UCHAR *component_name_ptr, UINT component_name_length,
- UCHAR *property_name_ptr, UINT property_name_length,
- NX_AZURE_IOT_JSON_READER *property_value_reader_ptr, UINT version)
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr,
+ const UCHAR *component_name_ptr, UINT component_name_length,
+ NX_AZURE_IOT_JSON_READER *name_value_reader_ptr, UINT version)
{
double parsed_value = 0;
-INT status_code;
+UINT status_code;
const CHAR *description;
if (handle == NX_NULL)
@@ -357,15 +347,16 @@ const CHAR *description;
return(NX_NOT_SUCCESSFUL);
}
- if (property_name_length != (sizeof(target_temp_property_name) - 1) ||
- strncmp((CHAR *)property_name_ptr, (CHAR *)target_temp_property_name, property_name_length) != 0)
+ if (nx_azure_iot_json_reader_token_is_text_equal(name_value_reader_ptr,
+ (UCHAR *)target_temp_property_name,
+ sizeof(target_temp_property_name) - 1) == NX_FALSE)
{
- printf("PnP property=%.*s is not supported on thermostat component\r\n",
- property_name_length, property_name_ptr);
+ printf("Unknown property for component %.*s received\r\n", component_name_length, component_name_ptr);
status_code = 404;
description = temp_response_description_failed;
}
- else if (nx_azure_iot_json_reader_token_double_get(property_value_reader_ptr, &parsed_value))
+ else if (nx_azure_iot_json_reader_next_token(name_value_reader_ptr) ||
+ nx_azure_iot_json_reader_token_double_get(name_value_reader_ptr, &parsed_value))
{
status_code = 401;
description = temp_response_description_failed;
@@ -392,7 +383,7 @@ const CHAR *description;
handle -> avgTemperature = handle -> allTemperatures / handle -> numTemperatureUpdates;
}
- sample_send_target_temperature_report(handle, iothub_client_ptr, parsed_value,
+ sample_send_target_temperature_report(handle, iotpnp_client_ptr, parsed_value,
status_code, version, description);
return(NX_AZURE_IOT_SUCCESS);
diff --git a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.h b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.h
index ffa2906f..37f73e2d 100644
--- a/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.h
+++ b/addons/azure_iot/samples/sample_pnp_temperature_controller/sample_pnp_thermostat_component.h
@@ -16,7 +16,7 @@
extern "C" {
#endif
-#include "nx_azure_iot_hub_client.h"
+#include "nx_azure_iot_pnp_client.h"
#include "nx_azure_iot_json_reader.h"
#include "nx_azure_iot_json_writer.h"
#include "nx_api.h"
@@ -56,17 +56,17 @@ UINT sample_pnp_thermostat_process_command(SAMPLE_PNP_THERMOSTAT_COMPONENT *hand
NX_AZURE_IOT_JSON_READER *json_reader_ptr,
NX_AZURE_IOT_JSON_WRITER *json_response_ptr, UINT *status_code);
-UINT sample_pnp_thermostat_telemetry_send(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle, NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr);
+UINT sample_pnp_thermostat_telemetry_send(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr);
UINT sample_pnp_thermostat_report_max_temp_since_last_reboot_property(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr);
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr);
UINT sample_pnp_thermostat_process_property_update(SAMPLE_PNP_THERMOSTAT_COMPONENT *handle,
- NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr,
- UCHAR *component_name_ptr, UINT component_name_length,
- UCHAR *property_name_ptr, UINT property_name_length,
- NX_AZURE_IOT_JSON_READER *property_value_reader_ptr, UINT version);
+ NX_AZURE_IOT_PNP_CLIENT *iotpnp_client_ptr,
+ const UCHAR *component_name_ptr, UINT component_name_length,
+ NX_AZURE_IOT_JSON_READER *name_value_reader_ptr, UINT version);
#ifdef __cplusplus
}