A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Sat Oct 21 20:12:19 2017 +0000
Revision:
34:6be9c2058664
Parent:
29:4a11413cf217
Child:
36:8e1d94b0a70c
1.1.26

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