A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
Azure.IoT Build
Date:
Fri Jul 01 10:42:48 2016 -0700
Revision:
5:ae49385aff34
Parent:
1:eab586236bfe
Child:
6:641a9672db08
1.0.10

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