Microsoft Azure IoTHub client AMQP transport

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp iothub_client_sample_amqp ... more

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

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AzureIoTClient 30:20a85b733111 1 // Copyright (c) Microsoft. All rights reserved.
AzureIoTClient 30:20a85b733111 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
AzureIoTClient 30:20a85b733111 3
AzureIoTClient 30:20a85b733111 4 #include <stdlib.h>
AzureIoTClient 30:20a85b733111 5 #include <limits.h>
AzureIoTClient 53:e21e1e88460f 6 #include "internal/iothubtransport_amqp_connection.h"
AzureIoTClient 30:20a85b733111 7 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 30:20a85b733111 8 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 30:20a85b733111 9 #include "azure_c_shared_utility/strings.h"
AzureIoTClient 30:20a85b733111 10 #include "azure_c_shared_utility/uniqueid.h"
AzureIoTClient 30:20a85b733111 11 #include "azure_uamqp_c/sasl_mechanism.h"
AzureIoTClient 30:20a85b733111 12 #include "azure_uamqp_c/saslclientio.h"
AzureIoTClient 30:20a85b733111 13 #include "azure_uamqp_c/sasl_mssbcbs.h"
AzureIoTClient 30:20a85b733111 14 #include "azure_uamqp_c/connection.h"
AzureIoTClient 41:71c01aa3df1a 15 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 30:20a85b733111 16
AzureIoTClient 30:20a85b733111 17 #define RESULT_OK 0
AzureIoTClient 30:20a85b733111 18 #define DEFAULT_INCOMING_WINDOW_SIZE UINT_MAX
AzureIoTClient 30:20a85b733111 19 #define DEFAULT_OUTGOING_WINDOW_SIZE 100
AzureIoTClient 30:20a85b733111 20 #define SASL_IO_OPTION_LOG_TRACE "logtrace"
AzureIoTClient 30:20a85b733111 21 #define DEFAULT_UNIQUE_ID_LENGTH 40
AzureIoTClient 30:20a85b733111 22
AzureIoTClient 30:20a85b733111 23 typedef struct AMQP_CONNECTION_INSTANCE_TAG
AzureIoTClient 30:20a85b733111 24 {
AzureIoTClient 41:71c01aa3df1a 25 STRING_HANDLE iothub_fqdn;
AzureIoTClient 41:71c01aa3df1a 26 XIO_HANDLE underlying_io_transport;
AzureIoTClient 41:71c01aa3df1a 27 CBS_HANDLE cbs_handle;
AzureIoTClient 41:71c01aa3df1a 28 CONNECTION_HANDLE connection_handle;
AzureIoTClient 41:71c01aa3df1a 29 SESSION_HANDLE session_handle;
AzureIoTClient 41:71c01aa3df1a 30 XIO_HANDLE sasl_io;
AzureIoTClient 41:71c01aa3df1a 31 SASL_MECHANISM_HANDLE sasl_mechanism;
AzureIoTClient 46:c688c75b63b9 32 bool has_cbs;
AzureIoTClient 46:c688c75b63b9 33 bool has_sasl_mechanism;
AzureIoTClient 41:71c01aa3df1a 34 bool is_trace_on;
AzureIoTClient 41:71c01aa3df1a 35 AMQP_CONNECTION_STATE current_state;
AzureIoTClient 41:71c01aa3df1a 36 ON_AMQP_CONNECTION_STATE_CHANGED on_state_changed_callback;
AzureIoTClient 41:71c01aa3df1a 37 const void* on_state_changed_context;
AzureIoTClient 47:8a238e75a0f7 38 uint32_t svc2cl_keep_alive_timeout_secs;
AzureIoTClient 47:8a238e75a0f7 39 double cl2svc_keep_alive_send_ratio;
AzureIoTClient 30:20a85b733111 40 } AMQP_CONNECTION_INSTANCE;
AzureIoTClient 30:20a85b733111 41
AzureIoTClient 31:adadaef857c1 42
AzureIoTClient 31:adadaef857c1 43 DEFINE_ENUM_STRINGS(AMQP_CONNECTION_STATE, AMQP_CONNECTION_STATE_VALUES);
AzureIoTClient 31:adadaef857c1 44
AzureIoTClient 31:adadaef857c1 45
AzureIoTClient 30:20a85b733111 46 static int create_sasl_components(AMQP_CONNECTION_INSTANCE* instance)
AzureIoTClient 30:20a85b733111 47 {
AzureIoTClient 41:71c01aa3df1a 48 int result;
AzureIoTClient 41:71c01aa3df1a 49 SASL_MECHANISM_HANDLE sasl_mechanism;
AzureIoTClient 41:71c01aa3df1a 50 XIO_HANDLE sasl_io;
AzureIoTClient 30:20a85b733111 51
AzureIoTClient 41:71c01aa3df1a 52 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_012: [`instance->sasl_mechanism` shall be created using saslmechanism_create()]
AzureIoTClient 41:71c01aa3df1a 53 if ((sasl_mechanism = saslmechanism_create(saslmssbcbs_get_interface(), NULL)) == NULL)
AzureIoTClient 41:71c01aa3df1a 54 {
AzureIoTClient 41:71c01aa3df1a 55 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_013: [If saslmechanism_create() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 56 LogError("Failed creating the SASL mechanism (saslmechanism_create failed)");
AzureIoTClient 41:71c01aa3df1a 57 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 58 }
AzureIoTClient 41:71c01aa3df1a 59 else
AzureIoTClient 41:71c01aa3df1a 60 {
AzureIoTClient 41:71c01aa3df1a 61 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_014: [A SASLCLIENTIO_CONFIG shall be set with `instance->underlying_io_transport` and `instance->sasl_mechanism`]
AzureIoTClient 41:71c01aa3df1a 62 SASLCLIENTIO_CONFIG sasl_client_config;
AzureIoTClient 41:71c01aa3df1a 63 sasl_client_config.sasl_mechanism = sasl_mechanism;
AzureIoTClient 41:71c01aa3df1a 64 sasl_client_config.underlying_io = instance->underlying_io_transport;
AzureIoTClient 56:8704100b3b54 65
AzureIoTClient 41:71c01aa3df1a 66 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_015: [`instance->sasl_io` shall be created using xio_create() passing saslclientio_get_interface_description() and the SASLCLIENTIO_CONFIG instance]
AzureIoTClient 41:71c01aa3df1a 67 if ((sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_client_config)) == NULL)
AzureIoTClient 41:71c01aa3df1a 68 {
AzureIoTClient 41:71c01aa3df1a 69 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_016: [If xio_create() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 70 LogError("Failed creating the SASL I/O (xio_create failed)");
AzureIoTClient 41:71c01aa3df1a 71 saslmechanism_destroy(sasl_mechanism);
AzureIoTClient 41:71c01aa3df1a 72 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 73 }
AzureIoTClient 41:71c01aa3df1a 74 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_017: [The sasl_io "logtrace" option shall be set using xio_setoption(), passing `instance->is_trace_on`]
AzureIoTClient 41:71c01aa3df1a 75 else if (xio_setoption(sasl_io, SASL_IO_OPTION_LOG_TRACE, (const void*)&instance->is_trace_on) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 76 {
AzureIoTClient 41:71c01aa3df1a 77 LogError("Failed setting the SASL I/O logging trace option (xio_setoption failed)");
AzureIoTClient 41:71c01aa3df1a 78 xio_destroy(sasl_io);
AzureIoTClient 41:71c01aa3df1a 79 saslmechanism_destroy(sasl_mechanism);
AzureIoTClient 41:71c01aa3df1a 80 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 81 }
AzureIoTClient 41:71c01aa3df1a 82 else
AzureIoTClient 41:71c01aa3df1a 83 {
AzureIoTClient 41:71c01aa3df1a 84 instance->sasl_mechanism = sasl_mechanism;
AzureIoTClient 41:71c01aa3df1a 85 instance->sasl_io = sasl_io;
AzureIoTClient 41:71c01aa3df1a 86 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 87 }
AzureIoTClient 41:71c01aa3df1a 88 }
AzureIoTClient 30:20a85b733111 89
AzureIoTClient 41:71c01aa3df1a 90 return result;
AzureIoTClient 30:20a85b733111 91 }
AzureIoTClient 30:20a85b733111 92
AzureIoTClient 30:20a85b733111 93 static void update_state(AMQP_CONNECTION_INSTANCE* instance, AMQP_CONNECTION_STATE new_state)
AzureIoTClient 30:20a85b733111 94 {
AzureIoTClient 41:71c01aa3df1a 95 if (new_state != instance->current_state)
AzureIoTClient 41:71c01aa3df1a 96 {
AzureIoTClient 41:71c01aa3df1a 97 AMQP_CONNECTION_STATE previous_state = instance->current_state;
AzureIoTClient 41:71c01aa3df1a 98 instance->current_state = new_state;
AzureIoTClient 30:20a85b733111 99
AzureIoTClient 41:71c01aa3df1a 100 if (instance->on_state_changed_callback != NULL)
AzureIoTClient 41:71c01aa3df1a 101 {
AzureIoTClient 41:71c01aa3df1a 102 instance->on_state_changed_callback(instance->on_state_changed_context, previous_state, new_state);
AzureIoTClient 41:71c01aa3df1a 103 }
AzureIoTClient 41:71c01aa3df1a 104 }
AzureIoTClient 30:20a85b733111 105 }
AzureIoTClient 30:20a85b733111 106
AzureIoTClient 30:20a85b733111 107 static void on_connection_io_error(void* context)
AzureIoTClient 30:20a85b733111 108 {
AzureIoTClient 41:71c01aa3df1a 109 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_022: [If the connection calls back with an I/O error, `instance->on_state_changed_callback` shall be invoked if set passing code AMQP_CONNECTION_STATE_ERROR and `instance->on_state_changed_context`]
AzureIoTClient 41:71c01aa3df1a 110 update_state((AMQP_CONNECTION_INSTANCE*)context, AMQP_CONNECTION_STATE_ERROR);
AzureIoTClient 30:20a85b733111 111 }
AzureIoTClient 30:20a85b733111 112
AzureIoTClient 30:20a85b733111 113 static void on_connection_state_changed(void* context, CONNECTION_STATE new_connection_state, CONNECTION_STATE previous_connection_state)
AzureIoTClient 30:20a85b733111 114 {
AzureIoTClient 41:71c01aa3df1a 115 (void)previous_connection_state;
AzureIoTClient 30:20a85b733111 116
AzureIoTClient 41:71c01aa3df1a 117 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)context;
AzureIoTClient 30:20a85b733111 118
AzureIoTClient 41:71c01aa3df1a 119 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_063: [If `on_connection_state_changed` is called back, `instance->on_state_changed_callback` shall be invoked, if defined]
AzureIoTClient 46:c688c75b63b9 120 if (new_connection_state == CONNECTION_STATE_START)
AzureIoTClient 41:71c01aa3df1a 121 {
AzureIoTClient 41:71c01aa3df1a 122 // connection is using x509 authentication.
AzureIoTClient 41:71c01aa3df1a 123 // At this point uamqp's connection only raises CONNECTION_STATE_START when using X509 auth.
AzureIoTClient 41:71c01aa3df1a 124 // So that should be all we expect to consider the amqp_connection_handle opened.
AzureIoTClient 46:c688c75b63b9 125 if (instance->has_cbs == false || instance->has_sasl_mechanism == false)
AzureIoTClient 41:71c01aa3df1a 126 {
AzureIoTClient 41:71c01aa3df1a 127 update_state(instance, AMQP_CONNECTION_STATE_OPENED);
AzureIoTClient 41:71c01aa3df1a 128 }
AzureIoTClient 41:71c01aa3df1a 129 }
AzureIoTClient 41:71c01aa3df1a 130 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_064: [If `on_connection_state_changed` new state is CONNECTION_STATE_OPENED, `instance->on_state_changed_callback` shall be invoked with state AMQP_CONNECTION_STATE_OPENED]
AzureIoTClient 41:71c01aa3df1a 131 else if (new_connection_state == CONNECTION_STATE_OPENED)
AzureIoTClient 41:71c01aa3df1a 132 {
AzureIoTClient 41:71c01aa3df1a 133 update_state(instance, AMQP_CONNECTION_STATE_OPENED);
AzureIoTClient 41:71c01aa3df1a 134 }
AzureIoTClient 41:71c01aa3df1a 135 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_065: [If `on_connection_state_changed` new state is CONNECTION_STATE_END, `instance->on_state_changed_callback` shall be invoked with state AMQP_CONNECTION_STATE_CLOSED]
AzureIoTClient 41:71c01aa3df1a 136 else if (new_connection_state == CONNECTION_STATE_END)
AzureIoTClient 41:71c01aa3df1a 137 {
AzureIoTClient 41:71c01aa3df1a 138 update_state(instance, AMQP_CONNECTION_STATE_CLOSED);
AzureIoTClient 41:71c01aa3df1a 139 }
AzureIoTClient 41:71c01aa3df1a 140 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_071: [If `on_connection_state_changed` new state is CONNECTION_STATE_ERROR or CONNECTION_STATE_DISCARDING, `instance->on_state_changed_callback` shall be invoked with state AMQP_CONNECTION_STATE_ERROR]
AzureIoTClient 41:71c01aa3df1a 141 else if (new_connection_state == CONNECTION_STATE_ERROR || new_connection_state == CONNECTION_STATE_DISCARDING)
AzureIoTClient 41:71c01aa3df1a 142 {
AzureIoTClient 41:71c01aa3df1a 143 update_state(instance, AMQP_CONNECTION_STATE_ERROR);
AzureIoTClient 41:71c01aa3df1a 144 }
AzureIoTClient 30:20a85b733111 145 }
AzureIoTClient 30:20a85b733111 146
AzureIoTClient 31:adadaef857c1 147 static void on_cbs_open_complete(void* context, CBS_OPEN_COMPLETE_RESULT open_complete_result)
AzureIoTClient 31:adadaef857c1 148 {
AzureIoTClient 31:adadaef857c1 149 (void)context;
AzureIoTClient 31:adadaef857c1 150 (void)open_complete_result;
AzureIoTClient 31:adadaef857c1 151 if (open_complete_result != CBS_OPEN_OK)
AzureIoTClient 31:adadaef857c1 152 {
AzureIoTClient 31:adadaef857c1 153 LogError("CBS open failed");
AzureIoTClient 31:adadaef857c1 154 }
AzureIoTClient 31:adadaef857c1 155 }
AzureIoTClient 31:adadaef857c1 156
AzureIoTClient 31:adadaef857c1 157 static void on_cbs_error(void* context)
AzureIoTClient 31:adadaef857c1 158 {
AzureIoTClient 31:adadaef857c1 159 (void)context;
AzureIoTClient 31:adadaef857c1 160 LogError("CBS Error occured");
AzureIoTClient 31:adadaef857c1 161 }
AzureIoTClient 31:adadaef857c1 162
AzureIoTClient 30:20a85b733111 163 static int create_connection_handle(AMQP_CONNECTION_INSTANCE* instance)
AzureIoTClient 30:20a85b733111 164 {
AzureIoTClient 41:71c01aa3df1a 165 int result;
AzureIoTClient 41:71c01aa3df1a 166 char* unique_container_id = NULL;
AzureIoTClient 41:71c01aa3df1a 167 XIO_HANDLE connection_io_transport;
AzureIoTClient 30:20a85b733111 168
AzureIoTClient 41:71c01aa3df1a 169 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_007: [If `instance->sasl_io` is defined it shall be used as parameter `xio` in connection_create2()]
AzureIoTClient 41:71c01aa3df1a 170 if (instance->sasl_io != NULL)
AzureIoTClient 41:71c01aa3df1a 171 {
AzureIoTClient 41:71c01aa3df1a 172 connection_io_transport = instance->sasl_io;
AzureIoTClient 41:71c01aa3df1a 173 }
AzureIoTClient 41:71c01aa3df1a 174 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_018: [If `instance->sasl_io` is not defined, `instance->underlying_io_transport` shall be used as parameter `xio` in connection_create2()]
AzureIoTClient 41:71c01aa3df1a 175 else
AzureIoTClient 41:71c01aa3df1a 176 {
AzureIoTClient 41:71c01aa3df1a 177 connection_io_transport = instance->underlying_io_transport;
AzureIoTClient 41:71c01aa3df1a 178 }
AzureIoTClient 30:20a85b733111 179
AzureIoTClient 41:71c01aa3df1a 180 if ((unique_container_id = (char*)malloc(sizeof(char) * DEFAULT_UNIQUE_ID_LENGTH + 1)) == NULL)
AzureIoTClient 41:71c01aa3df1a 181 {
AzureIoTClient 41:71c01aa3df1a 182 result = __LINE__;
AzureIoTClient 41:71c01aa3df1a 183 LogError("Failed creating the AMQP connection (failed creating unique ID container)");
AzureIoTClient 41:71c01aa3df1a 184 }
AzureIoTClient 41:71c01aa3df1a 185 else
AzureIoTClient 41:71c01aa3df1a 186 {
AzureIoTClient 41:71c01aa3df1a 187 memset(unique_container_id, 0, sizeof(char) * DEFAULT_UNIQUE_ID_LENGTH + 1);
AzureIoTClient 30:20a85b733111 188
AzureIoTClient 41:71c01aa3df1a 189 if (UniqueId_Generate(unique_container_id, DEFAULT_UNIQUE_ID_LENGTH) != UNIQUEID_OK)
AzureIoTClient 41:71c01aa3df1a 190 {
AzureIoTClient 41:71c01aa3df1a 191 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 192 LogError("Failed creating the AMQP connection (UniqueId_Generate failed)");
AzureIoTClient 41:71c01aa3df1a 193 }
AzureIoTClient 41:71c01aa3df1a 194 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_019: [`instance->connection_handle` shall be created using connection_create2(), passing the `connection_underlying_io`, `instance->iothub_host_fqdn` and an unique string as container ID]
AzureIoTClient 41:71c01aa3df1a 195 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_020: [connection_create2() shall also receive `on_connection_state_changed` and `on_connection_error` callback functions]
AzureIoTClient 41:71c01aa3df1a 196 else if ((instance->connection_handle = connection_create2(connection_io_transport, STRING_c_str(instance->iothub_fqdn), unique_container_id, NULL, NULL, on_connection_state_changed, (void*)instance, on_connection_io_error, (void*)instance)) == NULL)
AzureIoTClient 41:71c01aa3df1a 197 {
AzureIoTClient 41:71c01aa3df1a 198 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_021: [If connection_create2() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 199 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 200 LogError("Failed creating the AMQP connection (connection_create2 failed)");
AzureIoTClient 41:71c01aa3df1a 201 }
AzureIoTClient 47:8a238e75a0f7 202 else if (connection_set_idle_timeout(instance->connection_handle, 1000 * instance->svc2cl_keep_alive_timeout_secs) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 203 {
AzureIoTClient 41:71c01aa3df1a 204 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_074: [If connection_set_idle_timeout() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 205 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 206 LogError("Failed creating the AMQP connection (connection_set_idle_timeout failed)");
AzureIoTClient 41:71c01aa3df1a 207 }
AzureIoTClient 56:8704100b3b54 208 else if (connection_set_remote_idle_timeout_empty_frame_send_ratio(instance->connection_handle, instance->cl2svc_keep_alive_send_ratio) != RESULT_OK)
AzureIoTClient 56:8704100b3b54 209 {
AzureIoTClient 56:8704100b3b54 210 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_99_001: [If connection_set_remote_idle_timeout_empty_frame_send_ratio fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 56:8704100b3b54 211 result = __FAILURE__;
AzureIoTClient 56:8704100b3b54 212 LogError("Failed creating the AMQP connection (connection_set_remote_idle_timeout_empty_frame_send_ratio)");
AzureIoTClient 47:8a238e75a0f7 213 }
AzureIoTClient 41:71c01aa3df1a 214 else
AzureIoTClient 41:71c01aa3df1a 215 {
AzureIoTClient 41:71c01aa3df1a 216 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_023: [The connection tracing shall be set using connection_set_trace(), passing `instance->is_trace_on`]
AzureIoTClient 41:71c01aa3df1a 217 connection_set_trace(instance->connection_handle, instance->is_trace_on);
AzureIoTClient 30:20a85b733111 218
AzureIoTClient 41:71c01aa3df1a 219 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 220 }
AzureIoTClient 41:71c01aa3df1a 221 }
AzureIoTClient 30:20a85b733111 222
AzureIoTClient 41:71c01aa3df1a 223 if (unique_container_id != NULL)
AzureIoTClient 41:71c01aa3df1a 224 {
AzureIoTClient 41:71c01aa3df1a 225 free(unique_container_id);
AzureIoTClient 41:71c01aa3df1a 226 }
AzureIoTClient 30:20a85b733111 227
AzureIoTClient 41:71c01aa3df1a 228 return result;
AzureIoTClient 30:20a85b733111 229 }
AzureIoTClient 30:20a85b733111 230
AzureIoTClient 30:20a85b733111 231 static int create_session_handle(AMQP_CONNECTION_INSTANCE* instance)
AzureIoTClient 30:20a85b733111 232 {
AzureIoTClient 41:71c01aa3df1a 233 int result;
AzureIoTClient 30:20a85b733111 234
AzureIoTClient 41:71c01aa3df1a 235 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_024: [`instance->session_handle` shall be created using session_create(), passing `instance->connection_handle`]
AzureIoTClient 41:71c01aa3df1a 236 if ((instance->session_handle = session_create(instance->connection_handle, NULL, NULL)) == NULL)
AzureIoTClient 41:71c01aa3df1a 237 {
AzureIoTClient 41:71c01aa3df1a 238 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_025: [If session_create() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 239 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 240 LogError("Failed creating the AMQP connection (connection_create2 failed)");
AzureIoTClient 41:71c01aa3df1a 241 }
AzureIoTClient 41:71c01aa3df1a 242 else
AzureIoTClient 41:71c01aa3df1a 243 {
AzureIoTClient 41:71c01aa3df1a 244 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_026: [The `instance->session_handle` incoming window size shall be set as UINT_MAX using session_set_incoming_window()]
AzureIoTClient 41:71c01aa3df1a 245 if (session_set_incoming_window(instance->session_handle, (uint32_t)DEFAULT_INCOMING_WINDOW_SIZE) != 0)
AzureIoTClient 41:71c01aa3df1a 246 {
AzureIoTClient 41:71c01aa3df1a 247 LogError("Failed to set the AMQP session incoming window size.");
AzureIoTClient 41:71c01aa3df1a 248 }
AzureIoTClient 30:20a85b733111 249
AzureIoTClient 41:71c01aa3df1a 250 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_027: [The `instance->session_handle` outgoing window size shall be set as 100 using session_set_outgoing_window()]
AzureIoTClient 41:71c01aa3df1a 251 if (session_set_outgoing_window(instance->session_handle, DEFAULT_OUTGOING_WINDOW_SIZE) != 0)
AzureIoTClient 41:71c01aa3df1a 252 {
AzureIoTClient 41:71c01aa3df1a 253 LogError("Failed to set the AMQP session outgoing window size.");
AzureIoTClient 41:71c01aa3df1a 254 }
AzureIoTClient 30:20a85b733111 255
AzureIoTClient 41:71c01aa3df1a 256 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 257 }
AzureIoTClient 56:8704100b3b54 258
AzureIoTClient 41:71c01aa3df1a 259 return result;
AzureIoTClient 30:20a85b733111 260 }
AzureIoTClient 30:20a85b733111 261
AzureIoTClient 30:20a85b733111 262 static int create_cbs_handle(AMQP_CONNECTION_INSTANCE* instance)
AzureIoTClient 30:20a85b733111 263 {
AzureIoTClient 41:71c01aa3df1a 264 int result;
AzureIoTClient 30:20a85b733111 265
AzureIoTClient 41:71c01aa3df1a 266 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_029: [`instance->cbs_handle` shall be created using cbs_create()`]
AzureIoTClient 41:71c01aa3df1a 267 if ((instance->cbs_handle = cbs_create(instance->session_handle)) == NULL)
AzureIoTClient 41:71c01aa3df1a 268 {
AzureIoTClient 41:71c01aa3df1a 269 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_030: [If cbs_create() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 270 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 271 LogError("Failed to create the CBS connection.");
AzureIoTClient 41:71c01aa3df1a 272 }
AzureIoTClient 41:71c01aa3df1a 273 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_031: [`instance->cbs_handle` shall be opened using `cbs_open_async`]
AzureIoTClient 41:71c01aa3df1a 274 else if (cbs_open_async(instance->cbs_handle, on_cbs_open_complete, instance->cbs_handle, on_cbs_error, instance->cbs_handle) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 275 {
AzureIoTClient 41:71c01aa3df1a 276 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_032: [If cbs_open() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 277 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 278 LogError("Failed to open the connection with CBS.");
AzureIoTClient 41:71c01aa3df1a 279 }
AzureIoTClient 41:71c01aa3df1a 280 else
AzureIoTClient 41:71c01aa3df1a 281 {
AzureIoTClient 41:71c01aa3df1a 282 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 283 }
AzureIoTClient 30:20a85b733111 284
AzureIoTClient 41:71c01aa3df1a 285 return result;
AzureIoTClient 30:20a85b733111 286 }
AzureIoTClient 30:20a85b733111 287
AzureIoTClient 30:20a85b733111 288
AzureIoTClient 30:20a85b733111 289 // Public APIS:
AzureIoTClient 30:20a85b733111 290
AzureIoTClient 30:20a85b733111 291 void amqp_connection_destroy(AMQP_CONNECTION_HANDLE conn_handle)
AzureIoTClient 30:20a85b733111 292 {
AzureIoTClient 41:71c01aa3df1a 293 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_035: [If `conn_handle` is NULL, amqp_connection_destroy() shall fail and return]
AzureIoTClient 41:71c01aa3df1a 294 if (conn_handle != NULL)
AzureIoTClient 41:71c01aa3df1a 295 {
AzureIoTClient 41:71c01aa3df1a 296 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle;
AzureIoTClient 30:20a85b733111 297
AzureIoTClient 41:71c01aa3df1a 298 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_036: [amqp_connection_destroy() shall destroy `instance->cbs_handle` if set using cbs_destroy()]
AzureIoTClient 41:71c01aa3df1a 299 if (instance->cbs_handle != NULL)
AzureIoTClient 41:71c01aa3df1a 300 {
AzureIoTClient 41:71c01aa3df1a 301 cbs_destroy(instance->cbs_handle);
AzureIoTClient 41:71c01aa3df1a 302 }
AzureIoTClient 30:20a85b733111 303
AzureIoTClient 41:71c01aa3df1a 304 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_037: [amqp_connection_destroy() shall destroy `instance->session_handle` if set using session_destroy()]
AzureIoTClient 41:71c01aa3df1a 305 if (instance->session_handle != NULL)
AzureIoTClient 41:71c01aa3df1a 306 {
AzureIoTClient 41:71c01aa3df1a 307 session_destroy(instance->session_handle);
AzureIoTClient 41:71c01aa3df1a 308 }
AzureIoTClient 30:20a85b733111 309
AzureIoTClient 41:71c01aa3df1a 310 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_067: [amqp_connection_destroy() shall destroy `instance->connection_handle` if set using connection_destroy()]
AzureIoTClient 41:71c01aa3df1a 311 if (instance->connection_handle != NULL)
AzureIoTClient 41:71c01aa3df1a 312 {
AzureIoTClient 41:71c01aa3df1a 313 connection_destroy(instance->connection_handle);
AzureIoTClient 41:71c01aa3df1a 314 }
AzureIoTClient 30:20a85b733111 315
AzureIoTClient 41:71c01aa3df1a 316 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_038: [amqp_connection_destroy() shall destroy `instance->sasl_io` if set using xio_destroy()]
AzureIoTClient 41:71c01aa3df1a 317 if (instance->sasl_io != NULL)
AzureIoTClient 41:71c01aa3df1a 318 {
AzureIoTClient 41:71c01aa3df1a 319 xio_destroy(instance->sasl_io);
AzureIoTClient 41:71c01aa3df1a 320 }
AzureIoTClient 30:20a85b733111 321
AzureIoTClient 41:71c01aa3df1a 322 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_039: [amqp_connection_destroy() shall destroy `instance->sasl_mechanism` if set using saslmechanism_destroy()]
AzureIoTClient 41:71c01aa3df1a 323 if (instance->sasl_mechanism != NULL)
AzureIoTClient 41:71c01aa3df1a 324 {
AzureIoTClient 41:71c01aa3df1a 325 saslmechanism_destroy(instance->sasl_mechanism);
AzureIoTClient 41:71c01aa3df1a 326 }
AzureIoTClient 30:20a85b733111 327
AzureIoTClient 41:71c01aa3df1a 328 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_059: [amqp_connection_destroy() shall destroy `instance->iothub_host_fqdn` if set using STRING_delete()]
AzureIoTClient 41:71c01aa3df1a 329 if (instance->iothub_fqdn != NULL)
AzureIoTClient 41:71c01aa3df1a 330 {
AzureIoTClient 41:71c01aa3df1a 331 STRING_delete(instance->iothub_fqdn);
AzureIoTClient 41:71c01aa3df1a 332 }
AzureIoTClient 30:20a85b733111 333
AzureIoTClient 41:71c01aa3df1a 334 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_040: [amqp_connection_destroy() shall free the memory allocated for the connection instance]
AzureIoTClient 41:71c01aa3df1a 335 free(instance);
AzureIoTClient 41:71c01aa3df1a 336 }
AzureIoTClient 30:20a85b733111 337 }
AzureIoTClient 30:20a85b733111 338
AzureIoTClient 30:20a85b733111 339 AMQP_CONNECTION_HANDLE amqp_connection_create(AMQP_CONNECTION_CONFIG* config)
AzureIoTClient 30:20a85b733111 340 {
AzureIoTClient 41:71c01aa3df1a 341 AMQP_CONNECTION_HANDLE result;
AzureIoTClient 30:20a85b733111 342
AzureIoTClient 41:71c01aa3df1a 343 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_001: [If `config` is NULL, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 344 if (config == NULL)
AzureIoTClient 41:71c01aa3df1a 345 {
AzureIoTClient 41:71c01aa3df1a 346 result = NULL;
AzureIoTClient 41:71c01aa3df1a 347 LogError("amqp_connection_create failed (config is NULL)");
AzureIoTClient 41:71c01aa3df1a 348 }
AzureIoTClient 41:71c01aa3df1a 349 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_002: [If `config->iothub_host_fqdn` is NULL, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 350 else if (config->iothub_host_fqdn == NULL)
AzureIoTClient 41:71c01aa3df1a 351 {
AzureIoTClient 41:71c01aa3df1a 352 result = NULL;
AzureIoTClient 41:71c01aa3df1a 353 LogError("amqp_connection_create failed (config->iothub_host_fqdn is NULL)");
AzureIoTClient 41:71c01aa3df1a 354 }
AzureIoTClient 41:71c01aa3df1a 355 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_003: [If `config->underlying_io_transport` is NULL, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 356 else if (config->underlying_io_transport == NULL)
AzureIoTClient 41:71c01aa3df1a 357 {
AzureIoTClient 41:71c01aa3df1a 358 result = NULL;
AzureIoTClient 41:71c01aa3df1a 359 LogError("amqp_connection_create failed (config->underlying_io_transport is NULL)");
AzureIoTClient 41:71c01aa3df1a 360 }
AzureIoTClient 41:71c01aa3df1a 361 else
AzureIoTClient 41:71c01aa3df1a 362 {
AzureIoTClient 41:71c01aa3df1a 363 AMQP_CONNECTION_INSTANCE* instance;
AzureIoTClient 30:20a85b733111 364
AzureIoTClient 41:71c01aa3df1a 365 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_057: [amqp_connection_create() shall allocate memory for an instance of the connection state]
AzureIoTClient 41:71c01aa3df1a 366 if ((instance = (AMQP_CONNECTION_INSTANCE*)malloc(sizeof(AMQP_CONNECTION_INSTANCE))) == NULL)
AzureIoTClient 41:71c01aa3df1a 367 {
AzureIoTClient 41:71c01aa3df1a 368 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_058: [If malloc() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 369 result = NULL;
AzureIoTClient 41:71c01aa3df1a 370 LogError("amqp_connection_create failed (malloc failed)");
AzureIoTClient 41:71c01aa3df1a 371 }
AzureIoTClient 41:71c01aa3df1a 372 else
AzureIoTClient 41:71c01aa3df1a 373 {
AzureIoTClient 41:71c01aa3df1a 374 memset(instance, 0, sizeof(AMQP_CONNECTION_INSTANCE));
AzureIoTClient 30:20a85b733111 375
AzureIoTClient 41:71c01aa3df1a 376 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_005: [A copy of `config->iothub_host_fqdn` shall be saved on `instance->iothub_host_fqdn`]
AzureIoTClient 41:71c01aa3df1a 377 if ((instance->iothub_fqdn = STRING_construct(config->iothub_host_fqdn)) == NULL)
AzureIoTClient 41:71c01aa3df1a 378 {
AzureIoTClient 41:71c01aa3df1a 379 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_066: [If STRING_construct() fails, amqp_connection_create() shall fail and return NULL]
AzureIoTClient 41:71c01aa3df1a 380 result = NULL;
AzureIoTClient 41:71c01aa3df1a 381 LogError("amqp_connection_create failed (STRING_construct failed)");
AzureIoTClient 41:71c01aa3df1a 382 }
AzureIoTClient 41:71c01aa3df1a 383 else
AzureIoTClient 41:71c01aa3df1a 384 {
AzureIoTClient 41:71c01aa3df1a 385 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_006: [`config->underlying_io_transport` shall be saved on `instance->underlying_io_transport`]
AzureIoTClient 41:71c01aa3df1a 386 instance->underlying_io_transport = config->underlying_io_transport;
AzureIoTClient 41:71c01aa3df1a 387 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_008: [`config->is_trace_on` shall be saved on `instance->is_trace_on`]
AzureIoTClient 41:71c01aa3df1a 388 instance->is_trace_on = config->is_trace_on;
AzureIoTClient 41:71c01aa3df1a 389 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_060: [`config->on_state_changed_callback` shall be saved on `instance->on_state_changed_callback`]
AzureIoTClient 41:71c01aa3df1a 390 instance->on_state_changed_callback = config->on_state_changed_callback;
AzureIoTClient 41:71c01aa3df1a 391 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_061: [`config->on_state_changed_context` shall be saved on `instance->on_state_changed_context`]
AzureIoTClient 41:71c01aa3df1a 392 instance->on_state_changed_context = config->on_state_changed_context;
AzureIoTClient 46:c688c75b63b9 393 instance->has_sasl_mechanism = config->create_sasl_io;
AzureIoTClient 46:c688c75b63b9 394 instance->has_cbs = config->create_cbs_connection;
AzureIoTClient 30:20a85b733111 395
AzureIoTClient 47:8a238e75a0f7 396 instance->svc2cl_keep_alive_timeout_secs = (uint32_t)config->svc2cl_keep_alive_timeout_secs;
AzureIoTClient 56:8704100b3b54 397 instance->cl2svc_keep_alive_send_ratio = (double)config->cl2svc_keep_alive_send_ratio;
AzureIoTClient 37:abd16824f63b 398
AzureIoTClient 41:71c01aa3df1a 399 instance->current_state = AMQP_CONNECTION_STATE_CLOSED;
AzureIoTClient 30:20a85b733111 400
AzureIoTClient 41:71c01aa3df1a 401 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_011: [If `config->create_sasl_io` is true or `config->create_cbs_connection` is true, amqp_connection_create() shall create SASL I/O]
AzureIoTClient 41:71c01aa3df1a 402 if ((config->create_sasl_io || config->create_cbs_connection) && create_sasl_components(instance) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 403 {
AzureIoTClient 41:71c01aa3df1a 404 result = NULL;
AzureIoTClient 41:71c01aa3df1a 405 LogError("amqp_connection_create failed (failed creating the SASL components)");
AzureIoTClient 41:71c01aa3df1a 406 }
AzureIoTClient 41:71c01aa3df1a 407 else if (create_connection_handle(instance) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 408 {
AzureIoTClient 41:71c01aa3df1a 409 result = NULL;
AzureIoTClient 41:71c01aa3df1a 410 LogError("amqp_connection_create failed (failed creating the AMQP connection)");
AzureIoTClient 41:71c01aa3df1a 411 }
AzureIoTClient 41:71c01aa3df1a 412 else if (create_session_handle(instance) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 413 {
AzureIoTClient 41:71c01aa3df1a 414 result = NULL;
AzureIoTClient 41:71c01aa3df1a 415 LogError("amqp_connection_create failed (failed creating the AMQP session)");
AzureIoTClient 41:71c01aa3df1a 416 }
AzureIoTClient 41:71c01aa3df1a 417 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_028: [Only if `config->create_cbs_connection` is true, amqp_connection_create() shall create and open the CBS_HANDLE]
AzureIoTClient 41:71c01aa3df1a 418 else if (config->create_cbs_connection && create_cbs_handle(instance) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 419 {
AzureIoTClient 41:71c01aa3df1a 420 result = NULL;
AzureIoTClient 41:71c01aa3df1a 421 LogError("amqp_connection_create failed (failed creating the CBS handle)");
AzureIoTClient 41:71c01aa3df1a 422 }
AzureIoTClient 41:71c01aa3df1a 423 else
AzureIoTClient 41:71c01aa3df1a 424 {
AzureIoTClient 41:71c01aa3df1a 425 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_034: [If no failures occur, amqp_connection_create() shall return the handle to the connection state]
AzureIoTClient 41:71c01aa3df1a 426 result = (AMQP_CONNECTION_HANDLE)instance;
AzureIoTClient 41:71c01aa3df1a 427 }
AzureIoTClient 41:71c01aa3df1a 428 }
AzureIoTClient 30:20a85b733111 429
AzureIoTClient 41:71c01aa3df1a 430 if (result == NULL)
AzureIoTClient 41:71c01aa3df1a 431 {
AzureIoTClient 41:71c01aa3df1a 432 amqp_connection_destroy((AMQP_CONNECTION_HANDLE)instance);
AzureIoTClient 41:71c01aa3df1a 433 }
AzureIoTClient 41:71c01aa3df1a 434 }
AzureIoTClient 41:71c01aa3df1a 435 }
AzureIoTClient 30:20a85b733111 436
AzureIoTClient 41:71c01aa3df1a 437 return result;
AzureIoTClient 30:20a85b733111 438 }
AzureIoTClient 30:20a85b733111 439
AzureIoTClient 30:20a85b733111 440 void amqp_connection_do_work(AMQP_CONNECTION_HANDLE conn_handle)
AzureIoTClient 30:20a85b733111 441 {
AzureIoTClient 41:71c01aa3df1a 442 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_041: [If `conn_handle` is NULL, amqp_connection_do_work() shall fail and return]
AzureIoTClient 41:71c01aa3df1a 443 if (conn_handle != NULL)
AzureIoTClient 41:71c01aa3df1a 444 {
AzureIoTClient 41:71c01aa3df1a 445 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle;
AzureIoTClient 30:20a85b733111 446
AzureIoTClient 41:71c01aa3df1a 447 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_042: [connection_dowork() shall be invoked passing `instance->connection_handle`]
AzureIoTClient 41:71c01aa3df1a 448 connection_dowork(instance->connection_handle);
AzureIoTClient 41:71c01aa3df1a 449 }
AzureIoTClient 30:20a85b733111 450 }
AzureIoTClient 30:20a85b733111 451
AzureIoTClient 30:20a85b733111 452 int amqp_connection_get_session_handle(AMQP_CONNECTION_HANDLE conn_handle, SESSION_HANDLE* session_handle)
AzureIoTClient 30:20a85b733111 453 {
AzureIoTClient 41:71c01aa3df1a 454 int result;
AzureIoTClient 56:8704100b3b54 455
AzureIoTClient 41:71c01aa3df1a 456 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_043: [If `conn_handle` is NULL, amqp_connection_get_session_handle() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 457 if (conn_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 458 {
AzureIoTClient 41:71c01aa3df1a 459 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 460 LogError("amqp_connection_get_session_handle failed (conn_handle is NULL)");
AzureIoTClient 41:71c01aa3df1a 461 }
AzureIoTClient 41:71c01aa3df1a 462 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_044: [If `session_handle` is NULL, amqp_connection_get_session_handle() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 463 else if (session_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 464 {
AzureIoTClient 41:71c01aa3df1a 465 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 466 LogError("amqp_connection_get_session_handle failed (session_handle is NULL)");
AzureIoTClient 41:71c01aa3df1a 467 }
AzureIoTClient 41:71c01aa3df1a 468 else
AzureIoTClient 41:71c01aa3df1a 469 {
AzureIoTClient 41:71c01aa3df1a 470 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle;
AzureIoTClient 30:20a85b733111 471
AzureIoTClient 41:71c01aa3df1a 472 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_045: [`session_handle` shall be set to point to `instance->session_handle`]
AzureIoTClient 41:71c01aa3df1a 473 *session_handle = instance->session_handle;
AzureIoTClient 30:20a85b733111 474
AzureIoTClient 41:71c01aa3df1a 475 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_046: [amqp_connection_get_session_handle() shall return success code 0]
AzureIoTClient 41:71c01aa3df1a 476 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 477 }
AzureIoTClient 30:20a85b733111 478
AzureIoTClient 41:71c01aa3df1a 479 return result;
AzureIoTClient 30:20a85b733111 480 }
AzureIoTClient 30:20a85b733111 481
AzureIoTClient 30:20a85b733111 482 int amqp_connection_get_cbs_handle(AMQP_CONNECTION_HANDLE conn_handle, CBS_HANDLE* cbs_handle)
AzureIoTClient 30:20a85b733111 483 {
AzureIoTClient 41:71c01aa3df1a 484 int result;
AzureIoTClient 30:20a85b733111 485
AzureIoTClient 41:71c01aa3df1a 486 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_047: [If `conn_handle` is NULL, amqp_connection_get_cbs_handle() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 487 if (conn_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 488 {
AzureIoTClient 41:71c01aa3df1a 489 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 490 LogError("amqp_connection_get_cbs_handle failed (conn_handle is NULL)");
AzureIoTClient 41:71c01aa3df1a 491 }
AzureIoTClient 41:71c01aa3df1a 492 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_048: [If `cbs_handle` is NULL, amqp_connection_get_cbs_handle() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 493 else if (cbs_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 494 {
AzureIoTClient 41:71c01aa3df1a 495 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 496 LogError("amqp_connection_get_cbs_handle failed (parameter cbs_handle is NULL)");
AzureIoTClient 41:71c01aa3df1a 497 }
AzureIoTClient 41:71c01aa3df1a 498 else
AzureIoTClient 41:71c01aa3df1a 499 {
AzureIoTClient 41:71c01aa3df1a 500 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle;
AzureIoTClient 30:20a85b733111 501
AzureIoTClient 41:71c01aa3df1a 502 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_049: [If `instance->cbs_handle` is NULL, amqp_connection_get_cbs_handle() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 503 if (instance->cbs_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 504 {
AzureIoTClient 41:71c01aa3df1a 505 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 506 LogError("amqp_connection_get_cbs_handle failed (there is not a cbs_handle to be returned)");
AzureIoTClient 41:71c01aa3df1a 507 }
AzureIoTClient 41:71c01aa3df1a 508 else
AzureIoTClient 41:71c01aa3df1a 509 {
AzureIoTClient 41:71c01aa3df1a 510 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_050: [`cbs_handle` shall be set to point to `instance->cbs_handle`]
AzureIoTClient 41:71c01aa3df1a 511 *cbs_handle = instance->cbs_handle;
AzureIoTClient 30:20a85b733111 512
AzureIoTClient 41:71c01aa3df1a 513 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_051: [amqp_connection_get_cbs_handle() shall return success code 0]
AzureIoTClient 41:71c01aa3df1a 514 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 515 }
AzureIoTClient 41:71c01aa3df1a 516 }
AzureIoTClient 30:20a85b733111 517
AzureIoTClient 41:71c01aa3df1a 518 return result;
AzureIoTClient 30:20a85b733111 519 }
AzureIoTClient 30:20a85b733111 520
AzureIoTClient 30:20a85b733111 521 int amqp_connection_set_logging(AMQP_CONNECTION_HANDLE conn_handle, bool is_trace_on)
AzureIoTClient 30:20a85b733111 522 {
AzureIoTClient 41:71c01aa3df1a 523 int result;
AzureIoTClient 30:20a85b733111 524
AzureIoTClient 41:71c01aa3df1a 525 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_052: [If `conn_handle` is NULL, amqp_connection_set_logging() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 526 if (conn_handle == NULL)
AzureIoTClient 41:71c01aa3df1a 527 {
AzureIoTClient 41:71c01aa3df1a 528 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 529 LogError("amqp_connection_set_logging failed (conn_handle is NULL)");
AzureIoTClient 41:71c01aa3df1a 530 }
AzureIoTClient 41:71c01aa3df1a 531 else
AzureIoTClient 41:71c01aa3df1a 532 {
AzureIoTClient 41:71c01aa3df1a 533 AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle;
AzureIoTClient 30:20a85b733111 534
AzureIoTClient 41:71c01aa3df1a 535 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_053: [`instance->is_trace_on` shall be set to `is_trace_on`]
AzureIoTClient 41:71c01aa3df1a 536 instance->is_trace_on = is_trace_on;
AzureIoTClient 30:20a85b733111 537
AzureIoTClient 41:71c01aa3df1a 538 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_054: [Tracing on `instance->sasl_io` shall be set to `instance->is_trace_on` if the value has changed]
AzureIoTClient 41:71c01aa3df1a 539 if (instance->sasl_io != NULL &&
AzureIoTClient 41:71c01aa3df1a 540 xio_setoption(instance->sasl_io, SASL_IO_OPTION_LOG_TRACE, (const void*)&instance->is_trace_on) != RESULT_OK)
AzureIoTClient 41:71c01aa3df1a 541 {
AzureIoTClient 41:71c01aa3df1a 542 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_072: [If xio_setoption() fails, amqp_connection_set_logging() shall fail and return __FAILURE__]
AzureIoTClient 41:71c01aa3df1a 543 result = __FAILURE__;
AzureIoTClient 41:71c01aa3df1a 544 LogError("amqp_connection_set_logging failed (xio_setoption() failed)");
AzureIoTClient 41:71c01aa3df1a 545 }
AzureIoTClient 41:71c01aa3df1a 546 else
AzureIoTClient 41:71c01aa3df1a 547 {
AzureIoTClient 41:71c01aa3df1a 548 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_055: [Tracing on `instance->connection_handle` shall be set to `instance->is_trace_on` if the value has changed]
AzureIoTClient 41:71c01aa3df1a 549 connection_set_trace(instance->connection_handle, instance->is_trace_on);
AzureIoTClient 30:20a85b733111 550
AzureIoTClient 41:71c01aa3df1a 551 // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_056: [amqp_connection_set_logging() shall return success code 0]
AzureIoTClient 41:71c01aa3df1a 552 result = RESULT_OK;
AzureIoTClient 41:71c01aa3df1a 553 }
AzureIoTClient 41:71c01aa3df1a 554 }
AzureIoTClient 30:20a85b733111 555
AzureIoTClient 41:71c01aa3df1a 556 return result;
AzureIoTClient 30:20a85b733111 557 }