A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Thu Oct 20 17:07:44 2016 -0700
Revision:
12:b30dacf113f2
Parent:
8:20dc883fb313
Child:
13:9abd748f4e78
1.0.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
Azure.IoT Build 0:6ae2f7bca550 5 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 0:6ae2f7bca550 6 #include <crtdbg.h>
Azure.IoT Build 0:6ae2f7bca550 7 #endif
Azure.IoT Build 0:6ae2f7bca550 8 #include <string.h>
Azure.IoT Build 0:6ae2f7bca550 9 #include <stdint.h>
Azure.IoT Build 0:6ae2f7bca550 10 #include <stdbool.h>
Azure.IoT Build 0:6ae2f7bca550 11 #include "azure_uamqp_c/link.h"
Azure.IoT Build 0:6ae2f7bca550 12 #include "azure_uamqp_c/session.h"
Azure.IoT Build 0:6ae2f7bca550 13 #include "azure_uamqp_c/amqpvalue.h"
Azure.IoT Build 0:6ae2f7bca550 14 #include "azure_uamqp_c/amqp_definitions.h"
Azure.IoT Build 0:6ae2f7bca550 15 #include "azure_uamqp_c/amqpalloc.h"
Azure.IoT Build 0:6ae2f7bca550 16 #include "azure_uamqp_c/amqp_frame_codec.h"
Azure.IoT Build 0:6ae2f7bca550 17 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 12:b30dacf113f2 18 #include "azure_c_shared_utility/singlylinkedlist.h"
Azure.IoT Build 0:6ae2f7bca550 19
Azure.IoT Build 0:6ae2f7bca550 20 #define DEFAULT_LINK_CREDIT 10000
Azure.IoT Build 0:6ae2f7bca550 21
Azure.IoT Build 0:6ae2f7bca550 22 typedef struct DELIVERY_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 23 {
Azure.IoT Build 0:6ae2f7bca550 24 delivery_number delivery_id;
Azure.IoT Build 0:6ae2f7bca550 25 ON_DELIVERY_SETTLED on_delivery_settled;
Azure.IoT Build 0:6ae2f7bca550 26 void* callback_context;
Azure.IoT Build 0:6ae2f7bca550 27 void* link;
Azure.IoT Build 0:6ae2f7bca550 28 } DELIVERY_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 29
Azure.IoT Build 0:6ae2f7bca550 30 typedef struct LINK_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 31 {
Azure.IoT Build 0:6ae2f7bca550 32 SESSION_HANDLE session;
Azure.IoT Build 0:6ae2f7bca550 33 LINK_STATE link_state;
Azure.IoT Build 0:6ae2f7bca550 34 LINK_STATE previous_link_state;
Azure.IoT Build 0:6ae2f7bca550 35 AMQP_VALUE source;
Azure.IoT Build 0:6ae2f7bca550 36 AMQP_VALUE target;
Azure.IoT Build 0:6ae2f7bca550 37 handle handle;
Azure.IoT Build 0:6ae2f7bca550 38 LINK_ENDPOINT_HANDLE link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 39 char* name;
AzureIoTClient 12:b30dacf113f2 40 SINGLYLINKEDLIST_HANDLE pending_deliveries;
Azure.IoT Build 0:6ae2f7bca550 41 sequence_no delivery_count;
Azure.IoT Build 0:6ae2f7bca550 42 role role;
Azure.IoT Build 0:6ae2f7bca550 43 ON_LINK_STATE_CHANGED on_link_state_changed;
Azure.IoT Build 0:6ae2f7bca550 44 ON_LINK_FLOW_ON on_link_flow_on;
Azure.IoT Build 0:6ae2f7bca550 45 ON_TRANSFER_RECEIVED on_transfer_received;
Azure.IoT Build 0:6ae2f7bca550 46 void* callback_context;
Azure.IoT Build 0:6ae2f7bca550 47 sender_settle_mode snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 48 receiver_settle_mode rcv_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 49 sequence_no initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 50 uint64_t max_message_size;
Azure.IoT Build 0:6ae2f7bca550 51 uint32_t link_credit;
Azure.IoT Build 0:6ae2f7bca550 52 uint32_t available;
Azure.IoT Build 0:6ae2f7bca550 53 fields attach_properties;
AzureIoTClient 12:b30dacf113f2 54 bool is_underlying_session_begun;
AzureIoTClient 12:b30dacf113f2 55 bool is_closed;
AzureIoTClient 12:b30dacf113f2 56 unsigned char* received_payload;
AzureIoTClient 12:b30dacf113f2 57 uint32_t received_payload_size;
AzureIoTClient 12:b30dacf113f2 58 delivery_number received_delivery_id;
Azure.IoT Build 0:6ae2f7bca550 59 } LINK_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 60
Azure.IoT Build 0:6ae2f7bca550 61 static void set_link_state(LINK_INSTANCE* link_instance, LINK_STATE link_state)
Azure.IoT Build 0:6ae2f7bca550 62 {
Azure.IoT Build 0:6ae2f7bca550 63 link_instance->previous_link_state = link_instance->link_state;
Azure.IoT Build 0:6ae2f7bca550 64 link_instance->link_state = link_state;
Azure.IoT Build 0:6ae2f7bca550 65
Azure.IoT Build 0:6ae2f7bca550 66 if (link_instance->on_link_state_changed != NULL)
Azure.IoT Build 0:6ae2f7bca550 67 {
Azure.IoT Build 0:6ae2f7bca550 68 link_instance->on_link_state_changed(link_instance->callback_context, link_state, link_instance->previous_link_state);
Azure.IoT Build 0:6ae2f7bca550 69 }
Azure.IoT Build 0:6ae2f7bca550 70 }
Azure.IoT Build 0:6ae2f7bca550 71
Azure.IoT Build 0:6ae2f7bca550 72 static int send_flow(LINK_INSTANCE* link)
Azure.IoT Build 0:6ae2f7bca550 73 {
Azure.IoT Build 0:6ae2f7bca550 74 int result;
Azure.IoT Build 0:6ae2f7bca550 75 FLOW_HANDLE flow = flow_create(0, 0, 0);
Azure.IoT Build 0:6ae2f7bca550 76
Azure.IoT Build 0:6ae2f7bca550 77 if (flow == NULL)
Azure.IoT Build 0:6ae2f7bca550 78 {
Azure.IoT Build 0:6ae2f7bca550 79 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 80 }
Azure.IoT Build 0:6ae2f7bca550 81 else
Azure.IoT Build 0:6ae2f7bca550 82 {
Azure.IoT Build 0:6ae2f7bca550 83 if ((flow_set_link_credit(flow, link->link_credit) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 84 (flow_set_handle(flow, link->handle) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 85 (flow_set_delivery_count(flow, link->delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 86 {
Azure.IoT Build 0:6ae2f7bca550 87 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 88 }
Azure.IoT Build 0:6ae2f7bca550 89 else
Azure.IoT Build 0:6ae2f7bca550 90 {
Azure.IoT Build 0:6ae2f7bca550 91 if (session_send_flow(link->link_endpoint, flow) != 0)
Azure.IoT Build 0:6ae2f7bca550 92 {
Azure.IoT Build 0:6ae2f7bca550 93 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 94 }
Azure.IoT Build 0:6ae2f7bca550 95 else
Azure.IoT Build 0:6ae2f7bca550 96 {
Azure.IoT Build 0:6ae2f7bca550 97 result = 0;
Azure.IoT Build 0:6ae2f7bca550 98 }
Azure.IoT Build 0:6ae2f7bca550 99 }
Azure.IoT Build 0:6ae2f7bca550 100
Azure.IoT Build 0:6ae2f7bca550 101 flow_destroy(flow);
Azure.IoT Build 0:6ae2f7bca550 102 }
Azure.IoT Build 0:6ae2f7bca550 103
Azure.IoT Build 0:6ae2f7bca550 104 return result;
Azure.IoT Build 0:6ae2f7bca550 105 }
Azure.IoT Build 0:6ae2f7bca550 106
Azure.IoT Build 0:6ae2f7bca550 107 static int send_disposition(LINK_INSTANCE* link_instance, delivery_number delivery_number, AMQP_VALUE delivery_state)
Azure.IoT Build 0:6ae2f7bca550 108 {
Azure.IoT Build 0:6ae2f7bca550 109 int result;
Azure.IoT Build 0:6ae2f7bca550 110
Azure.IoT Build 0:6ae2f7bca550 111 DISPOSITION_HANDLE disposition = disposition_create(link_instance->role, delivery_number);
Azure.IoT Build 0:6ae2f7bca550 112 if (disposition == NULL)
Azure.IoT Build 0:6ae2f7bca550 113 {
Azure.IoT Build 0:6ae2f7bca550 114 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 115 }
Azure.IoT Build 0:6ae2f7bca550 116 else
Azure.IoT Build 0:6ae2f7bca550 117 {
Azure.IoT Build 0:6ae2f7bca550 118 if ((disposition_set_last(disposition, delivery_number) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 119 (disposition_set_settled(disposition, true) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 120 ((delivery_state != NULL) && (disposition_set_state(disposition, delivery_state) != 0)))
Azure.IoT Build 0:6ae2f7bca550 121 {
Azure.IoT Build 0:6ae2f7bca550 122 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 123 }
Azure.IoT Build 0:6ae2f7bca550 124 else
Azure.IoT Build 0:6ae2f7bca550 125 {
Azure.IoT Build 0:6ae2f7bca550 126 if (session_send_disposition(link_instance->link_endpoint, disposition) != 0)
Azure.IoT Build 0:6ae2f7bca550 127 {
Azure.IoT Build 0:6ae2f7bca550 128 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 129 }
Azure.IoT Build 0:6ae2f7bca550 130 else
Azure.IoT Build 0:6ae2f7bca550 131 {
Azure.IoT Build 0:6ae2f7bca550 132 result = 0;
Azure.IoT Build 0:6ae2f7bca550 133 }
Azure.IoT Build 0:6ae2f7bca550 134 }
Azure.IoT Build 0:6ae2f7bca550 135
Azure.IoT Build 0:6ae2f7bca550 136 disposition_destroy(disposition);
Azure.IoT Build 0:6ae2f7bca550 137 }
Azure.IoT Build 0:6ae2f7bca550 138
Azure.IoT Build 0:6ae2f7bca550 139 return result;
Azure.IoT Build 0:6ae2f7bca550 140 }
Azure.IoT Build 0:6ae2f7bca550 141
AzureIoTClient 12:b30dacf113f2 142 static int send_detach(LINK_INSTANCE* link_instance, bool close, ERROR_HANDLE error_handle)
Azure.IoT Build 0:6ae2f7bca550 143 {
Azure.IoT Build 0:6ae2f7bca550 144 int result;
Azure.IoT Build 0:6ae2f7bca550 145 DETACH_HANDLE detach_performative;
Azure.IoT Build 0:6ae2f7bca550 146
Azure.IoT Build 0:6ae2f7bca550 147 detach_performative = detach_create(0);
Azure.IoT Build 0:6ae2f7bca550 148 if (detach_performative == NULL)
Azure.IoT Build 0:6ae2f7bca550 149 {
Azure.IoT Build 0:6ae2f7bca550 150 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 151 }
Azure.IoT Build 0:6ae2f7bca550 152 else
Azure.IoT Build 0:6ae2f7bca550 153 {
Azure.IoT Build 0:6ae2f7bca550 154 if ((error_handle != NULL) &&
Azure.IoT Build 0:6ae2f7bca550 155 (detach_set_error(detach_performative, error_handle) != 0))
Azure.IoT Build 0:6ae2f7bca550 156 {
Azure.IoT Build 0:6ae2f7bca550 157 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 158 }
AzureIoTClient 12:b30dacf113f2 159 else if (close &&
AzureIoTClient 12:b30dacf113f2 160 (detach_set_closed(detach_performative, true) != 0))
AzureIoTClient 12:b30dacf113f2 161 {
AzureIoTClient 12:b30dacf113f2 162 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 163 }
AzureIoTClient 12:b30dacf113f2 164 else
Azure.IoT Build 0:6ae2f7bca550 165 {
Azure.IoT Build 0:6ae2f7bca550 166 if (session_send_detach(link_instance->link_endpoint, detach_performative) != 0)
Azure.IoT Build 0:6ae2f7bca550 167 {
Azure.IoT Build 0:6ae2f7bca550 168 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 169 }
Azure.IoT Build 0:6ae2f7bca550 170 else
Azure.IoT Build 0:6ae2f7bca550 171 {
AzureIoTClient 12:b30dacf113f2 172 if (close)
AzureIoTClient 12:b30dacf113f2 173 {
AzureIoTClient 12:b30dacf113f2 174 /* Declare link to be closed */
AzureIoTClient 12:b30dacf113f2 175 link_instance->is_closed = true;
AzureIoTClient 12:b30dacf113f2 176 }
AzureIoTClient 12:b30dacf113f2 177
Azure.IoT Build 0:6ae2f7bca550 178 result = 0;
Azure.IoT Build 0:6ae2f7bca550 179 }
Azure.IoT Build 0:6ae2f7bca550 180 }
Azure.IoT Build 0:6ae2f7bca550 181
Azure.IoT Build 0:6ae2f7bca550 182 detach_destroy(detach_performative);
Azure.IoT Build 0:6ae2f7bca550 183 }
Azure.IoT Build 0:6ae2f7bca550 184
Azure.IoT Build 0:6ae2f7bca550 185 return result;
Azure.IoT Build 0:6ae2f7bca550 186 }
Azure.IoT Build 0:6ae2f7bca550 187
AzureIoTClient 12:b30dacf113f2 188 static int send_attach(LINK_INSTANCE* link, const char* name, handle handle, role role)
AzureIoTClient 12:b30dacf113f2 189 {
AzureIoTClient 12:b30dacf113f2 190 int result;
AzureIoTClient 12:b30dacf113f2 191 ATTACH_HANDLE attach = attach_create(name, handle, role);
AzureIoTClient 12:b30dacf113f2 192
AzureIoTClient 12:b30dacf113f2 193 if (attach == NULL)
AzureIoTClient 12:b30dacf113f2 194 {
AzureIoTClient 12:b30dacf113f2 195 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 196 }
AzureIoTClient 12:b30dacf113f2 197 else
AzureIoTClient 12:b30dacf113f2 198 {
AzureIoTClient 12:b30dacf113f2 199 result = 0;
AzureIoTClient 12:b30dacf113f2 200
AzureIoTClient 12:b30dacf113f2 201 link->delivery_count = link->initial_delivery_count;
AzureIoTClient 12:b30dacf113f2 202
AzureIoTClient 12:b30dacf113f2 203 attach_set_snd_settle_mode(attach, link->snd_settle_mode);
AzureIoTClient 12:b30dacf113f2 204 attach_set_rcv_settle_mode(attach, link->rcv_settle_mode);
AzureIoTClient 12:b30dacf113f2 205 attach_set_role(attach, role);
AzureIoTClient 12:b30dacf113f2 206 attach_set_source(attach, link->source);
AzureIoTClient 12:b30dacf113f2 207 attach_set_target(attach, link->target);
AzureIoTClient 12:b30dacf113f2 208 attach_set_properties(attach, link->attach_properties);
AzureIoTClient 12:b30dacf113f2 209
AzureIoTClient 12:b30dacf113f2 210 if (role == role_sender)
AzureIoTClient 12:b30dacf113f2 211 {
AzureIoTClient 12:b30dacf113f2 212 if (attach_set_initial_delivery_count(attach, link->delivery_count) != 0)
AzureIoTClient 12:b30dacf113f2 213 {
AzureIoTClient 12:b30dacf113f2 214 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 215 }
AzureIoTClient 12:b30dacf113f2 216 }
AzureIoTClient 12:b30dacf113f2 217
AzureIoTClient 12:b30dacf113f2 218 if (result == 0)
AzureIoTClient 12:b30dacf113f2 219 {
AzureIoTClient 12:b30dacf113f2 220 if ((attach_set_max_message_size(attach, link->max_message_size) != 0) ||
AzureIoTClient 12:b30dacf113f2 221 (session_send_attach(link->link_endpoint, attach) != 0))
AzureIoTClient 12:b30dacf113f2 222 {
AzureIoTClient 12:b30dacf113f2 223 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 224 }
AzureIoTClient 12:b30dacf113f2 225 else
AzureIoTClient 12:b30dacf113f2 226 {
AzureIoTClient 12:b30dacf113f2 227 result = 0;
AzureIoTClient 12:b30dacf113f2 228 }
AzureIoTClient 12:b30dacf113f2 229 }
AzureIoTClient 12:b30dacf113f2 230
AzureIoTClient 12:b30dacf113f2 231 attach_destroy(attach);
AzureIoTClient 12:b30dacf113f2 232 }
AzureIoTClient 12:b30dacf113f2 233
AzureIoTClient 12:b30dacf113f2 234 return result;
AzureIoTClient 12:b30dacf113f2 235 }
AzureIoTClient 12:b30dacf113f2 236
Azure.IoT Build 0:6ae2f7bca550 237 static void link_frame_received(void* context, AMQP_VALUE performative, uint32_t payload_size, const unsigned char* payload_bytes)
Azure.IoT Build 0:6ae2f7bca550 238 {
Azure.IoT Build 0:6ae2f7bca550 239 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 240 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(performative);
Azure.IoT Build 0:6ae2f7bca550 241
Azure.IoT Build 0:6ae2f7bca550 242 if (is_attach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 243 {
Azure.IoT Build 0:6ae2f7bca550 244 ATTACH_HANDLE attach_handle;
Azure.IoT Build 0:6ae2f7bca550 245 if (amqpvalue_get_attach(performative, &attach_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 246 {
Azure.IoT Build 0:6ae2f7bca550 247 if ((link_instance->role == role_receiver) &&
Azure.IoT Build 0:6ae2f7bca550 248 (attach_get_initial_delivery_count(attach_handle, &link_instance->delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 249 {
Azure.IoT Build 0:6ae2f7bca550 250 /* error */
Azure.IoT Build 0:6ae2f7bca550 251 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 252 }
Azure.IoT Build 0:6ae2f7bca550 253 else
Azure.IoT Build 0:6ae2f7bca550 254 {
Azure.IoT Build 0:6ae2f7bca550 255 if (link_instance->link_state == LINK_STATE_HALF_ATTACHED)
Azure.IoT Build 0:6ae2f7bca550 256 {
Azure.IoT Build 0:6ae2f7bca550 257 if (link_instance->role == role_receiver)
Azure.IoT Build 0:6ae2f7bca550 258 {
Azure.IoT Build 0:6ae2f7bca550 259 link_instance->link_credit = DEFAULT_LINK_CREDIT;
Azure.IoT Build 0:6ae2f7bca550 260 send_flow(link_instance);
Azure.IoT Build 0:6ae2f7bca550 261 }
Azure.IoT Build 0:6ae2f7bca550 262 else
Azure.IoT Build 0:6ae2f7bca550 263 {
Azure.IoT Build 0:6ae2f7bca550 264 link_instance->link_credit = 0;
Azure.IoT Build 0:6ae2f7bca550 265 }
Azure.IoT Build 0:6ae2f7bca550 266
Azure.IoT Build 0:6ae2f7bca550 267 set_link_state(link_instance, LINK_STATE_ATTACHED);
Azure.IoT Build 0:6ae2f7bca550 268 }
Azure.IoT Build 0:6ae2f7bca550 269 }
Azure.IoT Build 0:6ae2f7bca550 270
Azure.IoT Build 0:6ae2f7bca550 271 attach_destroy(attach_handle);
Azure.IoT Build 0:6ae2f7bca550 272 }
Azure.IoT Build 0:6ae2f7bca550 273 }
Azure.IoT Build 0:6ae2f7bca550 274 else if (is_flow_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 275 {
Azure.IoT Build 0:6ae2f7bca550 276 FLOW_HANDLE flow_handle;
Azure.IoT Build 0:6ae2f7bca550 277 if (amqpvalue_get_flow(performative, &flow_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 278 {
Azure.IoT Build 0:6ae2f7bca550 279 if (link_instance->role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 280 {
Azure.IoT Build 0:6ae2f7bca550 281 delivery_number rcv_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 282 uint32_t rcv_link_credit;
Azure.IoT Build 0:6ae2f7bca550 283
Azure.IoT Build 0:6ae2f7bca550 284 if ((flow_get_link_credit(flow_handle, &rcv_link_credit) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 285 (flow_get_delivery_count(flow_handle, &rcv_delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 286 {
Azure.IoT Build 0:6ae2f7bca550 287 /* error */
Azure.IoT Build 0:6ae2f7bca550 288 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 289 }
Azure.IoT Build 0:6ae2f7bca550 290 else
Azure.IoT Build 0:6ae2f7bca550 291 {
Azure.IoT Build 0:6ae2f7bca550 292 link_instance->link_credit = rcv_delivery_count + rcv_link_credit - link_instance->delivery_count;
Azure.IoT Build 0:6ae2f7bca550 293 if (link_instance->link_credit > 0)
Azure.IoT Build 0:6ae2f7bca550 294 {
Azure.IoT Build 0:6ae2f7bca550 295 link_instance->on_link_flow_on(link_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 296 }
Azure.IoT Build 0:6ae2f7bca550 297 }
Azure.IoT Build 0:6ae2f7bca550 298 }
Azure.IoT Build 0:6ae2f7bca550 299 }
Azure.IoT Build 0:6ae2f7bca550 300
Azure.IoT Build 0:6ae2f7bca550 301 flow_destroy(flow_handle);
Azure.IoT Build 0:6ae2f7bca550 302 }
Azure.IoT Build 0:6ae2f7bca550 303 else if (is_transfer_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 304 {
Azure.IoT Build 0:6ae2f7bca550 305 if (link_instance->on_transfer_received != NULL)
Azure.IoT Build 0:6ae2f7bca550 306 {
Azure.IoT Build 0:6ae2f7bca550 307 TRANSFER_HANDLE transfer_handle;
Azure.IoT Build 0:6ae2f7bca550 308 if (amqpvalue_get_transfer(performative, &transfer_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 309 {
Azure.IoT Build 0:6ae2f7bca550 310 AMQP_VALUE delivery_state;
AzureIoTClient 12:b30dacf113f2 311 bool more;
Azure.IoT Build 0:6ae2f7bca550 312
Azure.IoT Build 0:6ae2f7bca550 313 link_instance->link_credit--;
Azure.IoT Build 0:6ae2f7bca550 314 link_instance->delivery_count++;
Azure.IoT Build 0:6ae2f7bca550 315 if (link_instance->link_credit == 0)
Azure.IoT Build 0:6ae2f7bca550 316 {
Azure.IoT Build 0:6ae2f7bca550 317 link_instance->link_credit = DEFAULT_LINK_CREDIT;
Azure.IoT Build 0:6ae2f7bca550 318 send_flow(link_instance);
Azure.IoT Build 0:6ae2f7bca550 319 }
Azure.IoT Build 0:6ae2f7bca550 320
AzureIoTClient 12:b30dacf113f2 321 if (transfer_get_more(transfer_handle, &more) != 0)
AzureIoTClient 12:b30dacf113f2 322 {
AzureIoTClient 12:b30dacf113f2 323 LogError("Could not get the more field from the transfer performative");
AzureIoTClient 12:b30dacf113f2 324 }
AzureIoTClient 12:b30dacf113f2 325 else
AzureIoTClient 12:b30dacf113f2 326 {
AzureIoTClient 12:b30dacf113f2 327 bool is_error = false;
AzureIoTClient 12:b30dacf113f2 328
AzureIoTClient 12:b30dacf113f2 329 if (transfer_get_delivery_id(transfer_handle, &link_instance->received_delivery_id) != 0)
AzureIoTClient 12:b30dacf113f2 330 {
AzureIoTClient 12:b30dacf113f2 331 /* is this not a continuation transfer? */
AzureIoTClient 12:b30dacf113f2 332 if (link_instance->received_payload_size == 0)
AzureIoTClient 12:b30dacf113f2 333 {
AzureIoTClient 12:b30dacf113f2 334 LogError("Could not get the delivery Id from the transfer performative");
AzureIoTClient 12:b30dacf113f2 335 is_error = true;
AzureIoTClient 12:b30dacf113f2 336 }
AzureIoTClient 12:b30dacf113f2 337 }
AzureIoTClient 12:b30dacf113f2 338
AzureIoTClient 12:b30dacf113f2 339 if (!is_error)
AzureIoTClient 12:b30dacf113f2 340 {
AzureIoTClient 12:b30dacf113f2 341 /* If this is a continuation transfer or if this is the first chunk of a multi frame transfer */
AzureIoTClient 12:b30dacf113f2 342 if ((link_instance->received_payload_size > 0) || more)
AzureIoTClient 12:b30dacf113f2 343 {
AzureIoTClient 12:b30dacf113f2 344 unsigned char* new_received_payload = (unsigned char*)realloc(link_instance->received_payload, link_instance->received_payload_size + payload_size);
AzureIoTClient 12:b30dacf113f2 345 if (new_received_payload == NULL)
AzureIoTClient 12:b30dacf113f2 346 {
AzureIoTClient 12:b30dacf113f2 347 LogError("Could not allocate memory for the received payload");
AzureIoTClient 12:b30dacf113f2 348 }
AzureIoTClient 12:b30dacf113f2 349 else
AzureIoTClient 12:b30dacf113f2 350 {
AzureIoTClient 12:b30dacf113f2 351 link_instance->received_payload = new_received_payload;
AzureIoTClient 12:b30dacf113f2 352 (void)memcpy(link_instance->received_payload + link_instance->received_payload_size, payload_bytes, payload_size);
AzureIoTClient 12:b30dacf113f2 353 link_instance->received_payload_size += payload_size;
AzureIoTClient 12:b30dacf113f2 354 }
AzureIoTClient 12:b30dacf113f2 355 }
Azure.IoT Build 0:6ae2f7bca550 356
AzureIoTClient 12:b30dacf113f2 357 if (!more)
AzureIoTClient 12:b30dacf113f2 358 {
AzureIoTClient 12:b30dacf113f2 359 const unsigned char* indicate_payload_bytes;
AzureIoTClient 12:b30dacf113f2 360 uint32_t indicate_payload_size;
AzureIoTClient 12:b30dacf113f2 361
AzureIoTClient 12:b30dacf113f2 362 /* if no previously stored chunks then simply report the current payload */
AzureIoTClient 12:b30dacf113f2 363 if (link_instance->received_payload_size > 0)
AzureIoTClient 12:b30dacf113f2 364 {
AzureIoTClient 12:b30dacf113f2 365 indicate_payload_size = link_instance->received_payload_size;
AzureIoTClient 12:b30dacf113f2 366 indicate_payload_bytes = link_instance->received_payload;
AzureIoTClient 12:b30dacf113f2 367 }
AzureIoTClient 12:b30dacf113f2 368 else
AzureIoTClient 12:b30dacf113f2 369 {
AzureIoTClient 12:b30dacf113f2 370 indicate_payload_size = payload_size;
AzureIoTClient 12:b30dacf113f2 371 indicate_payload_bytes = payload_bytes;
AzureIoTClient 12:b30dacf113f2 372 }
AzureIoTClient 12:b30dacf113f2 373
AzureIoTClient 12:b30dacf113f2 374 delivery_state = link_instance->on_transfer_received(link_instance->callback_context, transfer_handle, indicate_payload_size, indicate_payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 375
AzureIoTClient 12:b30dacf113f2 376 if (link_instance->received_payload_size > 0)
AzureIoTClient 12:b30dacf113f2 377 {
AzureIoTClient 12:b30dacf113f2 378 free(link_instance->received_payload);
AzureIoTClient 12:b30dacf113f2 379 link_instance->received_payload = NULL;
AzureIoTClient 12:b30dacf113f2 380 link_instance->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 381 }
AzureIoTClient 12:b30dacf113f2 382
AzureIoTClient 12:b30dacf113f2 383 if (send_disposition(link_instance, link_instance->received_delivery_id, delivery_state) != 0)
AzureIoTClient 12:b30dacf113f2 384 {
AzureIoTClient 12:b30dacf113f2 385 LogError("Cannot send disposition frame");
AzureIoTClient 12:b30dacf113f2 386 }
AzureIoTClient 12:b30dacf113f2 387
AzureIoTClient 12:b30dacf113f2 388 if (delivery_state != NULL)
AzureIoTClient 12:b30dacf113f2 389 {
AzureIoTClient 12:b30dacf113f2 390 amqpvalue_destroy(delivery_state);
AzureIoTClient 12:b30dacf113f2 391 }
AzureIoTClient 12:b30dacf113f2 392 }
AzureIoTClient 12:b30dacf113f2 393 }
AzureIoTClient 12:b30dacf113f2 394 }
Azure.IoT Build 0:6ae2f7bca550 395
Azure.IoT Build 0:6ae2f7bca550 396 transfer_destroy(transfer_handle);
Azure.IoT Build 0:6ae2f7bca550 397 }
Azure.IoT Build 0:6ae2f7bca550 398 }
Azure.IoT Build 0:6ae2f7bca550 399 }
Azure.IoT Build 0:6ae2f7bca550 400 else if (is_disposition_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 401 {
Azure.IoT Build 0:6ae2f7bca550 402 DISPOSITION_HANDLE disposition;
Azure.IoT Build 0:6ae2f7bca550 403 if (amqpvalue_get_disposition(performative, &disposition) != 0)
Azure.IoT Build 0:6ae2f7bca550 404 {
Azure.IoT Build 0:6ae2f7bca550 405 /* error */
Azure.IoT Build 0:6ae2f7bca550 406 }
Azure.IoT Build 0:6ae2f7bca550 407 else
Azure.IoT Build 0:6ae2f7bca550 408 {
Azure.IoT Build 0:6ae2f7bca550 409 delivery_number first;
Azure.IoT Build 0:6ae2f7bca550 410 delivery_number last;
Azure.IoT Build 0:6ae2f7bca550 411
Azure.IoT Build 0:6ae2f7bca550 412 if (disposition_get_first(disposition, &first) != 0)
Azure.IoT Build 0:6ae2f7bca550 413 {
Azure.IoT Build 0:6ae2f7bca550 414 /* error */
Azure.IoT Build 0:6ae2f7bca550 415 }
Azure.IoT Build 0:6ae2f7bca550 416 else
Azure.IoT Build 0:6ae2f7bca550 417 {
Azure.IoT Build 0:6ae2f7bca550 418 bool settled;
Azure.IoT Build 0:6ae2f7bca550 419
Azure.IoT Build 0:6ae2f7bca550 420 if (disposition_get_last(disposition, &last) != 0)
Azure.IoT Build 0:6ae2f7bca550 421 {
Azure.IoT Build 0:6ae2f7bca550 422 last = first;
Azure.IoT Build 0:6ae2f7bca550 423 }
Azure.IoT Build 0:6ae2f7bca550 424
Azure.IoT Build 0:6ae2f7bca550 425 if (disposition_get_settled(disposition, &settled) != 0)
Azure.IoT Build 0:6ae2f7bca550 426 {
Azure.IoT Build 0:6ae2f7bca550 427 /* Error */
Azure.IoT Build 0:6ae2f7bca550 428 settled = false;
Azure.IoT Build 0:6ae2f7bca550 429 }
Azure.IoT Build 0:6ae2f7bca550 430
Azure.IoT Build 0:6ae2f7bca550 431 if (settled)
Azure.IoT Build 0:6ae2f7bca550 432 {
AzureIoTClient 12:b30dacf113f2 433 LIST_ITEM_HANDLE pending_delivery = singlylinkedlist_get_head_item(link_instance->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 434 while (pending_delivery != NULL)
Azure.IoT Build 0:6ae2f7bca550 435 {
AzureIoTClient 12:b30dacf113f2 436 LIST_ITEM_HANDLE next_pending_delivery = singlylinkedlist_get_next_item(pending_delivery);
AzureIoTClient 12:b30dacf113f2 437 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 438 if (delivery_instance == NULL)
Azure.IoT Build 0:6ae2f7bca550 439 {
Azure.IoT Build 0:6ae2f7bca550 440 /* error */
Azure.IoT Build 0:6ae2f7bca550 441 break;
Azure.IoT Build 0:6ae2f7bca550 442 }
Azure.IoT Build 0:6ae2f7bca550 443 else
Azure.IoT Build 0:6ae2f7bca550 444 {
Azure.IoT Build 0:6ae2f7bca550 445 if ((delivery_instance->delivery_id >= first) && (delivery_instance->delivery_id <= last))
Azure.IoT Build 0:6ae2f7bca550 446 {
AzureIoTClient 7:9e9ab3b0efef 447 AMQP_VALUE delivery_state;
AzureIoTClient 7:9e9ab3b0efef 448 if (disposition_get_state(disposition, &delivery_state) != 0)
Azure.IoT Build 0:6ae2f7bca550 449 {
Azure.IoT Build 0:6ae2f7bca550 450 /* error */
Azure.IoT Build 0:6ae2f7bca550 451 }
Azure.IoT Build 0:6ae2f7bca550 452 else
Azure.IoT Build 0:6ae2f7bca550 453 {
AzureIoTClient 7:9e9ab3b0efef 454 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, delivery_state);
AzureIoTClient 7:9e9ab3b0efef 455 amqpalloc_free(delivery_instance);
AzureIoTClient 12:b30dacf113f2 456 if (singlylinkedlist_remove(link_instance->pending_deliveries, pending_delivery) != 0)
AzureIoTClient 7:9e9ab3b0efef 457 {
AzureIoTClient 7:9e9ab3b0efef 458 /* error */
AzureIoTClient 7:9e9ab3b0efef 459 break;
AzureIoTClient 7:9e9ab3b0efef 460 }
AzureIoTClient 7:9e9ab3b0efef 461 else
AzureIoTClient 7:9e9ab3b0efef 462 {
AzureIoTClient 7:9e9ab3b0efef 463 pending_delivery = next_pending_delivery;
AzureIoTClient 7:9e9ab3b0efef 464 }
Azure.IoT Build 0:6ae2f7bca550 465 }
Azure.IoT Build 0:6ae2f7bca550 466 }
Azure.IoT Build 0:6ae2f7bca550 467 else
Azure.IoT Build 0:6ae2f7bca550 468 {
Azure.IoT Build 0:6ae2f7bca550 469 pending_delivery = next_pending_delivery;
Azure.IoT Build 0:6ae2f7bca550 470 }
Azure.IoT Build 0:6ae2f7bca550 471 }
Azure.IoT Build 0:6ae2f7bca550 472 }
Azure.IoT Build 0:6ae2f7bca550 473 }
Azure.IoT Build 0:6ae2f7bca550 474 }
Azure.IoT Build 0:6ae2f7bca550 475
Azure.IoT Build 0:6ae2f7bca550 476 disposition_destroy(disposition);
Azure.IoT Build 0:6ae2f7bca550 477 }
Azure.IoT Build 0:6ae2f7bca550 478 }
Azure.IoT Build 0:6ae2f7bca550 479 else if (is_detach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 480 {
AzureIoTClient 1:eab586236bfe 481 DETACH_HANDLE detach;
AzureIoTClient 1:eab586236bfe 482
AzureIoTClient 1:eab586236bfe 483 /* Set link state appropriately based on whether we received detach condition */
AzureIoTClient 1:eab586236bfe 484 if (amqpvalue_get_detach(performative, &detach) == 0)
AzureIoTClient 1:eab586236bfe 485 {
AzureIoTClient 12:b30dacf113f2 486 bool closed = false;
AzureIoTClient 1:eab586236bfe 487 ERROR_HANDLE error;
AzureIoTClient 1:eab586236bfe 488 if (detach_get_error(detach, &error) == 0)
AzureIoTClient 1:eab586236bfe 489 {
AzureIoTClient 1:eab586236bfe 490 error_destroy(error);
AzureIoTClient 1:eab586236bfe 491
AzureIoTClient 1:eab586236bfe 492 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 493 }
AzureIoTClient 12:b30dacf113f2 494 else
AzureIoTClient 1:eab586236bfe 495 {
AzureIoTClient 12:b30dacf113f2 496 (void)detach_get_closed(detach, &closed);
AzureIoTClient 12:b30dacf113f2 497
AzureIoTClient 1:eab586236bfe 498 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 1:eab586236bfe 499 }
AzureIoTClient 12:b30dacf113f2 500
AzureIoTClient 12:b30dacf113f2 501 /* Received a detach while attached */
AzureIoTClient 12:b30dacf113f2 502 if (link_instance->previous_link_state == LINK_STATE_ATTACHED)
AzureIoTClient 12:b30dacf113f2 503 {
AzureIoTClient 12:b30dacf113f2 504 /* Respond with ack */
AzureIoTClient 12:b30dacf113f2 505 (void)send_detach(link_instance, closed, NULL);
AzureIoTClient 12:b30dacf113f2 506 }
AzureIoTClient 12:b30dacf113f2 507
AzureIoTClient 12:b30dacf113f2 508 /* Received a closing detach after we sent a non-closing detach. */
AzureIoTClient 12:b30dacf113f2 509 else if (closed &&
AzureIoTClient 12:b30dacf113f2 510 (link_instance->previous_link_state == LINK_STATE_HALF_ATTACHED) &&
AzureIoTClient 12:b30dacf113f2 511 !link_instance->is_closed)
AzureIoTClient 12:b30dacf113f2 512 {
AzureIoTClient 12:b30dacf113f2 513
AzureIoTClient 12:b30dacf113f2 514 /* In this case, we MUST signal that we closed by reattaching and then sending a closing detach.*/
AzureIoTClient 12:b30dacf113f2 515 (void)send_attach(link_instance, link_instance->name, 0, link_instance->role);
AzureIoTClient 12:b30dacf113f2 516 (void)send_detach(link_instance, true, NULL);
AzureIoTClient 12:b30dacf113f2 517 }
AzureIoTClient 12:b30dacf113f2 518
AzureIoTClient 12:b30dacf113f2 519 detach_destroy(detach);
AzureIoTClient 1:eab586236bfe 520 }
AzureIoTClient 1:eab586236bfe 521 }
Azure.IoT Build 0:6ae2f7bca550 522 }
Azure.IoT Build 0:6ae2f7bca550 523
Azure.IoT Build 0:6ae2f7bca550 524 static void on_session_state_changed(void* context, SESSION_STATE new_session_state, SESSION_STATE previous_session_state)
Azure.IoT Build 0:6ae2f7bca550 525 {
Azure.IoT Build 0:6ae2f7bca550 526 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 527 (void)previous_session_state;
Azure.IoT Build 0:6ae2f7bca550 528
Azure.IoT Build 0:6ae2f7bca550 529 if (new_session_state == SESSION_STATE_MAPPED)
Azure.IoT Build 0:6ae2f7bca550 530 {
AzureIoTClient 12:b30dacf113f2 531 if ((link_instance->link_state == LINK_STATE_DETACHED) && (!link_instance->is_closed))
Azure.IoT Build 0:6ae2f7bca550 532 {
Azure.IoT Build 0:6ae2f7bca550 533 if (send_attach(link_instance, link_instance->name, 0, link_instance->role) == 0)
Azure.IoT Build 0:6ae2f7bca550 534 {
Azure.IoT Build 0:6ae2f7bca550 535 set_link_state(link_instance, LINK_STATE_HALF_ATTACHED);
Azure.IoT Build 0:6ae2f7bca550 536 }
Azure.IoT Build 0:6ae2f7bca550 537 }
Azure.IoT Build 0:6ae2f7bca550 538 }
Azure.IoT Build 0:6ae2f7bca550 539 else if (new_session_state == SESSION_STATE_DISCARDING)
Azure.IoT Build 0:6ae2f7bca550 540 {
Azure.IoT Build 0:6ae2f7bca550 541 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 542 }
AzureIoTClient 1:eab586236bfe 543 else if (new_session_state == SESSION_STATE_ERROR)
AzureIoTClient 1:eab586236bfe 544 {
AzureIoTClient 1:eab586236bfe 545 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 546 }
Azure.IoT Build 0:6ae2f7bca550 547 }
Azure.IoT Build 0:6ae2f7bca550 548
Azure.IoT Build 0:6ae2f7bca550 549 static void on_session_flow_on(void* context)
Azure.IoT Build 0:6ae2f7bca550 550 {
Azure.IoT Build 0:6ae2f7bca550 551 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 552 if (link_instance->role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 553 {
Azure.IoT Build 0:6ae2f7bca550 554 link_instance->on_link_flow_on(link_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 555 }
Azure.IoT Build 0:6ae2f7bca550 556 }
Azure.IoT Build 0:6ae2f7bca550 557
Azure.IoT Build 0:6ae2f7bca550 558 static void on_send_complete(void* context, IO_SEND_RESULT send_result)
Azure.IoT Build 0:6ae2f7bca550 559 {
Azure.IoT Build 0:6ae2f7bca550 560 LIST_ITEM_HANDLE delivery_instance_list_item = (LIST_ITEM_HANDLE)context;
AzureIoTClient 12:b30dacf113f2 561 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(delivery_instance_list_item);
Azure.IoT Build 0:6ae2f7bca550 562 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)delivery_instance->link;
AzureIoTClient 6:641a9672db08 563 (void)send_result;
Azure.IoT Build 0:6ae2f7bca550 564 if (link_instance->snd_settle_mode == sender_settle_mode_settled)
Azure.IoT Build 0:6ae2f7bca550 565 {
AzureIoTClient 7:9e9ab3b0efef 566 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, NULL);
Azure.IoT Build 0:6ae2f7bca550 567 amqpalloc_free(delivery_instance);
AzureIoTClient 12:b30dacf113f2 568 (void)singlylinkedlist_remove(link_instance->pending_deliveries, delivery_instance_list_item);
Azure.IoT Build 0:6ae2f7bca550 569 }
Azure.IoT Build 0:6ae2f7bca550 570 }
Azure.IoT Build 0:6ae2f7bca550 571
Azure.IoT Build 0:6ae2f7bca550 572 LINK_HANDLE link_create(SESSION_HANDLE session, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
Azure.IoT Build 0:6ae2f7bca550 573 {
Azure.IoT Build 0:6ae2f7bca550 574 LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 575 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 576 {
Azure.IoT Build 0:6ae2f7bca550 577 result->link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 578 result->previous_link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 579 result->role = role;
Azure.IoT Build 0:6ae2f7bca550 580 result->source = amqpvalue_clone(source);
Azure.IoT Build 0:6ae2f7bca550 581 result->target = amqpvalue_clone(target);
Azure.IoT Build 0:6ae2f7bca550 582 result->session = session;
Azure.IoT Build 0:6ae2f7bca550 583 result->handle = 0;
Azure.IoT Build 0:6ae2f7bca550 584 result->snd_settle_mode = sender_settle_mode_unsettled;
Azure.IoT Build 0:6ae2f7bca550 585 result->rcv_settle_mode = receiver_settle_mode_first;
Azure.IoT Build 0:6ae2f7bca550 586 result->delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 587 result->initial_delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 588 result->max_message_size = 0;
AzureIoTClient 12:b30dacf113f2 589 result->is_underlying_session_begun = false;
AzureIoTClient 12:b30dacf113f2 590 result->is_closed = false;
Azure.IoT Build 0:6ae2f7bca550 591 result->attach_properties = NULL;
AzureIoTClient 12:b30dacf113f2 592 result->received_payload = NULL;
AzureIoTClient 12:b30dacf113f2 593 result->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 594 result->received_delivery_id = 0;
Azure.IoT Build 0:6ae2f7bca550 595
AzureIoTClient 12:b30dacf113f2 596 result->pending_deliveries = singlylinkedlist_create();
Azure.IoT Build 0:6ae2f7bca550 597 if (result->pending_deliveries == NULL)
Azure.IoT Build 0:6ae2f7bca550 598 {
Azure.IoT Build 0:6ae2f7bca550 599 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 600 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 601 }
Azure.IoT Build 0:6ae2f7bca550 602 else
Azure.IoT Build 0:6ae2f7bca550 603 {
Azure.IoT Build 0:6ae2f7bca550 604 result->name = amqpalloc_malloc(strlen(name) + 1);
Azure.IoT Build 0:6ae2f7bca550 605 if (result->name == NULL)
Azure.IoT Build 0:6ae2f7bca550 606 {
AzureIoTClient 12:b30dacf113f2 607 singlylinkedlist_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 608 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 609 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 610 }
Azure.IoT Build 0:6ae2f7bca550 611 else
Azure.IoT Build 0:6ae2f7bca550 612 {
Azure.IoT Build 0:6ae2f7bca550 613 result->on_link_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 614 result->callback_context = NULL;
Azure.IoT Build 0:6ae2f7bca550 615 set_link_state(result, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 616
Azure.IoT Build 0:6ae2f7bca550 617 (void)strcpy(result->name, name);
Azure.IoT Build 0:6ae2f7bca550 618 result->link_endpoint = session_create_link_endpoint(session, name);
Azure.IoT Build 0:6ae2f7bca550 619 if (result->link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 620 {
AzureIoTClient 12:b30dacf113f2 621 singlylinkedlist_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 622 amqpalloc_free(result->name);
Azure.IoT Build 0:6ae2f7bca550 623 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 624 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 625 }
Azure.IoT Build 0:6ae2f7bca550 626 }
Azure.IoT Build 0:6ae2f7bca550 627 }
Azure.IoT Build 0:6ae2f7bca550 628 }
Azure.IoT Build 0:6ae2f7bca550 629
Azure.IoT Build 0:6ae2f7bca550 630 return result;
Azure.IoT Build 0:6ae2f7bca550 631 }
Azure.IoT Build 0:6ae2f7bca550 632
Azure.IoT Build 0:6ae2f7bca550 633 LINK_HANDLE link_create_from_endpoint(SESSION_HANDLE session, LINK_ENDPOINT_HANDLE link_endpoint, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
Azure.IoT Build 0:6ae2f7bca550 634 {
Azure.IoT Build 0:6ae2f7bca550 635 LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 636 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 637 {
Azure.IoT Build 0:6ae2f7bca550 638 result->link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 639 result->previous_link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 640 result->session = session;
Azure.IoT Build 0:6ae2f7bca550 641 result->handle = 0;
Azure.IoT Build 0:6ae2f7bca550 642 result->snd_settle_mode = sender_settle_mode_unsettled;
Azure.IoT Build 0:6ae2f7bca550 643 result->rcv_settle_mode = receiver_settle_mode_first;
Azure.IoT Build 0:6ae2f7bca550 644 result->delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 645 result->initial_delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 646 result->max_message_size = 0;
AzureIoTClient 12:b30dacf113f2 647 result->is_underlying_session_begun = false;
AzureIoTClient 12:b30dacf113f2 648 result->is_closed = false;
Azure.IoT Build 0:6ae2f7bca550 649 result->attach_properties = NULL;
AzureIoTClient 12:b30dacf113f2 650 result->received_payload = NULL;
AzureIoTClient 12:b30dacf113f2 651 result->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 652 result->received_delivery_id = 0;
Azure.IoT Build 0:6ae2f7bca550 653 result->source = amqpvalue_clone(target);
Azure.IoT Build 0:6ae2f7bca550 654 result->target = amqpvalue_clone(source);
Azure.IoT Build 0:6ae2f7bca550 655 if (role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 656 {
Azure.IoT Build 0:6ae2f7bca550 657 result->role = role_receiver;
Azure.IoT Build 0:6ae2f7bca550 658 }
Azure.IoT Build 0:6ae2f7bca550 659 else
Azure.IoT Build 0:6ae2f7bca550 660 {
Azure.IoT Build 0:6ae2f7bca550 661 result->role = role_sender;
Azure.IoT Build 0:6ae2f7bca550 662 }
Azure.IoT Build 0:6ae2f7bca550 663
AzureIoTClient 12:b30dacf113f2 664 result->pending_deliveries = singlylinkedlist_create();
Azure.IoT Build 0:6ae2f7bca550 665 if (result->pending_deliveries == NULL)
Azure.IoT Build 0:6ae2f7bca550 666 {
Azure.IoT Build 0:6ae2f7bca550 667 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 668 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 669 }
Azure.IoT Build 0:6ae2f7bca550 670 else
Azure.IoT Build 0:6ae2f7bca550 671 {
Azure.IoT Build 0:6ae2f7bca550 672 result->name = amqpalloc_malloc(strlen(name) + 1);
Azure.IoT Build 0:6ae2f7bca550 673 if (result->name == NULL)
Azure.IoT Build 0:6ae2f7bca550 674 {
AzureIoTClient 12:b30dacf113f2 675 singlylinkedlist_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 676 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 677 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 678 }
Azure.IoT Build 0:6ae2f7bca550 679 else
Azure.IoT Build 0:6ae2f7bca550 680 {
Azure.IoT Build 0:6ae2f7bca550 681 (void)strcpy(result->name, name);
Azure.IoT Build 0:6ae2f7bca550 682 result->on_link_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 683 result->callback_context = NULL;
Azure.IoT Build 0:6ae2f7bca550 684 result->link_endpoint = link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 685 }
Azure.IoT Build 0:6ae2f7bca550 686 }
Azure.IoT Build 0:6ae2f7bca550 687 }
Azure.IoT Build 0:6ae2f7bca550 688
Azure.IoT Build 0:6ae2f7bca550 689 return result;
Azure.IoT Build 0:6ae2f7bca550 690 }
Azure.IoT Build 0:6ae2f7bca550 691
Azure.IoT Build 0:6ae2f7bca550 692 void link_destroy(LINK_HANDLE link)
Azure.IoT Build 0:6ae2f7bca550 693 {
Azure.IoT Build 0:6ae2f7bca550 694 if (link != NULL)
Azure.IoT Build 0:6ae2f7bca550 695 {
AzureIoTClient 12:b30dacf113f2 696 link->on_link_state_changed = NULL;
AzureIoTClient 12:b30dacf113f2 697 (void)link_detach(link, true);
AzureIoTClient 12:b30dacf113f2 698 session_destroy_link_endpoint(link->link_endpoint);
Azure.IoT Build 0:6ae2f7bca550 699 amqpvalue_destroy(link->source);
Azure.IoT Build 0:6ae2f7bca550 700 amqpvalue_destroy(link->target);
Azure.IoT Build 0:6ae2f7bca550 701 if (link->pending_deliveries != NULL)
Azure.IoT Build 0:6ae2f7bca550 702 {
AzureIoTClient 12:b30dacf113f2 703 LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(link->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 704 while (item != NULL)
Azure.IoT Build 0:6ae2f7bca550 705 {
AzureIoTClient 12:b30dacf113f2 706 LIST_ITEM_HANDLE next_item = singlylinkedlist_get_next_item(item);
AzureIoTClient 12:b30dacf113f2 707 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(item);
Azure.IoT Build 0:6ae2f7bca550 708 if (delivery_instance != NULL)
Azure.IoT Build 0:6ae2f7bca550 709 {
Azure.IoT Build 0:6ae2f7bca550 710 amqpalloc_free(delivery_instance);
Azure.IoT Build 0:6ae2f7bca550 711 }
Azure.IoT Build 0:6ae2f7bca550 712
Azure.IoT Build 0:6ae2f7bca550 713 item = next_item;
Azure.IoT Build 0:6ae2f7bca550 714 }
Azure.IoT Build 0:6ae2f7bca550 715
AzureIoTClient 12:b30dacf113f2 716 singlylinkedlist_destroy(link->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 717 }
Azure.IoT Build 0:6ae2f7bca550 718
Azure.IoT Build 0:6ae2f7bca550 719 if (link->name != NULL)
Azure.IoT Build 0:6ae2f7bca550 720 {
Azure.IoT Build 0:6ae2f7bca550 721 amqpalloc_free(link->name);
Azure.IoT Build 0:6ae2f7bca550 722 }
Azure.IoT Build 0:6ae2f7bca550 723
AzureIoTClient 3:96522ba2ddf8 724 if (link->attach_properties != NULL)
Azure.IoT Build 0:6ae2f7bca550 725 {
AzureIoTClient 3:96522ba2ddf8 726 amqpvalue_destroy(link->attach_properties);
Azure.IoT Build 0:6ae2f7bca550 727 }
Azure.IoT Build 0:6ae2f7bca550 728
AzureIoTClient 12:b30dacf113f2 729 if (link->received_payload != NULL)
AzureIoTClient 12:b30dacf113f2 730 {
AzureIoTClient 12:b30dacf113f2 731 free(link->received_payload);
AzureIoTClient 12:b30dacf113f2 732 }
AzureIoTClient 12:b30dacf113f2 733
Azure.IoT Build 0:6ae2f7bca550 734 amqpalloc_free(link);
Azure.IoT Build 0:6ae2f7bca550 735 }
Azure.IoT Build 0:6ae2f7bca550 736 }
Azure.IoT Build 0:6ae2f7bca550 737
Azure.IoT Build 0:6ae2f7bca550 738 int link_set_snd_settle_mode(LINK_HANDLE link, sender_settle_mode snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 739 {
Azure.IoT Build 0:6ae2f7bca550 740 int result;
Azure.IoT Build 0:6ae2f7bca550 741
Azure.IoT Build 0:6ae2f7bca550 742 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 743 {
Azure.IoT Build 0:6ae2f7bca550 744 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 745 }
Azure.IoT Build 0:6ae2f7bca550 746 else
Azure.IoT Build 0:6ae2f7bca550 747 {
Azure.IoT Build 0:6ae2f7bca550 748 link->snd_settle_mode = snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 749 result = 0;
Azure.IoT Build 0:6ae2f7bca550 750 }
Azure.IoT Build 0:6ae2f7bca550 751
Azure.IoT Build 0:6ae2f7bca550 752 return result;
Azure.IoT Build 0:6ae2f7bca550 753 }
Azure.IoT Build 0:6ae2f7bca550 754
Azure.IoT Build 0:6ae2f7bca550 755 int link_get_snd_settle_mode(LINK_HANDLE link, sender_settle_mode* snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 756 {
Azure.IoT Build 0:6ae2f7bca550 757 int result;
Azure.IoT Build 0:6ae2f7bca550 758
Azure.IoT Build 0:6ae2f7bca550 759 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 760 (snd_settle_mode == NULL))
Azure.IoT Build 0:6ae2f7bca550 761 {
Azure.IoT Build 0:6ae2f7bca550 762 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 763 }
Azure.IoT Build 0:6ae2f7bca550 764 else
Azure.IoT Build 0:6ae2f7bca550 765 {
Azure.IoT Build 0:6ae2f7bca550 766 *snd_settle_mode = link->snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 767
Azure.IoT Build 0:6ae2f7bca550 768 result = 0;
Azure.IoT Build 0:6ae2f7bca550 769 }
Azure.IoT Build 0:6ae2f7bca550 770
Azure.IoT Build 0:6ae2f7bca550 771 return result;
Azure.IoT Build 0:6ae2f7bca550 772 }
Azure.IoT Build 0:6ae2f7bca550 773
Azure.IoT Build 0:6ae2f7bca550 774 int link_set_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 775 {
Azure.IoT Build 0:6ae2f7bca550 776 int result;
Azure.IoT Build 0:6ae2f7bca550 777
Azure.IoT Build 0:6ae2f7bca550 778 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 779 {
Azure.IoT Build 0:6ae2f7bca550 780 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 781 }
Azure.IoT Build 0:6ae2f7bca550 782 else
Azure.IoT Build 0:6ae2f7bca550 783 {
Azure.IoT Build 0:6ae2f7bca550 784 link->rcv_settle_mode = rcv_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 785 result = 0;
Azure.IoT Build 0:6ae2f7bca550 786 }
Azure.IoT Build 0:6ae2f7bca550 787
Azure.IoT Build 0:6ae2f7bca550 788 return result;
Azure.IoT Build 0:6ae2f7bca550 789 }
Azure.IoT Build 0:6ae2f7bca550 790
Azure.IoT Build 0:6ae2f7bca550 791 int link_get_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode* rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 792 {
Azure.IoT Build 0:6ae2f7bca550 793 int result;
Azure.IoT Build 0:6ae2f7bca550 794
Azure.IoT Build 0:6ae2f7bca550 795 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 796 (rcv_settle_mode == NULL))
Azure.IoT Build 0:6ae2f7bca550 797 {
Azure.IoT Build 0:6ae2f7bca550 798 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 799 }
Azure.IoT Build 0:6ae2f7bca550 800 else
Azure.IoT Build 0:6ae2f7bca550 801 {
Azure.IoT Build 0:6ae2f7bca550 802 *rcv_settle_mode = link->rcv_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 803 result = 0;
Azure.IoT Build 0:6ae2f7bca550 804 }
Azure.IoT Build 0:6ae2f7bca550 805
Azure.IoT Build 0:6ae2f7bca550 806 return result;
Azure.IoT Build 0:6ae2f7bca550 807 }
Azure.IoT Build 0:6ae2f7bca550 808
Azure.IoT Build 0:6ae2f7bca550 809 int link_set_initial_delivery_count(LINK_HANDLE link, sequence_no initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 810 {
Azure.IoT Build 0:6ae2f7bca550 811 int result;
Azure.IoT Build 0:6ae2f7bca550 812
Azure.IoT Build 0:6ae2f7bca550 813 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 814 {
Azure.IoT Build 0:6ae2f7bca550 815 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 816 }
Azure.IoT Build 0:6ae2f7bca550 817 else
Azure.IoT Build 0:6ae2f7bca550 818 {
Azure.IoT Build 0:6ae2f7bca550 819 link->initial_delivery_count = initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 820 result = 0;
Azure.IoT Build 0:6ae2f7bca550 821 }
Azure.IoT Build 0:6ae2f7bca550 822
Azure.IoT Build 0:6ae2f7bca550 823 return result;
Azure.IoT Build 0:6ae2f7bca550 824 }
Azure.IoT Build 0:6ae2f7bca550 825
Azure.IoT Build 0:6ae2f7bca550 826 int link_get_initial_delivery_count(LINK_HANDLE link, sequence_no* initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 827 {
Azure.IoT Build 0:6ae2f7bca550 828 int result;
Azure.IoT Build 0:6ae2f7bca550 829
Azure.IoT Build 0:6ae2f7bca550 830 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 831 (initial_delivery_count == NULL))
Azure.IoT Build 0:6ae2f7bca550 832 {
Azure.IoT Build 0:6ae2f7bca550 833 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 834 }
Azure.IoT Build 0:6ae2f7bca550 835 else
Azure.IoT Build 0:6ae2f7bca550 836 {
Azure.IoT Build 0:6ae2f7bca550 837 *initial_delivery_count = link->initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 838 result = 0;
Azure.IoT Build 0:6ae2f7bca550 839 }
Azure.IoT Build 0:6ae2f7bca550 840
Azure.IoT Build 0:6ae2f7bca550 841 return result;
Azure.IoT Build 0:6ae2f7bca550 842 }
Azure.IoT Build 0:6ae2f7bca550 843
Azure.IoT Build 0:6ae2f7bca550 844 int link_set_max_message_size(LINK_HANDLE link, uint64_t max_message_size)
Azure.IoT Build 0:6ae2f7bca550 845 {
Azure.IoT Build 0:6ae2f7bca550 846 int result;
Azure.IoT Build 0:6ae2f7bca550 847
Azure.IoT Build 0:6ae2f7bca550 848 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 849 {
Azure.IoT Build 0:6ae2f7bca550 850 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 851 }
Azure.IoT Build 0:6ae2f7bca550 852 else
Azure.IoT Build 0:6ae2f7bca550 853 {
Azure.IoT Build 0:6ae2f7bca550 854 link->max_message_size = max_message_size;
Azure.IoT Build 0:6ae2f7bca550 855 result = 0;
Azure.IoT Build 0:6ae2f7bca550 856 }
Azure.IoT Build 0:6ae2f7bca550 857
Azure.IoT Build 0:6ae2f7bca550 858 return result;
Azure.IoT Build 0:6ae2f7bca550 859 }
Azure.IoT Build 0:6ae2f7bca550 860
Azure.IoT Build 0:6ae2f7bca550 861 int link_get_max_message_size(LINK_HANDLE link, uint64_t* max_message_size)
Azure.IoT Build 0:6ae2f7bca550 862 {
Azure.IoT Build 0:6ae2f7bca550 863 int result;
Azure.IoT Build 0:6ae2f7bca550 864
Azure.IoT Build 0:6ae2f7bca550 865 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 866 (max_message_size == NULL))
Azure.IoT Build 0:6ae2f7bca550 867 {
Azure.IoT Build 0:6ae2f7bca550 868 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 869 }
Azure.IoT Build 0:6ae2f7bca550 870 else
Azure.IoT Build 0:6ae2f7bca550 871 {
Azure.IoT Build 0:6ae2f7bca550 872 *max_message_size = link->max_message_size;
Azure.IoT Build 0:6ae2f7bca550 873 result = 0;
Azure.IoT Build 0:6ae2f7bca550 874 }
Azure.IoT Build 0:6ae2f7bca550 875
Azure.IoT Build 0:6ae2f7bca550 876 return result;
Azure.IoT Build 0:6ae2f7bca550 877 }
Azure.IoT Build 0:6ae2f7bca550 878
Azure.IoT Build 0:6ae2f7bca550 879 int link_set_attach_properties(LINK_HANDLE link, fields attach_properties)
Azure.IoT Build 0:6ae2f7bca550 880 {
Azure.IoT Build 0:6ae2f7bca550 881 int result;
Azure.IoT Build 0:6ae2f7bca550 882
Azure.IoT Build 0:6ae2f7bca550 883 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 884 {
Azure.IoT Build 0:6ae2f7bca550 885 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 886 }
Azure.IoT Build 0:6ae2f7bca550 887 else
Azure.IoT Build 0:6ae2f7bca550 888 {
Azure.IoT Build 0:6ae2f7bca550 889 link->attach_properties = amqpvalue_clone(attach_properties);
Azure.IoT Build 0:6ae2f7bca550 890 if (link->attach_properties == NULL)
Azure.IoT Build 0:6ae2f7bca550 891 {
Azure.IoT Build 0:6ae2f7bca550 892 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 893 }
Azure.IoT Build 0:6ae2f7bca550 894 else
Azure.IoT Build 0:6ae2f7bca550 895 {
Azure.IoT Build 0:6ae2f7bca550 896 result = 0;
Azure.IoT Build 0:6ae2f7bca550 897 }
Azure.IoT Build 0:6ae2f7bca550 898 }
Azure.IoT Build 0:6ae2f7bca550 899
Azure.IoT Build 0:6ae2f7bca550 900 return result;
Azure.IoT Build 0:6ae2f7bca550 901 }
Azure.IoT Build 0:6ae2f7bca550 902
Azure.IoT Build 0:6ae2f7bca550 903 int link_attach(LINK_HANDLE link, ON_TRANSFER_RECEIVED on_transfer_received, ON_LINK_STATE_CHANGED on_link_state_changed, ON_LINK_FLOW_ON on_link_flow_on, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 904 {
Azure.IoT Build 0:6ae2f7bca550 905 int result;
Azure.IoT Build 0:6ae2f7bca550 906
AzureIoTClient 12:b30dacf113f2 907 if ((link == NULL) ||
AzureIoTClient 12:b30dacf113f2 908 (link->is_closed))
Azure.IoT Build 0:6ae2f7bca550 909 {
Azure.IoT Build 0:6ae2f7bca550 910 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 911 }
Azure.IoT Build 0:6ae2f7bca550 912 else
Azure.IoT Build 0:6ae2f7bca550 913 {
Azure.IoT Build 0:6ae2f7bca550 914 if (!link->is_underlying_session_begun)
Azure.IoT Build 0:6ae2f7bca550 915 {
Azure.IoT Build 0:6ae2f7bca550 916 link->on_link_state_changed = on_link_state_changed;
Azure.IoT Build 0:6ae2f7bca550 917 link->on_transfer_received = on_transfer_received;
Azure.IoT Build 0:6ae2f7bca550 918 link->on_link_flow_on = on_link_flow_on;
Azure.IoT Build 0:6ae2f7bca550 919 link->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 920
Azure.IoT Build 0:6ae2f7bca550 921 if (session_begin(link->session) != 0)
Azure.IoT Build 0:6ae2f7bca550 922 {
Azure.IoT Build 0:6ae2f7bca550 923 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 924 }
Azure.IoT Build 0:6ae2f7bca550 925 else
Azure.IoT Build 0:6ae2f7bca550 926 {
AzureIoTClient 12:b30dacf113f2 927 link->is_underlying_session_begun = true;
Azure.IoT Build 0:6ae2f7bca550 928
Azure.IoT Build 0:6ae2f7bca550 929 if (session_start_link_endpoint(link->link_endpoint, link_frame_received, on_session_state_changed, on_session_flow_on, link) != 0)
Azure.IoT Build 0:6ae2f7bca550 930 {
Azure.IoT Build 0:6ae2f7bca550 931 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 932 }
Azure.IoT Build 0:6ae2f7bca550 933 else
Azure.IoT Build 0:6ae2f7bca550 934 {
AzureIoTClient 12:b30dacf113f2 935 link->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 936
Azure.IoT Build 0:6ae2f7bca550 937 result = 0;
Azure.IoT Build 0:6ae2f7bca550 938 }
Azure.IoT Build 0:6ae2f7bca550 939 }
Azure.IoT Build 0:6ae2f7bca550 940 }
Azure.IoT Build 0:6ae2f7bca550 941 else
Azure.IoT Build 0:6ae2f7bca550 942 {
Azure.IoT Build 0:6ae2f7bca550 943 result = 0;
Azure.IoT Build 0:6ae2f7bca550 944 }
Azure.IoT Build 0:6ae2f7bca550 945 }
Azure.IoT Build 0:6ae2f7bca550 946
Azure.IoT Build 0:6ae2f7bca550 947 return result;
Azure.IoT Build 0:6ae2f7bca550 948 }
Azure.IoT Build 0:6ae2f7bca550 949
AzureIoTClient 12:b30dacf113f2 950 int link_detach(LINK_HANDLE link, bool close)
Azure.IoT Build 0:6ae2f7bca550 951 {
Azure.IoT Build 0:6ae2f7bca550 952 int result;
Azure.IoT Build 0:6ae2f7bca550 953
AzureIoTClient 12:b30dacf113f2 954 if ((link == NULL) ||
AzureIoTClient 12:b30dacf113f2 955 (link->is_closed))
AzureIoTClient 12:b30dacf113f2 956 {
Azure.IoT Build 0:6ae2f7bca550 957 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 958 }
Azure.IoT Build 0:6ae2f7bca550 959 else
Azure.IoT Build 0:6ae2f7bca550 960 {
AzureIoTClient 12:b30dacf113f2 961 switch (link->link_state)
AzureIoTClient 12:b30dacf113f2 962 {
AzureIoTClient 12:b30dacf113f2 963
AzureIoTClient 12:b30dacf113f2 964 case LINK_STATE_HALF_ATTACHED:
AzureIoTClient 12:b30dacf113f2 965 /* Sending detach when remote is not yet attached */
AzureIoTClient 12:b30dacf113f2 966 if (send_detach(link, close, NULL) != 0)
AzureIoTClient 12:b30dacf113f2 967 {
AzureIoTClient 12:b30dacf113f2 968 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 969 }
AzureIoTClient 12:b30dacf113f2 970 else
AzureIoTClient 12:b30dacf113f2 971 {
AzureIoTClient 12:b30dacf113f2 972 set_link_state(link, LINK_STATE_DETACHED);
AzureIoTClient 12:b30dacf113f2 973 result = 0;
AzureIoTClient 12:b30dacf113f2 974 }
AzureIoTClient 12:b30dacf113f2 975 break;
AzureIoTClient 12:b30dacf113f2 976
AzureIoTClient 12:b30dacf113f2 977 case LINK_STATE_ATTACHED:
AzureIoTClient 12:b30dacf113f2 978 /* Send detach and wait for remote to respond */
AzureIoTClient 12:b30dacf113f2 979 if (send_detach(link, close, NULL) != 0)
AzureIoTClient 12:b30dacf113f2 980 {
AzureIoTClient 12:b30dacf113f2 981 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 982 }
AzureIoTClient 12:b30dacf113f2 983 else
AzureIoTClient 12:b30dacf113f2 984 {
AzureIoTClient 12:b30dacf113f2 985 set_link_state(link, LINK_STATE_HALF_ATTACHED);
AzureIoTClient 12:b30dacf113f2 986 result = 0;
AzureIoTClient 12:b30dacf113f2 987 }
AzureIoTClient 12:b30dacf113f2 988 break;
AzureIoTClient 12:b30dacf113f2 989
AzureIoTClient 12:b30dacf113f2 990 case LINK_STATE_DETACHED:
AzureIoTClient 12:b30dacf113f2 991 /* Already detached */
AzureIoTClient 12:b30dacf113f2 992 result = 0;
AzureIoTClient 12:b30dacf113f2 993 break;
AzureIoTClient 12:b30dacf113f2 994
AzureIoTClient 12:b30dacf113f2 995 default:
AzureIoTClient 12:b30dacf113f2 996 case LINK_STATE_ERROR:
AzureIoTClient 12:b30dacf113f2 997 /* Already detached and in error state */
AzureIoTClient 12:b30dacf113f2 998 result = __LINE__;
AzureIoTClient 12:b30dacf113f2 999 break;
AzureIoTClient 12:b30dacf113f2 1000 }
Azure.IoT Build 0:6ae2f7bca550 1001 }
Azure.IoT Build 0:6ae2f7bca550 1002
Azure.IoT Build 0:6ae2f7bca550 1003 return result;
Azure.IoT Build 0:6ae2f7bca550 1004 }
Azure.IoT Build 0:6ae2f7bca550 1005
Azure.IoT Build 0:6ae2f7bca550 1006 LINK_TRANSFER_RESULT link_transfer(LINK_HANDLE link, message_format message_format, PAYLOAD* payloads, size_t payload_count, ON_DELIVERY_SETTLED on_delivery_settled, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 1007 {
Azure.IoT Build 0:6ae2f7bca550 1008 LINK_TRANSFER_RESULT result;
Azure.IoT Build 0:6ae2f7bca550 1009
Azure.IoT Build 0:6ae2f7bca550 1010 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 1011 {
Azure.IoT Build 0:6ae2f7bca550 1012 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1013 }
Azure.IoT Build 0:6ae2f7bca550 1014 else
Azure.IoT Build 0:6ae2f7bca550 1015 {
AzureIoTClient 2:64b4feb67cd3 1016 if ((link->role != role_sender) ||
AzureIoTClient 7:9e9ab3b0efef 1017 (link->link_state != LINK_STATE_ATTACHED))
Azure.IoT Build 0:6ae2f7bca550 1018 {
Azure.IoT Build 0:6ae2f7bca550 1019 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1020 }
Azure.IoT Build 0:6ae2f7bca550 1021 else if (link->link_credit == 0)
Azure.IoT Build 0:6ae2f7bca550 1022 {
Azure.IoT Build 0:6ae2f7bca550 1023 result = LINK_TRANSFER_BUSY;
Azure.IoT Build 0:6ae2f7bca550 1024 }
Azure.IoT Build 0:6ae2f7bca550 1025 else
Azure.IoT Build 0:6ae2f7bca550 1026 {
Azure.IoT Build 0:6ae2f7bca550 1027 TRANSFER_HANDLE transfer = transfer_create(0);
Azure.IoT Build 0:6ae2f7bca550 1028 if (transfer == NULL)
Azure.IoT Build 0:6ae2f7bca550 1029 {
Azure.IoT Build 0:6ae2f7bca550 1030 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1031 }
Azure.IoT Build 0:6ae2f7bca550 1032 else
Azure.IoT Build 0:6ae2f7bca550 1033 {
AzureIoTClient 7:9e9ab3b0efef 1034 sequence_no delivery_count = link->delivery_count + 1;
AzureIoTClient 7:9e9ab3b0efef 1035 unsigned char delivery_tag_bytes[sizeof(delivery_count)];
Azure.IoT Build 0:6ae2f7bca550 1036 delivery_tag delivery_tag;
Azure.IoT Build 0:6ae2f7bca550 1037 bool settled;
Azure.IoT Build 0:6ae2f7bca550 1038
AzureIoTClient 7:9e9ab3b0efef 1039 (void)memcpy(delivery_tag_bytes, &delivery_count, sizeof(delivery_count));
Azure.IoT Build 0:6ae2f7bca550 1040
Azure.IoT Build 0:6ae2f7bca550 1041 delivery_tag.bytes = &delivery_tag_bytes;
Azure.IoT Build 0:6ae2f7bca550 1042 delivery_tag.length = sizeof(delivery_tag_bytes);
Azure.IoT Build 0:6ae2f7bca550 1043
Azure.IoT Build 0:6ae2f7bca550 1044 if (link->snd_settle_mode == sender_settle_mode_unsettled)
Azure.IoT Build 0:6ae2f7bca550 1045 {
Azure.IoT Build 0:6ae2f7bca550 1046 settled = false;
Azure.IoT Build 0:6ae2f7bca550 1047 }
Azure.IoT Build 0:6ae2f7bca550 1048 else
Azure.IoT Build 0:6ae2f7bca550 1049 {
Azure.IoT Build 0:6ae2f7bca550 1050 settled = true;
Azure.IoT Build 0:6ae2f7bca550 1051 }
Azure.IoT Build 0:6ae2f7bca550 1052
Azure.IoT Build 0:6ae2f7bca550 1053 if ((transfer_set_delivery_tag(transfer, delivery_tag) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 1054 (transfer_set_message_format(transfer, message_format) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 1055 (transfer_set_settled(transfer, settled) != 0))
Azure.IoT Build 0:6ae2f7bca550 1056 {
Azure.IoT Build 0:6ae2f7bca550 1057 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1058 }
Azure.IoT Build 0:6ae2f7bca550 1059 else
Azure.IoT Build 0:6ae2f7bca550 1060 {
Azure.IoT Build 0:6ae2f7bca550 1061 AMQP_VALUE transfer_value = amqpvalue_create_transfer(transfer);
Azure.IoT Build 0:6ae2f7bca550 1062
Azure.IoT Build 0:6ae2f7bca550 1063 if (transfer_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 1064 {
Azure.IoT Build 0:6ae2f7bca550 1065 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1066 }
Azure.IoT Build 0:6ae2f7bca550 1067 else
Azure.IoT Build 0:6ae2f7bca550 1068 {
Azure.IoT Build 0:6ae2f7bca550 1069 DELIVERY_INSTANCE* pending_delivery = amqpalloc_malloc(sizeof(DELIVERY_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 1070 if (pending_delivery == NULL)
Azure.IoT Build 0:6ae2f7bca550 1071 {
Azure.IoT Build 0:6ae2f7bca550 1072 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1073 }
Azure.IoT Build 0:6ae2f7bca550 1074 else
Azure.IoT Build 0:6ae2f7bca550 1075 {
Azure.IoT Build 0:6ae2f7bca550 1076 LIST_ITEM_HANDLE delivery_instance_list_item;
Azure.IoT Build 0:6ae2f7bca550 1077 pending_delivery->on_delivery_settled = on_delivery_settled;
Azure.IoT Build 0:6ae2f7bca550 1078 pending_delivery->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 1079 pending_delivery->link = link;
AzureIoTClient 12:b30dacf113f2 1080 delivery_instance_list_item = singlylinkedlist_add(link->pending_deliveries, pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1081
Azure.IoT Build 0:6ae2f7bca550 1082 if (delivery_instance_list_item == NULL)
Azure.IoT Build 0:6ae2f7bca550 1083 {
Azure.IoT Build 0:6ae2f7bca550 1084 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1085 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1086 }
Azure.IoT Build 0:6ae2f7bca550 1087 else
Azure.IoT Build 0:6ae2f7bca550 1088 {
Azure.IoT Build 0:6ae2f7bca550 1089 /* here we should feed data to the transfer frame */
Azure.IoT Build 0:6ae2f7bca550 1090 switch (session_send_transfer(link->link_endpoint, transfer, payloads, payload_count, &pending_delivery->delivery_id, (settled) ? on_send_complete : NULL, delivery_instance_list_item))
Azure.IoT Build 0:6ae2f7bca550 1091 {
Azure.IoT Build 0:6ae2f7bca550 1092 default:
Azure.IoT Build 0:6ae2f7bca550 1093 case SESSION_SEND_TRANSFER_ERROR:
AzureIoTClient 12:b30dacf113f2 1094 singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 3:96522ba2ddf8 1095 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1096 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1097 break;
Azure.IoT Build 0:6ae2f7bca550 1098
Azure.IoT Build 0:6ae2f7bca550 1099 case SESSION_SEND_TRANSFER_BUSY:
AzureIoTClient 3:96522ba2ddf8 1100 /* Ensure we remove from list again since sender will attempt to transfer again on flow on */
AzureIoTClient 12:b30dacf113f2 1101 singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 3:96522ba2ddf8 1102 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1103 result = LINK_TRANSFER_BUSY;
Azure.IoT Build 0:6ae2f7bca550 1104 break;
Azure.IoT Build 0:6ae2f7bca550 1105
Azure.IoT Build 0:6ae2f7bca550 1106 case SESSION_SEND_TRANSFER_OK:
AzureIoTClient 7:9e9ab3b0efef 1107 link->delivery_count = delivery_count;
Azure.IoT Build 0:6ae2f7bca550 1108 link->link_credit--;
Azure.IoT Build 0:6ae2f7bca550 1109 result = LINK_TRANSFER_OK;
Azure.IoT Build 0:6ae2f7bca550 1110 break;
Azure.IoT Build 0:6ae2f7bca550 1111 }
Azure.IoT Build 0:6ae2f7bca550 1112 }
Azure.IoT Build 0:6ae2f7bca550 1113 }
Azure.IoT Build 0:6ae2f7bca550 1114
Azure.IoT Build 0:6ae2f7bca550 1115 amqpvalue_destroy(transfer_value);
Azure.IoT Build 0:6ae2f7bca550 1116 }
Azure.IoT Build 0:6ae2f7bca550 1117 }
Azure.IoT Build 0:6ae2f7bca550 1118
Azure.IoT Build 0:6ae2f7bca550 1119 transfer_destroy(transfer);
Azure.IoT Build 0:6ae2f7bca550 1120 }
Azure.IoT Build 0:6ae2f7bca550 1121 }
Azure.IoT Build 0:6ae2f7bca550 1122 }
Azure.IoT Build 0:6ae2f7bca550 1123
Azure.IoT Build 0:6ae2f7bca550 1124 return result;
Azure.IoT Build 0:6ae2f7bca550 1125 }