Demo using MBED TLS

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Committer:
markrad
Date:
Thu Jan 05 00:20:03 2017 +0000
Revision:
58:f50b97b08851
Sample using MBED TLS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 58:f50b97b08851 1 // Copyright (c) Microsoft. All rights reserved.
markrad 58:f50b97b08851 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
markrad 58:f50b97b08851 3
markrad 58:f50b97b08851 4 #include <stdlib.h>
markrad 58:f50b97b08851 5 #ifdef _CRTDBG_MAP_ALLOC
markrad 58:f50b97b08851 6 #include <crtdbg.h>
markrad 58:f50b97b08851 7 #endif
markrad 58:f50b97b08851 8 #include "azure_uamqp_c/message_receiver.h"
markrad 58:f50b97b08851 9 #include "azure_uamqp_c/amqpalloc.h"
markrad 58:f50b97b08851 10 #include "azure_uamqp_c/amqpvalue.h"
markrad 58:f50b97b08851 11 #include "azure_uamqp_c/amqp_definitions.h"
markrad 58:f50b97b08851 12
markrad 58:f50b97b08851 13 typedef struct MESSAGE_RECEIVER_INSTANCE_TAG
markrad 58:f50b97b08851 14 {
markrad 58:f50b97b08851 15 LINK_HANDLE link;
markrad 58:f50b97b08851 16 ON_MESSAGE_RECEIVED on_message_received;
markrad 58:f50b97b08851 17 ON_MESSAGE_RECEIVER_STATE_CHANGED on_message_receiver_state_changed;
markrad 58:f50b97b08851 18 MESSAGE_RECEIVER_STATE message_receiver_state;
markrad 58:f50b97b08851 19 const void* on_message_receiver_state_changed_context;
markrad 58:f50b97b08851 20 const void* callback_context;
markrad 58:f50b97b08851 21 MESSAGE_HANDLE decoded_message;
markrad 58:f50b97b08851 22 bool decode_error;
markrad 58:f50b97b08851 23 } MESSAGE_RECEIVER_INSTANCE;
markrad 58:f50b97b08851 24
markrad 58:f50b97b08851 25 static void set_message_receiver_state(MESSAGE_RECEIVER_INSTANCE* message_receiver_instance, MESSAGE_RECEIVER_STATE new_state)
markrad 58:f50b97b08851 26 {
markrad 58:f50b97b08851 27 MESSAGE_RECEIVER_STATE previous_state = message_receiver_instance->message_receiver_state;
markrad 58:f50b97b08851 28 message_receiver_instance->message_receiver_state = new_state;
markrad 58:f50b97b08851 29 if (message_receiver_instance->on_message_receiver_state_changed != NULL)
markrad 58:f50b97b08851 30 {
markrad 58:f50b97b08851 31 message_receiver_instance->on_message_receiver_state_changed(message_receiver_instance->on_message_receiver_state_changed_context, new_state, previous_state);
markrad 58:f50b97b08851 32 }
markrad 58:f50b97b08851 33 }
markrad 58:f50b97b08851 34
markrad 58:f50b97b08851 35 static void decode_message_value_callback(void* context, AMQP_VALUE decoded_value)
markrad 58:f50b97b08851 36 {
markrad 58:f50b97b08851 37 MESSAGE_RECEIVER_INSTANCE* message_receiver_instance = (MESSAGE_RECEIVER_INSTANCE*)context;
markrad 58:f50b97b08851 38 MESSAGE_HANDLE decoded_message = message_receiver_instance->decoded_message;
markrad 58:f50b97b08851 39 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(decoded_value);
markrad 58:f50b97b08851 40
markrad 58:f50b97b08851 41 if (is_application_properties_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 42 {
markrad 58:f50b97b08851 43 if (message_set_application_properties(decoded_message, decoded_value) != 0)
markrad 58:f50b97b08851 44 {
markrad 58:f50b97b08851 45 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 46 }
markrad 58:f50b97b08851 47 }
markrad 58:f50b97b08851 48 else if (is_properties_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 49 {
markrad 58:f50b97b08851 50 PROPERTIES_HANDLE properties;
markrad 58:f50b97b08851 51 if (amqpvalue_get_properties(decoded_value, &properties) != 0)
markrad 58:f50b97b08851 52 {
markrad 58:f50b97b08851 53 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 54 }
markrad 58:f50b97b08851 55 else
markrad 58:f50b97b08851 56 {
markrad 58:f50b97b08851 57 if (message_set_properties(decoded_message, properties) != 0)
markrad 58:f50b97b08851 58 {
markrad 58:f50b97b08851 59 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 60 }
markrad 58:f50b97b08851 61
markrad 58:f50b97b08851 62 properties_destroy(properties);
markrad 58:f50b97b08851 63 }
markrad 58:f50b97b08851 64 }
markrad 58:f50b97b08851 65 else if (is_delivery_annotations_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 66 {
markrad 58:f50b97b08851 67 annotations delivery_annotations = amqpvalue_get_inplace_described_value(decoded_value);
markrad 58:f50b97b08851 68 if ((delivery_annotations == NULL) ||
markrad 58:f50b97b08851 69 (message_set_delivery_annotations(decoded_message, delivery_annotations) != 0))
markrad 58:f50b97b08851 70 {
markrad 58:f50b97b08851 71 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 72 }
markrad 58:f50b97b08851 73 }
markrad 58:f50b97b08851 74 else if (is_message_annotations_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 75 {
markrad 58:f50b97b08851 76 annotations message_annotations = amqpvalue_get_inplace_described_value(decoded_value);
markrad 58:f50b97b08851 77 if ((message_annotations == NULL) ||
markrad 58:f50b97b08851 78 (message_set_message_annotations(decoded_message, message_annotations) != 0))
markrad 58:f50b97b08851 79 {
markrad 58:f50b97b08851 80 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 81 }
markrad 58:f50b97b08851 82 }
markrad 58:f50b97b08851 83 else if (is_header_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 84 {
markrad 58:f50b97b08851 85 HEADER_HANDLE header;
markrad 58:f50b97b08851 86 if (amqpvalue_get_header(decoded_value, &header) != 0)
markrad 58:f50b97b08851 87 {
markrad 58:f50b97b08851 88 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 89 }
markrad 58:f50b97b08851 90 else
markrad 58:f50b97b08851 91 {
markrad 58:f50b97b08851 92 if (message_set_header(decoded_message, header) != 0)
markrad 58:f50b97b08851 93 {
markrad 58:f50b97b08851 94 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 95 }
markrad 58:f50b97b08851 96
markrad 58:f50b97b08851 97 header_destroy(header);
markrad 58:f50b97b08851 98 }
markrad 58:f50b97b08851 99 }
markrad 58:f50b97b08851 100 else if (is_footer_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 101 {
markrad 58:f50b97b08851 102 annotations footer = amqpvalue_get_inplace_described_value(decoded_value);
markrad 58:f50b97b08851 103 if ((footer == NULL) ||
markrad 58:f50b97b08851 104 (message_set_footer(decoded_message, footer) != 0))
markrad 58:f50b97b08851 105 {
markrad 58:f50b97b08851 106 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 107 }
markrad 58:f50b97b08851 108 }
markrad 58:f50b97b08851 109 else if (is_amqp_value_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 110 {
markrad 58:f50b97b08851 111 MESSAGE_BODY_TYPE body_type;
markrad 58:f50b97b08851 112 message_get_body_type(decoded_message, &body_type);
markrad 58:f50b97b08851 113 if (body_type != MESSAGE_BODY_TYPE_NONE)
markrad 58:f50b97b08851 114 {
markrad 58:f50b97b08851 115 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 116 }
markrad 58:f50b97b08851 117 else
markrad 58:f50b97b08851 118 {
markrad 58:f50b97b08851 119 AMQP_VALUE body_amqp_value = amqpvalue_get_inplace_described_value(decoded_value);
markrad 58:f50b97b08851 120 if ((body_amqp_value == NULL) ||
markrad 58:f50b97b08851 121 (message_set_body_amqp_value(decoded_message, body_amqp_value) != 0))
markrad 58:f50b97b08851 122 {
markrad 58:f50b97b08851 123 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 124 }
markrad 58:f50b97b08851 125 }
markrad 58:f50b97b08851 126 }
markrad 58:f50b97b08851 127 else if (is_data_type_by_descriptor(descriptor))
markrad 58:f50b97b08851 128 {
markrad 58:f50b97b08851 129 MESSAGE_BODY_TYPE body_type;
markrad 58:f50b97b08851 130 message_get_body_type(decoded_message, &body_type);
markrad 58:f50b97b08851 131 if ((body_type != MESSAGE_BODY_TYPE_NONE) &&
markrad 58:f50b97b08851 132 (body_type != MESSAGE_BODY_TYPE_DATA))
markrad 58:f50b97b08851 133 {
markrad 58:f50b97b08851 134 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 135 }
markrad 58:f50b97b08851 136 else
markrad 58:f50b97b08851 137 {
markrad 58:f50b97b08851 138 AMQP_VALUE body_data_value = amqpvalue_get_inplace_described_value(decoded_value);
markrad 58:f50b97b08851 139 data data_value;
markrad 58:f50b97b08851 140
markrad 58:f50b97b08851 141 if ((body_data_value == NULL) ||
markrad 58:f50b97b08851 142 (amqpvalue_get_data(body_data_value, &data_value) != 0))
markrad 58:f50b97b08851 143 {
markrad 58:f50b97b08851 144 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 145 }
markrad 58:f50b97b08851 146 else
markrad 58:f50b97b08851 147 {
markrad 58:f50b97b08851 148 BINARY_DATA binary_data;
markrad 58:f50b97b08851 149 binary_data.bytes = data_value.bytes;
markrad 58:f50b97b08851 150 binary_data.length = data_value.length;
markrad 58:f50b97b08851 151 if (message_add_body_amqp_data(decoded_message, binary_data) != 0)
markrad 58:f50b97b08851 152 {
markrad 58:f50b97b08851 153 message_receiver_instance->decode_error = true;
markrad 58:f50b97b08851 154 }
markrad 58:f50b97b08851 155 }
markrad 58:f50b97b08851 156 }
markrad 58:f50b97b08851 157 }
markrad 58:f50b97b08851 158 }
markrad 58:f50b97b08851 159
markrad 58:f50b97b08851 160 static AMQP_VALUE on_transfer_received(void* context, TRANSFER_HANDLE transfer, uint32_t payload_size, const unsigned char* payload_bytes)
markrad 58:f50b97b08851 161 {
markrad 58:f50b97b08851 162 AMQP_VALUE result = NULL;
markrad 58:f50b97b08851 163
markrad 58:f50b97b08851 164 MESSAGE_RECEIVER_INSTANCE* message_receiver_instance = (MESSAGE_RECEIVER_INSTANCE*)context;
markrad 58:f50b97b08851 165 (void)transfer;
markrad 58:f50b97b08851 166 if (message_receiver_instance->on_message_received != NULL)
markrad 58:f50b97b08851 167 {
markrad 58:f50b97b08851 168 MESSAGE_HANDLE message = message_create();
markrad 58:f50b97b08851 169 if (message == NULL)
markrad 58:f50b97b08851 170 {
markrad 58:f50b97b08851 171 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 172 }
markrad 58:f50b97b08851 173 else
markrad 58:f50b97b08851 174 {
markrad 58:f50b97b08851 175 message_receiver_instance->decoded_message;
markrad 58:f50b97b08851 176 AMQPVALUE_DECODER_HANDLE amqpvalue_decoder = amqpvalue_decoder_create(decode_message_value_callback, message_receiver_instance);
markrad 58:f50b97b08851 177 if (amqpvalue_decoder == NULL)
markrad 58:f50b97b08851 178 {
markrad 58:f50b97b08851 179 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 180 }
markrad 58:f50b97b08851 181 else
markrad 58:f50b97b08851 182 {
markrad 58:f50b97b08851 183 message_receiver_instance->decoded_message = message;
markrad 58:f50b97b08851 184 message_receiver_instance->decode_error = false;
markrad 58:f50b97b08851 185 if (amqpvalue_decode_bytes(amqpvalue_decoder, payload_bytes, payload_size) != 0)
markrad 58:f50b97b08851 186 {
markrad 58:f50b97b08851 187 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 188 }
markrad 58:f50b97b08851 189 else
markrad 58:f50b97b08851 190 {
markrad 58:f50b97b08851 191 if (message_receiver_instance->decode_error)
markrad 58:f50b97b08851 192 {
markrad 58:f50b97b08851 193 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 194 }
markrad 58:f50b97b08851 195 else
markrad 58:f50b97b08851 196 {
markrad 58:f50b97b08851 197 result = message_receiver_instance->on_message_received(message_receiver_instance->callback_context, message);
markrad 58:f50b97b08851 198 }
markrad 58:f50b97b08851 199 }
markrad 58:f50b97b08851 200
markrad 58:f50b97b08851 201 amqpvalue_decoder_destroy(amqpvalue_decoder);
markrad 58:f50b97b08851 202 }
markrad 58:f50b97b08851 203
markrad 58:f50b97b08851 204 message_destroy(message);
markrad 58:f50b97b08851 205 }
markrad 58:f50b97b08851 206 }
markrad 58:f50b97b08851 207
markrad 58:f50b97b08851 208 return result;
markrad 58:f50b97b08851 209 }
markrad 58:f50b97b08851 210
markrad 58:f50b97b08851 211 static void on_link_state_changed(void* context, LINK_STATE new_link_state, LINK_STATE previous_link_state)
markrad 58:f50b97b08851 212 {
markrad 58:f50b97b08851 213 MESSAGE_RECEIVER_INSTANCE* message_receiver_instance = (MESSAGE_RECEIVER_INSTANCE*)context;
markrad 58:f50b97b08851 214 (void)previous_link_state;
markrad 58:f50b97b08851 215
markrad 58:f50b97b08851 216 switch (new_link_state)
markrad 58:f50b97b08851 217 {
markrad 58:f50b97b08851 218 case LINK_STATE_ATTACHED:
markrad 58:f50b97b08851 219 if (message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_OPENING)
markrad 58:f50b97b08851 220 {
markrad 58:f50b97b08851 221 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_OPEN);
markrad 58:f50b97b08851 222 }
markrad 58:f50b97b08851 223 break;
markrad 58:f50b97b08851 224 case LINK_STATE_DETACHED:
markrad 58:f50b97b08851 225 if ((message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_OPEN) ||
markrad 58:f50b97b08851 226 (message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_CLOSING))
markrad 58:f50b97b08851 227 {
markrad 58:f50b97b08851 228 /* User initiated transition, we should be good */
markrad 58:f50b97b08851 229 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_IDLE);
markrad 58:f50b97b08851 230 }
markrad 58:f50b97b08851 231 else if (message_receiver_instance->message_receiver_state != MESSAGE_RECEIVER_STATE_IDLE)
markrad 58:f50b97b08851 232 {
markrad 58:f50b97b08851 233 /* Any other transition must be an error */
markrad 58:f50b97b08851 234 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 235 }
markrad 58:f50b97b08851 236 break;
markrad 58:f50b97b08851 237 case LINK_STATE_ERROR:
markrad 58:f50b97b08851 238 if (message_receiver_instance->message_receiver_state != MESSAGE_RECEIVER_STATE_ERROR)
markrad 58:f50b97b08851 239 {
markrad 58:f50b97b08851 240 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 241 }
markrad 58:f50b97b08851 242 break;
markrad 58:f50b97b08851 243 }
markrad 58:f50b97b08851 244 }
markrad 58:f50b97b08851 245
markrad 58:f50b97b08851 246 MESSAGE_RECEIVER_HANDLE messagereceiver_create(LINK_HANDLE link, ON_MESSAGE_RECEIVER_STATE_CHANGED on_message_receiver_state_changed, void* context)
markrad 58:f50b97b08851 247 {
markrad 58:f50b97b08851 248 MESSAGE_RECEIVER_INSTANCE* result = (MESSAGE_RECEIVER_INSTANCE*)amqpalloc_malloc(sizeof(MESSAGE_RECEIVER_INSTANCE));
markrad 58:f50b97b08851 249 if (result != NULL)
markrad 58:f50b97b08851 250 {
markrad 58:f50b97b08851 251 result->link = link;
markrad 58:f50b97b08851 252 result->on_message_receiver_state_changed = on_message_receiver_state_changed;
markrad 58:f50b97b08851 253 result->on_message_receiver_state_changed_context = context;
markrad 58:f50b97b08851 254 result->message_receiver_state = MESSAGE_RECEIVER_STATE_IDLE;
markrad 58:f50b97b08851 255 }
markrad 58:f50b97b08851 256
markrad 58:f50b97b08851 257 return result;
markrad 58:f50b97b08851 258 }
markrad 58:f50b97b08851 259
markrad 58:f50b97b08851 260 void messagereceiver_destroy(MESSAGE_RECEIVER_HANDLE message_receiver)
markrad 58:f50b97b08851 261 {
markrad 58:f50b97b08851 262 if (message_receiver != NULL)
markrad 58:f50b97b08851 263 {
markrad 58:f50b97b08851 264 (void)messagereceiver_close(message_receiver);
markrad 58:f50b97b08851 265 amqpalloc_free(message_receiver);
markrad 58:f50b97b08851 266 }
markrad 58:f50b97b08851 267 }
markrad 58:f50b97b08851 268
markrad 58:f50b97b08851 269 int messagereceiver_open(MESSAGE_RECEIVER_HANDLE message_receiver, ON_MESSAGE_RECEIVED on_message_received, const void* callback_context)
markrad 58:f50b97b08851 270 {
markrad 58:f50b97b08851 271 int result;
markrad 58:f50b97b08851 272
markrad 58:f50b97b08851 273 if (message_receiver == NULL)
markrad 58:f50b97b08851 274 {
markrad 58:f50b97b08851 275 result = __LINE__;
markrad 58:f50b97b08851 276 }
markrad 58:f50b97b08851 277 else
markrad 58:f50b97b08851 278 {
markrad 58:f50b97b08851 279 MESSAGE_RECEIVER_INSTANCE* message_receiver_instance = (MESSAGE_RECEIVER_INSTANCE*)message_receiver;
markrad 58:f50b97b08851 280
markrad 58:f50b97b08851 281 if (message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_IDLE)
markrad 58:f50b97b08851 282 {
markrad 58:f50b97b08851 283 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_OPENING);
markrad 58:f50b97b08851 284 if (link_attach(message_receiver_instance->link, on_transfer_received, on_link_state_changed, NULL, message_receiver_instance) != 0)
markrad 58:f50b97b08851 285 {
markrad 58:f50b97b08851 286 result = __LINE__;
markrad 58:f50b97b08851 287 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 288 }
markrad 58:f50b97b08851 289 else
markrad 58:f50b97b08851 290 {
markrad 58:f50b97b08851 291 message_receiver_instance->on_message_received = on_message_received;
markrad 58:f50b97b08851 292 message_receiver_instance->callback_context = callback_context;
markrad 58:f50b97b08851 293
markrad 58:f50b97b08851 294 result = 0;
markrad 58:f50b97b08851 295 }
markrad 58:f50b97b08851 296 }
markrad 58:f50b97b08851 297 else
markrad 58:f50b97b08851 298 {
markrad 58:f50b97b08851 299 result = 0;
markrad 58:f50b97b08851 300 }
markrad 58:f50b97b08851 301 }
markrad 58:f50b97b08851 302
markrad 58:f50b97b08851 303 return result;
markrad 58:f50b97b08851 304 }
markrad 58:f50b97b08851 305
markrad 58:f50b97b08851 306 int messagereceiver_close(MESSAGE_RECEIVER_HANDLE message_receiver)
markrad 58:f50b97b08851 307 {
markrad 58:f50b97b08851 308 int result;
markrad 58:f50b97b08851 309
markrad 58:f50b97b08851 310 if (message_receiver == NULL)
markrad 58:f50b97b08851 311 {
markrad 58:f50b97b08851 312 result = __LINE__;
markrad 58:f50b97b08851 313 }
markrad 58:f50b97b08851 314 else
markrad 58:f50b97b08851 315 {
markrad 58:f50b97b08851 316 MESSAGE_RECEIVER_INSTANCE* message_receiver_instance = (MESSAGE_RECEIVER_INSTANCE*)message_receiver;
markrad 58:f50b97b08851 317
markrad 58:f50b97b08851 318 if ((message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_OPENING) ||
markrad 58:f50b97b08851 319 (message_receiver_instance->message_receiver_state == MESSAGE_RECEIVER_STATE_OPEN))
markrad 58:f50b97b08851 320 {
markrad 58:f50b97b08851 321 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_CLOSING);
markrad 58:f50b97b08851 322
markrad 58:f50b97b08851 323 if (link_detach(message_receiver_instance->link, true) != 0)
markrad 58:f50b97b08851 324 {
markrad 58:f50b97b08851 325 result = __LINE__;
markrad 58:f50b97b08851 326 set_message_receiver_state(message_receiver_instance, MESSAGE_RECEIVER_STATE_ERROR);
markrad 58:f50b97b08851 327 }
markrad 58:f50b97b08851 328 else
markrad 58:f50b97b08851 329 {
markrad 58:f50b97b08851 330 result = 0;
markrad 58:f50b97b08851 331 }
markrad 58:f50b97b08851 332 }
markrad 58:f50b97b08851 333 else
markrad 58:f50b97b08851 334 {
markrad 58:f50b97b08851 335 result = 0;
markrad 58:f50b97b08851 336 }
markrad 58:f50b97b08851 337 }
markrad 58:f50b97b08851 338
markrad 58:f50b97b08851 339 return result;
markrad 58:f50b97b08851 340 }