A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Thu Oct 04 09:16:13 2018 -0700
Revision:
47:365a93fdb5bb
Parent:
43:4c1e4e94cdd3
1.2.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
AzureIoTClient 20:206846c14c80 5
AzureIoTClient 19:000ab4e6a2c1 6 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 21:f9c433d8e6ca 7 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 27:d74f1cea23e1 8 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 40:f0ceafa8d570 9 #include "azure_uamqp_c/link.h"
AzureIoTClient 40:f0ceafa8d570 10 #include "azure_uamqp_c/amqp_definitions.h"
AzureIoTClient 40:f0ceafa8d570 11 #include "azure_uamqp_c/message.h"
Azure.IoT Build 0:6ae2f7bca550 12 #include "azure_uamqp_c/message_receiver.h"
Azure.IoT Build 0:6ae2f7bca550 13 #include "azure_uamqp_c/amqpvalue.h"
Azure.IoT Build 0:6ae2f7bca550 14
Azure.IoT Build 0:6ae2f7bca550 15 typedef struct MESSAGE_RECEIVER_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 16 {
AzureIoTClient 28:add19eb7defa 17 LINK_HANDLE link;
AzureIoTClient 28:add19eb7defa 18 ON_MESSAGE_RECEIVED on_message_received;
AzureIoTClient 28:add19eb7defa 19 ON_MESSAGE_RECEIVER_STATE_CHANGED on_message_receiver_state_changed;
AzureIoTClient 28:add19eb7defa 20 MESSAGE_RECEIVER_STATE message_receiver_state;
AzureIoTClient 28:add19eb7defa 21 const void* on_message_receiver_state_changed_context;
AzureIoTClient 28:add19eb7defa 22 const void* callback_context;
AzureIoTClient 28:add19eb7defa 23 MESSAGE_HANDLE decoded_message;
AzureIoTClient 28:add19eb7defa 24 bool decode_error;
Azure.IoT Build 0:6ae2f7bca550 25 } MESSAGE_RECEIVER_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 26
AzureIoTClient 34:6be9c2058664 27 static void set_message_receiver_state(MESSAGE_RECEIVER_INSTANCE* message_receiver, MESSAGE_RECEIVER_STATE new_state)
Azure.IoT Build 0:6ae2f7bca550 28 {
AzureIoTClient 34:6be9c2058664 29 MESSAGE_RECEIVER_STATE previous_state = message_receiver->message_receiver_state;
AzureIoTClient 34:6be9c2058664 30 message_receiver->message_receiver_state = new_state;
AzureIoTClient 34:6be9c2058664 31 if (message_receiver->on_message_receiver_state_changed != NULL)
AzureIoTClient 28:add19eb7defa 32 {
AzureIoTClient 34:6be9c2058664 33 message_receiver->on_message_receiver_state_changed(message_receiver->on_message_receiver_state_changed_context, new_state, previous_state);
AzureIoTClient 28:add19eb7defa 34 }
Azure.IoT Build 0:6ae2f7bca550 35 }
Azure.IoT Build 0:6ae2f7bca550 36
Azure.IoT Build 0:6ae2f7bca550 37 static void decode_message_value_callback(void* context, AMQP_VALUE decoded_value)
Azure.IoT Build 0:6ae2f7bca550 38 {
AzureIoTClient 34:6be9c2058664 39 MESSAGE_RECEIVER_INSTANCE* message_receiver = (MESSAGE_RECEIVER_INSTANCE*)context;
AzureIoTClient 34:6be9c2058664 40 MESSAGE_HANDLE decoded_message = message_receiver->decoded_message;
AzureIoTClient 28:add19eb7defa 41 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(decoded_value);
Azure.IoT Build 0:6ae2f7bca550 42
AzureIoTClient 28:add19eb7defa 43 if (is_application_properties_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 44 {
AzureIoTClient 28:add19eb7defa 45 if (message_set_application_properties(decoded_message, decoded_value) != 0)
AzureIoTClient 28:add19eb7defa 46 {
AzureIoTClient 34:6be9c2058664 47 LogError("Error setting application properties on received message");
AzureIoTClient 34:6be9c2058664 48 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 49 }
AzureIoTClient 28:add19eb7defa 50 }
AzureIoTClient 28:add19eb7defa 51 else if (is_properties_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 52 {
AzureIoTClient 28:add19eb7defa 53 PROPERTIES_HANDLE properties;
AzureIoTClient 28:add19eb7defa 54 if (amqpvalue_get_properties(decoded_value, &properties) != 0)
AzureIoTClient 28:add19eb7defa 55 {
AzureIoTClient 34:6be9c2058664 56 LogError("Error getting message properties");
AzureIoTClient 34:6be9c2058664 57 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 58 }
AzureIoTClient 28:add19eb7defa 59 else
AzureIoTClient 28:add19eb7defa 60 {
AzureIoTClient 28:add19eb7defa 61 if (message_set_properties(decoded_message, properties) != 0)
AzureIoTClient 28:add19eb7defa 62 {
AzureIoTClient 34:6be9c2058664 63 LogError("Error setting message properties on received message");
AzureIoTClient 34:6be9c2058664 64 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 65 }
Azure.IoT Build 0:6ae2f7bca550 66
AzureIoTClient 28:add19eb7defa 67 properties_destroy(properties);
AzureIoTClient 28:add19eb7defa 68 }
AzureIoTClient 28:add19eb7defa 69 }
AzureIoTClient 28:add19eb7defa 70 else if (is_delivery_annotations_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 71 {
AzureIoTClient 28:add19eb7defa 72 annotations delivery_annotations = amqpvalue_get_inplace_described_value(decoded_value);
AzureIoTClient 34:6be9c2058664 73 if (delivery_annotations == NULL)
AzureIoTClient 28:add19eb7defa 74 {
AzureIoTClient 34:6be9c2058664 75 LogError("Error getting delivery annotations");
AzureIoTClient 34:6be9c2058664 76 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 77 }
AzureIoTClient 34:6be9c2058664 78 else
AzureIoTClient 34:6be9c2058664 79 {
AzureIoTClient 34:6be9c2058664 80 if (message_set_delivery_annotations(decoded_message, delivery_annotations) != 0)
AzureIoTClient 34:6be9c2058664 81 {
AzureIoTClient 34:6be9c2058664 82 LogError("Error setting delivery annotations on received message");
AzureIoTClient 34:6be9c2058664 83 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 84 }
AzureIoTClient 28:add19eb7defa 85 }
AzureIoTClient 28:add19eb7defa 86 }
AzureIoTClient 28:add19eb7defa 87 else if (is_message_annotations_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 88 {
AzureIoTClient 28:add19eb7defa 89 annotations message_annotations = amqpvalue_get_inplace_described_value(decoded_value);
AzureIoTClient 34:6be9c2058664 90 if (message_annotations == NULL)
AzureIoTClient 28:add19eb7defa 91 {
AzureIoTClient 34:6be9c2058664 92 LogError("Error getting message annotations");
AzureIoTClient 34:6be9c2058664 93 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 94 }
AzureIoTClient 34:6be9c2058664 95 else
AzureIoTClient 34:6be9c2058664 96 {
AzureIoTClient 34:6be9c2058664 97 if (message_set_message_annotations(decoded_message, message_annotations) != 0)
AzureIoTClient 34:6be9c2058664 98 {
AzureIoTClient 34:6be9c2058664 99 LogError("Error setting message annotations on received message");
AzureIoTClient 34:6be9c2058664 100 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 101 }
AzureIoTClient 28:add19eb7defa 102 }
AzureIoTClient 28:add19eb7defa 103 }
AzureIoTClient 28:add19eb7defa 104 else if (is_header_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 105 {
AzureIoTClient 28:add19eb7defa 106 HEADER_HANDLE header;
AzureIoTClient 28:add19eb7defa 107 if (amqpvalue_get_header(decoded_value, &header) != 0)
AzureIoTClient 28:add19eb7defa 108 {
AzureIoTClient 34:6be9c2058664 109 LogError("Error getting message header");
AzureIoTClient 34:6be9c2058664 110 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 111 }
AzureIoTClient 28:add19eb7defa 112 else
AzureIoTClient 28:add19eb7defa 113 {
AzureIoTClient 28:add19eb7defa 114 if (message_set_header(decoded_message, header) != 0)
AzureIoTClient 28:add19eb7defa 115 {
AzureIoTClient 34:6be9c2058664 116 LogError("Error setting message header on received message");
AzureIoTClient 34:6be9c2058664 117 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 118 }
Azure.IoT Build 0:6ae2f7bca550 119
AzureIoTClient 28:add19eb7defa 120 header_destroy(header);
AzureIoTClient 28:add19eb7defa 121 }
AzureIoTClient 28:add19eb7defa 122 }
AzureIoTClient 28:add19eb7defa 123 else if (is_footer_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 124 {
AzureIoTClient 28:add19eb7defa 125 annotations footer = amqpvalue_get_inplace_described_value(decoded_value);
AzureIoTClient 34:6be9c2058664 126 if (footer == NULL)
AzureIoTClient 28:add19eb7defa 127 {
AzureIoTClient 34:6be9c2058664 128 LogError("Error getting message footer");
AzureIoTClient 34:6be9c2058664 129 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 130 }
AzureIoTClient 34:6be9c2058664 131 else
AzureIoTClient 34:6be9c2058664 132 {
AzureIoTClient 34:6be9c2058664 133 if (message_set_footer(decoded_message, footer) != 0)
AzureIoTClient 34:6be9c2058664 134 {
AzureIoTClient 34:6be9c2058664 135 LogError("Error setting message footer on received message");
AzureIoTClient 34:6be9c2058664 136 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 137 }
AzureIoTClient 28:add19eb7defa 138 }
AzureIoTClient 28:add19eb7defa 139 }
AzureIoTClient 28:add19eb7defa 140 else if (is_amqp_value_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 141 {
AzureIoTClient 28:add19eb7defa 142 MESSAGE_BODY_TYPE body_type;
AzureIoTClient 34:6be9c2058664 143 if (message_get_body_type(decoded_message, &body_type) != 0)
AzureIoTClient 28:add19eb7defa 144 {
AzureIoTClient 34:6be9c2058664 145 LogError("Error getting message body type");
AzureIoTClient 34:6be9c2058664 146 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 147 }
AzureIoTClient 28:add19eb7defa 148 else
AzureIoTClient 28:add19eb7defa 149 {
AzureIoTClient 34:6be9c2058664 150 if (body_type != MESSAGE_BODY_TYPE_NONE)
AzureIoTClient 34:6be9c2058664 151 {
AzureIoTClient 34:6be9c2058664 152 LogError("Body already set on received message");
AzureIoTClient 34:6be9c2058664 153 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 154 }
AzureIoTClient 34:6be9c2058664 155 else
AzureIoTClient 28:add19eb7defa 156 {
AzureIoTClient 34:6be9c2058664 157 AMQP_VALUE body_amqp_value = amqpvalue_get_inplace_described_value(decoded_value);
AzureIoTClient 34:6be9c2058664 158 if (body_amqp_value == NULL)
AzureIoTClient 34:6be9c2058664 159 {
AzureIoTClient 34:6be9c2058664 160 LogError("Error getting body AMQP value");
AzureIoTClient 34:6be9c2058664 161 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 162 }
AzureIoTClient 34:6be9c2058664 163 else
AzureIoTClient 34:6be9c2058664 164 {
AzureIoTClient 34:6be9c2058664 165 if (message_set_body_amqp_value(decoded_message, body_amqp_value) != 0)
AzureIoTClient 34:6be9c2058664 166 {
AzureIoTClient 34:6be9c2058664 167 LogError("Error setting body AMQP value on received message");
AzureIoTClient 34:6be9c2058664 168 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 169 }
AzureIoTClient 34:6be9c2058664 170 }
AzureIoTClient 28:add19eb7defa 171 }
AzureIoTClient 28:add19eb7defa 172 }
AzureIoTClient 28:add19eb7defa 173 }
AzureIoTClient 28:add19eb7defa 174 else if (is_data_type_by_descriptor(descriptor))
AzureIoTClient 28:add19eb7defa 175 {
AzureIoTClient 28:add19eb7defa 176 MESSAGE_BODY_TYPE body_type;
AzureIoTClient 34:6be9c2058664 177 if (message_get_body_type(decoded_message, &body_type) != 0)
AzureIoTClient 28:add19eb7defa 178 {
AzureIoTClient 34:6be9c2058664 179 LogError("Error getting message body type");
AzureIoTClient 34:6be9c2058664 180 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 181 }
AzureIoTClient 28:add19eb7defa 182 else
AzureIoTClient 28:add19eb7defa 183 {
AzureIoTClient 34:6be9c2058664 184 if ((body_type != MESSAGE_BODY_TYPE_NONE) &&
AzureIoTClient 34:6be9c2058664 185 (body_type != MESSAGE_BODY_TYPE_DATA))
AzureIoTClient 28:add19eb7defa 186 {
AzureIoTClient 34:6be9c2058664 187 LogError("Message body type already set to something different than AMQP DATA");
AzureIoTClient 34:6be9c2058664 188 message_receiver->decode_error = true;
AzureIoTClient 28:add19eb7defa 189 }
AzureIoTClient 28:add19eb7defa 190 else
AzureIoTClient 28:add19eb7defa 191 {
AzureIoTClient 34:6be9c2058664 192 AMQP_VALUE body_data_value = amqpvalue_get_inplace_described_value(decoded_value);
AzureIoTClient 34:6be9c2058664 193 if (body_data_value == NULL)
AzureIoTClient 34:6be9c2058664 194 {
AzureIoTClient 34:6be9c2058664 195 LogError("Error getting body DATA value");
AzureIoTClient 34:6be9c2058664 196 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 197 }
AzureIoTClient 34:6be9c2058664 198 else
AzureIoTClient 28:add19eb7defa 199 {
AzureIoTClient 34:6be9c2058664 200 data data_value;
AzureIoTClient 34:6be9c2058664 201 if (amqpvalue_get_data(body_data_value, &data_value) != 0)
AzureIoTClient 34:6be9c2058664 202 {
AzureIoTClient 34:6be9c2058664 203 LogError("Error getting body DATA AMQP value");
AzureIoTClient 34:6be9c2058664 204 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 205 }
AzureIoTClient 34:6be9c2058664 206 else
AzureIoTClient 34:6be9c2058664 207 {
AzureIoTClient 34:6be9c2058664 208 BINARY_DATA binary_data;
AzureIoTClient 34:6be9c2058664 209 binary_data.bytes = (const unsigned char*)data_value.bytes;
AzureIoTClient 34:6be9c2058664 210 binary_data.length = data_value.length;
AzureIoTClient 34:6be9c2058664 211 if (message_add_body_amqp_data(decoded_message, binary_data) != 0)
AzureIoTClient 34:6be9c2058664 212 {
AzureIoTClient 34:6be9c2058664 213 LogError("Error adding body DATA to received message");
AzureIoTClient 34:6be9c2058664 214 message_receiver->decode_error = true;
AzureIoTClient 34:6be9c2058664 215 }
AzureIoTClient 34:6be9c2058664 216 }
AzureIoTClient 28:add19eb7defa 217 }
AzureIoTClient 28:add19eb7defa 218 }
AzureIoTClient 28:add19eb7defa 219 }
AzureIoTClient 28:add19eb7defa 220 }
Azure.IoT Build 0:6ae2f7bca550 221 }
Azure.IoT Build 0:6ae2f7bca550 222
Azure.IoT Build 0:6ae2f7bca550 223 static AMQP_VALUE on_transfer_received(void* context, TRANSFER_HANDLE transfer, uint32_t payload_size, const unsigned char* payload_bytes)
Azure.IoT Build 0:6ae2f7bca550 224 {
AzureIoTClient 28:add19eb7defa 225 AMQP_VALUE result = NULL;
AzureIoTClient 34:6be9c2058664 226 MESSAGE_RECEIVER_INSTANCE* message_receiver = (MESSAGE_RECEIVER_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 227
AzureIoTClient 6:641a9672db08 228 (void)transfer;
AzureIoTClient 34:6be9c2058664 229 if (message_receiver->on_message_received != NULL)
AzureIoTClient 28:add19eb7defa 230 {
AzureIoTClient 28:add19eb7defa 231 MESSAGE_HANDLE message = message_create();
AzureIoTClient 28:add19eb7defa 232 if (message == NULL)
AzureIoTClient 28:add19eb7defa 233 {
AzureIoTClient 34:6be9c2058664 234 LogError("Cannot create message");
AzureIoTClient 34:6be9c2058664 235 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 236 }
AzureIoTClient 28:add19eb7defa 237 else
AzureIoTClient 28:add19eb7defa 238 {
AzureIoTClient 34:6be9c2058664 239 AMQPVALUE_DECODER_HANDLE amqpvalue_decoder = amqpvalue_decoder_create(decode_message_value_callback, message_receiver);
AzureIoTClient 28:add19eb7defa 240 if (amqpvalue_decoder == NULL)
AzureIoTClient 28:add19eb7defa 241 {
AzureIoTClient 34:6be9c2058664 242 LogError("Cannot create AMQP value decoder");
AzureIoTClient 34:6be9c2058664 243 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 244 }
AzureIoTClient 28:add19eb7defa 245 else
AzureIoTClient 28:add19eb7defa 246 {
AzureIoTClient 34:6be9c2058664 247 message_receiver->decoded_message = message;
AzureIoTClient 34:6be9c2058664 248 message_receiver->decode_error = false;
AzureIoTClient 28:add19eb7defa 249 if (amqpvalue_decode_bytes(amqpvalue_decoder, payload_bytes, payload_size) != 0)
AzureIoTClient 28:add19eb7defa 250 {
AzureIoTClient 34:6be9c2058664 251 LogError("Cannot decode bytes");
AzureIoTClient 34:6be9c2058664 252 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 253 }
AzureIoTClient 28:add19eb7defa 254 else
AzureIoTClient 28:add19eb7defa 255 {
AzureIoTClient 34:6be9c2058664 256 if (message_receiver->decode_error)
AzureIoTClient 28:add19eb7defa 257 {
AzureIoTClient 34:6be9c2058664 258 LogError("Error decoding message");
AzureIoTClient 34:6be9c2058664 259 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 260 }
AzureIoTClient 28:add19eb7defa 261 else
AzureIoTClient 28:add19eb7defa 262 {
AzureIoTClient 34:6be9c2058664 263 result = message_receiver->on_message_received(message_receiver->callback_context, message);
AzureIoTClient 28:add19eb7defa 264 }
AzureIoTClient 28:add19eb7defa 265 }
Azure.IoT Build 0:6ae2f7bca550 266
AzureIoTClient 28:add19eb7defa 267 amqpvalue_decoder_destroy(amqpvalue_decoder);
AzureIoTClient 28:add19eb7defa 268 }
Azure.IoT Build 0:6ae2f7bca550 269
AzureIoTClient 28:add19eb7defa 270 message_destroy(message);
AzureIoTClient 28:add19eb7defa 271 }
AzureIoTClient 28:add19eb7defa 272 }
Azure.IoT Build 0:6ae2f7bca550 273
AzureIoTClient 28:add19eb7defa 274 return result;
Azure.IoT Build 0:6ae2f7bca550 275 }
Azure.IoT Build 0:6ae2f7bca550 276
Azure.IoT Build 0:6ae2f7bca550 277 static void on_link_state_changed(void* context, LINK_STATE new_link_state, LINK_STATE previous_link_state)
Azure.IoT Build 0:6ae2f7bca550 278 {
AzureIoTClient 34:6be9c2058664 279 MESSAGE_RECEIVER_INSTANCE* message_receiver = (MESSAGE_RECEIVER_INSTANCE*)context;
AzureIoTClient 6:641a9672db08 280 (void)previous_link_state;
Azure.IoT Build 0:6ae2f7bca550 281
AzureIoTClient 28:add19eb7defa 282 switch (new_link_state)
AzureIoTClient 28:add19eb7defa 283 {
AzureIoTClient 17:923575db8b2d 284 default:
AzureIoTClient 17:923575db8b2d 285 break;
AzureIoTClient 17:923575db8b2d 286
AzureIoTClient 28:add19eb7defa 287 case LINK_STATE_ATTACHED:
AzureIoTClient 34:6be9c2058664 288 if (message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_OPENING)
AzureIoTClient 28:add19eb7defa 289 {
AzureIoTClient 34:6be9c2058664 290 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_OPEN);
AzureIoTClient 28:add19eb7defa 291 }
AzureIoTClient 28:add19eb7defa 292 break;
AzureIoTClient 28:add19eb7defa 293 case LINK_STATE_DETACHED:
AzureIoTClient 34:6be9c2058664 294 if ((message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_OPEN) ||
AzureIoTClient 34:6be9c2058664 295 (message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_CLOSING))
Azure.IoT Build 0:6ae2f7bca550 296 {
Azure.IoT Build 0:6ae2f7bca550 297 /* User initiated transition, we should be good */
AzureIoTClient 34:6be9c2058664 298 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_IDLE);
Azure.IoT Build 0:6ae2f7bca550 299 }
AzureIoTClient 34:6be9c2058664 300 else if (message_receiver->message_receiver_state != MESSAGE_RECEIVER_STATE_IDLE)
Azure.IoT Build 0:6ae2f7bca550 301 {
Azure.IoT Build 0:6ae2f7bca550 302 /* Any other transition must be an error */
AzureIoTClient 34:6be9c2058664 303 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
Azure.IoT Build 0:6ae2f7bca550 304 }
Azure.IoT Build 0:6ae2f7bca550 305 break;
AzureIoTClient 1:eab586236bfe 306 case LINK_STATE_ERROR:
AzureIoTClient 34:6be9c2058664 307 if (message_receiver->message_receiver_state != MESSAGE_RECEIVER_STATE_ERROR)
AzureIoTClient 1:eab586236bfe 308 {
AzureIoTClient 34:6be9c2058664 309 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 1:eab586236bfe 310 }
AzureIoTClient 1:eab586236bfe 311 break;
AzureIoTClient 28:add19eb7defa 312 }
Azure.IoT Build 0:6ae2f7bca550 313 }
Azure.IoT Build 0:6ae2f7bca550 314
Azure.IoT Build 0:6ae2f7bca550 315 MESSAGE_RECEIVER_HANDLE messagereceiver_create(LINK_HANDLE link, ON_MESSAGE_RECEIVER_STATE_CHANGED on_message_receiver_state_changed, void* context)
Azure.IoT Build 0:6ae2f7bca550 316 {
AzureIoTClient 34:6be9c2058664 317 MESSAGE_RECEIVER_INSTANCE* message_receiver = (MESSAGE_RECEIVER_INSTANCE*)malloc(sizeof(MESSAGE_RECEIVER_INSTANCE));
AzureIoTClient 34:6be9c2058664 318 if (message_receiver == NULL)
AzureIoTClient 28:add19eb7defa 319 {
AzureIoTClient 34:6be9c2058664 320 LogError("Error creating message receiver");
AzureIoTClient 34:6be9c2058664 321 }
AzureIoTClient 34:6be9c2058664 322 else
AzureIoTClient 34:6be9c2058664 323 {
AzureIoTClient 34:6be9c2058664 324 message_receiver->link = link;
AzureIoTClient 34:6be9c2058664 325 message_receiver->on_message_receiver_state_changed = on_message_receiver_state_changed;
AzureIoTClient 34:6be9c2058664 326 message_receiver->on_message_receiver_state_changed_context = context;
AzureIoTClient 34:6be9c2058664 327 message_receiver->message_receiver_state = MESSAGE_RECEIVER_STATE_IDLE;
AzureIoTClient 28:add19eb7defa 328 }
Azure.IoT Build 0:6ae2f7bca550 329
AzureIoTClient 34:6be9c2058664 330 return message_receiver;
Azure.IoT Build 0:6ae2f7bca550 331 }
Azure.IoT Build 0:6ae2f7bca550 332
Azure.IoT Build 0:6ae2f7bca550 333 void messagereceiver_destroy(MESSAGE_RECEIVER_HANDLE message_receiver)
Azure.IoT Build 0:6ae2f7bca550 334 {
AzureIoTClient 34:6be9c2058664 335 if (message_receiver == NULL)
AzureIoTClient 34:6be9c2058664 336 {
AzureIoTClient 34:6be9c2058664 337 LogError("NULL message_receiver");
AzureIoTClient 34:6be9c2058664 338 }
AzureIoTClient 34:6be9c2058664 339 else
AzureIoTClient 28:add19eb7defa 340 {
AzureIoTClient 28:add19eb7defa 341 (void)messagereceiver_close(message_receiver);
AzureIoTClient 28:add19eb7defa 342 free(message_receiver);
AzureIoTClient 28:add19eb7defa 343 }
Azure.IoT Build 0:6ae2f7bca550 344 }
Azure.IoT Build 0:6ae2f7bca550 345
AzureIoTClient 23:1111ee8bcba4 346 int messagereceiver_open(MESSAGE_RECEIVER_HANDLE message_receiver, ON_MESSAGE_RECEIVED on_message_received, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 347 {
AzureIoTClient 28:add19eb7defa 348 int result;
Azure.IoT Build 0:6ae2f7bca550 349
AzureIoTClient 28:add19eb7defa 350 if (message_receiver == NULL)
AzureIoTClient 28:add19eb7defa 351 {
AzureIoTClient 34:6be9c2058664 352 LogError("NULL message_receiver");
AzureIoTClient 28:add19eb7defa 353 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 354 }
AzureIoTClient 28:add19eb7defa 355 else
AzureIoTClient 28:add19eb7defa 356 {
AzureIoTClient 34:6be9c2058664 357 if (message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_IDLE)
AzureIoTClient 28:add19eb7defa 358 {
AzureIoTClient 34:6be9c2058664 359 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_OPENING);
AzureIoTClient 34:6be9c2058664 360 if (link_attach(message_receiver->link, on_transfer_received, on_link_state_changed, NULL, message_receiver) != 0)
AzureIoTClient 28:add19eb7defa 361 {
AzureIoTClient 34:6be9c2058664 362 LogError("Link attach failed");
AzureIoTClient 28:add19eb7defa 363 result = __FAILURE__;
AzureIoTClient 34:6be9c2058664 364 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 365 }
AzureIoTClient 28:add19eb7defa 366 else
AzureIoTClient 28:add19eb7defa 367 {
AzureIoTClient 34:6be9c2058664 368 message_receiver->on_message_received = on_message_received;
AzureIoTClient 34:6be9c2058664 369 message_receiver->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 370
AzureIoTClient 28:add19eb7defa 371 result = 0;
AzureIoTClient 28:add19eb7defa 372 }
AzureIoTClient 28:add19eb7defa 373 }
AzureIoTClient 28:add19eb7defa 374 else
AzureIoTClient 28:add19eb7defa 375 {
AzureIoTClient 28:add19eb7defa 376 result = 0;
AzureIoTClient 28:add19eb7defa 377 }
AzureIoTClient 28:add19eb7defa 378 }
Azure.IoT Build 0:6ae2f7bca550 379
AzureIoTClient 28:add19eb7defa 380 return result;
Azure.IoT Build 0:6ae2f7bca550 381 }
Azure.IoT Build 0:6ae2f7bca550 382
Azure.IoT Build 0:6ae2f7bca550 383 int messagereceiver_close(MESSAGE_RECEIVER_HANDLE message_receiver)
Azure.IoT Build 0:6ae2f7bca550 384 {
AzureIoTClient 28:add19eb7defa 385 int result;
Azure.IoT Build 0:6ae2f7bca550 386
AzureIoTClient 28:add19eb7defa 387 if (message_receiver == NULL)
AzureIoTClient 28:add19eb7defa 388 {
AzureIoTClient 34:6be9c2058664 389 LogError("NULL message_receiver");
AzureIoTClient 28:add19eb7defa 390 result = __FAILURE__;
AzureIoTClient 28:add19eb7defa 391 }
AzureIoTClient 28:add19eb7defa 392 else
AzureIoTClient 28:add19eb7defa 393 {
AzureIoTClient 34:6be9c2058664 394 if ((message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_OPENING) ||
AzureIoTClient 34:6be9c2058664 395 (message_receiver->message_receiver_state == MESSAGE_RECEIVER_STATE_OPEN))
AzureIoTClient 28:add19eb7defa 396 {
AzureIoTClient 34:6be9c2058664 397 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_CLOSING);
Azure.IoT Build 0:6ae2f7bca550 398
AzureIoTClient 43:4c1e4e94cdd3 399 if (link_detach(message_receiver->link, true, NULL, NULL, NULL) != 0)
AzureIoTClient 28:add19eb7defa 400 {
AzureIoTClient 34:6be9c2058664 401 LogError("link detach failed");
AzureIoTClient 28:add19eb7defa 402 result = __FAILURE__;
AzureIoTClient 34:6be9c2058664 403 set_message_receiver_state(message_receiver, MESSAGE_RECEIVER_STATE_ERROR);
AzureIoTClient 28:add19eb7defa 404 }
AzureIoTClient 28:add19eb7defa 405 else
AzureIoTClient 28:add19eb7defa 406 {
AzureIoTClient 28:add19eb7defa 407 result = 0;
AzureIoTClient 28:add19eb7defa 408 }
AzureIoTClient 28:add19eb7defa 409 }
AzureIoTClient 28:add19eb7defa 410 else
AzureIoTClient 28:add19eb7defa 411 {
AzureIoTClient 28:add19eb7defa 412 result = 0;
AzureIoTClient 28:add19eb7defa 413 }
AzureIoTClient 28:add19eb7defa 414 }
Azure.IoT Build 0:6ae2f7bca550 415
AzureIoTClient 28:add19eb7defa 416 return result;
Azure.IoT Build 0:6ae2f7bca550 417 }
AzureIoTClient 20:206846c14c80 418
AzureIoTClient 20:206846c14c80 419 int messagereceiver_get_link_name(MESSAGE_RECEIVER_HANDLE message_receiver, const char** link_name)
AzureIoTClient 20:206846c14c80 420 {
AzureIoTClient 20:206846c14c80 421 int result;
AzureIoTClient 20:206846c14c80 422
AzureIoTClient 20:206846c14c80 423 if (message_receiver == NULL)
AzureIoTClient 20:206846c14c80 424 {
AzureIoTClient 34:6be9c2058664 425 LogError("NULL message_receiver");
AzureIoTClient 20:206846c14c80 426 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 427 }
AzureIoTClient 20:206846c14c80 428 else
AzureIoTClient 20:206846c14c80 429 {
AzureIoTClient 34:6be9c2058664 430 if (link_get_name(message_receiver->link, link_name) != 0)
AzureIoTClient 20:206846c14c80 431 {
AzureIoTClient 34:6be9c2058664 432 LogError("Getting link name failed");
AzureIoTClient 20:206846c14c80 433 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 434 }
AzureIoTClient 20:206846c14c80 435 else
AzureIoTClient 20:206846c14c80 436 {
AzureIoTClient 20:206846c14c80 437 result = 0;
AzureIoTClient 20:206846c14c80 438 }
AzureIoTClient 20:206846c14c80 439 }
AzureIoTClient 20:206846c14c80 440
AzureIoTClient 20:206846c14c80 441 return result;
AzureIoTClient 20:206846c14c80 442 }
AzureIoTClient 20:206846c14c80 443
AzureIoTClient 20:206846c14c80 444 int messagereceiver_get_received_message_id(MESSAGE_RECEIVER_HANDLE message_receiver, delivery_number* message_id)
AzureIoTClient 20:206846c14c80 445 {
AzureIoTClient 20:206846c14c80 446 int result;
AzureIoTClient 20:206846c14c80 447
AzureIoTClient 20:206846c14c80 448 if (message_receiver == NULL)
AzureIoTClient 20:206846c14c80 449 {
AzureIoTClient 34:6be9c2058664 450 LogError("NULL message_receiver");
AzureIoTClient 20:206846c14c80 451 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 452 }
AzureIoTClient 20:206846c14c80 453 else
AzureIoTClient 20:206846c14c80 454 {
AzureIoTClient 34:6be9c2058664 455 if (link_get_received_message_id(message_receiver->link, message_id) != 0)
AzureIoTClient 20:206846c14c80 456 {
AzureIoTClient 34:6be9c2058664 457 LogError("Failed getting received message Id");
AzureIoTClient 20:206846c14c80 458 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 459 }
AzureIoTClient 20:206846c14c80 460 else
AzureIoTClient 20:206846c14c80 461 {
AzureIoTClient 20:206846c14c80 462 result = 0;
AzureIoTClient 20:206846c14c80 463 }
AzureIoTClient 20:206846c14c80 464 }
AzureIoTClient 20:206846c14c80 465
AzureIoTClient 20:206846c14c80 466 return result;
AzureIoTClient 20:206846c14c80 467 }
AzureIoTClient 20:206846c14c80 468
AzureIoTClient 20:206846c14c80 469 int messagereceiver_send_message_disposition(MESSAGE_RECEIVER_HANDLE message_receiver, const char* link_name, delivery_number message_number, AMQP_VALUE delivery_state)
AzureIoTClient 20:206846c14c80 470 {
AzureIoTClient 20:206846c14c80 471 int result;
AzureIoTClient 20:206846c14c80 472
AzureIoTClient 20:206846c14c80 473 if (message_receiver == NULL)
AzureIoTClient 20:206846c14c80 474 {
AzureIoTClient 34:6be9c2058664 475 LogError("NULL message_receiver");
AzureIoTClient 20:206846c14c80 476 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 477 }
AzureIoTClient 20:206846c14c80 478 else
AzureIoTClient 20:206846c14c80 479 {
AzureIoTClient 34:6be9c2058664 480 if (message_receiver->message_receiver_state != MESSAGE_RECEIVER_STATE_OPEN)
AzureIoTClient 20:206846c14c80 481 {
AzureIoTClient 34:6be9c2058664 482 LogError("Message received not open");
AzureIoTClient 20:206846c14c80 483 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 484 }
AzureIoTClient 20:206846c14c80 485 else
AzureIoTClient 20:206846c14c80 486 {
AzureIoTClient 20:206846c14c80 487 const char* my_name;
AzureIoTClient 34:6be9c2058664 488 if (link_get_name(message_receiver->link, &my_name) != 0)
AzureIoTClient 20:206846c14c80 489 {
AzureIoTClient 34:6be9c2058664 490 LogError("Failed getting link name");
AzureIoTClient 20:206846c14c80 491 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 492 }
AzureIoTClient 20:206846c14c80 493 else
AzureIoTClient 20:206846c14c80 494 {
AzureIoTClient 20:206846c14c80 495 if (strcmp(link_name, my_name) != 0)
AzureIoTClient 20:206846c14c80 496 {
AzureIoTClient 34:6be9c2058664 497 LogError("Link name does not match");
AzureIoTClient 20:206846c14c80 498 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 499 }
AzureIoTClient 20:206846c14c80 500 else
AzureIoTClient 20:206846c14c80 501 {
AzureIoTClient 34:6be9c2058664 502 if (link_send_disposition(message_receiver->link, message_number, delivery_state) != 0)
AzureIoTClient 20:206846c14c80 503 {
AzureIoTClient 34:6be9c2058664 504 LogError("Seding disposition failed");
AzureIoTClient 20:206846c14c80 505 result = __FAILURE__;
AzureIoTClient 20:206846c14c80 506 }
AzureIoTClient 20:206846c14c80 507 else
AzureIoTClient 20:206846c14c80 508 {
AzureIoTClient 20:206846c14c80 509 result = 0;
AzureIoTClient 20:206846c14c80 510 }
AzureIoTClient 20:206846c14c80 511 }
AzureIoTClient 20:206846c14c80 512 }
AzureIoTClient 20:206846c14c80 513 }
AzureIoTClient 20:206846c14c80 514 }
AzureIoTClient 20:206846c14c80 515
AzureIoTClient 20:206846c14c80 516 return result;
AzureIoTClient 20:206846c14c80 517 }
AzureIoTClient 23:1111ee8bcba4 518
AzureIoTClient 23:1111ee8bcba4 519 void messagereceiver_set_trace(MESSAGE_RECEIVER_HANDLE message_receiver, bool trace_on)
AzureIoTClient 23:1111ee8bcba4 520 {
AzureIoTClient 34:6be9c2058664 521 if (message_receiver == NULL)
AzureIoTClient 34:6be9c2058664 522 {
AzureIoTClient 34:6be9c2058664 523 LogError("NULL message_receiver");
AzureIoTClient 34:6be9c2058664 524 }
AzureIoTClient 34:6be9c2058664 525 else
AzureIoTClient 34:6be9c2058664 526 {
AzureIoTClient 34:6be9c2058664 527 /* No tracing is yet implemented for message receiver */
AzureIoTClient 34:6be9c2058664 528 (void)trace_on;
AzureIoTClient 34:6be9c2058664 529 }
AzureIoTClient 23:1111ee8bcba4 530 }