A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Jun 02 15:53:07 2017 -0700
Revision:
27:d74f1cea23e1
Parent:
24:2c59c2d43ebf
Child:
28:add19eb7defa
1.1.16

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