A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Mon Jun 11 15:39:52 2018 -0700
Revision:
43:4c1e4e94cdd3
Parent:
41:0e723f9cbd89
Child:
44:9dd558f13109
1.2.5

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