A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Aug 12 13:49:27 2016 -0700
Revision:
8:20dc883fb313
Parent:
7:9e9ab3b0efef
Child:
12:b30dacf113f2
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"
Azure.IoT Build 0:6ae2f7bca550 18 #include "azure_c_shared_utility/list.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;
Azure.IoT Build 0:6ae2f7bca550 40 LIST_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 6:641a9672db08 54 int is_underlying_session_begun : 1;
Azure.IoT Build 0:6ae2f7bca550 55 } LINK_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 56
Azure.IoT Build 0:6ae2f7bca550 57 static void set_link_state(LINK_INSTANCE* link_instance, LINK_STATE link_state)
Azure.IoT Build 0:6ae2f7bca550 58 {
Azure.IoT Build 0:6ae2f7bca550 59 link_instance->previous_link_state = link_instance->link_state;
Azure.IoT Build 0:6ae2f7bca550 60 link_instance->link_state = link_state;
Azure.IoT Build 0:6ae2f7bca550 61
Azure.IoT Build 0:6ae2f7bca550 62 if (link_instance->on_link_state_changed != NULL)
Azure.IoT Build 0:6ae2f7bca550 63 {
Azure.IoT Build 0:6ae2f7bca550 64 link_instance->on_link_state_changed(link_instance->callback_context, link_state, link_instance->previous_link_state);
Azure.IoT Build 0:6ae2f7bca550 65 }
Azure.IoT Build 0:6ae2f7bca550 66 }
Azure.IoT Build 0:6ae2f7bca550 67
Azure.IoT Build 0:6ae2f7bca550 68 static int send_flow(LINK_INSTANCE* link)
Azure.IoT Build 0:6ae2f7bca550 69 {
Azure.IoT Build 0:6ae2f7bca550 70 int result;
Azure.IoT Build 0:6ae2f7bca550 71 FLOW_HANDLE flow = flow_create(0, 0, 0);
Azure.IoT Build 0:6ae2f7bca550 72
Azure.IoT Build 0:6ae2f7bca550 73 if (flow == NULL)
Azure.IoT Build 0:6ae2f7bca550 74 {
Azure.IoT Build 0:6ae2f7bca550 75 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 76 }
Azure.IoT Build 0:6ae2f7bca550 77 else
Azure.IoT Build 0:6ae2f7bca550 78 {
Azure.IoT Build 0:6ae2f7bca550 79 if ((flow_set_link_credit(flow, link->link_credit) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 80 (flow_set_handle(flow, link->handle) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 81 (flow_set_delivery_count(flow, link->delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 82 {
Azure.IoT Build 0:6ae2f7bca550 83 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 84 }
Azure.IoT Build 0:6ae2f7bca550 85 else
Azure.IoT Build 0:6ae2f7bca550 86 {
Azure.IoT Build 0:6ae2f7bca550 87 if (session_send_flow(link->link_endpoint, flow) != 0)
Azure.IoT Build 0:6ae2f7bca550 88 {
Azure.IoT Build 0:6ae2f7bca550 89 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 90 }
Azure.IoT Build 0:6ae2f7bca550 91 else
Azure.IoT Build 0:6ae2f7bca550 92 {
Azure.IoT Build 0:6ae2f7bca550 93 result = 0;
Azure.IoT Build 0:6ae2f7bca550 94 }
Azure.IoT Build 0:6ae2f7bca550 95 }
Azure.IoT Build 0:6ae2f7bca550 96
Azure.IoT Build 0:6ae2f7bca550 97 flow_destroy(flow);
Azure.IoT Build 0:6ae2f7bca550 98 }
Azure.IoT Build 0:6ae2f7bca550 99
Azure.IoT Build 0:6ae2f7bca550 100 return result;
Azure.IoT Build 0:6ae2f7bca550 101 }
Azure.IoT Build 0:6ae2f7bca550 102
Azure.IoT Build 0:6ae2f7bca550 103 static int send_disposition(LINK_INSTANCE* link_instance, delivery_number delivery_number, AMQP_VALUE delivery_state)
Azure.IoT Build 0:6ae2f7bca550 104 {
Azure.IoT Build 0:6ae2f7bca550 105 int result;
Azure.IoT Build 0:6ae2f7bca550 106
Azure.IoT Build 0:6ae2f7bca550 107 DISPOSITION_HANDLE disposition = disposition_create(link_instance->role, delivery_number);
Azure.IoT Build 0:6ae2f7bca550 108 if (disposition == NULL)
Azure.IoT Build 0:6ae2f7bca550 109 {
Azure.IoT Build 0:6ae2f7bca550 110 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 111 }
Azure.IoT Build 0:6ae2f7bca550 112 else
Azure.IoT Build 0:6ae2f7bca550 113 {
Azure.IoT Build 0:6ae2f7bca550 114 if ((disposition_set_last(disposition, delivery_number) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 115 (disposition_set_settled(disposition, true) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 116 ((delivery_state != NULL) && (disposition_set_state(disposition, delivery_state) != 0)))
Azure.IoT Build 0:6ae2f7bca550 117 {
Azure.IoT Build 0:6ae2f7bca550 118 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 119 }
Azure.IoT Build 0:6ae2f7bca550 120 else
Azure.IoT Build 0:6ae2f7bca550 121 {
Azure.IoT Build 0:6ae2f7bca550 122 if (session_send_disposition(link_instance->link_endpoint, disposition) != 0)
Azure.IoT Build 0:6ae2f7bca550 123 {
Azure.IoT Build 0:6ae2f7bca550 124 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 125 }
Azure.IoT Build 0:6ae2f7bca550 126 else
Azure.IoT Build 0:6ae2f7bca550 127 {
Azure.IoT Build 0:6ae2f7bca550 128 result = 0;
Azure.IoT Build 0:6ae2f7bca550 129 }
Azure.IoT Build 0:6ae2f7bca550 130 }
Azure.IoT Build 0:6ae2f7bca550 131
Azure.IoT Build 0:6ae2f7bca550 132 disposition_destroy(disposition);
Azure.IoT Build 0:6ae2f7bca550 133 }
Azure.IoT Build 0:6ae2f7bca550 134
Azure.IoT Build 0:6ae2f7bca550 135 return result;
Azure.IoT Build 0:6ae2f7bca550 136 }
Azure.IoT Build 0:6ae2f7bca550 137
Azure.IoT Build 0:6ae2f7bca550 138 static int send_detach_frame(LINK_INSTANCE* link_instance, ERROR_HANDLE error_handle)
Azure.IoT Build 0:6ae2f7bca550 139 {
Azure.IoT Build 0:6ae2f7bca550 140 int result;
Azure.IoT Build 0:6ae2f7bca550 141 DETACH_HANDLE detach_performative;
Azure.IoT Build 0:6ae2f7bca550 142
Azure.IoT Build 0:6ae2f7bca550 143 detach_performative = detach_create(0);
Azure.IoT Build 0:6ae2f7bca550 144 if (detach_performative == NULL)
Azure.IoT Build 0:6ae2f7bca550 145 {
Azure.IoT Build 0:6ae2f7bca550 146 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 147 }
Azure.IoT Build 0:6ae2f7bca550 148 else
Azure.IoT Build 0:6ae2f7bca550 149 {
Azure.IoT Build 0:6ae2f7bca550 150 if ((error_handle != NULL) &&
Azure.IoT Build 0:6ae2f7bca550 151 (detach_set_error(detach_performative, error_handle) != 0))
Azure.IoT Build 0:6ae2f7bca550 152 {
Azure.IoT Build 0:6ae2f7bca550 153 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 154 }
Azure.IoT Build 0:6ae2f7bca550 155 else
Azure.IoT Build 0:6ae2f7bca550 156 {
Azure.IoT Build 0:6ae2f7bca550 157 if (session_send_detach(link_instance->link_endpoint, detach_performative) != 0)
Azure.IoT Build 0:6ae2f7bca550 158 {
Azure.IoT Build 0:6ae2f7bca550 159 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 160 }
Azure.IoT Build 0:6ae2f7bca550 161 else
Azure.IoT Build 0:6ae2f7bca550 162 {
Azure.IoT Build 0:6ae2f7bca550 163 result = 0;
Azure.IoT Build 0:6ae2f7bca550 164 }
Azure.IoT Build 0:6ae2f7bca550 165 }
Azure.IoT Build 0:6ae2f7bca550 166
Azure.IoT Build 0:6ae2f7bca550 167 detach_destroy(detach_performative);
Azure.IoT Build 0:6ae2f7bca550 168 }
Azure.IoT Build 0:6ae2f7bca550 169
Azure.IoT Build 0:6ae2f7bca550 170 return result;
Azure.IoT Build 0:6ae2f7bca550 171 }
Azure.IoT Build 0:6ae2f7bca550 172
Azure.IoT Build 0:6ae2f7bca550 173 static void link_frame_received(void* context, AMQP_VALUE performative, uint32_t payload_size, const unsigned char* payload_bytes)
Azure.IoT Build 0:6ae2f7bca550 174 {
Azure.IoT Build 0:6ae2f7bca550 175 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 176 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(performative);
Azure.IoT Build 0:6ae2f7bca550 177
Azure.IoT Build 0:6ae2f7bca550 178 if (is_attach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 179 {
Azure.IoT Build 0:6ae2f7bca550 180 ATTACH_HANDLE attach_handle;
Azure.IoT Build 0:6ae2f7bca550 181 if (amqpvalue_get_attach(performative, &attach_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 182 {
Azure.IoT Build 0:6ae2f7bca550 183 if ((link_instance->role == role_receiver) &&
Azure.IoT Build 0:6ae2f7bca550 184 (attach_get_initial_delivery_count(attach_handle, &link_instance->delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 185 {
Azure.IoT Build 0:6ae2f7bca550 186 /* error */
Azure.IoT Build 0:6ae2f7bca550 187 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 188 }
Azure.IoT Build 0:6ae2f7bca550 189 else
Azure.IoT Build 0:6ae2f7bca550 190 {
Azure.IoT Build 0:6ae2f7bca550 191 if (link_instance->link_state == LINK_STATE_HALF_ATTACHED)
Azure.IoT Build 0:6ae2f7bca550 192 {
Azure.IoT Build 0:6ae2f7bca550 193 if (link_instance->role == role_receiver)
Azure.IoT Build 0:6ae2f7bca550 194 {
Azure.IoT Build 0:6ae2f7bca550 195 link_instance->link_credit = DEFAULT_LINK_CREDIT;
Azure.IoT Build 0:6ae2f7bca550 196 send_flow(link_instance);
Azure.IoT Build 0:6ae2f7bca550 197 }
Azure.IoT Build 0:6ae2f7bca550 198 else
Azure.IoT Build 0:6ae2f7bca550 199 {
Azure.IoT Build 0:6ae2f7bca550 200 link_instance->link_credit = 0;
Azure.IoT Build 0:6ae2f7bca550 201 }
Azure.IoT Build 0:6ae2f7bca550 202
Azure.IoT Build 0:6ae2f7bca550 203 set_link_state(link_instance, LINK_STATE_ATTACHED);
Azure.IoT Build 0:6ae2f7bca550 204 }
Azure.IoT Build 0:6ae2f7bca550 205 }
Azure.IoT Build 0:6ae2f7bca550 206
Azure.IoT Build 0:6ae2f7bca550 207 attach_destroy(attach_handle);
Azure.IoT Build 0:6ae2f7bca550 208 }
Azure.IoT Build 0:6ae2f7bca550 209 }
Azure.IoT Build 0:6ae2f7bca550 210 else if (is_flow_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 211 {
Azure.IoT Build 0:6ae2f7bca550 212 FLOW_HANDLE flow_handle;
Azure.IoT Build 0:6ae2f7bca550 213 if (amqpvalue_get_flow(performative, &flow_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 214 {
Azure.IoT Build 0:6ae2f7bca550 215 if (link_instance->role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 216 {
Azure.IoT Build 0:6ae2f7bca550 217 delivery_number rcv_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 218 uint32_t rcv_link_credit;
Azure.IoT Build 0:6ae2f7bca550 219
Azure.IoT Build 0:6ae2f7bca550 220 if ((flow_get_link_credit(flow_handle, &rcv_link_credit) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 221 (flow_get_delivery_count(flow_handle, &rcv_delivery_count) != 0))
Azure.IoT Build 0:6ae2f7bca550 222 {
Azure.IoT Build 0:6ae2f7bca550 223 /* error */
Azure.IoT Build 0:6ae2f7bca550 224 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 225 }
Azure.IoT Build 0:6ae2f7bca550 226 else
Azure.IoT Build 0:6ae2f7bca550 227 {
Azure.IoT Build 0:6ae2f7bca550 228 link_instance->link_credit = rcv_delivery_count + rcv_link_credit - link_instance->delivery_count;
Azure.IoT Build 0:6ae2f7bca550 229 if (link_instance->link_credit > 0)
Azure.IoT Build 0:6ae2f7bca550 230 {
Azure.IoT Build 0:6ae2f7bca550 231 link_instance->on_link_flow_on(link_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 232 }
Azure.IoT Build 0:6ae2f7bca550 233 }
Azure.IoT Build 0:6ae2f7bca550 234 }
Azure.IoT Build 0:6ae2f7bca550 235 }
Azure.IoT Build 0:6ae2f7bca550 236
Azure.IoT Build 0:6ae2f7bca550 237 flow_destroy(flow_handle);
Azure.IoT Build 0:6ae2f7bca550 238 }
Azure.IoT Build 0:6ae2f7bca550 239 else if (is_transfer_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 240 {
Azure.IoT Build 0:6ae2f7bca550 241 if (link_instance->on_transfer_received != NULL)
Azure.IoT Build 0:6ae2f7bca550 242 {
Azure.IoT Build 0:6ae2f7bca550 243 TRANSFER_HANDLE transfer_handle;
Azure.IoT Build 0:6ae2f7bca550 244 if (amqpvalue_get_transfer(performative, &transfer_handle) == 0)
Azure.IoT Build 0:6ae2f7bca550 245 {
Azure.IoT Build 0:6ae2f7bca550 246 AMQP_VALUE delivery_state;
Azure.IoT Build 0:6ae2f7bca550 247 delivery_number received_delivery_id;
Azure.IoT Build 0:6ae2f7bca550 248
Azure.IoT Build 0:6ae2f7bca550 249 link_instance->link_credit--;
Azure.IoT Build 0:6ae2f7bca550 250 link_instance->delivery_count++;
Azure.IoT Build 0:6ae2f7bca550 251 if (link_instance->link_credit == 0)
Azure.IoT Build 0:6ae2f7bca550 252 {
Azure.IoT Build 0:6ae2f7bca550 253 link_instance->link_credit = DEFAULT_LINK_CREDIT;
Azure.IoT Build 0:6ae2f7bca550 254 send_flow(link_instance);
Azure.IoT Build 0:6ae2f7bca550 255 }
Azure.IoT Build 0:6ae2f7bca550 256
Azure.IoT Build 0:6ae2f7bca550 257 if (transfer_get_delivery_id(transfer_handle, &received_delivery_id) != 0)
Azure.IoT Build 0:6ae2f7bca550 258 {
Azure.IoT Build 0:6ae2f7bca550 259 /* error */
Azure.IoT Build 0:6ae2f7bca550 260 }
Azure.IoT Build 0:6ae2f7bca550 261 else
Azure.IoT Build 0:6ae2f7bca550 262 {
Azure.IoT Build 0:6ae2f7bca550 263 delivery_state = link_instance->on_transfer_received(link_instance->callback_context, transfer_handle, payload_size, payload_bytes);
Azure.IoT Build 0:6ae2f7bca550 264
Azure.IoT Build 0:6ae2f7bca550 265 if (send_disposition(link_instance, received_delivery_id, delivery_state) != 0)
Azure.IoT Build 0:6ae2f7bca550 266 {
Azure.IoT Build 0:6ae2f7bca550 267 /* error */
Azure.IoT Build 0:6ae2f7bca550 268 }
Azure.IoT Build 0:6ae2f7bca550 269
Azure.IoT Build 0:6ae2f7bca550 270 if (delivery_state != NULL)
Azure.IoT Build 0:6ae2f7bca550 271 {
Azure.IoT Build 0:6ae2f7bca550 272 amqpvalue_destroy(delivery_state);
Azure.IoT Build 0:6ae2f7bca550 273 }
Azure.IoT Build 0:6ae2f7bca550 274 }
Azure.IoT Build 0:6ae2f7bca550 275
Azure.IoT Build 0:6ae2f7bca550 276 transfer_destroy(transfer_handle);
Azure.IoT Build 0:6ae2f7bca550 277 }
Azure.IoT Build 0:6ae2f7bca550 278 }
Azure.IoT Build 0:6ae2f7bca550 279 }
Azure.IoT Build 0:6ae2f7bca550 280 else if (is_disposition_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 281 {
Azure.IoT Build 0:6ae2f7bca550 282 DISPOSITION_HANDLE disposition;
Azure.IoT Build 0:6ae2f7bca550 283 if (amqpvalue_get_disposition(performative, &disposition) != 0)
Azure.IoT Build 0:6ae2f7bca550 284 {
Azure.IoT Build 0:6ae2f7bca550 285 /* error */
Azure.IoT Build 0:6ae2f7bca550 286 }
Azure.IoT Build 0:6ae2f7bca550 287 else
Azure.IoT Build 0:6ae2f7bca550 288 {
Azure.IoT Build 0:6ae2f7bca550 289 delivery_number first;
Azure.IoT Build 0:6ae2f7bca550 290 delivery_number last;
Azure.IoT Build 0:6ae2f7bca550 291
Azure.IoT Build 0:6ae2f7bca550 292 if (disposition_get_first(disposition, &first) != 0)
Azure.IoT Build 0:6ae2f7bca550 293 {
Azure.IoT Build 0:6ae2f7bca550 294 /* error */
Azure.IoT Build 0:6ae2f7bca550 295 }
Azure.IoT Build 0:6ae2f7bca550 296 else
Azure.IoT Build 0:6ae2f7bca550 297 {
Azure.IoT Build 0:6ae2f7bca550 298 bool settled;
Azure.IoT Build 0:6ae2f7bca550 299
Azure.IoT Build 0:6ae2f7bca550 300 if (disposition_get_last(disposition, &last) != 0)
Azure.IoT Build 0:6ae2f7bca550 301 {
Azure.IoT Build 0:6ae2f7bca550 302 last = first;
Azure.IoT Build 0:6ae2f7bca550 303 }
Azure.IoT Build 0:6ae2f7bca550 304
Azure.IoT Build 0:6ae2f7bca550 305 if (disposition_get_settled(disposition, &settled) != 0)
Azure.IoT Build 0:6ae2f7bca550 306 {
Azure.IoT Build 0:6ae2f7bca550 307 /* Error */
Azure.IoT Build 0:6ae2f7bca550 308 settled = false;
Azure.IoT Build 0:6ae2f7bca550 309 }
Azure.IoT Build 0:6ae2f7bca550 310
Azure.IoT Build 0:6ae2f7bca550 311 if (settled)
Azure.IoT Build 0:6ae2f7bca550 312 {
Azure.IoT Build 0:6ae2f7bca550 313 LIST_ITEM_HANDLE pending_delivery = list_get_head_item(link_instance->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 314 while (pending_delivery != NULL)
Azure.IoT Build 0:6ae2f7bca550 315 {
Azure.IoT Build 0:6ae2f7bca550 316 LIST_ITEM_HANDLE next_pending_delivery = list_get_next_item(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 317 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)list_item_get_value(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 318 if (delivery_instance == NULL)
Azure.IoT Build 0:6ae2f7bca550 319 {
Azure.IoT Build 0:6ae2f7bca550 320 /* error */
Azure.IoT Build 0:6ae2f7bca550 321 break;
Azure.IoT Build 0:6ae2f7bca550 322 }
Azure.IoT Build 0:6ae2f7bca550 323 else
Azure.IoT Build 0:6ae2f7bca550 324 {
Azure.IoT Build 0:6ae2f7bca550 325 if ((delivery_instance->delivery_id >= first) && (delivery_instance->delivery_id <= last))
Azure.IoT Build 0:6ae2f7bca550 326 {
AzureIoTClient 7:9e9ab3b0efef 327 AMQP_VALUE delivery_state;
AzureIoTClient 7:9e9ab3b0efef 328 if (disposition_get_state(disposition, &delivery_state) != 0)
Azure.IoT Build 0:6ae2f7bca550 329 {
Azure.IoT Build 0:6ae2f7bca550 330 /* error */
Azure.IoT Build 0:6ae2f7bca550 331 }
Azure.IoT Build 0:6ae2f7bca550 332 else
Azure.IoT Build 0:6ae2f7bca550 333 {
AzureIoTClient 7:9e9ab3b0efef 334 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, delivery_state);
AzureIoTClient 7:9e9ab3b0efef 335 amqpalloc_free(delivery_instance);
AzureIoTClient 7:9e9ab3b0efef 336 if (list_remove(link_instance->pending_deliveries, pending_delivery) != 0)
AzureIoTClient 7:9e9ab3b0efef 337 {
AzureIoTClient 7:9e9ab3b0efef 338 /* error */
AzureIoTClient 7:9e9ab3b0efef 339 break;
AzureIoTClient 7:9e9ab3b0efef 340 }
AzureIoTClient 7:9e9ab3b0efef 341 else
AzureIoTClient 7:9e9ab3b0efef 342 {
AzureIoTClient 7:9e9ab3b0efef 343 pending_delivery = next_pending_delivery;
AzureIoTClient 7:9e9ab3b0efef 344 }
Azure.IoT Build 0:6ae2f7bca550 345 }
Azure.IoT Build 0:6ae2f7bca550 346 }
Azure.IoT Build 0:6ae2f7bca550 347 else
Azure.IoT Build 0:6ae2f7bca550 348 {
Azure.IoT Build 0:6ae2f7bca550 349 pending_delivery = next_pending_delivery;
Azure.IoT Build 0:6ae2f7bca550 350 }
Azure.IoT Build 0:6ae2f7bca550 351 }
Azure.IoT Build 0:6ae2f7bca550 352 }
Azure.IoT Build 0:6ae2f7bca550 353 }
Azure.IoT Build 0:6ae2f7bca550 354 }
Azure.IoT Build 0:6ae2f7bca550 355
Azure.IoT Build 0:6ae2f7bca550 356 disposition_destroy(disposition);
Azure.IoT Build 0:6ae2f7bca550 357 }
Azure.IoT Build 0:6ae2f7bca550 358 }
Azure.IoT Build 0:6ae2f7bca550 359 else if (is_detach_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 360 {
AzureIoTClient 1:eab586236bfe 361 DETACH_HANDLE detach;
AzureIoTClient 1:eab586236bfe 362
AzureIoTClient 1:eab586236bfe 363 /* Respond with ack */
AzureIoTClient 1:eab586236bfe 364 (void)send_detach_frame(link_instance, NULL);
AzureIoTClient 1:eab586236bfe 365
AzureIoTClient 1:eab586236bfe 366 /* Set link state appropriately based on whether we received detach condition */
AzureIoTClient 1:eab586236bfe 367 if (amqpvalue_get_detach(performative, &detach) == 0)
AzureIoTClient 1:eab586236bfe 368 {
AzureIoTClient 1:eab586236bfe 369 ERROR_HANDLE error;
AzureIoTClient 1:eab586236bfe 370 if (detach_get_error(detach, &error) == 0)
AzureIoTClient 1:eab586236bfe 371 {
AzureIoTClient 1:eab586236bfe 372 error_destroy(error);
AzureIoTClient 1:eab586236bfe 373
AzureIoTClient 1:eab586236bfe 374 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 375 }
AzureIoTClient 1:eab586236bfe 376 else
AzureIoTClient 1:eab586236bfe 377 {
AzureIoTClient 1:eab586236bfe 378 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 1:eab586236bfe 379 }
AzureIoTClient 1:eab586236bfe 380 }
AzureIoTClient 1:eab586236bfe 381 }
Azure.IoT Build 0:6ae2f7bca550 382 }
Azure.IoT Build 0:6ae2f7bca550 383
Azure.IoT Build 0:6ae2f7bca550 384 static int send_attach(LINK_INSTANCE* link, const char* name, handle handle, role role)
Azure.IoT Build 0:6ae2f7bca550 385 {
Azure.IoT Build 0:6ae2f7bca550 386 int result;
Azure.IoT Build 0:6ae2f7bca550 387 ATTACH_HANDLE attach = attach_create(name, handle, role);
Azure.IoT Build 0:6ae2f7bca550 388
Azure.IoT Build 0:6ae2f7bca550 389 if (attach == NULL)
Azure.IoT Build 0:6ae2f7bca550 390 {
Azure.IoT Build 0:6ae2f7bca550 391 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 392 }
Azure.IoT Build 0:6ae2f7bca550 393 else
Azure.IoT Build 0:6ae2f7bca550 394 {
Azure.IoT Build 0:6ae2f7bca550 395 result = 0;
Azure.IoT Build 0:6ae2f7bca550 396
Azure.IoT Build 0:6ae2f7bca550 397 link->delivery_count = link->initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 398
Azure.IoT Build 0:6ae2f7bca550 399 attach_set_snd_settle_mode(attach, link->snd_settle_mode);
Azure.IoT Build 0:6ae2f7bca550 400 attach_set_rcv_settle_mode(attach, link->rcv_settle_mode);
Azure.IoT Build 0:6ae2f7bca550 401 attach_set_role(attach, role);
Azure.IoT Build 0:6ae2f7bca550 402 attach_set_source(attach, link->source);
Azure.IoT Build 0:6ae2f7bca550 403 attach_set_target(attach, link->target);
Azure.IoT Build 0:6ae2f7bca550 404 attach_set_properties(attach, link->attach_properties);
Azure.IoT Build 0:6ae2f7bca550 405
Azure.IoT Build 0:6ae2f7bca550 406 if (role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 407 {
Azure.IoT Build 0:6ae2f7bca550 408 if (attach_set_initial_delivery_count(attach, link->delivery_count) != 0)
Azure.IoT Build 0:6ae2f7bca550 409 {
Azure.IoT Build 0:6ae2f7bca550 410 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 411 }
Azure.IoT Build 0:6ae2f7bca550 412 }
Azure.IoT Build 0:6ae2f7bca550 413
Azure.IoT Build 0:6ae2f7bca550 414 if (result == 0)
Azure.IoT Build 0:6ae2f7bca550 415 {
Azure.IoT Build 0:6ae2f7bca550 416 if ((attach_set_max_message_size(attach, link->max_message_size) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 417 (session_send_attach(link->link_endpoint, attach) != 0))
Azure.IoT Build 0:6ae2f7bca550 418 {
Azure.IoT Build 0:6ae2f7bca550 419 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 420 }
Azure.IoT Build 0:6ae2f7bca550 421 else
Azure.IoT Build 0:6ae2f7bca550 422 {
Azure.IoT Build 0:6ae2f7bca550 423 result = 0;
Azure.IoT Build 0:6ae2f7bca550 424 }
Azure.IoT Build 0:6ae2f7bca550 425 }
Azure.IoT Build 0:6ae2f7bca550 426
Azure.IoT Build 0:6ae2f7bca550 427 attach_destroy(attach);
Azure.IoT Build 0:6ae2f7bca550 428 }
Azure.IoT Build 0:6ae2f7bca550 429
Azure.IoT Build 0:6ae2f7bca550 430 return result;
Azure.IoT Build 0:6ae2f7bca550 431 }
Azure.IoT Build 0:6ae2f7bca550 432
Azure.IoT Build 0:6ae2f7bca550 433 static int send_detach(LINK_INSTANCE* link_instance, ERROR_HANDLE error)
Azure.IoT Build 0:6ae2f7bca550 434 {
Azure.IoT Build 0:6ae2f7bca550 435 int result;
Azure.IoT Build 0:6ae2f7bca550 436
Azure.IoT Build 0:6ae2f7bca550 437 DETACH_HANDLE detach = detach_create(0);
Azure.IoT Build 0:6ae2f7bca550 438 if (detach == NULL)
Azure.IoT Build 0:6ae2f7bca550 439 {
Azure.IoT Build 0:6ae2f7bca550 440 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 441 }
Azure.IoT Build 0:6ae2f7bca550 442 else
Azure.IoT Build 0:6ae2f7bca550 443 {
Azure.IoT Build 0:6ae2f7bca550 444 if (((error != NULL) && (detach_set_error(detach, error) != 0)) ||
Azure.IoT Build 0:6ae2f7bca550 445 (session_send_detach(link_instance->link_endpoint, detach) != 0))
Azure.IoT Build 0:6ae2f7bca550 446 {
Azure.IoT Build 0:6ae2f7bca550 447 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 448 }
Azure.IoT Build 0:6ae2f7bca550 449 else
Azure.IoT Build 0:6ae2f7bca550 450 {
Azure.IoT Build 0:6ae2f7bca550 451 result = 0;
Azure.IoT Build 0:6ae2f7bca550 452 }
Azure.IoT Build 0:6ae2f7bca550 453
Azure.IoT Build 0:6ae2f7bca550 454 detach_destroy(detach);
Azure.IoT Build 0:6ae2f7bca550 455 }
Azure.IoT Build 0:6ae2f7bca550 456
Azure.IoT Build 0:6ae2f7bca550 457 return result;
Azure.IoT Build 0:6ae2f7bca550 458 }
Azure.IoT Build 0:6ae2f7bca550 459
Azure.IoT Build 0:6ae2f7bca550 460 static void on_session_state_changed(void* context, SESSION_STATE new_session_state, SESSION_STATE previous_session_state)
Azure.IoT Build 0:6ae2f7bca550 461 {
Azure.IoT Build 0:6ae2f7bca550 462 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 463 (void)previous_session_state;
Azure.IoT Build 0:6ae2f7bca550 464
Azure.IoT Build 0:6ae2f7bca550 465 if (new_session_state == SESSION_STATE_MAPPED)
Azure.IoT Build 0:6ae2f7bca550 466 {
Azure.IoT Build 0:6ae2f7bca550 467 if (link_instance->link_state == LINK_STATE_DETACHED)
Azure.IoT Build 0:6ae2f7bca550 468 {
Azure.IoT Build 0:6ae2f7bca550 469 if (send_attach(link_instance, link_instance->name, 0, link_instance->role) == 0)
Azure.IoT Build 0:6ae2f7bca550 470 {
Azure.IoT Build 0:6ae2f7bca550 471 set_link_state(link_instance, LINK_STATE_HALF_ATTACHED);
Azure.IoT Build 0:6ae2f7bca550 472 }
Azure.IoT Build 0:6ae2f7bca550 473 }
Azure.IoT Build 0:6ae2f7bca550 474 }
Azure.IoT Build 0:6ae2f7bca550 475 else if (new_session_state == SESSION_STATE_DISCARDING)
Azure.IoT Build 0:6ae2f7bca550 476 {
Azure.IoT Build 0:6ae2f7bca550 477 set_link_state(link_instance, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 478 }
AzureIoTClient 1:eab586236bfe 479 else if (new_session_state == SESSION_STATE_ERROR)
AzureIoTClient 1:eab586236bfe 480 {
AzureIoTClient 1:eab586236bfe 481 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 482 }
Azure.IoT Build 0:6ae2f7bca550 483 }
Azure.IoT Build 0:6ae2f7bca550 484
Azure.IoT Build 0:6ae2f7bca550 485 static void on_session_flow_on(void* context)
Azure.IoT Build 0:6ae2f7bca550 486 {
Azure.IoT Build 0:6ae2f7bca550 487 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 488 if (link_instance->role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 489 {
Azure.IoT Build 0:6ae2f7bca550 490 link_instance->on_link_flow_on(link_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 491 }
Azure.IoT Build 0:6ae2f7bca550 492 }
Azure.IoT Build 0:6ae2f7bca550 493
Azure.IoT Build 0:6ae2f7bca550 494 static void on_send_complete(void* context, IO_SEND_RESULT send_result)
Azure.IoT Build 0:6ae2f7bca550 495 {
Azure.IoT Build 0:6ae2f7bca550 496 LIST_ITEM_HANDLE delivery_instance_list_item = (LIST_ITEM_HANDLE)context;
Azure.IoT Build 0:6ae2f7bca550 497 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)list_item_get_value(delivery_instance_list_item);
Azure.IoT Build 0:6ae2f7bca550 498 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)delivery_instance->link;
AzureIoTClient 6:641a9672db08 499 (void)send_result;
Azure.IoT Build 0:6ae2f7bca550 500 if (link_instance->snd_settle_mode == sender_settle_mode_settled)
Azure.IoT Build 0:6ae2f7bca550 501 {
AzureIoTClient 7:9e9ab3b0efef 502 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, NULL);
Azure.IoT Build 0:6ae2f7bca550 503 amqpalloc_free(delivery_instance);
Azure.IoT Build 0:6ae2f7bca550 504 (void)list_remove(link_instance->pending_deliveries, delivery_instance_list_item);
Azure.IoT Build 0:6ae2f7bca550 505 }
Azure.IoT Build 0:6ae2f7bca550 506 }
Azure.IoT Build 0:6ae2f7bca550 507
Azure.IoT Build 0:6ae2f7bca550 508 LINK_HANDLE link_create(SESSION_HANDLE session, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
Azure.IoT Build 0:6ae2f7bca550 509 {
Azure.IoT Build 0:6ae2f7bca550 510 LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 511 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 512 {
Azure.IoT Build 0:6ae2f7bca550 513 result->link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 514 result->previous_link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 515 result->role = role;
Azure.IoT Build 0:6ae2f7bca550 516 result->source = amqpvalue_clone(source);
Azure.IoT Build 0:6ae2f7bca550 517 result->target = amqpvalue_clone(target);
Azure.IoT Build 0:6ae2f7bca550 518 result->session = session;
Azure.IoT Build 0:6ae2f7bca550 519 result->handle = 0;
Azure.IoT Build 0:6ae2f7bca550 520 result->snd_settle_mode = sender_settle_mode_unsettled;
Azure.IoT Build 0:6ae2f7bca550 521 result->rcv_settle_mode = receiver_settle_mode_first;
Azure.IoT Build 0:6ae2f7bca550 522 result->delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 523 result->initial_delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 524 result->max_message_size = 0;
Azure.IoT Build 0:6ae2f7bca550 525 result->is_underlying_session_begun = 0;
Azure.IoT Build 0:6ae2f7bca550 526 result->attach_properties = NULL;
Azure.IoT Build 0:6ae2f7bca550 527
Azure.IoT Build 0:6ae2f7bca550 528 result->pending_deliveries = list_create();
Azure.IoT Build 0:6ae2f7bca550 529 if (result->pending_deliveries == NULL)
Azure.IoT Build 0:6ae2f7bca550 530 {
Azure.IoT Build 0:6ae2f7bca550 531 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 532 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 533 }
Azure.IoT Build 0:6ae2f7bca550 534 else
Azure.IoT Build 0:6ae2f7bca550 535 {
Azure.IoT Build 0:6ae2f7bca550 536 result->name = amqpalloc_malloc(strlen(name) + 1);
Azure.IoT Build 0:6ae2f7bca550 537 if (result->name == NULL)
Azure.IoT Build 0:6ae2f7bca550 538 {
Azure.IoT Build 0:6ae2f7bca550 539 list_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 540 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 541 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 542 }
Azure.IoT Build 0:6ae2f7bca550 543 else
Azure.IoT Build 0:6ae2f7bca550 544 {
Azure.IoT Build 0:6ae2f7bca550 545 result->on_link_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 546 result->callback_context = NULL;
Azure.IoT Build 0:6ae2f7bca550 547 set_link_state(result, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 548
Azure.IoT Build 0:6ae2f7bca550 549 (void)strcpy(result->name, name);
Azure.IoT Build 0:6ae2f7bca550 550 result->link_endpoint = session_create_link_endpoint(session, name);
Azure.IoT Build 0:6ae2f7bca550 551 if (result->link_endpoint == NULL)
Azure.IoT Build 0:6ae2f7bca550 552 {
Azure.IoT Build 0:6ae2f7bca550 553 list_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 554 amqpalloc_free(result->name);
Azure.IoT Build 0:6ae2f7bca550 555 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 556 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 557 }
Azure.IoT Build 0:6ae2f7bca550 558 }
Azure.IoT Build 0:6ae2f7bca550 559 }
Azure.IoT Build 0:6ae2f7bca550 560 }
Azure.IoT Build 0:6ae2f7bca550 561
Azure.IoT Build 0:6ae2f7bca550 562 return result;
Azure.IoT Build 0:6ae2f7bca550 563 }
Azure.IoT Build 0:6ae2f7bca550 564
Azure.IoT Build 0:6ae2f7bca550 565 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 566 {
Azure.IoT Build 0:6ae2f7bca550 567 LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 568 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 569 {
Azure.IoT Build 0:6ae2f7bca550 570 result->link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 571 result->previous_link_state = LINK_STATE_DETACHED;
Azure.IoT Build 0:6ae2f7bca550 572 result->session = session;
Azure.IoT Build 0:6ae2f7bca550 573 result->handle = 0;
Azure.IoT Build 0:6ae2f7bca550 574 result->snd_settle_mode = sender_settle_mode_unsettled;
Azure.IoT Build 0:6ae2f7bca550 575 result->rcv_settle_mode = receiver_settle_mode_first;
Azure.IoT Build 0:6ae2f7bca550 576 result->delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 577 result->initial_delivery_count = 0;
Azure.IoT Build 0:6ae2f7bca550 578 result->max_message_size = 0;
Azure.IoT Build 0:6ae2f7bca550 579 result->is_underlying_session_begun = 0;
Azure.IoT Build 0:6ae2f7bca550 580 result->attach_properties = NULL;
Azure.IoT Build 0:6ae2f7bca550 581 result->source = amqpvalue_clone(target);
Azure.IoT Build 0:6ae2f7bca550 582 result->target = amqpvalue_clone(source);
Azure.IoT Build 0:6ae2f7bca550 583 if (role == role_sender)
Azure.IoT Build 0:6ae2f7bca550 584 {
Azure.IoT Build 0:6ae2f7bca550 585 result->role = role_receiver;
Azure.IoT Build 0:6ae2f7bca550 586 }
Azure.IoT Build 0:6ae2f7bca550 587 else
Azure.IoT Build 0:6ae2f7bca550 588 {
Azure.IoT Build 0:6ae2f7bca550 589 result->role = role_sender;
Azure.IoT Build 0:6ae2f7bca550 590 }
Azure.IoT Build 0:6ae2f7bca550 591
Azure.IoT Build 0:6ae2f7bca550 592 result->pending_deliveries = list_create();
Azure.IoT Build 0:6ae2f7bca550 593 if (result->pending_deliveries == NULL)
Azure.IoT Build 0:6ae2f7bca550 594 {
Azure.IoT Build 0:6ae2f7bca550 595 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 596 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 597 }
Azure.IoT Build 0:6ae2f7bca550 598 else
Azure.IoT Build 0:6ae2f7bca550 599 {
Azure.IoT Build 0:6ae2f7bca550 600 result->name = amqpalloc_malloc(strlen(name) + 1);
Azure.IoT Build 0:6ae2f7bca550 601 if (result->name == NULL)
Azure.IoT Build 0:6ae2f7bca550 602 {
Azure.IoT Build 0:6ae2f7bca550 603 list_destroy(result->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 604 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 605 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 606 }
Azure.IoT Build 0:6ae2f7bca550 607 else
Azure.IoT Build 0:6ae2f7bca550 608 {
Azure.IoT Build 0:6ae2f7bca550 609 (void)strcpy(result->name, name);
Azure.IoT Build 0:6ae2f7bca550 610 result->on_link_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 611 result->callback_context = NULL;
Azure.IoT Build 0:6ae2f7bca550 612 result->link_endpoint = link_endpoint;
Azure.IoT Build 0:6ae2f7bca550 613 }
Azure.IoT Build 0:6ae2f7bca550 614 }
Azure.IoT Build 0:6ae2f7bca550 615 }
Azure.IoT Build 0:6ae2f7bca550 616
Azure.IoT Build 0:6ae2f7bca550 617 return result;
Azure.IoT Build 0:6ae2f7bca550 618 }
Azure.IoT Build 0:6ae2f7bca550 619
Azure.IoT Build 0:6ae2f7bca550 620 void link_destroy(LINK_HANDLE link)
Azure.IoT Build 0:6ae2f7bca550 621 {
Azure.IoT Build 0:6ae2f7bca550 622 if (link != NULL)
Azure.IoT Build 0:6ae2f7bca550 623 {
AzureIoTClient 2:64b4feb67cd3 624 link->on_link_state_changed = NULL;
AzureIoTClient 2:64b4feb67cd3 625 link_detach(link);
Azure.IoT Build 0:6ae2f7bca550 626
Azure.IoT Build 0:6ae2f7bca550 627 session_destroy_link_endpoint(link->link_endpoint);
Azure.IoT Build 0:6ae2f7bca550 628 amqpvalue_destroy(link->source);
Azure.IoT Build 0:6ae2f7bca550 629 amqpvalue_destroy(link->target);
Azure.IoT Build 0:6ae2f7bca550 630 if (link->pending_deliveries != NULL)
Azure.IoT Build 0:6ae2f7bca550 631 {
Azure.IoT Build 0:6ae2f7bca550 632 LIST_ITEM_HANDLE item = list_get_head_item(link->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 633 while (item != NULL)
Azure.IoT Build 0:6ae2f7bca550 634 {
Azure.IoT Build 0:6ae2f7bca550 635 LIST_ITEM_HANDLE next_item = list_get_next_item(item);
Azure.IoT Build 0:6ae2f7bca550 636 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)list_item_get_value(item);
Azure.IoT Build 0:6ae2f7bca550 637 if (delivery_instance != NULL)
Azure.IoT Build 0:6ae2f7bca550 638 {
Azure.IoT Build 0:6ae2f7bca550 639 amqpalloc_free(delivery_instance);
Azure.IoT Build 0:6ae2f7bca550 640 }
Azure.IoT Build 0:6ae2f7bca550 641
Azure.IoT Build 0:6ae2f7bca550 642 item = next_item;
Azure.IoT Build 0:6ae2f7bca550 643 }
Azure.IoT Build 0:6ae2f7bca550 644
Azure.IoT Build 0:6ae2f7bca550 645 list_destroy(link->pending_deliveries);
Azure.IoT Build 0:6ae2f7bca550 646 }
Azure.IoT Build 0:6ae2f7bca550 647
Azure.IoT Build 0:6ae2f7bca550 648 if (link->name != NULL)
Azure.IoT Build 0:6ae2f7bca550 649 {
Azure.IoT Build 0:6ae2f7bca550 650 amqpalloc_free(link->name);
Azure.IoT Build 0:6ae2f7bca550 651 }
Azure.IoT Build 0:6ae2f7bca550 652
AzureIoTClient 3:96522ba2ddf8 653 if (link->attach_properties != NULL)
Azure.IoT Build 0:6ae2f7bca550 654 {
AzureIoTClient 3:96522ba2ddf8 655 amqpvalue_destroy(link->attach_properties);
Azure.IoT Build 0:6ae2f7bca550 656 }
Azure.IoT Build 0:6ae2f7bca550 657
Azure.IoT Build 0:6ae2f7bca550 658 amqpalloc_free(link);
Azure.IoT Build 0:6ae2f7bca550 659 }
Azure.IoT Build 0:6ae2f7bca550 660 }
Azure.IoT Build 0:6ae2f7bca550 661
Azure.IoT Build 0:6ae2f7bca550 662 int link_set_snd_settle_mode(LINK_HANDLE link, sender_settle_mode snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 663 {
Azure.IoT Build 0:6ae2f7bca550 664 int result;
Azure.IoT Build 0:6ae2f7bca550 665
Azure.IoT Build 0:6ae2f7bca550 666 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 667 {
Azure.IoT Build 0:6ae2f7bca550 668 result = __LINE__;
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 link->snd_settle_mode = snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 673 result = 0;
Azure.IoT Build 0:6ae2f7bca550 674 }
Azure.IoT Build 0:6ae2f7bca550 675
Azure.IoT Build 0:6ae2f7bca550 676 return result;
Azure.IoT Build 0:6ae2f7bca550 677 }
Azure.IoT Build 0:6ae2f7bca550 678
Azure.IoT Build 0:6ae2f7bca550 679 int link_get_snd_settle_mode(LINK_HANDLE link, sender_settle_mode* snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 680 {
Azure.IoT Build 0:6ae2f7bca550 681 int result;
Azure.IoT Build 0:6ae2f7bca550 682
Azure.IoT Build 0:6ae2f7bca550 683 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 684 (snd_settle_mode == NULL))
Azure.IoT Build 0:6ae2f7bca550 685 {
Azure.IoT Build 0:6ae2f7bca550 686 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 687 }
Azure.IoT Build 0:6ae2f7bca550 688 else
Azure.IoT Build 0:6ae2f7bca550 689 {
Azure.IoT Build 0:6ae2f7bca550 690 *snd_settle_mode = link->snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 691
Azure.IoT Build 0:6ae2f7bca550 692 result = 0;
Azure.IoT Build 0:6ae2f7bca550 693 }
Azure.IoT Build 0:6ae2f7bca550 694
Azure.IoT Build 0:6ae2f7bca550 695 return result;
Azure.IoT Build 0:6ae2f7bca550 696 }
Azure.IoT Build 0:6ae2f7bca550 697
Azure.IoT Build 0:6ae2f7bca550 698 int link_set_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 699 {
Azure.IoT Build 0:6ae2f7bca550 700 int result;
Azure.IoT Build 0:6ae2f7bca550 701
Azure.IoT Build 0:6ae2f7bca550 702 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 703 {
Azure.IoT Build 0:6ae2f7bca550 704 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 705 }
Azure.IoT Build 0:6ae2f7bca550 706 else
Azure.IoT Build 0:6ae2f7bca550 707 {
Azure.IoT Build 0:6ae2f7bca550 708 link->rcv_settle_mode = rcv_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 709 result = 0;
Azure.IoT Build 0:6ae2f7bca550 710 }
Azure.IoT Build 0:6ae2f7bca550 711
Azure.IoT Build 0:6ae2f7bca550 712 return result;
Azure.IoT Build 0:6ae2f7bca550 713 }
Azure.IoT Build 0:6ae2f7bca550 714
Azure.IoT Build 0:6ae2f7bca550 715 int link_get_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode* rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 716 {
Azure.IoT Build 0:6ae2f7bca550 717 int result;
Azure.IoT Build 0:6ae2f7bca550 718
Azure.IoT Build 0:6ae2f7bca550 719 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 720 (rcv_settle_mode == NULL))
Azure.IoT Build 0:6ae2f7bca550 721 {
Azure.IoT Build 0:6ae2f7bca550 722 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 723 }
Azure.IoT Build 0:6ae2f7bca550 724 else
Azure.IoT Build 0:6ae2f7bca550 725 {
Azure.IoT Build 0:6ae2f7bca550 726 *rcv_settle_mode = link->rcv_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 727 result = 0;
Azure.IoT Build 0:6ae2f7bca550 728 }
Azure.IoT Build 0:6ae2f7bca550 729
Azure.IoT Build 0:6ae2f7bca550 730 return result;
Azure.IoT Build 0:6ae2f7bca550 731 }
Azure.IoT Build 0:6ae2f7bca550 732
Azure.IoT Build 0:6ae2f7bca550 733 int link_set_initial_delivery_count(LINK_HANDLE link, sequence_no initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 734 {
Azure.IoT Build 0:6ae2f7bca550 735 int result;
Azure.IoT Build 0:6ae2f7bca550 736
Azure.IoT Build 0:6ae2f7bca550 737 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 738 {
Azure.IoT Build 0:6ae2f7bca550 739 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 740 }
Azure.IoT Build 0:6ae2f7bca550 741 else
Azure.IoT Build 0:6ae2f7bca550 742 {
Azure.IoT Build 0:6ae2f7bca550 743 link->initial_delivery_count = initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 744 result = 0;
Azure.IoT Build 0:6ae2f7bca550 745 }
Azure.IoT Build 0:6ae2f7bca550 746
Azure.IoT Build 0:6ae2f7bca550 747 return result;
Azure.IoT Build 0:6ae2f7bca550 748 }
Azure.IoT Build 0:6ae2f7bca550 749
Azure.IoT Build 0:6ae2f7bca550 750 int link_get_initial_delivery_count(LINK_HANDLE link, sequence_no* initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 751 {
Azure.IoT Build 0:6ae2f7bca550 752 int result;
Azure.IoT Build 0:6ae2f7bca550 753
Azure.IoT Build 0:6ae2f7bca550 754 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 755 (initial_delivery_count == NULL))
Azure.IoT Build 0:6ae2f7bca550 756 {
Azure.IoT Build 0:6ae2f7bca550 757 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 758 }
Azure.IoT Build 0:6ae2f7bca550 759 else
Azure.IoT Build 0:6ae2f7bca550 760 {
Azure.IoT Build 0:6ae2f7bca550 761 *initial_delivery_count = link->initial_delivery_count;
Azure.IoT Build 0:6ae2f7bca550 762 result = 0;
Azure.IoT Build 0:6ae2f7bca550 763 }
Azure.IoT Build 0:6ae2f7bca550 764
Azure.IoT Build 0:6ae2f7bca550 765 return result;
Azure.IoT Build 0:6ae2f7bca550 766 }
Azure.IoT Build 0:6ae2f7bca550 767
Azure.IoT Build 0:6ae2f7bca550 768 int link_set_max_message_size(LINK_HANDLE link, uint64_t max_message_size)
Azure.IoT Build 0:6ae2f7bca550 769 {
Azure.IoT Build 0:6ae2f7bca550 770 int result;
Azure.IoT Build 0:6ae2f7bca550 771
Azure.IoT Build 0:6ae2f7bca550 772 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 773 {
Azure.IoT Build 0:6ae2f7bca550 774 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 775 }
Azure.IoT Build 0:6ae2f7bca550 776 else
Azure.IoT Build 0:6ae2f7bca550 777 {
Azure.IoT Build 0:6ae2f7bca550 778 link->max_message_size = max_message_size;
Azure.IoT Build 0:6ae2f7bca550 779 result = 0;
Azure.IoT Build 0:6ae2f7bca550 780 }
Azure.IoT Build 0:6ae2f7bca550 781
Azure.IoT Build 0:6ae2f7bca550 782 return result;
Azure.IoT Build 0:6ae2f7bca550 783 }
Azure.IoT Build 0:6ae2f7bca550 784
Azure.IoT Build 0:6ae2f7bca550 785 int link_get_max_message_size(LINK_HANDLE link, uint64_t* max_message_size)
Azure.IoT Build 0:6ae2f7bca550 786 {
Azure.IoT Build 0:6ae2f7bca550 787 int result;
Azure.IoT Build 0:6ae2f7bca550 788
Azure.IoT Build 0:6ae2f7bca550 789 if ((link == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 790 (max_message_size == NULL))
Azure.IoT Build 0:6ae2f7bca550 791 {
Azure.IoT Build 0:6ae2f7bca550 792 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 793 }
Azure.IoT Build 0:6ae2f7bca550 794 else
Azure.IoT Build 0:6ae2f7bca550 795 {
Azure.IoT Build 0:6ae2f7bca550 796 *max_message_size = link->max_message_size;
Azure.IoT Build 0:6ae2f7bca550 797 result = 0;
Azure.IoT Build 0:6ae2f7bca550 798 }
Azure.IoT Build 0:6ae2f7bca550 799
Azure.IoT Build 0:6ae2f7bca550 800 return result;
Azure.IoT Build 0:6ae2f7bca550 801 }
Azure.IoT Build 0:6ae2f7bca550 802
Azure.IoT Build 0:6ae2f7bca550 803 int link_set_attach_properties(LINK_HANDLE link, fields attach_properties)
Azure.IoT Build 0:6ae2f7bca550 804 {
Azure.IoT Build 0:6ae2f7bca550 805 int result;
Azure.IoT Build 0:6ae2f7bca550 806
Azure.IoT Build 0:6ae2f7bca550 807 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 808 {
Azure.IoT Build 0:6ae2f7bca550 809 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 810 }
Azure.IoT Build 0:6ae2f7bca550 811 else
Azure.IoT Build 0:6ae2f7bca550 812 {
Azure.IoT Build 0:6ae2f7bca550 813 link->attach_properties = amqpvalue_clone(attach_properties);
Azure.IoT Build 0:6ae2f7bca550 814 if (link->attach_properties == NULL)
Azure.IoT Build 0:6ae2f7bca550 815 {
Azure.IoT Build 0:6ae2f7bca550 816 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 817 }
Azure.IoT Build 0:6ae2f7bca550 818 else
Azure.IoT Build 0:6ae2f7bca550 819 {
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
Azure.IoT Build 0:6ae2f7bca550 824 return result;
Azure.IoT Build 0:6ae2f7bca550 825 }
Azure.IoT Build 0:6ae2f7bca550 826
Azure.IoT Build 0:6ae2f7bca550 827 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 828 {
Azure.IoT Build 0:6ae2f7bca550 829 int result;
Azure.IoT Build 0:6ae2f7bca550 830
Azure.IoT Build 0:6ae2f7bca550 831 if (link == 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 if (!link->is_underlying_session_begun)
Azure.IoT Build 0:6ae2f7bca550 838 {
Azure.IoT Build 0:6ae2f7bca550 839 link->on_link_state_changed = on_link_state_changed;
Azure.IoT Build 0:6ae2f7bca550 840 link->on_transfer_received = on_transfer_received;
Azure.IoT Build 0:6ae2f7bca550 841 link->on_link_flow_on = on_link_flow_on;
Azure.IoT Build 0:6ae2f7bca550 842 link->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 843
Azure.IoT Build 0:6ae2f7bca550 844 if (session_begin(link->session) != 0)
Azure.IoT Build 0:6ae2f7bca550 845 {
Azure.IoT Build 0:6ae2f7bca550 846 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 847 }
Azure.IoT Build 0:6ae2f7bca550 848 else
Azure.IoT Build 0:6ae2f7bca550 849 {
Azure.IoT Build 0:6ae2f7bca550 850 link->is_underlying_session_begun = 1;
Azure.IoT Build 0:6ae2f7bca550 851
Azure.IoT Build 0:6ae2f7bca550 852 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 853 {
Azure.IoT Build 0:6ae2f7bca550 854 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 855 }
Azure.IoT Build 0:6ae2f7bca550 856 else
Azure.IoT Build 0:6ae2f7bca550 857 {
Azure.IoT Build 0:6ae2f7bca550 858 result = 0;
Azure.IoT Build 0:6ae2f7bca550 859 }
Azure.IoT Build 0:6ae2f7bca550 860 }
Azure.IoT Build 0:6ae2f7bca550 861 }
Azure.IoT Build 0:6ae2f7bca550 862 else
Azure.IoT Build 0:6ae2f7bca550 863 {
Azure.IoT Build 0:6ae2f7bca550 864 result = 0;
Azure.IoT Build 0:6ae2f7bca550 865 }
Azure.IoT Build 0:6ae2f7bca550 866 }
Azure.IoT Build 0:6ae2f7bca550 867
Azure.IoT Build 0:6ae2f7bca550 868 return result;
Azure.IoT Build 0:6ae2f7bca550 869 }
Azure.IoT Build 0:6ae2f7bca550 870
Azure.IoT Build 0:6ae2f7bca550 871 int link_detach(LINK_HANDLE link)
Azure.IoT Build 0:6ae2f7bca550 872 {
Azure.IoT Build 0:6ae2f7bca550 873 int result;
Azure.IoT Build 0:6ae2f7bca550 874
Azure.IoT Build 0:6ae2f7bca550 875 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 876 {
Azure.IoT Build 0:6ae2f7bca550 877 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 878 }
Azure.IoT Build 0:6ae2f7bca550 879 else
Azure.IoT Build 0:6ae2f7bca550 880 {
AzureIoTClient 1:eab586236bfe 881 if (link->link_state == LINK_STATE_ERROR)
AzureIoTClient 1:eab586236bfe 882 {
AzureIoTClient 1:eab586236bfe 883 result = __LINE__;
AzureIoTClient 1:eab586236bfe 884 }
AzureIoTClient 1:eab586236bfe 885 else if ((link->link_state == LINK_STATE_HALF_ATTACHED) ||
Azure.IoT Build 0:6ae2f7bca550 886 (link->link_state == LINK_STATE_ATTACHED))
Azure.IoT Build 0:6ae2f7bca550 887 {
Azure.IoT Build 0:6ae2f7bca550 888 if (send_detach(link, NULL) != 0)
Azure.IoT Build 0:6ae2f7bca550 889 {
Azure.IoT Build 0:6ae2f7bca550 890 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 891 }
Azure.IoT Build 0:6ae2f7bca550 892 else
Azure.IoT Build 0:6ae2f7bca550 893 {
Azure.IoT Build 0:6ae2f7bca550 894 set_link_state(link, LINK_STATE_DETACHED);
AzureIoTClient 1:eab586236bfe 895 link->on_link_state_changed = NULL;
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 else
Azure.IoT Build 0:6ae2f7bca550 900 {
Azure.IoT Build 0:6ae2f7bca550 901 set_link_state(link, LINK_STATE_DETACHED);
AzureIoTClient 1:eab586236bfe 902 link->on_link_state_changed = NULL;
Azure.IoT Build 0:6ae2f7bca550 903 result = 0;
Azure.IoT Build 0:6ae2f7bca550 904 }
Azure.IoT Build 0:6ae2f7bca550 905 }
Azure.IoT Build 0:6ae2f7bca550 906
Azure.IoT Build 0:6ae2f7bca550 907 return result;
Azure.IoT Build 0:6ae2f7bca550 908 }
Azure.IoT Build 0:6ae2f7bca550 909
Azure.IoT Build 0:6ae2f7bca550 910 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 911 {
Azure.IoT Build 0:6ae2f7bca550 912 LINK_TRANSFER_RESULT result;
Azure.IoT Build 0:6ae2f7bca550 913
Azure.IoT Build 0:6ae2f7bca550 914 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 915 {
Azure.IoT Build 0:6ae2f7bca550 916 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 917 }
Azure.IoT Build 0:6ae2f7bca550 918 else
Azure.IoT Build 0:6ae2f7bca550 919 {
AzureIoTClient 2:64b4feb67cd3 920 if ((link->role != role_sender) ||
AzureIoTClient 7:9e9ab3b0efef 921 (link->link_state != LINK_STATE_ATTACHED))
Azure.IoT Build 0:6ae2f7bca550 922 {
Azure.IoT Build 0:6ae2f7bca550 923 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 924 }
Azure.IoT Build 0:6ae2f7bca550 925 else if (link->link_credit == 0)
Azure.IoT Build 0:6ae2f7bca550 926 {
Azure.IoT Build 0:6ae2f7bca550 927 result = LINK_TRANSFER_BUSY;
Azure.IoT Build 0:6ae2f7bca550 928 }
Azure.IoT Build 0:6ae2f7bca550 929 else
Azure.IoT Build 0:6ae2f7bca550 930 {
Azure.IoT Build 0:6ae2f7bca550 931 TRANSFER_HANDLE transfer = transfer_create(0);
Azure.IoT Build 0:6ae2f7bca550 932 if (transfer == NULL)
Azure.IoT Build 0:6ae2f7bca550 933 {
Azure.IoT Build 0:6ae2f7bca550 934 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 935 }
Azure.IoT Build 0:6ae2f7bca550 936 else
Azure.IoT Build 0:6ae2f7bca550 937 {
AzureIoTClient 7:9e9ab3b0efef 938 sequence_no delivery_count = link->delivery_count + 1;
AzureIoTClient 7:9e9ab3b0efef 939 unsigned char delivery_tag_bytes[sizeof(delivery_count)];
Azure.IoT Build 0:6ae2f7bca550 940 delivery_tag delivery_tag;
Azure.IoT Build 0:6ae2f7bca550 941 bool settled;
Azure.IoT Build 0:6ae2f7bca550 942
AzureIoTClient 7:9e9ab3b0efef 943 (void)memcpy(delivery_tag_bytes, &delivery_count, sizeof(delivery_count));
Azure.IoT Build 0:6ae2f7bca550 944
Azure.IoT Build 0:6ae2f7bca550 945 delivery_tag.bytes = &delivery_tag_bytes;
Azure.IoT Build 0:6ae2f7bca550 946 delivery_tag.length = sizeof(delivery_tag_bytes);
Azure.IoT Build 0:6ae2f7bca550 947
Azure.IoT Build 0:6ae2f7bca550 948 if (link->snd_settle_mode == sender_settle_mode_unsettled)
Azure.IoT Build 0:6ae2f7bca550 949 {
Azure.IoT Build 0:6ae2f7bca550 950 settled = false;
Azure.IoT Build 0:6ae2f7bca550 951 }
Azure.IoT Build 0:6ae2f7bca550 952 else
Azure.IoT Build 0:6ae2f7bca550 953 {
Azure.IoT Build 0:6ae2f7bca550 954 settled = true;
Azure.IoT Build 0:6ae2f7bca550 955 }
Azure.IoT Build 0:6ae2f7bca550 956
Azure.IoT Build 0:6ae2f7bca550 957 if ((transfer_set_delivery_tag(transfer, delivery_tag) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 958 (transfer_set_message_format(transfer, message_format) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 959 (transfer_set_settled(transfer, settled) != 0))
Azure.IoT Build 0:6ae2f7bca550 960 {
Azure.IoT Build 0:6ae2f7bca550 961 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 962 }
Azure.IoT Build 0:6ae2f7bca550 963 else
Azure.IoT Build 0:6ae2f7bca550 964 {
Azure.IoT Build 0:6ae2f7bca550 965 AMQP_VALUE transfer_value = amqpvalue_create_transfer(transfer);
Azure.IoT Build 0:6ae2f7bca550 966
Azure.IoT Build 0:6ae2f7bca550 967 if (transfer_value == NULL)
Azure.IoT Build 0:6ae2f7bca550 968 {
Azure.IoT Build 0:6ae2f7bca550 969 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 970 }
Azure.IoT Build 0:6ae2f7bca550 971 else
Azure.IoT Build 0:6ae2f7bca550 972 {
Azure.IoT Build 0:6ae2f7bca550 973 DELIVERY_INSTANCE* pending_delivery = amqpalloc_malloc(sizeof(DELIVERY_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 974 if (pending_delivery == NULL)
Azure.IoT Build 0:6ae2f7bca550 975 {
Azure.IoT Build 0:6ae2f7bca550 976 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 977 }
Azure.IoT Build 0:6ae2f7bca550 978 else
Azure.IoT Build 0:6ae2f7bca550 979 {
Azure.IoT Build 0:6ae2f7bca550 980 LIST_ITEM_HANDLE delivery_instance_list_item;
Azure.IoT Build 0:6ae2f7bca550 981 pending_delivery->on_delivery_settled = on_delivery_settled;
Azure.IoT Build 0:6ae2f7bca550 982 pending_delivery->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 983 pending_delivery->link = link;
Azure.IoT Build 0:6ae2f7bca550 984 delivery_instance_list_item = list_add(link->pending_deliveries, pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 985
Azure.IoT Build 0:6ae2f7bca550 986 if (delivery_instance_list_item == NULL)
Azure.IoT Build 0:6ae2f7bca550 987 {
Azure.IoT Build 0:6ae2f7bca550 988 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 989 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 990 }
Azure.IoT Build 0:6ae2f7bca550 991 else
Azure.IoT Build 0:6ae2f7bca550 992 {
Azure.IoT Build 0:6ae2f7bca550 993 /* here we should feed data to the transfer frame */
Azure.IoT Build 0:6ae2f7bca550 994 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 995 {
Azure.IoT Build 0:6ae2f7bca550 996 default:
Azure.IoT Build 0:6ae2f7bca550 997 case SESSION_SEND_TRANSFER_ERROR:
AzureIoTClient 3:96522ba2ddf8 998 list_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 3:96522ba2ddf8 999 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1000 result = LINK_TRANSFER_ERROR;
Azure.IoT Build 0:6ae2f7bca550 1001 break;
Azure.IoT Build 0:6ae2f7bca550 1002
Azure.IoT Build 0:6ae2f7bca550 1003 case SESSION_SEND_TRANSFER_BUSY:
AzureIoTClient 3:96522ba2ddf8 1004 /* Ensure we remove from list again since sender will attempt to transfer again on flow on */
AzureIoTClient 3:96522ba2ddf8 1005 list_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 3:96522ba2ddf8 1006 amqpalloc_free(pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1007 result = LINK_TRANSFER_BUSY;
Azure.IoT Build 0:6ae2f7bca550 1008 break;
Azure.IoT Build 0:6ae2f7bca550 1009
Azure.IoT Build 0:6ae2f7bca550 1010 case SESSION_SEND_TRANSFER_OK:
AzureIoTClient 7:9e9ab3b0efef 1011 link->delivery_count = delivery_count;
Azure.IoT Build 0:6ae2f7bca550 1012 link->link_credit--;
Azure.IoT Build 0:6ae2f7bca550 1013 result = LINK_TRANSFER_OK;
Azure.IoT Build 0:6ae2f7bca550 1014 break;
Azure.IoT Build 0:6ae2f7bca550 1015 }
Azure.IoT Build 0:6ae2f7bca550 1016 }
Azure.IoT Build 0:6ae2f7bca550 1017 }
Azure.IoT Build 0:6ae2f7bca550 1018
Azure.IoT Build 0:6ae2f7bca550 1019 amqpvalue_destroy(transfer_value);
Azure.IoT Build 0:6ae2f7bca550 1020 }
Azure.IoT Build 0:6ae2f7bca550 1021 }
Azure.IoT Build 0:6ae2f7bca550 1022
Azure.IoT Build 0:6ae2f7bca550 1023 transfer_destroy(transfer);
Azure.IoT Build 0:6ae2f7bca550 1024 }
Azure.IoT Build 0:6ae2f7bca550 1025 }
Azure.IoT Build 0:6ae2f7bca550 1026 }
Azure.IoT Build 0:6ae2f7bca550 1027
Azure.IoT Build 0:6ae2f7bca550 1028 return result;
Azure.IoT Build 0:6ae2f7bca550 1029 }