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
iothubtransportamqp_methods.c@57:56ac1346c70d, 2018-10-04 (annotated)
- 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?
User | Revision | Line number | New 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 | } |