A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Tue Mar 20 10:29:38 2018 -0700
Revision:
41:0e723f9cbd89
Parent:
37:c923ba7f6cf9
Child:
43:4c1e4e94cdd3
1.2.1

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