Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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