A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Feb 24 14:00:58 2017 -0800
Revision:
19:000ab4e6a2c1
Parent:
18:a922a4a30a82
Child:
20:206846c14c80
1.1.8

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>
AzureIoTClient 6:641a9672db08 5 #include <stdbool.h>
Azure.IoT Build 0:6ae2f7bca550 6 #include <string.h>
AzureIoTClient 19:000ab4e6a2c1 7 #include "azure_c_shared_utility/optimize_size.h"
Azure.IoT Build 5:ae49385aff34 8 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 0:6ae2f7bca550 9 #include "azure_uamqp_c/message_sender.h"
Azure.IoT Build 0:6ae2f7bca550 10 #include "azure_uamqp_c/amqpalloc.h"
Azure.IoT Build 0:6ae2f7bca550 11 #include "azure_uamqp_c/amqpvalue_to_string.h"
Azure.IoT Build 0:6ae2f7bca550 12
Azure.IoT Build 0:6ae2f7bca550 13 typedef enum MESSAGE_SEND_STATE_TAG
Azure.IoT Build 0:6ae2f7bca550 14 {
AzureIoTClient 6:641a9672db08 15 MESSAGE_SEND_STATE_NOT_SENT,
AzureIoTClient 6:641a9672db08 16 MESSAGE_SEND_STATE_PENDING
Azure.IoT Build 0:6ae2f7bca550 17 } MESSAGE_SEND_STATE;
Azure.IoT Build 0:6ae2f7bca550 18
Azure.IoT Build 0:6ae2f7bca550 19 typedef enum SEND_ONE_MESSAGE_RESULT_TAG
Azure.IoT Build 0:6ae2f7bca550 20 {
AzureIoTClient 6:641a9672db08 21 SEND_ONE_MESSAGE_OK,
AzureIoTClient 6:641a9672db08 22 SEND_ONE_MESSAGE_ERROR,
AzureIoTClient 6:641a9672db08 23 SEND_ONE_MESSAGE_BUSY
Azure.IoT Build 0:6ae2f7bca550 24 } SEND_ONE_MESSAGE_RESULT;
Azure.IoT Build 0:6ae2f7bca550 25
Azure.IoT Build 0:6ae2f7bca550 26 typedef struct MESSAGE_WITH_CALLBACK_TAG
Azure.IoT Build 0:6ae2f7bca550 27 {
AzureIoTClient 6:641a9672db08 28 MESSAGE_HANDLE message;
AzureIoTClient 6:641a9672db08 29 ON_MESSAGE_SEND_COMPLETE on_message_send_complete;
AzureIoTClient 6:641a9672db08 30 void* context;
AzureIoTClient 6:641a9672db08 31 MESSAGE_SENDER_HANDLE message_sender;
AzureIoTClient 6:641a9672db08 32 MESSAGE_SEND_STATE message_send_state;
Azure.IoT Build 0:6ae2f7bca550 33 } MESSAGE_WITH_CALLBACK;
Azure.IoT Build 0:6ae2f7bca550 34
Azure.IoT Build 0:6ae2f7bca550 35 typedef struct MESSAGE_SENDER_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 36 {
AzureIoTClient 6:641a9672db08 37 LINK_HANDLE link;
AzureIoTClient 6:641a9672db08 38 size_t message_count;
AzureIoTClient 6:641a9672db08 39 MESSAGE_WITH_CALLBACK** messages;
AzureIoTClient 6:641a9672db08 40 MESSAGE_SENDER_STATE message_sender_state;
AzureIoTClient 6:641a9672db08 41 ON_MESSAGE_SENDER_STATE_CHANGED on_message_sender_state_changed;
AzureIoTClient 6:641a9672db08 42 void* on_message_sender_state_changed_context;
AzureIoTClient 6:641a9672db08 43 unsigned int is_trace_on : 1;
Azure.IoT Build 0:6ae2f7bca550 44 } MESSAGE_SENDER_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 45
Azure.IoT Build 0:6ae2f7bca550 46 static void remove_pending_message_by_index(MESSAGE_SENDER_INSTANCE* message_sender_instance, size_t index)
Azure.IoT Build 0:6ae2f7bca550 47 {
AzureIoTClient 6:641a9672db08 48 MESSAGE_WITH_CALLBACK** new_messages;
Azure.IoT Build 0:6ae2f7bca550 49
AzureIoTClient 6:641a9672db08 50 if (message_sender_instance->messages[index]->message != NULL)
AzureIoTClient 6:641a9672db08 51 {
AzureIoTClient 6:641a9672db08 52 message_destroy(message_sender_instance->messages[index]->message);
AzureIoTClient 6:641a9672db08 53 message_sender_instance->messages[index]->message = NULL;
AzureIoTClient 6:641a9672db08 54 }
Azure.IoT Build 0:6ae2f7bca550 55
AzureIoTClient 6:641a9672db08 56 amqpalloc_free(message_sender_instance->messages[index]);
Azure.IoT Build 0:6ae2f7bca550 57
AzureIoTClient 6:641a9672db08 58 if (message_sender_instance->message_count - index > 1)
AzureIoTClient 6:641a9672db08 59 {
AzureIoTClient 6:641a9672db08 60 (void)memmove(&message_sender_instance->messages[index], &message_sender_instance->messages[index + 1], sizeof(MESSAGE_WITH_CALLBACK*) * (message_sender_instance->message_count - index - 1));
AzureIoTClient 6:641a9672db08 61 }
Azure.IoT Build 0:6ae2f7bca550 62
AzureIoTClient 6:641a9672db08 63 message_sender_instance->message_count--;
Azure.IoT Build 0:6ae2f7bca550 64
AzureIoTClient 6:641a9672db08 65 if (message_sender_instance->message_count > 0)
AzureIoTClient 6:641a9672db08 66 {
AzureIoTClient 6:641a9672db08 67 new_messages = (MESSAGE_WITH_CALLBACK**)amqpalloc_realloc(message_sender_instance->messages, sizeof(MESSAGE_WITH_CALLBACK*) * (message_sender_instance->message_count));
AzureIoTClient 6:641a9672db08 68 if (new_messages != NULL)
AzureIoTClient 6:641a9672db08 69 {
AzureIoTClient 6:641a9672db08 70 message_sender_instance->messages = new_messages;
AzureIoTClient 6:641a9672db08 71 }
AzureIoTClient 6:641a9672db08 72 }
AzureIoTClient 6:641a9672db08 73 else
AzureIoTClient 6:641a9672db08 74 {
AzureIoTClient 6:641a9672db08 75 amqpalloc_free(message_sender_instance->messages);
AzureIoTClient 6:641a9672db08 76 message_sender_instance->messages = NULL;
AzureIoTClient 6:641a9672db08 77 }
Azure.IoT Build 0:6ae2f7bca550 78 }
Azure.IoT Build 0:6ae2f7bca550 79
Azure.IoT Build 0:6ae2f7bca550 80 static void remove_pending_message(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_WITH_CALLBACK* message_with_callback)
Azure.IoT Build 0:6ae2f7bca550 81 {
AzureIoTClient 6:641a9672db08 82 size_t i;
Azure.IoT Build 0:6ae2f7bca550 83
AzureIoTClient 6:641a9672db08 84 for (i = 0; i < message_sender_instance->message_count; i++)
AzureIoTClient 6:641a9672db08 85 {
AzureIoTClient 6:641a9672db08 86 if (message_sender_instance->messages[i] == message_with_callback)
AzureIoTClient 6:641a9672db08 87 {
AzureIoTClient 6:641a9672db08 88 remove_pending_message_by_index(message_sender_instance, i);
AzureIoTClient 6:641a9672db08 89 break;
AzureIoTClient 6:641a9672db08 90 }
AzureIoTClient 6:641a9672db08 91 }
Azure.IoT Build 0:6ae2f7bca550 92 }
Azure.IoT Build 0:6ae2f7bca550 93
AzureIoTClient 7:9e9ab3b0efef 94 static void on_delivery_settled(void* context, delivery_number delivery_no, AMQP_VALUE delivery_state)
Azure.IoT Build 0:6ae2f7bca550 95 {
AzureIoTClient 6:641a9672db08 96 MESSAGE_WITH_CALLBACK* message_with_callback = (MESSAGE_WITH_CALLBACK*)context;
AzureIoTClient 6:641a9672db08 97 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_with_callback->message_sender;
AzureIoTClient 6:641a9672db08 98 (void)delivery_no;
Azure.IoT Build 0:6ae2f7bca550 99
AzureIoTClient 6:641a9672db08 100 if (message_with_callback->on_message_send_complete != NULL)
AzureIoTClient 6:641a9672db08 101 {
AzureIoTClient 7:9e9ab3b0efef 102 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(delivery_state);
AzureIoTClient 16:22a72cf8e416 103 if ((descriptor == NULL) && (delivery_state != NULL))
AzureIoTClient 7:9e9ab3b0efef 104 {
AzureIoTClient 7:9e9ab3b0efef 105 LogError("Error getting descriptor for delivery state");
AzureIoTClient 7:9e9ab3b0efef 106 }
AzureIoTClient 7:9e9ab3b0efef 107 else
AzureIoTClient 7:9e9ab3b0efef 108 {
AzureIoTClient 7:9e9ab3b0efef 109 MESSAGE_SEND_RESULT message_send_result;
AzureIoTClient 7:9e9ab3b0efef 110
AzureIoTClient 7:9e9ab3b0efef 111 if ((delivery_state == NULL) ||
AzureIoTClient 7:9e9ab3b0efef 112 (is_accepted_type_by_descriptor(descriptor)))
AzureIoTClient 7:9e9ab3b0efef 113 {
AzureIoTClient 7:9e9ab3b0efef 114 message_send_result = MESSAGE_SEND_OK;
AzureIoTClient 7:9e9ab3b0efef 115 }
AzureIoTClient 7:9e9ab3b0efef 116 else
AzureIoTClient 7:9e9ab3b0efef 117 {
AzureIoTClient 7:9e9ab3b0efef 118 message_send_result = MESSAGE_SEND_ERROR;
AzureIoTClient 7:9e9ab3b0efef 119 }
AzureIoTClient 7:9e9ab3b0efef 120
AzureIoTClient 7:9e9ab3b0efef 121 message_with_callback->on_message_send_complete(message_with_callback->context, message_send_result);
AzureIoTClient 7:9e9ab3b0efef 122 }
AzureIoTClient 6:641a9672db08 123 }
Azure.IoT Build 0:6ae2f7bca550 124
AzureIoTClient 6:641a9672db08 125 remove_pending_message(message_sender_instance, message_with_callback);
Azure.IoT Build 0:6ae2f7bca550 126 }
Azure.IoT Build 0:6ae2f7bca550 127
Azure.IoT Build 0:6ae2f7bca550 128 static int encode_bytes(void* context, const unsigned char* bytes, size_t length)
Azure.IoT Build 0:6ae2f7bca550 129 {
AzureIoTClient 6:641a9672db08 130 PAYLOAD* payload = (PAYLOAD*)context;
AzureIoTClient 6:641a9672db08 131 (void)memcpy((unsigned char*)payload->bytes + payload->length, bytes, length);
AzureIoTClient 6:641a9672db08 132 payload->length += length;
AzureIoTClient 6:641a9672db08 133 return 0;
Azure.IoT Build 0:6ae2f7bca550 134 }
Azure.IoT Build 0:6ae2f7bca550 135
Azure.IoT Build 0:6ae2f7bca550 136 static void log_message_chunk(MESSAGE_SENDER_INSTANCE* message_sender_instance, const char* name, AMQP_VALUE value)
Azure.IoT Build 0:6ae2f7bca550 137 {
AzureIoTClient 9:c22db038556c 138 #ifdef NO_LOGGING
AzureIoTClient 9:c22db038556c 139 UNUSED(message_sender_instance);
AzureIoTClient 9:c22db038556c 140 UNUSED(name);
AzureIoTClient 9:c22db038556c 141 UNUSED(value);
AzureIoTClient 9:c22db038556c 142 #else
AzureIoTClient 6:641a9672db08 143 if (xlogging_get_log_function() != NULL && message_sender_instance->is_trace_on == 1)
AzureIoTClient 6:641a9672db08 144 {
AzureIoTClient 6:641a9672db08 145 char* value_as_string = NULL;
AzureIoTClient 16:22a72cf8e416 146 LOG(AZ_LOG_TRACE, 0, "%s", name);
AzureIoTClient 16:22a72cf8e416 147 LOG(AZ_LOG_TRACE, 0, "%s", (value_as_string = amqpvalue_to_string(value)));
AzureIoTClient 6:641a9672db08 148 if (value_as_string != NULL)
AzureIoTClient 6:641a9672db08 149 {
AzureIoTClient 6:641a9672db08 150 amqpalloc_free(value_as_string);
AzureIoTClient 6:641a9672db08 151 }
AzureIoTClient 6:641a9672db08 152 }
AzureIoTClient 9:c22db038556c 153 #endif
Azure.IoT Build 0:6ae2f7bca550 154 }
Azure.IoT Build 0:6ae2f7bca550 155
Azure.IoT Build 0:6ae2f7bca550 156 static SEND_ONE_MESSAGE_RESULT send_one_message(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_WITH_CALLBACK* message_with_callback, MESSAGE_HANDLE message)
Azure.IoT Build 0:6ae2f7bca550 157 {
AzureIoTClient 6:641a9672db08 158 SEND_ONE_MESSAGE_RESULT result;
Azure.IoT Build 0:6ae2f7bca550 159
AzureIoTClient 6:641a9672db08 160 size_t encoded_size;
AzureIoTClient 6:641a9672db08 161 size_t total_encoded_size = 0;
AzureIoTClient 6:641a9672db08 162 MESSAGE_BODY_TYPE message_body_type;
Azure.IoT Build 0:6ae2f7bca550 163 message_format message_format;
Azure.IoT Build 0:6ae2f7bca550 164
AzureIoTClient 6:641a9672db08 165 if ((message_get_body_type(message, &message_body_type) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 166 (message_get_message_format(message, &message_format) != 0))
AzureIoTClient 6:641a9672db08 167 {
AzureIoTClient 6:641a9672db08 168 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 169 }
AzureIoTClient 6:641a9672db08 170 else
AzureIoTClient 6:641a9672db08 171 {
AzureIoTClient 6:641a9672db08 172 // header
AzureIoTClient 6:641a9672db08 173 HEADER_HANDLE header;
AzureIoTClient 6:641a9672db08 174 AMQP_VALUE header_amqp_value;
AzureIoTClient 6:641a9672db08 175 PROPERTIES_HANDLE properties;
AzureIoTClient 6:641a9672db08 176 AMQP_VALUE properties_amqp_value;
AzureIoTClient 6:641a9672db08 177 AMQP_VALUE application_properties;
AzureIoTClient 6:641a9672db08 178 AMQP_VALUE application_properties_value;
AzureIoTClient 6:641a9672db08 179 AMQP_VALUE body_amqp_value = NULL;
AzureIoTClient 6:641a9672db08 180 size_t body_data_count = 0;
AzureIoTClient 13:9abd748f4e78 181 AMQP_VALUE msg_annotations = NULL;
Azure.IoT Build 0:6ae2f7bca550 182
AzureIoTClient 6:641a9672db08 183 message_get_header(message, &header);
AzureIoTClient 6:641a9672db08 184 header_amqp_value = amqpvalue_create_header(header);
AzureIoTClient 6:641a9672db08 185 if (header != NULL)
AzureIoTClient 6:641a9672db08 186 {
AzureIoTClient 6:641a9672db08 187 amqpvalue_get_encoded_size(header_amqp_value, &encoded_size);
AzureIoTClient 6:641a9672db08 188 total_encoded_size += encoded_size;
AzureIoTClient 6:641a9672db08 189 }
Azure.IoT Build 0:6ae2f7bca550 190
AzureIoTClient 13:9abd748f4e78 191 // message annotations
AzureIoTClient 13:9abd748f4e78 192 if ((message_get_message_annotations(message, &msg_annotations) == 0) &&
AzureIoTClient 13:9abd748f4e78 193 (msg_annotations != NULL))
AzureIoTClient 13:9abd748f4e78 194 {
AzureIoTClient 13:9abd748f4e78 195 amqpvalue_get_encoded_size(msg_annotations, &encoded_size);
AzureIoTClient 13:9abd748f4e78 196 total_encoded_size += encoded_size;
AzureIoTClient 13:9abd748f4e78 197 }
AzureIoTClient 13:9abd748f4e78 198
AzureIoTClient 6:641a9672db08 199 // properties
AzureIoTClient 6:641a9672db08 200 message_get_properties(message, &properties);
AzureIoTClient 6:641a9672db08 201 properties_amqp_value = amqpvalue_create_properties(properties);
AzureIoTClient 6:641a9672db08 202 if (properties != NULL)
AzureIoTClient 6:641a9672db08 203 {
AzureIoTClient 6:641a9672db08 204 amqpvalue_get_encoded_size(properties_amqp_value, &encoded_size);
AzureIoTClient 6:641a9672db08 205 total_encoded_size += encoded_size;
AzureIoTClient 6:641a9672db08 206 }
Azure.IoT Build 0:6ae2f7bca550 207
AzureIoTClient 6:641a9672db08 208 // application properties
AzureIoTClient 6:641a9672db08 209 message_get_application_properties(message, &application_properties);
AzureIoTClient 6:641a9672db08 210 application_properties_value = amqpvalue_create_application_properties(application_properties);
AzureIoTClient 6:641a9672db08 211 if (application_properties != NULL)
AzureIoTClient 6:641a9672db08 212 {
AzureIoTClient 6:641a9672db08 213 amqpvalue_get_encoded_size(application_properties_value, &encoded_size);
AzureIoTClient 6:641a9672db08 214 total_encoded_size += encoded_size;
AzureIoTClient 6:641a9672db08 215 }
Azure.IoT Build 0:6ae2f7bca550 216
AzureIoTClient 6:641a9672db08 217 result = SEND_ONE_MESSAGE_OK;
Azure.IoT Build 0:6ae2f7bca550 218
AzureIoTClient 6:641a9672db08 219 // body - amqp data
AzureIoTClient 6:641a9672db08 220 switch (message_body_type)
AzureIoTClient 6:641a9672db08 221 {
AzureIoTClient 6:641a9672db08 222 default:
AzureIoTClient 6:641a9672db08 223 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 224 break;
Azure.IoT Build 0:6ae2f7bca550 225
AzureIoTClient 6:641a9672db08 226 case MESSAGE_BODY_TYPE_VALUE:
AzureIoTClient 6:641a9672db08 227 {
AzureIoTClient 6:641a9672db08 228 AMQP_VALUE message_body_amqp_value;
AzureIoTClient 6:641a9672db08 229 if (message_get_inplace_body_amqp_value(message, &message_body_amqp_value) != 0)
AzureIoTClient 6:641a9672db08 230 {
AzureIoTClient 6:641a9672db08 231 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 232 }
AzureIoTClient 6:641a9672db08 233 else
AzureIoTClient 6:641a9672db08 234 {
AzureIoTClient 6:641a9672db08 235 body_amqp_value = amqpvalue_create_amqp_value(message_body_amqp_value);
AzureIoTClient 6:641a9672db08 236 if ((body_amqp_value == NULL) ||
AzureIoTClient 6:641a9672db08 237 (amqpvalue_get_encoded_size(body_amqp_value, &encoded_size) != 0))
AzureIoTClient 6:641a9672db08 238 {
AzureIoTClient 6:641a9672db08 239 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 240 }
AzureIoTClient 6:641a9672db08 241 else
AzureIoTClient 6:641a9672db08 242 {
AzureIoTClient 6:641a9672db08 243 total_encoded_size += encoded_size;
AzureIoTClient 6:641a9672db08 244 }
AzureIoTClient 6:641a9672db08 245 }
Azure.IoT Build 0:6ae2f7bca550 246
AzureIoTClient 6:641a9672db08 247 break;
AzureIoTClient 6:641a9672db08 248 }
Azure.IoT Build 0:6ae2f7bca550 249
AzureIoTClient 6:641a9672db08 250 case MESSAGE_BODY_TYPE_DATA:
AzureIoTClient 6:641a9672db08 251 {
AzureIoTClient 6:641a9672db08 252 BINARY_DATA binary_data;
Azure.IoT Build 0:6ae2f7bca550 253 size_t i;
Azure.IoT Build 0:6ae2f7bca550 254
Azure.IoT Build 0:6ae2f7bca550 255 if (message_get_body_amqp_data_count(message, &body_data_count) != 0)
Azure.IoT Build 0:6ae2f7bca550 256 {
Azure.IoT Build 0:6ae2f7bca550 257 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 258 }
Azure.IoT Build 0:6ae2f7bca550 259 else
Azure.IoT Build 0:6ae2f7bca550 260 {
Azure.IoT Build 0:6ae2f7bca550 261 for (i = 0; i < body_data_count; i++)
Azure.IoT Build 0:6ae2f7bca550 262 {
Azure.IoT Build 0:6ae2f7bca550 263 if (message_get_body_amqp_data(message, i, &binary_data) != 0)
Azure.IoT Build 0:6ae2f7bca550 264 {
Azure.IoT Build 0:6ae2f7bca550 265 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 266 }
Azure.IoT Build 0:6ae2f7bca550 267 else
Azure.IoT Build 0:6ae2f7bca550 268 {
AzureIoTClient 6:641a9672db08 269 amqp_binary binary_value;
AzureIoTClient 6:641a9672db08 270 binary_value.bytes = binary_data.bytes;
AzureIoTClient 6:641a9672db08 271 binary_value.length = (uint32_t)binary_data.length;
Azure.IoT Build 0:6ae2f7bca550 272 AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value);
Azure.IoT Build 0:6ae2f7bca550 273 if (body_amqp_data == NULL)
Azure.IoT Build 0:6ae2f7bca550 274 {
Azure.IoT Build 0:6ae2f7bca550 275 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 276 }
Azure.IoT Build 0:6ae2f7bca550 277 else
Azure.IoT Build 0:6ae2f7bca550 278 {
Azure.IoT Build 0:6ae2f7bca550 279 if (amqpvalue_get_encoded_size(body_amqp_data, &encoded_size) != 0)
Azure.IoT Build 0:6ae2f7bca550 280 {
Azure.IoT Build 0:6ae2f7bca550 281 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 282 }
Azure.IoT Build 0:6ae2f7bca550 283 else
Azure.IoT Build 0:6ae2f7bca550 284 {
Azure.IoT Build 0:6ae2f7bca550 285 total_encoded_size += encoded_size;
Azure.IoT Build 0:6ae2f7bca550 286 }
Azure.IoT Build 0:6ae2f7bca550 287
Azure.IoT Build 0:6ae2f7bca550 288 amqpvalue_destroy(body_amqp_data);
Azure.IoT Build 0:6ae2f7bca550 289 }
Azure.IoT Build 0:6ae2f7bca550 290 }
Azure.IoT Build 0:6ae2f7bca550 291 }
Azure.IoT Build 0:6ae2f7bca550 292 }
AzureIoTClient 6:641a9672db08 293 break;
AzureIoTClient 6:641a9672db08 294 }
AzureIoTClient 6:641a9672db08 295 }
Azure.IoT Build 0:6ae2f7bca550 296
AzureIoTClient 6:641a9672db08 297 if (result == 0)
AzureIoTClient 6:641a9672db08 298 {
AzureIoTClient 6:641a9672db08 299 void* data_bytes = amqpalloc_malloc(total_encoded_size);
AzureIoTClient 6:641a9672db08 300 PAYLOAD payload;
AzureIoTClient 6:641a9672db08 301 payload.bytes = data_bytes;
AzureIoTClient 6:641a9672db08 302 payload.length = 0;
AzureIoTClient 6:641a9672db08 303 result = SEND_ONE_MESSAGE_OK;
Azure.IoT Build 0:6ae2f7bca550 304
AzureIoTClient 6:641a9672db08 305 if (header != NULL)
AzureIoTClient 6:641a9672db08 306 {
AzureIoTClient 6:641a9672db08 307 if (amqpvalue_encode(header_amqp_value, encode_bytes, &payload) != 0)
AzureIoTClient 6:641a9672db08 308 {
AzureIoTClient 6:641a9672db08 309 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 310 }
Azure.IoT Build 0:6ae2f7bca550 311
AzureIoTClient 6:641a9672db08 312 log_message_chunk(message_sender_instance, "Header:", header_amqp_value);
AzureIoTClient 6:641a9672db08 313 }
Azure.IoT Build 0:6ae2f7bca550 314
AzureIoTClient 13:9abd748f4e78 315 if ((result == SEND_ONE_MESSAGE_OK) && (msg_annotations != NULL))
AzureIoTClient 13:9abd748f4e78 316 {
AzureIoTClient 13:9abd748f4e78 317 if (amqpvalue_encode(msg_annotations, encode_bytes, &payload) != 0)
AzureIoTClient 13:9abd748f4e78 318 {
AzureIoTClient 13:9abd748f4e78 319 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 13:9abd748f4e78 320 }
AzureIoTClient 13:9abd748f4e78 321
AzureIoTClient 13:9abd748f4e78 322 log_message_chunk(message_sender_instance, "Message Annotations:", msg_annotations);
AzureIoTClient 13:9abd748f4e78 323 }
AzureIoTClient 13:9abd748f4e78 324
AzureIoTClient 6:641a9672db08 325 if ((result == SEND_ONE_MESSAGE_OK) && (properties != NULL))
AzureIoTClient 6:641a9672db08 326 {
AzureIoTClient 6:641a9672db08 327 if (amqpvalue_encode(properties_amqp_value, encode_bytes, &payload) != 0)
AzureIoTClient 6:641a9672db08 328 {
AzureIoTClient 6:641a9672db08 329 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 330 }
Azure.IoT Build 0:6ae2f7bca550 331
AzureIoTClient 6:641a9672db08 332 log_message_chunk(message_sender_instance, "Properties:", properties_amqp_value);
AzureIoTClient 6:641a9672db08 333 }
Azure.IoT Build 0:6ae2f7bca550 334
AzureIoTClient 6:641a9672db08 335 if ((result == SEND_ONE_MESSAGE_OK) && (application_properties != NULL))
AzureIoTClient 6:641a9672db08 336 {
AzureIoTClient 6:641a9672db08 337 if (amqpvalue_encode(application_properties_value, encode_bytes, &payload) != 0)
AzureIoTClient 6:641a9672db08 338 {
AzureIoTClient 6:641a9672db08 339 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 340 }
Azure.IoT Build 0:6ae2f7bca550 341
AzureIoTClient 6:641a9672db08 342 log_message_chunk(message_sender_instance, "Application properties:", application_properties_value);
AzureIoTClient 6:641a9672db08 343 }
Azure.IoT Build 0:6ae2f7bca550 344
AzureIoTClient 6:641a9672db08 345 if (result == SEND_ONE_MESSAGE_OK)
AzureIoTClient 6:641a9672db08 346 {
AzureIoTClient 6:641a9672db08 347 switch (message_body_type)
AzureIoTClient 6:641a9672db08 348 {
AzureIoTClient 17:923575db8b2d 349 default:
AzureIoTClient 17:923575db8b2d 350 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 17:923575db8b2d 351 break;
AzureIoTClient 17:923575db8b2d 352
AzureIoTClient 6:641a9672db08 353 case MESSAGE_BODY_TYPE_VALUE:
AzureIoTClient 6:641a9672db08 354 {
AzureIoTClient 6:641a9672db08 355 if (amqpvalue_encode(body_amqp_value, encode_bytes, &payload) != 0)
AzureIoTClient 6:641a9672db08 356 {
AzureIoTClient 6:641a9672db08 357 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 358 }
Azure.IoT Build 0:6ae2f7bca550 359
AzureIoTClient 6:641a9672db08 360 log_message_chunk(message_sender_instance, "Body - amqp value:", body_amqp_value);
AzureIoTClient 6:641a9672db08 361 break;
AzureIoTClient 6:641a9672db08 362 }
AzureIoTClient 6:641a9672db08 363 case MESSAGE_BODY_TYPE_DATA:
AzureIoTClient 6:641a9672db08 364 {
Azure.IoT Build 0:6ae2f7bca550 365 BINARY_DATA binary_data;
Azure.IoT Build 0:6ae2f7bca550 366 size_t i;
Azure.IoT Build 0:6ae2f7bca550 367
Azure.IoT Build 0:6ae2f7bca550 368 for (i = 0; i < body_data_count; i++)
Azure.IoT Build 0:6ae2f7bca550 369 {
Azure.IoT Build 0:6ae2f7bca550 370 if (message_get_body_amqp_data(message, i, &binary_data) != 0)
Azure.IoT Build 0:6ae2f7bca550 371 {
Azure.IoT Build 0:6ae2f7bca550 372 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 373 }
Azure.IoT Build 0:6ae2f7bca550 374 else
Azure.IoT Build 0:6ae2f7bca550 375 {
AzureIoTClient 6:641a9672db08 376 amqp_binary binary_value;
AzureIoTClient 6:641a9672db08 377 binary_value.bytes = binary_data.bytes;
AzureIoTClient 6:641a9672db08 378 binary_value.length = (uint32_t)binary_data.length;
Azure.IoT Build 0:6ae2f7bca550 379 AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value);
Azure.IoT Build 0:6ae2f7bca550 380 if (body_amqp_data == NULL)
Azure.IoT Build 0:6ae2f7bca550 381 {
Azure.IoT Build 0:6ae2f7bca550 382 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 383 }
Azure.IoT Build 0:6ae2f7bca550 384 else
Azure.IoT Build 0:6ae2f7bca550 385 {
Azure.IoT Build 0:6ae2f7bca550 386 if (amqpvalue_encode(body_amqp_data, encode_bytes, &payload) != 0)
Azure.IoT Build 0:6ae2f7bca550 387 {
Azure.IoT Build 0:6ae2f7bca550 388 result = SEND_ONE_MESSAGE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 389 break;
Azure.IoT Build 0:6ae2f7bca550 390 }
Azure.IoT Build 0:6ae2f7bca550 391
Azure.IoT Build 0:6ae2f7bca550 392 amqpvalue_destroy(body_amqp_data);
Azure.IoT Build 0:6ae2f7bca550 393 }
Azure.IoT Build 0:6ae2f7bca550 394 }
Azure.IoT Build 0:6ae2f7bca550 395 }
AzureIoTClient 6:641a9672db08 396 break;
AzureIoTClient 6:641a9672db08 397 }
AzureIoTClient 6:641a9672db08 398 }
AzureIoTClient 6:641a9672db08 399 }
Azure.IoT Build 0:6ae2f7bca550 400
AzureIoTClient 6:641a9672db08 401 if (result == SEND_ONE_MESSAGE_OK)
AzureIoTClient 6:641a9672db08 402 {
AzureIoTClient 6:641a9672db08 403 message_with_callback->message_send_state = MESSAGE_SEND_STATE_PENDING;
AzureIoTClient 6:641a9672db08 404 switch (link_transfer(message_sender_instance->link, message_format, &payload, 1, on_delivery_settled, message_with_callback))
AzureIoTClient 6:641a9672db08 405 {
AzureIoTClient 6:641a9672db08 406 default:
AzureIoTClient 6:641a9672db08 407 case LINK_TRANSFER_ERROR:
AzureIoTClient 6:641a9672db08 408 result = SEND_ONE_MESSAGE_ERROR;
AzureIoTClient 6:641a9672db08 409 break;
Azure.IoT Build 0:6ae2f7bca550 410
AzureIoTClient 6:641a9672db08 411 case LINK_TRANSFER_BUSY:
AzureIoTClient 6:641a9672db08 412 message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT;
AzureIoTClient 6:641a9672db08 413 result = SEND_ONE_MESSAGE_BUSY;
AzureIoTClient 6:641a9672db08 414 break;
Azure.IoT Build 0:6ae2f7bca550 415
AzureIoTClient 6:641a9672db08 416 case LINK_TRANSFER_OK:
AzureIoTClient 6:641a9672db08 417 result = SEND_ONE_MESSAGE_OK;
AzureIoTClient 6:641a9672db08 418 break;
AzureIoTClient 6:641a9672db08 419 }
AzureIoTClient 6:641a9672db08 420 }
Azure.IoT Build 0:6ae2f7bca550 421
AzureIoTClient 6:641a9672db08 422 amqpalloc_free(data_bytes);
Azure.IoT Build 0:6ae2f7bca550 423
AzureIoTClient 6:641a9672db08 424 if (body_amqp_value != NULL)
AzureIoTClient 6:641a9672db08 425 {
AzureIoTClient 6:641a9672db08 426 amqpvalue_destroy(body_amqp_value);
AzureIoTClient 6:641a9672db08 427 }
Azure.IoT Build 0:6ae2f7bca550 428
AzureIoTClient 6:641a9672db08 429 amqpvalue_destroy(application_properties);
AzureIoTClient 6:641a9672db08 430 amqpvalue_destroy(application_properties_value);
AzureIoTClient 6:641a9672db08 431 amqpvalue_destroy(properties_amqp_value);
AzureIoTClient 6:641a9672db08 432 properties_destroy(properties);
AzureIoTClient 6:641a9672db08 433 }
AzureIoTClient 6:641a9672db08 434 }
Azure.IoT Build 0:6ae2f7bca550 435
AzureIoTClient 6:641a9672db08 436 return result;
Azure.IoT Build 0:6ae2f7bca550 437 }
Azure.IoT Build 0:6ae2f7bca550 438
Azure.IoT Build 0:6ae2f7bca550 439 static void send_all_pending_messages(MESSAGE_SENDER_INSTANCE* message_sender_instance)
Azure.IoT Build 0:6ae2f7bca550 440 {
AzureIoTClient 6:641a9672db08 441 size_t i;
Azure.IoT Build 0:6ae2f7bca550 442
AzureIoTClient 6:641a9672db08 443 for (i = 0; i < message_sender_instance->message_count; i++)
AzureIoTClient 6:641a9672db08 444 {
AzureIoTClient 6:641a9672db08 445 if (message_sender_instance->messages[i]->message_send_state == MESSAGE_SEND_STATE_NOT_SENT)
AzureIoTClient 6:641a9672db08 446 {
AzureIoTClient 6:641a9672db08 447 switch (send_one_message(message_sender_instance, message_sender_instance->messages[i], message_sender_instance->messages[i]->message))
AzureIoTClient 6:641a9672db08 448 {
AzureIoTClient 6:641a9672db08 449 default:
AzureIoTClient 6:641a9672db08 450 case SEND_ONE_MESSAGE_ERROR:
AzureIoTClient 6:641a9672db08 451 {
AzureIoTClient 6:641a9672db08 452 ON_MESSAGE_SEND_COMPLETE on_message_send_complete = message_sender_instance->messages[i]->on_message_send_complete;
AzureIoTClient 6:641a9672db08 453 void* context = message_sender_instance->messages[i]->context;
AzureIoTClient 6:641a9672db08 454 remove_pending_message_by_index(message_sender_instance, i);
Azure.IoT Build 0:6ae2f7bca550 455
AzureIoTClient 18:a922a4a30a82 456 if (on_message_send_complete != NULL)
AzureIoTClient 18:a922a4a30a82 457 {
AzureIoTClient 18:a922a4a30a82 458 on_message_send_complete(context, MESSAGE_SEND_ERROR);
AzureIoTClient 18:a922a4a30a82 459 }
AzureIoTClient 18:a922a4a30a82 460
AzureIoTClient 6:641a9672db08 461 i = message_sender_instance->message_count;
AzureIoTClient 6:641a9672db08 462 break;
AzureIoTClient 6:641a9672db08 463 }
AzureIoTClient 6:641a9672db08 464 case SEND_ONE_MESSAGE_BUSY:
AzureIoTClient 6:641a9672db08 465 i = message_sender_instance->message_count + 1;
AzureIoTClient 6:641a9672db08 466 break;
Azure.IoT Build 0:6ae2f7bca550 467
AzureIoTClient 6:641a9672db08 468 case SEND_ONE_MESSAGE_OK:
AzureIoTClient 6:641a9672db08 469 break;
AzureIoTClient 6:641a9672db08 470 }
Azure.IoT Build 0:6ae2f7bca550 471
AzureIoTClient 6:641a9672db08 472 i--;
AzureIoTClient 6:641a9672db08 473 }
AzureIoTClient 6:641a9672db08 474 }
Azure.IoT Build 0:6ae2f7bca550 475 }
Azure.IoT Build 0:6ae2f7bca550 476
Azure.IoT Build 0:6ae2f7bca550 477 static void set_message_sender_state(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_SENDER_STATE new_state)
Azure.IoT Build 0:6ae2f7bca550 478 {
AzureIoTClient 6:641a9672db08 479 MESSAGE_SENDER_STATE previous_state = message_sender_instance->message_sender_state;
AzureIoTClient 6:641a9672db08 480 message_sender_instance->message_sender_state = new_state;
AzureIoTClient 6:641a9672db08 481 if (message_sender_instance->on_message_sender_state_changed != NULL)
AzureIoTClient 6:641a9672db08 482 {
AzureIoTClient 6:641a9672db08 483 message_sender_instance->on_message_sender_state_changed(message_sender_instance->on_message_sender_state_changed_context, new_state, previous_state);
AzureIoTClient 6:641a9672db08 484 }
Azure.IoT Build 0:6ae2f7bca550 485 }
Azure.IoT Build 0:6ae2f7bca550 486
AzureIoTClient 2:64b4feb67cd3 487 static void indicate_all_messages_as_error(MESSAGE_SENDER_INSTANCE* message_sender_instance)
AzureIoTClient 2:64b4feb67cd3 488 {
AzureIoTClient 2:64b4feb67cd3 489 size_t i;
AzureIoTClient 2:64b4feb67cd3 490
AzureIoTClient 2:64b4feb67cd3 491 for (i = 0; i < message_sender_instance->message_count; i++)
AzureIoTClient 2:64b4feb67cd3 492 {
AzureIoTClient 2:64b4feb67cd3 493 if (message_sender_instance->messages[i]->on_message_send_complete != NULL)
AzureIoTClient 2:64b4feb67cd3 494 {
AzureIoTClient 2:64b4feb67cd3 495 message_sender_instance->messages[i]->on_message_send_complete(message_sender_instance->messages[i]->context, MESSAGE_SEND_ERROR);
AzureIoTClient 2:64b4feb67cd3 496 }
AzureIoTClient 2:64b4feb67cd3 497
AzureIoTClient 2:64b4feb67cd3 498 message_destroy(message_sender_instance->messages[i]->message);
AzureIoTClient 2:64b4feb67cd3 499 amqpalloc_free(message_sender_instance->messages[i]);
AzureIoTClient 2:64b4feb67cd3 500 }
AzureIoTClient 2:64b4feb67cd3 501
AzureIoTClient 2:64b4feb67cd3 502 if (message_sender_instance->messages != NULL)
AzureIoTClient 2:64b4feb67cd3 503 {
AzureIoTClient 2:64b4feb67cd3 504 message_sender_instance->message_count = 0;
AzureIoTClient 2:64b4feb67cd3 505
AzureIoTClient 2:64b4feb67cd3 506 amqpalloc_free(message_sender_instance->messages);
AzureIoTClient 2:64b4feb67cd3 507 message_sender_instance->messages = NULL;
AzureIoTClient 2:64b4feb67cd3 508 }
AzureIoTClient 2:64b4feb67cd3 509 }
AzureIoTClient 2:64b4feb67cd3 510
Azure.IoT Build 0:6ae2f7bca550 511 static void on_link_state_changed(void* context, LINK_STATE new_link_state, LINK_STATE previous_link_state)
Azure.IoT Build 0:6ae2f7bca550 512 {
AzureIoTClient 6:641a9672db08 513 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 514 (void)previous_link_state;
Azure.IoT Build 0:6ae2f7bca550 515
AzureIoTClient 6:641a9672db08 516 switch (new_link_state)
AzureIoTClient 6:641a9672db08 517 {
AzureIoTClient 17:923575db8b2d 518 default:
AzureIoTClient 17:923575db8b2d 519 break;
AzureIoTClient 17:923575db8b2d 520
AzureIoTClient 6:641a9672db08 521 case LINK_STATE_ATTACHED:
AzureIoTClient 6:641a9672db08 522 if (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_OPENING)
AzureIoTClient 6:641a9672db08 523 {
AzureIoTClient 6:641a9672db08 524 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_OPEN);
AzureIoTClient 6:641a9672db08 525 }
AzureIoTClient 6:641a9672db08 526 break;
AzureIoTClient 6:641a9672db08 527 case LINK_STATE_DETACHED:
Azure.IoT Build 0:6ae2f7bca550 528 if ((message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_OPEN) ||
Azure.IoT Build 0:6ae2f7bca550 529 (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_CLOSING))
Azure.IoT Build 0:6ae2f7bca550 530 {
Azure.IoT Build 0:6ae2f7bca550 531 /* User initiated transition, we should be good */
AzureIoTClient 2:64b4feb67cd3 532 indicate_all_messages_as_error(message_sender_instance);
Azure.IoT Build 0:6ae2f7bca550 533 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_IDLE);
Azure.IoT Build 0:6ae2f7bca550 534 }
Azure.IoT Build 0:6ae2f7bca550 535 else if (message_sender_instance->message_sender_state != MESSAGE_SENDER_STATE_IDLE)
Azure.IoT Build 0:6ae2f7bca550 536 {
Azure.IoT Build 0:6ae2f7bca550 537 /* Any other transition must be an error */
Azure.IoT Build 0:6ae2f7bca550 538 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_ERROR);
Azure.IoT Build 0:6ae2f7bca550 539 }
Azure.IoT Build 0:6ae2f7bca550 540 break;
AzureIoTClient 6:641a9672db08 541 case LINK_STATE_ERROR:
AzureIoTClient 6:641a9672db08 542 if (message_sender_instance->message_sender_state != MESSAGE_SENDER_STATE_ERROR)
AzureIoTClient 6:641a9672db08 543 {
AzureIoTClient 2:64b4feb67cd3 544 indicate_all_messages_as_error(message_sender_instance);
AzureIoTClient 6:641a9672db08 545 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_ERROR);
AzureIoTClient 6:641a9672db08 546 }
AzureIoTClient 6:641a9672db08 547 break;
AzureIoTClient 6:641a9672db08 548 }
Azure.IoT Build 0:6ae2f7bca550 549 }
Azure.IoT Build 0:6ae2f7bca550 550
Azure.IoT Build 0:6ae2f7bca550 551 static void on_link_flow_on(void* context)
Azure.IoT Build 0:6ae2f7bca550 552 {
AzureIoTClient 6:641a9672db08 553 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 554 send_all_pending_messages(message_sender_instance);
Azure.IoT Build 0:6ae2f7bca550 555 }
Azure.IoT Build 0:6ae2f7bca550 556
Azure.IoT Build 5:ae49385aff34 557 MESSAGE_SENDER_HANDLE messagesender_create(LINK_HANDLE link, ON_MESSAGE_SENDER_STATE_CHANGED on_message_sender_state_changed, void* context)
Azure.IoT Build 0:6ae2f7bca550 558 {
AzureIoTClient 6:641a9672db08 559 MESSAGE_SENDER_INSTANCE* result = amqpalloc_malloc(sizeof(MESSAGE_SENDER_INSTANCE));
AzureIoTClient 6:641a9672db08 560 if (result != NULL)
AzureIoTClient 6:641a9672db08 561 {
AzureIoTClient 6:641a9672db08 562 result->messages = NULL;
AzureIoTClient 6:641a9672db08 563 result->message_count = 0;
AzureIoTClient 6:641a9672db08 564 result->link = link;
AzureIoTClient 6:641a9672db08 565 result->on_message_sender_state_changed = on_message_sender_state_changed;
AzureIoTClient 6:641a9672db08 566 result->on_message_sender_state_changed_context = context;
AzureIoTClient 6:641a9672db08 567 result->message_sender_state = MESSAGE_SENDER_STATE_IDLE;
AzureIoTClient 6:641a9672db08 568 result->is_trace_on = 0;
AzureIoTClient 6:641a9672db08 569 }
Azure.IoT Build 0:6ae2f7bca550 570
AzureIoTClient 6:641a9672db08 571 return result;
Azure.IoT Build 0:6ae2f7bca550 572 }
Azure.IoT Build 0:6ae2f7bca550 573
Azure.IoT Build 0:6ae2f7bca550 574 void messagesender_destroy(MESSAGE_SENDER_HANDLE message_sender)
Azure.IoT Build 0:6ae2f7bca550 575 {
AzureIoTClient 6:641a9672db08 576 if (message_sender != NULL)
AzureIoTClient 6:641a9672db08 577 {
AzureIoTClient 6:641a9672db08 578 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_sender;
Azure.IoT Build 0:6ae2f7bca550 579
AzureIoTClient 6:641a9672db08 580 messagesender_close(message_sender_instance);
Azure.IoT Build 0:6ae2f7bca550 581
AzureIoTClient 2:64b4feb67cd3 582 indicate_all_messages_as_error(message_sender_instance);
Azure.IoT Build 0:6ae2f7bca550 583
AzureIoTClient 6:641a9672db08 584 amqpalloc_free(message_sender);
AzureIoTClient 6:641a9672db08 585 }
Azure.IoT Build 0:6ae2f7bca550 586 }
Azure.IoT Build 0:6ae2f7bca550 587
Azure.IoT Build 0:6ae2f7bca550 588 int messagesender_open(MESSAGE_SENDER_HANDLE message_sender)
Azure.IoT Build 0:6ae2f7bca550 589 {
AzureIoTClient 6:641a9672db08 590 int result;
Azure.IoT Build 0:6ae2f7bca550 591
AzureIoTClient 6:641a9672db08 592 if (message_sender == NULL)
AzureIoTClient 6:641a9672db08 593 {
AzureIoTClient 19:000ab4e6a2c1 594 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 595 }
AzureIoTClient 6:641a9672db08 596 else
AzureIoTClient 6:641a9672db08 597 {
AzureIoTClient 6:641a9672db08 598 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_sender;
Azure.IoT Build 0:6ae2f7bca550 599
AzureIoTClient 6:641a9672db08 600 if (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_IDLE)
AzureIoTClient 6:641a9672db08 601 {
AzureIoTClient 6:641a9672db08 602 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_OPENING);
AzureIoTClient 6:641a9672db08 603 if (link_attach(message_sender_instance->link, NULL, on_link_state_changed, on_link_flow_on, message_sender_instance) != 0)
AzureIoTClient 6:641a9672db08 604 {
AzureIoTClient 19:000ab4e6a2c1 605 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 606 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_ERROR);
AzureIoTClient 6:641a9672db08 607 }
AzureIoTClient 6:641a9672db08 608 else
AzureIoTClient 6:641a9672db08 609 {
AzureIoTClient 6:641a9672db08 610 result = 0;
AzureIoTClient 6:641a9672db08 611 }
AzureIoTClient 6:641a9672db08 612 }
AzureIoTClient 6:641a9672db08 613 else
AzureIoTClient 6:641a9672db08 614 {
AzureIoTClient 6:641a9672db08 615 result = 0;
AzureIoTClient 6:641a9672db08 616 }
AzureIoTClient 6:641a9672db08 617 }
Azure.IoT Build 0:6ae2f7bca550 618
AzureIoTClient 6:641a9672db08 619 return result;
Azure.IoT Build 0:6ae2f7bca550 620 }
Azure.IoT Build 0:6ae2f7bca550 621
Azure.IoT Build 0:6ae2f7bca550 622 int messagesender_close(MESSAGE_SENDER_HANDLE message_sender)
Azure.IoT Build 0:6ae2f7bca550 623 {
AzureIoTClient 6:641a9672db08 624 int result;
Azure.IoT Build 0:6ae2f7bca550 625
AzureIoTClient 6:641a9672db08 626 if (message_sender == NULL)
AzureIoTClient 6:641a9672db08 627 {
AzureIoTClient 19:000ab4e6a2c1 628 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 629 }
AzureIoTClient 6:641a9672db08 630 else
AzureIoTClient 6:641a9672db08 631 {
AzureIoTClient 6:641a9672db08 632 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_sender;
Azure.IoT Build 0:6ae2f7bca550 633
AzureIoTClient 6:641a9672db08 634 if ((message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_OPENING) ||
AzureIoTClient 6:641a9672db08 635 (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_OPEN))
AzureIoTClient 6:641a9672db08 636 {
AzureIoTClient 6:641a9672db08 637 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_CLOSING);
AzureIoTClient 12:b30dacf113f2 638 if (link_detach(message_sender_instance->link, true) != 0)
AzureIoTClient 6:641a9672db08 639 {
AzureIoTClient 19:000ab4e6a2c1 640 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 641 set_message_sender_state(message_sender_instance, MESSAGE_SENDER_STATE_ERROR);
AzureIoTClient 6:641a9672db08 642 }
AzureIoTClient 6:641a9672db08 643 else
AzureIoTClient 6:641a9672db08 644 {
AzureIoTClient 6:641a9672db08 645 result = 0;
AzureIoTClient 6:641a9672db08 646 }
AzureIoTClient 6:641a9672db08 647 }
AzureIoTClient 6:641a9672db08 648 else
AzureIoTClient 6:641a9672db08 649 {
AzureIoTClient 6:641a9672db08 650 result = 0;
AzureIoTClient 6:641a9672db08 651 }
AzureIoTClient 6:641a9672db08 652 }
Azure.IoT Build 0:6ae2f7bca550 653
AzureIoTClient 6:641a9672db08 654 return result;
Azure.IoT Build 0:6ae2f7bca550 655 }
Azure.IoT Build 0:6ae2f7bca550 656
Azure.IoT Build 0:6ae2f7bca550 657 int messagesender_send(MESSAGE_SENDER_HANDLE message_sender, MESSAGE_HANDLE message, ON_MESSAGE_SEND_COMPLETE on_message_send_complete, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 658 {
AzureIoTClient 6:641a9672db08 659 int result;
Azure.IoT Build 0:6ae2f7bca550 660
AzureIoTClient 6:641a9672db08 661 if ((message_sender == NULL) ||
AzureIoTClient 6:641a9672db08 662 (message == NULL))
AzureIoTClient 6:641a9672db08 663 {
AzureIoTClient 19:000ab4e6a2c1 664 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 665 }
AzureIoTClient 6:641a9672db08 666 else
AzureIoTClient 6:641a9672db08 667 {
AzureIoTClient 6:641a9672db08 668 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_sender;
AzureIoTClient 6:641a9672db08 669 if (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_ERROR)
AzureIoTClient 6:641a9672db08 670 {
AzureIoTClient 19:000ab4e6a2c1 671 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 672 }
AzureIoTClient 6:641a9672db08 673 else
AzureIoTClient 6:641a9672db08 674 {
AzureIoTClient 6:641a9672db08 675 MESSAGE_WITH_CALLBACK* message_with_callback = (MESSAGE_WITH_CALLBACK*)amqpalloc_malloc(sizeof(MESSAGE_WITH_CALLBACK));
AzureIoTClient 6:641a9672db08 676 if (message_with_callback == NULL)
AzureIoTClient 6:641a9672db08 677 {
AzureIoTClient 19:000ab4e6a2c1 678 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 679 }
AzureIoTClient 6:641a9672db08 680 else
AzureIoTClient 6:641a9672db08 681 {
AzureIoTClient 6:641a9672db08 682 MESSAGE_WITH_CALLBACK** new_messages = (MESSAGE_WITH_CALLBACK**)amqpalloc_realloc(message_sender_instance->messages, sizeof(MESSAGE_WITH_CALLBACK*) * (message_sender_instance->message_count + 1));
AzureIoTClient 6:641a9672db08 683 if (new_messages == NULL)
AzureIoTClient 6:641a9672db08 684 {
AzureIoTClient 6:641a9672db08 685 amqpalloc_free(message_with_callback);
AzureIoTClient 19:000ab4e6a2c1 686 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 687 }
AzureIoTClient 6:641a9672db08 688 else
AzureIoTClient 6:641a9672db08 689 {
AzureIoTClient 6:641a9672db08 690 result = 0;
Azure.IoT Build 0:6ae2f7bca550 691
AzureIoTClient 6:641a9672db08 692 message_sender_instance->messages = new_messages;
AzureIoTClient 6:641a9672db08 693 if (message_sender_instance->message_sender_state != MESSAGE_SENDER_STATE_OPEN)
AzureIoTClient 6:641a9672db08 694 {
AzureIoTClient 6:641a9672db08 695 message_with_callback->message = message_clone(message);
AzureIoTClient 6:641a9672db08 696 if (message_with_callback->message == NULL)
AzureIoTClient 6:641a9672db08 697 {
AzureIoTClient 6:641a9672db08 698 amqpalloc_free(message_with_callback);
AzureIoTClient 19:000ab4e6a2c1 699 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 700 }
AzureIoTClient 6:641a9672db08 701
AzureIoTClient 6:641a9672db08 702 message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT;
AzureIoTClient 6:641a9672db08 703 }
AzureIoTClient 6:641a9672db08 704 else
AzureIoTClient 6:641a9672db08 705 {
AzureIoTClient 6:641a9672db08 706 message_with_callback->message = NULL;
AzureIoTClient 6:641a9672db08 707 message_with_callback->message_send_state = MESSAGE_SEND_STATE_PENDING;
AzureIoTClient 6:641a9672db08 708 }
Azure.IoT Build 0:6ae2f7bca550 709
AzureIoTClient 6:641a9672db08 710 if (result == 0)
AzureIoTClient 6:641a9672db08 711 {
AzureIoTClient 6:641a9672db08 712 message_with_callback->on_message_send_complete = on_message_send_complete;
AzureIoTClient 6:641a9672db08 713 message_with_callback->context = callback_context;
AzureIoTClient 6:641a9672db08 714 message_with_callback->message_sender = message_sender_instance;
AzureIoTClient 6:641a9672db08 715
AzureIoTClient 6:641a9672db08 716 message_sender_instance->messages[message_sender_instance->message_count] = message_with_callback;
AzureIoTClient 6:641a9672db08 717 message_sender_instance->message_count++;
Azure.IoT Build 0:6ae2f7bca550 718
AzureIoTClient 6:641a9672db08 719 if (message_sender_instance->message_sender_state == MESSAGE_SENDER_STATE_OPEN)
AzureIoTClient 6:641a9672db08 720 {
AzureIoTClient 6:641a9672db08 721 switch (send_one_message(message_sender_instance, message_with_callback, message))
AzureIoTClient 6:641a9672db08 722 {
AzureIoTClient 6:641a9672db08 723 default:
AzureIoTClient 6:641a9672db08 724 case SEND_ONE_MESSAGE_ERROR:
AzureIoTClient 18:a922a4a30a82 725
AzureIoTClient 18:a922a4a30a82 726 if (message_with_callback->on_message_send_complete != NULL)
AzureIoTClient 18:a922a4a30a82 727 {
AzureIoTClient 18:a922a4a30a82 728 message_with_callback->on_message_send_complete(message_with_callback->context, MESSAGE_SEND_ERROR);
AzureIoTClient 18:a922a4a30a82 729 }
AzureIoTClient 18:a922a4a30a82 730
AzureIoTClient 6:641a9672db08 731 remove_pending_message_by_index(message_sender_instance, message_sender_instance->message_count - 1);
AzureIoTClient 19:000ab4e6a2c1 732 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 733 break;
Azure.IoT Build 0:6ae2f7bca550 734
AzureIoTClient 6:641a9672db08 735 case SEND_ONE_MESSAGE_BUSY:
AzureIoTClient 6:641a9672db08 736 message_with_callback->message = message_clone(message);
AzureIoTClient 6:641a9672db08 737 if (message_with_callback->message == NULL)
AzureIoTClient 6:641a9672db08 738 {
AzureIoTClient 6:641a9672db08 739 amqpalloc_free(message_with_callback);
AzureIoTClient 19:000ab4e6a2c1 740 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 741 }
AzureIoTClient 6:641a9672db08 742 else
AzureIoTClient 6:641a9672db08 743 {
AzureIoTClient 6:641a9672db08 744 message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT;
AzureIoTClient 6:641a9672db08 745 result = 0;
AzureIoTClient 6:641a9672db08 746 }
AzureIoTClient 6:641a9672db08 747 break;
Azure.IoT Build 0:6ae2f7bca550 748
AzureIoTClient 6:641a9672db08 749 case SEND_ONE_MESSAGE_OK:
AzureIoTClient 6:641a9672db08 750 result = 0;
AzureIoTClient 6:641a9672db08 751 break;
AzureIoTClient 6:641a9672db08 752 }
AzureIoTClient 6:641a9672db08 753 }
AzureIoTClient 6:641a9672db08 754 }
AzureIoTClient 6:641a9672db08 755 }
AzureIoTClient 6:641a9672db08 756 }
AzureIoTClient 6:641a9672db08 757 }
AzureIoTClient 6:641a9672db08 758 }
AzureIoTClient 6:641a9672db08 759 return result;
AzureIoTClient 6:641a9672db08 760 }
Azure.IoT Build 0:6ae2f7bca550 761
AzureIoTClient 6:641a9672db08 762 void messagesender_set_trace(MESSAGE_SENDER_HANDLE message_sender, bool traceOn)
AzureIoTClient 6:641a9672db08 763 {
AzureIoTClient 6:641a9672db08 764 MESSAGE_SENDER_INSTANCE* message_sender_instance = (MESSAGE_SENDER_INSTANCE*)message_sender;
AzureIoTClient 6:641a9672db08 765 if (message_sender_instance != NULL)
AzureIoTClient 6:641a9672db08 766 {
AzureIoTClient 6:641a9672db08 767 message_sender_instance->is_trace_on = traceOn ? 1 : 0;
AzureIoTClient 6:641a9672db08 768 }
Azure.IoT Build 0:6ae2f7bca550 769 }