A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Apr 21 14:50:32 2017 -0700
Revision:
23:1111ee8bcba4
Parent:
22:524bded3f7a8
Child:
25:1101516ee67d
1.1.13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
Azure.IoT Build 0:6ae2f7bca550 5 #include <string.h>
AzureIoTClient 21:f9c433d8e6ca 6 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 21:f9c433d8e6ca 7 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:6ae2f7bca550 8 #include "azure_uamqp_c/session.h"
Azure.IoT Build 0:6ae2f7bca550 9 #include "azure_uamqp_c/connection.h"
Azure.IoT Build 0:6ae2f7bca550 10 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 0:6ae2f7bca550 11
Azure.IoT Build 0:6ae2f7bca550 12 typedef struct LINK_ENDPOINT_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 13 {
Azure.IoT Build 0:6ae2f7bca550 14 char* name;
Azure.IoT Build 0:6ae2f7bca550 15 handle input_handle;
Azure.IoT Build 0:6ae2f7bca550 16 handle output_handle;
Azure.IoT Build 0:6ae2f7bca550 17 ON_ENDPOINT_FRAME_RECEIVED frame_received_callback;
Azure.IoT Build 0:6ae2f7bca550 18 ON_SESSION_STATE_CHANGED on_session_state_changed;
Azure.IoT Build 0:6ae2f7bca550 19 ON_SESSION_FLOW_ON on_session_flow_on;
Azure.IoT Build 0:6ae2f7bca550 20 void* callback_context;
Azure.IoT Build 0:6ae2f7bca550 21 SESSION_HANDLE session;
Azure.IoT Build 0:6ae2f7bca550 22 } LINK_ENDPOINT_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 23
Azure.IoT Build 0:6ae2f7bca550 24 typedef struct SESSION_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 25 {
Azure.IoT Build 0:6ae2f7bca550 26 ON_ENDPOINT_FRAME_RECEIVED frame_received_callback;
Azure.IoT Build 0:6ae2f7bca550 27 void* frame_received_callback_context;
Azure.IoT Build 0:6ae2f7bca550 28 SESSION_STATE session_state;
Azure.IoT Build 0:6ae2f7bca550 29 SESSION_STATE previous_session_state;
Azure.IoT Build 0:6ae2f7bca550 30 CONNECTION_HANDLE connection;
Azure.IoT Build 0:6ae2f7bca550 31 ENDPOINT_HANDLE endpoint;
Azure.IoT Build 0:6ae2f7bca550 32 LINK_ENDPOINT_INSTANCE** link_endpoints;
Azure.IoT Build 0:6ae2f7bca550 33 uint32_t link_endpoint_count;
Azure.IoT Build 0:6ae2f7bca550 34
Azure.IoT Build 0:6ae2f7bca550 35 ON_LINK_ATTACHED on_link_attached;
Azure.IoT Build 0:6ae2f7bca550 36 void* on_link_attached_callback_context;
Azure.IoT Build 0:6ae2f7bca550 37
Azure.IoT Build 0:6ae2f7bca550 38 /* Codes_SRS_SESSION_01_016: [next-outgoing-id The next-outgoing-id is the transfer-id to assign to the next transfer frame.] */
Azure.IoT Build 0:6ae2f7bca550 39 transfer_number next_outgoing_id;
Azure.IoT Build 0:6ae2f7bca550 40 transfer_number next_incoming_id;
Azure.IoT Build 0:6ae2f7bca550 41 uint32_t desired_incoming_window;
Azure.IoT Build 0:6ae2f7bca550 42 uint32_t incoming_window;
Azure.IoT Build 0:6ae2f7bca550 43 uint32_t outgoing_window;
Azure.IoT Build 0:6ae2f7bca550 44 handle handle_max;
Azure.IoT Build 0:6ae2f7bca550 45 uint32_t remote_incoming_window;
Azure.IoT Build 0:6ae2f7bca550 46 uint32_t remote_outgoing_window;
AzureIoTClient 6:641a9672db08 47 int is_underlying_connection_open : 1;
Azure.IoT Build 0:6ae2f7bca550 48 } SESSION_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 49
AzureIoTClient 6:641a9672db08 50 #define UNDERLYING_CONNECTION_NOT_OPEN 0
AzureIoTClient 6:641a9672db08 51 #define UNDERLYING_CONNECTION_OPEN -1
AzureIoTClient 6:641a9672db08 52
Azure.IoT Build 0:6ae2f7bca550 53 static void session_set_state(SESSION_INSTANCE* session_instance, SESSION_STATE session_state)
Azure.IoT Build 0:6ae2f7bca550 54 {
Azure.IoT Build 0:6ae2f7bca550 55 uint64_t i;
Azure.IoT Build 0:6ae2f7bca550 56
Azure.IoT Build 0:6ae2f7bca550 57 session_instance->previous_session_state = session_instance->session_state;
Azure.IoT Build 0:6ae2f7bca550 58 session_instance->session_state = session_state;
Azure.IoT Build 0:6ae2f7bca550 59
Azure.IoT Build 0:6ae2f7bca550 60 for (i = 0; i < session_instance->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 61 {
Azure.IoT Build 0:6ae2f7bca550 62 if (session_instance->link_endpoints[i]->on_session_state_changed != NULL)
Azure.IoT Build 0:6ae2f7bca550 63 {
Azure.IoT Build 0:6ae2f7bca550 64 session_instance->link_endpoints[i]->on_session_state_changed(session_instance->link_endpoints[i]->callback_context, session_state, session_instance->previous_session_state);
Azure.IoT Build 0:6ae2f7bca550 65 }
Azure.IoT Build 0:6ae2f7bca550 66 }
Azure.IoT Build 0:6ae2f7bca550 67 }
Azure.IoT Build 0:6ae2f7bca550 68
Azure.IoT Build 0:6ae2f7bca550 69 static int send_end_frame(SESSION_INSTANCE* session_instance, ERROR_HANDLE error_handle)
Azure.IoT Build 0:6ae2f7bca550 70 {
Azure.IoT Build 0:6ae2f7bca550 71 int result;
Azure.IoT Build 0:6ae2f7bca550 72 END_HANDLE end_performative;
Azure.IoT Build 0:6ae2f7bca550 73
Azure.IoT Build 0:6ae2f7bca550 74 end_performative = end_create();
Azure.IoT Build 0:6ae2f7bca550 75 if (end_performative == NULL)
Azure.IoT Build 0:6ae2f7bca550 76 {
AzureIoTClient 19:000ab4e6a2c1 77 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 78 }
Azure.IoT Build 0:6ae2f7bca550 79 else
Azure.IoT Build 0:6ae2f7bca550 80 {
Azure.IoT Build 0:6ae2f7bca550 81 if ((error_handle != NULL) &&
Azure.IoT Build 0:6ae2f7bca550 82 (end_set_error(end_performative, error_handle) != 0))
Azure.IoT Build 0:6ae2f7bca550 83 {
AzureIoTClient 19:000ab4e6a2c1 84 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 85 }
Azure.IoT Build 0:6ae2f7bca550 86 else
Azure.IoT Build 0:6ae2f7bca550 87 {
Azure.IoT Build 0:6ae2f7bca550 88 AMQP_VALUE end_performative_value = amqpvalue_create_end(end_performative);
Azure.IoT Build 0:6ae2f7bca550 89 if (end_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 90 {
AzureIoTClient 19:000ab4e6a2c1 91 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 92 }
Azure.IoT Build 0:6ae2f7bca550 93 else
Azure.IoT Build 0:6ae2f7bca550 94 {
Azure.IoT Build 0:6ae2f7bca550 95 if (connection_encode_frame(session_instance->endpoint, end_performative_value, NULL, 0, NULL, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 96 {
AzureIoTClient 19:000ab4e6a2c1 97 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 98 }
Azure.IoT Build 0:6ae2f7bca550 99 else
Azure.IoT Build 0:6ae2f7bca550 100 {
Azure.IoT Build 0:6ae2f7bca550 101 result = 0;
Azure.IoT Build 0:6ae2f7bca550 102 }
Azure.IoT Build 0:6ae2f7bca550 103
Azure.IoT Build 0:6ae2f7bca550 104 amqpvalue_destroy(end_performative_value);
Azure.IoT Build 0:6ae2f7bca550 105 }
Azure.IoT Build 0:6ae2f7bca550 106 }
Azure.IoT Build 0:6ae2f7bca550 107
Azure.IoT Build 0:6ae2f7bca550 108 end_destroy(end_performative);
Azure.IoT Build 0:6ae2f7bca550 109 }
Azure.IoT Build 0:6ae2f7bca550 110
Azure.IoT Build 0:6ae2f7bca550 111 return result;
Azure.IoT Build 0:6ae2f7bca550 112 }
Azure.IoT Build 0:6ae2f7bca550 113
Azure.IoT Build 0:6ae2f7bca550 114 static void end_session_with_error(SESSION_INSTANCE* session_instance, const char* condition_value, const char* description)
Azure.IoT Build 0:6ae2f7bca550 115 {
Azure.IoT Build 0:6ae2f7bca550 116 ERROR_HANDLE error_handle = error_create(condition_value);
Azure.IoT Build 0:6ae2f7bca550 117 if (error_handle == NULL)
Azure.IoT Build 0:6ae2f7bca550 118 {
Azure.IoT Build 0:6ae2f7bca550 119 /* fatal error */
Azure.IoT Build 0:6ae2f7bca550 120 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 121 (void)connection_close(session_instance->connection, "amqp:internal-error", "Cannot allocate error handle to end session");
Azure.IoT Build 0:6ae2f7bca550 122 }
Azure.IoT Build 0:6ae2f7bca550 123 else
Azure.IoT Build 0:6ae2f7bca550 124 {
Azure.IoT Build 0:6ae2f7bca550 125 if ((error_set_description(error_handle, description) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 126 (send_end_frame(session_instance, error_handle) != 0))
Azure.IoT Build 0:6ae2f7bca550 127 {
Azure.IoT Build 0:6ae2f7bca550 128 /* fatal error */
Azure.IoT Build 0:6ae2f7bca550 129 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 130 (void)connection_close(session_instance->connection, "amqp:internal-error", "Cannot allocate error handle to end session");
Azure.IoT Build 0:6ae2f7bca550 131 }
Azure.IoT Build 0:6ae2f7bca550 132 else
Azure.IoT Build 0:6ae2f7bca550 133 {
Azure.IoT Build 0:6ae2f7bca550 134 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 135 }
Azure.IoT Build 0:6ae2f7bca550 136
Azure.IoT Build 0:6ae2f7bca550 137 error_destroy(error_handle);
Azure.IoT Build 0:6ae2f7bca550 138 }
Azure.IoT Build 0:6ae2f7bca550 139 }
Azure.IoT Build 0:6ae2f7bca550 140
Azure.IoT Build 0:6ae2f7bca550 141 static int send_begin(SESSION_INSTANCE* session_instance)
Azure.IoT Build 0:6ae2f7bca550 142 {
Azure.IoT Build 0:6ae2f7bca550 143 int result;
Azure.IoT Build 0:6ae2f7bca550 144 BEGIN_HANDLE begin = begin_create(session_instance->next_outgoing_id, session_instance->incoming_window, session_instance->outgoing_window);
Azure.IoT Build 0:6ae2f7bca550 145
Azure.IoT Build 0:6ae2f7bca550 146 if (begin == NULL)
Azure.IoT Build 0:6ae2f7bca550 147 {
AzureIoTClient 19:000ab4e6a2c1 148 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 149 }
Azure.IoT Build 0:6ae2f7bca550 150 else
Azure.IoT Build 0:6ae2f7bca550 151 {
Azure.IoT Build 0:6ae2f7bca550 152 uint16_t remote_channel;
Azure.IoT Build 0:6ae2f7bca550 153 if (begin_set_handle_max(begin, session_instance->handle_max) != 0)
Azure.IoT Build 0:6ae2f7bca550 154 {
AzureIoTClient 19:000ab4e6a2c1 155 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 156 }
Azure.IoT Build 0:6ae2f7bca550 157 else if ((session_instance->session_state == SESSION_STATE_BEGIN_RCVD) &&
Azure.IoT Build 0:6ae2f7bca550 158 ((connection_endpoint_get_incoming_channel(session_instance->endpoint, &remote_channel) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 159 (begin_set_remote_channel(begin, remote_channel) != 0)))
Azure.IoT Build 0:6ae2f7bca550 160 {
AzureIoTClient 19:000ab4e6a2c1 161 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 162 }
Azure.IoT Build 0:6ae2f7bca550 163 else
Azure.IoT Build 0:6ae2f7bca550 164 {
Azure.IoT Build 0:6ae2f7bca550 165 AMQP_VALUE begin_performative_value = amqpvalue_create_begin(begin);
Azure.IoT Build 0:6ae2f7bca550 166 if (begin_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 167 {
AzureIoTClient 19:000ab4e6a2c1 168 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 169 }
Azure.IoT Build 0:6ae2f7bca550 170 else
Azure.IoT Build 0:6ae2f7bca550 171 {
Azure.IoT Build 0:6ae2f7bca550 172 if (connection_encode_frame(session_instance->endpoint, begin_performative_value, NULL, 0, NULL, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 173 {
AzureIoTClient 19:000ab4e6a2c1 174 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 175 }
Azure.IoT Build 0:6ae2f7bca550 176 else
Azure.IoT Build 0:6ae2f7bca550 177 {
Azure.IoT Build 0:6ae2f7bca550 178 result = 0;
Azure.IoT Build 0:6ae2f7bca550 179 }
Azure.IoT Build 0:6ae2f7bca550 180
Azure.IoT Build 0:6ae2f7bca550 181 amqpvalue_destroy(begin_performative_value);
Azure.IoT Build 0:6ae2f7bca550 182 }
Azure.IoT Build 0:6ae2f7bca550 183 }
Azure.IoT Build 0:6ae2f7bca550 184
Azure.IoT Build 0:6ae2f7bca550 185 begin_destroy(begin);
Azure.IoT Build 0:6ae2f7bca550 186 }
Azure.IoT Build 0:6ae2f7bca550 187
Azure.IoT Build 0:6ae2f7bca550 188 return result;
Azure.IoT Build 0:6ae2f7bca550 189 }
Azure.IoT Build 0:6ae2f7bca550 190
Azure.IoT Build 0:6ae2f7bca550 191 static int send_flow(SESSION_INSTANCE* session)
Azure.IoT Build 0:6ae2f7bca550 192 {
Azure.IoT Build 0:6ae2f7bca550 193 int result;
Azure.IoT Build 0:6ae2f7bca550 194 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 195 {
AzureIoTClient 19:000ab4e6a2c1 196 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 197 }
Azure.IoT Build 0:6ae2f7bca550 198 else
Azure.IoT Build 0:6ae2f7bca550 199 {
Azure.IoT Build 0:6ae2f7bca550 200 FLOW_HANDLE flow = flow_create(session->incoming_window, session->next_outgoing_id, session->outgoing_window);
Azure.IoT Build 0:6ae2f7bca550 201
Azure.IoT Build 0:6ae2f7bca550 202 if (flow == NULL)
Azure.IoT Build 0:6ae2f7bca550 203 {
AzureIoTClient 19:000ab4e6a2c1 204 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 205 }
Azure.IoT Build 0:6ae2f7bca550 206 else
Azure.IoT Build 0:6ae2f7bca550 207 {
Azure.IoT Build 0:6ae2f7bca550 208 if (flow_set_next_incoming_id(flow, session->next_incoming_id) != 0)
Azure.IoT Build 0:6ae2f7bca550 209 {
AzureIoTClient 19:000ab4e6a2c1 210 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 211 }
Azure.IoT Build 0:6ae2f7bca550 212 else
Azure.IoT Build 0:6ae2f7bca550 213 {
Azure.IoT Build 0:6ae2f7bca550 214 AMQP_VALUE flow_performative_value = amqpvalue_create_flow(flow);
Azure.IoT Build 0:6ae2f7bca550 215 if (flow_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 216 {
AzureIoTClient 19:000ab4e6a2c1 217 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 218 }
Azure.IoT Build 0:6ae2f7bca550 219 else
Azure.IoT Build 0:6ae2f7bca550 220 {
Azure.IoT Build 0:6ae2f7bca550 221 if (connection_encode_frame(session->endpoint, flow_performative_value, NULL, 0, NULL, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 222 {
AzureIoTClient 19:000ab4e6a2c1 223 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 224 }
Azure.IoT Build 0:6ae2f7bca550 225 else
Azure.IoT Build 0:6ae2f7bca550 226 {
Azure.IoT Build 0:6ae2f7bca550 227 result = 0;
Azure.IoT Build 0:6ae2f7bca550 228 }
Azure.IoT Build 0:6ae2f7bca550 229
Azure.IoT Build 0:6ae2f7bca550 230 amqpvalue_destroy(flow_performative_value);
Azure.IoT Build 0:6ae2f7bca550 231 }
Azure.IoT Build 0:6ae2f7bca550 232 }
Azure.IoT Build 0:6ae2f7bca550 233
Azure.IoT Build 0:6ae2f7bca550 234 flow_destroy(flow);
Azure.IoT Build 0:6ae2f7bca550 235 }
Azure.IoT Build 0:6ae2f7bca550 236 }
Azure.IoT Build 0:6ae2f7bca550 237
Azure.IoT Build 0:6ae2f7bca550 238 return result;
Azure.IoT Build 0:6ae2f7bca550 239 }
Azure.IoT Build 0:6ae2f7bca550 240
Azure.IoT Build 0:6ae2f7bca550 241 static LINK_ENDPOINT_INSTANCE* find_link_endpoint_by_name(SESSION_INSTANCE* session, const char* name)
Azure.IoT Build 0:6ae2f7bca550 242 {
Azure.IoT Build 0:6ae2f7bca550 243 uint32_t i;
Azure.IoT Build 0:6ae2f7bca550 244 LINK_ENDPOINT_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 245
Azure.IoT Build 0:6ae2f7bca550 246 for (i = 0; i < session->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 247 {
Azure.IoT Build 0:6ae2f7bca550 248 if (strcmp(session->link_endpoints[i]->name, name) == 0)
Azure.IoT Build 0:6ae2f7bca550 249 {
Azure.IoT Build 0:6ae2f7bca550 250 break;
Azure.IoT Build 0:6ae2f7bca550 251 }
Azure.IoT Build 0:6ae2f7bca550 252 }
Azure.IoT Build 0:6ae2f7bca550 253
Azure.IoT Build 0:6ae2f7bca550 254 if (i == session->link_endpoint_count)
Azure.IoT Build 0:6ae2f7bca550 255 {
Azure.IoT Build 0:6ae2f7bca550 256 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 257 }
Azure.IoT Build 0:6ae2f7bca550 258 else
Azure.IoT Build 0:6ae2f7bca550 259 {
Azure.IoT Build 0:6ae2f7bca550 260 result = session->link_endpoints[i];
Azure.IoT Build 0:6ae2f7bca550 261 }
Azure.IoT Build 0:6ae2f7bca550 262
Azure.IoT Build 0:6ae2f7bca550 263 return result;
Azure.IoT Build 0:6ae2f7bca550 264 }
Azure.IoT Build 0:6ae2f7bca550 265
Azure.IoT Build 0:6ae2f7bca550 266 static LINK_ENDPOINT_INSTANCE* find_link_endpoint_by_input_handle(SESSION_INSTANCE* session, handle input_handle)
Azure.IoT Build 0:6ae2f7bca550 267 {
Azure.IoT Build 0:6ae2f7bca550 268 uint32_t i;
Azure.IoT Build 0:6ae2f7bca550 269 LINK_ENDPOINT_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 270
Azure.IoT Build 0:6ae2f7bca550 271 for (i = 0; i < session->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 272 {
Azure.IoT Build 0:6ae2f7bca550 273 if (session->link_endpoints[i]->input_handle == input_handle)
Azure.IoT Build 0:6ae2f7bca550 274 {
Azure.IoT Build 0:6ae2f7bca550 275 break;
Azure.IoT Build 0:6ae2f7bca550 276 }
Azure.IoT Build 0:6ae2f7bca550 277 }
Azure.IoT Build 0:6ae2f7bca550 278
Azure.IoT Build 0:6ae2f7bca550 279 if (i == session->link_endpoint_count)
Azure.IoT Build 0:6ae2f7bca550 280 {
Azure.IoT Build 0:6ae2f7bca550 281 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 282 }
Azure.IoT Build 0:6ae2f7bca550 283 else
Azure.IoT Build 0:6ae2f7bca550 284 {
Azure.IoT Build 0:6ae2f7bca550 285 result = session->link_endpoints[i];
Azure.IoT Build 0:6ae2f7bca550 286 }
Azure.IoT Build 0:6ae2f7bca550 287
Azure.IoT Build 0:6ae2f7bca550 288 return result;
Azure.IoT Build 0:6ae2f7bca550 289 }
Azure.IoT Build 0:6ae2f7bca550 290
Azure.IoT Build 0:6ae2f7bca550 291 static void on_connection_state_changed(void* context, CONNECTION_STATE new_connection_state, CONNECTION_STATE previous_connection_state)
Azure.IoT Build 0:6ae2f7bca550 292 {
Azure.IoT Build 0:6ae2f7bca550 293 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 294
Azure.IoT Build 0:6ae2f7bca550 295 /* Codes_SRS_SESSION_01_060: [If the previous connection state is not OPENED and the new connection state is OPENED, the BEGIN frame shall be sent out and the state shall be switched to BEGIN_SENT.] */
Azure.IoT Build 0:6ae2f7bca550 296 if ((new_connection_state == CONNECTION_STATE_OPENED) && (previous_connection_state != CONNECTION_STATE_OPENED) && (session_instance->session_state == SESSION_STATE_UNMAPPED))
Azure.IoT Build 0:6ae2f7bca550 297 {
Azure.IoT Build 0:6ae2f7bca550 298 if (send_begin(session_instance) == 0)
Azure.IoT Build 0:6ae2f7bca550 299 {
Azure.IoT Build 0:6ae2f7bca550 300 session_set_state(session_instance, SESSION_STATE_BEGIN_SENT);
Azure.IoT Build 0:6ae2f7bca550 301 }
Azure.IoT Build 0:6ae2f7bca550 302 }
Azure.IoT Build 0:6ae2f7bca550 303 /* Codes_SRS_SESSION_01_061: [If the previous connection state is OPENED and the new connection state is not OPENED anymore, the state shall be switched to DISCARDING.] */
Azure.IoT Build 0:6ae2f7bca550 304 else if ((new_connection_state == CONNECTION_STATE_CLOSE_RCVD) || (new_connection_state == CONNECTION_STATE_END))
Azure.IoT Build 0:6ae2f7bca550 305 {
Azure.IoT Build 0:6ae2f7bca550 306 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 307 }
AzureIoTClient 1:eab586236bfe 308 /* Codes_SRS_SESSION_09_001: [If the new connection state is ERROR, the state shall be switched to ERROR.] */
AzureIoTClient 1:eab586236bfe 309 else if (new_connection_state == CONNECTION_STATE_ERROR)
AzureIoTClient 1:eab586236bfe 310 {
AzureIoTClient 1:eab586236bfe 311 session_set_state(session_instance, SESSION_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 312 }
Azure.IoT Build 0:6ae2f7bca550 313 }
Azure.IoT Build 0:6ae2f7bca550 314
Azure.IoT Build 0:6ae2f7bca550 315 static void on_frame_received(void* context, AMQP_VALUE performative, uint32_t payload_size, const unsigned char* payload_bytes)
Azure.IoT Build 0:6ae2f7bca550 316 {
Azure.IoT Build 0:6ae2f7bca550 317 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 318 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(performative);
Azure.IoT Build 0:6ae2f7bca550 319
Azure.IoT Build 0:6ae2f7bca550 320 if (is_begin_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 321 {
Azure.IoT Build 0:6ae2f7bca550 322 BEGIN_HANDLE begin_handle;
Azure.IoT Build 0:6ae2f7bca550 323
Azure.IoT Build 0:6ae2f7bca550 324 if (amqpvalue_get_begin(performative, &begin_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 325 {
Azure.IoT Build 0:6ae2f7bca550 326 connection_close(session_instance->connection, "amqp:decode-error", "Cannot decode BEGIN frame");
Azure.IoT Build 0:6ae2f7bca550 327 }
Azure.IoT Build 0:6ae2f7bca550 328 else
Azure.IoT Build 0:6ae2f7bca550 329 {
Azure.IoT Build 0:6ae2f7bca550 330 if ((begin_get_incoming_window(begin_handle, &session_instance->remote_incoming_window) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 331 (begin_get_next_outgoing_id(begin_handle, &session_instance->next_incoming_id) != 0))
Azure.IoT Build 0:6ae2f7bca550 332 {
Azure.IoT Build 0:6ae2f7bca550 333 /* error */
Azure.IoT Build 0:6ae2f7bca550 334 begin_destroy(begin_handle);
Azure.IoT Build 0:6ae2f7bca550 335 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 336 connection_close(session_instance->connection, "amqp:decode-error", "Cannot get incoming windows and next outgoing id");
Azure.IoT Build 0:6ae2f7bca550 337 }
Azure.IoT Build 0:6ae2f7bca550 338 else
Azure.IoT Build 0:6ae2f7bca550 339 {
Azure.IoT Build 0:6ae2f7bca550 340 begin_destroy(begin_handle);
Azure.IoT Build 0:6ae2f7bca550 341
Azure.IoT Build 0:6ae2f7bca550 342 if (session_instance->session_state == SESSION_STATE_BEGIN_SENT)
Azure.IoT Build 0:6ae2f7bca550 343 {
Azure.IoT Build 0:6ae2f7bca550 344 session_set_state(session_instance, SESSION_STATE_MAPPED);
Azure.IoT Build 0:6ae2f7bca550 345 }
Azure.IoT Build 0:6ae2f7bca550 346 else if(session_instance->session_state == SESSION_STATE_UNMAPPED)
Azure.IoT Build 0:6ae2f7bca550 347 {
Azure.IoT Build 0:6ae2f7bca550 348 session_set_state(session_instance, SESSION_STATE_BEGIN_RCVD);
Azure.IoT Build 0:6ae2f7bca550 349 if (send_begin(session_instance) != 0)
Azure.IoT Build 0:6ae2f7bca550 350 {
Azure.IoT Build 0:6ae2f7bca550 351 connection_close(session_instance->connection, "amqp:internal-error", "Failed sending BEGIN frame");
Azure.IoT Build 0:6ae2f7bca550 352 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 353 }
Azure.IoT Build 0:6ae2f7bca550 354 else
Azure.IoT Build 0:6ae2f7bca550 355 {
Azure.IoT Build 0:6ae2f7bca550 356 session_set_state(session_instance, SESSION_STATE_MAPPED);
Azure.IoT Build 0:6ae2f7bca550 357 }
Azure.IoT Build 0:6ae2f7bca550 358 }
Azure.IoT Build 0:6ae2f7bca550 359 }
Azure.IoT Build 0:6ae2f7bca550 360 }
Azure.IoT Build 0:6ae2f7bca550 361 }
Azure.IoT Build 0:6ae2f7bca550 362 else if (is_attach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 363 {
Azure.IoT Build 0:6ae2f7bca550 364 const char* name = NULL;
Azure.IoT Build 0:6ae2f7bca550 365 ATTACH_HANDLE attach_handle;
Azure.IoT Build 0:6ae2f7bca550 366
Azure.IoT Build 0:6ae2f7bca550 367 if (amqpvalue_get_attach(performative, &attach_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 368 {
Azure.IoT Build 0:6ae2f7bca550 369 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode ATTACH frame");
Azure.IoT Build 0:6ae2f7bca550 370 }
Azure.IoT Build 0:6ae2f7bca550 371 else
Azure.IoT Build 0:6ae2f7bca550 372 {
Azure.IoT Build 0:6ae2f7bca550 373 role role;
Azure.IoT Build 0:6ae2f7bca550 374 AMQP_VALUE source;
Azure.IoT Build 0:6ae2f7bca550 375 AMQP_VALUE target;
Azure.IoT Build 0:6ae2f7bca550 376
Azure.IoT Build 0:6ae2f7bca550 377 if ((attach_get_name(attach_handle, &name) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 378 (attach_get_role(attach_handle, &role) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 379 (attach_get_source(attach_handle, &source) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 380 (attach_get_target(attach_handle, &target) != 0))
Azure.IoT Build 0:6ae2f7bca550 381 {
Azure.IoT Build 0:6ae2f7bca550 382 end_session_with_error(session_instance, "amqp:decode-error", "Cannot get link name from ATTACH frame");
Azure.IoT Build 0:6ae2f7bca550 383 }
Azure.IoT Build 0:6ae2f7bca550 384 else
Azure.IoT Build 0:6ae2f7bca550 385 {
Azure.IoT Build 0:6ae2f7bca550 386 LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_name(session_instance, name);
Azure.IoT Build 0:6ae2f7bca550 387 if (link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 388 {
Azure.IoT Build 0:6ae2f7bca550 389 /* new link attach */
Azure.IoT Build 0:6ae2f7bca550 390 if (session_instance->on_link_attached != NULL)
Azure.IoT Build 0:6ae2f7bca550 391 {
Azure.IoT Build 0:6ae2f7bca550 392 LINK_ENDPOINT_HANDLE new_link_endpoint = session_create_link_endpoint(session_instance, name);
Azure.IoT Build 0:6ae2f7bca550 393 if (new_link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 394 {
Azure.IoT Build 0:6ae2f7bca550 395 end_session_with_error(session_instance, "amqp:internal-error", "Cannot create link endpoint");
Azure.IoT Build 0:6ae2f7bca550 396 }
Azure.IoT Build 0:6ae2f7bca550 397 else if (attach_get_handle(attach_handle, &new_link_endpoint->input_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 398 {
Azure.IoT Build 0:6ae2f7bca550 399 end_session_with_error(session_instance, "amqp:decode-error", "Cannot get input handle from ATTACH frame");
Azure.IoT Build 0:6ae2f7bca550 400 }
Azure.IoT Build 0:6ae2f7bca550 401 else
Azure.IoT Build 0:6ae2f7bca550 402 {
Azure.IoT Build 0:6ae2f7bca550 403 if (!session_instance->on_link_attached(session_instance->on_link_attached_callback_context, new_link_endpoint, name, role, source, target))
Azure.IoT Build 0:6ae2f7bca550 404 {
Azure.IoT Build 0:6ae2f7bca550 405 session_destroy_link_endpoint(new_link_endpoint);
Azure.IoT Build 0:6ae2f7bca550 406 new_link_endpoint = NULL;
Azure.IoT Build 0:6ae2f7bca550 407 }
Azure.IoT Build 0:6ae2f7bca550 408 else
Azure.IoT Build 0:6ae2f7bca550 409 {
Azure.IoT Build 0:6ae2f7bca550 410 if (new_link_endpoint->frame_received_callback != NULL)
Azure.IoT Build 0:6ae2f7bca550 411 {
Azure.IoT Build 0:6ae2f7bca550 412 new_link_endpoint->frame_received_callback(new_link_endpoint->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 413 }
Azure.IoT Build 0:6ae2f7bca550 414 }
Azure.IoT Build 0:6ae2f7bca550 415 }
Azure.IoT Build 0:6ae2f7bca550 416 }
Azure.IoT Build 0:6ae2f7bca550 417 }
Azure.IoT Build 0:6ae2f7bca550 418 else
Azure.IoT Build 0:6ae2f7bca550 419 {
Azure.IoT Build 0:6ae2f7bca550 420 if (attach_get_handle(attach_handle, &link_endpoint->input_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 421 {
Azure.IoT Build 0:6ae2f7bca550 422 end_session_with_error(session_instance, "amqp:decode-error", "Cannot get input handle from ATTACH frame");
Azure.IoT Build 0:6ae2f7bca550 423 }
Azure.IoT Build 0:6ae2f7bca550 424 else
Azure.IoT Build 0:6ae2f7bca550 425 {
Azure.IoT Build 0:6ae2f7bca550 426 link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 427 }
Azure.IoT Build 0:6ae2f7bca550 428 }
Azure.IoT Build 0:6ae2f7bca550 429 }
Azure.IoT Build 0:6ae2f7bca550 430
Azure.IoT Build 0:6ae2f7bca550 431 attach_destroy(attach_handle);
Azure.IoT Build 0:6ae2f7bca550 432 }
Azure.IoT Build 0:6ae2f7bca550 433 }
Azure.IoT Build 0:6ae2f7bca550 434 else if (is_detach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 435 {
Azure.IoT Build 0:6ae2f7bca550 436 DETACH_HANDLE detach_handle;
Azure.IoT Build 0:6ae2f7bca550 437
Azure.IoT Build 0:6ae2f7bca550 438 if (amqpvalue_get_detach(performative, &detach_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 439 {
Azure.IoT Build 0:6ae2f7bca550 440 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode DETACH frame");
Azure.IoT Build 0:6ae2f7bca550 441 }
Azure.IoT Build 0:6ae2f7bca550 442 else
Azure.IoT Build 0:6ae2f7bca550 443 {
Azure.IoT Build 0:6ae2f7bca550 444 uint32_t remote_handle;
Azure.IoT Build 0:6ae2f7bca550 445 if (detach_get_handle(detach_handle, &remote_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 446 {
Azure.IoT Build 0:6ae2f7bca550 447 end_session_with_error(session_instance, "amqp:decode-error", "Cannot get handle from DETACH frame");
Azure.IoT Build 0:6ae2f7bca550 448
Azure.IoT Build 0:6ae2f7bca550 449 detach_destroy(detach_handle);
Azure.IoT Build 0:6ae2f7bca550 450 }
Azure.IoT Build 0:6ae2f7bca550 451 else
Azure.IoT Build 0:6ae2f7bca550 452 {
Azure.IoT Build 0:6ae2f7bca550 453 detach_destroy(detach_handle);
Azure.IoT Build 0:6ae2f7bca550 454
Azure.IoT Build 0:6ae2f7bca550 455 LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_input_handle(session_instance, remote_handle);
Azure.IoT Build 0:6ae2f7bca550 456 if (link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 457 {
Azure.IoT Build 0:6ae2f7bca550 458 end_session_with_error(session_instance, "amqp:session:unattached-handle", "");
Azure.IoT Build 0:6ae2f7bca550 459 }
Azure.IoT Build 0:6ae2f7bca550 460 else
Azure.IoT Build 0:6ae2f7bca550 461 {
Azure.IoT Build 0:6ae2f7bca550 462 link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 463 }
Azure.IoT Build 0:6ae2f7bca550 464 }
Azure.IoT Build 0:6ae2f7bca550 465 }
Azure.IoT Build 0:6ae2f7bca550 466 }
Azure.IoT Build 0:6ae2f7bca550 467 else if (is_flow_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 468 {
Azure.IoT Build 0:6ae2f7bca550 469 FLOW_HANDLE flow_handle;
Azure.IoT Build 0:6ae2f7bca550 470
Azure.IoT Build 0:6ae2f7bca550 471 if (amqpvalue_get_flow(performative, &flow_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 472 {
Azure.IoT Build 0:6ae2f7bca550 473 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode FLOW frame");
Azure.IoT Build 0:6ae2f7bca550 474 }
Azure.IoT Build 0:6ae2f7bca550 475 else
Azure.IoT Build 0:6ae2f7bca550 476 {
Azure.IoT Build 0:6ae2f7bca550 477 uint32_t remote_handle;
Azure.IoT Build 0:6ae2f7bca550 478 transfer_number flow_next_incoming_id;
Azure.IoT Build 0:6ae2f7bca550 479 uint32_t flow_incoming_window;
Azure.IoT Build 0:6ae2f7bca550 480
Azure.IoT Build 0:6ae2f7bca550 481 if (flow_get_next_incoming_id(flow_handle, &flow_next_incoming_id) != 0)
Azure.IoT Build 0:6ae2f7bca550 482 {
Azure.IoT Build 0:6ae2f7bca550 483 /*
Azure.IoT Build 0:6ae2f7bca550 484 If the next-incoming-id field of the flow frame is not set,
Azure.IoT Build 0:6ae2f7bca550 485 then remote-incomingwindow is computed as follows:
Azure.IoT Build 0:6ae2f7bca550 486 initial-outgoing-id(endpoint) + incoming-window(flow) - next-outgoing-id(endpoint)
Azure.IoT Build 0:6ae2f7bca550 487 */
Azure.IoT Build 0:6ae2f7bca550 488 flow_next_incoming_id = session_instance->next_outgoing_id;
Azure.IoT Build 0:6ae2f7bca550 489 }
Azure.IoT Build 0:6ae2f7bca550 490
Azure.IoT Build 0:6ae2f7bca550 491 if ((flow_get_next_outgoing_id(flow_handle, &session_instance->next_incoming_id) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 492 (flow_get_incoming_window(flow_handle, &flow_incoming_window) != 0))
Azure.IoT Build 0:6ae2f7bca550 493 {
Azure.IoT Build 0:6ae2f7bca550 494 flow_destroy(flow_handle);
Azure.IoT Build 0:6ae2f7bca550 495
Azure.IoT Build 0:6ae2f7bca550 496 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode FLOW frame");
Azure.IoT Build 0:6ae2f7bca550 497 }
Azure.IoT Build 0:6ae2f7bca550 498 else
Azure.IoT Build 0:6ae2f7bca550 499 {
Azure.IoT Build 0:6ae2f7bca550 500 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = NULL;
Azure.IoT Build 0:6ae2f7bca550 501
Azure.IoT Build 0:6ae2f7bca550 502 session_instance->remote_incoming_window = flow_next_incoming_id + flow_incoming_window - session_instance->next_outgoing_id;
Azure.IoT Build 0:6ae2f7bca550 503
Azure.IoT Build 0:6ae2f7bca550 504 if (flow_get_handle(flow_handle, &remote_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 505 {
Azure.IoT Build 0:6ae2f7bca550 506 link_endpoint_instance = find_link_endpoint_by_input_handle(session_instance, remote_handle);
Azure.IoT Build 0:6ae2f7bca550 507 }
Azure.IoT Build 0:6ae2f7bca550 508
Azure.IoT Build 0:6ae2f7bca550 509 flow_destroy(flow_handle);
Azure.IoT Build 0:6ae2f7bca550 510
Azure.IoT Build 0:6ae2f7bca550 511 if (link_endpoint_instance != NULL)
Azure.IoT Build 0:6ae2f7bca550 512 {
Azure.IoT Build 0:6ae2f7bca550 513 link_endpoint_instance->frame_received_callback(link_endpoint_instance->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 514 }
Azure.IoT Build 0:6ae2f7bca550 515
Azure.IoT Build 0:6ae2f7bca550 516 size_t i = 0;
Azure.IoT Build 0:6ae2f7bca550 517 while ((session_instance->remote_incoming_window > 0) && (i < session_instance->link_endpoint_count))
Azure.IoT Build 0:6ae2f7bca550 518 {
Azure.IoT Build 0:6ae2f7bca550 519 /* notify the caller that it can send here */
Azure.IoT Build 0:6ae2f7bca550 520 if (session_instance->link_endpoints[i]->on_session_flow_on != NULL)
Azure.IoT Build 0:6ae2f7bca550 521 {
Azure.IoT Build 0:6ae2f7bca550 522 session_instance->link_endpoints[i]->on_session_flow_on(session_instance->link_endpoints[i]->callback_context);
Azure.IoT Build 0:6ae2f7bca550 523 }
Azure.IoT Build 0:6ae2f7bca550 524
Azure.IoT Build 0:6ae2f7bca550 525 i++;
Azure.IoT Build 0:6ae2f7bca550 526 }
Azure.IoT Build 0:6ae2f7bca550 527 }
Azure.IoT Build 0:6ae2f7bca550 528 }
Azure.IoT Build 0:6ae2f7bca550 529 }
Azure.IoT Build 0:6ae2f7bca550 530 else if (is_transfer_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 531 {
Azure.IoT Build 0:6ae2f7bca550 532 TRANSFER_HANDLE transfer_handle;
Azure.IoT Build 0:6ae2f7bca550 533
Azure.IoT Build 0:6ae2f7bca550 534 if (amqpvalue_get_transfer(performative, &transfer_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 535 {
Azure.IoT Build 0:6ae2f7bca550 536 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode TRANSFER frame");
Azure.IoT Build 0:6ae2f7bca550 537 }
Azure.IoT Build 0:6ae2f7bca550 538 else
Azure.IoT Build 0:6ae2f7bca550 539 {
Azure.IoT Build 0:6ae2f7bca550 540 uint32_t remote_handle;
Azure.IoT Build 0:6ae2f7bca550 541 delivery_number delivery_id;
Azure.IoT Build 0:6ae2f7bca550 542
Azure.IoT Build 0:6ae2f7bca550 543 transfer_get_delivery_id(transfer_handle, &delivery_id);
Azure.IoT Build 0:6ae2f7bca550 544 if (transfer_get_handle(transfer_handle, &remote_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 545 {
Azure.IoT Build 0:6ae2f7bca550 546 transfer_destroy(transfer_handle);
Azure.IoT Build 0:6ae2f7bca550 547 end_session_with_error(session_instance, "amqp:decode-error", "Cannot get handle from TRANSFER frame");
Azure.IoT Build 0:6ae2f7bca550 548 }
Azure.IoT Build 0:6ae2f7bca550 549 else
Azure.IoT Build 0:6ae2f7bca550 550 {
Azure.IoT Build 0:6ae2f7bca550 551 transfer_destroy(transfer_handle);
Azure.IoT Build 0:6ae2f7bca550 552
Azure.IoT Build 0:6ae2f7bca550 553 session_instance->next_incoming_id++;
Azure.IoT Build 0:6ae2f7bca550 554 session_instance->remote_outgoing_window--;
Azure.IoT Build 0:6ae2f7bca550 555 session_instance->incoming_window--;
Azure.IoT Build 0:6ae2f7bca550 556
AzureIoTClient 12:b30dacf113f2 557 LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_input_handle(session_instance, remote_handle);
Azure.IoT Build 0:6ae2f7bca550 558 if (link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 559 {
Azure.IoT Build 0:6ae2f7bca550 560 end_session_with_error(session_instance, "amqp:session:unattached-handle", "");
Azure.IoT Build 0:6ae2f7bca550 561 }
Azure.IoT Build 0:6ae2f7bca550 562 else
Azure.IoT Build 0:6ae2f7bca550 563 {
Azure.IoT Build 0:6ae2f7bca550 564 link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 565 }
Azure.IoT Build 0:6ae2f7bca550 566
Azure.IoT Build 0:6ae2f7bca550 567 if (session_instance->incoming_window == 0)
Azure.IoT Build 0:6ae2f7bca550 568 {
Azure.IoT Build 0:6ae2f7bca550 569 session_instance->incoming_window = session_instance->desired_incoming_window;
Azure.IoT Build 0:6ae2f7bca550 570 send_flow(session_instance);
Azure.IoT Build 0:6ae2f7bca550 571 }
Azure.IoT Build 0:6ae2f7bca550 572 }
Azure.IoT Build 0:6ae2f7bca550 573 }
Azure.IoT Build 0:6ae2f7bca550 574 }
Azure.IoT Build 0:6ae2f7bca550 575 else if (is_disposition_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 576 {
Azure.IoT Build 0:6ae2f7bca550 577 uint32_t i;
Azure.IoT Build 0:6ae2f7bca550 578
Azure.IoT Build 0:6ae2f7bca550 579 for (i = 0; i < session_instance->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 580 {
Azure.IoT Build 0:6ae2f7bca550 581 LINK_ENDPOINT_INSTANCE* link_endpoint = session_instance->link_endpoints[i];
Azure.IoT Build 0:6ae2f7bca550 582 link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 583 }
Azure.IoT Build 0:6ae2f7bca550 584 }
Azure.IoT Build 0:6ae2f7bca550 585 else if (is_end_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 586 {
Azure.IoT Build 0:6ae2f7bca550 587 END_HANDLE end_handle;
Azure.IoT Build 0:6ae2f7bca550 588
Azure.IoT Build 0:6ae2f7bca550 589 if (amqpvalue_get_end(performative, &end_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 590 {
Azure.IoT Build 0:6ae2f7bca550 591 end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode END frame");
Azure.IoT Build 0:6ae2f7bca550 592 }
Azure.IoT Build 0:6ae2f7bca550 593 else
Azure.IoT Build 0:6ae2f7bca550 594 {
Azure.IoT Build 0:6ae2f7bca550 595 if ((session_instance->session_state != SESSION_STATE_END_RCVD) &&
Azure.IoT Build 0:6ae2f7bca550 596 (session_instance->session_state != SESSION_STATE_DISCARDING))
Azure.IoT Build 0:6ae2f7bca550 597 {
Azure.IoT Build 0:6ae2f7bca550 598 session_set_state(session_instance, SESSION_STATE_END_RCVD);
Azure.IoT Build 0:6ae2f7bca550 599 if (send_end_frame(session_instance, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 600 {
Azure.IoT Build 0:6ae2f7bca550 601 /* fatal error */
Azure.IoT Build 0:6ae2f7bca550 602 (void)connection_close(session_instance->connection, "amqp:internal-error", "Cannot send END frame.");
Azure.IoT Build 0:6ae2f7bca550 603 }
Azure.IoT Build 0:6ae2f7bca550 604
Azure.IoT Build 0:6ae2f7bca550 605 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 606 }
Azure.IoT Build 0:6ae2f7bca550 607 }
Azure.IoT Build 0:6ae2f7bca550 608 }
Azure.IoT Build 0:6ae2f7bca550 609 }
Azure.IoT Build 0:6ae2f7bca550 610
Azure.IoT Build 0:6ae2f7bca550 611 SESSION_HANDLE session_create(CONNECTION_HANDLE connection, ON_LINK_ATTACHED on_link_attached, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 612 {
Azure.IoT Build 0:6ae2f7bca550 613 SESSION_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 614
Azure.IoT Build 0:6ae2f7bca550 615 if (connection == NULL)
Azure.IoT Build 0:6ae2f7bca550 616 {
Azure.IoT Build 0:6ae2f7bca550 617 /* Codes_SRS_SESSION_01_031: [If connection is NULL, session_create shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 618 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 619 }
Azure.IoT Build 0:6ae2f7bca550 620 else
Azure.IoT Build 0:6ae2f7bca550 621 {
Azure.IoT Build 0:6ae2f7bca550 622 /* Codes_SRS_SESSION_01_030: [session_create shall create a new session instance and return a non-NULL handle to it.] */
AzureIoTClient 23:1111ee8bcba4 623 result = (SESSION_INSTANCE*)malloc(sizeof(SESSION_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 624 /* Codes_SRS_SESSION_01_042: [If allocating memory for the session fails, session_create shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 625 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 626 {
Azure.IoT Build 0:6ae2f7bca550 627 result->connection = connection;
Azure.IoT Build 0:6ae2f7bca550 628 result->link_endpoints = NULL;
Azure.IoT Build 0:6ae2f7bca550 629 result->link_endpoint_count = 0;
Azure.IoT Build 0:6ae2f7bca550 630 result->handle_max = 4294967295u;
Azure.IoT Build 0:6ae2f7bca550 631
Azure.IoT Build 0:6ae2f7bca550 632 /* Codes_SRS_SESSION_01_057: [The delivery ids shall be assigned starting at 0.] */
Azure.IoT Build 0:6ae2f7bca550 633 /* Codes_SRS_SESSION_01_017: [The nextoutgoing-id MAY be initialized to an arbitrary value ] */
Azure.IoT Build 0:6ae2f7bca550 634 result->next_outgoing_id = 0;
Azure.IoT Build 0:6ae2f7bca550 635
Azure.IoT Build 0:6ae2f7bca550 636 result->desired_incoming_window = 1;
Azure.IoT Build 0:6ae2f7bca550 637 result->incoming_window = 1;
Azure.IoT Build 0:6ae2f7bca550 638 result->outgoing_window = 1;
Azure.IoT Build 0:6ae2f7bca550 639 result->handle_max = 4294967295u;
Azure.IoT Build 0:6ae2f7bca550 640 result->remote_incoming_window = 0;
Azure.IoT Build 0:6ae2f7bca550 641 result->remote_outgoing_window = 0;
Azure.IoT Build 0:6ae2f7bca550 642 result->previous_session_state = SESSION_STATE_UNMAPPED;
AzureIoTClient 6:641a9672db08 643 result->is_underlying_connection_open = UNDERLYING_CONNECTION_NOT_OPEN;
Azure.IoT Build 0:6ae2f7bca550 644 result->session_state = SESSION_STATE_UNMAPPED;
Azure.IoT Build 0:6ae2f7bca550 645 result->on_link_attached = on_link_attached;
Azure.IoT Build 0:6ae2f7bca550 646 result->on_link_attached_callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 647
Azure.IoT Build 0:6ae2f7bca550 648 /* Codes_SRS_SESSION_01_032: [session_create shall create a new session endpoint by calling connection_create_endpoint.] */
Azure.IoT Build 0:6ae2f7bca550 649 result->endpoint = connection_create_endpoint(connection);
Azure.IoT Build 0:6ae2f7bca550 650 if (result->endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 651 {
Azure.IoT Build 0:6ae2f7bca550 652 /* Codes_SRS_SESSION_01_033: [If connection_create_endpoint fails, session_create shall fail and return NULL.] */
AzureIoTClient 21:f9c433d8e6ca 653 free(result);
Azure.IoT Build 0:6ae2f7bca550 654 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 655 }
Azure.IoT Build 0:6ae2f7bca550 656 else
Azure.IoT Build 0:6ae2f7bca550 657 {
Azure.IoT Build 0:6ae2f7bca550 658 session_set_state(result, SESSION_STATE_UNMAPPED);
Azure.IoT Build 0:6ae2f7bca550 659 }
Azure.IoT Build 0:6ae2f7bca550 660 }
Azure.IoT Build 0:6ae2f7bca550 661 }
Azure.IoT Build 0:6ae2f7bca550 662
Azure.IoT Build 0:6ae2f7bca550 663 return result;
Azure.IoT Build 0:6ae2f7bca550 664 }
Azure.IoT Build 0:6ae2f7bca550 665
Azure.IoT Build 0:6ae2f7bca550 666 SESSION_HANDLE session_create_from_endpoint(CONNECTION_HANDLE connection, ENDPOINT_HANDLE endpoint, ON_LINK_ATTACHED on_link_attached, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 667 {
Azure.IoT Build 0:6ae2f7bca550 668 SESSION_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 669
Azure.IoT Build 0:6ae2f7bca550 670 if (endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 671 {
Azure.IoT Build 0:6ae2f7bca550 672 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 673 }
Azure.IoT Build 0:6ae2f7bca550 674 else
Azure.IoT Build 0:6ae2f7bca550 675 {
AzureIoTClient 23:1111ee8bcba4 676 result = (SESSION_INSTANCE*)malloc(sizeof(SESSION_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 677 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 678 {
Azure.IoT Build 0:6ae2f7bca550 679 result->connection = connection;
Azure.IoT Build 0:6ae2f7bca550 680 result->link_endpoints = NULL;
Azure.IoT Build 0:6ae2f7bca550 681 result->link_endpoint_count = 0;
Azure.IoT Build 0:6ae2f7bca550 682 result->handle_max = 4294967295u;
Azure.IoT Build 0:6ae2f7bca550 683
Azure.IoT Build 0:6ae2f7bca550 684 result->next_outgoing_id = 0;
Azure.IoT Build 0:6ae2f7bca550 685
AzureIoTClient 22:524bded3f7a8 686 result->desired_incoming_window = 1;
AzureIoTClient 22:524bded3f7a8 687 result->incoming_window = 1;
Azure.IoT Build 0:6ae2f7bca550 688 result->outgoing_window = 1;
Azure.IoT Build 0:6ae2f7bca550 689 result->handle_max = 4294967295u;
Azure.IoT Build 0:6ae2f7bca550 690 result->remote_incoming_window = 0;
Azure.IoT Build 0:6ae2f7bca550 691 result->remote_outgoing_window = 0;
Azure.IoT Build 0:6ae2f7bca550 692 result->previous_session_state = SESSION_STATE_UNMAPPED;
AzureIoTClient 6:641a9672db08 693 result->is_underlying_connection_open = UNDERLYING_CONNECTION_NOT_OPEN;
Azure.IoT Build 0:6ae2f7bca550 694 result->session_state = SESSION_STATE_UNMAPPED;
Azure.IoT Build 0:6ae2f7bca550 695 result->on_link_attached = on_link_attached;
Azure.IoT Build 0:6ae2f7bca550 696 result->on_link_attached_callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 697
Azure.IoT Build 0:6ae2f7bca550 698 result->endpoint = endpoint;
Azure.IoT Build 0:6ae2f7bca550 699 session_set_state(result, SESSION_STATE_UNMAPPED);
Azure.IoT Build 0:6ae2f7bca550 700 }
Azure.IoT Build 0:6ae2f7bca550 701 }
Azure.IoT Build 0:6ae2f7bca550 702
Azure.IoT Build 0:6ae2f7bca550 703 return result;
Azure.IoT Build 0:6ae2f7bca550 704 }
Azure.IoT Build 0:6ae2f7bca550 705
Azure.IoT Build 0:6ae2f7bca550 706 void session_destroy(SESSION_HANDLE session)
Azure.IoT Build 0:6ae2f7bca550 707 {
Azure.IoT Build 0:6ae2f7bca550 708 /* Codes_SRS_SESSION_01_036: [If session is NULL, session_destroy shall do nothing.] */
Azure.IoT Build 0:6ae2f7bca550 709 if (session != NULL)
Azure.IoT Build 0:6ae2f7bca550 710 {
Azure.IoT Build 0:6ae2f7bca550 711 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 712
Azure.IoT Build 0:6ae2f7bca550 713 session_end(session, NULL, NULL);
Azure.IoT Build 0:6ae2f7bca550 714
Azure.IoT Build 0:6ae2f7bca550 715 /* Codes_SRS_SESSION_01_034: [session_destroy shall free all resources allocated by session_create.] */
Azure.IoT Build 0:6ae2f7bca550 716 /* Codes_SRS_SESSION_01_035: [The endpoint created in session_create shall be freed by calling connection_destroy_endpoint.] */
Azure.IoT Build 0:6ae2f7bca550 717 connection_destroy_endpoint(session_instance->endpoint);
Azure.IoT Build 0:6ae2f7bca550 718 if (session_instance->link_endpoints != NULL)
Azure.IoT Build 0:6ae2f7bca550 719 {
AzureIoTClient 21:f9c433d8e6ca 720 free(session_instance->link_endpoints);
Azure.IoT Build 0:6ae2f7bca550 721 }
Azure.IoT Build 0:6ae2f7bca550 722
AzureIoTClient 21:f9c433d8e6ca 723 free(session);
Azure.IoT Build 0:6ae2f7bca550 724 }
Azure.IoT Build 0:6ae2f7bca550 725 }
Azure.IoT Build 0:6ae2f7bca550 726
Azure.IoT Build 0:6ae2f7bca550 727 int session_begin(SESSION_HANDLE session)
Azure.IoT Build 0:6ae2f7bca550 728 {
Azure.IoT Build 0:6ae2f7bca550 729 int result;
Azure.IoT Build 0:6ae2f7bca550 730
Azure.IoT Build 0:6ae2f7bca550 731 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 732 {
AzureIoTClient 19:000ab4e6a2c1 733 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 734 }
Azure.IoT Build 0:6ae2f7bca550 735 else
Azure.IoT Build 0:6ae2f7bca550 736 {
Azure.IoT Build 0:6ae2f7bca550 737 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 738
Azure.IoT Build 0:6ae2f7bca550 739 if (connection_start_endpoint(session_instance->endpoint, on_frame_received, on_connection_state_changed, session_instance) != 0)
Azure.IoT Build 0:6ae2f7bca550 740 {
AzureIoTClient 19:000ab4e6a2c1 741 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 742 }
Azure.IoT Build 0:6ae2f7bca550 743 else
Azure.IoT Build 0:6ae2f7bca550 744 {
Azure.IoT Build 0:6ae2f7bca550 745 if (!session_instance->is_underlying_connection_open)
Azure.IoT Build 0:6ae2f7bca550 746 {
Azure.IoT Build 0:6ae2f7bca550 747 if (connection_open(session_instance->connection) != 0)
Azure.IoT Build 0:6ae2f7bca550 748 {
AzureIoTClient 6:641a9672db08 749 session_instance->is_underlying_connection_open = UNDERLYING_CONNECTION_NOT_OPEN;
AzureIoTClient 19:000ab4e6a2c1 750 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 751 }
Azure.IoT Build 0:6ae2f7bca550 752 else
Azure.IoT Build 0:6ae2f7bca550 753 {
AzureIoTClient 6:641a9672db08 754 session_instance->is_underlying_connection_open = UNDERLYING_CONNECTION_OPEN;
Azure.IoT Build 0:6ae2f7bca550 755 result = 0;
Azure.IoT Build 0:6ae2f7bca550 756 }
Azure.IoT Build 0:6ae2f7bca550 757 }
Azure.IoT Build 0:6ae2f7bca550 758 else
Azure.IoT Build 0:6ae2f7bca550 759 {
Azure.IoT Build 0:6ae2f7bca550 760 result = 0;
Azure.IoT Build 0:6ae2f7bca550 761 }
Azure.IoT Build 0:6ae2f7bca550 762 }
Azure.IoT Build 0:6ae2f7bca550 763 }
Azure.IoT Build 0:6ae2f7bca550 764
Azure.IoT Build 0:6ae2f7bca550 765 return result;
Azure.IoT Build 0:6ae2f7bca550 766 }
Azure.IoT Build 0:6ae2f7bca550 767
Azure.IoT Build 0:6ae2f7bca550 768 int session_end(SESSION_HANDLE session, const char* condition_value, const char* description)
Azure.IoT Build 0:6ae2f7bca550 769 {
Azure.IoT Build 0:6ae2f7bca550 770 int result;
Azure.IoT Build 0:6ae2f7bca550 771
Azure.IoT Build 0:6ae2f7bca550 772 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 773 {
AzureIoTClient 19:000ab4e6a2c1 774 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 775 }
Azure.IoT Build 0:6ae2f7bca550 776 else
Azure.IoT Build 0:6ae2f7bca550 777 {
Azure.IoT Build 0:6ae2f7bca550 778 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 779
Azure.IoT Build 0:6ae2f7bca550 780 if ((session_instance->session_state != SESSION_STATE_UNMAPPED) &&
Azure.IoT Build 0:6ae2f7bca550 781 (session_instance->session_state != SESSION_STATE_DISCARDING))
Azure.IoT Build 0:6ae2f7bca550 782 {
Azure.IoT Build 0:6ae2f7bca550 783 ERROR_HANDLE error_handle = NULL;
Azure.IoT Build 0:6ae2f7bca550 784 result = 0;
Azure.IoT Build 0:6ae2f7bca550 785
Azure.IoT Build 0:6ae2f7bca550 786 if (condition_value != NULL)
Azure.IoT Build 0:6ae2f7bca550 787 {
Azure.IoT Build 0:6ae2f7bca550 788 error_handle = error_create(condition_value);
Azure.IoT Build 0:6ae2f7bca550 789 if (error_handle == NULL)
Azure.IoT Build 0:6ae2f7bca550 790 {
AzureIoTClient 19:000ab4e6a2c1 791 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 792 }
Azure.IoT Build 0:6ae2f7bca550 793 else
Azure.IoT Build 0:6ae2f7bca550 794 {
Azure.IoT Build 0:6ae2f7bca550 795 if (error_set_description(error_handle, description) != 0)
Azure.IoT Build 0:6ae2f7bca550 796 {
AzureIoTClient 19:000ab4e6a2c1 797 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 798 }
Azure.IoT Build 0:6ae2f7bca550 799 }
Azure.IoT Build 0:6ae2f7bca550 800 }
Azure.IoT Build 0:6ae2f7bca550 801
Azure.IoT Build 0:6ae2f7bca550 802 if (result == 0)
Azure.IoT Build 0:6ae2f7bca550 803 {
Azure.IoT Build 0:6ae2f7bca550 804 if (send_end_frame(session_instance, error_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 805 {
AzureIoTClient 19:000ab4e6a2c1 806 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 807 }
Azure.IoT Build 0:6ae2f7bca550 808 else
Azure.IoT Build 0:6ae2f7bca550 809 {
Azure.IoT Build 0:6ae2f7bca550 810 session_set_state(session_instance, SESSION_STATE_DISCARDING);
Azure.IoT Build 0:6ae2f7bca550 811 result = 0;
Azure.IoT Build 0:6ae2f7bca550 812 }
Azure.IoT Build 0:6ae2f7bca550 813 }
Azure.IoT Build 0:6ae2f7bca550 814
Azure.IoT Build 0:6ae2f7bca550 815 if (error_handle != NULL)
Azure.IoT Build 0:6ae2f7bca550 816 {
Azure.IoT Build 0:6ae2f7bca550 817 error_destroy(error_handle);
Azure.IoT Build 0:6ae2f7bca550 818 }
Azure.IoT Build 0:6ae2f7bca550 819 }
Azure.IoT Build 0:6ae2f7bca550 820 else
Azure.IoT Build 0:6ae2f7bca550 821 {
Azure.IoT Build 0:6ae2f7bca550 822 result = 0;
Azure.IoT Build 0:6ae2f7bca550 823 }
Azure.IoT Build 0:6ae2f7bca550 824 }
Azure.IoT Build 0:6ae2f7bca550 825
Azure.IoT Build 0:6ae2f7bca550 826 return result;
Azure.IoT Build 0:6ae2f7bca550 827 }
Azure.IoT Build 0:6ae2f7bca550 828
Azure.IoT Build 0:6ae2f7bca550 829 int session_set_incoming_window(SESSION_HANDLE session, uint32_t incoming_window)
Azure.IoT Build 0:6ae2f7bca550 830 {
Azure.IoT Build 0:6ae2f7bca550 831 int result;
Azure.IoT Build 0:6ae2f7bca550 832
Azure.IoT Build 0:6ae2f7bca550 833 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 834 {
AzureIoTClient 19:000ab4e6a2c1 835 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 836 }
Azure.IoT Build 0:6ae2f7bca550 837 else
Azure.IoT Build 0:6ae2f7bca550 838 {
Azure.IoT Build 0:6ae2f7bca550 839 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 840
Azure.IoT Build 0:6ae2f7bca550 841 session_instance->desired_incoming_window = incoming_window;
Azure.IoT Build 0:6ae2f7bca550 842 session_instance->incoming_window = incoming_window;
Azure.IoT Build 0:6ae2f7bca550 843
Azure.IoT Build 0:6ae2f7bca550 844 result = 0;
Azure.IoT Build 0:6ae2f7bca550 845 }
Azure.IoT Build 0:6ae2f7bca550 846
Azure.IoT Build 0:6ae2f7bca550 847 return result;
Azure.IoT Build 0:6ae2f7bca550 848 }
Azure.IoT Build 0:6ae2f7bca550 849
Azure.IoT Build 0:6ae2f7bca550 850 int session_get_incoming_window(SESSION_HANDLE session, uint32_t* incoming_window)
Azure.IoT Build 0:6ae2f7bca550 851 {
Azure.IoT Build 0:6ae2f7bca550 852 int result;
Azure.IoT Build 0:6ae2f7bca550 853
Azure.IoT Build 0:6ae2f7bca550 854 if ((session == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 855 (incoming_window == NULL))
Azure.IoT Build 0:6ae2f7bca550 856 {
AzureIoTClient 19:000ab4e6a2c1 857 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 858 }
Azure.IoT Build 0:6ae2f7bca550 859 else
Azure.IoT Build 0:6ae2f7bca550 860 {
Azure.IoT Build 0:6ae2f7bca550 861 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 862
Azure.IoT Build 0:6ae2f7bca550 863 *incoming_window = session_instance->incoming_window;
Azure.IoT Build 0:6ae2f7bca550 864
Azure.IoT Build 0:6ae2f7bca550 865 result = 0;
Azure.IoT Build 0:6ae2f7bca550 866 }
Azure.IoT Build 0:6ae2f7bca550 867
Azure.IoT Build 0:6ae2f7bca550 868 return result;
Azure.IoT Build 0:6ae2f7bca550 869 }
Azure.IoT Build 0:6ae2f7bca550 870
Azure.IoT Build 0:6ae2f7bca550 871 int session_set_outgoing_window(SESSION_HANDLE session, uint32_t outgoing_window)
Azure.IoT Build 0:6ae2f7bca550 872 {
Azure.IoT Build 0:6ae2f7bca550 873 int result;
Azure.IoT Build 0:6ae2f7bca550 874
Azure.IoT Build 0:6ae2f7bca550 875 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 876 {
AzureIoTClient 19:000ab4e6a2c1 877 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 878 }
Azure.IoT Build 0:6ae2f7bca550 879 else
Azure.IoT Build 0:6ae2f7bca550 880 {
Azure.IoT Build 0:6ae2f7bca550 881 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 882
Azure.IoT Build 0:6ae2f7bca550 883 session_instance->outgoing_window = outgoing_window;
Azure.IoT Build 0:6ae2f7bca550 884
Azure.IoT Build 0:6ae2f7bca550 885 result = 0;
Azure.IoT Build 0:6ae2f7bca550 886 }
Azure.IoT Build 0:6ae2f7bca550 887
Azure.IoT Build 0:6ae2f7bca550 888 return result;
Azure.IoT Build 0:6ae2f7bca550 889 }
Azure.IoT Build 0:6ae2f7bca550 890
Azure.IoT Build 0:6ae2f7bca550 891 int session_get_outgoing_window(SESSION_HANDLE session, uint32_t* outgoing_window)
Azure.IoT Build 0:6ae2f7bca550 892 {
Azure.IoT Build 0:6ae2f7bca550 893 int result;
Azure.IoT Build 0:6ae2f7bca550 894
Azure.IoT Build 0:6ae2f7bca550 895 if ((session == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 896 (outgoing_window == NULL))
Azure.IoT Build 0:6ae2f7bca550 897 {
AzureIoTClient 19:000ab4e6a2c1 898 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 899 }
Azure.IoT Build 0:6ae2f7bca550 900 else
Azure.IoT Build 0:6ae2f7bca550 901 {
Azure.IoT Build 0:6ae2f7bca550 902 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 903
Azure.IoT Build 0:6ae2f7bca550 904 *outgoing_window = session_instance->outgoing_window;
Azure.IoT Build 0:6ae2f7bca550 905
Azure.IoT Build 0:6ae2f7bca550 906 result = 0;
Azure.IoT Build 0:6ae2f7bca550 907 }
Azure.IoT Build 0:6ae2f7bca550 908
Azure.IoT Build 0:6ae2f7bca550 909 return result;
Azure.IoT Build 0:6ae2f7bca550 910 }
Azure.IoT Build 0:6ae2f7bca550 911
Azure.IoT Build 0:6ae2f7bca550 912 int session_set_handle_max(SESSION_HANDLE session, handle handle_max)
Azure.IoT Build 0:6ae2f7bca550 913 {
Azure.IoT Build 0:6ae2f7bca550 914 int result;
Azure.IoT Build 0:6ae2f7bca550 915
Azure.IoT Build 0:6ae2f7bca550 916 if (session == NULL)
Azure.IoT Build 0:6ae2f7bca550 917 {
AzureIoTClient 19:000ab4e6a2c1 918 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 919 }
Azure.IoT Build 0:6ae2f7bca550 920 else
Azure.IoT Build 0:6ae2f7bca550 921 {
Azure.IoT Build 0:6ae2f7bca550 922 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 923
Azure.IoT Build 0:6ae2f7bca550 924 session_instance->handle_max = handle_max;
Azure.IoT Build 0:6ae2f7bca550 925
Azure.IoT Build 0:6ae2f7bca550 926 result = 0;
Azure.IoT Build 0:6ae2f7bca550 927 }
Azure.IoT Build 0:6ae2f7bca550 928
Azure.IoT Build 0:6ae2f7bca550 929 return result;
Azure.IoT Build 0:6ae2f7bca550 930 }
Azure.IoT Build 0:6ae2f7bca550 931
Azure.IoT Build 0:6ae2f7bca550 932 int session_get_handle_max(SESSION_HANDLE session, handle* handle_max)
Azure.IoT Build 0:6ae2f7bca550 933 {
Azure.IoT Build 0:6ae2f7bca550 934 int result;
Azure.IoT Build 0:6ae2f7bca550 935
Azure.IoT Build 0:6ae2f7bca550 936 if ((session == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 937 (handle_max == NULL))
Azure.IoT Build 0:6ae2f7bca550 938 {
AzureIoTClient 19:000ab4e6a2c1 939 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 940 }
Azure.IoT Build 0:6ae2f7bca550 941 else
Azure.IoT Build 0:6ae2f7bca550 942 {
Azure.IoT Build 0:6ae2f7bca550 943 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 944
Azure.IoT Build 0:6ae2f7bca550 945 *handle_max = session_instance->handle_max;
Azure.IoT Build 0:6ae2f7bca550 946
Azure.IoT Build 0:6ae2f7bca550 947 result = 0;
Azure.IoT Build 0:6ae2f7bca550 948 }
Azure.IoT Build 0:6ae2f7bca550 949
Azure.IoT Build 0:6ae2f7bca550 950 return result;
Azure.IoT Build 0:6ae2f7bca550 951 }
Azure.IoT Build 0:6ae2f7bca550 952
Azure.IoT Build 0:6ae2f7bca550 953 LINK_ENDPOINT_HANDLE session_create_link_endpoint(SESSION_HANDLE session, const char* name)
Azure.IoT Build 0:6ae2f7bca550 954 {
Azure.IoT Build 0:6ae2f7bca550 955 LINK_ENDPOINT_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 956
Azure.IoT Build 0:6ae2f7bca550 957 /* Codes_SRS_SESSION_01_044: [If session, name or frame_received_callback is NULL, session_create_link_endpoint shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 958 if ((session == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 959 (name == NULL))
Azure.IoT Build 0:6ae2f7bca550 960 {
Azure.IoT Build 0:6ae2f7bca550 961 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 962 }
Azure.IoT Build 0:6ae2f7bca550 963 else
Azure.IoT Build 0:6ae2f7bca550 964 {
Azure.IoT Build 0:6ae2f7bca550 965 /* Codes_SRS_SESSION_01_043: [session_create_link_endpoint shall create a link endpoint associated with a given session and return a non-NULL handle to it.] */
Azure.IoT Build 0:6ae2f7bca550 966 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
Azure.IoT Build 0:6ae2f7bca550 967
AzureIoTClient 21:f9c433d8e6ca 968 result = (LINK_ENDPOINT_INSTANCE*)malloc(sizeof(LINK_ENDPOINT_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 969 /* Codes_SRS_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 970 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 971 {
Azure.IoT Build 0:6ae2f7bca550 972 /* Codes_SRS_SESSION_01_046: [An unused handle shall be assigned to the link endpoint.] */
Azure.IoT Build 0:6ae2f7bca550 973 handle selected_handle = 0;
Azure.IoT Build 0:6ae2f7bca550 974 size_t i;
AzureIoTClient 23:1111ee8bcba4 975 size_t name_length;
Azure.IoT Build 0:6ae2f7bca550 976
Azure.IoT Build 0:6ae2f7bca550 977 for (i = 0; i < session_instance->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 978 {
Azure.IoT Build 0:6ae2f7bca550 979 if (session_instance->link_endpoints[i]->output_handle > selected_handle)
Azure.IoT Build 0:6ae2f7bca550 980 {
Azure.IoT Build 0:6ae2f7bca550 981 break;
Azure.IoT Build 0:6ae2f7bca550 982 }
Azure.IoT Build 0:6ae2f7bca550 983
Azure.IoT Build 0:6ae2f7bca550 984 selected_handle++;
Azure.IoT Build 0:6ae2f7bca550 985 }
Azure.IoT Build 0:6ae2f7bca550 986
Azure.IoT Build 0:6ae2f7bca550 987 result->on_session_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 988 result->on_session_flow_on = NULL;
Azure.IoT Build 0:6ae2f7bca550 989 result->frame_received_callback = NULL;
Azure.IoT Build 0:6ae2f7bca550 990 result->callback_context = NULL;
Azure.IoT Build 0:6ae2f7bca550 991 result->output_handle = selected_handle;
AzureIoTClient 13:9abd748f4e78 992 result->input_handle = 0xFFFFFFFF;
AzureIoTClient 23:1111ee8bcba4 993 name_length = strlen(name);
AzureIoTClient 23:1111ee8bcba4 994 result->name = (char*)malloc(name_length + 1);
Azure.IoT Build 0:6ae2f7bca550 995 if (result->name == NULL)
Azure.IoT Build 0:6ae2f7bca550 996 {
Azure.IoT Build 0:6ae2f7bca550 997 /* Codes_SRS_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
AzureIoTClient 21:f9c433d8e6ca 998 free(result);
Azure.IoT Build 0:6ae2f7bca550 999 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 1000 }
Azure.IoT Build 0:6ae2f7bca550 1001 else
Azure.IoT Build 0:6ae2f7bca550 1002 {
Azure.IoT Build 0:6ae2f7bca550 1003 LINK_ENDPOINT_INSTANCE** new_link_endpoints;
AzureIoTClient 23:1111ee8bcba4 1004 (void)memcpy(result->name, name, name_length + 1);
Azure.IoT Build 0:6ae2f7bca550 1005 result->session = session;
Azure.IoT Build 0:6ae2f7bca550 1006
AzureIoTClient 23:1111ee8bcba4 1007 new_link_endpoints = (LINK_ENDPOINT_INSTANCE**)realloc(session_instance->link_endpoints, sizeof(LINK_ENDPOINT_INSTANCE*) * (session_instance->link_endpoint_count + 1));
Azure.IoT Build 0:6ae2f7bca550 1008 if (new_link_endpoints == NULL)
Azure.IoT Build 0:6ae2f7bca550 1009 {
Azure.IoT Build 0:6ae2f7bca550 1010 /* Codes_SRS_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
AzureIoTClient 21:f9c433d8e6ca 1011 free(result->name);
AzureIoTClient 21:f9c433d8e6ca 1012 free(result);
Azure.IoT Build 0:6ae2f7bca550 1013 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 1014 }
Azure.IoT Build 0:6ae2f7bca550 1015 else
Azure.IoT Build 0:6ae2f7bca550 1016 {
Azure.IoT Build 0:6ae2f7bca550 1017 session_instance->link_endpoints = new_link_endpoints;
Azure.IoT Build 0:6ae2f7bca550 1018
Azure.IoT Build 0:6ae2f7bca550 1019 if (session_instance->link_endpoint_count - selected_handle > 0)
Azure.IoT Build 0:6ae2f7bca550 1020 {
AzureIoTClient 7:9e9ab3b0efef 1021 (void)memmove(&session_instance->link_endpoints[selected_handle + 1], &session_instance->link_endpoints[selected_handle], (session_instance->link_endpoint_count - selected_handle) * sizeof(LINK_ENDPOINT_INSTANCE*));
Azure.IoT Build 0:6ae2f7bca550 1022 }
Azure.IoT Build 0:6ae2f7bca550 1023
Azure.IoT Build 0:6ae2f7bca550 1024 session_instance->link_endpoints[selected_handle] = result;
Azure.IoT Build 0:6ae2f7bca550 1025 session_instance->link_endpoint_count++;
Azure.IoT Build 0:6ae2f7bca550 1026 }
Azure.IoT Build 0:6ae2f7bca550 1027 }
Azure.IoT Build 0:6ae2f7bca550 1028 }
Azure.IoT Build 0:6ae2f7bca550 1029 }
Azure.IoT Build 0:6ae2f7bca550 1030
Azure.IoT Build 0:6ae2f7bca550 1031 return result;
Azure.IoT Build 0:6ae2f7bca550 1032 }
Azure.IoT Build 0:6ae2f7bca550 1033
Azure.IoT Build 0:6ae2f7bca550 1034 void session_destroy_link_endpoint(LINK_ENDPOINT_HANDLE link_endpoint)
Azure.IoT Build 0:6ae2f7bca550 1035 {
Azure.IoT Build 0:6ae2f7bca550 1036 /* Codes_SRS_SESSION_01_050: [If link_endpoint is NULL, session_destroy_link_endpoint shall do nothing.] */
Azure.IoT Build 0:6ae2f7bca550 1037 if (link_endpoint != NULL)
Azure.IoT Build 0:6ae2f7bca550 1038 {
Azure.IoT Build 0:6ae2f7bca550 1039 LINK_ENDPOINT_INSTANCE* endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1040 SESSION_INSTANCE* session_instance = endpoint_instance->session;
Azure.IoT Build 0:6ae2f7bca550 1041 uint64_t i;
Azure.IoT Build 0:6ae2f7bca550 1042
Azure.IoT Build 0:6ae2f7bca550 1043 /* Codes_SRS_SESSION_01_049: [session_destroy_link_endpoint shall free all resources associated with the endpoint.] */
Azure.IoT Build 0:6ae2f7bca550 1044 for (i = 0; i < session_instance->link_endpoint_count; i++)
Azure.IoT Build 0:6ae2f7bca550 1045 {
Azure.IoT Build 0:6ae2f7bca550 1046 if (session_instance->link_endpoints[i] == link_endpoint)
Azure.IoT Build 0:6ae2f7bca550 1047 {
Azure.IoT Build 0:6ae2f7bca550 1048 break;
Azure.IoT Build 0:6ae2f7bca550 1049 }
Azure.IoT Build 0:6ae2f7bca550 1050 }
Azure.IoT Build 0:6ae2f7bca550 1051
Azure.IoT Build 0:6ae2f7bca550 1052 if (i < session_instance->link_endpoint_count)
Azure.IoT Build 0:6ae2f7bca550 1053 {
Azure.IoT Build 0:6ae2f7bca550 1054 LINK_ENDPOINT_INSTANCE** new_endpoints;
Azure.IoT Build 0:6ae2f7bca550 1055
AzureIoTClient 12:b30dacf113f2 1056 if (i < (session_instance->link_endpoint_count - 1))
AzureIoTClient 12:b30dacf113f2 1057 {
AzureIoTClient 7:9e9ab3b0efef 1058 (void)memmove(&session_instance->link_endpoints[i], &session_instance->link_endpoints[i + 1], (session_instance->link_endpoint_count - (uint32_t)i - 1) * sizeof(LINK_ENDPOINT_INSTANCE*));
AzureIoTClient 7:9e9ab3b0efef 1059 }
AzureIoTClient 7:9e9ab3b0efef 1060
Azure.IoT Build 0:6ae2f7bca550 1061 session_instance->link_endpoint_count--;
Azure.IoT Build 0:6ae2f7bca550 1062
Azure.IoT Build 0:6ae2f7bca550 1063 if (session_instance->link_endpoint_count == 0)
Azure.IoT Build 0:6ae2f7bca550 1064 {
AzureIoTClient 21:f9c433d8e6ca 1065 free(session_instance->link_endpoints);
Azure.IoT Build 0:6ae2f7bca550 1066 session_instance->link_endpoints = NULL;
Azure.IoT Build 0:6ae2f7bca550 1067 }
Azure.IoT Build 0:6ae2f7bca550 1068 else
Azure.IoT Build 0:6ae2f7bca550 1069 {
AzureIoTClient 21:f9c433d8e6ca 1070 new_endpoints = (LINK_ENDPOINT_INSTANCE**)realloc(session_instance->link_endpoints, sizeof(LINK_ENDPOINT_INSTANCE*) * session_instance->link_endpoint_count);
Azure.IoT Build 0:6ae2f7bca550 1071 if (new_endpoints != NULL)
Azure.IoT Build 0:6ae2f7bca550 1072 {
Azure.IoT Build 0:6ae2f7bca550 1073 session_instance->link_endpoints = new_endpoints;
Azure.IoT Build 0:6ae2f7bca550 1074 }
Azure.IoT Build 0:6ae2f7bca550 1075 }
Azure.IoT Build 0:6ae2f7bca550 1076 }
Azure.IoT Build 0:6ae2f7bca550 1077
Azure.IoT Build 0:6ae2f7bca550 1078 if (endpoint_instance->name != NULL)
Azure.IoT Build 0:6ae2f7bca550 1079 {
AzureIoTClient 21:f9c433d8e6ca 1080 free(endpoint_instance->name);
Azure.IoT Build 0:6ae2f7bca550 1081 }
Azure.IoT Build 0:6ae2f7bca550 1082
AzureIoTClient 21:f9c433d8e6ca 1083 free(endpoint_instance);
Azure.IoT Build 0:6ae2f7bca550 1084 }
Azure.IoT Build 0:6ae2f7bca550 1085 }
Azure.IoT Build 0:6ae2f7bca550 1086
Azure.IoT Build 0:6ae2f7bca550 1087 int session_start_link_endpoint(LINK_ENDPOINT_HANDLE link_endpoint, ON_ENDPOINT_FRAME_RECEIVED frame_received_callback, ON_SESSION_STATE_CHANGED on_session_state_changed, ON_SESSION_FLOW_ON on_session_flow_on, void* context)
Azure.IoT Build 0:6ae2f7bca550 1088 {
Azure.IoT Build 0:6ae2f7bca550 1089 int result;
Azure.IoT Build 0:6ae2f7bca550 1090
Azure.IoT Build 0:6ae2f7bca550 1091 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1092 (frame_received_callback == NULL))
Azure.IoT Build 0:6ae2f7bca550 1093 {
AzureIoTClient 19:000ab4e6a2c1 1094 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1095 }
Azure.IoT Build 0:6ae2f7bca550 1096 else
Azure.IoT Build 0:6ae2f7bca550 1097 {
Azure.IoT Build 0:6ae2f7bca550 1098 link_endpoint->frame_received_callback = frame_received_callback;
Azure.IoT Build 0:6ae2f7bca550 1099 link_endpoint->on_session_state_changed = on_session_state_changed;
Azure.IoT Build 0:6ae2f7bca550 1100 link_endpoint->on_session_flow_on = on_session_flow_on;
Azure.IoT Build 0:6ae2f7bca550 1101 link_endpoint->callback_context = context;
Azure.IoT Build 0:6ae2f7bca550 1102
Azure.IoT Build 0:6ae2f7bca550 1103 if (link_endpoint->on_session_state_changed != NULL)
Azure.IoT Build 0:6ae2f7bca550 1104 {
Azure.IoT Build 0:6ae2f7bca550 1105 link_endpoint->on_session_state_changed(link_endpoint->callback_context, link_endpoint->session->session_state, link_endpoint->session->previous_session_state);
Azure.IoT Build 0:6ae2f7bca550 1106 }
Azure.IoT Build 0:6ae2f7bca550 1107
Azure.IoT Build 0:6ae2f7bca550 1108 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1109 }
Azure.IoT Build 0:6ae2f7bca550 1110
Azure.IoT Build 0:6ae2f7bca550 1111 return result;
Azure.IoT Build 0:6ae2f7bca550 1112 }
Azure.IoT Build 0:6ae2f7bca550 1113
Azure.IoT Build 0:6ae2f7bca550 1114 static int encode_frame(LINK_ENDPOINT_HANDLE link_endpoint, const AMQP_VALUE performative, PAYLOAD* payloads, size_t payload_count)
Azure.IoT Build 0:6ae2f7bca550 1115 {
Azure.IoT Build 0:6ae2f7bca550 1116 int result;
Azure.IoT Build 0:6ae2f7bca550 1117
Azure.IoT Build 0:6ae2f7bca550 1118 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1119 (performative == NULL))
Azure.IoT Build 0:6ae2f7bca550 1120 {
AzureIoTClient 19:000ab4e6a2c1 1121 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1122 }
Azure.IoT Build 0:6ae2f7bca550 1123 else
Azure.IoT Build 0:6ae2f7bca550 1124 {
Azure.IoT Build 0:6ae2f7bca550 1125 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1126 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)link_endpoint_instance->session;
Azure.IoT Build 0:6ae2f7bca550 1127
Azure.IoT Build 0:6ae2f7bca550 1128 if (connection_encode_frame(session_instance->endpoint, performative, payloads, payload_count, NULL, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 1129 {
AzureIoTClient 19:000ab4e6a2c1 1130 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1131 }
Azure.IoT Build 0:6ae2f7bca550 1132 else
Azure.IoT Build 0:6ae2f7bca550 1133 {
Azure.IoT Build 0:6ae2f7bca550 1134 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1135 }
Azure.IoT Build 0:6ae2f7bca550 1136 }
Azure.IoT Build 0:6ae2f7bca550 1137
Azure.IoT Build 0:6ae2f7bca550 1138 return result;
Azure.IoT Build 0:6ae2f7bca550 1139 }
Azure.IoT Build 0:6ae2f7bca550 1140
Azure.IoT Build 0:6ae2f7bca550 1141 int session_send_flow(LINK_ENDPOINT_HANDLE link_endpoint, FLOW_HANDLE flow)
Azure.IoT Build 0:6ae2f7bca550 1142 {
Azure.IoT Build 0:6ae2f7bca550 1143 int result;
Azure.IoT Build 0:6ae2f7bca550 1144
Azure.IoT Build 0:6ae2f7bca550 1145 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1146 (flow == NULL))
Azure.IoT Build 0:6ae2f7bca550 1147 {
AzureIoTClient 19:000ab4e6a2c1 1148 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1149 }
Azure.IoT Build 0:6ae2f7bca550 1150 else
Azure.IoT Build 0:6ae2f7bca550 1151 {
Azure.IoT Build 0:6ae2f7bca550 1152 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1153 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)link_endpoint_instance->session;
Azure.IoT Build 0:6ae2f7bca550 1154
Azure.IoT Build 0:6ae2f7bca550 1155 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1156
Azure.IoT Build 0:6ae2f7bca550 1157 if (session_instance->session_state == SESSION_STATE_BEGIN_RCVD)
Azure.IoT Build 0:6ae2f7bca550 1158 {
Azure.IoT Build 0:6ae2f7bca550 1159 if (flow_set_next_incoming_id(flow, session_instance->next_incoming_id) != 0)
Azure.IoT Build 0:6ae2f7bca550 1160 {
AzureIoTClient 19:000ab4e6a2c1 1161 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1162 }
Azure.IoT Build 0:6ae2f7bca550 1163 }
Azure.IoT Build 0:6ae2f7bca550 1164
Azure.IoT Build 0:6ae2f7bca550 1165 if (result == 0)
Azure.IoT Build 0:6ae2f7bca550 1166 {
AzureIoTClient 12:b30dacf113f2 1167 if ((flow_set_next_incoming_id(flow, session_instance->next_incoming_id) != 0) ||
AzureIoTClient 12:b30dacf113f2 1168 (flow_set_incoming_window(flow, session_instance->incoming_window) != 0) ||
AzureIoTClient 12:b30dacf113f2 1169 (flow_set_next_outgoing_id(flow, session_instance->next_outgoing_id) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 1170 (flow_set_outgoing_window(flow, session_instance->outgoing_window) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 1171 (flow_set_handle(flow, link_endpoint_instance->output_handle) != 0))
Azure.IoT Build 0:6ae2f7bca550 1172 {
AzureIoTClient 19:000ab4e6a2c1 1173 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1174 }
Azure.IoT Build 0:6ae2f7bca550 1175 else
Azure.IoT Build 0:6ae2f7bca550 1176 {
Azure.IoT Build 0:6ae2f7bca550 1177 AMQP_VALUE flow_performative_value = amqpvalue_create_flow(flow);
Azure.IoT Build 0:6ae2f7bca550 1178 if (flow_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 1179 {
AzureIoTClient 19:000ab4e6a2c1 1180 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1181 }
Azure.IoT Build 0:6ae2f7bca550 1182 else
Azure.IoT Build 0:6ae2f7bca550 1183 {
Azure.IoT Build 0:6ae2f7bca550 1184 if (encode_frame(link_endpoint, flow_performative_value, NULL, 0) != 0)
Azure.IoT Build 0:6ae2f7bca550 1185 {
AzureIoTClient 19:000ab4e6a2c1 1186 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1187 }
Azure.IoT Build 0:6ae2f7bca550 1188 else
Azure.IoT Build 0:6ae2f7bca550 1189 {
Azure.IoT Build 0:6ae2f7bca550 1190 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1191 }
Azure.IoT Build 0:6ae2f7bca550 1192
Azure.IoT Build 0:6ae2f7bca550 1193 amqpvalue_destroy(flow_performative_value);
Azure.IoT Build 0:6ae2f7bca550 1194 }
Azure.IoT Build 0:6ae2f7bca550 1195 }
Azure.IoT Build 0:6ae2f7bca550 1196 }
Azure.IoT Build 0:6ae2f7bca550 1197 }
Azure.IoT Build 0:6ae2f7bca550 1198
Azure.IoT Build 0:6ae2f7bca550 1199 return result;
Azure.IoT Build 0:6ae2f7bca550 1200 }
Azure.IoT Build 0:6ae2f7bca550 1201
Azure.IoT Build 0:6ae2f7bca550 1202 int session_send_attach(LINK_ENDPOINT_HANDLE link_endpoint, ATTACH_HANDLE attach)
Azure.IoT Build 0:6ae2f7bca550 1203 {
Azure.IoT Build 0:6ae2f7bca550 1204 int result;
Azure.IoT Build 0:6ae2f7bca550 1205
Azure.IoT Build 0:6ae2f7bca550 1206 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1207 (attach == NULL))
Azure.IoT Build 0:6ae2f7bca550 1208 {
AzureIoTClient 19:000ab4e6a2c1 1209 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1210 }
Azure.IoT Build 0:6ae2f7bca550 1211 else
Azure.IoT Build 0:6ae2f7bca550 1212 {
Azure.IoT Build 0:6ae2f7bca550 1213 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1214
Azure.IoT Build 0:6ae2f7bca550 1215 if (attach_set_handle(attach, link_endpoint_instance->output_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 1216 {
AzureIoTClient 19:000ab4e6a2c1 1217 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1218 }
Azure.IoT Build 0:6ae2f7bca550 1219 else
Azure.IoT Build 0:6ae2f7bca550 1220 {
Azure.IoT Build 0:6ae2f7bca550 1221 AMQP_VALUE attach_performative_value = amqpvalue_create_attach(attach);
Azure.IoT Build 0:6ae2f7bca550 1222 if (attach_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 1223 {
AzureIoTClient 19:000ab4e6a2c1 1224 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1225 }
Azure.IoT Build 0:6ae2f7bca550 1226 else
Azure.IoT Build 0:6ae2f7bca550 1227 {
Azure.IoT Build 0:6ae2f7bca550 1228 if (encode_frame(link_endpoint, attach_performative_value, NULL, 0) != 0)
Azure.IoT Build 0:6ae2f7bca550 1229 {
AzureIoTClient 19:000ab4e6a2c1 1230 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1231 }
Azure.IoT Build 0:6ae2f7bca550 1232 else
Azure.IoT Build 0:6ae2f7bca550 1233 {
Azure.IoT Build 0:6ae2f7bca550 1234 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1235 }
Azure.IoT Build 0:6ae2f7bca550 1236
Azure.IoT Build 0:6ae2f7bca550 1237 amqpvalue_destroy(attach_performative_value);
Azure.IoT Build 0:6ae2f7bca550 1238 }
Azure.IoT Build 0:6ae2f7bca550 1239 }
Azure.IoT Build 0:6ae2f7bca550 1240 }
Azure.IoT Build 0:6ae2f7bca550 1241
Azure.IoT Build 0:6ae2f7bca550 1242 return result;
Azure.IoT Build 0:6ae2f7bca550 1243 }
Azure.IoT Build 0:6ae2f7bca550 1244
Azure.IoT Build 0:6ae2f7bca550 1245 int session_send_disposition(LINK_ENDPOINT_HANDLE link_endpoint, DISPOSITION_HANDLE disposition)
Azure.IoT Build 0:6ae2f7bca550 1246 {
Azure.IoT Build 0:6ae2f7bca550 1247 int result;
Azure.IoT Build 0:6ae2f7bca550 1248
Azure.IoT Build 0:6ae2f7bca550 1249 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1250 (disposition == NULL))
Azure.IoT Build 0:6ae2f7bca550 1251 {
AzureIoTClient 19:000ab4e6a2c1 1252 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1253 }
Azure.IoT Build 0:6ae2f7bca550 1254 else
Azure.IoT Build 0:6ae2f7bca550 1255 {
Azure.IoT Build 0:6ae2f7bca550 1256 AMQP_VALUE disposition_performative_value = amqpvalue_create_disposition(disposition);
Azure.IoT Build 0:6ae2f7bca550 1257 if (disposition_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 1258 {
AzureIoTClient 19:000ab4e6a2c1 1259 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1260 }
Azure.IoT Build 0:6ae2f7bca550 1261 else
Azure.IoT Build 0:6ae2f7bca550 1262 {
Azure.IoT Build 0:6ae2f7bca550 1263 if (encode_frame(link_endpoint, disposition_performative_value, NULL, 0) != 0)
Azure.IoT Build 0:6ae2f7bca550 1264 {
AzureIoTClient 19:000ab4e6a2c1 1265 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1266 }
Azure.IoT Build 0:6ae2f7bca550 1267 else
Azure.IoT Build 0:6ae2f7bca550 1268 {
Azure.IoT Build 0:6ae2f7bca550 1269 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1270 }
Azure.IoT Build 0:6ae2f7bca550 1271
Azure.IoT Build 0:6ae2f7bca550 1272 amqpvalue_destroy(disposition_performative_value);
Azure.IoT Build 0:6ae2f7bca550 1273 }
Azure.IoT Build 0:6ae2f7bca550 1274 }
Azure.IoT Build 0:6ae2f7bca550 1275
Azure.IoT Build 0:6ae2f7bca550 1276 return result;
Azure.IoT Build 0:6ae2f7bca550 1277 }
Azure.IoT Build 0:6ae2f7bca550 1278
Azure.IoT Build 0:6ae2f7bca550 1279 int session_send_detach(LINK_ENDPOINT_HANDLE link_endpoint, DETACH_HANDLE detach)
Azure.IoT Build 0:6ae2f7bca550 1280 {
Azure.IoT Build 0:6ae2f7bca550 1281 int result;
Azure.IoT Build 0:6ae2f7bca550 1282
Azure.IoT Build 0:6ae2f7bca550 1283 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1284 (detach == NULL))
Azure.IoT Build 0:6ae2f7bca550 1285 {
AzureIoTClient 19:000ab4e6a2c1 1286 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1287 }
Azure.IoT Build 0:6ae2f7bca550 1288 else
Azure.IoT Build 0:6ae2f7bca550 1289 {
Azure.IoT Build 0:6ae2f7bca550 1290 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1291
Azure.IoT Build 0:6ae2f7bca550 1292 if (detach_set_handle(detach, link_endpoint_instance->output_handle) != 0)
Azure.IoT Build 0:6ae2f7bca550 1293 {
AzureIoTClient 19:000ab4e6a2c1 1294 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1295 }
Azure.IoT Build 0:6ae2f7bca550 1296 else
Azure.IoT Build 0:6ae2f7bca550 1297 {
Azure.IoT Build 0:6ae2f7bca550 1298 AMQP_VALUE detach_performative_value = amqpvalue_create_detach(detach);
Azure.IoT Build 0:6ae2f7bca550 1299 if (detach_performative_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 1300 {
AzureIoTClient 19:000ab4e6a2c1 1301 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1302 }
Azure.IoT Build 0:6ae2f7bca550 1303 else
Azure.IoT Build 0:6ae2f7bca550 1304 {
Azure.IoT Build 0:6ae2f7bca550 1305 if (encode_frame(link_endpoint, detach_performative_value, NULL, 0) != 0)
Azure.IoT Build 0:6ae2f7bca550 1306 {
AzureIoTClient 19:000ab4e6a2c1 1307 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1308 }
Azure.IoT Build 0:6ae2f7bca550 1309 else
Azure.IoT Build 0:6ae2f7bca550 1310 {
Azure.IoT Build 0:6ae2f7bca550 1311 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1312 }
Azure.IoT Build 0:6ae2f7bca550 1313
Azure.IoT Build 0:6ae2f7bca550 1314 amqpvalue_destroy(detach_performative_value);
Azure.IoT Build 0:6ae2f7bca550 1315 }
Azure.IoT Build 0:6ae2f7bca550 1316 }
Azure.IoT Build 0:6ae2f7bca550 1317 }
Azure.IoT Build 0:6ae2f7bca550 1318
Azure.IoT Build 0:6ae2f7bca550 1319 return result;
Azure.IoT Build 0:6ae2f7bca550 1320 }
Azure.IoT Build 0:6ae2f7bca550 1321
Azure.IoT Build 0:6ae2f7bca550 1322 /* Codes_SRS_SESSION_01_051: [session_send_transfer shall send a transfer frame with the performative indicated in the transfer argument.] */
Azure.IoT Build 0:6ae2f7bca550 1323 SESSION_SEND_TRANSFER_RESULT session_send_transfer(LINK_ENDPOINT_HANDLE link_endpoint, TRANSFER_HANDLE transfer, PAYLOAD* payloads, size_t payload_count, delivery_number* delivery_id, ON_SEND_COMPLETE on_send_complete, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 1324 {
Azure.IoT Build 0:6ae2f7bca550 1325 SESSION_SEND_TRANSFER_RESULT result;
Azure.IoT Build 0:6ae2f7bca550 1326
Azure.IoT Build 0:6ae2f7bca550 1327 /* Codes_SRS_SESSION_01_054: [If link_endpoint or transfer is NULL, session_send_transfer shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 1328 if ((link_endpoint == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 1329 (transfer == NULL))
Azure.IoT Build 0:6ae2f7bca550 1330 {
Azure.IoT Build 0:6ae2f7bca550 1331 result = SESSION_SEND_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1332 }
Azure.IoT Build 0:6ae2f7bca550 1333 else
Azure.IoT Build 0:6ae2f7bca550 1334 {
Azure.IoT Build 0:6ae2f7bca550 1335 LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 1336 SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)link_endpoint_instance->session;
Azure.IoT Build 0:6ae2f7bca550 1337
Azure.IoT Build 0:6ae2f7bca550 1338 /* Codes_SRS_SESSION_01_059: [When session_send_transfer is called while the session is not in the MAPPED state, session_send_transfer shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 1339 if (session_instance->session_state != SESSION_STATE_MAPPED)
Azure.IoT Build 0:6ae2f7bca550 1340 {
Azure.IoT Build 0:6ae2f7bca550 1341 result = SESSION_SEND_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1342 }
Azure.IoT Build 0:6ae2f7bca550 1343 else
Azure.IoT Build 0:6ae2f7bca550 1344 {
AzureIoTClient 6:641a9672db08 1345 size_t payload_size = 0;
Azure.IoT Build 0:6ae2f7bca550 1346 size_t i;
Azure.IoT Build 0:6ae2f7bca550 1347
Azure.IoT Build 0:6ae2f7bca550 1348 for (i = 0; i < payload_count; i++)
Azure.IoT Build 0:6ae2f7bca550 1349 {
AzureIoTClient 6:641a9672db08 1350 if ((payloads[i].length > UINT32_MAX) ||
AzureIoTClient 6:641a9672db08 1351 (payload_size + payloads[i].length < payload_size))
AzureIoTClient 6:641a9672db08 1352 {
AzureIoTClient 6:641a9672db08 1353 break;
AzureIoTClient 6:641a9672db08 1354 }
AzureIoTClient 6:641a9672db08 1355
AzureIoTClient 6:641a9672db08 1356 payload_size += payloads[i].length;
AzureIoTClient 6:641a9672db08 1357 }
Azure.IoT Build 0:6ae2f7bca550 1358
AzureIoTClient 6:641a9672db08 1359 if ((i < payload_count) ||
AzureIoTClient 6:641a9672db08 1360 (payload_size > UINT32_MAX))
AzureIoTClient 6:641a9672db08 1361 {
AzureIoTClient 6:641a9672db08 1362 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1363 }
AzureIoTClient 6:641a9672db08 1364 else
AzureIoTClient 6:641a9672db08 1365 {
AzureIoTClient 6:641a9672db08 1366 if (session_instance->remote_incoming_window == 0)
AzureIoTClient 6:641a9672db08 1367 {
AzureIoTClient 6:641a9672db08 1368 result = SESSION_SEND_TRANSFER_BUSY;
AzureIoTClient 6:641a9672db08 1369 }
AzureIoTClient 6:641a9672db08 1370 else
AzureIoTClient 6:641a9672db08 1371 {
AzureIoTClient 6:641a9672db08 1372 /* Codes_SRS_SESSION_01_012: [The session endpoint assigns each outgoing transfer frame an implicit transfer-id from a session scoped sequence.] */
AzureIoTClient 6:641a9672db08 1373 /* Codes_SRS_SESSION_01_027: [sending a transfer Upon sending a transfer, the sending endpoint will increment its next-outgoing-id] */
AzureIoTClient 6:641a9672db08 1374 *delivery_id = session_instance->next_outgoing_id;
AzureIoTClient 6:641a9672db08 1375 if ((transfer_set_handle(transfer, link_endpoint_instance->output_handle) != 0) ||
AzureIoTClient 6:641a9672db08 1376 (transfer_set_delivery_id(transfer, *delivery_id) != 0) ||
AzureIoTClient 6:641a9672db08 1377 (transfer_set_more(transfer, false) != 0))
AzureIoTClient 6:641a9672db08 1378 {
AzureIoTClient 6:641a9672db08 1379 /* Codes_SRS_SESSION_01_058: [When any other error occurs, session_send_transfer shall fail and return a non-zero value.] */
AzureIoTClient 6:641a9672db08 1380 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1381 }
AzureIoTClient 6:641a9672db08 1382 else
AzureIoTClient 6:641a9672db08 1383 {
AzureIoTClient 6:641a9672db08 1384 AMQP_VALUE transfer_value;
Azure.IoT Build 0:6ae2f7bca550 1385
AzureIoTClient 6:641a9672db08 1386 transfer_value = amqpvalue_create_transfer(transfer);
AzureIoTClient 6:641a9672db08 1387 if (transfer_value == NULL)
AzureIoTClient 6:641a9672db08 1388 {
AzureIoTClient 6:641a9672db08 1389 /* Codes_SRS_SESSION_01_058: [When any other error occurs, session_send_transfer shall fail and return a non-zero value.] */
AzureIoTClient 6:641a9672db08 1390 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1391 }
AzureIoTClient 6:641a9672db08 1392 else
AzureIoTClient 6:641a9672db08 1393 {
AzureIoTClient 6:641a9672db08 1394 uint32_t available_frame_size;
AzureIoTClient 6:641a9672db08 1395 size_t encoded_size;
Azure.IoT Build 0:6ae2f7bca550 1396
AzureIoTClient 6:641a9672db08 1397 if ((connection_get_remote_max_frame_size(session_instance->connection, &available_frame_size) != 0) ||
AzureIoTClient 6:641a9672db08 1398 (amqpvalue_get_encoded_size(transfer_value, &encoded_size) != 0))
AzureIoTClient 6:641a9672db08 1399 {
AzureIoTClient 6:641a9672db08 1400 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1401 }
AzureIoTClient 6:641a9672db08 1402 else
AzureIoTClient 6:641a9672db08 1403 {
AzureIoTClient 6:641a9672db08 1404 payload_size = 0;
Azure.IoT Build 0:6ae2f7bca550 1405
AzureIoTClient 6:641a9672db08 1406 for (i = 0; i < payload_count; i++)
AzureIoTClient 6:641a9672db08 1407 {
AzureIoTClient 6:641a9672db08 1408 payload_size += payloads[i].length;
AzureIoTClient 6:641a9672db08 1409 }
AzureIoTClient 6:641a9672db08 1410
AzureIoTClient 6:641a9672db08 1411 available_frame_size -= (uint32_t)encoded_size;
AzureIoTClient 6:641a9672db08 1412 available_frame_size -= 8;
Azure.IoT Build 0:6ae2f7bca550 1413
AzureIoTClient 6:641a9672db08 1414 if (available_frame_size >= payload_size)
AzureIoTClient 6:641a9672db08 1415 {
AzureIoTClient 6:641a9672db08 1416 /* Codes_SRS_SESSION_01_055: [The encoding of the frame shall be done by calling connection_encode_frame and passing as arguments: the connection handle associated with the session, the transfer performative and the payload chunks passed to session_send_transfer.] */
AzureIoTClient 6:641a9672db08 1417 if (connection_encode_frame(session_instance->endpoint, transfer_value, payloads, payload_count, on_send_complete, callback_context) != 0)
AzureIoTClient 6:641a9672db08 1418 {
AzureIoTClient 6:641a9672db08 1419 /* Codes_SRS_SESSION_01_056: [If connection_encode_frame fails then session_send_transfer shall fail and return a non-zero value.] */
AzureIoTClient 6:641a9672db08 1420 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1421 }
AzureIoTClient 6:641a9672db08 1422 else
AzureIoTClient 6:641a9672db08 1423 {
AzureIoTClient 6:641a9672db08 1424 /* Codes_SRS_SESSION_01_018: [is incremented after each successive transfer according to RFC-1982 [RFC1982] serial number arithmetic.] */
AzureIoTClient 6:641a9672db08 1425 session_instance->next_outgoing_id++;
AzureIoTClient 6:641a9672db08 1426 session_instance->remote_incoming_window--;
AzureIoTClient 6:641a9672db08 1427 session_instance->outgoing_window--;
Azure.IoT Build 0:6ae2f7bca550 1428
AzureIoTClient 6:641a9672db08 1429 /* Codes_SRS_SESSION_01_053: [On success, session_send_transfer shall return 0.] */
AzureIoTClient 6:641a9672db08 1430 result = SESSION_SEND_TRANSFER_OK;
AzureIoTClient 6:641a9672db08 1431 }
AzureIoTClient 6:641a9672db08 1432 }
AzureIoTClient 6:641a9672db08 1433 else
AzureIoTClient 6:641a9672db08 1434 {
AzureIoTClient 6:641a9672db08 1435 size_t current_payload_index = 0;
AzureIoTClient 6:641a9672db08 1436 uint32_t current_payload_pos = 0;
Azure.IoT Build 0:6ae2f7bca550 1437
AzureIoTClient 6:641a9672db08 1438 /* break it down into different deliveries */
AzureIoTClient 6:641a9672db08 1439 while (payload_size > 0)
AzureIoTClient 6:641a9672db08 1440 {
AzureIoTClient 6:641a9672db08 1441 uint32_t transfer_frame_payload_count = 0;
AzureIoTClient 6:641a9672db08 1442 uint32_t current_transfer_frame_payload_size = (uint32_t)payload_size;
AzureIoTClient 6:641a9672db08 1443 uint32_t byte_counter;
AzureIoTClient 6:641a9672db08 1444 size_t temp_current_payload_index = current_payload_index;
AzureIoTClient 6:641a9672db08 1445 uint32_t temp_current_payload_pos = current_payload_pos;
AzureIoTClient 6:641a9672db08 1446 AMQP_VALUE multi_transfer_amqp_value;
AzureIoTClient 6:641a9672db08 1447 bool more;
AzureIoTClient 6:641a9672db08 1448
AzureIoTClient 6:641a9672db08 1449 if (current_transfer_frame_payload_size > available_frame_size)
AzureIoTClient 6:641a9672db08 1450 {
AzureIoTClient 6:641a9672db08 1451 current_transfer_frame_payload_size = available_frame_size;
AzureIoTClient 6:641a9672db08 1452 }
Azure.IoT Build 0:6ae2f7bca550 1453
AzureIoTClient 6:641a9672db08 1454 if (available_frame_size >= payload_size)
AzureIoTClient 6:641a9672db08 1455 {
AzureIoTClient 6:641a9672db08 1456 more = false;
AzureIoTClient 6:641a9672db08 1457 }
AzureIoTClient 6:641a9672db08 1458 else
AzureIoTClient 6:641a9672db08 1459 {
AzureIoTClient 6:641a9672db08 1460 more = true;
AzureIoTClient 6:641a9672db08 1461 }
Azure.IoT Build 0:6ae2f7bca550 1462
AzureIoTClient 6:641a9672db08 1463 if (transfer_set_more(transfer, more) != 0)
AzureIoTClient 6:641a9672db08 1464 {
AzureIoTClient 6:641a9672db08 1465 break;
AzureIoTClient 6:641a9672db08 1466 }
Azure.IoT Build 0:6ae2f7bca550 1467
AzureIoTClient 6:641a9672db08 1468 multi_transfer_amqp_value = amqpvalue_create_transfer(transfer);
AzureIoTClient 6:641a9672db08 1469 if (multi_transfer_amqp_value == NULL)
AzureIoTClient 6:641a9672db08 1470 {
AzureIoTClient 6:641a9672db08 1471 break;
AzureIoTClient 6:641a9672db08 1472 }
Azure.IoT Build 0:6ae2f7bca550 1473
AzureIoTClient 6:641a9672db08 1474 byte_counter = current_transfer_frame_payload_size;
AzureIoTClient 6:641a9672db08 1475 while (byte_counter > 0)
AzureIoTClient 6:641a9672db08 1476 {
AzureIoTClient 6:641a9672db08 1477 if (payloads[temp_current_payload_index].length - temp_current_payload_pos >= byte_counter)
AzureIoTClient 6:641a9672db08 1478 {
AzureIoTClient 6:641a9672db08 1479 /* more data than we need */
AzureIoTClient 6:641a9672db08 1480 temp_current_payload_pos += byte_counter;
AzureIoTClient 6:641a9672db08 1481 byte_counter = 0;
AzureIoTClient 6:641a9672db08 1482 }
AzureIoTClient 6:641a9672db08 1483 else
AzureIoTClient 6:641a9672db08 1484 {
AzureIoTClient 6:641a9672db08 1485 byte_counter -= (uint32_t)payloads[temp_current_payload_index].length - temp_current_payload_pos;
AzureIoTClient 6:641a9672db08 1486 temp_current_payload_index++;
AzureIoTClient 6:641a9672db08 1487 temp_current_payload_pos = 0;
AzureIoTClient 6:641a9672db08 1488 }
AzureIoTClient 6:641a9672db08 1489 }
Azure.IoT Build 0:6ae2f7bca550 1490
AzureIoTClient 6:641a9672db08 1491 transfer_frame_payload_count = (uint32_t)(temp_current_payload_index - current_payload_index + 1);
AzureIoTClient 21:f9c433d8e6ca 1492 PAYLOAD* transfer_frame_payloads = (PAYLOAD*)malloc(transfer_frame_payload_count * sizeof(PAYLOAD));
AzureIoTClient 6:641a9672db08 1493 if (transfer_frame_payloads == NULL)
AzureIoTClient 6:641a9672db08 1494 {
AzureIoTClient 6:641a9672db08 1495 amqpvalue_destroy(multi_transfer_amqp_value);
AzureIoTClient 6:641a9672db08 1496 break;
AzureIoTClient 6:641a9672db08 1497 }
Azure.IoT Build 0:6ae2f7bca550 1498
AzureIoTClient 6:641a9672db08 1499 /* copy data */
AzureIoTClient 6:641a9672db08 1500 byte_counter = current_transfer_frame_payload_size;
AzureIoTClient 6:641a9672db08 1501 transfer_frame_payload_count = 0;
Azure.IoT Build 0:6ae2f7bca550 1502
AzureIoTClient 6:641a9672db08 1503 while (byte_counter > 0)
AzureIoTClient 6:641a9672db08 1504 {
AzureIoTClient 6:641a9672db08 1505 if (payloads[current_payload_index].length - current_payload_pos > byte_counter)
AzureIoTClient 6:641a9672db08 1506 {
AzureIoTClient 6:641a9672db08 1507 /* more data than we need */
AzureIoTClient 6:641a9672db08 1508 transfer_frame_payloads[transfer_frame_payload_count].bytes = payloads[current_payload_index].bytes + current_payload_pos;
AzureIoTClient 6:641a9672db08 1509 transfer_frame_payloads[transfer_frame_payload_count].length = byte_counter;
AzureIoTClient 6:641a9672db08 1510 current_payload_pos += byte_counter;
AzureIoTClient 6:641a9672db08 1511 byte_counter = 0;
AzureIoTClient 6:641a9672db08 1512 }
AzureIoTClient 6:641a9672db08 1513 else
AzureIoTClient 6:641a9672db08 1514 {
AzureIoTClient 6:641a9672db08 1515 /* copy entire payload and move to the next */
AzureIoTClient 6:641a9672db08 1516 transfer_frame_payloads[transfer_frame_payload_count].bytes = payloads[current_payload_index].bytes + current_payload_pos;
AzureIoTClient 6:641a9672db08 1517 transfer_frame_payloads[transfer_frame_payload_count].length = payloads[current_payload_index].length - current_payload_pos;
AzureIoTClient 6:641a9672db08 1518 byte_counter -= (uint32_t)payloads[current_payload_index].length - current_payload_pos;
AzureIoTClient 6:641a9672db08 1519 current_payload_index++;
AzureIoTClient 6:641a9672db08 1520 current_payload_pos = 0;
AzureIoTClient 6:641a9672db08 1521 }
Azure.IoT Build 0:6ae2f7bca550 1522
AzureIoTClient 6:641a9672db08 1523 transfer_frame_payload_count++;
AzureIoTClient 6:641a9672db08 1524 }
Azure.IoT Build 0:6ae2f7bca550 1525
AzureIoTClient 6:641a9672db08 1526 if (connection_encode_frame(session_instance->endpoint, multi_transfer_amqp_value, transfer_frame_payloads, transfer_frame_payload_count, on_send_complete, callback_context) != 0)
AzureIoTClient 6:641a9672db08 1527 {
AzureIoTClient 21:f9c433d8e6ca 1528 free(transfer_frame_payloads);
AzureIoTClient 6:641a9672db08 1529 amqpvalue_destroy(multi_transfer_amqp_value);
AzureIoTClient 6:641a9672db08 1530 break;
AzureIoTClient 6:641a9672db08 1531 }
Azure.IoT Build 0:6ae2f7bca550 1532
AzureIoTClient 21:f9c433d8e6ca 1533 free(transfer_frame_payloads);
AzureIoTClient 6:641a9672db08 1534 amqpvalue_destroy(multi_transfer_amqp_value);
AzureIoTClient 6:641a9672db08 1535 payload_size -= current_transfer_frame_payload_size;
AzureIoTClient 6:641a9672db08 1536 }
Azure.IoT Build 0:6ae2f7bca550 1537
AzureIoTClient 6:641a9672db08 1538 if (payload_size > 0)
AzureIoTClient 6:641a9672db08 1539 {
AzureIoTClient 6:641a9672db08 1540 result = SESSION_SEND_TRANSFER_ERROR;
AzureIoTClient 6:641a9672db08 1541 }
AzureIoTClient 6:641a9672db08 1542 else
AzureIoTClient 6:641a9672db08 1543 {
AzureIoTClient 6:641a9672db08 1544 /* Codes_SRS_SESSION_01_018: [is incremented after each successive transfer according to RFC-1982 [RFC1982] serial number arithmetic.] */
AzureIoTClient 6:641a9672db08 1545 session_instance->next_outgoing_id++;
AzureIoTClient 6:641a9672db08 1546 session_instance->remote_incoming_window--;
AzureIoTClient 6:641a9672db08 1547 session_instance->outgoing_window--;
Azure.IoT Build 0:6ae2f7bca550 1548
AzureIoTClient 6:641a9672db08 1549 result = SESSION_SEND_TRANSFER_OK;
AzureIoTClient 6:641a9672db08 1550 }
AzureIoTClient 6:641a9672db08 1551 }
AzureIoTClient 6:641a9672db08 1552 }
Azure.IoT Build 0:6ae2f7bca550 1553
AzureIoTClient 6:641a9672db08 1554 amqpvalue_destroy(transfer_value);
AzureIoTClient 6:641a9672db08 1555 }
AzureIoTClient 6:641a9672db08 1556 }
AzureIoTClient 6:641a9672db08 1557 }
AzureIoTClient 6:641a9672db08 1558 }
Azure.IoT Build 0:6ae2f7bca550 1559 }
Azure.IoT Build 0:6ae2f7bca550 1560 }
Azure.IoT Build 0:6ae2f7bca550 1561
Azure.IoT Build 0:6ae2f7bca550 1562 return result;
Azure.IoT Build 0:6ae2f7bca550 1563 }