A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Nov 17 13:58:00 2017 -0800
Revision:
36:8e1d94b0a70c
Parent:
34:6be9c2058664
Child:
37:c923ba7f6cf9
1.1.28

Who changed what in which revision?

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