A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

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