1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 /** 12 * @file nx_azure_iot_hub_client.h 13 * 14 * @brief Definition for the Azure IoT Hub client. 15 * @remark The IoT Hub MQTT protocol is described at 16 * https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support. 17 * 18 */ 19 20 #ifndef NX_AZURE_IOT_HUB_CLIENT_PROPERTIES_H 21 #define NX_AZURE_IOT_HUB_CLIENT_PROPERTIES_H 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 #include "azure/iot/az_iot_hub_client_properties.h" 28 #include "nx_azure_iot_hub_client.h" 29 #include "nx_azure_iot_json_reader.h" 30 #include "nx_azure_iot_json_writer.h" 31 32 /* Property type. */ 33 #define NX_AZURE_IOT_HUB_CLIENT_PROPERTY_REPORTED_FROM_DEVICE 0 34 #define NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE 1 35 36 /** 37 * @brief Append the necessary characters to a reported property JSON payload belonging to a 38 * subcomponent. 39 * 40 * The payload will be of the form: 41 * 42 * @code 43 * "reported": { 44 * "<component_name>": { 45 * "__t": "c", 46 * "temperature": 23 47 * } 48 * } 49 * @endcode 50 * 51 * @note This API should be used in conjunction with 52 * nx_azure_iot_hub_client_reported_properties_component_end(). 53 * 54 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 55 * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER 56 * @param[in] component_name_ptr A pointer to a component name 57 * @param[in] component_name_length Length of `component_name_ptr` 58 * @return A `UINT` with the result of the API. 59 * @retval #NX_AZURE_IOT_SUCCESS Successful if JSON payload was prefixed successfully. 60 */ 61 UINT nx_azure_iot_hub_client_reported_properties_component_begin(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 62 NX_AZURE_IOT_JSON_WRITER *writer_ptr, 63 const UCHAR *component_name_ptr, 64 USHORT component_name_length); 65 66 /** 67 * @brief Append the necessary characters to end a reported property JSON payload belonging to a 68 * subcomponent. 69 * 70 * @note This API should be used in conjunction with 71 * nx_azure_iot_hub_client_reported_properties_component_begin(). 72 * 73 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 74 * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER 75 * @return A `UINT` with the result of the API. 76 * @retval #NX_AZURE_IOT_SUCCESS The JSON payload was suffixed successfully. 77 */ 78 UINT nx_azure_iot_hub_client_reported_properties_component_end(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 79 NX_AZURE_IOT_JSON_WRITER *writer_ptr); 80 81 /** 82 * @brief Begin a property response payload with confirmation status. 83 * 84 * This API should be used in response to an incoming writable property. More details can be found 85 * here: 86 * 87 * https://docs.microsoft.com/en-us/azure/iot-pnp/concepts-convention#writable-properties 88 * 89 * The payload will be of the form: 90 * 91 * **Without component** 92 * @code 93 * //{ 94 * // "<property_name>":{ 95 * // "ac": <status_code>, 96 * // "av": <version>, 97 * // "ad": "<description>", 98 * // "value": <user_value> 99 * // } 100 * //} 101 * @endcode 102 * 103 * To send a status for a property belonging to a component, first call the 104 * nx_azure_iot_hub_client_reported_property_status_begin() API to prefix the payload with the 105 * necessary identification. The API call flow would look like the following with the listed JSON 106 * payload being generated. 107 * 108 * **With component** 109 * @code 110 * 111 * nx_azure_iot_hub_client_reported_properties_component_begin() 112 * nx_azure_iot_hub_client_reported_properties_status_begin() 113 * // Append user value here (<user_value>) 114 * nx_azure_iot_hub_client_reported_properties_status_end() 115 * nx_azure_iot_hub_client_reported_properties_component_end() 116 * 117 * //{ 118 * // "<component_name>": { 119 * // "__t": "c", 120 * // "<property_name>": { 121 * // "ac": <status_code>, 122 * // "av": <version>, 123 * // "ad": "<description>", 124 * // "value": <user_value> 125 * // } 126 * // } 127 * //} 128 * @endcode 129 * 130 * @note This API should be used in conjunction with 131 * nx_azure_iot_hub_client_reported_properties_status_end(). 132 * 133 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 134 * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER 135 * @param[in] property_name_ptr A pointer to property name. 136 * @param[in] property_name_length Length of `property_name_ptr`. 137 * @param[in] status_code The HTTP-like status code to respond with. 138 * @param[in] version The version of the property the application is acknowledging. 139 * This can be retrieved from the service request by calling nx_azure_iot_hub_client_properties_version_get. 140 * @param[in] description_ptr An optional pointer to description detailing the context or any details about 141 * the acknowledgement. This can be empty string. 142 * @param[in] description_length Length of description_ptr 143 * 144 * @return A `UINT` with the result of the API. 145 * @retval #NX_AZURE_IOT_SUCCESS Successful appended JSON prefix. 146 */ 147 UINT nx_azure_iot_hub_client_reported_properties_status_begin(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 148 NX_AZURE_IOT_JSON_WRITER *writer_ptr, 149 const UCHAR *property_name_ptr, UINT property_name_length, 150 UINT status_code, ULONG version, 151 const UCHAR *description_ptr, UINT description_length); 152 153 /** 154 * @brief End a property response payload with confirmation status. 155 * 156 * @note This API should be used in conjunction with 157 * nx_azure_iot_hub_client_reported_properties_status_begin(). 158 * 159 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 160 * @param[in] writer_ptr A pointer to a #NX_AZURE_IOT_JSON_WRITER 161 * 162 * @return A `UINT` with the result of the API. 163 * @retval #NX_AZURE_IOT_SUCCESS Successful appended JSON suffix. 164 */ 165 UINT nx_azure_iot_hub_client_reported_properties_status_end(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 166 NX_AZURE_IOT_JSON_WRITER *writer_ptr); 167 168 169 /** 170 * @brief Get the property version. the next writable property in the property document passed. 171 * 172 * @warning This modifies the state of the json reader. To then use the same json reader 173 * with nx_azure_iot_hub_client_properties_component_property_next_get(), you must call 174 * nx_azure_iot_json_reader_init() again after this call and before the call to 175 * nx_azure_iot_hub_client_properties_component_property_next_get() or make an additional copy before 176 * calling this API. 177 * 178 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 179 * @param[in] reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing properties document 180 * @param[in] message_type Type of message repsonse, only valid value are NX_AZURE_IOT_HUB_PROPERTIES or NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES 181 * @param[out] version_ptr The numeric version of the properties in JSON payload 182 * @return A `UINT` with the result of the API. 183 * @retval #NX_AZURE_IOT_SUCCESS Successful if next writable property is found. 184 */ 185 UINT nx_azure_iot_hub_client_properties_version_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 186 NX_AZURE_IOT_JSON_READER *reader_ptr, 187 UINT message_type, ULONG *version_ptr); 188 189 /** 190 * @brief Iteratively read the Azure IoT Plug and Play component properties. 191 * 192 * Note that between calls, the UCHAR* pointed to by \p component_name_pptr shall not be modified, 193 * only checked and compared. Internally, the pointer is only changed if the component name changes 194 * in the JSON document and is not necessarily set every invocation of the function. 195 * 196 * On success, the `reader_ptr` will be set on a valid property name. After checking the 197 * property name, the reader can be advanced to the property value by calling 198 * nx_azure_iot_json_reader_next_token(). Note that on the subsequent call to this API, it is expected that 199 * the json reader will be placed AFTER the read property name and value. That means that after 200 * reading the property value (including single values or complex objects), the user must call 201 * nx_azure_iot_json_reader_next_token(). 202 * 203 * Below is a code snippet which you can use as a starting point: 204 * 205 * @code 206 * 207 * while ((status = nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, 208 * &json_reader, 209 * message_type, 210 * NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, 211 * &component_name_ptr, &component_length)) == NX_AZURE_IOT_SUCCESS) 212 * { 213 * 214 * // Check if property is of interest (substitute user_property for your own property name) 215 * if (nx_azure_iot_json_reader_token_is_text_equal(&json_reader, user_property, user_property_length)) 216 * { 217 * nx_azure_iot_json_reader_next_token(&json_reader); 218 * 219 * // Get the property value here 220 * // Example: nx_azure_iot_json_reader_token_int32_get(&json_reader, &user_int); 221 * 222 * // Skip to next property value 223 * nx_azure_iot_json_reader_next_token(&json_reader); 224 * } 225 * else 226 * { 227 * // The JSON reader must be advanced regardless of whether the property 228 * // is of interest or not. 229 * nx_azure_iot_json_reader_next_token(&json_reader); 230 * 231 * // Skip children in case the property value is an object 232 * nx_azure_iot_json_reader_skip_children(&json_reader); 233 * nx_azure_iot_json_reader_next_token(&json_reader); 234 * } 235 * } 236 * 237 * @endcode 238 * 239 * @warning If you need to retrieve more than one \p property_type, you should first complete the 240 * scan of all components for the first property type (until the API returns 241 * NX_AZURE_IOT_NOT_FOUND). Then you must call nx_azure_iot_json_reader_init() again after this call 242 * and before the next call to `nx_azure_iot_hub_client_properties_component_property_next_get` with the 243 * different \p property_type. 244 * 245 * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT. 246 * @param[in] reader_ptr A pointer to a #NX_AZURE_IOT_JSON_READER containing properties document 247 * @param[in] message_type Type of message repsonse, only valid value are NX_AZURE_IOT_HUB_PROPERTIES or NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES 248 * @param[in] property_type Type of property, only valid value are NX_AZURE_IOT_HUB_CLIENT_PROPERTY_REPORTED_FROM_DEVICE or NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE 249 * @param[out] component_name_pptr A pointer to component name for the property returned using reader_ptr 250 * @param[out] component_name_length_ptr Length of the component name 251 * @return A `UINT` with the result of the API. 252 * @retval #NX_AZURE_IOT_SUCCESS Successful if next writable property is found. 253 */ 254 UINT nx_azure_iot_hub_client_properties_component_property_next_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, 255 NX_AZURE_IOT_JSON_READER *reader_ptr, 256 UINT message_type, UINT property_type, 257 const UCHAR **component_name_pptr, 258 USHORT *component_name_length_ptr); 259 260 #ifdef __cplusplus 261 } 262 #endif 263 #endif /* NX_AZURE_IOT_HUB_CLIENT_PROPERTIES_H */ 264