Microsoft Azure IoTHub client AMQP transport

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp iothub_client_sample_amqp ... more

This library implements the AMQP transport for Microsoft Azure IoTHub client. The code is replicated from https://github.com/Azure/azure-iot-sdks

Committer:
AzureIoTClient
Date:
Thu Oct 04 09:14:47 2018 -0700
Revision:
57:56ac1346c70d
Parent:
56:8704100b3b54
1.2.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AzureIoTClient 42:c2eaa912a28c 1 // Copyright (c) Microsoft. All rights reserved.
AzureIoTClient 42:c2eaa912a28c 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
AzureIoTClient 42:c2eaa912a28c 3
AzureIoTClient 42:c2eaa912a28c 4 #include <stdlib.h>
AzureIoTClient 42:c2eaa912a28c 5 #include <stddef.h>
AzureIoTClient 42:c2eaa912a28c 6 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 42:c2eaa912a28c 7 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 42:c2eaa912a28c 8 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 42:c2eaa912a28c 9 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 42:c2eaa912a28c 10 #include "azure_c_shared_utility/strings.h"
AzureIoTClient 42:c2eaa912a28c 11 #include "azure_uamqp_c/link.h"
AzureIoTClient 42:c2eaa912a28c 12 #include "azure_uamqp_c/messaging.h"
AzureIoTClient 42:c2eaa912a28c 13 #include "azure_uamqp_c/message_receiver.h"
AzureIoTClient 42:c2eaa912a28c 14 #include "azure_uamqp_c/message_sender.h"
AzureIoTClient 50:f3a92c6c6534 15 #include "azure_uamqp_c/amqp_definitions_application_properties.h"
AzureIoTClient 50:f3a92c6c6534 16
AzureIoTClient 53:e21e1e88460f 17 #include "internal/iothubtransportamqp_methods.h"
AzureIoTClient 42:c2eaa912a28c 18
AzureIoTClient 42:c2eaa912a28c 19 typedef enum SUBSCRIBE_STATE_TAG
AzureIoTClient 42:c2eaa912a28c 20 {
AzureIoTClient 42:c2eaa912a28c 21 SUBSCRIBE_STATE_NOT_SUBSCRIBED,
AzureIoTClient 42:c2eaa912a28c 22 SUBSCRIBE_STATE_SUBSCRIBED
AzureIoTClient 42:c2eaa912a28c 23 } SUBSCRIBE_STATE;
AzureIoTClient 42:c2eaa912a28c 24
AzureIoTClient 42:c2eaa912a28c 25 typedef struct IOTHUBTRANSPORT_AMQP_METHODS_TAG
AzureIoTClient 42:c2eaa912a28c 26 {
AzureIoTClient 42:c2eaa912a28c 27 char* device_id;
AzureIoTClient 54:830550fef7ea 28 char* module_id;
AzureIoTClient 42:c2eaa912a28c 29 char* hostname;
AzureIoTClient 42:c2eaa912a28c 30 LINK_HANDLE receiver_link;
AzureIoTClient 42:c2eaa912a28c 31 LINK_HANDLE sender_link;
AzureIoTClient 42:c2eaa912a28c 32 MESSAGE_RECEIVER_HANDLE message_receiver;
AzureIoTClient 42:c2eaa912a28c 33 MESSAGE_SENDER_HANDLE message_sender;
AzureIoTClient 42:c2eaa912a28c 34 ON_METHOD_REQUEST_RECEIVED on_method_request_received;
AzureIoTClient 42:c2eaa912a28c 35 void* on_method_request_received_context;
AzureIoTClient 42:c2eaa912a28c 36 ON_METHODS_ERROR on_methods_error;
AzureIoTClient 42:c2eaa912a28c 37 void* on_methods_error_context;
AzureIoTClient 42:c2eaa912a28c 38 ON_METHODS_UNSUBSCRIBED on_methods_unsubscribed;
AzureIoTClient 42:c2eaa912a28c 39 void* on_methods_unsubscribed_context;
AzureIoTClient 42:c2eaa912a28c 40 SUBSCRIBE_STATE subscribe_state;
AzureIoTClient 42:c2eaa912a28c 41 IOTHUBTRANSPORT_AMQP_METHOD_HANDLE* method_request_handles;
AzureIoTClient 42:c2eaa912a28c 42 size_t method_request_handle_count;
AzureIoTClient 42:c2eaa912a28c 43 bool receiver_link_disconnected;
AzureIoTClient 42:c2eaa912a28c 44 bool sender_link_disconnected;
AzureIoTClient 42:c2eaa912a28c 45 } IOTHUBTRANSPORT_AMQP_METHODS;
AzureIoTClient 42:c2eaa912a28c 46
AzureIoTClient 42:c2eaa912a28c 47 typedef enum MESSAGE_OUTCOME_TAG
AzureIoTClient 42:c2eaa912a28c 48 {
AzureIoTClient 42:c2eaa912a28c 49 MESSAGE_OUTCOME_ACCEPTED,
AzureIoTClient 42:c2eaa912a28c 50 MESSAGE_OUTCOME_REJECTED,
AzureIoTClient 42:c2eaa912a28c 51 MESSAGE_OUTCOME_RELEASED
AzureIoTClient 42:c2eaa912a28c 52 } MESSAGE_OUTCOME;
AzureIoTClient 42:c2eaa912a28c 53
AzureIoTClient 42:c2eaa912a28c 54 typedef struct IOTHUBTRANSPORT_AMQP_METHOD_TAG
AzureIoTClient 42:c2eaa912a28c 55 {
AzureIoTClient 42:c2eaa912a28c 56 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle;
AzureIoTClient 42:c2eaa912a28c 57 uuid correlation_id;
AzureIoTClient 42:c2eaa912a28c 58 } IOTHUBTRANSPORT_AMQP_METHOD;
AzureIoTClient 42:c2eaa912a28c 59
AzureIoTClient 42:c2eaa912a28c 60 static void remove_tracked_handle(IOTHUBTRANSPORT_AMQP_METHODS* amqp_methods_handle, IOTHUBTRANSPORT_AMQP_METHOD_HANDLE method_request_handle)
AzureIoTClient 42:c2eaa912a28c 61 {
AzureIoTClient 42:c2eaa912a28c 62 size_t i;
AzureIoTClient 42:c2eaa912a28c 63
AzureIoTClient 42:c2eaa912a28c 64 for (i = 0; i < amqp_methods_handle->method_request_handle_count; i++)
AzureIoTClient 42:c2eaa912a28c 65 {
AzureIoTClient 42:c2eaa912a28c 66 if (amqp_methods_handle->method_request_handles[i] == method_request_handle)
AzureIoTClient 42:c2eaa912a28c 67 {
AzureIoTClient 42:c2eaa912a28c 68 if (amqp_methods_handle->method_request_handle_count - i > 1)
AzureIoTClient 42:c2eaa912a28c 69 {
AzureIoTClient 42:c2eaa912a28c 70 (void)memmove(&amqp_methods_handle->method_request_handles[i], &amqp_methods_handle->method_request_handles[i + 1],
AzureIoTClient 42:c2eaa912a28c 71 (amqp_methods_handle->method_request_handle_count - i - 1) * sizeof(IOTHUBTRANSPORT_AMQP_METHOD_HANDLE));
AzureIoTClient 42:c2eaa912a28c 72 }
AzureIoTClient 42:c2eaa912a28c 73
AzureIoTClient 42:c2eaa912a28c 74 amqp_methods_handle->method_request_handle_count--;
AzureIoTClient 42:c2eaa912a28c 75 i--;
AzureIoTClient 42:c2eaa912a28c 76 }
AzureIoTClient 42:c2eaa912a28c 77 }
AzureIoTClient 42:c2eaa912a28c 78
AzureIoTClient 42:c2eaa912a28c 79 if (amqp_methods_handle->method_request_handle_count == 0)
AzureIoTClient 42:c2eaa912a28c 80 {
AzureIoTClient 42:c2eaa912a28c 81 free(amqp_methods_handle->method_request_handles);
AzureIoTClient 42:c2eaa912a28c 82 amqp_methods_handle->method_request_handles = NULL;
AzureIoTClient 42:c2eaa912a28c 83 }
AzureIoTClient 42:c2eaa912a28c 84 else
AzureIoTClient 42:c2eaa912a28c 85 {
AzureIoTClient 42:c2eaa912a28c 86 IOTHUBTRANSPORT_AMQP_METHOD_HANDLE* new_handles = (IOTHUBTRANSPORT_AMQP_METHOD_HANDLE*)realloc(amqp_methods_handle->method_request_handles, amqp_methods_handle->method_request_handle_count * sizeof(IOTHUBTRANSPORT_AMQP_METHOD_HANDLE));
AzureIoTClient 42:c2eaa912a28c 87 if (new_handles != NULL)
AzureIoTClient 42:c2eaa912a28c 88 {
AzureIoTClient 42:c2eaa912a28c 89 amqp_methods_handle->method_request_handles = new_handles;
AzureIoTClient 42:c2eaa912a28c 90 }
AzureIoTClient 42:c2eaa912a28c 91 }
AzureIoTClient 42:c2eaa912a28c 92 }
AzureIoTClient 42:c2eaa912a28c 93
AzureIoTClient 54:830550fef7ea 94 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransportamqp_methods_create(const char* hostname, const char* device_id, const char* module_id)
AzureIoTClient 42:c2eaa912a28c 95 {
AzureIoTClient 42:c2eaa912a28c 96 IOTHUBTRANSPORT_AMQP_METHODS* result;
AzureIoTClient 42:c2eaa912a28c 97
AzureIoTClient 42:c2eaa912a28c 98 if ((hostname == NULL) ||
AzureIoTClient 42:c2eaa912a28c 99 (device_id == NULL))
AzureIoTClient 42:c2eaa912a28c 100 {
AzureIoTClient 42:c2eaa912a28c 101 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_002: [ If any argument is NULL, `iothubtransportamqp_methods_create` shall return NULL. ]*/
AzureIoTClient 42:c2eaa912a28c 102 result = NULL;
AzureIoTClient 42:c2eaa912a28c 103 LogError("Bad arguments: hostname=%p, device_id=%p", hostname, device_id);
AzureIoTClient 42:c2eaa912a28c 104 }
AzureIoTClient 42:c2eaa912a28c 105 else
AzureIoTClient 42:c2eaa912a28c 106 {
AzureIoTClient 42:c2eaa912a28c 107 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_001: [ `iothubtransportamqp_methods_create` shall instantiate a new handler for C2D methods over AMQP for device `device_id` and on success return a non-NULL handle to it. ]*/
AzureIoTClient 42:c2eaa912a28c 108 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_003: [ `iothubtransportamqp_methods_create` shall allocate memory for the new instance. ]*/
AzureIoTClient 42:c2eaa912a28c 109 result = malloc(sizeof(IOTHUBTRANSPORT_AMQP_METHODS));
AzureIoTClient 42:c2eaa912a28c 110 if (result == NULL)
AzureIoTClient 42:c2eaa912a28c 111 {
AzureIoTClient 42:c2eaa912a28c 112 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_004: [ If allocating memory fails, `iothubtransportamqp_methods_create` shall return NULL. ]*/
AzureIoTClient 42:c2eaa912a28c 113 LogError("Cannot allocate memory for AMQP C2D methods handle");
AzureIoTClient 42:c2eaa912a28c 114 }
AzureIoTClient 42:c2eaa912a28c 115 else
AzureIoTClient 42:c2eaa912a28c 116 {
AzureIoTClient 54:830550fef7ea 117 memset(result, 0, sizeof(IOTHUBTRANSPORT_AMQP_METHODS));
AzureIoTClient 56:8704100b3b54 118
AzureIoTClient 42:c2eaa912a28c 119 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_115: [ `iothubtransportamqp_methods_create` shall save the device id for later use by using `mallocAndStrcpy_s`. ]*/
AzureIoTClient 42:c2eaa912a28c 120 if (mallocAndStrcpy_s(&result->device_id, device_id) != 0)
AzureIoTClient 42:c2eaa912a28c 121 {
AzureIoTClient 42:c2eaa912a28c 122 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_116: [ If `mallocAndStrcpy_s` fails, `iothubtransportamqp_methods_create` shall return NULL. ]*/
AzureIoTClient 42:c2eaa912a28c 123 LogError("Cannot copy device_id");
AzureIoTClient 42:c2eaa912a28c 124 free(result);
AzureIoTClient 42:c2eaa912a28c 125 result = NULL;
AzureIoTClient 42:c2eaa912a28c 126 }
AzureIoTClient 54:830550fef7ea 127 else if ((module_id != NULL) && (mallocAndStrcpy_s(&result->module_id, module_id) != 0))
AzureIoTClient 54:830550fef7ea 128 {
AzureIoTClient 54:830550fef7ea 129 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_116: [ If `mallocAndStrcpy_s` fails, `iothubtransportamqp_methods_create` shall return NULL. ]*/
AzureIoTClient 54:830550fef7ea 130 LogError("Cannot copy device_id");
AzureIoTClient 54:830550fef7ea 131 free(result->device_id);
AzureIoTClient 54:830550fef7ea 132 free(result);
AzureIoTClient 54:830550fef7ea 133 result = NULL;
AzureIoTClient 54:830550fef7ea 134 }
AzureIoTClient 42:c2eaa912a28c 135 else
AzureIoTClient 42:c2eaa912a28c 136 {
AzureIoTClient 42:c2eaa912a28c 137 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_139: [ `iothubtransportamqp_methods_create` shall save the `hostname` for later use by using `mallocAndStrcpy_s`. ]*/
AzureIoTClient 42:c2eaa912a28c 138 if (mallocAndStrcpy_s(&result->hostname, hostname) != 0)
AzureIoTClient 42:c2eaa912a28c 139 {
AzureIoTClient 42:c2eaa912a28c 140 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_116: [ If `mallocAndStrcpy_s` fails, `iothubtransportamqp_methods_create` shall return NULL. ]*/
AzureIoTClient 42:c2eaa912a28c 141 LogError("Cannot copy hostname");
AzureIoTClient 42:c2eaa912a28c 142 free(result->device_id);
AzureIoTClient 54:830550fef7ea 143 free(result->module_id);
AzureIoTClient 42:c2eaa912a28c 144 free(result);
AzureIoTClient 42:c2eaa912a28c 145 result = NULL;
AzureIoTClient 42:c2eaa912a28c 146 }
AzureIoTClient 42:c2eaa912a28c 147 else
AzureIoTClient 42:c2eaa912a28c 148 {
AzureIoTClient 42:c2eaa912a28c 149 result->subscribe_state = SUBSCRIBE_STATE_NOT_SUBSCRIBED;
AzureIoTClient 42:c2eaa912a28c 150 result->method_request_handles = NULL;
AzureIoTClient 42:c2eaa912a28c 151 result->method_request_handle_count = 0;
AzureIoTClient 42:c2eaa912a28c 152 result->receiver_link_disconnected = false;
AzureIoTClient 42:c2eaa912a28c 153 result->sender_link_disconnected = false;
AzureIoTClient 42:c2eaa912a28c 154 }
AzureIoTClient 42:c2eaa912a28c 155 }
AzureIoTClient 42:c2eaa912a28c 156 }
AzureIoTClient 42:c2eaa912a28c 157 }
AzureIoTClient 42:c2eaa912a28c 158
AzureIoTClient 42:c2eaa912a28c 159 return result;
AzureIoTClient 42:c2eaa912a28c 160 }
AzureIoTClient 42:c2eaa912a28c 161
AzureIoTClient 42:c2eaa912a28c 162 void iothubtransportamqp_methods_destroy(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 42:c2eaa912a28c 163 {
AzureIoTClient 42:c2eaa912a28c 164 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_006: [ If `iothubtransport_amqp_methods_handle` is NULL, `iothubtransportamqp_methods_destroy` shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 165 if (iothubtransport_amqp_methods_handle == NULL)
AzureIoTClient 42:c2eaa912a28c 166 {
AzureIoTClient 42:c2eaa912a28c 167 LogError("NULL handle");
AzureIoTClient 42:c2eaa912a28c 168 }
AzureIoTClient 42:c2eaa912a28c 169 else
AzureIoTClient 42:c2eaa912a28c 170 {
AzureIoTClient 42:c2eaa912a28c 171 size_t i;
AzureIoTClient 42:c2eaa912a28c 172
AzureIoTClient 42:c2eaa912a28c 173 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_007: [ If the instance pointed to by `iothubtransport_amqp_methods_handle` is subscribed to receive C2D methods, `iothubtransportamqp_methods_destroy` shall free all resources allocated by the subscribe. ]*/
AzureIoTClient 42:c2eaa912a28c 174 if (iothubtransport_amqp_methods_handle->subscribe_state == SUBSCRIBE_STATE_SUBSCRIBED)
AzureIoTClient 42:c2eaa912a28c 175 {
AzureIoTClient 42:c2eaa912a28c 176 iothubtransportamqp_methods_unsubscribe(iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 177 }
AzureIoTClient 42:c2eaa912a28c 178
AzureIoTClient 42:c2eaa912a28c 179 for (i = 0; i < iothubtransport_amqp_methods_handle->method_request_handle_count; i++)
AzureIoTClient 42:c2eaa912a28c 180 {
AzureIoTClient 42:c2eaa912a28c 181 free(iothubtransport_amqp_methods_handle->method_request_handles[i]);
AzureIoTClient 42:c2eaa912a28c 182 }
AzureIoTClient 42:c2eaa912a28c 183
AzureIoTClient 42:c2eaa912a28c 184 if (iothubtransport_amqp_methods_handle->method_request_handles != NULL)
AzureIoTClient 42:c2eaa912a28c 185 {
AzureIoTClient 42:c2eaa912a28c 186 free(iothubtransport_amqp_methods_handle->method_request_handles);
AzureIoTClient 42:c2eaa912a28c 187 }
AzureIoTClient 42:c2eaa912a28c 188
AzureIoTClient 42:c2eaa912a28c 189 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_005: [ `iothubtransportamqp_methods_destroy` shall free all resources allocated by `iothubtransportamqp_methods_create` for the handle `iothubtransport_amqp_methods_handle`. ]*/
AzureIoTClient 42:c2eaa912a28c 190 free(iothubtransport_amqp_methods_handle->hostname);
AzureIoTClient 42:c2eaa912a28c 191 free(iothubtransport_amqp_methods_handle->device_id);
AzureIoTClient 54:830550fef7ea 192 free(iothubtransport_amqp_methods_handle->module_id);
AzureIoTClient 42:c2eaa912a28c 193 free(iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 194 }
AzureIoTClient 42:c2eaa912a28c 195 }
AzureIoTClient 42:c2eaa912a28c 196
AzureIoTClient 42:c2eaa912a28c 197 static void call_methods_unsubscribed_if_needed(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE amqp_methods_handle)
AzureIoTClient 42:c2eaa912a28c 198 {
AzureIoTClient 42:c2eaa912a28c 199 if (amqp_methods_handle->receiver_link_disconnected && amqp_methods_handle->sender_link_disconnected)
AzureIoTClient 42:c2eaa912a28c 200 {
AzureIoTClient 42:c2eaa912a28c 201 amqp_methods_handle->receiver_link_disconnected = false;
AzureIoTClient 42:c2eaa912a28c 202 amqp_methods_handle->sender_link_disconnected = false;
AzureIoTClient 42:c2eaa912a28c 203 amqp_methods_handle->on_methods_unsubscribed(amqp_methods_handle->on_methods_unsubscribed_context);
AzureIoTClient 42:c2eaa912a28c 204 }
AzureIoTClient 42:c2eaa912a28c 205 }
AzureIoTClient 42:c2eaa912a28c 206
AzureIoTClient 42:c2eaa912a28c 207 static void on_message_receiver_state_changed(const void* context, MESSAGE_RECEIVER_STATE new_state, MESSAGE_RECEIVER_STATE previous_state)
AzureIoTClient 42:c2eaa912a28c 208 {
AzureIoTClient 42:c2eaa912a28c 209 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_119: [ When `on_message_receiver_state_changed` is called with the `new_state` being `MESSAGE_RECEIVER_STATE_ERROR`, an error shall be indicated by calling the `on_methods_error` callback passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 210 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_126: [ For the other state changes, on_message_receiver_state_changed shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 211 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE amqp_methods_handle = (IOTHUBTRANSPORT_AMQP_METHODS_HANDLE)context;
AzureIoTClient 42:c2eaa912a28c 212 if ((new_state != previous_state) &&
AzureIoTClient 42:c2eaa912a28c 213 (new_state == MESSAGE_RECEIVER_STATE_ERROR))
AzureIoTClient 42:c2eaa912a28c 214 {
AzureIoTClient 42:c2eaa912a28c 215 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_120: [ When an error is indicated by calling the `on_methods_error`, it shall be called with the context being the `on_methods_error_context` argument passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 216 amqp_methods_handle->on_methods_error(amqp_methods_handle->on_methods_error_context);
AzureIoTClient 42:c2eaa912a28c 217 }
AzureIoTClient 42:c2eaa912a28c 218 else
AzureIoTClient 42:c2eaa912a28c 219 {
AzureIoTClient 42:c2eaa912a28c 220 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_12_001: [ When `on_message_receiver_state_changed` is called with the `new_state` being `MESSAGE_RECEIVER_STATE_IDLE` and `previous_state` being `MESSAGE_RECEIVER_STATE_OPEN`and the sender link is already diconnected `on_message_receiver_state_changed` calls to `on_methods_unsubscribed`. ]*/
AzureIoTClient 42:c2eaa912a28c 221 if ((new_state == MESSAGE_RECEIVER_STATE_IDLE) && (previous_state == MESSAGE_RECEIVER_STATE_OPEN))
AzureIoTClient 42:c2eaa912a28c 222 {
AzureIoTClient 42:c2eaa912a28c 223 amqp_methods_handle->receiver_link_disconnected = true;
AzureIoTClient 42:c2eaa912a28c 224 }
AzureIoTClient 42:c2eaa912a28c 225 call_methods_unsubscribed_if_needed(amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 226 }
AzureIoTClient 42:c2eaa912a28c 227 }
AzureIoTClient 42:c2eaa912a28c 228
AzureIoTClient 42:c2eaa912a28c 229 static void on_message_sender_state_changed(void* context, MESSAGE_SENDER_STATE new_state, MESSAGE_SENDER_STATE previous_state)
AzureIoTClient 42:c2eaa912a28c 230 {
AzureIoTClient 42:c2eaa912a28c 231 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE amqp_methods_handle = (IOTHUBTRANSPORT_AMQP_METHODS_HANDLE)context;
AzureIoTClient 42:c2eaa912a28c 232 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_059: [ When `on_message_sender_state_changed` is called with the `new_state` being `MESSAGE_SENDER_STATE_ERROR`, an error shall be indicated by calling the `on_methods_error` callback passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 233 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_127: [ For the other state changes, on_message_sender_state_changed shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 234 if ((new_state != previous_state) &&
AzureIoTClient 42:c2eaa912a28c 235 (new_state == MESSAGE_SENDER_STATE_ERROR))
AzureIoTClient 42:c2eaa912a28c 236 {
AzureIoTClient 42:c2eaa912a28c 237 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_120: [ When an error is indicated by calling the `on_methods_error`, it shall be called with the context being the `on_methods_error_context` argument passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 238 amqp_methods_handle->on_methods_error(amqp_methods_handle->on_methods_error_context);
AzureIoTClient 42:c2eaa912a28c 239 }
AzureIoTClient 42:c2eaa912a28c 240 else
AzureIoTClient 42:c2eaa912a28c 241 {
AzureIoTClient 42:c2eaa912a28c 242 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_12_002: [ When `on_message_sender_state_changed` is called with the `new_state` being `MESSAGE_SENDER_STATE_IDLE` and `previous_state` being `MESSAGE_SENDER_STATE_OPEN`and the receiver link is already diconnected `on_message_sender_state_changed` calls to `on_methods_unsubscribed`. ]*/
AzureIoTClient 42:c2eaa912a28c 243 if ((new_state == MESSAGE_SENDER_STATE_IDLE) && (previous_state == MESSAGE_SENDER_STATE_OPEN))
AzureIoTClient 42:c2eaa912a28c 244 {
AzureIoTClient 42:c2eaa912a28c 245 amqp_methods_handle->sender_link_disconnected = true;
AzureIoTClient 42:c2eaa912a28c 246 }
AzureIoTClient 42:c2eaa912a28c 247 call_methods_unsubscribed_if_needed(amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 248 }
AzureIoTClient 42:c2eaa912a28c 249 }
AzureIoTClient 42:c2eaa912a28c 250
AzureIoTClient 56:8704100b3b54 251 static void on_message_send_complete(void* context, MESSAGE_SEND_RESULT send_result, AMQP_VALUE delivery_state)
AzureIoTClient 42:c2eaa912a28c 252 {
AzureIoTClient 56:8704100b3b54 253 (void)delivery_state;
AzureIoTClient 42:c2eaa912a28c 254 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_084: [ Otherwise no action shall be taken. ]*/
AzureIoTClient 42:c2eaa912a28c 255 if (send_result == MESSAGE_SEND_ERROR)
AzureIoTClient 42:c2eaa912a28c 256 {
AzureIoTClient 42:c2eaa912a28c 257 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE amqp_methods_handle = (IOTHUBTRANSPORT_AMQP_METHODS_HANDLE)context;
AzureIoTClient 42:c2eaa912a28c 258 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_083: [ If `send_result` is `MESSAGE_SEND_ERROR` then an error shall be indicated by calling the `on_methods_error` callback passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 259 amqp_methods_handle->on_methods_error(amqp_methods_handle->on_methods_error_context);
AzureIoTClient 42:c2eaa912a28c 260 }
AzureIoTClient 42:c2eaa912a28c 261 }
AzureIoTClient 42:c2eaa912a28c 262
AzureIoTClient 42:c2eaa912a28c 263 static AMQP_VALUE on_message_received(const void* context, MESSAGE_HANDLE message)
AzureIoTClient 42:c2eaa912a28c 264 {
AzureIoTClient 42:c2eaa912a28c 265 PROPERTIES_HANDLE properties;
AzureIoTClient 42:c2eaa912a28c 266 /* VS believes this is not initialized, so have to set it to the worse case here */
AzureIoTClient 42:c2eaa912a28c 267 AMQP_VALUE result = NULL;
AzureIoTClient 42:c2eaa912a28c 268 IOTHUBTRANSPORT_AMQP_METHODS_HANDLE amqp_methods_handle = (IOTHUBTRANSPORT_AMQP_METHODS_HANDLE)context;
AzureIoTClient 42:c2eaa912a28c 269 MESSAGE_OUTCOME message_outcome;
AzureIoTClient 42:c2eaa912a28c 270
AzureIoTClient 42:c2eaa912a28c 271 if (message == NULL)
AzureIoTClient 42:c2eaa912a28c 272 {
AzureIoTClient 42:c2eaa912a28c 273 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_041: [ If `message` is NULL, the RELEASED outcome shall be returned and an error shall be indicated. ]*/
AzureIoTClient 42:c2eaa912a28c 274 LogError("NULL message");
AzureIoTClient 42:c2eaa912a28c 275 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 276 }
AzureIoTClient 42:c2eaa912a28c 277 else
AzureIoTClient 42:c2eaa912a28c 278 {
AzureIoTClient 42:c2eaa912a28c 279 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_043: [ When `on_message_received` is called (to indicate a new message being received over the receiver link), the message shall be processed as below: ]*/
AzureIoTClient 42:c2eaa912a28c 280 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_044: [ - The message properties shall be obtained by calling `message_get_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 281 if (message_get_properties(message, &properties) != 0)
AzureIoTClient 42:c2eaa912a28c 282 {
AzureIoTClient 42:c2eaa912a28c 283 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_045: [ If `message_get_properties` fails, the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 284 LogError("Cannot retrieve message properties");
AzureIoTClient 42:c2eaa912a28c 285 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 286 result = messaging_delivery_rejected("amqp:decode-error", "Cannot retrieve message properties");
AzureIoTClient 42:c2eaa912a28c 287 }
AzureIoTClient 42:c2eaa912a28c 288 else
AzureIoTClient 42:c2eaa912a28c 289 {
AzureIoTClient 42:c2eaa912a28c 290 AMQP_VALUE correlation_id;
AzureIoTClient 42:c2eaa912a28c 291
AzureIoTClient 42:c2eaa912a28c 292 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_046: [ - The correlation id shall be obtained by calling `properties_get_correlation_id` on the message properties. ]*/
AzureIoTClient 42:c2eaa912a28c 293 if (properties_get_correlation_id(properties, &correlation_id) != 0)
AzureIoTClient 42:c2eaa912a28c 294 {
AzureIoTClient 42:c2eaa912a28c 295 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_047: [ If `properties_get_correlation_id` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 296 LogError("Cannot retrieve correlation id");
AzureIoTClient 42:c2eaa912a28c 297 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 298 result = messaging_delivery_rejected("amqp:decode-error", "Cannot retrieve correlation id");
AzureIoTClient 42:c2eaa912a28c 299 }
AzureIoTClient 42:c2eaa912a28c 300 else
AzureIoTClient 42:c2eaa912a28c 301 {
AzureIoTClient 42:c2eaa912a28c 302 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_112: [ Memory shall be allocated for the `IOTHUBTRANSPORT_AMQP_METHOD_HANDLE` to hold the correlation-id, so that it can be used in the `iothubtransportamqp_methods_respond` function. ]*/
AzureIoTClient 42:c2eaa912a28c 303 IOTHUBTRANSPORT_AMQP_METHOD* method_handle = (IOTHUBTRANSPORT_AMQP_METHOD*)malloc(sizeof(IOTHUBTRANSPORT_AMQP_METHOD));
AzureIoTClient 42:c2eaa912a28c 304 if (method_handle == NULL)
AzureIoTClient 42:c2eaa912a28c 305 {
AzureIoTClient 42:c2eaa912a28c 306 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_130: [ If allocating memory for the `IOTHUBTRANSPORT_AMQP_METHOD_HANDLE` handle fails, the RELEASED outcome shall be returned and an error shall be indicated. ]*/
AzureIoTClient 42:c2eaa912a28c 307 LogError("Cannot allocate method handle");
AzureIoTClient 42:c2eaa912a28c 308 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 309 }
AzureIoTClient 42:c2eaa912a28c 310 else
AzureIoTClient 42:c2eaa912a28c 311 {
AzureIoTClient 42:c2eaa912a28c 312 IOTHUBTRANSPORT_AMQP_METHOD_HANDLE* new_handles;
AzureIoTClient 42:c2eaa912a28c 313 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_113: [ All `IOTHUBTRANSPORT_AMQP_METHOD_HANDLE` handles shall be tracked in an array of handles that shall be resized accordingly when a methopd handle is added to it. ]*/
AzureIoTClient 42:c2eaa912a28c 314 new_handles = (IOTHUBTRANSPORT_AMQP_METHOD_HANDLE*)realloc(amqp_methods_handle->method_request_handles, (amqp_methods_handle->method_request_handle_count + 1) * sizeof(IOTHUBTRANSPORT_AMQP_METHOD_HANDLE));
AzureIoTClient 42:c2eaa912a28c 315 if (new_handles == NULL)
AzureIoTClient 42:c2eaa912a28c 316 {
AzureIoTClient 42:c2eaa912a28c 317 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_138: [ If resizing the tracked method handles array fails, the RELEASED outcome shall be returned and an error shall be indicated. ]*/
AzureIoTClient 42:c2eaa912a28c 318 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 319 LogError("Cannot grow method handles array");
AzureIoTClient 42:c2eaa912a28c 320 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 321 }
AzureIoTClient 42:c2eaa912a28c 322 else
AzureIoTClient 42:c2eaa912a28c 323 {
AzureIoTClient 42:c2eaa912a28c 324 amqp_methods_handle->method_request_handles = new_handles;
AzureIoTClient 42:c2eaa912a28c 325
AzureIoTClient 42:c2eaa912a28c 326 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_121: [ The uuid value for the correlation ID shall be obtained by calling `amqpvalue_get_uuid`. ]*/
AzureIoTClient 42:c2eaa912a28c 327 if (amqpvalue_get_uuid(correlation_id, &method_handle->correlation_id) != 0)
AzureIoTClient 42:c2eaa912a28c 328 {
AzureIoTClient 42:c2eaa912a28c 329 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_122: [ If `amqpvalue_get_uuid` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 330 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 331 LogError("Cannot get uuid value for correlation-id");
AzureIoTClient 42:c2eaa912a28c 332 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 333 result = messaging_delivery_rejected("amqp:decode-error", "Cannot get uuid value for correlation-id");
AzureIoTClient 42:c2eaa912a28c 334 }
AzureIoTClient 42:c2eaa912a28c 335 else
AzureIoTClient 42:c2eaa912a28c 336 {
AzureIoTClient 42:c2eaa912a28c 337 BINARY_DATA binary_data;
AzureIoTClient 42:c2eaa912a28c 338
AzureIoTClient 42:c2eaa912a28c 339 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_048: [ - The message payload shall be obtained by calling `message_get_body_amqp_data_in_place` with the index argument being 0. ]*/
AzureIoTClient 42:c2eaa912a28c 340 if (message_get_body_amqp_data_in_place(message, 0, &binary_data) != 0)
AzureIoTClient 42:c2eaa912a28c 341 {
AzureIoTClient 42:c2eaa912a28c 342 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_049: [ If `message_get_body_amqp_data_in_place` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 343 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 344 LogError("Cannot get method request message payload");
AzureIoTClient 42:c2eaa912a28c 345 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 346 result = messaging_delivery_rejected("amqp:decode-error", "Cannot get method request message payload");
AzureIoTClient 42:c2eaa912a28c 347 }
AzureIoTClient 42:c2eaa912a28c 348 else
AzureIoTClient 42:c2eaa912a28c 349 {
AzureIoTClient 42:c2eaa912a28c 350 AMQP_VALUE application_properties;
AzureIoTClient 42:c2eaa912a28c 351
AzureIoTClient 42:c2eaa912a28c 352 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_099: [ The application properties for the received message shall be obtained by calling `message_get_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 353 if (message_get_application_properties(message, &application_properties) != 0)
AzureIoTClient 42:c2eaa912a28c 354 {
AzureIoTClient 42:c2eaa912a28c 355 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_133: [ If `message_get_application_properties` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 356 LogError("Cannot get application properties");
AzureIoTClient 42:c2eaa912a28c 357 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 358 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 359 result = messaging_delivery_rejected("amqp:decode-error", "Cannot get application properties");
AzureIoTClient 42:c2eaa912a28c 360 }
AzureIoTClient 42:c2eaa912a28c 361 else
AzureIoTClient 42:c2eaa912a28c 362 {
AzureIoTClient 42:c2eaa912a28c 363 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_123: [ The AMQP map shall be retrieve from the application properties by calling `amqpvalue_get_inplace_described_value`. ]*/
AzureIoTClient 42:c2eaa912a28c 364 AMQP_VALUE amqp_properties_map = amqpvalue_get_inplace_described_value(application_properties);
AzureIoTClient 42:c2eaa912a28c 365 if (amqp_properties_map == NULL)
AzureIoTClient 42:c2eaa912a28c 366 {
AzureIoTClient 42:c2eaa912a28c 367 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_134: [ If `amqpvalue_get_inplace_described_value` fails the RELEASED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 368 LogError("Cannot get application properties map");
AzureIoTClient 42:c2eaa912a28c 369 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 370 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 371 }
AzureIoTClient 42:c2eaa912a28c 372 else
AzureIoTClient 42:c2eaa912a28c 373 {
AzureIoTClient 42:c2eaa912a28c 374 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_100: [ A property key `IoThub-methodname` shall be created by calling `amqpvalue_create_string`. ]*/
AzureIoTClient 42:c2eaa912a28c 375 AMQP_VALUE property_key = amqpvalue_create_string("IoThub-methodname");
AzureIoTClient 42:c2eaa912a28c 376 if (property_key == NULL)
AzureIoTClient 42:c2eaa912a28c 377 {
AzureIoTClient 42:c2eaa912a28c 378 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_132: [ If `amqpvalue_create_string` fails the RELEASED outcome shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 379 LogError("Cannot create the property key for method name");
AzureIoTClient 42:c2eaa912a28c 380 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 381 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 382 }
AzureIoTClient 42:c2eaa912a28c 383 else
AzureIoTClient 42:c2eaa912a28c 384 {
AzureIoTClient 42:c2eaa912a28c 385 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_101: [ The method name property value shall be found in the map by calling `amqpvalue_get_map_value`. ]*/
AzureIoTClient 42:c2eaa912a28c 386 AMQP_VALUE property_value = amqpvalue_get_map_value(amqp_properties_map, property_key);
AzureIoTClient 42:c2eaa912a28c 387 if (property_value == NULL)
AzureIoTClient 42:c2eaa912a28c 388 {
AzureIoTClient 42:c2eaa912a28c 389 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_103: [ If `amqpvalue_get_map_value` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 390 LogError("Cannot find the IoThub-methodname property in the properties map");
AzureIoTClient 42:c2eaa912a28c 391 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 392 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 393 result = messaging_delivery_rejected("amqp:decode-error", "Cannot find the IoThub-methodname property in the properties map");
AzureIoTClient 42:c2eaa912a28c 394 }
AzureIoTClient 42:c2eaa912a28c 395 else
AzureIoTClient 42:c2eaa912a28c 396 {
AzureIoTClient 42:c2eaa912a28c 397 const char* method_name;
AzureIoTClient 42:c2eaa912a28c 398
AzureIoTClient 42:c2eaa912a28c 399 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_102: [ The string contained by the property value shall be obtained by calling `amqpvalue_get_string`. ]*/
AzureIoTClient 42:c2eaa912a28c 400 if (amqpvalue_get_string(property_value, &method_name) != 0)
AzureIoTClient 42:c2eaa912a28c 401 {
AzureIoTClient 42:c2eaa912a28c 402 /*Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_131: [ If `amqpvalue_get_string` fails the REJECTED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 403 LogError("Cannot read the method name from the property value");
AzureIoTClient 42:c2eaa912a28c 404 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 405 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 406 result = messaging_delivery_rejected("amqp:decode-error", "Cannot read the method name from the property value");
AzureIoTClient 42:c2eaa912a28c 407 }
AzureIoTClient 42:c2eaa912a28c 408 else
AzureIoTClient 42:c2eaa912a28c 409 {
AzureIoTClient 42:c2eaa912a28c 410 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_056: [ On success the `on_message_received` callback shall return a newly constructed delivery state obtained by calling `messaging_delivery_accepted`. ]*/
AzureIoTClient 42:c2eaa912a28c 411 result = messaging_delivery_accepted();
AzureIoTClient 42:c2eaa912a28c 412 if (result == NULL)
AzureIoTClient 42:c2eaa912a28c 413 {
AzureIoTClient 42:c2eaa912a28c 414 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_057: [ If `messaging_delivery_accepted` fails the RELEASED outcome with `amqp:decode-error` shall be returned. ]*/
AzureIoTClient 42:c2eaa912a28c 415 LogError("Cannot allocate memory for delivery state");
AzureIoTClient 42:c2eaa912a28c 416 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 417 message_outcome = MESSAGE_OUTCOME_RELEASED;
AzureIoTClient 42:c2eaa912a28c 418 }
AzureIoTClient 42:c2eaa912a28c 419 else
AzureIoTClient 42:c2eaa912a28c 420 {
AzureIoTClient 42:c2eaa912a28c 421 method_handle->iothubtransport_amqp_methods_handle = amqp_methods_handle;
AzureIoTClient 42:c2eaa912a28c 422
AzureIoTClient 42:c2eaa912a28c 423 /* set the method request handle in the handle array */
AzureIoTClient 42:c2eaa912a28c 424 amqp_methods_handle->method_request_handles[amqp_methods_handle->method_request_handle_count] = method_handle;
AzureIoTClient 42:c2eaa912a28c 425 amqp_methods_handle->method_request_handle_count++;
AzureIoTClient 42:c2eaa912a28c 426
AzureIoTClient 42:c2eaa912a28c 427 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_050: [ The binary message payload shall be indicated by calling the `on_method_request_received` callback passed to `iothubtransportamqp_methods_subscribe` with the arguments: ]*/
AzureIoTClient 42:c2eaa912a28c 428 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_051: [ - `context` shall be set to the `on_method_request_received_context` argument passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 429 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_098: [ - `method_name` shall be set to the application property value for `IoThub-methodname`. ]*/
AzureIoTClient 42:c2eaa912a28c 430 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_052: [ - `request` shall be set to the payload bytes obtained by calling `message_get_body_amqp_data_in_place`. ]*/
AzureIoTClient 42:c2eaa912a28c 431 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_053: [ - `request_size` shall be set to the payload size obtained by calling `message_get_body_amqp_data_in_place`. ]*/
AzureIoTClient 42:c2eaa912a28c 432 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_054: [ - `method_handle` shall be set to a newly created `IOTHUBTRANSPORT_AMQP_METHOD_HANDLE` that can be passed later as an argument to `iothubtransportamqp_methods_respond`. ]*/
AzureIoTClient 42:c2eaa912a28c 433 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_109: [ `iothubtransportamqp_methods_respond` shall be allowed to be called from the callback `on_method_request_received`. ]*/
AzureIoTClient 42:c2eaa912a28c 434 if (amqp_methods_handle->on_method_request_received(amqp_methods_handle->on_method_request_received_context, method_name, binary_data.bytes, binary_data.length, method_handle) != 0)
AzureIoTClient 42:c2eaa912a28c 435 {
AzureIoTClient 42:c2eaa912a28c 436 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_147: [ If `on_method_request_received` fails, the REJECTED outcome shall be returned with `amqp:internal-error`. ]*/
AzureIoTClient 42:c2eaa912a28c 437 LogError("Cannot execute the callback with the given data");
AzureIoTClient 42:c2eaa912a28c 438 amqpvalue_destroy(result);
AzureIoTClient 42:c2eaa912a28c 439 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 440 amqp_methods_handle->method_request_handle_count--;
AzureIoTClient 42:c2eaa912a28c 441 message_outcome = MESSAGE_OUTCOME_REJECTED;
AzureIoTClient 42:c2eaa912a28c 442 result = messaging_delivery_rejected("amqp:internal-error", "Cannot execute the callback with the given data");
AzureIoTClient 42:c2eaa912a28c 443 }
AzureIoTClient 42:c2eaa912a28c 444 else
AzureIoTClient 42:c2eaa912a28c 445 {
AzureIoTClient 42:c2eaa912a28c 446 message_outcome = MESSAGE_OUTCOME_ACCEPTED;
AzureIoTClient 42:c2eaa912a28c 447 }
AzureIoTClient 42:c2eaa912a28c 448 }
AzureIoTClient 42:c2eaa912a28c 449 }
AzureIoTClient 42:c2eaa912a28c 450
AzureIoTClient 42:c2eaa912a28c 451 amqpvalue_destroy(property_value);
AzureIoTClient 42:c2eaa912a28c 452 }
AzureIoTClient 42:c2eaa912a28c 453
AzureIoTClient 42:c2eaa912a28c 454 amqpvalue_destroy(property_key);
AzureIoTClient 42:c2eaa912a28c 455 }
AzureIoTClient 42:c2eaa912a28c 456 }
AzureIoTClient 42:c2eaa912a28c 457
AzureIoTClient 42:c2eaa912a28c 458 application_properties_destroy(application_properties);
AzureIoTClient 42:c2eaa912a28c 459 }
AzureIoTClient 42:c2eaa912a28c 460 }
AzureIoTClient 42:c2eaa912a28c 461 }
AzureIoTClient 42:c2eaa912a28c 462 }
AzureIoTClient 42:c2eaa912a28c 463 }
AzureIoTClient 42:c2eaa912a28c 464 }
AzureIoTClient 42:c2eaa912a28c 465
AzureIoTClient 42:c2eaa912a28c 466 properties_destroy(properties);
AzureIoTClient 42:c2eaa912a28c 467 }
AzureIoTClient 42:c2eaa912a28c 468 }
AzureIoTClient 42:c2eaa912a28c 469
AzureIoTClient 42:c2eaa912a28c 470 switch (message_outcome)
AzureIoTClient 42:c2eaa912a28c 471 {
AzureIoTClient 42:c2eaa912a28c 472 default:
AzureIoTClient 42:c2eaa912a28c 473 break;
AzureIoTClient 42:c2eaa912a28c 474
AzureIoTClient 42:c2eaa912a28c 475 case MESSAGE_OUTCOME_RELEASED:
AzureIoTClient 42:c2eaa912a28c 476 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_129: [ The released outcome shall be created by calling `messaging_delivery_released`. ]*/
AzureIoTClient 42:c2eaa912a28c 477 result = messaging_delivery_released();
AzureIoTClient 42:c2eaa912a28c 478
AzureIoTClient 42:c2eaa912a28c 479 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_128: [ When the RELEASED outcome is returned, an error shall be indicated by calling the `on_methods_error` callback passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 480 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_042: [ When an error is indicated by calling the `on_methods_error`, it shall be called with the context being the `on_methods_error_context` argument passed to `iothubtransportamqp_methods_subscribe`. ]*/
AzureIoTClient 42:c2eaa912a28c 481 amqp_methods_handle->on_methods_error(amqp_methods_handle->on_methods_error_context);
AzureIoTClient 42:c2eaa912a28c 482 break;
AzureIoTClient 42:c2eaa912a28c 483
AzureIoTClient 42:c2eaa912a28c 484 case MESSAGE_OUTCOME_REJECTED:
AzureIoTClient 42:c2eaa912a28c 485 case MESSAGE_OUTCOME_ACCEPTED:
AzureIoTClient 42:c2eaa912a28c 486 /* all is well */
AzureIoTClient 42:c2eaa912a28c 487 break;
AzureIoTClient 42:c2eaa912a28c 488 }
AzureIoTClient 42:c2eaa912a28c 489
AzureIoTClient 42:c2eaa912a28c 490 return result;
AzureIoTClient 42:c2eaa912a28c 491 }
AzureIoTClient 42:c2eaa912a28c 492
AzureIoTClient 54:830550fef7ea 493 STRING_HANDLE create_correlation_id(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 54:830550fef7ea 494 {
AzureIoTClient 54:830550fef7ea 495 if (iothubtransport_amqp_methods_handle->module_id != NULL)
AzureIoTClient 54:830550fef7ea 496 {
AzureIoTClient 56:8704100b3b54 497 return STRING_construct_sprintf("%s/%s", iothubtransport_amqp_methods_handle->device_id, iothubtransport_amqp_methods_handle->module_id);
AzureIoTClient 54:830550fef7ea 498 }
AzureIoTClient 54:830550fef7ea 499 else
AzureIoTClient 54:830550fef7ea 500 {
AzureIoTClient 54:830550fef7ea 501 return STRING_construct(iothubtransport_amqp_methods_handle->device_id);
AzureIoTClient 54:830550fef7ea 502 }
AzureIoTClient 54:830550fef7ea 503 }
AzureIoTClient 54:830550fef7ea 504
AzureIoTClient 54:830550fef7ea 505 STRING_HANDLE create_peer_endpoint_name(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 54:830550fef7ea 506 {
AzureIoTClient 54:830550fef7ea 507 if (iothubtransport_amqp_methods_handle->module_id != NULL)
AzureIoTClient 54:830550fef7ea 508 {
AzureIoTClient 54:830550fef7ea 509 return STRING_construct_sprintf("amqps://%s/devices/%s/modules/%s/methods/devicebound", iothubtransport_amqp_methods_handle->hostname, iothubtransport_amqp_methods_handle->device_id, iothubtransport_amqp_methods_handle->module_id);
AzureIoTClient 54:830550fef7ea 510 }
AzureIoTClient 54:830550fef7ea 511 else
AzureIoTClient 54:830550fef7ea 512 {
AzureIoTClient 54:830550fef7ea 513 return STRING_construct_sprintf("amqps://%s/devices/%s/methods/devicebound", iothubtransport_amqp_methods_handle->hostname, iothubtransport_amqp_methods_handle->device_id);
AzureIoTClient 54:830550fef7ea 514 }
AzureIoTClient 54:830550fef7ea 515 }
AzureIoTClient 54:830550fef7ea 516
AzureIoTClient 54:830550fef7ea 517 STRING_HANDLE create_requests_link_name(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 54:830550fef7ea 518 {
AzureIoTClient 54:830550fef7ea 519 if (iothubtransport_amqp_methods_handle->module_id != NULL)
AzureIoTClient 54:830550fef7ea 520 {
AzureIoTClient 54:830550fef7ea 521 return STRING_construct_sprintf("methods_requests_link-%s/%s", iothubtransport_amqp_methods_handle->device_id, iothubtransport_amqp_methods_handle->module_id);
AzureIoTClient 54:830550fef7ea 522 }
AzureIoTClient 54:830550fef7ea 523 else
AzureIoTClient 54:830550fef7ea 524 {
AzureIoTClient 54:830550fef7ea 525 return STRING_construct_sprintf("methods_requests_link-%s", iothubtransport_amqp_methods_handle->device_id);
AzureIoTClient 54:830550fef7ea 526 }
AzureIoTClient 54:830550fef7ea 527 }
AzureIoTClient 54:830550fef7ea 528
AzureIoTClient 54:830550fef7ea 529 STRING_HANDLE create_responses_link_name(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 54:830550fef7ea 530 {
AzureIoTClient 54:830550fef7ea 531 if (iothubtransport_amqp_methods_handle->module_id != NULL)
AzureIoTClient 54:830550fef7ea 532 {
AzureIoTClient 54:830550fef7ea 533 return STRING_construct_sprintf("methods_responses_link-%s/%s", iothubtransport_amqp_methods_handle->device_id, iothubtransport_amqp_methods_handle->module_id);
AzureIoTClient 54:830550fef7ea 534 }
AzureIoTClient 54:830550fef7ea 535 else
AzureIoTClient 54:830550fef7ea 536 {
AzureIoTClient 54:830550fef7ea 537 return STRING_construct_sprintf("methods_responses_link-%s", iothubtransport_amqp_methods_handle->device_id);
AzureIoTClient 54:830550fef7ea 538 }
AzureIoTClient 54:830550fef7ea 539 }
AzureIoTClient 54:830550fef7ea 540
AzureIoTClient 54:830550fef7ea 541
AzureIoTClient 54:830550fef7ea 542
AzureIoTClient 42:c2eaa912a28c 543 static int set_link_attach_properties(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 42:c2eaa912a28c 544 {
AzureIoTClient 42:c2eaa912a28c 545 int result = 0;
AzureIoTClient 42:c2eaa912a28c 546 fields link_attach_properties;
AzureIoTClient 42:c2eaa912a28c 547
AzureIoTClient 42:c2eaa912a28c 548 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_140: [ A link attach properties map shall be created by calling `amqpvalue_create_map`. ]*/
AzureIoTClient 42:c2eaa912a28c 549 link_attach_properties = amqpvalue_create_map();
AzureIoTClient 42:c2eaa912a28c 550 if (link_attach_properties == NULL)
AzureIoTClient 42:c2eaa912a28c 551 {
AzureIoTClient 42:c2eaa912a28c 552 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 54:830550fef7ea 553 LogError("Cannot create the map for link attach properties");
AzureIoTClient 42:c2eaa912a28c 554 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 555 }
AzureIoTClient 42:c2eaa912a28c 556 else
AzureIoTClient 42:c2eaa912a28c 557 {
AzureIoTClient 42:c2eaa912a28c 558 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_141: [ A property key which shall be a symbol named `com.microsoft:channel-correlation-id` shall be created by calling `amqp_create_symbol`. ]*/
AzureIoTClient 42:c2eaa912a28c 559 AMQP_VALUE channel_correlation_id_property_key = amqpvalue_create_symbol("com.microsoft:channel-correlation-id");
AzureIoTClient 42:c2eaa912a28c 560 if (channel_correlation_id_property_key == NULL)
AzureIoTClient 42:c2eaa912a28c 561 {
AzureIoTClient 42:c2eaa912a28c 562 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 563 LogError("Cannot create the channel correlation id property key for the link attach properties");
AzureIoTClient 42:c2eaa912a28c 564 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 565 }
AzureIoTClient 42:c2eaa912a28c 566 else
AzureIoTClient 42:c2eaa912a28c 567 {
AzureIoTClient 54:830550fef7ea 568 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_142: [ A property value of type string that shall contain the device id (and "/" + module id if module is present) shall be created by calling `amqpvalue_create_string`. ]*/
AzureIoTClient 54:830550fef7ea 569 STRING_HANDLE correlation_id = NULL;
AzureIoTClient 54:830550fef7ea 570 AMQP_VALUE channel_correlation_id_property_value = NULL;
AzureIoTClient 54:830550fef7ea 571
AzureIoTClient 54:830550fef7ea 572 if ((correlation_id = create_correlation_id(iothubtransport_amqp_methods_handle)) == NULL)
AzureIoTClient 54:830550fef7ea 573 {
AzureIoTClient 54:830550fef7ea 574 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 54:830550fef7ea 575 LogError("Cannot create the channel correlation id string for the link attach properties");
AzureIoTClient 54:830550fef7ea 576 result = __FAILURE__;
AzureIoTClient 54:830550fef7ea 577 }
AzureIoTClient 54:830550fef7ea 578 else if ((channel_correlation_id_property_value = amqpvalue_create_string(STRING_c_str(correlation_id))) == NULL)
AzureIoTClient 42:c2eaa912a28c 579 {
AzureIoTClient 42:c2eaa912a28c 580 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 581 LogError("Cannot create the channel correlation id property key for the link attach properties");
AzureIoTClient 42:c2eaa912a28c 582 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 583 }
AzureIoTClient 42:c2eaa912a28c 584 else
AzureIoTClient 42:c2eaa912a28c 585 {
AzureIoTClient 42:c2eaa912a28c 586 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_143: [ The `com.microsoft:channel-correlation-id` shall be added to the link attach properties by calling `amqpvalue_set_map_value`. ]*/
AzureIoTClient 42:c2eaa912a28c 587 if (amqpvalue_set_map_value(link_attach_properties, channel_correlation_id_property_key, channel_correlation_id_property_value) != 0)
AzureIoTClient 42:c2eaa912a28c 588 {
AzureIoTClient 42:c2eaa912a28c 589 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 590 LogError("Cannot set the property for channel correlation on the link attach properties");
AzureIoTClient 42:c2eaa912a28c 591 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 592 }
AzureIoTClient 42:c2eaa912a28c 593 else
AzureIoTClient 42:c2eaa912a28c 594 {
AzureIoTClient 42:c2eaa912a28c 595 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_150: [ A property key which shall be a symbol named `com.microsoft:api-version` shall be created by calling `amqp_create_symbol`. ]*/
AzureIoTClient 42:c2eaa912a28c 596 AMQP_VALUE api_version_property_key = amqpvalue_create_symbol("com.microsoft:api-version");
AzureIoTClient 42:c2eaa912a28c 597 if (api_version_property_key == NULL)
AzureIoTClient 42:c2eaa912a28c 598 {
AzureIoTClient 42:c2eaa912a28c 599 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 600 LogError("Cannot create the API version property key for the link attach properties");
AzureIoTClient 42:c2eaa912a28c 601 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 602 }
AzureIoTClient 42:c2eaa912a28c 603 else
AzureIoTClient 42:c2eaa912a28c 604 {
AzureIoTClient 42:c2eaa912a28c 605 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_151: [ A property value of type string that shall contain the `2016-11-14` shall be created by calling `amqpvalue_create_string`. ]*/
AzureIoTClient 42:c2eaa912a28c 606 AMQP_VALUE api_version_property_value = amqpvalue_create_string("2016-11-14");
AzureIoTClient 42:c2eaa912a28c 607 if (api_version_property_value == NULL)
AzureIoTClient 42:c2eaa912a28c 608 {
AzureIoTClient 42:c2eaa912a28c 609 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 610 LogError("Cannot create the API version property value for the link attach properties");
AzureIoTClient 42:c2eaa912a28c 611 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 612 }
AzureIoTClient 42:c2eaa912a28c 613 else
AzureIoTClient 42:c2eaa912a28c 614 {
AzureIoTClient 42:c2eaa912a28c 615 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_152: [ The `com.microsoft:api-version` shall be added to the link attach properties by calling `amqpvalue_set_map_value`. ]*/
AzureIoTClient 42:c2eaa912a28c 616 if (amqpvalue_set_map_value(link_attach_properties, api_version_property_key, api_version_property_value) != 0)
AzureIoTClient 42:c2eaa912a28c 617 {
AzureIoTClient 42:c2eaa912a28c 618 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 619 LogError("Cannot set the property for API version on the link attach properties");
AzureIoTClient 42:c2eaa912a28c 620 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 621 }
AzureIoTClient 42:c2eaa912a28c 622 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_144: [ The link attach properties shall be set on the receiver and sender link by calling `link_set_attach_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 623 else if (link_set_attach_properties(iothubtransport_amqp_methods_handle->sender_link, link_attach_properties) != 0)
AzureIoTClient 42:c2eaa912a28c 624 {
AzureIoTClient 42:c2eaa912a28c 625 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 626 LogError("Cannot set the link attach properties on the sender link");
AzureIoTClient 42:c2eaa912a28c 627 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 628 }
AzureIoTClient 42:c2eaa912a28c 629 else if (link_set_attach_properties(iothubtransport_amqp_methods_handle->receiver_link, link_attach_properties) != 0)
AzureIoTClient 42:c2eaa912a28c 630 {
AzureIoTClient 42:c2eaa912a28c 631 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_145: [ If any call for creating or setting the link attach properties fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 632 LogError("Cannot set the link attach properties on the receiver link");
AzureIoTClient 42:c2eaa912a28c 633 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 634 }
AzureIoTClient 42:c2eaa912a28c 635 else
AzureIoTClient 42:c2eaa912a28c 636 {
AzureIoTClient 42:c2eaa912a28c 637 result = 0;
AzureIoTClient 42:c2eaa912a28c 638 }
AzureIoTClient 42:c2eaa912a28c 639
AzureIoTClient 42:c2eaa912a28c 640 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_146: [ The link attach properties and all associated values shall be freed by calling `amqpvalue_destroy` after setting the link attach properties. ]*/
AzureIoTClient 42:c2eaa912a28c 641 amqpvalue_destroy(api_version_property_value);
AzureIoTClient 42:c2eaa912a28c 642 }
AzureIoTClient 42:c2eaa912a28c 643
AzureIoTClient 42:c2eaa912a28c 644 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_146: [ The link attach properties and all associated values shall be freed by calling `amqpvalue_destroy` after setting the link attach properties. ]*/
AzureIoTClient 42:c2eaa912a28c 645 amqpvalue_destroy(api_version_property_key);
AzureIoTClient 42:c2eaa912a28c 646 }
AzureIoTClient 42:c2eaa912a28c 647 }
AzureIoTClient 42:c2eaa912a28c 648
AzureIoTClient 42:c2eaa912a28c 649 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_146: [ The link attach properties and all associated values shall be freed by calling `amqpvalue_destroy` after setting the link attach properties. ]*/
AzureIoTClient 42:c2eaa912a28c 650 amqpvalue_destroy(channel_correlation_id_property_value);
AzureIoTClient 42:c2eaa912a28c 651 }
AzureIoTClient 54:830550fef7ea 652 STRING_delete(correlation_id);
AzureIoTClient 42:c2eaa912a28c 653
AzureIoTClient 42:c2eaa912a28c 654 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_146: [ The link attach properties and all associated values shall be freed by calling `amqpvalue_destroy` after setting the link attach properties. ]*/
AzureIoTClient 42:c2eaa912a28c 655 amqpvalue_destroy(channel_correlation_id_property_key);
AzureIoTClient 42:c2eaa912a28c 656 }
AzureIoTClient 42:c2eaa912a28c 657
AzureIoTClient 42:c2eaa912a28c 658 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_146: [ The link attach properties and all associated values shall be freed by calling `amqpvalue_destroy` after setting the link attach properties. ]*/
AzureIoTClient 42:c2eaa912a28c 659 amqpvalue_destroy(link_attach_properties);
AzureIoTClient 42:c2eaa912a28c 660 }
AzureIoTClient 42:c2eaa912a28c 661
AzureIoTClient 42:c2eaa912a28c 662 return result;
AzureIoTClient 42:c2eaa912a28c 663 }
AzureIoTClient 42:c2eaa912a28c 664
AzureIoTClient 42:c2eaa912a28c 665 int iothubtransportamqp_methods_subscribe(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle,
AzureIoTClient 42:c2eaa912a28c 666 SESSION_HANDLE session_handle, ON_METHODS_ERROR on_methods_error, void* on_methods_error_context,
AzureIoTClient 42:c2eaa912a28c 667 ON_METHOD_REQUEST_RECEIVED on_method_request_received, void* on_method_request_received_context,
AzureIoTClient 42:c2eaa912a28c 668 ON_METHODS_UNSUBSCRIBED on_methods_unsubscribed, void* on_methods_unsubscribed_context)
AzureIoTClient 42:c2eaa912a28c 669 {
AzureIoTClient 42:c2eaa912a28c 670 int result;
AzureIoTClient 42:c2eaa912a28c 671
AzureIoTClient 42:c2eaa912a28c 672 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_009: [ If any of the argument `iothubtransport_amqp_methods_handle`, `session_handle`, `on_methods_error`, `on_method_request_received`, `on_methods_unsubscribed` is NULL, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 673 if ((iothubtransport_amqp_methods_handle == NULL) ||
AzureIoTClient 42:c2eaa912a28c 674 (session_handle == NULL) ||
AzureIoTClient 42:c2eaa912a28c 675 (on_methods_error == NULL) ||
AzureIoTClient 42:c2eaa912a28c 676 (on_method_request_received == NULL) ||
AzureIoTClient 42:c2eaa912a28c 677 (on_methods_unsubscribed == NULL))
AzureIoTClient 42:c2eaa912a28c 678 {
AzureIoTClient 56:8704100b3b54 679 LogError("Invalid arguments: iothubtransport_amqp_methods_handle=%p, session_handle=%p, on_methods_error=%p, on_method_request_received=%p, on_methods_unsubscribed=%p",
AzureIoTClient 42:c2eaa912a28c 680 iothubtransport_amqp_methods_handle, session_handle, on_methods_error, on_method_request_received, on_methods_unsubscribed);
AzureIoTClient 42:c2eaa912a28c 681 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 682 }
AzureIoTClient 42:c2eaa912a28c 683 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_137: [ `iothubtransportamqp_methods_subscribe` after another succesfull `iothubtransportamqp_methods_subscribe` without any unsubscribe shall return a non-zero value without performing any subscribe action. ]*/
AzureIoTClient 42:c2eaa912a28c 684 else if (iothubtransport_amqp_methods_handle->subscribe_state != SUBSCRIBE_STATE_NOT_SUBSCRIBED)
AzureIoTClient 42:c2eaa912a28c 685 {
AzureIoTClient 42:c2eaa912a28c 686 LogError("Already subscribed");
AzureIoTClient 42:c2eaa912a28c 687 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 688 }
AzureIoTClient 42:c2eaa912a28c 689 else
AzureIoTClient 42:c2eaa912a28c 690 {
AzureIoTClient 54:830550fef7ea 691 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_015: [ The address string used to create the source shall be of the form `/devices/{device id}` + (`/modules/{module id}` if modules are present) + `/methods/devicebound`. ]*/
AzureIoTClient 42:c2eaa912a28c 692 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_016: [ The string shall be created by using `STRING_construct_sprintf`. ]*/
AzureIoTClient 54:830550fef7ea 693 STRING_HANDLE peer_endpoint_string = create_peer_endpoint_name(iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 694 if (peer_endpoint_string == NULL)
AzureIoTClient 42:c2eaa912a28c 695 {
AzureIoTClient 42:c2eaa912a28c 696 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_018: [ If `STRING_construct_sprintf` fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 697 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 698 }
AzureIoTClient 42:c2eaa912a28c 699 else
AzureIoTClient 42:c2eaa912a28c 700 {
AzureIoTClient 42:c2eaa912a28c 701 iothubtransport_amqp_methods_handle->on_method_request_received = on_method_request_received;
AzureIoTClient 42:c2eaa912a28c 702 iothubtransport_amqp_methods_handle->on_method_request_received_context = on_method_request_received_context;
AzureIoTClient 42:c2eaa912a28c 703 iothubtransport_amqp_methods_handle->on_methods_error = on_methods_error;
AzureIoTClient 42:c2eaa912a28c 704 iothubtransport_amqp_methods_handle->on_methods_error_context = on_methods_error_context;
AzureIoTClient 42:c2eaa912a28c 705 iothubtransport_amqp_methods_handle->on_methods_unsubscribed = on_methods_unsubscribed;
AzureIoTClient 42:c2eaa912a28c 706 iothubtransport_amqp_methods_handle->on_methods_unsubscribed_context = on_methods_unsubscribed_context;
AzureIoTClient 42:c2eaa912a28c 707
AzureIoTClient 42:c2eaa912a28c 708 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_014: [ - `source` shall be the a source value created by calling `messaging_create_source`. ]*/
AzureIoTClient 42:c2eaa912a28c 709 AMQP_VALUE receiver_source = messaging_create_source(STRING_c_str(peer_endpoint_string));
AzureIoTClient 42:c2eaa912a28c 710 if (receiver_source == NULL)
AzureIoTClient 42:c2eaa912a28c 711 {
AzureIoTClient 42:c2eaa912a28c 712 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_019: [ If creating the target or source values fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 713 LogError("Cannot create receiver source");
AzureIoTClient 42:c2eaa912a28c 714 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 715 }
AzureIoTClient 42:c2eaa912a28c 716 else
AzureIoTClient 42:c2eaa912a28c 717 {
AzureIoTClient 42:c2eaa912a28c 718 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_017: [ - `target` shall be the a target value created by calling `messaging_create_target`. ]*/
AzureIoTClient 42:c2eaa912a28c 719 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_117: [ The address string used to create the target shall be `requests`. ]*/
AzureIoTClient 42:c2eaa912a28c 720 AMQP_VALUE receiver_target = messaging_create_target("requests");
AzureIoTClient 42:c2eaa912a28c 721 if (receiver_target == NULL)
AzureIoTClient 42:c2eaa912a28c 722 {
AzureIoTClient 42:c2eaa912a28c 723 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_019: [ If creating the target or source values fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 724 LogError("Cannot create receiver target");
AzureIoTClient 42:c2eaa912a28c 725 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 726 }
AzureIoTClient 42:c2eaa912a28c 727 else
AzureIoTClient 42:c2eaa912a28c 728 {
AzureIoTClient 54:830550fef7ea 729 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_012: [ - `name` shall be in the format `methods_requests_link-{device_id}` (+ `/{module-id}` if module id is present). ]*/
AzureIoTClient 56:8704100b3b54 730 STRING_HANDLE requests_link_name = create_requests_link_name(iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 731 if (requests_link_name == NULL)
AzureIoTClient 42:c2eaa912a28c 732 {
AzureIoTClient 42:c2eaa912a28c 733 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_153: [ If constructing the requests link name fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 734 LogError("Cannot create methods requests link name.");
AzureIoTClient 42:c2eaa912a28c 735 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 736 }
AzureIoTClient 42:c2eaa912a28c 737 else
AzureIoTClient 42:c2eaa912a28c 738 {
AzureIoTClient 42:c2eaa912a28c 739 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_010: [ `iothubtransportamqp_methods_subscribe` shall create a receiver link by calling `link_create` with the following arguments: ]*/
AzureIoTClient 42:c2eaa912a28c 740 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_011: [ - `session_handle` shall be the session_handle argument passed to iothubtransportamqp_methods_subscribe ]*/
AzureIoTClient 42:c2eaa912a28c 741 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_013: [ - `role` shall be role_receiver. ]*/
AzureIoTClient 42:c2eaa912a28c 742 iothubtransport_amqp_methods_handle->receiver_link = link_create(session_handle, STRING_c_str(requests_link_name), role_receiver, receiver_source, receiver_target);
AzureIoTClient 42:c2eaa912a28c 743 if (iothubtransport_amqp_methods_handle->receiver_link == NULL)
AzureIoTClient 42:c2eaa912a28c 744 {
AzureIoTClient 42:c2eaa912a28c 745 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_020: [ If creating the receiver link fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 746 LogError("Cannot create receiver link");
AzureIoTClient 42:c2eaa912a28c 747 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 748 }
AzureIoTClient 42:c2eaa912a28c 749 else
AzureIoTClient 42:c2eaa912a28c 750 {
AzureIoTClient 42:c2eaa912a28c 751 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_025: [ - `source` shall be the a source value created by calling `messaging_create_source`. ]*/
AzureIoTClient 42:c2eaa912a28c 752 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_026: [ The address string used to create the target shall be `responses`. ]*/
AzureIoTClient 42:c2eaa912a28c 753 AMQP_VALUE sender_source = messaging_create_source("responses");
AzureIoTClient 42:c2eaa912a28c 754 if (sender_source == NULL)
AzureIoTClient 42:c2eaa912a28c 755 {
AzureIoTClient 42:c2eaa912a28c 756 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_031: [ If creating the target or source values fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 757 LogError("Cannot create sender source");
AzureIoTClient 42:c2eaa912a28c 758 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 759 }
AzureIoTClient 42:c2eaa912a28c 760 else
AzureIoTClient 42:c2eaa912a28c 761 {
AzureIoTClient 42:c2eaa912a28c 762 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_027: [ - `target` shall be the a target value created by calling `messaging_create_target`. ]*/
AzureIoTClient 42:c2eaa912a28c 763 AMQP_VALUE sender_target = messaging_create_target(STRING_c_str(peer_endpoint_string));
AzureIoTClient 42:c2eaa912a28c 764 if (sender_target == NULL)
AzureIoTClient 42:c2eaa912a28c 765 {
AzureIoTClient 42:c2eaa912a28c 766 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_031: [ If creating the target or source values fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 767 LogError("Cannot create sender target");
AzureIoTClient 42:c2eaa912a28c 768 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 769 }
AzureIoTClient 42:c2eaa912a28c 770 else
AzureIoTClient 42:c2eaa912a28c 771 {
AzureIoTClient 54:830550fef7ea 772 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_023: [ - `name` shall be format `methods_responses_link-{device_id}` (+ `/{module-id}` if module id is present). ]*/
AzureIoTClient 54:830550fef7ea 773 STRING_HANDLE responses_link_name = create_responses_link_name(iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 774 if (responses_link_name == NULL)
AzureIoTClient 42:c2eaa912a28c 775 {
AzureIoTClient 54:830550fef7ea 776 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_154: [ If constructing the responses link name fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 777 LogError("Cannot create methods responses link name.");
AzureIoTClient 42:c2eaa912a28c 778 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 779 }
AzureIoTClient 42:c2eaa912a28c 780 else
AzureIoTClient 42:c2eaa912a28c 781 {
AzureIoTClient 42:c2eaa912a28c 782 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_021: [ `iothubtransportamqp_methods_subscribe` shall create a sender link by calling `link_create` with the following arguments: ]*/
AzureIoTClient 42:c2eaa912a28c 783 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_022: [ - `session_handle` shall be the session_handle argument passed to iothubtransportamqp_methods_subscribe ]*/
AzureIoTClient 42:c2eaa912a28c 784 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_024: [ - `role` shall be role_sender. ]*/
AzureIoTClient 42:c2eaa912a28c 785 iothubtransport_amqp_methods_handle->sender_link = link_create(session_handle, STRING_c_str(responses_link_name), role_sender, sender_source, sender_target);
AzureIoTClient 42:c2eaa912a28c 786 if (iothubtransport_amqp_methods_handle->sender_link == NULL)
AzureIoTClient 42:c2eaa912a28c 787 {
AzureIoTClient 42:c2eaa912a28c 788 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_032: [ If creating the receiver link fails `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 789 LogError("Cannot create sender link");
AzureIoTClient 42:c2eaa912a28c 790 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 791 }
AzureIoTClient 42:c2eaa912a28c 792 else
AzureIoTClient 42:c2eaa912a28c 793 {
AzureIoTClient 42:c2eaa912a28c 794 if (set_link_attach_properties(iothubtransport_amqp_methods_handle) != 0)
AzureIoTClient 42:c2eaa912a28c 795 {
AzureIoTClient 42:c2eaa912a28c 796 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 797 }
AzureIoTClient 42:c2eaa912a28c 798 else
AzureIoTClient 42:c2eaa912a28c 799 {
AzureIoTClient 42:c2eaa912a28c 800 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_033: [ `iothubtransportamqp_methods_subscribe` shall create a message receiver associated with the receiver link by calling `messagereceiver_create` and passing the receiver link handle to it. ]*/
AzureIoTClient 42:c2eaa912a28c 801 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_118: [ An `on_message_receiver_state_changed` callback together with its context shall be passed to `messagereceiver_create`. ]*/
AzureIoTClient 42:c2eaa912a28c 802 iothubtransport_amqp_methods_handle->message_receiver = messagereceiver_create(iothubtransport_amqp_methods_handle->receiver_link, on_message_receiver_state_changed, iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 803 if (iothubtransport_amqp_methods_handle->message_receiver == NULL)
AzureIoTClient 42:c2eaa912a28c 804 {
AzureIoTClient 42:c2eaa912a28c 805 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_034: [ If `messagereceiver_create` fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 806 LogError("Cannot create message receiver");
AzureIoTClient 42:c2eaa912a28c 807 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 808 }
AzureIoTClient 42:c2eaa912a28c 809 else
AzureIoTClient 42:c2eaa912a28c 810 {
AzureIoTClient 42:c2eaa912a28c 811 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_035: [ `iothubtransportamqp_methods_subscribe` shall create a message sender associated with the sender link by calling `messagesender_create` and passing the sender link handle to it. ]*/
AzureIoTClient 42:c2eaa912a28c 812 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_106: [ An `on_message_sender_state_changed` callback together with its context shall be passed to `messagesender_create`. ]*/
AzureIoTClient 42:c2eaa912a28c 813 iothubtransport_amqp_methods_handle->message_sender = messagesender_create(iothubtransport_amqp_methods_handle->sender_link, on_message_sender_state_changed, iothubtransport_amqp_methods_handle);
AzureIoTClient 42:c2eaa912a28c 814 if (iothubtransport_amqp_methods_handle->message_sender == NULL)
AzureIoTClient 42:c2eaa912a28c 815 {
AzureIoTClient 42:c2eaa912a28c 816 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_036: [ If `messagesender_create` fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 817 LogError("Cannot create message sender");
AzureIoTClient 42:c2eaa912a28c 818 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 819 }
AzureIoTClient 42:c2eaa912a28c 820 else
AzureIoTClient 42:c2eaa912a28c 821 {
AzureIoTClient 42:c2eaa912a28c 822 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_037: [ `iothubtransportamqp_methods_subscribe` shall open the message sender by calling `messagesender_open`. ]*/
AzureIoTClient 42:c2eaa912a28c 823 if (messagesender_open(iothubtransport_amqp_methods_handle->message_sender) != 0)
AzureIoTClient 42:c2eaa912a28c 824 {
AzureIoTClient 42:c2eaa912a28c 825 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_038: [ If `messagesender_open` fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 826 LogError("Cannot open the message sender");
AzureIoTClient 42:c2eaa912a28c 827 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 828 }
AzureIoTClient 42:c2eaa912a28c 829 else
AzureIoTClient 42:c2eaa912a28c 830 {
AzureIoTClient 42:c2eaa912a28c 831 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_039: [ `iothubtransportamqp_methods_subscribe` shall open the message sender by calling `messagereceiver_open`. ]*/
AzureIoTClient 42:c2eaa912a28c 832 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_104: [ An `on_message_received` callback together with its context shall be passed to `messagereceiver_open`. ]*/
AzureIoTClient 42:c2eaa912a28c 833 if (messagereceiver_open(iothubtransport_amqp_methods_handle->message_receiver, on_message_received, iothubtransport_amqp_methods_handle) != 0)
AzureIoTClient 42:c2eaa912a28c 834 {
AzureIoTClient 42:c2eaa912a28c 835 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_040: [ If `messagereceiver_open` fails, `iothubtransportamqp_methods_subscribe` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 836 LogError("Cannot open the message receiver");
AzureIoTClient 42:c2eaa912a28c 837 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 838 }
AzureIoTClient 42:c2eaa912a28c 839 else
AzureIoTClient 42:c2eaa912a28c 840 {
AzureIoTClient 42:c2eaa912a28c 841 iothubtransport_amqp_methods_handle->subscribe_state = SUBSCRIBE_STATE_SUBSCRIBED;
AzureIoTClient 42:c2eaa912a28c 842
AzureIoTClient 42:c2eaa912a28c 843 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_008: [ On success it shall return 0. ]*/
AzureIoTClient 42:c2eaa912a28c 844 result = 0;
AzureIoTClient 42:c2eaa912a28c 845 }
AzureIoTClient 42:c2eaa912a28c 846 }
AzureIoTClient 42:c2eaa912a28c 847 }
AzureIoTClient 42:c2eaa912a28c 848 }
AzureIoTClient 42:c2eaa912a28c 849 }
AzureIoTClient 42:c2eaa912a28c 850 }
AzureIoTClient 42:c2eaa912a28c 851
AzureIoTClient 42:c2eaa912a28c 852 STRING_delete(responses_link_name);
AzureIoTClient 42:c2eaa912a28c 853 }
AzureIoTClient 42:c2eaa912a28c 854
AzureIoTClient 42:c2eaa912a28c 855 amqpvalue_destroy(sender_target);
AzureIoTClient 42:c2eaa912a28c 856 }
AzureIoTClient 42:c2eaa912a28c 857
AzureIoTClient 42:c2eaa912a28c 858 amqpvalue_destroy(sender_source);
AzureIoTClient 42:c2eaa912a28c 859 }
AzureIoTClient 42:c2eaa912a28c 860 }
AzureIoTClient 42:c2eaa912a28c 861
AzureIoTClient 42:c2eaa912a28c 862 STRING_delete(requests_link_name);
AzureIoTClient 42:c2eaa912a28c 863 }
AzureIoTClient 42:c2eaa912a28c 864
AzureIoTClient 42:c2eaa912a28c 865 amqpvalue_destroy(receiver_target);
AzureIoTClient 42:c2eaa912a28c 866 }
AzureIoTClient 42:c2eaa912a28c 867
AzureIoTClient 42:c2eaa912a28c 868 amqpvalue_destroy(receiver_source);
AzureIoTClient 42:c2eaa912a28c 869 }
AzureIoTClient 42:c2eaa912a28c 870
AzureIoTClient 42:c2eaa912a28c 871 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_105: [ The string created in order to hold the source and target addresses shall be freed by calling `STRING_delete`. ]*/
AzureIoTClient 42:c2eaa912a28c 872 STRING_delete(peer_endpoint_string);
AzureIoTClient 42:c2eaa912a28c 873 }
AzureIoTClient 42:c2eaa912a28c 874 }
AzureIoTClient 42:c2eaa912a28c 875
AzureIoTClient 42:c2eaa912a28c 876 return result;
AzureIoTClient 42:c2eaa912a28c 877 }
AzureIoTClient 42:c2eaa912a28c 878
AzureIoTClient 42:c2eaa912a28c 879 void iothubtransportamqp_methods_unsubscribe(IOTHUBTRANSPORT_AMQP_METHODS_HANDLE iothubtransport_amqp_methods_handle)
AzureIoTClient 42:c2eaa912a28c 880 {
AzureIoTClient 42:c2eaa912a28c 881 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_072: [ If the argument `iothubtransport_amqp_methods_handle` is NULL, `iothubtransportamqp_methods_unsubscribe` shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 882 if (iothubtransport_amqp_methods_handle == NULL)
AzureIoTClient 42:c2eaa912a28c 883 {
AzureIoTClient 42:c2eaa912a28c 884 LogError("NULL handle");
AzureIoTClient 42:c2eaa912a28c 885 }
AzureIoTClient 42:c2eaa912a28c 886 else
AzureIoTClient 42:c2eaa912a28c 887 {
AzureIoTClient 42:c2eaa912a28c 888 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_135: [ If subscribe was not called yet, `iothubtransportamqp_methods_unsubscribe` shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 889 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_136: [ `iothubtransportamqp_methods_unsubscribe` after `iothubtransportamqp_methods_unsubscribe` shall do nothing. ]*/
AzureIoTClient 42:c2eaa912a28c 890 if (iothubtransport_amqp_methods_handle->subscribe_state != SUBSCRIBE_STATE_SUBSCRIBED)
AzureIoTClient 42:c2eaa912a28c 891 {
AzureIoTClient 42:c2eaa912a28c 892 LogError("unsubscribe called while not subscribed");
AzureIoTClient 42:c2eaa912a28c 893 }
AzureIoTClient 42:c2eaa912a28c 894 else
AzureIoTClient 42:c2eaa912a28c 895 {
AzureIoTClient 42:c2eaa912a28c 896 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_073: [ Otherwise `iothubtransportamqp_methods_unsubscribe` shall free all resources allocated in `iothubtransportamqp_methods_subscribe`: ]*/
AzureIoTClient 42:c2eaa912a28c 897 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_075: [ - It shall free the message receiver by calling `messagereceiver_destroy'. ]*/
AzureIoTClient 42:c2eaa912a28c 898 messagereceiver_destroy(iothubtransport_amqp_methods_handle->message_receiver);
AzureIoTClient 42:c2eaa912a28c 899 iothubtransport_amqp_methods_handle->message_receiver = NULL;
AzureIoTClient 42:c2eaa912a28c 900 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_074: [ - It shall free the message sender by calling `messagesender_destroy'. ]*/
AzureIoTClient 42:c2eaa912a28c 901 messagesender_destroy(iothubtransport_amqp_methods_handle->message_sender);
AzureIoTClient 42:c2eaa912a28c 902 iothubtransport_amqp_methods_handle->message_sender = NULL;
AzureIoTClient 42:c2eaa912a28c 903 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_076: [ - It shall free the sender link by calling `link_destroy'. ]*/
AzureIoTClient 42:c2eaa912a28c 904 link_destroy(iothubtransport_amqp_methods_handle->sender_link);
AzureIoTClient 42:c2eaa912a28c 905 iothubtransport_amqp_methods_handle->sender_link = NULL;
AzureIoTClient 42:c2eaa912a28c 906 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_077: [ - It shall free the receiver link by calling `link_destroy'. ]*/
AzureIoTClient 42:c2eaa912a28c 907 link_destroy(iothubtransport_amqp_methods_handle->receiver_link);
AzureIoTClient 42:c2eaa912a28c 908 iothubtransport_amqp_methods_handle->receiver_link = NULL;
AzureIoTClient 42:c2eaa912a28c 909
AzureIoTClient 42:c2eaa912a28c 910 iothubtransport_amqp_methods_handle->subscribe_state = SUBSCRIBE_STATE_NOT_SUBSCRIBED;
AzureIoTClient 42:c2eaa912a28c 911 }
AzureIoTClient 42:c2eaa912a28c 912 }
AzureIoTClient 42:c2eaa912a28c 913 }
AzureIoTClient 42:c2eaa912a28c 914
AzureIoTClient 42:c2eaa912a28c 915 int iothubtransportamqp_methods_respond(IOTHUBTRANSPORT_AMQP_METHOD_HANDLE method_handle, const unsigned char* response, size_t response_size, int status_code)
AzureIoTClient 42:c2eaa912a28c 916 {
AzureIoTClient 42:c2eaa912a28c 917 int result;
AzureIoTClient 42:c2eaa912a28c 918
AzureIoTClient 42:c2eaa912a28c 919 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_107: [ If the argument `method_handle` is NULL, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 920 if (method_handle == NULL)
AzureIoTClient 42:c2eaa912a28c 921 {
AzureIoTClient 42:c2eaa912a28c 922 LogError("NULL method handle");
AzureIoTClient 42:c2eaa912a28c 923 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 924 }
AzureIoTClient 42:c2eaa912a28c 925 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_108: [ If `response_size` is greater than zero and `response` is NULL, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 926 else if ((response == NULL) && (response_size > 0))
AzureIoTClient 42:c2eaa912a28c 927 {
AzureIoTClient 42:c2eaa912a28c 928 LogError("NULL response buffer with > 0 response payload size");
AzureIoTClient 42:c2eaa912a28c 929 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 930 }
AzureIoTClient 42:c2eaa912a28c 931 else
AzureIoTClient 42:c2eaa912a28c 932 {
AzureIoTClient 42:c2eaa912a28c 933 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_061: [ - A new uAMQP message shall be created by calling `message_create`. ]*/
AzureIoTClient 42:c2eaa912a28c 934 MESSAGE_HANDLE message = message_create();
AzureIoTClient 42:c2eaa912a28c 935 if (message == NULL)
AzureIoTClient 42:c2eaa912a28c 936 {
AzureIoTClient 42:c2eaa912a28c 937 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_062: [ If the `message_create` call fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 938 LogError("Cannot create message");
AzureIoTClient 42:c2eaa912a28c 939 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 940 }
AzureIoTClient 42:c2eaa912a28c 941 else
AzureIoTClient 42:c2eaa912a28c 942 {
AzureIoTClient 42:c2eaa912a28c 943 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_063: [ - A new properties handle shall be created by calling `properties_create`. ]*/
AzureIoTClient 42:c2eaa912a28c 944 PROPERTIES_HANDLE properties = properties_create();
AzureIoTClient 42:c2eaa912a28c 945 if (properties == NULL)
AzureIoTClient 42:c2eaa912a28c 946 {
AzureIoTClient 42:c2eaa912a28c 947 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_064: [ If the `properties_create call` fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 948 LogError("Cannot create properties");
AzureIoTClient 42:c2eaa912a28c 949 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 950 }
AzureIoTClient 42:c2eaa912a28c 951 else
AzureIoTClient 42:c2eaa912a28c 952 {
AzureIoTClient 42:c2eaa912a28c 953 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_124: [ - An AMQP value holding the correlation id associated with the `method_handle` handle shall be created by calling `amqpvalue_create_uuid`. ]*/
AzureIoTClient 42:c2eaa912a28c 954 AMQP_VALUE correlation_id = amqpvalue_create_uuid(method_handle->correlation_id);
AzureIoTClient 42:c2eaa912a28c 955 if (correlation_id == NULL)
AzureIoTClient 42:c2eaa912a28c 956 {
AzureIoTClient 42:c2eaa912a28c 957 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_125: [ If `amqpvalue_create_uuid` fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 958 LogError("Cannot create correlation_id value");
AzureIoTClient 42:c2eaa912a28c 959 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 960 }
AzureIoTClient 42:c2eaa912a28c 961 else
AzureIoTClient 42:c2eaa912a28c 962 {
AzureIoTClient 42:c2eaa912a28c 963 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_065: [ - The correlation id on the message properties shall be set by calling `properties_set_correlation_id` and passing as argument the already create correlation ID AMQP value. ]*/
AzureIoTClient 42:c2eaa912a28c 964 if (properties_set_correlation_id(properties, correlation_id) != 0)
AzureIoTClient 42:c2eaa912a28c 965 {
AzureIoTClient 42:c2eaa912a28c 966 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_066: [ If the `properties_set_correlation_id` call fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 967 LogError("Cannot set correlation_id on the properties");
AzureIoTClient 42:c2eaa912a28c 968 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 969 }
AzureIoTClient 42:c2eaa912a28c 970 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_148: [ The properties shall be set on the message by calling `message_set_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 971 else if (message_set_properties(message, properties) != 0)
AzureIoTClient 42:c2eaa912a28c 972 {
AzureIoTClient 42:c2eaa912a28c 973 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_149: [ If `message_set_properties` fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 974 LogError("Cannot set properties on the response message");
AzureIoTClient 42:c2eaa912a28c 975 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 976 }
AzureIoTClient 42:c2eaa912a28c 977 else
AzureIoTClient 42:c2eaa912a28c 978 {
AzureIoTClient 42:c2eaa912a28c 979 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_090: [ An AMQP map shall be created to hold the application properties for the response by calling `amqpvalue_create_map`. ]*/
AzureIoTClient 42:c2eaa912a28c 980 AMQP_VALUE application_properties_map = amqpvalue_create_map();
AzureIoTClient 42:c2eaa912a28c 981 if (application_properties_map == NULL)
AzureIoTClient 42:c2eaa912a28c 982 {
AzureIoTClient 42:c2eaa912a28c 983 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_096: [ If any of the calls `amqpvalue_create_string`, `amqpvalue_create_int`, `amqpvalue_create_map`, `amqpvalue_set_map_value` or `message_set_application_properties` fails `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 984 LogError("Cannot create map for application properties");
AzureIoTClient 42:c2eaa912a28c 985 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 986 }
AzureIoTClient 42:c2eaa912a28c 987 else
AzureIoTClient 42:c2eaa912a28c 988 {
AzureIoTClient 42:c2eaa912a28c 989 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_091: [ A property key `IoThub-status` shall be created by calling `amqpvalue_create_string`. ]*/
AzureIoTClient 42:c2eaa912a28c 990 AMQP_VALUE property_key_status = amqpvalue_create_string("IoThub-status");
AzureIoTClient 42:c2eaa912a28c 991 if (property_key_status == NULL)
AzureIoTClient 42:c2eaa912a28c 992 {
AzureIoTClient 42:c2eaa912a28c 993 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_096: [ If any of the calls `amqpvalue_create_string`, `amqpvalue_create_int`, `amqpvalue_create_map`, `amqpvalue_set_map_value` or `message_set_application_properties` fails `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 994 LogError("Cannot create the property key for the status property");
AzureIoTClient 42:c2eaa912a28c 995 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 996 }
AzureIoTClient 42:c2eaa912a28c 997 else
AzureIoTClient 42:c2eaa912a28c 998 {
AzureIoTClient 42:c2eaa912a28c 999 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_097: [ A property value of type int shall be created from the `status_code` argument by calling `amqpvalue_create_int`. ] ]*/
AzureIoTClient 42:c2eaa912a28c 1000 AMQP_VALUE property_value_status = amqpvalue_create_int(status_code);
AzureIoTClient 42:c2eaa912a28c 1001 if (property_value_status == NULL)
AzureIoTClient 42:c2eaa912a28c 1002 {
AzureIoTClient 42:c2eaa912a28c 1003 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_096: [ If any of the calls `amqpvalue_create_string`, `amqpvalue_create_int`, `amqpvalue_create_map`, `amqpvalue_set_map_value` or `message_set_application_properties` fails `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 1004 LogError("Cannot create the status code property value for the application properties map");
AzureIoTClient 42:c2eaa912a28c 1005 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 1006 }
AzureIoTClient 42:c2eaa912a28c 1007 else
AzureIoTClient 42:c2eaa912a28c 1008 {
AzureIoTClient 42:c2eaa912a28c 1009 /* Cdoes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_093: [ A new entry shall be added in the application properties map by calling `amqpvalue_set_map_value` and passing the key and value that were previously created. ]*/
AzureIoTClient 42:c2eaa912a28c 1010 if (amqpvalue_set_map_value(application_properties_map, property_key_status, property_value_status) != 0)
AzureIoTClient 42:c2eaa912a28c 1011 {
AzureIoTClient 42:c2eaa912a28c 1012 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_096: [ If any of the calls `amqpvalue_create_string`, `amqpvalue_create_int`, `amqpvalue_create_map`, `amqpvalue_set_map_value` or `message_set_application_properties` fails `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 1013 LogError("Cannot add the status property to the application properties");
AzureIoTClient 42:c2eaa912a28c 1014 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 1015 }
AzureIoTClient 42:c2eaa912a28c 1016 else
AzureIoTClient 42:c2eaa912a28c 1017 {
AzureIoTClient 42:c2eaa912a28c 1018 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_094: [ The application properties map shall be set on the response message by calling `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1019 if (message_set_application_properties(message, application_properties_map) != 0)
AzureIoTClient 42:c2eaa912a28c 1020 {
AzureIoTClient 42:c2eaa912a28c 1021 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_096: [ If any of the calls `amqpvalue_create_string`, `amqpvalue_create_int`, `amqpvalue_create_map`, `amqpvalue_set_map_value` or `message_set_application_properties` fails `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 1022 LogError("Cannot set the application properties on the message");
AzureIoTClient 42:c2eaa912a28c 1023 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 1024 }
AzureIoTClient 42:c2eaa912a28c 1025 else
AzureIoTClient 42:c2eaa912a28c 1026 {
AzureIoTClient 42:c2eaa912a28c 1027 BINARY_DATA binary_data;
AzureIoTClient 42:c2eaa912a28c 1028
AzureIoTClient 42:c2eaa912a28c 1029 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_079: [ The field `bytes` of the `binary_data` argument shall be set to the `response` argument value. ]*/
AzureIoTClient 42:c2eaa912a28c 1030 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_080: [ The field `length` of the `binary_data` argument shall be set to the `response_size` argument value. ]*/
AzureIoTClient 42:c2eaa912a28c 1031 binary_data.bytes = response;
AzureIoTClient 42:c2eaa912a28c 1032 binary_data.length = response_size;
AzureIoTClient 42:c2eaa912a28c 1033
AzureIoTClient 42:c2eaa912a28c 1034 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_078: [ The binary payload for the response shall be set by calling `message_add_body_amqp_data` for the newly created message handle. ]*/
AzureIoTClient 42:c2eaa912a28c 1035 if (message_add_body_amqp_data(message, binary_data) != 0)
AzureIoTClient 42:c2eaa912a28c 1036 {
AzureIoTClient 42:c2eaa912a28c 1037 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_081: [ If the `message_add_body_amqp_data` call fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 1038 LogError("Cannot set the response payload on the reponse message");
AzureIoTClient 42:c2eaa912a28c 1039 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 1040 }
AzureIoTClient 42:c2eaa912a28c 1041 else
AzureIoTClient 42:c2eaa912a28c 1042 {
AzureIoTClient 42:c2eaa912a28c 1043 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_067: [ The message shall be handed over to the message_sender by calling `messagesender_send` and passing as arguments: ]*/
AzureIoTClient 42:c2eaa912a28c 1044 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_068: [ - The response message handle. ]*/
AzureIoTClient 42:c2eaa912a28c 1045 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_069: [ - A send callback and its context for the `on_message_send_complete` callback. ]*/
AzureIoTClient 43:3da2d93bb955 1046 if (messagesender_send_async(method_handle->iothubtransport_amqp_methods_handle->message_sender, message, on_message_send_complete, method_handle->iothubtransport_amqp_methods_handle, 0) == NULL)
AzureIoTClient 42:c2eaa912a28c 1047 {
AzureIoTClient 42:c2eaa912a28c 1048 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_071: [ If the `messagesender_send` call fails, `iothubtransportamqp_methods_respond` shall fail and return a non-zero value. ]*/
AzureIoTClient 42:c2eaa912a28c 1049 LogError("Cannot send response message");
AzureIoTClient 42:c2eaa912a28c 1050 result = __FAILURE__;
AzureIoTClient 42:c2eaa912a28c 1051 }
AzureIoTClient 42:c2eaa912a28c 1052 else
AzureIoTClient 42:c2eaa912a28c 1053 {
AzureIoTClient 42:c2eaa912a28c 1054 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_114: [ The handle `method_handle` shall be removed from the array used to track the method handles. ]*/
AzureIoTClient 42:c2eaa912a28c 1055 remove_tracked_handle(method_handle->iothubtransport_amqp_methods_handle, method_handle);
AzureIoTClient 42:c2eaa912a28c 1056
AzureIoTClient 42:c2eaa912a28c 1057 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_111: [ The handle `method_handle` shall be freed (have no meaning) after `iothubtransportamqp_methods_respond` has been executed. ]*/
AzureIoTClient 42:c2eaa912a28c 1058 free(method_handle);
AzureIoTClient 42:c2eaa912a28c 1059
AzureIoTClient 42:c2eaa912a28c 1060 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_060: [ `iothubtransportamqp_methods_respond` shall construct a response message and on success it shall return 0. ]*/
AzureIoTClient 42:c2eaa912a28c 1061 result = 0;
AzureIoTClient 42:c2eaa912a28c 1062 }
AzureIoTClient 42:c2eaa912a28c 1063 }
AzureIoTClient 42:c2eaa912a28c 1064 }
AzureIoTClient 42:c2eaa912a28c 1065 }
AzureIoTClient 42:c2eaa912a28c 1066
AzureIoTClient 42:c2eaa912a28c 1067 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1068 amqpvalue_destroy(property_value_status);
AzureIoTClient 42:c2eaa912a28c 1069 }
AzureIoTClient 42:c2eaa912a28c 1070
AzureIoTClient 42:c2eaa912a28c 1071 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1072 amqpvalue_destroy(property_key_status);
AzureIoTClient 42:c2eaa912a28c 1073 }
AzureIoTClient 42:c2eaa912a28c 1074
AzureIoTClient 42:c2eaa912a28c 1075 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1076 amqpvalue_destroy(application_properties_map);
AzureIoTClient 42:c2eaa912a28c 1077 }
AzureIoTClient 42:c2eaa912a28c 1078 }
AzureIoTClient 42:c2eaa912a28c 1079
AzureIoTClient 42:c2eaa912a28c 1080 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1081 amqpvalue_destroy(correlation_id);
AzureIoTClient 42:c2eaa912a28c 1082 }
AzureIoTClient 42:c2eaa912a28c 1083
AzureIoTClient 42:c2eaa912a28c 1084 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1085 properties_destroy(properties);
AzureIoTClient 42:c2eaa912a28c 1086 }
AzureIoTClient 42:c2eaa912a28c 1087
AzureIoTClient 42:c2eaa912a28c 1088 /* Codes_SRS_IOTHUBTRANSPORT_AMQP_METHODS_01_095: [ The application property map and all intermediate values shall be freed after being passed to `message_set_application_properties`. ]*/
AzureIoTClient 42:c2eaa912a28c 1089 message_destroy(message);
AzureIoTClient 42:c2eaa912a28c 1090 }
AzureIoTClient 42:c2eaa912a28c 1091 }
AzureIoTClient 42:c2eaa912a28c 1092
AzureIoTClient 42:c2eaa912a28c 1093 return result;
AzureIoTClient 42:c2eaa912a28c 1094 }