A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Jun 30 10:41:22 2017 -0700
Revision:
28:add19eb7defa
Parent:
27:d74f1cea23e1
Child:
29:4a11413cf217
1.1.18

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 {
AzureIoTClient 28:add19eb7defa 22 delivery_number delivery_id;
AzureIoTClient 28:add19eb7defa 23 ON_DELIVERY_SETTLED on_delivery_settled;
AzureIoTClient 28:add19eb7defa 24 void* callback_context;
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 30 SESSION_HANDLE session;
AzureIoTClient 28:add19eb7defa 31 LINK_STATE link_state;
AzureIoTClient 28:add19eb7defa 32 LINK_STATE previous_link_state;
AzureIoTClient 28:add19eb7defa 33 AMQP_VALUE source;
AzureIoTClient 28:add19eb7defa 34 AMQP_VALUE target;
AzureIoTClient 28:add19eb7defa 35 handle handle;
AzureIoTClient 28:add19eb7defa 36 LINK_ENDPOINT_HANDLE link_endpoint;
AzureIoTClient 28:add19eb7defa 37 char* name;
AzureIoTClient 28:add19eb7defa 38 SINGLYLINKEDLIST_HANDLE pending_deliveries;
AzureIoTClient 28:add19eb7defa 39 sequence_no delivery_count;
AzureIoTClient 28:add19eb7defa 40 role role;
AzureIoTClient 28:add19eb7defa 41 ON_LINK_STATE_CHANGED on_link_state_changed;
AzureIoTClient 28:add19eb7defa 42 ON_LINK_FLOW_ON on_link_flow_on;
Azure.IoT Build 0:6ae2f7bca550 43 ON_TRANSFER_RECEIVED on_transfer_received;
AzureIoTClient 28:add19eb7defa 44 void* callback_context;
AzureIoTClient 28:add19eb7defa 45 sender_settle_mode snd_settle_mode;
AzureIoTClient 28:add19eb7defa 46 receiver_settle_mode rcv_settle_mode;
AzureIoTClient 28:add19eb7defa 47 sequence_no initial_delivery_count;
AzureIoTClient 28:add19eb7defa 48 uint64_t max_message_size;
AzureIoTClient 28:add19eb7defa 49 uint64_t peer_max_message_size;
AzureIoTClient 28:add19eb7defa 50 uint32_t link_credit;
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 62 link_instance->previous_link_state = link_instance->link_state;
AzureIoTClient 28:add19eb7defa 63 link_instance->link_state = link_state;
Azure.IoT Build 0:6ae2f7bca550 64
AzureIoTClient 28:add19eb7defa 65 if (link_instance->on_link_state_changed != NULL)
AzureIoTClient 28:add19eb7defa 66 {
AzureIoTClient 28:add19eb7defa 67 link_instance->on_link_state_changed(link_instance->callback_context, link_state, link_instance->previous_link_state);
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 99 int result;
AzureIoTClient 28:add19eb7defa 100 FLOW_HANDLE flow = flow_create(0, 0, 0);
Azure.IoT Build 0:6ae2f7bca550 101
AzureIoTClient 28:add19eb7defa 102 if (flow == NULL)
AzureIoTClient 28:add19eb7defa 103 {
AzureIoTClient 28:add19eb7defa 104 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 105 }
AzureIoTClient 28:add19eb7defa 106 else
AzureIoTClient 28:add19eb7defa 107 {
AzureIoTClient 28:add19eb7defa 108 if ((flow_set_link_credit(flow, link->link_credit) != 0) ||
AzureIoTClient 28:add19eb7defa 109 (flow_set_handle(flow, link->handle) != 0) ||
AzureIoTClient 28:add19eb7defa 110 (flow_set_delivery_count(flow, link->delivery_count) != 0))
AzureIoTClient 28:add19eb7defa 111 {
AzureIoTClient 28:add19eb7defa 112 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 113 }
AzureIoTClient 28:add19eb7defa 114 else
AzureIoTClient 28:add19eb7defa 115 {
AzureIoTClient 28:add19eb7defa 116 if (session_send_flow(link->link_endpoint, flow) != 0)
AzureIoTClient 28:add19eb7defa 117 {
AzureIoTClient 28:add19eb7defa 118 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 119 }
AzureIoTClient 28:add19eb7defa 120 else
AzureIoTClient 28:add19eb7defa 121 {
AzureIoTClient 28:add19eb7defa 122 result = 0;
AzureIoTClient 28:add19eb7defa 123 }
AzureIoTClient 28:add19eb7defa 124 }
Azure.IoT Build 0:6ae2f7bca550 125
AzureIoTClient 28:add19eb7defa 126 flow_destroy(flow);
AzureIoTClient 28:add19eb7defa 127 }
Azure.IoT Build 0:6ae2f7bca550 128
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 134 int result;
Azure.IoT Build 0:6ae2f7bca550 135
AzureIoTClient 28:add19eb7defa 136 DISPOSITION_HANDLE disposition = disposition_create(link_instance->role, delivery_number);
AzureIoTClient 28:add19eb7defa 137 if (disposition == NULL)
AzureIoTClient 28:add19eb7defa 138 {
AzureIoTClient 28:add19eb7defa 139 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 140 }
AzureIoTClient 28:add19eb7defa 141 else
AzureIoTClient 28:add19eb7defa 142 {
AzureIoTClient 28:add19eb7defa 143 if ((disposition_set_last(disposition, delivery_number) != 0) ||
AzureIoTClient 28:add19eb7defa 144 (disposition_set_settled(disposition, true) != 0) ||
AzureIoTClient 28:add19eb7defa 145 ((delivery_state != NULL) && (disposition_set_state(disposition, delivery_state) != 0)))
AzureIoTClient 28:add19eb7defa 146 {
AzureIoTClient 28:add19eb7defa 147 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 148 }
AzureIoTClient 28:add19eb7defa 149 else
AzureIoTClient 28:add19eb7defa 150 {
AzureIoTClient 28:add19eb7defa 151 if (session_send_disposition(link_instance->link_endpoint, disposition) != 0)
AzureIoTClient 28:add19eb7defa 152 {
AzureIoTClient 28:add19eb7defa 153 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 154 }
AzureIoTClient 28:add19eb7defa 155 else
AzureIoTClient 28:add19eb7defa 156 {
AzureIoTClient 28:add19eb7defa 157 result = 0;
AzureIoTClient 28:add19eb7defa 158 }
AzureIoTClient 28:add19eb7defa 159 }
Azure.IoT Build 0:6ae2f7bca550 160
AzureIoTClient 28:add19eb7defa 161 disposition_destroy(disposition);
AzureIoTClient 28:add19eb7defa 162 }
Azure.IoT Build 0:6ae2f7bca550 163
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 169 int result;
AzureIoTClient 28:add19eb7defa 170 DETACH_HANDLE detach_performative;
Azure.IoT Build 0:6ae2f7bca550 171
AzureIoTClient 28:add19eb7defa 172 detach_performative = detach_create(0);
AzureIoTClient 28:add19eb7defa 173 if (detach_performative == NULL)
AzureIoTClient 28:add19eb7defa 174 {
AzureIoTClient 28:add19eb7defa 175 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 176 }
AzureIoTClient 28:add19eb7defa 177 else
AzureIoTClient 28:add19eb7defa 178 {
AzureIoTClient 28:add19eb7defa 179 if ((error_handle != NULL) &&
AzureIoTClient 28:add19eb7defa 180 (detach_set_error(detach_performative, error_handle) != 0))
AzureIoTClient 28:add19eb7defa 181 {
AzureIoTClient 28:add19eb7defa 182 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 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
AzureIoTClient 28:add19eb7defa 190 {
AzureIoTClient 28:add19eb7defa 191 if (session_send_detach(link_instance->link_endpoint, detach_performative) != 0)
AzureIoTClient 28:add19eb7defa 192 {
AzureIoTClient 28:add19eb7defa 193 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 194 }
AzureIoTClient 28:add19eb7defa 195 else
AzureIoTClient 28:add19eb7defa 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
AzureIoTClient 28:add19eb7defa 203 result = 0;
AzureIoTClient 28:add19eb7defa 204 }
AzureIoTClient 28:add19eb7defa 205 }
Azure.IoT Build 0:6ae2f7bca550 206
AzureIoTClient 28:add19eb7defa 207 detach_destroy(detach_performative);
AzureIoTClient 28:add19eb7defa 208 }
Azure.IoT Build 0:6ae2f7bca550 209
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 267 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 28:add19eb7defa 268 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(performative);
Azure.IoT Build 0:6ae2f7bca550 269
AzureIoTClient 28:add19eb7defa 270 if (is_attach_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 271 {
AzureIoTClient 28:add19eb7defa 272 ATTACH_HANDLE attach_handle;
AzureIoTClient 24:2c59c2d43ebf 273
AzureIoTClient 28:add19eb7defa 274 if (amqpvalue_get_attach(performative, &attach_handle) == 0)
AzureIoTClient 28:add19eb7defa 275 {
AzureIoTClient 28:add19eb7defa 276 if ((link_instance->role == role_receiver) &&
AzureIoTClient 28:add19eb7defa 277 (attach_get_initial_delivery_count(attach_handle, &link_instance->delivery_count) != 0))
AzureIoTClient 28:add19eb7defa 278 {
AzureIoTClient 28:add19eb7defa 279 /* error */
AzureIoTClient 28:add19eb7defa 280 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 28:add19eb7defa 281 }
AzureIoTClient 28:add19eb7defa 282 else
AzureIoTClient 28:add19eb7defa 283 {
AzureIoTClient 28:add19eb7defa 284 if (attach_get_max_message_size(attach_handle, &link_instance->peer_max_message_size) != 0)
AzureIoTClient 28:add19eb7defa 285 {
AzureIoTClient 28:add19eb7defa 286 LogError("Could not retrieve peer_max_message_size from attach frame");
AzureIoTClient 28:add19eb7defa 287 }
AzureIoTClient 24:2c59c2d43ebf 288
AzureIoTClient 28:add19eb7defa 289 if ((link_instance->link_state == LINK_STATE_DETACHED) ||
AzureIoTClient 28:add19eb7defa 290 (link_instance->link_state == LINK_STATE_HALF_ATTACHED_ATTACH_SENT))
AzureIoTClient 28:add19eb7defa 291 {
AzureIoTClient 28:add19eb7defa 292 if (link_instance->role == role_receiver)
AzureIoTClient 28:add19eb7defa 293 {
AzureIoTClient 28:add19eb7defa 294 link_instance->link_credit = DEFAULT_LINK_CREDIT;
AzureIoTClient 28:add19eb7defa 295 send_flow(link_instance);
AzureIoTClient 28:add19eb7defa 296 }
AzureIoTClient 28:add19eb7defa 297 else
AzureIoTClient 28:add19eb7defa 298 {
AzureIoTClient 28:add19eb7defa 299 link_instance->link_credit = 0;
AzureIoTClient 28:add19eb7defa 300 }
Azure.IoT Build 0:6ae2f7bca550 301
AzureIoTClient 28:add19eb7defa 302 if (link_instance->link_state == LINK_STATE_DETACHED)
AzureIoTClient 28:add19eb7defa 303 {
AzureIoTClient 28:add19eb7defa 304 set_link_state(link_instance, LINK_STATE_HALF_ATTACHED_ATTACH_RECEIVED);
AzureIoTClient 28:add19eb7defa 305 }
AzureIoTClient 28:add19eb7defa 306 else
AzureIoTClient 28:add19eb7defa 307 {
AzureIoTClient 28:add19eb7defa 308 set_link_state(link_instance, LINK_STATE_ATTACHED);
AzureIoTClient 28:add19eb7defa 309 }
AzureIoTClient 28:add19eb7defa 310 }
AzureIoTClient 28:add19eb7defa 311 }
Azure.IoT Build 0:6ae2f7bca550 312
AzureIoTClient 28:add19eb7defa 313 attach_destroy(attach_handle);
AzureIoTClient 28:add19eb7defa 314 }
AzureIoTClient 28:add19eb7defa 315 }
AzureIoTClient 28:add19eb7defa 316 else if (is_flow_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 317 {
AzureIoTClient 28:add19eb7defa 318 FLOW_HANDLE flow_handle;
AzureIoTClient 28:add19eb7defa 319 if (amqpvalue_get_flow(performative, &flow_handle) == 0)
AzureIoTClient 28:add19eb7defa 320 {
AzureIoTClient 28:add19eb7defa 321 if (link_instance->role == role_sender)
AzureIoTClient 28:add19eb7defa 322 {
AzureIoTClient 28:add19eb7defa 323 delivery_number rcv_delivery_count;
AzureIoTClient 28:add19eb7defa 324 uint32_t rcv_link_credit;
Azure.IoT Build 0:6ae2f7bca550 325
AzureIoTClient 28:add19eb7defa 326 if ((flow_get_link_credit(flow_handle, &rcv_link_credit) != 0) ||
AzureIoTClient 28:add19eb7defa 327 (flow_get_delivery_count(flow_handle, &rcv_delivery_count) != 0))
AzureIoTClient 28:add19eb7defa 328 {
AzureIoTClient 28:add19eb7defa 329 /* error */
AzureIoTClient 28:add19eb7defa 330 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 28:add19eb7defa 331 }
AzureIoTClient 28:add19eb7defa 332 else
AzureIoTClient 28:add19eb7defa 333 {
AzureIoTClient 28:add19eb7defa 334 link_instance->link_credit = rcv_delivery_count + rcv_link_credit - link_instance->delivery_count;
AzureIoTClient 28:add19eb7defa 335 if (link_instance->link_credit > 0)
AzureIoTClient 28:add19eb7defa 336 {
AzureIoTClient 28:add19eb7defa 337 link_instance->on_link_flow_on(link_instance->callback_context);
AzureIoTClient 28:add19eb7defa 338 }
AzureIoTClient 28:add19eb7defa 339 }
AzureIoTClient 28:add19eb7defa 340 }
AzureIoTClient 28:add19eb7defa 341 }
Azure.IoT Build 0:6ae2f7bca550 342
AzureIoTClient 28:add19eb7defa 343 flow_destroy(flow_handle);
AzureIoTClient 28:add19eb7defa 344 }
AzureIoTClient 28:add19eb7defa 345 else if (is_transfer_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 346 {
AzureIoTClient 28:add19eb7defa 347 if (link_instance->on_transfer_received != NULL)
AzureIoTClient 28:add19eb7defa 348 {
AzureIoTClient 28:add19eb7defa 349 TRANSFER_HANDLE transfer_handle;
AzureIoTClient 28:add19eb7defa 350 if (amqpvalue_get_transfer(performative, &transfer_handle) == 0)
AzureIoTClient 28:add19eb7defa 351 {
AzureIoTClient 28:add19eb7defa 352 AMQP_VALUE delivery_state;
AzureIoTClient 12:b30dacf113f2 353 bool more;
AzureIoTClient 28:add19eb7defa 354 bool is_error;
Azure.IoT Build 0:6ae2f7bca550 355
AzureIoTClient 28:add19eb7defa 356 link_instance->link_credit--;
AzureIoTClient 28:add19eb7defa 357 link_instance->delivery_count++;
AzureIoTClient 28:add19eb7defa 358 if (link_instance->link_credit == 0)
AzureIoTClient 28:add19eb7defa 359 {
AzureIoTClient 28:add19eb7defa 360 link_instance->link_credit = DEFAULT_LINK_CREDIT;
AzureIoTClient 28:add19eb7defa 361 send_flow(link_instance);
AzureIoTClient 28:add19eb7defa 362 }
Azure.IoT Build 0:6ae2f7bca550 363
AzureIoTClient 28:add19eb7defa 364 more = false;
AzureIoTClient 28:add19eb7defa 365 /* Attempt to get more flag, default to false */
AzureIoTClient 28:add19eb7defa 366 (void)transfer_get_more(transfer_handle, &more);
AzureIoTClient 28:add19eb7defa 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
AzureIoTClient 28:add19eb7defa 434 transfer_destroy(transfer_handle);
AzureIoTClient 28:add19eb7defa 435 }
AzureIoTClient 28:add19eb7defa 436 }
AzureIoTClient 28:add19eb7defa 437 }
AzureIoTClient 28:add19eb7defa 438 else if (is_disposition_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 439 {
AzureIoTClient 28:add19eb7defa 440 DISPOSITION_HANDLE disposition;
AzureIoTClient 28:add19eb7defa 441 if (amqpvalue_get_disposition(performative, &disposition) != 0)
AzureIoTClient 28:add19eb7defa 442 {
AzureIoTClient 28:add19eb7defa 443 /* error */
AzureIoTClient 28:add19eb7defa 444 }
AzureIoTClient 28:add19eb7defa 445 else
AzureIoTClient 28:add19eb7defa 446 {
AzureIoTClient 28:add19eb7defa 447 delivery_number first;
AzureIoTClient 28:add19eb7defa 448 delivery_number last;
Azure.IoT Build 0:6ae2f7bca550 449
AzureIoTClient 28:add19eb7defa 450 if (disposition_get_first(disposition, &first) != 0)
AzureIoTClient 28:add19eb7defa 451 {
AzureIoTClient 28:add19eb7defa 452 /* error */
AzureIoTClient 28:add19eb7defa 453 }
AzureIoTClient 28:add19eb7defa 454 else
AzureIoTClient 28:add19eb7defa 455 {
Azure.IoT Build 0:6ae2f7bca550 456 bool settled;
Azure.IoT Build 0:6ae2f7bca550 457
AzureIoTClient 28:add19eb7defa 458 if (disposition_get_last(disposition, &last) != 0)
AzureIoTClient 28:add19eb7defa 459 {
AzureIoTClient 28:add19eb7defa 460 last = first;
AzureIoTClient 28:add19eb7defa 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 }
AzureIoTClient 28:add19eb7defa 512 }
Azure.IoT Build 0:6ae2f7bca550 513
AzureIoTClient 28:add19eb7defa 514 disposition_destroy(disposition);
AzureIoTClient 28:add19eb7defa 515 }
AzureIoTClient 28:add19eb7defa 516 }
AzureIoTClient 28:add19eb7defa 517 else if (is_detach_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 565 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 566 (void)previous_session_state;
Azure.IoT Build 0:6ae2f7bca550 567
AzureIoTClient 28:add19eb7defa 568 if (new_session_state == SESSION_STATE_MAPPED)
AzureIoTClient 28:add19eb7defa 569 {
AzureIoTClient 28:add19eb7defa 570 if ((link_instance->link_state == LINK_STATE_DETACHED) && (!link_instance->is_closed))
AzureIoTClient 28:add19eb7defa 571 {
AzureIoTClient 28:add19eb7defa 572 if (send_attach(link_instance, link_instance->name, 0, link_instance->role) == 0)
AzureIoTClient 28:add19eb7defa 573 {
AzureIoTClient 28:add19eb7defa 574 set_link_state(link_instance, LINK_STATE_HALF_ATTACHED_ATTACH_SENT);
AzureIoTClient 28:add19eb7defa 575 }
AzureIoTClient 28:add19eb7defa 576 }
AzureIoTClient 28:add19eb7defa 577 }
AzureIoTClient 28:add19eb7defa 578 else if (new_session_state == SESSION_STATE_DISCARDING)
AzureIoTClient 28:add19eb7defa 579 {
AzureIoTClient 23:1111ee8bcba4 580 set_link_state(link_instance, LINK_STATE_DETACHED);
AzureIoTClient 23:1111ee8bcba4 581 remove_all_pending_deliveries(link_instance, true);
AzureIoTClient 28:add19eb7defa 582 }
AzureIoTClient 28:add19eb7defa 583 else if (new_session_state == SESSION_STATE_ERROR)
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 592 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)context;
AzureIoTClient 28:add19eb7defa 593 if (link_instance->role == role_sender)
AzureIoTClient 28:add19eb7defa 594 {
AzureIoTClient 28:add19eb7defa 595 link_instance->on_link_flow_on(link_instance->callback_context);
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 601 LIST_ITEM_HANDLE delivery_instance_list_item = (LIST_ITEM_HANDLE)context;
AzureIoTClient 28:add19eb7defa 602 DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(delivery_instance_list_item);
AzureIoTClient 28:add19eb7defa 603 LINK_INSTANCE* link_instance = (LINK_INSTANCE*)delivery_instance->link;
AzureIoTClient 6:641a9672db08 604 (void)send_result;
AzureIoTClient 28:add19eb7defa 605 if (link_instance->snd_settle_mode == sender_settle_mode_settled)
AzureIoTClient 28:add19eb7defa 606 {
AzureIoTClient 28:add19eb7defa 607 delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, LINK_DELIVERY_SETTLE_REASON_SETTLED, NULL);
AzureIoTClient 28:add19eb7defa 608 free(delivery_instance);
AzureIoTClient 28:add19eb7defa 609 (void)singlylinkedlist_remove(link_instance->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 615 LINK_INSTANCE* result = (LINK_INSTANCE*)malloc(sizeof(LINK_INSTANCE));
AzureIoTClient 28:add19eb7defa 616 if (result != NULL)
AzureIoTClient 28:add19eb7defa 617 {
AzureIoTClient 28:add19eb7defa 618 result->link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 619 result->previous_link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 620 result->role = role;
AzureIoTClient 28:add19eb7defa 621 result->source = amqpvalue_clone(source);
AzureIoTClient 28:add19eb7defa 622 result->target = amqpvalue_clone(target);
AzureIoTClient 28:add19eb7defa 623 result->session = session;
AzureIoTClient 28:add19eb7defa 624 result->handle = 0;
AzureIoTClient 28:add19eb7defa 625 result->snd_settle_mode = sender_settle_mode_unsettled;
AzureIoTClient 28:add19eb7defa 626 result->rcv_settle_mode = receiver_settle_mode_first;
AzureIoTClient 28:add19eb7defa 627 result->delivery_count = 0;
AzureIoTClient 28:add19eb7defa 628 result->initial_delivery_count = 0;
AzureIoTClient 28:add19eb7defa 629 result->max_message_size = 0;
AzureIoTClient 28:add19eb7defa 630 result->peer_max_message_size = 0;
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 638 result->pending_deliveries = singlylinkedlist_create();
AzureIoTClient 28:add19eb7defa 639 if (result->pending_deliveries == NULL)
AzureIoTClient 28:add19eb7defa 640 {
AzureIoTClient 28:add19eb7defa 641 free(result);
AzureIoTClient 28:add19eb7defa 642 result = NULL;
AzureIoTClient 28:add19eb7defa 643 }
AzureIoTClient 28:add19eb7defa 644 else
AzureIoTClient 28:add19eb7defa 645 {
AzureIoTClient 23:1111ee8bcba4 646 size_t name_length = strlen(name);
AzureIoTClient 28:add19eb7defa 647 result->name = (char*)malloc(name_length + 1);
AzureIoTClient 28:add19eb7defa 648 if (result->name == NULL)
AzureIoTClient 28:add19eb7defa 649 {
AzureIoTClient 28:add19eb7defa 650 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 28:add19eb7defa 651 free(result);
AzureIoTClient 28:add19eb7defa 652 result = NULL;
AzureIoTClient 28:add19eb7defa 653 }
AzureIoTClient 28:add19eb7defa 654 else
AzureIoTClient 28:add19eb7defa 655 {
AzureIoTClient 28:add19eb7defa 656 result->on_link_state_changed = NULL;
AzureIoTClient 28:add19eb7defa 657 result->callback_context = NULL;
AzureIoTClient 28:add19eb7defa 658 set_link_state(result, LINK_STATE_DETACHED);
Azure.IoT Build 0:6ae2f7bca550 659
AzureIoTClient 28:add19eb7defa 660 (void)memcpy(result->name, name, name_length + 1);
AzureIoTClient 28:add19eb7defa 661 result->link_endpoint = session_create_link_endpoint(session, name);
AzureIoTClient 28:add19eb7defa 662 if (result->link_endpoint == NULL)
AzureIoTClient 28:add19eb7defa 663 {
AzureIoTClient 28:add19eb7defa 664 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 28:add19eb7defa 665 free(result->name);
AzureIoTClient 28:add19eb7defa 666 free(result);
AzureIoTClient 28:add19eb7defa 667 result = NULL;
AzureIoTClient 28:add19eb7defa 668 }
AzureIoTClient 28:add19eb7defa 669 }
AzureIoTClient 28:add19eb7defa 670 }
AzureIoTClient 28:add19eb7defa 671 }
Azure.IoT Build 0:6ae2f7bca550 672
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 678 LINK_INSTANCE* result = (LINK_INSTANCE*)malloc(sizeof(LINK_INSTANCE));
AzureIoTClient 28:add19eb7defa 679 if (result != NULL)
AzureIoTClient 28:add19eb7defa 680 {
AzureIoTClient 28:add19eb7defa 681 result->link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 682 result->previous_link_state = LINK_STATE_DETACHED;
AzureIoTClient 28:add19eb7defa 683 result->session = session;
AzureIoTClient 28:add19eb7defa 684 result->handle = 0;
AzureIoTClient 28:add19eb7defa 685 result->snd_settle_mode = sender_settle_mode_unsettled;
AzureIoTClient 28:add19eb7defa 686 result->rcv_settle_mode = receiver_settle_mode_first;
AzureIoTClient 28:add19eb7defa 687 result->delivery_count = 0;
AzureIoTClient 28:add19eb7defa 688 result->initial_delivery_count = 0;
AzureIoTClient 28:add19eb7defa 689 result->max_message_size = 0;
AzureIoTClient 28:add19eb7defa 690 result->peer_max_message_size = 0;
AzureIoTClient 28:add19eb7defa 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);
AzureIoTClient 28:add19eb7defa 698 result->target = amqpvalue_clone(source);
AzureIoTClient 28:add19eb7defa 699 if (role == role_sender)
AzureIoTClient 28:add19eb7defa 700 {
AzureIoTClient 28:add19eb7defa 701 result->role = role_receiver;
AzureIoTClient 28:add19eb7defa 702 }
AzureIoTClient 28:add19eb7defa 703 else
AzureIoTClient 28:add19eb7defa 704 {
AzureIoTClient 28:add19eb7defa 705 result->role = role_sender;
AzureIoTClient 28:add19eb7defa 706 }
Azure.IoT Build 0:6ae2f7bca550 707
AzureIoTClient 28:add19eb7defa 708 result->pending_deliveries = singlylinkedlist_create();
AzureIoTClient 28:add19eb7defa 709 if (result->pending_deliveries == NULL)
AzureIoTClient 28:add19eb7defa 710 {
AzureIoTClient 28:add19eb7defa 711 free(result);
AzureIoTClient 28:add19eb7defa 712 result = NULL;
AzureIoTClient 28:add19eb7defa 713 }
AzureIoTClient 28:add19eb7defa 714 else
AzureIoTClient 28:add19eb7defa 715 {
AzureIoTClient 23:1111ee8bcba4 716 size_t name_length = strlen(name);
AzureIoTClient 28:add19eb7defa 717 result->name = (char*)malloc(name_length + 1);
AzureIoTClient 28:add19eb7defa 718 if (result->name == NULL)
AzureIoTClient 28:add19eb7defa 719 {
AzureIoTClient 28:add19eb7defa 720 singlylinkedlist_destroy(result->pending_deliveries);
AzureIoTClient 28:add19eb7defa 721 free(result);
AzureIoTClient 28:add19eb7defa 722 result = NULL;
AzureIoTClient 28:add19eb7defa 723 }
AzureIoTClient 28:add19eb7defa 724 else
AzureIoTClient 28:add19eb7defa 725 {
AzureIoTClient 28:add19eb7defa 726 (void)memcpy(result->name, name, name_length + 1);
AzureIoTClient 28:add19eb7defa 727 result->on_link_state_changed = NULL;
AzureIoTClient 28:add19eb7defa 728 result->callback_context = NULL;
AzureIoTClient 28:add19eb7defa 729 result->link_endpoint = link_endpoint;
AzureIoTClient 28:add19eb7defa 730 }
AzureIoTClient 28:add19eb7defa 731 }
AzureIoTClient 28:add19eb7defa 732 }
Azure.IoT Build 0:6ae2f7bca550 733
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 739 if (link != NULL)
AzureIoTClient 28:add19eb7defa 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);
AzureIoTClient 28:add19eb7defa 746 amqpvalue_destroy(link->source);
AzureIoTClient 28:add19eb7defa 747 amqpvalue_destroy(link->target);
Azure.IoT Build 0:6ae2f7bca550 748
AzureIoTClient 28:add19eb7defa 749 if (link->name != NULL)
AzureIoTClient 28:add19eb7defa 750 {
AzureIoTClient 28:add19eb7defa 751 free(link->name);
AzureIoTClient 28:add19eb7defa 752 }
Azure.IoT Build 0:6ae2f7bca550 753
AzureIoTClient 28:add19eb7defa 754 if (link->attach_properties != NULL)
Azure.IoT Build 0:6ae2f7bca550 755 {
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 764 free(link);
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 770 int result;
Azure.IoT Build 0:6ae2f7bca550 771
AzureIoTClient 28:add19eb7defa 772 if (link == NULL)
AzureIoTClient 28:add19eb7defa 773 {
AzureIoTClient 28:add19eb7defa 774 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 775 }
AzureIoTClient 28:add19eb7defa 776 else
AzureIoTClient 28:add19eb7defa 777 {
AzureIoTClient 28:add19eb7defa 778 link->snd_settle_mode = snd_settle_mode;
AzureIoTClient 28:add19eb7defa 779 result = 0;
AzureIoTClient 28:add19eb7defa 780 }
Azure.IoT Build 0:6ae2f7bca550 781
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 787 int result;
Azure.IoT Build 0:6ae2f7bca550 788
AzureIoTClient 28:add19eb7defa 789 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 790 (snd_settle_mode == NULL))
AzureIoTClient 28:add19eb7defa 791 {
AzureIoTClient 28:add19eb7defa 792 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 793 }
AzureIoTClient 28:add19eb7defa 794 else
AzureIoTClient 28:add19eb7defa 795 {
AzureIoTClient 28:add19eb7defa 796 *snd_settle_mode = link->snd_settle_mode;
Azure.IoT Build 0:6ae2f7bca550 797
AzureIoTClient 28:add19eb7defa 798 result = 0;
AzureIoTClient 28:add19eb7defa 799 }
Azure.IoT Build 0:6ae2f7bca550 800
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 806 int result;
Azure.IoT Build 0:6ae2f7bca550 807
AzureIoTClient 28:add19eb7defa 808 if (link == NULL)
AzureIoTClient 28:add19eb7defa 809 {
AzureIoTClient 28:add19eb7defa 810 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 811 }
AzureIoTClient 28:add19eb7defa 812 else
AzureIoTClient 28:add19eb7defa 813 {
AzureIoTClient 28:add19eb7defa 814 link->rcv_settle_mode = rcv_settle_mode;
AzureIoTClient 28:add19eb7defa 815 result = 0;
AzureIoTClient 28:add19eb7defa 816 }
Azure.IoT Build 0:6ae2f7bca550 817
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 823 int result;
Azure.IoT Build 0:6ae2f7bca550 824
AzureIoTClient 28:add19eb7defa 825 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 826 (rcv_settle_mode == NULL))
AzureIoTClient 28:add19eb7defa 827 {
AzureIoTClient 28:add19eb7defa 828 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 829 }
AzureIoTClient 28:add19eb7defa 830 else
AzureIoTClient 28:add19eb7defa 831 {
AzureIoTClient 28:add19eb7defa 832 *rcv_settle_mode = link->rcv_settle_mode;
AzureIoTClient 28:add19eb7defa 833 result = 0;
AzureIoTClient 28:add19eb7defa 834 }
Azure.IoT Build 0:6ae2f7bca550 835
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 841 int result;
Azure.IoT Build 0:6ae2f7bca550 842
AzureIoTClient 28:add19eb7defa 843 if (link == NULL)
AzureIoTClient 28:add19eb7defa 844 {
AzureIoTClient 28:add19eb7defa 845 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 846 }
AzureIoTClient 28:add19eb7defa 847 else
AzureIoTClient 28:add19eb7defa 848 {
AzureIoTClient 28:add19eb7defa 849 link->initial_delivery_count = initial_delivery_count;
AzureIoTClient 28:add19eb7defa 850 result = 0;
AzureIoTClient 28:add19eb7defa 851 }
Azure.IoT Build 0:6ae2f7bca550 852
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 858 int result;
Azure.IoT Build 0:6ae2f7bca550 859
AzureIoTClient 28:add19eb7defa 860 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 861 (initial_delivery_count == NULL))
AzureIoTClient 28:add19eb7defa 862 {
AzureIoTClient 28:add19eb7defa 863 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 864 }
AzureIoTClient 28:add19eb7defa 865 else
AzureIoTClient 28:add19eb7defa 866 {
AzureIoTClient 28:add19eb7defa 867 *initial_delivery_count = link->initial_delivery_count;
AzureIoTClient 28:add19eb7defa 868 result = 0;
AzureIoTClient 28:add19eb7defa 869 }
Azure.IoT Build 0:6ae2f7bca550 870
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 876 int result;
Azure.IoT Build 0:6ae2f7bca550 877
AzureIoTClient 28:add19eb7defa 878 if (link == NULL)
AzureIoTClient 28:add19eb7defa 879 {
AzureIoTClient 28:add19eb7defa 880 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 881 }
AzureIoTClient 28:add19eb7defa 882 else
AzureIoTClient 28:add19eb7defa 883 {
AzureIoTClient 28:add19eb7defa 884 link->max_message_size = max_message_size;
AzureIoTClient 28:add19eb7defa 885 result = 0;
AzureIoTClient 28:add19eb7defa 886 }
Azure.IoT Build 0:6ae2f7bca550 887
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 893 int result;
Azure.IoT Build 0:6ae2f7bca550 894
AzureIoTClient 28:add19eb7defa 895 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 896 (max_message_size == NULL))
AzureIoTClient 28:add19eb7defa 897 {
AzureIoTClient 28:add19eb7defa 898 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 899 }
AzureIoTClient 28:add19eb7defa 900 else
AzureIoTClient 28:add19eb7defa 901 {
AzureIoTClient 28:add19eb7defa 902 *max_message_size = link->max_message_size;
AzureIoTClient 28:add19eb7defa 903 result = 0;
AzureIoTClient 28:add19eb7defa 904 }
Azure.IoT Build 0:6ae2f7bca550 905
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 911 int result;
AzureIoTClient 24:2c59c2d43ebf 912
AzureIoTClient 28:add19eb7defa 913 if ((link == NULL) ||
AzureIoTClient 28:add19eb7defa 914 (peer_max_message_size == NULL))
AzureIoTClient 28:add19eb7defa 915 {
AzureIoTClient 28:add19eb7defa 916 LogError("Bad arguments: link = %p, peer_max_message_size = %p",
AzureIoTClient 28:add19eb7defa 917 link, peer_max_message_size);
AzureIoTClient 28:add19eb7defa 918 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 919 }
AzureIoTClient 28:add19eb7defa 920 else if ((link->link_state != LINK_STATE_ATTACHED) &&
AzureIoTClient 28:add19eb7defa 921 (link->link_state != LINK_STATE_HALF_ATTACHED_ATTACH_RECEIVED))
AzureIoTClient 28:add19eb7defa 922 {
AzureIoTClient 28:add19eb7defa 923 LogError("Attempting to read peer max message size before it was received");
AzureIoTClient 28:add19eb7defa 924 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 925 }
AzureIoTClient 28:add19eb7defa 926 else
AzureIoTClient 28:add19eb7defa 927 {
AzureIoTClient 28:add19eb7defa 928 *peer_max_message_size = link->peer_max_message_size;
AzureIoTClient 28:add19eb7defa 929 result = 0;
AzureIoTClient 28:add19eb7defa 930 }
AzureIoTClient 24:2c59c2d43ebf 931
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 961 int result;
Azure.IoT Build 0:6ae2f7bca550 962
AzureIoTClient 28:add19eb7defa 963 if ((link == NULL) ||
AzureIoTClient 12:b30dacf113f2 964 (link->is_closed))
AzureIoTClient 28:add19eb7defa 965 {
AzureIoTClient 28:add19eb7defa 966 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 967 }
AzureIoTClient 28:add19eb7defa 968 else
AzureIoTClient 28:add19eb7defa 969 {
AzureIoTClient 28:add19eb7defa 970 if (!link->is_underlying_session_begun)
AzureIoTClient 28:add19eb7defa 971 {
AzureIoTClient 28:add19eb7defa 972 link->on_link_state_changed = on_link_state_changed;
AzureIoTClient 28:add19eb7defa 973 link->on_transfer_received = on_transfer_received;
AzureIoTClient 28:add19eb7defa 974 link->on_link_flow_on = on_link_flow_on;
AzureIoTClient 28:add19eb7defa 975 link->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 976
AzureIoTClient 28:add19eb7defa 977 if (session_begin(link->session) != 0)
AzureIoTClient 28:add19eb7defa 978 {
AzureIoTClient 28:add19eb7defa 979 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 980 }
AzureIoTClient 28:add19eb7defa 981 else
AzureIoTClient 28:add19eb7defa 982 {
AzureIoTClient 28:add19eb7defa 983 link->is_underlying_session_begun = true;
Azure.IoT Build 0:6ae2f7bca550 984
AzureIoTClient 28:add19eb7defa 985 if (session_start_link_endpoint(link->link_endpoint, link_frame_received, on_session_state_changed, on_session_flow_on, link) != 0)
AzureIoTClient 28:add19eb7defa 986 {
AzureIoTClient 28:add19eb7defa 987 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 988 }
AzureIoTClient 28:add19eb7defa 989 else
AzureIoTClient 28:add19eb7defa 990 {
AzureIoTClient 12:b30dacf113f2 991 link->received_payload_size = 0;
AzureIoTClient 12:b30dacf113f2 992
AzureIoTClient 28:add19eb7defa 993 result = 0;
AzureIoTClient 28:add19eb7defa 994 }
AzureIoTClient 28:add19eb7defa 995 }
AzureIoTClient 28:add19eb7defa 996 }
AzureIoTClient 28:add19eb7defa 997 else
AzureIoTClient 28:add19eb7defa 998 {
AzureIoTClient 28:add19eb7defa 999 result = 0;
AzureIoTClient 28:add19eb7defa 1000 }
AzureIoTClient 28:add19eb7defa 1001 }
Azure.IoT Build 0:6ae2f7bca550 1002
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 1013 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 1014 }
AzureIoTClient 28:add19eb7defa 1015 else
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 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 }
AzureIoTClient 28:add19eb7defa 1057 }
Azure.IoT Build 0:6ae2f7bca550 1058
AzureIoTClient 28:add19eb7defa 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 {
AzureIoTClient 28:add19eb7defa 1064 LINK_TRANSFER_RESULT result;
Azure.IoT Build 0:6ae2f7bca550 1065
AzureIoTClient 28:add19eb7defa 1066 if (link == NULL)
AzureIoTClient 28:add19eb7defa 1067 {
AzureIoTClient 28:add19eb7defa 1068 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1069 }
AzureIoTClient 28:add19eb7defa 1070 else
AzureIoTClient 28:add19eb7defa 1071 {
AzureIoTClient 28:add19eb7defa 1072 if ((link->role != role_sender) ||
AzureIoTClient 28:add19eb7defa 1073 (link->link_state != LINK_STATE_ATTACHED))
AzureIoTClient 28:add19eb7defa 1074 {
AzureIoTClient 28:add19eb7defa 1075 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1076 }
AzureIoTClient 28:add19eb7defa 1077 else if (link->link_credit == 0)
AzureIoTClient 28:add19eb7defa 1078 {
AzureIoTClient 28:add19eb7defa 1079 result = LINK_TRANSFER_BUSY;
AzureIoTClient 28:add19eb7defa 1080 }
AzureIoTClient 28:add19eb7defa 1081 else
AzureIoTClient 28:add19eb7defa 1082 {
AzureIoTClient 28:add19eb7defa 1083 TRANSFER_HANDLE transfer = transfer_create(0);
AzureIoTClient 28:add19eb7defa 1084 if (transfer == NULL)
AzureIoTClient 28:add19eb7defa 1085 {
AzureIoTClient 28:add19eb7defa 1086 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1087 }
AzureIoTClient 28:add19eb7defa 1088 else
AzureIoTClient 28:add19eb7defa 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)];
AzureIoTClient 28:add19eb7defa 1092 delivery_tag delivery_tag;
AzureIoTClient 28:add19eb7defa 1093 bool settled;
Azure.IoT Build 0:6ae2f7bca550 1094
AzureIoTClient 28:add19eb7defa 1095 (void)memcpy(delivery_tag_bytes, &delivery_count, sizeof(delivery_count));
Azure.IoT Build 0:6ae2f7bca550 1096
AzureIoTClient 28:add19eb7defa 1097 delivery_tag.bytes = &delivery_tag_bytes;
AzureIoTClient 28:add19eb7defa 1098 delivery_tag.length = sizeof(delivery_tag_bytes);
Azure.IoT Build 0:6ae2f7bca550 1099
AzureIoTClient 28:add19eb7defa 1100 if (link->snd_settle_mode == sender_settle_mode_unsettled)
AzureIoTClient 28:add19eb7defa 1101 {
AzureIoTClient 28:add19eb7defa 1102 settled = false;
AzureIoTClient 28:add19eb7defa 1103 }
AzureIoTClient 28:add19eb7defa 1104 else
AzureIoTClient 28:add19eb7defa 1105 {
AzureIoTClient 28:add19eb7defa 1106 settled = true;
AzureIoTClient 28:add19eb7defa 1107 }
Azure.IoT Build 0:6ae2f7bca550 1108
AzureIoTClient 28:add19eb7defa 1109 if ((transfer_set_delivery_tag(transfer, delivery_tag) != 0) ||
AzureIoTClient 28:add19eb7defa 1110 (transfer_set_message_format(transfer, message_format) != 0) ||
AzureIoTClient 28:add19eb7defa 1111 (transfer_set_settled(transfer, settled) != 0))
AzureIoTClient 28:add19eb7defa 1112 {
AzureIoTClient 28:add19eb7defa 1113 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1114 }
AzureIoTClient 28:add19eb7defa 1115 else
AzureIoTClient 28:add19eb7defa 1116 {
AzureIoTClient 28:add19eb7defa 1117 AMQP_VALUE transfer_value = amqpvalue_create_transfer(transfer);
Azure.IoT Build 0:6ae2f7bca550 1118
AzureIoTClient 28:add19eb7defa 1119 if (transfer_value == NULL)
AzureIoTClient 28:add19eb7defa 1120 {
AzureIoTClient 28:add19eb7defa 1121 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1122 }
AzureIoTClient 28:add19eb7defa 1123 else
AzureIoTClient 28:add19eb7defa 1124 {
AzureIoTClient 28:add19eb7defa 1125 DELIVERY_INSTANCE* pending_delivery = (DELIVERY_INSTANCE*)malloc(sizeof(DELIVERY_INSTANCE));
AzureIoTClient 28:add19eb7defa 1126 if (pending_delivery == NULL)
AzureIoTClient 28:add19eb7defa 1127 {
AzureIoTClient 28:add19eb7defa 1128 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1129 }
AzureIoTClient 28:add19eb7defa 1130 else
AzureIoTClient 28:add19eb7defa 1131 {
AzureIoTClient 28:add19eb7defa 1132 LIST_ITEM_HANDLE delivery_instance_list_item;
AzureIoTClient 28:add19eb7defa 1133 pending_delivery->on_delivery_settled = on_delivery_settled;
AzureIoTClient 28:add19eb7defa 1134 pending_delivery->callback_context = callback_context;
AzureIoTClient 28:add19eb7defa 1135 pending_delivery->link = link;
AzureIoTClient 28:add19eb7defa 1136 delivery_instance_list_item = singlylinkedlist_add(link->pending_deliveries, pending_delivery);
Azure.IoT Build 0:6ae2f7bca550 1137
AzureIoTClient 28:add19eb7defa 1138 if (delivery_instance_list_item == NULL)
AzureIoTClient 28:add19eb7defa 1139 {
AzureIoTClient 28:add19eb7defa 1140 free(pending_delivery);
AzureIoTClient 28:add19eb7defa 1141 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1142 }
AzureIoTClient 28:add19eb7defa 1143 else
AzureIoTClient 28:add19eb7defa 1144 {
AzureIoTClient 28:add19eb7defa 1145 /* here we should feed data to the transfer frame */
AzureIoTClient 28:add19eb7defa 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))
AzureIoTClient 28:add19eb7defa 1147 {
AzureIoTClient 28:add19eb7defa 1148 default:
AzureIoTClient 28:add19eb7defa 1149 case SESSION_SEND_TRANSFER_ERROR:
AzureIoTClient 28:add19eb7defa 1150 singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 28:add19eb7defa 1151 free(pending_delivery);
AzureIoTClient 28:add19eb7defa 1152 result = LINK_TRANSFER_ERROR;
AzureIoTClient 28:add19eb7defa 1153 break;
Azure.IoT Build 0:6ae2f7bca550 1154
AzureIoTClient 28:add19eb7defa 1155 case SESSION_SEND_TRANSFER_BUSY:
AzureIoTClient 28:add19eb7defa 1156 /* Ensure we remove from list again since sender will attempt to transfer again on flow on */
AzureIoTClient 28:add19eb7defa 1157 singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
AzureIoTClient 28:add19eb7defa 1158 free(pending_delivery);
AzureIoTClient 28:add19eb7defa 1159 result = LINK_TRANSFER_BUSY;
AzureIoTClient 28:add19eb7defa 1160 break;
Azure.IoT Build 0:6ae2f7bca550 1161
AzureIoTClient 28:add19eb7defa 1162 case SESSION_SEND_TRANSFER_OK:
AzureIoTClient 28:add19eb7defa 1163 link->delivery_count = delivery_count;
AzureIoTClient 28:add19eb7defa 1164 link->link_credit--;
AzureIoTClient 28:add19eb7defa 1165 result = LINK_TRANSFER_OK;
AzureIoTClient 28:add19eb7defa 1166 break;
AzureIoTClient 28:add19eb7defa 1167 }
AzureIoTClient 28:add19eb7defa 1168 }
AzureIoTClient 28:add19eb7defa 1169 }
Azure.IoT Build 0:6ae2f7bca550 1170
AzureIoTClient 28:add19eb7defa 1171 amqpvalue_destroy(transfer_value);
AzureIoTClient 28:add19eb7defa 1172 }
AzureIoTClient 28:add19eb7defa 1173 }
Azure.IoT Build 0:6ae2f7bca550 1174
AzureIoTClient 28:add19eb7defa 1175 transfer_destroy(transfer);
AzureIoTClient 28:add19eb7defa 1176 }
AzureIoTClient 28:add19eb7defa 1177 }
AzureIoTClient 28:add19eb7defa 1178 }
Azure.IoT Build 0:6ae2f7bca550 1179
AzureIoTClient 28:add19eb7defa 1180 return result;
Azure.IoT Build 0:6ae2f7bca550 1181 }
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 28:add19eb7defa 1222 result = 0;
AzureIoTClient 28:add19eb7defa 1223 }
AzureIoTClient 28:add19eb7defa 1224 else
AzureIoTClient 28:add19eb7defa 1225 {
AzureIoTClient 28:add19eb7defa 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 28:add19eb7defa 1230 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 1231 }
AzureIoTClient 20:206846c14c80 1232 }
AzureIoTClient 20:206846c14c80 1233 return result;
AzureIoTClient 23:1111ee8bcba4 1234 }