A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Apr 21 14:50:32 2017 -0700
Revision:
23:1111ee8bcba4
Parent:
21:f9c433d8e6ca
Child:
24:2c59c2d43ebf
1.1.13

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