A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Thu Oct 04 09:16:13 2018 -0700
Revision:
47:365a93fdb5bb
Parent:
46:01f7ca900e07
1.2.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
Azure.IoT Build 0:6ae2f7bca550 5 #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 46:01f7ca900e07 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 44:9dd558f13109 596 (void)detach_get_closed(detach, &closed);
AzureIoTClient 44:9dd558f13109 597
AzureIoTClient 19:000ab4e6a2c1 598 /* Received a detach while attached */
AzureIoTClient 19:000ab4e6a2c1 599 if (link_instance->link_state == LINK_STATE_ATTACHED)
AzureIoTClient 19:000ab4e6a2c1 600 {
AzureIoTClient 19:000ab4e6a2c1 601 /* Respond with ack */
AzureIoTClient 41:0e723f9cbd89 602 if (send_detach(link_instance, closed, NULL) != 0)
AzureIoTClient 41:0e723f9cbd89 603 {
AzureIoTClient 41:0e723f9cbd89 604 LogError("Failed sending detach frame");
AzureIoTClient 41:0e723f9cbd89 605 }
AzureIoTClient 19:000ab4e6a2c1 606 }
AzureIoTClient 19:000ab4e6a2c1 607 /* Received a closing detach after we sent a non-closing detach. */
AzureIoTClient 19:000ab4e6a2c1 608 else if (closed &&
AzureIoTClient 24:2c59c2d43ebf 609 ((link_instance->link_state == LINK_STATE_HALF_ATTACHED_ATTACH_SENT) || (link_instance->link_state == LINK_STATE_HALF_ATTACHED_ATTACH_RECEIVED)) &&
AzureIoTClient 19:000ab4e6a2c1 610 !link_instance->is_closed)
AzureIoTClient 19:000ab4e6a2c1 611 {
AzureIoTClient 19:000ab4e6a2c1 612
AzureIoTClient 19:000ab4e6a2c1 613 /* In this case, we MUST signal that we closed by reattaching and then sending a closing detach.*/
AzureIoTClient 41:0e723f9cbd89 614 if (send_attach(link_instance, link_instance->name, 0, link_instance->role) != 0)
AzureIoTClient 41:0e723f9cbd89 615 {
AzureIoTClient 41:0e723f9cbd89 616 LogError("Failed sending attach frame");
AzureIoTClient 41:0e723f9cbd89 617 }
AzureIoTClient 41:0e723f9cbd89 618
AzureIoTClient 41:0e723f9cbd89 619 if (send_detach(link_instance, true, NULL) != 0)
AzureIoTClient 41:0e723f9cbd89 620 {
AzureIoTClient 41:0e723f9cbd89 621 LogError("Failed sending detach frame");
AzureIoTClient 41:0e723f9cbd89 622 }
AzureIoTClient 19:000ab4e6a2c1 623 }
AzureIoTClient 19:000ab4e6a2c1 624
AzureIoTClient 46:01f7ca900e07 625 if (detach_get_error(detach, &error) != 0)
AzureIoTClient 1:eab586236bfe 626 {
AzureIoTClient 46:01f7ca900e07 627 error = NULL;
AzureIoTClient 46:01f7ca900e07 628 }
AzureIoTClient 46:01f7ca900e07 629 remove_all_pending_deliveries(link_instance, true);
AzureIoTClient 46:01f7ca900e07 630 // signal link detach received in order to handle cases like redirect
AzureIoTClient 46:01f7ca900e07 631 if (link_instance->on_link_detach_received_event_subscription.on_link_detach_received != NULL)
AzureIoTClient 46:01f7ca900e07 632 {
AzureIoTClient 46:01f7ca900e07 633 link_instance->on_link_detach_received_event_subscription.on_link_detach_received(link_instance->on_link_detach_received_event_subscription.context, error);
AzureIoTClient 46:01f7ca900e07 634 }
AzureIoTClient 43:4c1e4e94cdd3 635
AzureIoTClient 46:01f7ca900e07 636 if (error != NULL)
AzureIoTClient 46:01f7ca900e07 637 {
AzureIoTClient 46:01f7ca900e07 638 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 43:4c1e4e94cdd3 639 error_destroy(error);
AzureIoTClient 1:eab586236bfe 640 }
AzureIoTClient 46:01f7ca900e07 641 else
AzureIoTClient 1:eab586236bfe 642 {
AzureIoTClient 1:eab586236bfe 643 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 1:eab586236bfe 644 }
AzureIoTClient 12:b30dacf113f2 645
AzureIoTClient 12:b30dacf113f2 646 detach_destroy(detach);
AzureIoTClient 1:eab586236bfe 647 }
AzureIoTClient 1:eab586236bfe 648 }
Azure.IoT Build 0:6ae2f7bca550 649 }
Azure.IoT Build 0:6ae2f7bca550 650
Azure.IoT Build 0:6ae2f7bca550 651 static void on_session_state_changed(void* context, SESSION_STATE new_session_state, SESSION_STATE previous_session_state)
Azure.IoT Build 0:6ae2f7bca550 652 {
AzureIoTClient 28:add19eb7defa 653 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 654 (void)previous_session_state;
Azure.IoT Build 0:6ae2f7bca550 655
AzureIoTClient 28:add19eb7defa 656 if (new_session_state == SESSION_STATE_MAPPED)
AzureIoTClient 28:add19eb7defa 657 {
AzureIoTClient 28:add19eb7defa 658 if ((link_instance->link_state == LINK_STATE_DETACHED) && (!link_instance->is_closed))
AzureIoTClient 28:add19eb7defa 659 {
AzureIoTClient 28:add19eb7defa 660 if (send_attach(link_instance, link_instance->name, 0, link_instance->role) == 0)
AzureIoTClient 28:add19eb7defa 661 {
AzureIoTClient 28:add19eb7defa 662 set_link_state(link_instance, LINK_STATE_HALF_ATTACHED_ATTACH_SENT);
AzureIoTClient 28:add19eb7defa 663 }
AzureIoTClient 28:add19eb7defa 664 }
AzureIoTClient 28:add19eb7defa 665 }
AzureIoTClient 28:add19eb7defa 666 else if (new_session_state == SESSION_STATE_DISCARDING)
AzureIoTClient 28:add19eb7defa 667 {
AzureIoTClient 36:8e1d94b0a70c 668 remove_all_pending_deliveries(link_instance, true);
AzureIoTClient 36:8e1d94b0a70c 669 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 28:add19eb7defa 670 }
AzureIoTClient 28:add19eb7defa 671 else if (new_session_state == SESSION_STATE_ERROR)
AzureIoTClient 28:add19eb7defa 672 {
AzureIoTClient 36:8e1d94b0a70c 673 remove_all_pending_deliveries(link_instance, true);
AzureIoTClient 36:8e1d94b0a70c 674 set_link_state(link_instance, LINK_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 675 }
Azure.IoT Build 0:6ae2f7bca550 676 }
Azure.IoT Build 0:6ae2f7bca550 677
Azure.IoT Build 0:6ae2f7bca550 678 static void on_session_flow_on(void* context)
Azure.IoT Build 0:6ae2f7bca550 679 {
AzureIoTClient 28:add19eb7defa 680 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 28:add19eb7defa 681 if (link_instance->role == role_sender)
AzureIoTClient 28:add19eb7defa 682 {
AzureIoTClient 28:add19eb7defa 683 link_instance->on_link_flow_on(link_instance->callback_context);
AzureIoTClient 28:add19eb7defa 684 }
Azure.IoT Build 0:6ae2f7bca550 685 }
Azure.IoT Build 0:6ae2f7bca550 686
Azure.IoT Build 0:6ae2f7bca550 687 static void on_send_complete(void* context, IO_SEND_RESULT send_result)
Azure.IoT Build 0:6ae2f7bca550 688 {
AzureIoTClient 28:add19eb7defa 689 LIST_ITEM_HANDLE delivery_instance_list_item = (LIST_ITEM_HANDLE)context;
AzureIoTClient 36:8e1d94b0a70c 690 ASYNC_OPERATION_HANDLE pending_delivery_operation = (ASYNC_OPERATION_HANDLE)singlylinkedlist_item_get_value(delivery_instance_list_item);
AzureIoTClient 36:8e1d94b0a70c 691 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)GET_ASYNC_OPERATION_CONTEXT(DELIVERY_INSTANCE, pending_delivery_operation);
AzureIoTClient 36:8e1d94b0a70c 692 LINK_HANDLE link = (LINK_HANDLE)delivery_instance->link;
AzureIoTClient 6:641a9672db08 693 (void)send_result;
AzureIoTClient 36:8e1d94b0a70c 694 if (link->snd_settle_mode == sender_settle_mode_settled)
AzureIoTClient 28:add19eb7defa 695 {
AzureIoTClient 28:add19eb7defa 696 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, LINK_DELIVERY_SETTLE_REASON_SETTLED, NULL);
AzureIoTClient 36:8e1d94b0a70c 697 async_operation_destroy(pending_delivery_operation);
AzureIoTClient 36:8e1d94b0a70c 698 (void)singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 28:add19eb7defa 699 }
Azure.IoT Build 0:6ae2f7bca550 700 }
Azure.IoT Build 0:6ae2f7bca550 701
Azure.IoT Build 0:6ae2f7bca550 702 LINK_HANDLE link_create(SESSION_HANDLE session, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
Azure.IoT Build 0:6ae2f7bca550 703 {
AzureIoTClient 28:add19eb7defa 704 LINK_INSTANCE* result = (LINK_INSTANCE*)malloc(sizeof(LINK_INSTANCE));
AzureIoTClient 41:0e723f9cbd89 705 if (result == NULL)
AzureIoTClient 41:0e723f9cbd89 706 {
AzureIoTClient 41:0e723f9cbd89 707 LogError("Cannot create link");
AzureIoTClient 41:0e723f9cbd89 708 }
AzureIoTClient 41:0e723f9cbd89 709 else
AzureIoTClient 28:add19eb7defa 710 {
AzureIoTClient 28:add19eb7defa 711 result->link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 712 result->previous_link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 713 result->role = role;
AzureIoTClient 28:add19eb7defa 714 result->source = amqpvalue_clone(source);
AzureIoTClient 28:add19eb7defa 715 result->target = amqpvalue_clone(target);
AzureIoTClient 28:add19eb7defa 716 result->session = session;
AzureIoTClient 28:add19eb7defa 717 result->handle = 0;
AzureIoTClient 28:add19eb7defa 718 result->snd_settle_mode = sender_settle_mode_unsettled;
AzureIoTClient 28:add19eb7defa 719 result->rcv_settle_mode = receiver_settle_mode_first;
AzureIoTClient 28:add19eb7defa 720 result->delivery_count = 0;
AzureIoTClient 28:add19eb7defa 721 result->initial_delivery_count = 0;
AzureIoTClient 28:add19eb7defa 722 result->max_message_size = 0;
AzureIoTClient 41:0e723f9cbd89 723 result->max_link_credit = DEFAULT_LINK_CREDIT;
AzureIoTClient 28:add19eb7defa 724 result->peer_max_message_size = 0;
AzureIoTClient 28:add19eb7defa 725 result->is_underlying_session_begun = false;
AzureIoTClient 12:b30dacf113f2 726 result->is_closed = false;
Azure.IoT Build 0:6ae2f7bca550 727 result->attach_properties = NULL;
AzureIoTClient 12:b30dacf113f2 728 result->received_payload = NULL;
AzureIoTClient 12:b30dacf113f2 729 result->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 730 result->received_delivery_id = 0;
AzureIoTClient 43:4c1e4e94cdd3 731 result->on_link_detach_received_event_subscription.on_link_detach_received = NULL;
AzureIoTClient 43:4c1e4e94cdd3 732 result->on_link_detach_received_event_subscription.context = NULL;
Azure.IoT Build 0:6ae2f7bca550 733
AzureIoTClient 34:6be9c2058664 734 result->tick_counter = tickcounter_create();
AzureIoTClient 34:6be9c2058664 735 if (result->tick_counter == NULL)
AzureIoTClient 28:add19eb7defa 736 {
AzureIoTClient 41:0e723f9cbd89 737 LogError("Cannot create tick counter for link");
AzureIoTClient 28:add19eb7defa 738 free(result);
AzureIoTClient 28:add19eb7defa 739 result = NULL;
AzureIoTClient 28:add19eb7defa 740 }
AzureIoTClient 28:add19eb7defa 741 else
AzureIoTClient 28:add19eb7defa 742 {
AzureIoTClient 34:6be9c2058664 743 result->pending_deliveries = singlylinkedlist_create();
AzureIoTClient 34:6be9c2058664 744 if (result->pending_deliveries == NULL)
AzureIoTClient 28:add19eb7defa 745 {
AzureIoTClient 41:0e723f9cbd89 746 LogError("Cannot create pending deliveries list");
AzureIoTClient 34:6be9c2058664 747 tickcounter_destroy(result->tick_counter);
AzureIoTClient 28:add19eb7defa 748 free(result);
AzureIoTClient 28:add19eb7defa 749 result = NULL;
AzureIoTClient 28:add19eb7defa 750 }
AzureIoTClient 28:add19eb7defa 751 else
AzureIoTClient 28:add19eb7defa 752 {
AzureIoTClient 34:6be9c2058664 753 size_t name_length = strlen(name);
AzureIoTClient 34:6be9c2058664 754 result->name = (char*)malloc(name_length + 1);
AzureIoTClient 34:6be9c2058664 755 if (result->name == NULL)
AzureIoTClient 28:add19eb7defa 756 {
AzureIoTClient 41:0e723f9cbd89 757 LogError("Cannot allocate memory for link name");
AzureIoTClient 34:6be9c2058664 758 tickcounter_destroy(result->tick_counter);
AzureIoTClient 28:add19eb7defa 759 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 28:add19eb7defa 760 free(result);
AzureIoTClient 28:add19eb7defa 761 result = NULL;
AzureIoTClient 28:add19eb7defa 762 }
AzureIoTClient 34:6be9c2058664 763 else
AzureIoTClient 34:6be9c2058664 764 {
AzureIoTClient 34:6be9c2058664 765 result->on_link_state_changed = NULL;
AzureIoTClient 34:6be9c2058664 766 result->callback_context = NULL;
AzureIoTClient 34:6be9c2058664 767 set_link_state(result, LINK_STATE_DETACHED);
AzureIoTClient 34:6be9c2058664 768
AzureIoTClient 34:6be9c2058664 769 (void)memcpy(result->name, name, name_length + 1);
AzureIoTClient 34:6be9c2058664 770 result->link_endpoint = session_create_link_endpoint(session, name);
AzureIoTClient 34:6be9c2058664 771 if (result->link_endpoint == NULL)
AzureIoTClient 34:6be9c2058664 772 {
AzureIoTClient 41:0e723f9cbd89 773 LogError("Cannot create link endpoint");
AzureIoTClient 34:6be9c2058664 774 tickcounter_destroy(result->tick_counter);
AzureIoTClient 34:6be9c2058664 775 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 34:6be9c2058664 776 free(result->name);
AzureIoTClient 34:6be9c2058664 777 free(result);
AzureIoTClient 34:6be9c2058664 778 result = NULL;
AzureIoTClient 34:6be9c2058664 779 }
AzureIoTClient 34:6be9c2058664 780 }
AzureIoTClient 28:add19eb7defa 781 }
AzureIoTClient 28:add19eb7defa 782 }
AzureIoTClient 28:add19eb7defa 783 }
Azure.IoT Build 0:6ae2f7bca550 784
AzureIoTClient 28:add19eb7defa 785 return result;
Azure.IoT Build 0:6ae2f7bca550 786 }
Azure.IoT Build 0:6ae2f7bca550 787
Azure.IoT Build 0:6ae2f7bca550 788 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 789 {
AzureIoTClient 28:add19eb7defa 790 LINK_INSTANCE* result = (LINK_INSTANCE*)malloc(sizeof(LINK_INSTANCE));
AzureIoTClient 41:0e723f9cbd89 791 if (result == NULL)
AzureIoTClient 41:0e723f9cbd89 792 {
AzureIoTClient 41:0e723f9cbd89 793 LogError("Cannot create link");
AzureIoTClient 41:0e723f9cbd89 794 }
AzureIoTClient 41:0e723f9cbd89 795 else
AzureIoTClient 28:add19eb7defa 796 {
AzureIoTClient 28:add19eb7defa 797 result->link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 798 result->previous_link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 799 result->session = session;
AzureIoTClient 28:add19eb7defa 800 result->handle = 0;
AzureIoTClient 28:add19eb7defa 801 result->snd_settle_mode = sender_settle_mode_unsettled;
AzureIoTClient 28:add19eb7defa 802 result->rcv_settle_mode = receiver_settle_mode_first;
AzureIoTClient 28:add19eb7defa 803 result->delivery_count = 0;
AzureIoTClient 28:add19eb7defa 804 result->initial_delivery_count = 0;
AzureIoTClient 28:add19eb7defa 805 result->max_message_size = 0;
AzureIoTClient 41:0e723f9cbd89 806 result->max_link_credit = DEFAULT_LINK_CREDIT;
AzureIoTClient 28:add19eb7defa 807 result->peer_max_message_size = 0;
AzureIoTClient 28:add19eb7defa 808 result->is_underlying_session_begun = false;
AzureIoTClient 12:b30dacf113f2 809 result->is_closed = false;
Azure.IoT Build 0:6ae2f7bca550 810 result->attach_properties = NULL;
AzureIoTClient 12:b30dacf113f2 811 result->received_payload = NULL;
AzureIoTClient 12:b30dacf113f2 812 result->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 813 result->received_delivery_id = 0;
Azure.IoT Build 0:6ae2f7bca550 814 result->source = amqpvalue_clone(target);
AzureIoTClient 28:add19eb7defa 815 result->target = amqpvalue_clone(source);
AzureIoTClient 43:4c1e4e94cdd3 816 result->on_link_detach_received_event_subscription.on_link_detach_received = NULL;
AzureIoTClient 43:4c1e4e94cdd3 817 result->on_link_detach_received_event_subscription.context = NULL;
AzureIoTClient 41:0e723f9cbd89 818
AzureIoTClient 28:add19eb7defa 819 if (role == role_sender)
AzureIoTClient 28:add19eb7defa 820 {
AzureIoTClient 28:add19eb7defa 821 result->role = role_receiver;
AzureIoTClient 28:add19eb7defa 822 }
AzureIoTClient 28:add19eb7defa 823 else
AzureIoTClient 28:add19eb7defa 824 {
AzureIoTClient 28:add19eb7defa 825 result->role = role_sender;
AzureIoTClient 28:add19eb7defa 826 }
Azure.IoT Build 0:6ae2f7bca550 827
AzureIoTClient 34:6be9c2058664 828 result->tick_counter = tickcounter_create();
AzureIoTClient 34:6be9c2058664 829 if (result->tick_counter == NULL)
AzureIoTClient 28:add19eb7defa 830 {
AzureIoTClient 41:0e723f9cbd89 831 LogError("Cannot create tick counter for link");
AzureIoTClient 28:add19eb7defa 832 free(result);
AzureIoTClient 28:add19eb7defa 833 result = NULL;
AzureIoTClient 28:add19eb7defa 834 }
AzureIoTClient 28:add19eb7defa 835 else
AzureIoTClient 28:add19eb7defa 836 {
AzureIoTClient 34:6be9c2058664 837 result->pending_deliveries = singlylinkedlist_create();
AzureIoTClient 34:6be9c2058664 838 if (result->pending_deliveries == NULL)
AzureIoTClient 28:add19eb7defa 839 {
AzureIoTClient 41:0e723f9cbd89 840 LogError("Cannot create pending deliveries list");
AzureIoTClient 34:6be9c2058664 841 tickcounter_destroy(result->tick_counter);
AzureIoTClient 28:add19eb7defa 842 free(result);
AzureIoTClient 28:add19eb7defa 843 result = NULL;
AzureIoTClient 28:add19eb7defa 844 }
AzureIoTClient 28:add19eb7defa 845 else
AzureIoTClient 28:add19eb7defa 846 {
AzureIoTClient 34:6be9c2058664 847 size_t name_length = strlen(name);
AzureIoTClient 34:6be9c2058664 848 result->name = (char*)malloc(name_length + 1);
AzureIoTClient 34:6be9c2058664 849 if (result->name == NULL)
AzureIoTClient 34:6be9c2058664 850 {
AzureIoTClient 41:0e723f9cbd89 851 LogError("Cannot allocate memory for link name");
AzureIoTClient 34:6be9c2058664 852 tickcounter_destroy(result->tick_counter);
AzureIoTClient 34:6be9c2058664 853 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 34:6be9c2058664 854 free(result);
AzureIoTClient 34:6be9c2058664 855 result = NULL;
AzureIoTClient 34:6be9c2058664 856 }
AzureIoTClient 34:6be9c2058664 857 else
AzureIoTClient 34:6be9c2058664 858 {
AzureIoTClient 34:6be9c2058664 859 (void)memcpy(result->name, name, name_length + 1);
AzureIoTClient 34:6be9c2058664 860 result->on_link_state_changed = NULL;
AzureIoTClient 34:6be9c2058664 861 result->callback_context = NULL;
AzureIoTClient 34:6be9c2058664 862 result->link_endpoint = link_endpoint;
AzureIoTClient 34:6be9c2058664 863 }
AzureIoTClient 28:add19eb7defa 864 }
AzureIoTClient 28:add19eb7defa 865 }
AzureIoTClient 28:add19eb7defa 866 }
Azure.IoT Build 0:6ae2f7bca550 867
AzureIoTClient 28:add19eb7defa 868 return result;
Azure.IoT Build 0:6ae2f7bca550 869 }
Azure.IoT Build 0:6ae2f7bca550 870
Azure.IoT Build 0:6ae2f7bca550 871 void link_destroy(LINK_HANDLE link)
Azure.IoT Build 0:6ae2f7bca550 872 {
AzureIoTClient 41:0e723f9cbd89 873 if (link == NULL)
AzureIoTClient 41:0e723f9cbd89 874 {
AzureIoTClient 41:0e723f9cbd89 875 LogError("NULL link");
AzureIoTClient 41:0e723f9cbd89 876 }
AzureIoTClient 41:0e723f9cbd89 877 else
AzureIoTClient 28:add19eb7defa 878 {
AzureIoTClient 21:f9c433d8e6ca 879 remove_all_pending_deliveries((LINK_INSTANCE*)link, false);
AzureIoTClient 34:6be9c2058664 880 tickcounter_destroy(link->tick_counter);
AzureIoTClient 21:f9c433d8e6ca 881
AzureIoTClient 12:b30dacf113f2 882 link->on_link_state_changed = NULL;
AzureIoTClient 43:4c1e4e94cdd3 883 (void)link_detach(link, true, NULL, NULL, NULL);
AzureIoTClient 12:b30dacf113f2 884 session_destroy_link_endpoint(link->link_endpoint);
AzureIoTClient 28:add19eb7defa 885 amqpvalue_destroy(link->source);
AzureIoTClient 28:add19eb7defa 886 amqpvalue_destroy(link->target);
Azure.IoT Build 0:6ae2f7bca550 887
AzureIoTClient 28:add19eb7defa 888 if (link->name != NULL)
AzureIoTClient 28:add19eb7defa 889 {
AzureIoTClient 28:add19eb7defa 890 free(link->name);
AzureIoTClient 28:add19eb7defa 891 }
Azure.IoT Build 0:6ae2f7bca550 892
AzureIoTClient 28:add19eb7defa 893 if (link->attach_properties != NULL)
Azure.IoT Build 0:6ae2f7bca550 894 {
AzureIoTClient 28:add19eb7defa 895 amqpvalue_destroy(link->attach_properties);
Azure.IoT Build 0:6ae2f7bca550 896 }
Azure.IoT Build 0:6ae2f7bca550 897
AzureIoTClient 12:b30dacf113f2 898 if (link->received_payload != NULL)
AzureIoTClient 12:b30dacf113f2 899 {
AzureIoTClient 12:b30dacf113f2 900 free(link->received_payload);
AzureIoTClient 12:b30dacf113f2 901 }
AzureIoTClient 12:b30dacf113f2 902
AzureIoTClient 28:add19eb7defa 903 free(link);
AzureIoTClient 28:add19eb7defa 904 }
Azure.IoT Build 0:6ae2f7bca550 905 }
Azure.IoT Build 0:6ae2f7bca550 906
Azure.IoT Build 0:6ae2f7bca550 907 int link_set_snd_settle_mode(LINK_HANDLE link, sender_settle_mode snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 908 {
AzureIoTClient 28:add19eb7defa 909 int result;
Azure.IoT Build 0:6ae2f7bca550 910
AzureIoTClient 28:add19eb7defa 911 if (link == NULL)
AzureIoTClient 28:add19eb7defa 912 {
AzureIoTClient 41:0e723f9cbd89 913 LogError("NULL link");
AzureIoTClient 28:add19eb7defa 914 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 915 }
AzureIoTClient 28:add19eb7defa 916 else
AzureIoTClient 28:add19eb7defa 917 {
AzureIoTClient 28:add19eb7defa 918 link->snd_settle_mode = snd_settle_mode;
AzureIoTClient 28:add19eb7defa 919 result = 0;
AzureIoTClient 28:add19eb7defa 920 }
Azure.IoT Build 0:6ae2f7bca550 921
AzureIoTClient 28:add19eb7defa 922 return result;
Azure.IoT Build 0:6ae2f7bca550 923 }
Azure.IoT Build 0:6ae2f7bca550 924
Azure.IoT Build 0:6ae2f7bca550 925 int link_get_snd_settle_mode(LINK_HANDLE link, sender_settle_mode* snd_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 926 {
AzureIoTClient 28:add19eb7defa 927 int result;
Azure.IoT Build 0:6ae2f7bca550 928
AzureIoTClient 28:add19eb7defa 929 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 930 (snd_settle_mode == NULL))
AzureIoTClient 28:add19eb7defa 931 {
AzureIoTClient 41:0e723f9cbd89 932 LogError("Bad arguments: link = %p, snd_settle_mode = %p",
AzureIoTClient 41:0e723f9cbd89 933 link, snd_settle_mode);
AzureIoTClient 28:add19eb7defa 934 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 935 }
AzureIoTClient 28:add19eb7defa 936 else
AzureIoTClient 28:add19eb7defa 937 {
AzureIoTClient 28:add19eb7defa 938 *snd_settle_mode = link->snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 939
AzureIoTClient 28:add19eb7defa 940 result = 0;
AzureIoTClient 28:add19eb7defa 941 }
Azure.IoT Build 0:6ae2f7bca550 942
AzureIoTClient 28:add19eb7defa 943 return result;
Azure.IoT Build 0:6ae2f7bca550 944 }
Azure.IoT Build 0:6ae2f7bca550 945
Azure.IoT Build 0:6ae2f7bca550 946 int link_set_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 947 {
AzureIoTClient 28:add19eb7defa 948 int result;
Azure.IoT Build 0:6ae2f7bca550 949
AzureIoTClient 28:add19eb7defa 950 if (link == NULL)
AzureIoTClient 28:add19eb7defa 951 {
AzureIoTClient 41:0e723f9cbd89 952 LogError("NULL link");
AzureIoTClient 28:add19eb7defa 953 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 954 }
AzureIoTClient 28:add19eb7defa 955 else
AzureIoTClient 28:add19eb7defa 956 {
AzureIoTClient 28:add19eb7defa 957 link->rcv_settle_mode = rcv_settle_mode;
AzureIoTClient 28:add19eb7defa 958 result = 0;
AzureIoTClient 28:add19eb7defa 959 }
Azure.IoT Build 0:6ae2f7bca550 960
AzureIoTClient 28:add19eb7defa 961 return result;
Azure.IoT Build 0:6ae2f7bca550 962 }
Azure.IoT Build 0:6ae2f7bca550 963
Azure.IoT Build 0:6ae2f7bca550 964 int link_get_rcv_settle_mode(LINK_HANDLE link, receiver_settle_mode* rcv_settle_mode)
Azure.IoT Build 0:6ae2f7bca550 965 {
AzureIoTClient 28:add19eb7defa 966 int result;
Azure.IoT Build 0:6ae2f7bca550 967
AzureIoTClient 28:add19eb7defa 968 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 969 (rcv_settle_mode == NULL))
AzureIoTClient 28:add19eb7defa 970 {
AzureIoTClient 41:0e723f9cbd89 971 LogError("Bad arguments: link = %p, rcv_settle_mode = %p",
AzureIoTClient 41:0e723f9cbd89 972 link, rcv_settle_mode);
AzureIoTClient 28:add19eb7defa 973 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 974 }
AzureIoTClient 28:add19eb7defa 975 else
AzureIoTClient 28:add19eb7defa 976 {
AzureIoTClient 28:add19eb7defa 977 *rcv_settle_mode = link->rcv_settle_mode;
AzureIoTClient 28:add19eb7defa 978 result = 0;
AzureIoTClient 28:add19eb7defa 979 }
Azure.IoT Build 0:6ae2f7bca550 980
AzureIoTClient 28:add19eb7defa 981 return result;
Azure.IoT Build 0:6ae2f7bca550 982 }
Azure.IoT Build 0:6ae2f7bca550 983
Azure.IoT Build 0:6ae2f7bca550 984 int link_set_initial_delivery_count(LINK_HANDLE link, sequence_no initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 985 {
AzureIoTClient 28:add19eb7defa 986 int result;
Azure.IoT Build 0:6ae2f7bca550 987
AzureIoTClient 28:add19eb7defa 988 if (link == NULL)
AzureIoTClient 28:add19eb7defa 989 {
AzureIoTClient 41:0e723f9cbd89 990 LogError("NULL link");
AzureIoTClient 28:add19eb7defa 991 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 992 }
AzureIoTClient 28:add19eb7defa 993 else
AzureIoTClient 28:add19eb7defa 994 {
AzureIoTClient 28:add19eb7defa 995 link->initial_delivery_count = initial_delivery_count;
AzureIoTClient 28:add19eb7defa 996 result = 0;
AzureIoTClient 28:add19eb7defa 997 }
Azure.IoT Build 0:6ae2f7bca550 998
AzureIoTClient 28:add19eb7defa 999 return result;
Azure.IoT Build 0:6ae2f7bca550 1000 }
Azure.IoT Build 0:6ae2f7bca550 1001
Azure.IoT Build 0:6ae2f7bca550 1002 int link_get_initial_delivery_count(LINK_HANDLE link, sequence_no* initial_delivery_count)
Azure.IoT Build 0:6ae2f7bca550 1003 {
AzureIoTClient 28:add19eb7defa 1004 int result;
Azure.IoT Build 0:6ae2f7bca550 1005
AzureIoTClient 28:add19eb7defa 1006 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 1007 (initial_delivery_count == NULL))
AzureIoTClient 28:add19eb7defa 1008 {
AzureIoTClient 41:0e723f9cbd89 1009 LogError("Bad arguments: link = %p, initial_delivery_count = %p",
AzureIoTClient 41:0e723f9cbd89 1010 link, initial_delivery_count);
AzureIoTClient 28:add19eb7defa 1011 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1012 }
AzureIoTClient 28:add19eb7defa 1013 else
AzureIoTClient 28:add19eb7defa 1014 {
AzureIoTClient 28:add19eb7defa 1015 *initial_delivery_count = link->initial_delivery_count;
AzureIoTClient 28:add19eb7defa 1016 result = 0;
AzureIoTClient 28:add19eb7defa 1017 }
Azure.IoT Build 0:6ae2f7bca550 1018
AzureIoTClient 28:add19eb7defa 1019 return result;
Azure.IoT Build 0:6ae2f7bca550 1020 }
Azure.IoT Build 0:6ae2f7bca550 1021
Azure.IoT Build 0:6ae2f7bca550 1022 int link_set_max_message_size(LINK_HANDLE link, uint64_t max_message_size)
Azure.IoT Build 0:6ae2f7bca550 1023 {
AzureIoTClient 28:add19eb7defa 1024 int result;
Azure.IoT Build 0:6ae2f7bca550 1025
AzureIoTClient 28:add19eb7defa 1026 if (link == NULL)
AzureIoTClient 28:add19eb7defa 1027 {
AzureIoTClient 41:0e723f9cbd89 1028 LogError("NULL link");
AzureIoTClient 28:add19eb7defa 1029 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1030 }
AzureIoTClient 28:add19eb7defa 1031 else
AzureIoTClient 28:add19eb7defa 1032 {
AzureIoTClient 28:add19eb7defa 1033 link->max_message_size = max_message_size;
AzureIoTClient 28:add19eb7defa 1034 result = 0;
AzureIoTClient 28:add19eb7defa 1035 }
Azure.IoT Build 0:6ae2f7bca550 1036
AzureIoTClient 28:add19eb7defa 1037 return result;
Azure.IoT Build 0:6ae2f7bca550 1038 }
Azure.IoT Build 0:6ae2f7bca550 1039
Azure.IoT Build 0:6ae2f7bca550 1040 int link_get_max_message_size(LINK_HANDLE link, uint64_t* max_message_size)
Azure.IoT Build 0:6ae2f7bca550 1041 {
AzureIoTClient 28:add19eb7defa 1042 int result;
Azure.IoT Build 0:6ae2f7bca550 1043
AzureIoTClient 28:add19eb7defa 1044 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 1045 (max_message_size == NULL))
AzureIoTClient 28:add19eb7defa 1046 {
AzureIoTClient 41:0e723f9cbd89 1047 LogError("Bad arguments: link = %p, max_message_size = %p",
AzureIoTClient 41:0e723f9cbd89 1048 link, max_message_size);
AzureIoTClient 28:add19eb7defa 1049 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1050 }
AzureIoTClient 28:add19eb7defa 1051 else
AzureIoTClient 28:add19eb7defa 1052 {
AzureIoTClient 28:add19eb7defa 1053 *max_message_size = link->max_message_size;
AzureIoTClient 28:add19eb7defa 1054 result = 0;
AzureIoTClient 28:add19eb7defa 1055 }
Azure.IoT Build 0:6ae2f7bca550 1056
AzureIoTClient 28:add19eb7defa 1057 return result;
Azure.IoT Build 0:6ae2f7bca550 1058 }
Azure.IoT Build 0:6ae2f7bca550 1059
AzureIoTClient 24:2c59c2d43ebf 1060 int link_get_peer_max_message_size(LINK_HANDLE link, uint64_t* peer_max_message_size)
AzureIoTClient 24:2c59c2d43ebf 1061 {
AzureIoTClient 28:add19eb7defa 1062 int result;
AzureIoTClient 24:2c59c2d43ebf 1063
AzureIoTClient 28:add19eb7defa 1064 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 1065 (peer_max_message_size == NULL))
AzureIoTClient 28:add19eb7defa 1066 {
AzureIoTClient 28:add19eb7defa 1067 LogError("Bad arguments: link = %p, peer_max_message_size = %p",
AzureIoTClient 28:add19eb7defa 1068 link, peer_max_message_size);
AzureIoTClient 28:add19eb7defa 1069 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1070 }
AzureIoTClient 28:add19eb7defa 1071 else if ((link->link_state != LINK_STATE_ATTACHED) &&
AzureIoTClient 28:add19eb7defa 1072 (link->link_state != LINK_STATE_HALF_ATTACHED_ATTACH_RECEIVED))
AzureIoTClient 28:add19eb7defa 1073 {
AzureIoTClient 28:add19eb7defa 1074 LogError("Attempting to read peer max message size before it was received");
AzureIoTClient 28:add19eb7defa 1075 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1076 }
AzureIoTClient 28:add19eb7defa 1077 else
AzureIoTClient 28:add19eb7defa 1078 {
AzureIoTClient 28:add19eb7defa 1079 *peer_max_message_size = link->peer_max_message_size;
AzureIoTClient 28:add19eb7defa 1080 result = 0;
AzureIoTClient 28:add19eb7defa 1081 }
AzureIoTClient 24:2c59c2d43ebf 1082
AzureIoTClient 28:add19eb7defa 1083 return result;
AzureIoTClient 24:2c59c2d43ebf 1084 }
AzureIoTClient 24:2c59c2d43ebf 1085
Azure.IoT Build 0:6ae2f7bca550 1086 int link_set_attach_properties(LINK_HANDLE link, fields attach_properties)
Azure.IoT Build 0:6ae2f7bca550 1087 {
Azure.IoT Build 0:6ae2f7bca550 1088 int result;
Azure.IoT Build 0:6ae2f7bca550 1089
Azure.IoT Build 0:6ae2f7bca550 1090 if (link == NULL)
Azure.IoT Build 0:6ae2f7bca550 1091 {
AzureIoTClient 41:0e723f9cbd89 1092 LogError("NULL link");
AzureIoTClient 19:000ab4e6a2c1 1093 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1094 }
Azure.IoT Build 0:6ae2f7bca550 1095 else
Azure.IoT Build 0:6ae2f7bca550 1096 {
Azure.IoT Build 0:6ae2f7bca550 1097 link->attach_properties = amqpvalue_clone(attach_properties);
Azure.IoT Build 0:6ae2f7bca550 1098 if (link->attach_properties == NULL)
Azure.IoT Build 0:6ae2f7bca550 1099 {
AzureIoTClient 41:0e723f9cbd89 1100 LogError("Failed cloning attach properties");
AzureIoTClient 19:000ab4e6a2c1 1101 result = __FAILURE__;
Azure.IoT Build 0:6ae2f7bca550 1102 }
Azure.IoT Build 0:6ae2f7bca550 1103 else
Azure.IoT Build 0:6ae2f7bca550 1104 {
Azure.IoT Build 0:6ae2f7bca550 1105 result = 0;
Azure.IoT Build 0:6ae2f7bca550 1106 }
Azure.IoT Build 0:6ae2f7bca550 1107 }
Azure.IoT Build 0:6ae2f7bca550 1108
Azure.IoT Build 0:6ae2f7bca550 1109 return result;
Azure.IoT Build 0:6ae2f7bca550 1110 }
Azure.IoT Build 0:6ae2f7bca550 1111
AzureIoTClient 41:0e723f9cbd89 1112 int link_set_max_link_credit(LINK_HANDLE link, uint32_t max_link_credit)
AzureIoTClient 41:0e723f9cbd89 1113 {
AzureIoTClient 41:0e723f9cbd89 1114 int result;
AzureIoTClient 41:0e723f9cbd89 1115
AzureIoTClient 41:0e723f9cbd89 1116 if (link == NULL)
AzureIoTClient 41:0e723f9cbd89 1117 {
AzureIoTClient 41:0e723f9cbd89 1118 result = __FAILURE__;
AzureIoTClient 41:0e723f9cbd89 1119 }
AzureIoTClient 41:0e723f9cbd89 1120 else
AzureIoTClient 41:0e723f9cbd89 1121 {
AzureIoTClient 41:0e723f9cbd89 1122 link->max_link_credit = max_link_credit;
AzureIoTClient 41:0e723f9cbd89 1123 result = 0;
AzureIoTClient 41:0e723f9cbd89 1124 }
AzureIoTClient 41:0e723f9cbd89 1125
AzureIoTClient 41:0e723f9cbd89 1126 return result;
AzureIoTClient 41:0e723f9cbd89 1127 }
AzureIoTClient 41:0e723f9cbd89 1128
Azure.IoT Build 0:6ae2f7bca550 1129 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 1130 {
AzureIoTClient 28:add19eb7defa 1131 int result;
Azure.IoT Build 0:6ae2f7bca550 1132
AzureIoTClient 41:0e723f9cbd89 1133 if (link == NULL)
AzureIoTClient 28:add19eb7defa 1134 {
AzureIoTClient 41:0e723f9cbd89 1135 LogError("NULL link");
AzureIoTClient 41:0e723f9cbd89 1136 result = __FAILURE__;
AzureIoTClient 41:0e723f9cbd89 1137 }
AzureIoTClient 41:0e723f9cbd89 1138 else if (link->is_closed)
AzureIoTClient 41:0e723f9cbd89 1139 {
AzureIoTClient 41:0e723f9cbd89 1140 LogError("Already attached");
AzureIoTClient 28:add19eb7defa 1141 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1142 }
AzureIoTClient 28:add19eb7defa 1143 else
AzureIoTClient 28:add19eb7defa 1144 {
AzureIoTClient 28:add19eb7defa 1145 if (!link->is_underlying_session_begun)
AzureIoTClient 28:add19eb7defa 1146 {
AzureIoTClient 28:add19eb7defa 1147 link->on_link_state_changed = on_link_state_changed;
AzureIoTClient 28:add19eb7defa 1148 link->on_transfer_received = on_transfer_received;
AzureIoTClient 28:add19eb7defa 1149 link->on_link_flow_on = on_link_flow_on;
AzureIoTClient 28:add19eb7defa 1150 link->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 1151
AzureIoTClient 28:add19eb7defa 1152 if (session_begin(link->session) != 0)
AzureIoTClient 28:add19eb7defa 1153 {
AzureIoTClient 41:0e723f9cbd89 1154 LogError("Begin session failed");
AzureIoTClient 28:add19eb7defa 1155 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1156 }
AzureIoTClient 28:add19eb7defa 1157 else
AzureIoTClient 28:add19eb7defa 1158 {
AzureIoTClient 28:add19eb7defa 1159 link->is_underlying_session_begun = true;
Azure.IoT Build 0:6ae2f7bca550 1160
AzureIoTClient 28:add19eb7defa 1161 if (session_start_link_endpoint(link->link_endpoint, link_frame_received, on_session_state_changed, on_session_flow_on, link) != 0)
AzureIoTClient 28:add19eb7defa 1162 {
AzureIoTClient 41:0e723f9cbd89 1163 LogError("Binding link endpoint to session failed");
AzureIoTClient 28:add19eb7defa 1164 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1165 }
AzureIoTClient 28:add19eb7defa 1166 else
AzureIoTClient 28:add19eb7defa 1167 {
AzureIoTClient 12:b30dacf113f2 1168 link->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 1169
AzureIoTClient 28:add19eb7defa 1170 result = 0;
AzureIoTClient 28:add19eb7defa 1171 }
AzureIoTClient 28:add19eb7defa 1172 }
AzureIoTClient 28:add19eb7defa 1173 }
AzureIoTClient 28:add19eb7defa 1174 else
AzureIoTClient 28:add19eb7defa 1175 {
AzureIoTClient 28:add19eb7defa 1176 result = 0;
AzureIoTClient 28:add19eb7defa 1177 }
AzureIoTClient 28:add19eb7defa 1178 }
Azure.IoT Build 0:6ae2f7bca550 1179
AzureIoTClient 28:add19eb7defa 1180 return result;
Azure.IoT Build 0:6ae2f7bca550 1181 }
Azure.IoT Build 0:6ae2f7bca550 1182
AzureIoTClient 43:4c1e4e94cdd3 1183 int link_detach(LINK_HANDLE link, bool close, const char* error_condition, const char* error_description, AMQP_VALUE info)
Azure.IoT Build 0:6ae2f7bca550 1184 {
AzureIoTClient 28:add19eb7defa 1185 int result;
Azure.IoT Build 0:6ae2f7bca550 1186
AzureIoTClient 43:4c1e4e94cdd3 1187 (void)error_condition;
AzureIoTClient 43:4c1e4e94cdd3 1188 (void)error_description;
AzureIoTClient 43:4c1e4e94cdd3 1189 (void)info;
AzureIoTClient 43:4c1e4e94cdd3 1190
AzureIoTClient 41:0e723f9cbd89 1191 if (link == NULL)
AzureIoTClient 12:b30dacf113f2 1192 {
AzureIoTClient 41:0e723f9cbd89 1193 LogError("NULL link");
AzureIoTClient 28:add19eb7defa 1194 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1195 }
AzureIoTClient 41:0e723f9cbd89 1196 else if (link->is_closed)
AzureIoTClient 41:0e723f9cbd89 1197 {
AzureIoTClient 41:0e723f9cbd89 1198 result = 0;
AzureIoTClient 41:0e723f9cbd89 1199 }
AzureIoTClient 28:add19eb7defa 1200 else
AzureIoTClient 28:add19eb7defa 1201 {
AzureIoTClient 43:4c1e4e94cdd3 1202 ERROR_HANDLE error;
AzureIoTClient 43:4c1e4e94cdd3 1203
AzureIoTClient 43:4c1e4e94cdd3 1204 if (error_condition != NULL)
AzureIoTClient 43:4c1e4e94cdd3 1205 {
AzureIoTClient 43:4c1e4e94cdd3 1206 error = error_create(error_condition);
AzureIoTClient 43:4c1e4e94cdd3 1207 if (error == NULL)
AzureIoTClient 43:4c1e4e94cdd3 1208 {
AzureIoTClient 43:4c1e4e94cdd3 1209 LogInfo("Cannot create error for detach, detaching without error anyhow");
AzureIoTClient 43:4c1e4e94cdd3 1210 }
AzureIoTClient 43:4c1e4e94cdd3 1211 else
AzureIoTClient 43:4c1e4e94cdd3 1212 {
AzureIoTClient 43:4c1e4e94cdd3 1213 if (error_description != NULL)
AzureIoTClient 43:4c1e4e94cdd3 1214 {
AzureIoTClient 43:4c1e4e94cdd3 1215 if (error_set_description(error, error_description) != 0)
AzureIoTClient 43:4c1e4e94cdd3 1216 {
AzureIoTClient 43:4c1e4e94cdd3 1217 LogInfo("Cannot set error description on detach error, detaching anyhow");
AzureIoTClient 43:4c1e4e94cdd3 1218 }
AzureIoTClient 43:4c1e4e94cdd3 1219 }
AzureIoTClient 43:4c1e4e94cdd3 1220
AzureIoTClient 43:4c1e4e94cdd3 1221 if (info != NULL)
AzureIoTClient 43:4c1e4e94cdd3 1222 {
AzureIoTClient 43:4c1e4e94cdd3 1223 if (error_set_info(error, info) != 0)
AzureIoTClient 43:4c1e4e94cdd3 1224 {
AzureIoTClient 43:4c1e4e94cdd3 1225 LogInfo("Cannot set info map on detach error, detaching anyhow");
AzureIoTClient 43:4c1e4e94cdd3 1226 }
AzureIoTClient 43:4c1e4e94cdd3 1227 }
AzureIoTClient 43:4c1e4e94cdd3 1228 }
AzureIoTClient 43:4c1e4e94cdd3 1229 }
AzureIoTClient 43:4c1e4e94cdd3 1230 else
AzureIoTClient 43:4c1e4e94cdd3 1231 {
AzureIoTClient 43:4c1e4e94cdd3 1232 error = NULL;
AzureIoTClient 43:4c1e4e94cdd3 1233 }
AzureIoTClient 43:4c1e4e94cdd3 1234
AzureIoTClient 12:b30dacf113f2 1235 switch (link->link_state)
AzureIoTClient 12:b30dacf113f2 1236 {
AzureIoTClient 24:2c59c2d43ebf 1237 case LINK_STATE_HALF_ATTACHED_ATTACH_SENT:
AzureIoTClient 28:add19eb7defa 1238 case LINK_STATE_HALF_ATTACHED_ATTACH_RECEIVED:
AzureIoTClient 12:b30dacf113f2 1239 /* Sending detach when remote is not yet attached */
AzureIoTClient 43:4c1e4e94cdd3 1240 if (send_detach(link, close, error) != 0)
AzureIoTClient 12:b30dacf113f2 1241 {
AzureIoTClient 41:0e723f9cbd89 1242 LogError("Sending detach frame failed");
AzureIoTClient 19:000ab4e6a2c1 1243 result = __FAILURE__;
AzureIoTClient 12:b30dacf113f2 1244 }
AzureIoTClient 12:b30dacf113f2 1245 else
AzureIoTClient 12:b30dacf113f2 1246 {
AzureIoTClient 12:b30dacf113f2 1247 set_link_state(link, LINK_STATE_DETACHED);
AzureIoTClient 12:b30dacf113f2 1248 result = 0;
AzureIoTClient 12:b30dacf113f2 1249 }
AzureIoTClient 12:b30dacf113f2 1250 break;
AzureIoTClient 12:b30dacf113f2 1251
AzureIoTClient 12:b30dacf113f2 1252 case LINK_STATE_ATTACHED:
AzureIoTClient 12:b30dacf113f2 1253 /* Send detach and wait for remote to respond */
AzureIoTClient 43:4c1e4e94cdd3 1254 if (send_detach(link, close, error) != 0)
AzureIoTClient 12:b30dacf113f2 1255 {
AzureIoTClient 41:0e723f9cbd89 1256 LogError("Sending detach frame failed");
AzureIoTClient 19:000ab4e6a2c1 1257 result = __FAILURE__;
AzureIoTClient 12:b30dacf113f2 1258 }
AzureIoTClient 12:b30dacf113f2 1259 else
AzureIoTClient 12:b30dacf113f2 1260 {
AzureIoTClient 24:2c59c2d43ebf 1261 set_link_state(link, LINK_STATE_HALF_ATTACHED_ATTACH_SENT);
AzureIoTClient 12:b30dacf113f2 1262 result = 0;
AzureIoTClient 12:b30dacf113f2 1263 }
AzureIoTClient 12:b30dacf113f2 1264 break;
AzureIoTClient 12:b30dacf113f2 1265
AzureIoTClient 12:b30dacf113f2 1266 case LINK_STATE_DETACHED:
AzureIoTClient 12:b30dacf113f2 1267 /* Already detached */
AzureIoTClient 12:b30dacf113f2 1268 result = 0;
AzureIoTClient 12:b30dacf113f2 1269 break;
AzureIoTClient 12:b30dacf113f2 1270
AzureIoTClient 12:b30dacf113f2 1271 default:
AzureIoTClient 12:b30dacf113f2 1272 case LINK_STATE_ERROR:
AzureIoTClient 12:b30dacf113f2 1273 /* Already detached and in error state */
AzureIoTClient 19:000ab4e6a2c1 1274 result = __FAILURE__;
AzureIoTClient 12:b30dacf113f2 1275 break;
AzureIoTClient 12:b30dacf113f2 1276 }
AzureIoTClient 43:4c1e4e94cdd3 1277
AzureIoTClient 43:4c1e4e94cdd3 1278 if (error != NULL)
AzureIoTClient 43:4c1e4e94cdd3 1279 {
AzureIoTClient 43:4c1e4e94cdd3 1280 error_destroy(error);
AzureIoTClient 43:4c1e4e94cdd3 1281 }
AzureIoTClient 28:add19eb7defa 1282 }
Azure.IoT Build 0:6ae2f7bca550 1283
AzureIoTClient 28:add19eb7defa 1284 return result;
Azure.IoT Build 0:6ae2f7bca550 1285 }
Azure.IoT Build 0:6ae2f7bca550 1286
AzureIoTClient 36:8e1d94b0a70c 1287 static bool remove_pending_delivery_condition_function(const void* item, const void* match_context, bool* continue_processing)
Azure.IoT Build 0:6ae2f7bca550 1288 {
AzureIoTClient 36:8e1d94b0a70c 1289 bool result;
AzureIoTClient 36:8e1d94b0a70c 1290
AzureIoTClient 36:8e1d94b0a70c 1291 if (item == match_context)
AzureIoTClient 36:8e1d94b0a70c 1292 {
AzureIoTClient 36:8e1d94b0a70c 1293 result = true;
AzureIoTClient 36:8e1d94b0a70c 1294 *continue_processing = false;
AzureIoTClient 36:8e1d94b0a70c 1295 }
AzureIoTClient 36:8e1d94b0a70c 1296 else
AzureIoTClient 36:8e1d94b0a70c 1297 {
AzureIoTClient 36:8e1d94b0a70c 1298 result = false;
AzureIoTClient 36:8e1d94b0a70c 1299 *continue_processing = true;
AzureIoTClient 36:8e1d94b0a70c 1300 }
AzureIoTClient 36:8e1d94b0a70c 1301
AzureIoTClient 36:8e1d94b0a70c 1302 return result;
AzureIoTClient 36:8e1d94b0a70c 1303 }
Azure.IoT Build 0:6ae2f7bca550 1304
AzureIoTClient 36:8e1d94b0a70c 1305 static void link_transfer_cancel_handler(ASYNC_OPERATION_HANDLE link_transfer_operation)
AzureIoTClient 36:8e1d94b0a70c 1306 {
AzureIoTClient 36:8e1d94b0a70c 1307 DELIVERY_INSTANCE* pending_delivery = GET_ASYNC_OPERATION_CONTEXT(DELIVERY_INSTANCE, link_transfer_operation);
AzureIoTClient 36:8e1d94b0a70c 1308 if (pending_delivery->on_delivery_settled != NULL)
AzureIoTClient 28:add19eb7defa 1309 {
AzureIoTClient 36:8e1d94b0a70c 1310 pending_delivery->on_delivery_settled(pending_delivery->callback_context, pending_delivery->delivery_id, LINK_DELIVERY_SETTLE_REASON_CANCELLED, NULL);
AzureIoTClient 36:8e1d94b0a70c 1311 }
AzureIoTClient 46:01f7ca900e07 1312
AzureIoTClient 36:8e1d94b0a70c 1313 (void)singlylinkedlist_remove_if(((LINK_HANDLE)pending_delivery->link)->pending_deliveries, remove_pending_delivery_condition_function, pending_delivery);
AzureIoTClient 37:c923ba7f6cf9 1314
AzureIoTClient 37:c923ba7f6cf9 1315 async_operation_destroy(link_transfer_operation);
AzureIoTClient 36:8e1d94b0a70c 1316 }
AzureIoTClient 36:8e1d94b0a70c 1317
AzureIoTClient 36:8e1d94b0a70c 1318 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 1319 {
AzureIoTClient 36:8e1d94b0a70c 1320 ASYNC_OPERATION_HANDLE result;
AzureIoTClient 36:8e1d94b0a70c 1321
AzureIoTClient 36:8e1d94b0a70c 1322 if ((link == NULL) ||
AzureIoTClient 36:8e1d94b0a70c 1323 (link_transfer_error == NULL))
AzureIoTClient 36:8e1d94b0a70c 1324 {
AzureIoTClient 36:8e1d94b0a70c 1325 if (link_transfer_error != NULL)
AzureIoTClient 36:8e1d94b0a70c 1326 {
AzureIoTClient 36:8e1d94b0a70c 1327 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1328 }
AzureIoTClient 36:8e1d94b0a70c 1329
AzureIoTClient 41:0e723f9cbd89 1330 LogError("Invalid arguments: link = %p, link_transfer_error = %p",
AzureIoTClient 41:0e723f9cbd89 1331 link, link_transfer_error);
AzureIoTClient 36:8e1d94b0a70c 1332 result = NULL;
AzureIoTClient 28:add19eb7defa 1333 }
AzureIoTClient 28:add19eb7defa 1334 else
AzureIoTClient 28:add19eb7defa 1335 {
AzureIoTClient 41:0e723f9cbd89 1336 if (link->role != role_sender)
AzureIoTClient 28:add19eb7defa 1337 {
AzureIoTClient 41:0e723f9cbd89 1338 LogError("Link is not a sender link");
AzureIoTClient 36:8e1d94b0a70c 1339 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1340 result = NULL;
AzureIoTClient 28:add19eb7defa 1341 }
AzureIoTClient 41:0e723f9cbd89 1342 else if (link->link_state != LINK_STATE_ATTACHED)
AzureIoTClient 41:0e723f9cbd89 1343 {
AzureIoTClient 41:0e723f9cbd89 1344 LogError("Link is not attached");
AzureIoTClient 41:0e723f9cbd89 1345 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 41:0e723f9cbd89 1346 result = NULL;
AzureIoTClient 41:0e723f9cbd89 1347 }
AzureIoTClient 41:0e723f9cbd89 1348 else if (link->current_link_credit == 0)
AzureIoTClient 28:add19eb7defa 1349 {
AzureIoTClient 36:8e1d94b0a70c 1350 *link_transfer_error = LINK_TRANSFER_BUSY;
AzureIoTClient 36:8e1d94b0a70c 1351 result = NULL;
AzureIoTClient 28:add19eb7defa 1352 }
AzureIoTClient 28:add19eb7defa 1353 else
AzureIoTClient 28:add19eb7defa 1354 {
AzureIoTClient 36:8e1d94b0a70c 1355 result = CREATE_ASYNC_OPERATION(DELIVERY_INSTANCE, link_transfer_cancel_handler);
AzureIoTClient 41:0e723f9cbd89 1356 if (result == NULL)
AzureIoTClient 41:0e723f9cbd89 1357 {
AzureIoTClient 41:0e723f9cbd89 1358 LogError("Error creating async operation");
AzureIoTClient 41:0e723f9cbd89 1359 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 41:0e723f9cbd89 1360 }
AzureIoTClient 41:0e723f9cbd89 1361 else
AzureIoTClient 28:add19eb7defa 1362 {
AzureIoTClient 36:8e1d94b0a70c 1363 TRANSFER_HANDLE transfer = transfer_create(0);
AzureIoTClient 36:8e1d94b0a70c 1364 if (transfer == NULL)
AzureIoTClient 28:add19eb7defa 1365 {
AzureIoTClient 41:0e723f9cbd89 1366 LogError("Error creating transfer");
AzureIoTClient 36:8e1d94b0a70c 1367 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1368 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1369 result = NULL;
AzureIoTClient 28:add19eb7defa 1370 }
AzureIoTClient 28:add19eb7defa 1371 else
AzureIoTClient 28:add19eb7defa 1372 {
AzureIoTClient 36:8e1d94b0a70c 1373 sequence_no delivery_count = link->delivery_count + 1;
AzureIoTClient 36:8e1d94b0a70c 1374 unsigned char delivery_tag_bytes[sizeof(delivery_count)];
AzureIoTClient 36:8e1d94b0a70c 1375 delivery_tag delivery_tag;
AzureIoTClient 36:8e1d94b0a70c 1376 bool settled;
AzureIoTClient 36:8e1d94b0a70c 1377
AzureIoTClient 36:8e1d94b0a70c 1378 (void)memcpy(delivery_tag_bytes, &delivery_count, sizeof(delivery_count));
AzureIoTClient 36:8e1d94b0a70c 1379
AzureIoTClient 36:8e1d94b0a70c 1380 delivery_tag.bytes = &delivery_tag_bytes;
AzureIoTClient 36:8e1d94b0a70c 1381 delivery_tag.length = sizeof(delivery_tag_bytes);
Azure.IoT Build 0:6ae2f7bca550 1382
AzureIoTClient 36:8e1d94b0a70c 1383 if (link->snd_settle_mode == sender_settle_mode_unsettled)
AzureIoTClient 36:8e1d94b0a70c 1384 {
AzureIoTClient 36:8e1d94b0a70c 1385 settled = false;
AzureIoTClient 36:8e1d94b0a70c 1386 }
AzureIoTClient 36:8e1d94b0a70c 1387 else
AzureIoTClient 36:8e1d94b0a70c 1388 {
AzureIoTClient 36:8e1d94b0a70c 1389 settled = true;
AzureIoTClient 36:8e1d94b0a70c 1390 }
Azure.IoT Build 0:6ae2f7bca550 1391
AzureIoTClient 41:0e723f9cbd89 1392 if (transfer_set_delivery_tag(transfer, delivery_tag) != 0)
AzureIoTClient 41:0e723f9cbd89 1393 {
AzureIoTClient 41:0e723f9cbd89 1394 LogError("Failed setting delivery tag");
AzureIoTClient 41:0e723f9cbd89 1395 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 41:0e723f9cbd89 1396 async_operation_destroy(result);
AzureIoTClient 41:0e723f9cbd89 1397 result = NULL;
AzureIoTClient 41:0e723f9cbd89 1398 }
AzureIoTClient 41:0e723f9cbd89 1399 else if (transfer_set_message_format(transfer, message_format) != 0)
AzureIoTClient 28:add19eb7defa 1400 {
AzureIoTClient 41:0e723f9cbd89 1401 LogError("Failed setting message format");
AzureIoTClient 41:0e723f9cbd89 1402 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 41:0e723f9cbd89 1403 async_operation_destroy(result);
AzureIoTClient 41:0e723f9cbd89 1404 result = NULL;
AzureIoTClient 41:0e723f9cbd89 1405 }
AzureIoTClient 41:0e723f9cbd89 1406 else if (transfer_set_settled(transfer, settled) != 0)
AzureIoTClient 41:0e723f9cbd89 1407 {
AzureIoTClient 41:0e723f9cbd89 1408 LogError("Failed setting settled flag");
AzureIoTClient 36:8e1d94b0a70c 1409 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1410 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1411 result = NULL;
AzureIoTClient 28:add19eb7defa 1412 }
AzureIoTClient 28:add19eb7defa 1413 else
AzureIoTClient 28:add19eb7defa 1414 {
AzureIoTClient 36:8e1d94b0a70c 1415 AMQP_VALUE transfer_value = amqpvalue_create_transfer(transfer);
AzureIoTClient 36:8e1d94b0a70c 1416 if (transfer_value == NULL)
AzureIoTClient 28:add19eb7defa 1417 {
AzureIoTClient 41:0e723f9cbd89 1418 LogError("Failed creating transfer performative AMQP value");
AzureIoTClient 36:8e1d94b0a70c 1419 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1420 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1421 result = NULL;
AzureIoTClient 28:add19eb7defa 1422 }
AzureIoTClient 28:add19eb7defa 1423 else
AzureIoTClient 28:add19eb7defa 1424 {
AzureIoTClient 36:8e1d94b0a70c 1425 DELIVERY_INSTANCE* pending_delivery = GET_ASYNC_OPERATION_CONTEXT(DELIVERY_INSTANCE, result);
AzureIoTClient 36:8e1d94b0a70c 1426 if (pending_delivery == NULL)
AzureIoTClient 28:add19eb7defa 1427 {
AzureIoTClient 41:0e723f9cbd89 1428 LogError("Failed getting pending delivery");
AzureIoTClient 36:8e1d94b0a70c 1429 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1430 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1431 result = NULL;
AzureIoTClient 28:add19eb7defa 1432 }
AzureIoTClient 28:add19eb7defa 1433 else
AzureIoTClient 28:add19eb7defa 1434 {
AzureIoTClient 36:8e1d94b0a70c 1435 if (tickcounter_get_current_ms(link->tick_counter, &pending_delivery->start_tick) != 0)
AzureIoTClient 28:add19eb7defa 1436 {
AzureIoTClient 41:0e723f9cbd89 1437 LogError("Failed getting current tick");
AzureIoTClient 36:8e1d94b0a70c 1438 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1439 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1440 result = NULL;
AzureIoTClient 34:6be9c2058664 1441 }
AzureIoTClient 34:6be9c2058664 1442 else
AzureIoTClient 34:6be9c2058664 1443 {
AzureIoTClient 36:8e1d94b0a70c 1444 LIST_ITEM_HANDLE delivery_instance_list_item;
AzureIoTClient 36:8e1d94b0a70c 1445 pending_delivery->timeout = timeout;
AzureIoTClient 36:8e1d94b0a70c 1446 pending_delivery->on_delivery_settled = on_delivery_settled;
AzureIoTClient 36:8e1d94b0a70c 1447 pending_delivery->callback_context = callback_context;
AzureIoTClient 36:8e1d94b0a70c 1448 pending_delivery->link = link;
AzureIoTClient 36:8e1d94b0a70c 1449 delivery_instance_list_item = singlylinkedlist_add(link->pending_deliveries, result);
Azure.IoT Build 0:6ae2f7bca550 1450
AzureIoTClient 36:8e1d94b0a70c 1451 if (delivery_instance_list_item == NULL)
AzureIoTClient 36:8e1d94b0a70c 1452 {
AzureIoTClient 41:0e723f9cbd89 1453 LogError("Failed adding delivery to list");
AzureIoTClient 36:8e1d94b0a70c 1454 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1455 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1456 result = NULL;
AzureIoTClient 36:8e1d94b0a70c 1457 }
AzureIoTClient 36:8e1d94b0a70c 1458 else
AzureIoTClient 36:8e1d94b0a70c 1459 {
AzureIoTClient 36:8e1d94b0a70c 1460 /* here we should feed data to the transfer frame */
AzureIoTClient 36:8e1d94b0a70c 1461 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 1462 {
AzureIoTClient 36:8e1d94b0a70c 1463 default:
AzureIoTClient 36:8e1d94b0a70c 1464 case SESSION_SEND_TRANSFER_ERROR:
AzureIoTClient 41:0e723f9cbd89 1465 LogError("Failed session send transfer");
AzureIoTClient 41:0e723f9cbd89 1466 if (singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item) != 0)
AzureIoTClient 41:0e723f9cbd89 1467 {
AzureIoTClient 41:0e723f9cbd89 1468 LogError("Error removing pending delivery from the list");
AzureIoTClient 41:0e723f9cbd89 1469 }
AzureIoTClient 41:0e723f9cbd89 1470
AzureIoTClient 36:8e1d94b0a70c 1471 *link_transfer_error = LINK_TRANSFER_ERROR;
AzureIoTClient 36:8e1d94b0a70c 1472 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1473 result = NULL;
AzureIoTClient 36:8e1d94b0a70c 1474 break;
Azure.IoT Build 0:6ae2f7bca550 1475
AzureIoTClient 36:8e1d94b0a70c 1476 case SESSION_SEND_TRANSFER_BUSY:
AzureIoTClient 36:8e1d94b0a70c 1477 /* Ensure we remove from list again since sender will attempt to transfer again on flow on */
AzureIoTClient 41:0e723f9cbd89 1478 LogError("Failed session send transfer");
AzureIoTClient 41:0e723f9cbd89 1479 if (singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item) != 0)
AzureIoTClient 41:0e723f9cbd89 1480 {
AzureIoTClient 41:0e723f9cbd89 1481 LogError("Error removing pending delivery from the list");
AzureIoTClient 41:0e723f9cbd89 1482 }
AzureIoTClient 41:0e723f9cbd89 1483
AzureIoTClient 36:8e1d94b0a70c 1484 *link_transfer_error = LINK_TRANSFER_BUSY;
AzureIoTClient 36:8e1d94b0a70c 1485 async_operation_destroy(result);
AzureIoTClient 36:8e1d94b0a70c 1486 result = NULL;
AzureIoTClient 36:8e1d94b0a70c 1487 break;
AzureIoTClient 36:8e1d94b0a70c 1488
AzureIoTClient 36:8e1d94b0a70c 1489 case SESSION_SEND_TRANSFER_OK:
AzureIoTClient 36:8e1d94b0a70c 1490 link->delivery_count = delivery_count;
AzureIoTClient 41:0e723f9cbd89 1491 link->current_link_credit--;
AzureIoTClient 36:8e1d94b0a70c 1492 break;
AzureIoTClient 36:8e1d94b0a70c 1493 }
AzureIoTClient 34:6be9c2058664 1494 }
AzureIoTClient 28:add19eb7defa 1495 }
AzureIoTClient 28:add19eb7defa 1496 }
AzureIoTClient 36:8e1d94b0a70c 1497
AzureIoTClient 36:8e1d94b0a70c 1498 amqpvalue_destroy(transfer_value);
AzureIoTClient 28:add19eb7defa 1499 }
AzureIoTClient 28:add19eb7defa 1500 }
AzureIoTClient 36:8e1d94b0a70c 1501
AzureIoTClient 36:8e1d94b0a70c 1502 transfer_destroy(transfer);
AzureIoTClient 28:add19eb7defa 1503 }
AzureIoTClient 28:add19eb7defa 1504 }
AzureIoTClient 28:add19eb7defa 1505 }
AzureIoTClient 28:add19eb7defa 1506 }
Azure.IoT Build 0:6ae2f7bca550 1507
AzureIoTClient 28:add19eb7defa 1508 return result;
Azure.IoT Build 0:6ae2f7bca550 1509 }
AzureIoTClient 20:206846c14c80 1510
AzureIoTClient 20:206846c14c80 1511 int link_get_name(LINK_HANDLE link, const char** link_name)
AzureIoTClient 20:206846c14c80 1512 {
AzureIoTClient 20:206846c14c80 1513 int result;
AzureIoTClient 20:206846c14c80 1514
AzureIoTClient 20:206846c14c80 1515 if (link == NULL)
AzureIoTClient 20:206846c14c80 1516 {
AzureIoTClient 41:0e723f9cbd89 1517 LogError("NULL link");
AzureIoTClient 20:206846c14c80 1518 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 1519 }
AzureIoTClient 20:206846c14c80 1520 else
AzureIoTClient 20:206846c14c80 1521 {
AzureIoTClient 20:206846c14c80 1522 *link_name = link->name;
AzureIoTClient 20:206846c14c80 1523 result = 0;
AzureIoTClient 20:206846c14c80 1524 }
AzureIoTClient 20:206846c14c80 1525
AzureIoTClient 20:206846c14c80 1526 return result;
AzureIoTClient 20:206846c14c80 1527 }
AzureIoTClient 20:206846c14c80 1528
AzureIoTClient 20:206846c14c80 1529 int link_get_received_message_id(LINK_HANDLE link, delivery_number* message_id)
AzureIoTClient 20:206846c14c80 1530 {
AzureIoTClient 20:206846c14c80 1531 int result;
AzureIoTClient 20:206846c14c80 1532
AzureIoTClient 20:206846c14c80 1533 if (link == NULL)
AzureIoTClient 20:206846c14c80 1534 {
AzureIoTClient 41:0e723f9cbd89 1535 LogError("NULL link");
AzureIoTClient 20:206846c14c80 1536 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 1537 }
AzureIoTClient 20:206846c14c80 1538 else
AzureIoTClient 20:206846c14c80 1539 {
AzureIoTClient 20:206846c14c80 1540 *message_id = link->received_delivery_id;
AzureIoTClient 20:206846c14c80 1541 result = 0;
AzureIoTClient 20:206846c14c80 1542 }
AzureIoTClient 20:206846c14c80 1543
AzureIoTClient 20:206846c14c80 1544 return result;
AzureIoTClient 20:206846c14c80 1545 }
AzureIoTClient 20:206846c14c80 1546
AzureIoTClient 20:206846c14c80 1547 int link_send_disposition(LINK_HANDLE link, delivery_number message_id, AMQP_VALUE delivery_state)
AzureIoTClient 20:206846c14c80 1548 {
AzureIoTClient 20:206846c14c80 1549 int result;
AzureIoTClient 41:0e723f9cbd89 1550
AzureIoTClient 20:206846c14c80 1551 if (delivery_state == NULL)
AzureIoTClient 20:206846c14c80 1552 {
AzureIoTClient 28:add19eb7defa 1553 result = 0;
AzureIoTClient 28:add19eb7defa 1554 }
AzureIoTClient 28:add19eb7defa 1555 else
AzureIoTClient 28:add19eb7defa 1556 {
AzureIoTClient 28:add19eb7defa 1557 result = send_disposition(link, message_id, delivery_state);
AzureIoTClient 41:0e723f9cbd89 1558 if (result != 0)
AzureIoTClient 20:206846c14c80 1559 {
AzureIoTClient 20:206846c14c80 1560 LogError("Cannot send disposition frame");
AzureIoTClient 28:add19eb7defa 1561 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 1562 }
AzureIoTClient 20:206846c14c80 1563 }
AzureIoTClient 41:0e723f9cbd89 1564
AzureIoTClient 20:206846c14c80 1565 return result;
AzureIoTClient 23:1111ee8bcba4 1566 }
AzureIoTClient 34:6be9c2058664 1567
AzureIoTClient 34:6be9c2058664 1568 void link_dowork(LINK_HANDLE link)
AzureIoTClient 34:6be9c2058664 1569 {
AzureIoTClient 41:0e723f9cbd89 1570 if (link == NULL)
AzureIoTClient 41:0e723f9cbd89 1571 {
AzureIoTClient 41:0e723f9cbd89 1572 LogError("NULL link");
AzureIoTClient 41:0e723f9cbd89 1573 }
AzureIoTClient 41:0e723f9cbd89 1574 else
AzureIoTClient 34:6be9c2058664 1575 {
AzureIoTClient 34:6be9c2058664 1576 tickcounter_ms_t current_tick;
AzureIoTClient 34:6be9c2058664 1577
AzureIoTClient 34:6be9c2058664 1578 if (tickcounter_get_current_ms(link->tick_counter, &current_tick) != 0)
AzureIoTClient 34:6be9c2058664 1579 {
AzureIoTClient 41:0e723f9cbd89 1580 LogError("Cannot get tick counter value");
AzureIoTClient 34:6be9c2058664 1581 }
AzureIoTClient 34:6be9c2058664 1582 else
AzureIoTClient 34:6be9c2058664 1583 {
AzureIoTClient 34:6be9c2058664 1584 // go through all and find timed out deliveries
AzureIoTClient 34:6be9c2058664 1585 LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(link->pending_deliveries);
AzureIoTClient 34:6be9c2058664 1586 while (item != NULL)
AzureIoTClient 34:6be9c2058664 1587 {
AzureIoTClient 34:6be9c2058664 1588 LIST_ITEM_HANDLE next_item = singlylinkedlist_get_next_item(item);
AzureIoTClient 36:8e1d94b0a70c 1589 ASYNC_OPERATION_HANDLE delivery_instance_async_operation = (ASYNC_OPERATION_HANDLE)singlylinkedlist_item_get_value(item);
AzureIoTClient 36:8e1d94b0a70c 1590 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)GET_ASYNC_OPERATION_CONTEXT(DELIVERY_INSTANCE, delivery_instance_async_operation);
AzureIoTClient 34:6be9c2058664 1591
AzureIoTClient 34:6be9c2058664 1592 if ((delivery_instance->timeout != 0) &&
AzureIoTClient 34:6be9c2058664 1593 (current_tick - delivery_instance->start_tick >= delivery_instance->timeout))
AzureIoTClient 34:6be9c2058664 1594 {
AzureIoTClient 34:6be9c2058664 1595 if (delivery_instance->on_delivery_settled != NULL)
AzureIoTClient 34:6be9c2058664 1596 {
AzureIoTClient 34:6be9c2058664 1597 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, LINK_DELIVERY_SETTLE_REASON_TIMEOUT, NULL);
AzureIoTClient 34:6be9c2058664 1598 }
AzureIoTClient 34:6be9c2058664 1599
AzureIoTClient 41:0e723f9cbd89 1600 if (singlylinkedlist_remove(link->pending_deliveries, item) != 0)
AzureIoTClient 41:0e723f9cbd89 1601 {
AzureIoTClient 41:0e723f9cbd89 1602 LogError("Cannot remove item from list");
AzureIoTClient 41:0e723f9cbd89 1603 }
AzureIoTClient 41:0e723f9cbd89 1604
AzureIoTClient 36:8e1d94b0a70c 1605 async_operation_destroy(delivery_instance_async_operation);
AzureIoTClient 34:6be9c2058664 1606 }
AzureIoTClient 34:6be9c2058664 1607
AzureIoTClient 34:6be9c2058664 1608 item = next_item;
AzureIoTClient 34:6be9c2058664 1609 }
AzureIoTClient 34:6be9c2058664 1610 }
AzureIoTClient 34:6be9c2058664 1611 }
AzureIoTClient 34:6be9c2058664 1612 }
AzureIoTClient 43:4c1e4e94cdd3 1613
AzureIoTClient 43:4c1e4e94cdd3 1614 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 1615 {
AzureIoTClient 43:4c1e4e94cdd3 1616 ON_LINK_DETACH_EVENT_SUBSCRIPTION_HANDLE result;
AzureIoTClient 43:4c1e4e94cdd3 1617
AzureIoTClient 43:4c1e4e94cdd3 1618 if ((link == NULL) ||
AzureIoTClient 43:4c1e4e94cdd3 1619 (on_link_detach_received == NULL))
AzureIoTClient 43:4c1e4e94cdd3 1620 {
AzureIoTClient 43:4c1e4e94cdd3 1621 LogError("Invalid arguments: link = %p, on_link_detach_received = %p, context = %p",
AzureIoTClient 43:4c1e4e94cdd3 1622 link, on_link_detach_received, context);
AzureIoTClient 43:4c1e4e94cdd3 1623 result = NULL;
AzureIoTClient 43:4c1e4e94cdd3 1624 }
AzureIoTClient 43:4c1e4e94cdd3 1625 else
AzureIoTClient 43:4c1e4e94cdd3 1626 {
AzureIoTClient 43:4c1e4e94cdd3 1627 if (link->on_link_detach_received_event_subscription.on_link_detach_received != NULL)
AzureIoTClient 43:4c1e4e94cdd3 1628 {
AzureIoTClient 43:4c1e4e94cdd3 1629 LogError("Already subscribed for on_link_detach_received events");
AzureIoTClient 43:4c1e4e94cdd3 1630 result = NULL;
AzureIoTClient 43:4c1e4e94cdd3 1631 }
AzureIoTClient 43:4c1e4e94cdd3 1632 else
AzureIoTClient 43:4c1e4e94cdd3 1633 {
AzureIoTClient 43:4c1e4e94cdd3 1634 link->on_link_detach_received_event_subscription.on_link_detach_received = on_link_detach_received;
AzureIoTClient 43:4c1e4e94cdd3 1635 link->on_link_detach_received_event_subscription.context = context;
AzureIoTClient 43:4c1e4e94cdd3 1636
AzureIoTClient 43:4c1e4e94cdd3 1637 result = &link->on_link_detach_received_event_subscription;
AzureIoTClient 43:4c1e4e94cdd3 1638 }
AzureIoTClient 43:4c1e4e94cdd3 1639 }
AzureIoTClient 43:4c1e4e94cdd3 1640
AzureIoTClient 43:4c1e4e94cdd3 1641 return result;
AzureIoTClient 43:4c1e4e94cdd3 1642 }
AzureIoTClient 43:4c1e4e94cdd3 1643
AzureIoTClient 43:4c1e4e94cdd3 1644 void link_unsubscribe_on_link_detach_received(ON_LINK_DETACH_EVENT_SUBSCRIPTION_HANDLE event_subscription)
AzureIoTClient 43:4c1e4e94cdd3 1645 {
AzureIoTClient 43:4c1e4e94cdd3 1646 if (event_subscription == NULL)
AzureIoTClient 43:4c1e4e94cdd3 1647 {
AzureIoTClient 43:4c1e4e94cdd3 1648 LogError("NULL event_subscription");
AzureIoTClient 43:4c1e4e94cdd3 1649 }
AzureIoTClient 43:4c1e4e94cdd3 1650 else
AzureIoTClient 43:4c1e4e94cdd3 1651 {
AzureIoTClient 43:4c1e4e94cdd3 1652 event_subscription->on_link_detach_received = NULL;
AzureIoTClient 43:4c1e4e94cdd3 1653 event_subscription->context = NULL;
AzureIoTClient 43:4c1e4e94cdd3 1654 }
AzureIoTClient 43:4c1e4e94cdd3 1655 }