A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Mon Mar 05 17:41:28 2018 -0800
Revision:
40:f0ceafa8d570
Parent:
30:0407b2db334c
Child:
43:4c1e4e94cdd3
1.2.0

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