A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Thu Feb 15 11:36:00 2018 -0800
Revision:
39:e7c983378f41
Parent:
35:d0bed2404ee9
Child:
40:f0ceafa8d570
1.1.32

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
Azure.IoT Build 0:6ae2f7bca550 5 #include <stdio.h>
AzureIoTClient 6:641a9672db08 6 #include <stdbool.h>
Azure.IoT Build 0:6ae2f7bca550 7 #include <string.h>
AzureIoTClient 19:000ab4e6a2c1 8 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 21:f9c433d8e6ca 9 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 23:1111ee8bcba4 10 #include "azure_c_shared_utility/singlylinkedlist.h"
AzureIoTClient 27:d74f1cea23e1 11 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 39:e7c983378f41 12 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 0:6ae2f7bca550 13 #include "azure_uamqp_c/amqp_management.h"
Azure.IoT Build 0:6ae2f7bca550 14 #include "azure_uamqp_c/link.h"
Azure.IoT Build 0:6ae2f7bca550 15 #include "azure_uamqp_c/message_sender.h"
Azure.IoT Build 0:6ae2f7bca550 16 #include "azure_uamqp_c/message_receiver.h"
Azure.IoT Build 0:6ae2f7bca550 17 #include "azure_uamqp_c/messaging.h"
Azure.IoT Build 0:6ae2f7bca550 18
AzureIoTClient 23:1111ee8bcba4 19 static const char sender_suffix[] = "-sender";
AzureIoTClient 23:1111ee8bcba4 20 static const char receiver_suffix[] = "-receiver";
AzureIoTClient 23:1111ee8bcba4 21
AzureIoTClient 23:1111ee8bcba4 22 #define COUNT_CHARS(str) (sizeof(str) / sizeof((str)[0]) - 1)
Azure.IoT Build 0:6ae2f7bca550 23
Azure.IoT Build 0:6ae2f7bca550 24 typedef struct OPERATION_MESSAGE_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 25 {
AzureIoTClient 22:524bded3f7a8 26 ON_AMQP_MANAGEMENT_EXECUTE_OPERATION_COMPLETE on_execute_operation_complete;
AzureIoTClient 6:641a9672db08 27 void* callback_context;
AzureIoTClient 23:1111ee8bcba4 28 uint64_t message_id;
Azure.IoT Build 0:6ae2f7bca550 29 } OPERATION_MESSAGE_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 30
AzureIoTClient 22:524bded3f7a8 31 typedef enum AMQP_MANAGEMENT_STATE_TAG
AzureIoTClient 22:524bded3f7a8 32 {
AzureIoTClient 22:524bded3f7a8 33 AMQP_MANAGEMENT_STATE_IDLE,
AzureIoTClient 22:524bded3f7a8 34 AMQP_MANAGEMENT_STATE_OPENING,
AzureIoTClient 22:524bded3f7a8 35 AMQP_MANAGEMENT_STATE_OPEN,
AzureIoTClient 22:524bded3f7a8 36 AMQP_MANAGEMENT_STATE_ERROR
AzureIoTClient 22:524bded3f7a8 37 } AMQP_MANAGEMENT_STATE;
AzureIoTClient 22:524bded3f7a8 38
Azure.IoT Build 0:6ae2f7bca550 39 typedef struct AMQP_MANAGEMENT_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 40 {
AzureIoTClient 6:641a9672db08 41 LINK_HANDLE sender_link;
AzureIoTClient 6:641a9672db08 42 LINK_HANDLE receiver_link;
AzureIoTClient 6:641a9672db08 43 MESSAGE_SENDER_HANDLE message_sender;
AzureIoTClient 6:641a9672db08 44 MESSAGE_RECEIVER_HANDLE message_receiver;
AzureIoTClient 23:1111ee8bcba4 45 SINGLYLINKEDLIST_HANDLE pending_operations;
AzureIoTClient 23:1111ee8bcba4 46 uint64_t next_message_id;
AzureIoTClient 22:524bded3f7a8 47 ON_AMQP_MANAGEMENT_OPEN_COMPLETE on_amqp_management_open_complete;
AzureIoTClient 22:524bded3f7a8 48 void* on_amqp_management_open_complete_context;
AzureIoTClient 22:524bded3f7a8 49 ON_AMQP_MANAGEMENT_ERROR on_amqp_management_error;
AzureIoTClient 22:524bded3f7a8 50 void* on_amqp_management_error_context;
AzureIoTClient 6:641a9672db08 51 AMQP_MANAGEMENT_STATE amqp_management_state;
AzureIoTClient 39:e7c983378f41 52 char* status_code_key_name;
AzureIoTClient 39:e7c983378f41 53 char* status_description_key_name;
AzureIoTClient 6:641a9672db08 54 int sender_connected : 1;
AzureIoTClient 6:641a9672db08 55 int receiver_connected : 1;
Azure.IoT Build 0:6ae2f7bca550 56 } AMQP_MANAGEMENT_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 57
AzureIoTClient 23:1111ee8bcba4 58 static AMQP_VALUE on_message_received(const void* context, MESSAGE_HANDLE message)
Azure.IoT Build 0:6ae2f7bca550 59 {
AzureIoTClient 23:1111ee8bcba4 60 AMQP_VALUE result;
Azure.IoT Build 0:6ae2f7bca550 61
AzureIoTClient 23:1111ee8bcba4 62 if (context == NULL)
AzureIoTClient 6:641a9672db08 63 {
AzureIoTClient 23:1111ee8bcba4 64 /* Codes_SRS_AMQP_MANAGEMENT_01_108: [ When `on_message_received` is called with a NULL context, it shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 65 LogError("NULL context in on_message_received");
AzureIoTClient 23:1111ee8bcba4 66 result = NULL;
AzureIoTClient 6:641a9672db08 67 }
AzureIoTClient 6:641a9672db08 68 else
AzureIoTClient 6:641a9672db08 69 {
AzureIoTClient 23:1111ee8bcba4 70 AMQP_MANAGEMENT_HANDLE amqp_management = (AMQP_MANAGEMENT_HANDLE)context;
AzureIoTClient 23:1111ee8bcba4 71 AMQP_VALUE application_properties;
Azure.IoT Build 0:6ae2f7bca550 72
AzureIoTClient 23:1111ee8bcba4 73 /* Codes_SRS_AMQP_MANAGEMENT_01_109: [ `on_message_received` shall obtain the application properties from the message by calling `message_get_application_properties`. ]*/
AzureIoTClient 23:1111ee8bcba4 74 if (message_get_application_properties(message, &application_properties) != 0)
AzureIoTClient 6:641a9672db08 75 {
AzureIoTClient 23:1111ee8bcba4 76 /* Codes_SRS_AMQP_MANAGEMENT_01_113: [ If obtaining the application properties or message properties fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 77 LogError("Could not retrieve application properties");
AzureIoTClient 23:1111ee8bcba4 78 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 79 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 80 result = messaging_delivery_rejected("amqp:internal-error", "Could not get application properties on AMQP management response.");
AzureIoTClient 6:641a9672db08 81 }
AzureIoTClient 6:641a9672db08 82 else
AzureIoTClient 6:641a9672db08 83 {
AzureIoTClient 23:1111ee8bcba4 84 PROPERTIES_HANDLE response_properties;
Azure.IoT Build 0:6ae2f7bca550 85
AzureIoTClient 23:1111ee8bcba4 86 /* Codes_SRS_AMQP_MANAGEMENT_01_110: [ `on_message_received` shall obtain the message properties from the message by calling `message_get_properties`. ]*/
AzureIoTClient 23:1111ee8bcba4 87 if (message_get_properties(message, &response_properties) != 0)
AzureIoTClient 6:641a9672db08 88 {
AzureIoTClient 23:1111ee8bcba4 89 /* Codes_SRS_AMQP_MANAGEMENT_01_113: [ If obtaining the application properties or message properties fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 90 LogError("Could not retrieve message properties");
AzureIoTClient 23:1111ee8bcba4 91 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 92 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 93 result = messaging_delivery_rejected("amqp:internal-error", "Could not get message properties on AMQP management response.");
AzureIoTClient 6:641a9672db08 94 }
AzureIoTClient 6:641a9672db08 95 else
AzureIoTClient 6:641a9672db08 96 {
AzureIoTClient 23:1111ee8bcba4 97 AMQP_VALUE key;
AzureIoTClient 23:1111ee8bcba4 98 AMQP_VALUE value;
AzureIoTClient 23:1111ee8bcba4 99 AMQP_VALUE desc_key;
AzureIoTClient 23:1111ee8bcba4 100 AMQP_VALUE desc_value;
AzureIoTClient 23:1111ee8bcba4 101 AMQP_VALUE map;
AzureIoTClient 23:1111ee8bcba4 102 AMQP_VALUE correlation_id_value;
AzureIoTClient 23:1111ee8bcba4 103 uint64_t correlation_id;
AzureIoTClient 23:1111ee8bcba4 104
AzureIoTClient 23:1111ee8bcba4 105 /* Codes_SRS_AMQP_MANAGEMENT_01_111: [ `on_message_received` shall obtain the correlation Id from the message properties by using `properties_get_correlation_id`. ]*/
AzureIoTClient 23:1111ee8bcba4 106 if (properties_get_correlation_id(response_properties, &correlation_id_value) != 0)
AzureIoTClient 6:641a9672db08 107 {
AzureIoTClient 23:1111ee8bcba4 108 /* Codes_SRS_AMQP_MANAGEMENT_01_114: [ If obtaining the correlation Id fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ] */
AzureIoTClient 23:1111ee8bcba4 109 LogError("Could not retrieve correlation Id");
AzureIoTClient 23:1111ee8bcba4 110 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 111 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 112 result = messaging_delivery_rejected("amqp:internal-error", "Could not get correlation Id from AMQP management response.");
AzureIoTClient 6:641a9672db08 113 }
AzureIoTClient 6:641a9672db08 114 else
AzureIoTClient 6:641a9672db08 115 {
AzureIoTClient 23:1111ee8bcba4 116 if (amqpvalue_get_ulong(correlation_id_value, &correlation_id) != 0)
AzureIoTClient 6:641a9672db08 117 {
AzureIoTClient 23:1111ee8bcba4 118 /* Codes_SRS_AMQP_MANAGEMENT_01_132: [ If any functions manipulating AMQP values, application properties, etc., fail, an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 119 LogError("Could not retrieve correlation Id ulong value");
AzureIoTClient 23:1111ee8bcba4 120 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 121 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 122 result = messaging_delivery_rejected("amqp:internal-error", "Could not get correlation Id from AMQP management response.");
AzureIoTClient 6:641a9672db08 123 }
AzureIoTClient 6:641a9672db08 124 else
AzureIoTClient 6:641a9672db08 125 {
AzureIoTClient 23:1111ee8bcba4 126 /* Codes_SRS_AMQP_MANAGEMENT_01_119: [ `on_message_received` shall obtain the application properties map by calling `amqpvalue_get_inplace_described_value`. ]*/
AzureIoTClient 23:1111ee8bcba4 127 /* Codes_SRS_AMQP_MANAGEMENT_01_070: [ Response messages have the following application-properties: ]*/
AzureIoTClient 23:1111ee8bcba4 128 map = amqpvalue_get_inplace_described_value(application_properties);
AzureIoTClient 23:1111ee8bcba4 129 if (map == NULL)
AzureIoTClient 6:641a9672db08 130 {
AzureIoTClient 23:1111ee8bcba4 131 /* Codes_SRS_AMQP_MANAGEMENT_01_132: [ If any functions manipulating AMQP values, application properties, etc., fail, an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 132 LogError("Could not retrieve application property map");
AzureIoTClient 23:1111ee8bcba4 133 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 134 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 135 result = messaging_delivery_rejected("amqp:internal-error", "Could not get application property map from the application properties in the AMQP management response.");
AzureIoTClient 6:641a9672db08 136 }
AzureIoTClient 6:641a9672db08 137 else
AzureIoTClient 6:641a9672db08 138 {
AzureIoTClient 39:e7c983378f41 139 /* Codes_SRS_AMQP_MANAGEMENT_01_120: [ An AMQP value used to lookup the status code shall be created by calling `amqpvalue_create_string` with the status code key name (`statusCode`) as argument. ]*/
AzureIoTClient 23:1111ee8bcba4 140 /* Codes_SRS_AMQP_MANAGEMENT_01_071: [ statusCode integer Yes HTTP response code [RFC2616] ]*/
AzureIoTClient 39:e7c983378f41 141 key = amqpvalue_create_string(amqp_management->status_code_key_name);
AzureIoTClient 23:1111ee8bcba4 142 if (key == NULL)
AzureIoTClient 6:641a9672db08 143 {
AzureIoTClient 23:1111ee8bcba4 144 /* Codes_SRS_AMQP_MANAGEMENT_01_132: [ If any functions manipulating AMQP values, application properties, etc., fail, an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 145 LogError("Could not create status-code amqp value");
AzureIoTClient 23:1111ee8bcba4 146 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 147 /* Codes_SRS_AMQP_MANAGEMENT_01_135: [ When an error occurs in creating AMQP values (for status code, etc.) `on_message_received` shall call `messaging_delivery_released` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 148 result = messaging_delivery_released();
AzureIoTClient 6:641a9672db08 149 }
AzureIoTClient 1:eab586236bfe 150 else
AzureIoTClient 1:eab586236bfe 151 {
AzureIoTClient 23:1111ee8bcba4 152 /* Codes_SRS_AMQP_MANAGEMENT_01_121: [ The status code shall be looked up in the application properties by using `amqpvalue_get_map_value`. ]*/
AzureIoTClient 23:1111ee8bcba4 153 value = amqpvalue_get_map_value(map, key);
AzureIoTClient 23:1111ee8bcba4 154 if (value == NULL)
AzureIoTClient 1:eab586236bfe 155 {
AzureIoTClient 23:1111ee8bcba4 156 /* Codes_SRS_AMQP_MANAGEMENT_01_122: [ If status code is not found an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 157 LogError("Could not retrieve status code from application properties");
AzureIoTClient 23:1111ee8bcba4 158 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 159 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 160 result = messaging_delivery_rejected("amqp:internal-error", "Could not retrieve status code from the application properties in the AMQP management response.");
AzureIoTClient 1:eab586236bfe 161 }
AzureIoTClient 1:eab586236bfe 162 else
AzureIoTClient 1:eab586236bfe 163 {
AzureIoTClient 23:1111ee8bcba4 164 int32_t status_code;
AzureIoTClient 23:1111ee8bcba4 165 /* Codes_SRS_AMQP_MANAGEMENT_01_133: [ The status code value shall be extracted from the value found in the map by using `amqpvalue_get_int`. ]*/
AzureIoTClient 23:1111ee8bcba4 166 if (amqpvalue_get_int(value, &status_code) != 0)
AzureIoTClient 23:1111ee8bcba4 167 {
AzureIoTClient 23:1111ee8bcba4 168 /* Codes_SRS_AMQP_MANAGEMENT_01_132: [ If any functions manipulating AMQP values, application properties, etc., fail, an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 169 LogError("Could not retrieve status code int value");
AzureIoTClient 23:1111ee8bcba4 170 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 171 /* Codes_SRS_AMQP_MANAGEMENT_01_136: [ When `on_message_received` fails due to errors in parsing the response message `on_message_received` shall call `messaging_delivery_rejected` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 172 result = messaging_delivery_rejected("amqp:internal-error", "Could not retrieve status code value from the application properties in the AMQP management response.");
AzureIoTClient 23:1111ee8bcba4 173 }
AzureIoTClient 23:1111ee8bcba4 174 else
AzureIoTClient 1:eab586236bfe 175 {
AzureIoTClient 39:e7c983378f41 176 /* Codes_SRS_AMQP_MANAGEMENT_01_123: [ An AMQP value used to lookup the status description shall be created by calling `amqpvalue_create_string` with the status description key name (`statusDescription`) as argument. ]*/
AzureIoTClient 23:1111ee8bcba4 177 /* Codes_SRS_AMQP_MANAGEMENT_01_072: [ statusDescription string No Description of the status. ]*/
AzureIoTClient 39:e7c983378f41 178 desc_key = amqpvalue_create_string(amqp_management->status_description_key_name);
AzureIoTClient 23:1111ee8bcba4 179 if (desc_key == NULL)
AzureIoTClient 23:1111ee8bcba4 180 {
AzureIoTClient 23:1111ee8bcba4 181 /* Codes_SRS_AMQP_MANAGEMENT_01_132: [ If any functions manipulating AMQP values, application properties, etc., fail, an error shall be indicated to the consumer by calling the `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 182 LogError("Could not create status-description amqp value");
AzureIoTClient 23:1111ee8bcba4 183 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 184 /* Codes_SRS_AMQP_MANAGEMENT_01_135: [ When an error occurs in creating AMQP values (for status code, etc.) `on_message_received` shall call `messaging_delivery_released` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 185 result = messaging_delivery_released();
AzureIoTClient 23:1111ee8bcba4 186 }
AzureIoTClient 23:1111ee8bcba4 187 else
AzureIoTClient 23:1111ee8bcba4 188 {
AzureIoTClient 23:1111ee8bcba4 189 const char* status_description = NULL;
AzureIoTClient 23:1111ee8bcba4 190 LIST_ITEM_HANDLE list_item_handle;
AzureIoTClient 23:1111ee8bcba4 191 bool found = false;
AzureIoTClient 23:1111ee8bcba4 192 bool is_error = false;
AzureIoTClient 1:eab586236bfe 193
AzureIoTClient 23:1111ee8bcba4 194 /* Codes_SRS_AMQP_MANAGEMENT_01_124: [ The status description shall be looked up in the application properties by using `amqpvalue_get_map_value`. ]*/
AzureIoTClient 23:1111ee8bcba4 195 desc_value = amqpvalue_get_map_value(map, desc_key);
AzureIoTClient 23:1111ee8bcba4 196 if (desc_value != NULL)
AzureIoTClient 1:eab586236bfe 197 {
AzureIoTClient 23:1111ee8bcba4 198 /* Codes_SRS_AMQP_MANAGEMENT_01_134: [ The status description value shall be extracted from the value found in the map by using `amqpvalue_get_string`. ]*/
AzureIoTClient 23:1111ee8bcba4 199 if (amqpvalue_get_string(desc_value, &status_description) != 0)
AzureIoTClient 23:1111ee8bcba4 200 {
AzureIoTClient 23:1111ee8bcba4 201 /* Codes_SRS_AMQP_MANAGEMENT_01_125: [ If status description is not found, NULL shall be passed to the user callback as `status_description` argument. ]*/
AzureIoTClient 23:1111ee8bcba4 202 status_description = NULL;
AzureIoTClient 23:1111ee8bcba4 203 }
AzureIoTClient 1:eab586236bfe 204 }
AzureIoTClient 1:eab586236bfe 205 else
AzureIoTClient 1:eab586236bfe 206 {
AzureIoTClient 23:1111ee8bcba4 207 /* Codes_SRS_AMQP_MANAGEMENT_01_125: [ If status description is not found, NULL shall be passed to the user callback as `status_description` argument. ]*/
AzureIoTClient 23:1111ee8bcba4 208 status_description = NULL;
AzureIoTClient 23:1111ee8bcba4 209 }
AzureIoTClient 23:1111ee8bcba4 210
AzureIoTClient 23:1111ee8bcba4 211 list_item_handle = singlylinkedlist_get_head_item(amqp_management->pending_operations);
AzureIoTClient 23:1111ee8bcba4 212 while (list_item_handle != NULL)
AzureIoTClient 23:1111ee8bcba4 213 {
AzureIoTClient 23:1111ee8bcba4 214 /* Codes_SRS_AMQP_MANAGEMENT_01_116: [ Each pending operation item value shall be obtained by calling `singlylinkedlist_item_get_value`. ]*/
AzureIoTClient 23:1111ee8bcba4 215 OPERATION_MESSAGE_INSTANCE* operation_message = (OPERATION_MESSAGE_INSTANCE*)singlylinkedlist_item_get_value(list_item_handle);
AzureIoTClient 23:1111ee8bcba4 216 if (operation_message == NULL)
AzureIoTClient 1:eab586236bfe 217 {
AzureIoTClient 23:1111ee8bcba4 218 /* Codes_SRS_AMQP_MANAGEMENT_01_117: [ If iterating through the pending operations list fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 219 LogError("Could not create status-description amqp value");
AzureIoTClient 23:1111ee8bcba4 220 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 221 /* Codes_SRS_AMQP_MANAGEMENT_01_135: [ When an error occurs in creating AMQP values (for status code, etc.) `on_message_received` shall call `messaging_delivery_released` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 222 result = messaging_delivery_released();
AzureIoTClient 1:eab586236bfe 223 break;
AzureIoTClient 1:eab586236bfe 224 }
AzureIoTClient 1:eab586236bfe 225 else
AzureIoTClient 1:eab586236bfe 226 {
AzureIoTClient 23:1111ee8bcba4 227 AMQP_MANAGEMENT_EXECUTE_OPERATION_RESULT execute_operation_result;
AzureIoTClient 23:1111ee8bcba4 228
AzureIoTClient 23:1111ee8bcba4 229 /* Codes_SRS_AMQP_MANAGEMENT_01_112: [ `on_message_received` shall check if the correlation Id matches the stored message Id of any pending operation. ]*/
AzureIoTClient 23:1111ee8bcba4 230 /* Codes_SRS_AMQP_MANAGEMENT_01_068: [ The correlation-id of the response message MUST be the correlation-id from the request message (if present) ]*/
AzureIoTClient 23:1111ee8bcba4 231 /* Codes_SRS_AMQP_MANAGEMENT_01_069: [ else the message-id from the request message. ]*/
AzureIoTClient 23:1111ee8bcba4 232 if (correlation_id == operation_message->message_id)
AzureIoTClient 23:1111ee8bcba4 233 {
AzureIoTClient 23:1111ee8bcba4 234 /* Codes_SRS_AMQP_MANAGEMENT_01_074: [ Successful operations MUST result in a statusCode in the 2xx range as defined in Section 10.2 of [RFC2616]. ]*/
AzureIoTClient 23:1111ee8bcba4 235 if ((status_code < 200) || (status_code > 299))
AzureIoTClient 23:1111ee8bcba4 236 {
AzureIoTClient 23:1111ee8bcba4 237 /* Codes_SRS_AMQP_MANAGEMENT_01_128: [ If the status indicates that the operation failed, the result callback argument shall be `AMQP_MANAGEMENT_EXECUTE_OPERATION_FAILED_BAD_STATUS`. ]*/
AzureIoTClient 23:1111ee8bcba4 238 /* Codes_SRS_AMQP_MANAGEMENT_01_075: [ Unsuccessful operations MUST NOT result in a statusCode in the 2xx range as defined in Section 10.2 of [RFC2616]. ]*/
AzureIoTClient 23:1111ee8bcba4 239 execute_operation_result = AMQP_MANAGEMENT_EXECUTE_OPERATION_FAILED_BAD_STATUS;
AzureIoTClient 23:1111ee8bcba4 240 }
AzureIoTClient 23:1111ee8bcba4 241 else
AzureIoTClient 23:1111ee8bcba4 242 {
AzureIoTClient 23:1111ee8bcba4 243 /* Codes_SRS_AMQP_MANAGEMENT_01_127: [ If the operation succeeded the result callback argument shall be `AMQP_MANAGEMENT_EXECUTE_OPERATION_OK`. ]*/
AzureIoTClient 23:1111ee8bcba4 244 execute_operation_result = AMQP_MANAGEMENT_EXECUTE_OPERATION_OK;
AzureIoTClient 23:1111ee8bcba4 245 }
AzureIoTClient 23:1111ee8bcba4 246
AzureIoTClient 23:1111ee8bcba4 247 /* Codes_SRS_AMQP_MANAGEMENT_01_126: [ If a corresponding correlation Id is found in the pending operations list, the callback associated with the pending operation shall be called. ]*/
AzureIoTClient 39:e7c983378f41 248 /* Codes_SRS_AMQP_MANAGEMENT_01_166: [ The `message` shall be passed as argument to the callback. ]*/
AzureIoTClient 39:e7c983378f41 249 operation_message->on_execute_operation_complete(operation_message->callback_context, execute_operation_result, status_code, status_description, message);
AzureIoTClient 23:1111ee8bcba4 250
AzureIoTClient 23:1111ee8bcba4 251 free(operation_message);
AzureIoTClient 23:1111ee8bcba4 252
AzureIoTClient 23:1111ee8bcba4 253 /* Codes_SRS_AMQP_MANAGEMENT_01_129: [ After calling the callback, the pending operation shall be removed from the pending operations list by calling `singlylinkedlist_remove`. ]*/
AzureIoTClient 23:1111ee8bcba4 254 if (singlylinkedlist_remove(amqp_management->pending_operations, list_item_handle) != 0)
AzureIoTClient 23:1111ee8bcba4 255 {
AzureIoTClient 23:1111ee8bcba4 256 LogError("Cannot remove pending operation");
AzureIoTClient 23:1111ee8bcba4 257 is_error = true;
AzureIoTClient 23:1111ee8bcba4 258 break;
AzureIoTClient 23:1111ee8bcba4 259 }
AzureIoTClient 23:1111ee8bcba4 260 else
AzureIoTClient 23:1111ee8bcba4 261 {
AzureIoTClient 23:1111ee8bcba4 262 found = true;
AzureIoTClient 23:1111ee8bcba4 263 }
AzureIoTClient 23:1111ee8bcba4 264
AzureIoTClient 23:1111ee8bcba4 265 break;
AzureIoTClient 23:1111ee8bcba4 266 }
AzureIoTClient 1:eab586236bfe 267 }
Azure.IoT Build 0:6ae2f7bca550 268
AzureIoTClient 23:1111ee8bcba4 269 /* Codes_SRS_AMQP_MANAGEMENT_01_115: [ Iterating through the pending operations shall be done by using `singlylinkedlist_get_head_item` and `singlylinkedlist_get_next_item` until the enm of the pending operations singly linked list is reached. ]*/
AzureIoTClient 23:1111ee8bcba4 270 /* Codes_SRS_AMQP_MANAGEMENT_01_117: [ If iterating through the pending operations list fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 271 list_item_handle = singlylinkedlist_get_next_item(list_item_handle);
AzureIoTClient 23:1111ee8bcba4 272 }
AzureIoTClient 23:1111ee8bcba4 273
AzureIoTClient 23:1111ee8bcba4 274 if (is_error)
AzureIoTClient 23:1111ee8bcba4 275 {
AzureIoTClient 23:1111ee8bcba4 276 /* Codes_SRS_AMQP_MANAGEMENT_01_117: [ If iterating through the pending operations list fails, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 277 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 278 /* Codes_SRS_AMQP_MANAGEMENT_01_135: [ When an error occurs in creating AMQP values (for status code, etc.) `on_message_received` shall call `messaging_delivery_released` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 279 result = messaging_delivery_released();
AzureIoTClient 1:eab586236bfe 280 }
AzureIoTClient 23:1111ee8bcba4 281 else
AzureIoTClient 23:1111ee8bcba4 282 {
AzureIoTClient 23:1111ee8bcba4 283 if (!found)
AzureIoTClient 23:1111ee8bcba4 284 {
AzureIoTClient 23:1111ee8bcba4 285 /* Codes_SRS_AMQP_MANAGEMENT_01_118: [ If no pending operation is found matching the correlation Id, an error shall be indicated by calling `on_amqp_management_error` and passing the `on_amqp_management_error_context` to it. ]*/
AzureIoTClient 23:1111ee8bcba4 286 LogError("Could not match AMQP management response to request");
AzureIoTClient 23:1111ee8bcba4 287 amqp_management->on_amqp_management_error(amqp_management->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 288 /* Codes_SRS_AMQP_MANAGEMENT_01_135: [ When an error occurs in creating AMQP values (for status code, etc.) `on_message_received` shall call `messaging_delivery_released` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 289 result = messaging_delivery_rejected("amqp:internal-error", "Could not match AMQP management response to request");
AzureIoTClient 23:1111ee8bcba4 290 }
AzureIoTClient 23:1111ee8bcba4 291 else
AzureIoTClient 23:1111ee8bcba4 292 {
AzureIoTClient 23:1111ee8bcba4 293 /* Codes_SRS_AMQP_MANAGEMENT_01_130: [ The `on_message_received` shall call `messaging_delivery_accepted` and return the created delivery AMQP value. ]*/
AzureIoTClient 23:1111ee8bcba4 294 result = messaging_delivery_accepted();
AzureIoTClient 23:1111ee8bcba4 295 }
AzureIoTClient 23:1111ee8bcba4 296 }
AzureIoTClient 23:1111ee8bcba4 297
AzureIoTClient 23:1111ee8bcba4 298 if (desc_value != NULL)
AzureIoTClient 23:1111ee8bcba4 299 {
AzureIoTClient 23:1111ee8bcba4 300 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 301 amqpvalue_destroy(desc_value);
AzureIoTClient 23:1111ee8bcba4 302 }
AzureIoTClient 23:1111ee8bcba4 303
AzureIoTClient 23:1111ee8bcba4 304 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 305 amqpvalue_destroy(desc_key);
AzureIoTClient 1:eab586236bfe 306 }
AzureIoTClient 1:eab586236bfe 307 }
Azure.IoT Build 0:6ae2f7bca550 308
AzureIoTClient 23:1111ee8bcba4 309 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 310 amqpvalue_destroy(value);
AzureIoTClient 6:641a9672db08 311 }
AzureIoTClient 23:1111ee8bcba4 312
AzureIoTClient 23:1111ee8bcba4 313 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 314 amqpvalue_destroy(key);
AzureIoTClient 6:641a9672db08 315 }
AzureIoTClient 6:641a9672db08 316 }
AzureIoTClient 6:641a9672db08 317 }
AzureIoTClient 6:641a9672db08 318 }
AzureIoTClient 23:1111ee8bcba4 319
AzureIoTClient 23:1111ee8bcba4 320 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 321 properties_destroy(response_properties);
AzureIoTClient 6:641a9672db08 322 }
Azure.IoT Build 0:6ae2f7bca550 323
AzureIoTClient 23:1111ee8bcba4 324 /* Codes_SRS_AMQP_MANAGEMENT_01_131: [ All temporary values like AMQP values used as keys shall be freed before exiting the callback. ]*/
AzureIoTClient 23:1111ee8bcba4 325 application_properties_destroy(application_properties);
AzureIoTClient 6:641a9672db08 326 }
AzureIoTClient 6:641a9672db08 327 }
Azure.IoT Build 0:6ae2f7bca550 328
AzureIoTClient 6:641a9672db08 329 return result;
Azure.IoT Build 0:6ae2f7bca550 330 }
Azure.IoT Build 0:6ae2f7bca550 331
Azure.IoT Build 0:6ae2f7bca550 332 static void on_message_sender_state_changed(void* context, MESSAGE_SENDER_STATE new_state, MESSAGE_SENDER_STATE previous_state)
Azure.IoT Build 0:6ae2f7bca550 333 {
AzureIoTClient 23:1111ee8bcba4 334 if (context == NULL)
AzureIoTClient 6:641a9672db08 335 {
AzureIoTClient 23:1111ee8bcba4 336 /* Codes_SRS_AMQP_MANAGEMENT_01_137: [ When `on_message_sender_state_changed` is called with NULL `context`, it shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 337 LogError("on_message_sender_state_changed called with NULL context");
AzureIoTClient 23:1111ee8bcba4 338 }
AzureIoTClient 23:1111ee8bcba4 339 else
AzureIoTClient 23:1111ee8bcba4 340 {
AzureIoTClient 23:1111ee8bcba4 341 /* Codes_SRS_AMQP_MANAGEMENT_01_138: [ When `on_message_sender_state_changed` is called and the `new_state` is different than `previous_state`, the following actions shall be taken: ]*/
AzureIoTClient 23:1111ee8bcba4 342 /* Codes_SRS_AMQP_MANAGEMENT_01_148: [ When no state change is detected, `on_message_sender_state_changed` shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 343 if (new_state != previous_state)
AzureIoTClient 22:524bded3f7a8 344 {
AzureIoTClient 23:1111ee8bcba4 345 AMQP_MANAGEMENT_INSTANCE* amqp_management_instance = (AMQP_MANAGEMENT_INSTANCE*)context;
AzureIoTClient 23:1111ee8bcba4 346 switch (amqp_management_instance->amqp_management_state)
AzureIoTClient 23:1111ee8bcba4 347 {
AzureIoTClient 23:1111ee8bcba4 348 default:
AzureIoTClient 23:1111ee8bcba4 349 break;
AzureIoTClient 22:524bded3f7a8 350
AzureIoTClient 23:1111ee8bcba4 351 /* Codes_SRS_AMQP_MANAGEMENT_01_139: [ For the current state of AMQP management being `OPENING`: ]*/
AzureIoTClient 23:1111ee8bcba4 352 case AMQP_MANAGEMENT_STATE_OPENING:
AzureIoTClient 22:524bded3f7a8 353 {
AzureIoTClient 23:1111ee8bcba4 354 switch (new_state)
AzureIoTClient 23:1111ee8bcba4 355 {
AzureIoTClient 23:1111ee8bcba4 356 case MESSAGE_SENDER_STATE_OPENING:
AzureIoTClient 23:1111ee8bcba4 357 /* Codes_SRS_AMQP_MANAGEMENT_01_165: [ - If `new_state` is `MESSAGE_SENDER_STATE_OPEING` the transition shall be ignored. ]*/
AzureIoTClient 23:1111ee8bcba4 358 break;
AzureIoTClient 23:1111ee8bcba4 359
AzureIoTClient 23:1111ee8bcba4 360 default:
AzureIoTClient 23:1111ee8bcba4 361 /* Codes_SRS_AMQP_MANAGEMENT_01_140: [ - If `new_state` is `MESSAGE_SENDER_STATE_IDLE`, `MESSAGE_SENDER_STATE_CLOSING` or `MESSAGE_SENDER_STATE_ERROR`, the `on_amqp_management_open_complete` callback shall be called with `AMQP_MANAGEMENT_OPEN_ERROR`, while also passing the context passed in `amqp_management_open_async`. ]*/
AzureIoTClient 23:1111ee8bcba4 362 case MESSAGE_SENDER_STATE_IDLE:
AzureIoTClient 23:1111ee8bcba4 363 case MESSAGE_SENDER_STATE_CLOSING:
AzureIoTClient 23:1111ee8bcba4 364 case MESSAGE_SENDER_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 365 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 23:1111ee8bcba4 366 amqp_management_instance->on_amqp_management_open_complete(amqp_management_instance->on_amqp_management_open_complete_context, AMQP_MANAGEMENT_OPEN_ERROR);
AzureIoTClient 23:1111ee8bcba4 367 break;
AzureIoTClient 22:524bded3f7a8 368
AzureIoTClient 23:1111ee8bcba4 369 case MESSAGE_SENDER_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 370 amqp_management_instance->sender_connected = -1;
AzureIoTClient 23:1111ee8bcba4 371 /* Codes_SRS_AMQP_MANAGEMENT_01_142: [ - If `new_state` is `MESSAGE_SENDER_STATE_OPEN` and the message receiver did not yet indicate its state as `MESSAGE_RECEIVER_STATE_OPEN`, the `on_amqp_management_open_complete` callback shall not be called.]*/
AzureIoTClient 23:1111ee8bcba4 372 if (amqp_management_instance->receiver_connected != 0)
AzureIoTClient 23:1111ee8bcba4 373 {
AzureIoTClient 23:1111ee8bcba4 374 /* Codes_SRS_AMQP_MANAGEMENT_01_141: [ - If `new_state` is `MESSAGE_SENDER_STATE_OPEN` and the message receiver already indicated its state as `MESSAGE_RECEIVER_STATE_OPEN`, the `on_amqp_management_open_complete` callback shall be called with `AMQP_MANAGEMENT_OPEN_OK`, while also passing the context passed in `amqp_management_open_async`. ]*/
AzureIoTClient 23:1111ee8bcba4 375 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_OPEN;
AzureIoTClient 23:1111ee8bcba4 376 amqp_management_instance->on_amqp_management_open_complete(amqp_management_instance->on_amqp_management_open_complete_context, AMQP_MANAGEMENT_OPEN_OK);
AzureIoTClient 23:1111ee8bcba4 377 }
AzureIoTClient 23:1111ee8bcba4 378 break;
AzureIoTClient 23:1111ee8bcba4 379 }
AzureIoTClient 23:1111ee8bcba4 380 break;
AzureIoTClient 23:1111ee8bcba4 381 }
AzureIoTClient 23:1111ee8bcba4 382 /* Codes_SRS_AMQP_MANAGEMENT_01_144: [ For the current state of AMQP management being `OPEN`: ]*/
AzureIoTClient 23:1111ee8bcba4 383 case AMQP_MANAGEMENT_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 384 {
AzureIoTClient 23:1111ee8bcba4 385 switch (new_state)
AzureIoTClient 23:1111ee8bcba4 386 {
AzureIoTClient 23:1111ee8bcba4 387 default:
AzureIoTClient 23:1111ee8bcba4 388 /* Codes_SRS_AMQP_MANAGEMENT_01_143: [ - If `new_state` is `MESSAGE_SENDER_STATE_IDLE`, `MESSAGE_SENDER_STATE_OPENING`, `MESSAGE_SENDER_STATE_CLOSING` or `MESSAGE_SENDER_STATE_ERROR` the `on_amqp_management_error` callback shall be invoked while passing the `on_amqp_management_error_context` as argument. ]*/
AzureIoTClient 23:1111ee8bcba4 389 case MESSAGE_SENDER_STATE_IDLE:
AzureIoTClient 23:1111ee8bcba4 390 case MESSAGE_SENDER_STATE_CLOSING:
AzureIoTClient 23:1111ee8bcba4 391 case MESSAGE_SENDER_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 392 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_ERROR;
AzureIoTClient 23:1111ee8bcba4 393 amqp_management_instance->on_amqp_management_error(amqp_management_instance->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 394 break;
Azure.IoT Build 0:6ae2f7bca550 395
AzureIoTClient 23:1111ee8bcba4 396 case MESSAGE_SENDER_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 397 /* Codes_SRS_AMQP_MANAGEMENT_01_145: [ - If `new_state` is `MESSAGE_SENDER_STATE_OPEN`, `on_message_sender_state_changed` shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 398 break;
AzureIoTClient 23:1111ee8bcba4 399 }
AzureIoTClient 23:1111ee8bcba4 400 break;
AzureIoTClient 23:1111ee8bcba4 401 }
AzureIoTClient 23:1111ee8bcba4 402 /* Codes_SRS_AMQP_MANAGEMENT_01_146: [ For the current state of AMQP management being `ERROR`: ]*/
AzureIoTClient 23:1111ee8bcba4 403 case AMQP_MANAGEMENT_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 404 /* Codes_SRS_AMQP_MANAGEMENT_01_147: [ - All state transitions shall be ignored. ]*/
AzureIoTClient 23:1111ee8bcba4 405 break;
AzureIoTClient 23:1111ee8bcba4 406 }
AzureIoTClient 22:524bded3f7a8 407 }
AzureIoTClient 6:641a9672db08 408 }
Azure.IoT Build 0:6ae2f7bca550 409 }
Azure.IoT Build 0:6ae2f7bca550 410
Azure.IoT Build 0:6ae2f7bca550 411 static void on_message_receiver_state_changed(const void* context, MESSAGE_RECEIVER_STATE new_state, MESSAGE_RECEIVER_STATE previous_state)
Azure.IoT Build 0:6ae2f7bca550 412 {
AzureIoTClient 23:1111ee8bcba4 413 if (context == NULL)
AzureIoTClient 6:641a9672db08 414 {
AzureIoTClient 23:1111ee8bcba4 415 /* Codes_SRS_AMQP_MANAGEMENT_01_149: [ When `on_message_receiver_state_changed` is called with NULL `context`, it shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 416 LogError("on_message_receiver_state_changed called with NULL context");
AzureIoTClient 23:1111ee8bcba4 417 }
AzureIoTClient 23:1111ee8bcba4 418 else
AzureIoTClient 23:1111ee8bcba4 419 {
AzureIoTClient 23:1111ee8bcba4 420 /* Codes_SRS_AMQP_MANAGEMENT_01_150: [ When `on_message_receiver_state_changed` is called and the `new_state` is different than `previous_state`, the following actions shall be taken: ]*/
AzureIoTClient 23:1111ee8bcba4 421 /* Codes_SRS_AMQP_MANAGEMENT_01_160: [ When no state change is detected, `on_message_receiver_state_changed` shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 422 if (new_state != previous_state)
AzureIoTClient 22:524bded3f7a8 423 {
AzureIoTClient 23:1111ee8bcba4 424 AMQP_MANAGEMENT_INSTANCE* amqp_management_instance = (AMQP_MANAGEMENT_INSTANCE*)context;
AzureIoTClient 23:1111ee8bcba4 425 switch (amqp_management_instance->amqp_management_state)
AzureIoTClient 23:1111ee8bcba4 426 {
AzureIoTClient 23:1111ee8bcba4 427 default:
AzureIoTClient 23:1111ee8bcba4 428 break;
AzureIoTClient 22:524bded3f7a8 429
AzureIoTClient 23:1111ee8bcba4 430 /* Codes_SRS_AMQP_MANAGEMENT_01_151: [ For the current state of AMQP management being `OPENING`: ]*/
AzureIoTClient 23:1111ee8bcba4 431 case AMQP_MANAGEMENT_STATE_OPENING:
AzureIoTClient 22:524bded3f7a8 432 {
AzureIoTClient 23:1111ee8bcba4 433 switch (new_state)
AzureIoTClient 23:1111ee8bcba4 434 {
AzureIoTClient 23:1111ee8bcba4 435 case MESSAGE_RECEIVER_STATE_OPENING:
AzureIoTClient 23:1111ee8bcba4 436 /* Codes_SRS_AMQP_MANAGEMENT_01_164: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_OPEING` the transition shall be ignored. ]*/
AzureIoTClient 23:1111ee8bcba4 437 break;
AzureIoTClient 23:1111ee8bcba4 438
AzureIoTClient 23:1111ee8bcba4 439 default:
AzureIoTClient 23:1111ee8bcba4 440 /* Codes_SRS_AMQP_MANAGEMENT_01_152: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_IDLE`, `MESSAGE_RECEIVER_STATE_CLOSING` or `MESSAGE_RECEIVER_STATE_ERROR`, the `on_amqp_management_open_complete` callback shall be called with `AMQP_MANAGEMENT_OPEN_ERROR`, while also passing the context passed in `amqp_management_open_async`. ]*/
AzureIoTClient 23:1111ee8bcba4 441 case MESSAGE_RECEIVER_STATE_IDLE:
AzureIoTClient 23:1111ee8bcba4 442 case MESSAGE_RECEIVER_STATE_CLOSING:
AzureIoTClient 23:1111ee8bcba4 443 case MESSAGE_RECEIVER_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 444 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 23:1111ee8bcba4 445 amqp_management_instance->on_amqp_management_open_complete(amqp_management_instance->on_amqp_management_open_complete_context, AMQP_MANAGEMENT_OPEN_ERROR);
AzureIoTClient 23:1111ee8bcba4 446 break;
AzureIoTClient 22:524bded3f7a8 447
AzureIoTClient 23:1111ee8bcba4 448 case MESSAGE_RECEIVER_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 449 amqp_management_instance->receiver_connected = -1;
AzureIoTClient 23:1111ee8bcba4 450 /* Codes_SRS_AMQP_MANAGEMENT_01_154: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_OPEN` and the message sender did not yet indicate its state as `MESSAGE_RECEIVER_STATE_OPEN`, the `on_amqp_management_open_complete` callback shall not be called. ]*/
AzureIoTClient 23:1111ee8bcba4 451 if (amqp_management_instance->sender_connected != 0)
AzureIoTClient 23:1111ee8bcba4 452 {
AzureIoTClient 23:1111ee8bcba4 453 /* Codes_SRS_AMQP_MANAGEMENT_01_153: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_OPEN` and the message sender already indicated its state as `MESSAGE_RECEIVER_STATE_OPEN`, the `on_amqp_management_open_complete` callback shall be called with `AMQP_MANAGEMENT_OPEN_OK`, while also passing the context passed in `amqp_management_open_async`. ]*/
AzureIoTClient 23:1111ee8bcba4 454 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_OPEN;
AzureIoTClient 23:1111ee8bcba4 455 amqp_management_instance->on_amqp_management_open_complete(amqp_management_instance->on_amqp_management_open_complete_context, AMQP_MANAGEMENT_OPEN_OK);
AzureIoTClient 23:1111ee8bcba4 456 }
AzureIoTClient 23:1111ee8bcba4 457 break;
AzureIoTClient 23:1111ee8bcba4 458 }
AzureIoTClient 23:1111ee8bcba4 459 break;
AzureIoTClient 23:1111ee8bcba4 460 }
AzureIoTClient 23:1111ee8bcba4 461 /* Codes_SRS_AMQP_MANAGEMENT_01_155: [ For the current state of AMQP management being `OPEN`: ]*/
AzureIoTClient 23:1111ee8bcba4 462 case AMQP_MANAGEMENT_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 463 {
AzureIoTClient 23:1111ee8bcba4 464 switch (new_state)
AzureIoTClient 23:1111ee8bcba4 465 {
AzureIoTClient 23:1111ee8bcba4 466 default:
AzureIoTClient 23:1111ee8bcba4 467 /* Codes_SRS_AMQP_MANAGEMENT_01_156: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_IDLE`, `MESSAGE_RECEIVER_STATE_OPENING`, `MESSAGE_RECEIVER_STATE_CLOSING` or `MESSAGE_RECEIVER_STATE_ERROR` the `on_amqp_management_error` callback shall be invoked while passing the `on_amqp_management_error_context` as argument. ]*/
AzureIoTClient 23:1111ee8bcba4 468 case MESSAGE_RECEIVER_STATE_IDLE:
AzureIoTClient 23:1111ee8bcba4 469 case MESSAGE_RECEIVER_STATE_CLOSING:
AzureIoTClient 23:1111ee8bcba4 470 case MESSAGE_RECEIVER_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 471 amqp_management_instance->amqp_management_state = AMQP_MANAGEMENT_STATE_ERROR;
AzureIoTClient 23:1111ee8bcba4 472 amqp_management_instance->on_amqp_management_error(amqp_management_instance->on_amqp_management_error_context);
AzureIoTClient 23:1111ee8bcba4 473 break;
Azure.IoT Build 0:6ae2f7bca550 474
AzureIoTClient 23:1111ee8bcba4 475 case MESSAGE_RECEIVER_STATE_OPEN:
AzureIoTClient 23:1111ee8bcba4 476 /* Codes_SRS_AMQP_MANAGEMENT_01_157: [ - If `new_state` is `MESSAGE_RECEIVER_STATE_OPEN`, `on_message_receiver_state_changed` shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 477 break;
AzureIoTClient 23:1111ee8bcba4 478 }
AzureIoTClient 23:1111ee8bcba4 479 break;
AzureIoTClient 23:1111ee8bcba4 480 }
AzureIoTClient 23:1111ee8bcba4 481 /* Codes_SRS_AMQP_MANAGEMENT_01_158: [ For the current state of AMQP management being `ERROR`: ]*/
AzureIoTClient 23:1111ee8bcba4 482 case AMQP_MANAGEMENT_STATE_ERROR:
AzureIoTClient 23:1111ee8bcba4 483 /* Codes_SRS_AMQP_MANAGEMENT_01_159: [ - All state transitions shall be ignored. ]*/
AzureIoTClient 23:1111ee8bcba4 484 break;
AzureIoTClient 23:1111ee8bcba4 485 }
AzureIoTClient 22:524bded3f7a8 486 }
AzureIoTClient 6:641a9672db08 487 }
Azure.IoT Build 0:6ae2f7bca550 488 }
Azure.IoT Build 0:6ae2f7bca550 489
AzureIoTClient 23:1111ee8bcba4 490 static int set_message_id(MESSAGE_HANDLE message, uint64_t next_message_id)
Azure.IoT Build 0:6ae2f7bca550 491 {
AzureIoTClient 23:1111ee8bcba4 492 int result;
AzureIoTClient 23:1111ee8bcba4 493 PROPERTIES_HANDLE properties;
Azure.IoT Build 0:6ae2f7bca550 494
AzureIoTClient 23:1111ee8bcba4 495 /* Codes_SRS_AMQP_MANAGEMENT_01_094: [ In order to set the message Id on the message, the properties shall be obtained by calling `message_get_properties`. ]*/
AzureIoTClient 6:641a9672db08 496 if (message_get_properties(message, &properties) != 0)
AzureIoTClient 6:641a9672db08 497 {
AzureIoTClient 23:1111ee8bcba4 498 /* Codes_SRS_AMQP_MANAGEMENT_01_098: [ If any API fails while setting the message Id, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 499 LogError("Could not retrieve message properties");
AzureIoTClient 19:000ab4e6a2c1 500 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 501 }
AzureIoTClient 6:641a9672db08 502 else
AzureIoTClient 6:641a9672db08 503 {
AzureIoTClient 23:1111ee8bcba4 504 /* Codes_SRS_AMQP_MANAGEMENT_01_099: [ If the properties were not set on the message, a new properties instance shall be created by calling `properties_create`. ]*/
AzureIoTClient 21:f9c433d8e6ca 505 if (properties == NULL)
AzureIoTClient 21:f9c433d8e6ca 506 {
AzureIoTClient 21:f9c433d8e6ca 507 properties = properties_create();
AzureIoTClient 21:f9c433d8e6ca 508 }
AzureIoTClient 21:f9c433d8e6ca 509
AzureIoTClient 21:f9c433d8e6ca 510 if (properties == NULL)
AzureIoTClient 6:641a9672db08 511 {
AzureIoTClient 23:1111ee8bcba4 512 /* Codes_SRS_AMQP_MANAGEMENT_01_098: [ If any API fails while setting the message Id, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 513 LogError("Could not create message properties");
AzureIoTClient 19:000ab4e6a2c1 514 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 515 }
AzureIoTClient 6:641a9672db08 516 else
AzureIoTClient 6:641a9672db08 517 {
AzureIoTClient 23:1111ee8bcba4 518 /* Codes_SRS_AMQP_MANAGEMENT_01_095: [ A message Id with the next ulong value to be used shall be created by calling `amqpvalue_create_message_id_ulong`. ]*/
AzureIoTClient 21:f9c433d8e6ca 519 AMQP_VALUE message_id = amqpvalue_create_message_id_ulong(next_message_id);
AzureIoTClient 21:f9c433d8e6ca 520 if (message_id == NULL)
AzureIoTClient 21:f9c433d8e6ca 521 {
AzureIoTClient 23:1111ee8bcba4 522 /* Codes_SRS_AMQP_MANAGEMENT_01_098: [ If any API fails while setting the message Id, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 523 LogError("Could not create message id value");
AzureIoTClient 21:f9c433d8e6ca 524 result = __FAILURE__;
AzureIoTClient 21:f9c433d8e6ca 525 }
AzureIoTClient 21:f9c433d8e6ca 526 else
AzureIoTClient 21:f9c433d8e6ca 527 {
AzureIoTClient 23:1111ee8bcba4 528 /* Codes_SRS_AMQP_MANAGEMENT_01_096: [ The message Id value shall be set on the properties by calling `properties_set_message_id`. ]*/
AzureIoTClient 21:f9c433d8e6ca 529 if (properties_set_message_id(properties, message_id) != 0)
AzureIoTClient 21:f9c433d8e6ca 530 {
AzureIoTClient 23:1111ee8bcba4 531 /* Codes_SRS_AMQP_MANAGEMENT_01_098: [ If any API fails while setting the message Id, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 532 LogError("Could not set message Id on the properties");
AzureIoTClient 21:f9c433d8e6ca 533 result = __FAILURE__;
AzureIoTClient 21:f9c433d8e6ca 534 }
AzureIoTClient 23:1111ee8bcba4 535 /* Codes_SRS_AMQP_MANAGEMENT_01_097: [ The properties thus modified to contain the message Id shall be set on the message by calling `message_set_properties`. ]*/
AzureIoTClient 23:1111ee8bcba4 536 else if (message_set_properties(message, properties) != 0)
AzureIoTClient 23:1111ee8bcba4 537 {
AzureIoTClient 23:1111ee8bcba4 538 /* Codes_SRS_AMQP_MANAGEMENT_01_098: [ If any API fails while setting the message Id, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 539 LogError("Could not set message properties");
AzureIoTClient 23:1111ee8bcba4 540 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 541 }
AzureIoTClient 23:1111ee8bcba4 542 else
AzureIoTClient 23:1111ee8bcba4 543 {
AzureIoTClient 23:1111ee8bcba4 544 result = 0;
AzureIoTClient 23:1111ee8bcba4 545 }
AzureIoTClient 21:f9c433d8e6ca 546
AzureIoTClient 21:f9c433d8e6ca 547 amqpvalue_destroy(message_id);
AzureIoTClient 21:f9c433d8e6ca 548 }
AzureIoTClient 21:f9c433d8e6ca 549
AzureIoTClient 23:1111ee8bcba4 550 /* Codes_SRS_AMQP_MANAGEMENT_01_100: [ After setting the properties, the properties instance shall be freed by `properties_destroy`. ]*/
AzureIoTClient 21:f9c433d8e6ca 551 properties_destroy(properties);
AzureIoTClient 6:641a9672db08 552 }
AzureIoTClient 6:641a9672db08 553 }
Azure.IoT Build 0:6ae2f7bca550 554
AzureIoTClient 6:641a9672db08 555 return result;
Azure.IoT Build 0:6ae2f7bca550 556 }
Azure.IoT Build 0:6ae2f7bca550 557
Azure.IoT Build 0:6ae2f7bca550 558 static int add_string_key_value_pair_to_map(AMQP_VALUE map, const char* key, const char* value)
Azure.IoT Build 0:6ae2f7bca550 559 {
AzureIoTClient 6:641a9672db08 560 int result;
Azure.IoT Build 0:6ae2f7bca550 561
AzureIoTClient 23:1111ee8bcba4 562 /* Codes_SRS_AMQP_MANAGEMENT_01_084: [ For each of the arguments `operation`, `type` and `locales` an AMQP value of type string shall be created by calling `amqpvalue_create_string` in order to be used as key in the application properties map. ]*/
AzureIoTClient 6:641a9672db08 563 AMQP_VALUE key_value = amqpvalue_create_string(key);
AzureIoTClient 23:1111ee8bcba4 564 if (key_value == NULL)
AzureIoTClient 6:641a9672db08 565 {
AzureIoTClient 23:1111ee8bcba4 566 /* Codes_SRS_AMQP_MANAGEMENT_01_090: [ If any APIs used to create and set the application properties on the message fails, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 567 LogError("Could not create key value for %s", key);
AzureIoTClient 19:000ab4e6a2c1 568 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 569 }
AzureIoTClient 6:641a9672db08 570 else
AzureIoTClient 6:641a9672db08 571 {
AzureIoTClient 23:1111ee8bcba4 572 /* Codes_SRS_AMQP_MANAGEMENT_01_085: [ For each of the arguments `operation`, `type` and `locales` an AMQP value of type string containing the argument value shall be created by calling `amqpvalue_create_string` in order to be used as value in the application properties map. ]*/
AzureIoTClient 6:641a9672db08 573 AMQP_VALUE value_value = amqpvalue_create_string(value);
AzureIoTClient 6:641a9672db08 574 if (value_value == NULL)
AzureIoTClient 6:641a9672db08 575 {
AzureIoTClient 23:1111ee8bcba4 576 /* Codes_SRS_AMQP_MANAGEMENT_01_090: [ If any APIs used to create and set the application properties on the message fails, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 577 LogError("Could not create value for key %s", key);
AzureIoTClient 19:000ab4e6a2c1 578 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 579 }
AzureIoTClient 6:641a9672db08 580 else
AzureIoTClient 6:641a9672db08 581 {
AzureIoTClient 23:1111ee8bcba4 582 /* Codes_SRS_AMQP_MANAGEMENT_01_086: [ The key/value pairs for `operation`, `type` and `locales` shall be added to the application properties map by calling `amqpvalue_set_map_value`. ]*/
AzureIoTClient 6:641a9672db08 583 if (amqpvalue_set_map_value(map, key_value, value_value) != 0)
AzureIoTClient 6:641a9672db08 584 {
AzureIoTClient 23:1111ee8bcba4 585 /* Codes_SRS_AMQP_MANAGEMENT_01_090: [ If any APIs used to create and set the application properties on the message fails, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 586 LogError("Could not set the value in the map for key %s", key);
AzureIoTClient 19:000ab4e6a2c1 587 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 588 }
AzureIoTClient 6:641a9672db08 589 else
AzureIoTClient 6:641a9672db08 590 {
AzureIoTClient 6:641a9672db08 591 result = 0;
AzureIoTClient 6:641a9672db08 592 }
Azure.IoT Build 0:6ae2f7bca550 593
AzureIoTClient 23:1111ee8bcba4 594 amqpvalue_destroy(value_value);
AzureIoTClient 6:641a9672db08 595 }
Azure.IoT Build 0:6ae2f7bca550 596
AzureIoTClient 23:1111ee8bcba4 597 amqpvalue_destroy(key_value);
AzureIoTClient 6:641a9672db08 598 }
Azure.IoT Build 0:6ae2f7bca550 599
AzureIoTClient 6:641a9672db08 600 return result;
Azure.IoT Build 0:6ae2f7bca550 601 }
Azure.IoT Build 0:6ae2f7bca550 602
AzureIoTClient 39:e7c983378f41 603 static int internal_set_status_code_key_name(AMQP_MANAGEMENT_HANDLE amqp_management, const char* status_code_key_name)
AzureIoTClient 39:e7c983378f41 604 {
AzureIoTClient 39:e7c983378f41 605 int result;
AzureIoTClient 39:e7c983378f41 606 char* copied_status_code_key_name;
AzureIoTClient 39:e7c983378f41 607 if (mallocAndStrcpy_s(&copied_status_code_key_name, status_code_key_name) != 0)
AzureIoTClient 39:e7c983378f41 608 {
AzureIoTClient 39:e7c983378f41 609 LogError("Cannot copy status code key name");
AzureIoTClient 39:e7c983378f41 610 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 611 }
AzureIoTClient 39:e7c983378f41 612 else
AzureIoTClient 39:e7c983378f41 613 {
AzureIoTClient 39:e7c983378f41 614 if (amqp_management->status_code_key_name != NULL)
AzureIoTClient 39:e7c983378f41 615 {
AzureIoTClient 39:e7c983378f41 616 free(amqp_management->status_code_key_name);
AzureIoTClient 39:e7c983378f41 617 }
AzureIoTClient 39:e7c983378f41 618
AzureIoTClient 39:e7c983378f41 619 amqp_management->status_code_key_name = copied_status_code_key_name;
AzureIoTClient 39:e7c983378f41 620 result = 0;
AzureIoTClient 39:e7c983378f41 621 }
AzureIoTClient 39:e7c983378f41 622
AzureIoTClient 39:e7c983378f41 623 return result;
AzureIoTClient 39:e7c983378f41 624 }
AzureIoTClient 39:e7c983378f41 625
AzureIoTClient 39:e7c983378f41 626 static int internal_set_status_description_key_name(AMQP_MANAGEMENT_HANDLE amqp_management, const char* status_description_key_name)
AzureIoTClient 39:e7c983378f41 627 {
AzureIoTClient 39:e7c983378f41 628 int result;
AzureIoTClient 39:e7c983378f41 629 char* copied_status_description_key_name;
AzureIoTClient 39:e7c983378f41 630 if (mallocAndStrcpy_s(&copied_status_description_key_name, status_description_key_name) != 0)
AzureIoTClient 39:e7c983378f41 631 {
AzureIoTClient 39:e7c983378f41 632 LogError("Cannot copy status description key name");
AzureIoTClient 39:e7c983378f41 633 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 634 }
AzureIoTClient 39:e7c983378f41 635 else
AzureIoTClient 39:e7c983378f41 636 {
AzureIoTClient 39:e7c983378f41 637 if (amqp_management->status_description_key_name != NULL)
AzureIoTClient 39:e7c983378f41 638 {
AzureIoTClient 39:e7c983378f41 639 free(amqp_management->status_description_key_name);
AzureIoTClient 39:e7c983378f41 640 }
AzureIoTClient 39:e7c983378f41 641
AzureIoTClient 39:e7c983378f41 642 amqp_management->status_description_key_name = copied_status_description_key_name;
AzureIoTClient 39:e7c983378f41 643 result = 0;
AzureIoTClient 39:e7c983378f41 644 }
AzureIoTClient 39:e7c983378f41 645
AzureIoTClient 39:e7c983378f41 646 return result;
AzureIoTClient 39:e7c983378f41 647 }
AzureIoTClient 39:e7c983378f41 648
AzureIoTClient 22:524bded3f7a8 649 AMQP_MANAGEMENT_HANDLE amqp_management_create(SESSION_HANDLE session, const char* management_node)
Azure.IoT Build 0:6ae2f7bca550 650 {
AzureIoTClient 39:e7c983378f41 651 AMQP_MANAGEMENT_INSTANCE* amqp_management;
Azure.IoT Build 0:6ae2f7bca550 652
AzureIoTClient 23:1111ee8bcba4 653 if ((session == NULL) ||
AzureIoTClient 23:1111ee8bcba4 654 (management_node == NULL))
AzureIoTClient 6:641a9672db08 655 {
AzureIoTClient 23:1111ee8bcba4 656 /* Codes_SRS_AMQP_MANAGEMENT_01_002: [ If `session` or `management_node` is NULL then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 23:1111ee8bcba4 657 LogError("Bad arguments: session = %p, management_node = %p", session, management_node);
AzureIoTClient 39:e7c983378f41 658 amqp_management = NULL;
AzureIoTClient 23:1111ee8bcba4 659 }
AzureIoTClient 23:1111ee8bcba4 660 else if (strlen(management_node) == 0)
AzureIoTClient 23:1111ee8bcba4 661 {
AzureIoTClient 23:1111ee8bcba4 662 /* Codes_SRS_AMQP_MANAGEMENT_01_030: [ If `management_node` is an empty string, then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 23:1111ee8bcba4 663 LogError("Empty string management node");
AzureIoTClient 39:e7c983378f41 664 amqp_management = NULL;
AzureIoTClient 6:641a9672db08 665 }
AzureIoTClient 6:641a9672db08 666 else
AzureIoTClient 6:641a9672db08 667 {
AzureIoTClient 23:1111ee8bcba4 668 /* Codes_SRS_AMQP_MANAGEMENT_01_001: [ `amqp_management_create` shall create a new CBS instance and on success return a non-NULL handle to it. ]*/
AzureIoTClient 39:e7c983378f41 669 amqp_management = (AMQP_MANAGEMENT_INSTANCE*)malloc(sizeof(AMQP_MANAGEMENT_INSTANCE));
AzureIoTClient 39:e7c983378f41 670 if (amqp_management == NULL)
AzureIoTClient 6:641a9672db08 671 {
AzureIoTClient 23:1111ee8bcba4 672 /* Codes_SRS_AMQP_MANAGEMENT_01_005: [ If allocating memory for the new handle fails, `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 23:1111ee8bcba4 673 LogError("Cannot allocate memory for AMQP management handle");
AzureIoTClient 23:1111ee8bcba4 674 }
AzureIoTClient 23:1111ee8bcba4 675 else
AzureIoTClient 23:1111ee8bcba4 676 {
AzureIoTClient 39:e7c983378f41 677 amqp_management->sender_connected = 0;
AzureIoTClient 39:e7c983378f41 678 amqp_management->receiver_connected = 0;
AzureIoTClient 39:e7c983378f41 679 amqp_management->on_amqp_management_open_complete = NULL;
AzureIoTClient 39:e7c983378f41 680 amqp_management->on_amqp_management_open_complete_context = NULL;
AzureIoTClient 39:e7c983378f41 681 amqp_management->on_amqp_management_error = NULL;
AzureIoTClient 39:e7c983378f41 682 amqp_management->on_amqp_management_error_context = NULL;
AzureIoTClient 39:e7c983378f41 683 amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 39:e7c983378f41 684 amqp_management->status_code_key_name = NULL;
AzureIoTClient 39:e7c983378f41 685 amqp_management->status_description_key_name = NULL;
Azure.IoT Build 0:6ae2f7bca550 686
AzureIoTClient 23:1111ee8bcba4 687 /* Codes_SRS_AMQP_MANAGEMENT_01_003: [ `amqp_management_create` shall create a singly linked list for pending operations by calling `singlylinkedlist_create`. ]*/
AzureIoTClient 39:e7c983378f41 688 amqp_management->pending_operations = singlylinkedlist_create();
AzureIoTClient 39:e7c983378f41 689 if (amqp_management->pending_operations == NULL)
AzureIoTClient 6:641a9672db08 690 {
AzureIoTClient 23:1111ee8bcba4 691 /* Codes_SRS_AMQP_MANAGEMENT_01_004: [ If `singlylinkedlist_create` fails, `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 23:1111ee8bcba4 692 LogError("Cannot create pending operations list");
AzureIoTClient 6:641a9672db08 693 }
AzureIoTClient 6:641a9672db08 694 else
AzureIoTClient 6:641a9672db08 695 {
AzureIoTClient 39:e7c983378f41 696 /* Codes_SRS_AMQP_MANAGEMENT_01_181: [ `amqp_management_create` shall set the status code key name to be used for parsing the status code to `statusCode`. ]*/
AzureIoTClient 39:e7c983378f41 697 if (internal_set_status_code_key_name(amqp_management, "statusCode") != 0)
AzureIoTClient 6:641a9672db08 698 {
AzureIoTClient 39:e7c983378f41 699 LogError("Cannot set status code key name");
AzureIoTClient 6:641a9672db08 700 }
AzureIoTClient 6:641a9672db08 701 else
AzureIoTClient 6:641a9672db08 702 {
AzureIoTClient 39:e7c983378f41 703 /* Codes_SRS_AMQP_MANAGEMENT_01_182: [ `amqp_management_create` shall set the status description key name to be used for parsing the status description to `statusDescription`. ]*/
AzureIoTClient 39:e7c983378f41 704 if (internal_set_status_description_key_name(amqp_management, "statusDescription") != 0)
AzureIoTClient 6:641a9672db08 705 {
AzureIoTClient 39:e7c983378f41 706 LogError("Cannot set status description key name");
AzureIoTClient 6:641a9672db08 707 }
AzureIoTClient 6:641a9672db08 708 else
AzureIoTClient 6:641a9672db08 709 {
AzureIoTClient 39:e7c983378f41 710 /* Codes_SRS_AMQP_MANAGEMENT_01_010: [ The `source` argument shall be a value created by calling `messaging_create_source` with `management_node` as argument. ]*/
AzureIoTClient 39:e7c983378f41 711 AMQP_VALUE source = messaging_create_source(management_node);
AzureIoTClient 39:e7c983378f41 712 if (source == NULL)
AzureIoTClient 6:641a9672db08 713 {
AzureIoTClient 39:e7c983378f41 714 /* Codes_SRS_AMQP_MANAGEMENT_01_012: [ If `messaging_create_source` fails then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 715 LogError("Failed creating source AMQP value");
AzureIoTClient 6:641a9672db08 716 }
AzureIoTClient 6:641a9672db08 717 else
AzureIoTClient 6:641a9672db08 718 {
AzureIoTClient 39:e7c983378f41 719 /* Codes_SRS_AMQP_MANAGEMENT_01_011: [ The `target` argument shall be a value created by calling `messaging_create_target` with `management_node` as argument. ]*/
AzureIoTClient 39:e7c983378f41 720 AMQP_VALUE target = messaging_create_target(management_node);
AzureIoTClient 39:e7c983378f41 721 if (target == NULL)
AzureIoTClient 6:641a9672db08 722 {
AzureIoTClient 39:e7c983378f41 723 /* Codes_SRS_AMQP_MANAGEMENT_01_013: [ If `messaging_create_target` fails then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 724 LogError("Failed creating target AMQP value");
AzureIoTClient 6:641a9672db08 725 }
AzureIoTClient 6:641a9672db08 726 else
AzureIoTClient 6:641a9672db08 727 {
AzureIoTClient 39:e7c983378f41 728 size_t management_node_length = strlen(management_node);
AzureIoTClient 23:1111ee8bcba4 729
AzureIoTClient 39:e7c983378f41 730 char* sender_link_name = (char*)malloc(management_node_length + COUNT_CHARS(sender_suffix) + 1);
AzureIoTClient 39:e7c983378f41 731 if (sender_link_name == NULL)
AzureIoTClient 6:641a9672db08 732 {
AzureIoTClient 39:e7c983378f41 733 /* Codes_SRS_AMQP_MANAGEMENT_01_033: [ If any other error occurs `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 734 LogError("Failed allocating memory for sender link name");
AzureIoTClient 6:641a9672db08 735 }
AzureIoTClient 6:641a9672db08 736 else
AzureIoTClient 6:641a9672db08 737 {
AzureIoTClient 39:e7c983378f41 738 char* receiver_link_name;
AzureIoTClient 39:e7c983378f41 739
AzureIoTClient 39:e7c983378f41 740 (void)memcpy(sender_link_name, management_node, management_node_length);
AzureIoTClient 39:e7c983378f41 741 (void)memcpy(sender_link_name + management_node_length, sender_suffix, COUNT_CHARS(sender_suffix) + 1);
AzureIoTClient 39:e7c983378f41 742
AzureIoTClient 39:e7c983378f41 743 receiver_link_name = (char*)malloc(management_node_length + COUNT_CHARS(receiver_suffix) + 1);
AzureIoTClient 39:e7c983378f41 744 if (receiver_link_name == NULL)
AzureIoTClient 6:641a9672db08 745 {
AzureIoTClient 39:e7c983378f41 746 /* Codes_SRS_AMQP_MANAGEMENT_01_033: [ If any other error occurs `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 747 LogError("Failed allocating memory for receiver link name");
AzureIoTClient 6:641a9672db08 748 }
AzureIoTClient 6:641a9672db08 749 else
AzureIoTClient 6:641a9672db08 750 {
AzureIoTClient 39:e7c983378f41 751 (void)memcpy(receiver_link_name, management_node, management_node_length);
AzureIoTClient 39:e7c983378f41 752 (void)memcpy(receiver_link_name + management_node_length, receiver_suffix, COUNT_CHARS(receiver_suffix) + 1);
AzureIoTClient 39:e7c983378f41 753
AzureIoTClient 39:e7c983378f41 754 /* Codes_SRS_AMQP_MANAGEMENT_01_006: [ `amqp_management_create` shall create a sender link by calling `link_create`. ]*/
AzureIoTClient 39:e7c983378f41 755 /* Codes_SRS_AMQP_MANAGEMENT_01_007: [ The `session` argument shall be set to `session`. ]*/
AzureIoTClient 39:e7c983378f41 756 /* Codes_SRS_AMQP_MANAGEMENT_01_008: [ The `name` argument shall be constructed by concatenating the `management_node` value with `-sender`. ]*/
AzureIoTClient 39:e7c983378f41 757 /* Codes_SRS_AMQP_MANAGEMENT_01_009: [ The `role` argument shall be `role_sender`. ]*/
AzureIoTClient 39:e7c983378f41 758 /* Codes_SRS_AMQP_MANAGEMENT_01_019: [ The `source` argument shall be the value created by calling `messaging_create_source`. ]*/
AzureIoTClient 39:e7c983378f41 759 /* Codes_SRS_AMQP_MANAGEMENT_01_020: [ The `target` argument shall be the value created by calling `messaging_create_target`. ]*/
AzureIoTClient 39:e7c983378f41 760 amqp_management->sender_link = link_create(session, sender_link_name, role_sender, source, target);
AzureIoTClient 39:e7c983378f41 761 if (amqp_management->sender_link == NULL)
AzureIoTClient 6:641a9672db08 762 {
AzureIoTClient 39:e7c983378f41 763 /* Codes_SRS_AMQP_MANAGEMENT_01_014: [ If `link_create` fails when creating the sender link then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 764 LogError("Failed creating sender link");
AzureIoTClient 6:641a9672db08 765 }
AzureIoTClient 6:641a9672db08 766 else
AzureIoTClient 6:641a9672db08 767 {
AzureIoTClient 39:e7c983378f41 768 /* Codes_SRS_AMQP_MANAGEMENT_01_015: [ `amqp_management_create` shall create a receiver link by calling `link_create`. ]*/
AzureIoTClient 39:e7c983378f41 769 /* Codes_SRS_AMQP_MANAGEMENT_01_016: [ The `session` argument shall be set to `session`. ]*/
AzureIoTClient 39:e7c983378f41 770 /* Codes_SRS_AMQP_MANAGEMENT_01_017: [ The `name` argument shall be constructed by concatenating the `management_node` value with `-receiver`. ]*/
AzureIoTClient 39:e7c983378f41 771 /* Codes_SRS_AMQP_MANAGEMENT_01_018: [ The `role` argument shall be `role_receiver`. ]*/
AzureIoTClient 39:e7c983378f41 772 /* Codes_SRS_AMQP_MANAGEMENT_01_019: [ The `source` argument shall be the value created by calling `messaging_create_source`. ]*/
AzureIoTClient 39:e7c983378f41 773 /* Codes_SRS_AMQP_MANAGEMENT_01_020: [ The `target` argument shall be the value created by calling `messaging_create_target`. ]*/
AzureIoTClient 39:e7c983378f41 774 amqp_management->receiver_link = link_create(session, receiver_link_name, role_receiver, source, target);
AzureIoTClient 39:e7c983378f41 775 if (amqp_management->receiver_link == NULL)
AzureIoTClient 6:641a9672db08 776 {
AzureIoTClient 39:e7c983378f41 777 /* Codes_SRS_AMQP_MANAGEMENT_01_021: [ If `link_create` fails when creating the receiver link then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 778 LogError("Failed creating receiver link");
AzureIoTClient 6:641a9672db08 779 }
AzureIoTClient 6:641a9672db08 780 else
AzureIoTClient 6:641a9672db08 781 {
AzureIoTClient 39:e7c983378f41 782 /* Codes_SRS_AMQP_MANAGEMENT_01_022: [ `amqp_management_create` shall create a message sender by calling `messagesender_create` and passing to it the sender link handle. ]*/
AzureIoTClient 39:e7c983378f41 783 amqp_management->message_sender = messagesender_create(amqp_management->sender_link, on_message_sender_state_changed, amqp_management);
AzureIoTClient 39:e7c983378f41 784 if (amqp_management->message_sender == NULL)
AzureIoTClient 39:e7c983378f41 785 {
AzureIoTClient 39:e7c983378f41 786 /* Codes_SRS_AMQP_MANAGEMENT_01_031: [ If `messagesender_create` fails then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 787 LogError("Failed creating message sender");
AzureIoTClient 39:e7c983378f41 788 }
AzureIoTClient 39:e7c983378f41 789 else
AzureIoTClient 39:e7c983378f41 790 {
AzureIoTClient 39:e7c983378f41 791 /* Codes_SRS_AMQP_MANAGEMENT_01_023: [ `amqp_management_create` shall create a message receiver by calling `messagereceiver_create` and passing to it the receiver link handle. ]*/
AzureIoTClient 39:e7c983378f41 792 amqp_management->message_receiver = messagereceiver_create(amqp_management->receiver_link, on_message_receiver_state_changed, amqp_management);
AzureIoTClient 39:e7c983378f41 793 if (amqp_management->message_receiver == NULL)
AzureIoTClient 39:e7c983378f41 794 {
AzureIoTClient 39:e7c983378f41 795 /* Codes_SRS_AMQP_MANAGEMENT_01_032: [ If `messagereceiver_create` fails then `amqp_management_create` shall fail and return NULL. ]*/
AzureIoTClient 39:e7c983378f41 796 LogError("Failed creating message receiver");
AzureIoTClient 39:e7c983378f41 797 link_destroy(amqp_management->receiver_link);
AzureIoTClient 39:e7c983378f41 798 }
AzureIoTClient 39:e7c983378f41 799 else
AzureIoTClient 39:e7c983378f41 800 {
AzureIoTClient 39:e7c983378f41 801 free(receiver_link_name);
AzureIoTClient 39:e7c983378f41 802 free(sender_link_name);
AzureIoTClient 39:e7c983378f41 803 amqpvalue_destroy(target);
AzureIoTClient 39:e7c983378f41 804 amqpvalue_destroy(source);
AzureIoTClient 39:e7c983378f41 805
AzureIoTClient 39:e7c983378f41 806 /* Codes_SRS_AMQP_MANAGEMENT_01_106: [ The message Id set on the message properties shall start at 0. ]*/
AzureIoTClient 39:e7c983378f41 807 amqp_management->next_message_id = 0;
AzureIoTClient 39:e7c983378f41 808
AzureIoTClient 39:e7c983378f41 809 goto all_ok;
AzureIoTClient 39:e7c983378f41 810 }
AzureIoTClient 39:e7c983378f41 811
AzureIoTClient 39:e7c983378f41 812 messagesender_destroy(amqp_management->message_sender);
AzureIoTClient 39:e7c983378f41 813 }
AzureIoTClient 39:e7c983378f41 814
AzureIoTClient 39:e7c983378f41 815 link_destroy(amqp_management->receiver_link);
AzureIoTClient 6:641a9672db08 816 }
AzureIoTClient 39:e7c983378f41 817
AzureIoTClient 39:e7c983378f41 818 link_destroy(amqp_management->sender_link);
AzureIoTClient 6:641a9672db08 819 }
AzureIoTClient 39:e7c983378f41 820
AzureIoTClient 39:e7c983378f41 821 free(receiver_link_name);
AzureIoTClient 6:641a9672db08 822 }
AzureIoTClient 39:e7c983378f41 823
AzureIoTClient 39:e7c983378f41 824 free(sender_link_name);
AzureIoTClient 6:641a9672db08 825 }
AzureIoTClient 23:1111ee8bcba4 826
AzureIoTClient 39:e7c983378f41 827 amqpvalue_destroy(target);
AzureIoTClient 6:641a9672db08 828 }
Azure.IoT Build 0:6ae2f7bca550 829
AzureIoTClient 39:e7c983378f41 830 amqpvalue_destroy(source);
AzureIoTClient 6:641a9672db08 831 }
Azure.IoT Build 0:6ae2f7bca550 832
AzureIoTClient 39:e7c983378f41 833 free(amqp_management->status_description_key_name);
AzureIoTClient 6:641a9672db08 834 }
Azure.IoT Build 0:6ae2f7bca550 835
AzureIoTClient 39:e7c983378f41 836 free(amqp_management->status_code_key_name);
AzureIoTClient 6:641a9672db08 837 }
AzureIoTClient 39:e7c983378f41 838
AzureIoTClient 39:e7c983378f41 839 singlylinkedlist_destroy(amqp_management->pending_operations);
AzureIoTClient 6:641a9672db08 840 }
AzureIoTClient 39:e7c983378f41 841
AzureIoTClient 39:e7c983378f41 842 free(amqp_management);
AzureIoTClient 39:e7c983378f41 843 amqp_management = NULL;
AzureIoTClient 6:641a9672db08 844 }
AzureIoTClient 6:641a9672db08 845 }
Azure.IoT Build 0:6ae2f7bca550 846
AzureIoTClient 39:e7c983378f41 847 all_ok:
AzureIoTClient 39:e7c983378f41 848 return amqp_management;
Azure.IoT Build 0:6ae2f7bca550 849 }
Azure.IoT Build 0:6ae2f7bca550 850
AzureIoTClient 22:524bded3f7a8 851 void amqp_management_destroy(AMQP_MANAGEMENT_HANDLE amqp_management)
Azure.IoT Build 0:6ae2f7bca550 852 {
AzureIoTClient 23:1111ee8bcba4 853 if (amqp_management == NULL)
AzureIoTClient 6:641a9672db08 854 {
AzureIoTClient 23:1111ee8bcba4 855 /* Codes_SRS_AMQP_MANAGEMENT_01_025: [ If `amqp_management` is NULL, `amqp_management_destroy` shall do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 856 LogError("NULL amqp_management");
AzureIoTClient 23:1111ee8bcba4 857 }
AzureIoTClient 23:1111ee8bcba4 858 else
AzureIoTClient 23:1111ee8bcba4 859 {
AzureIoTClient 23:1111ee8bcba4 860 /* Codes_SRS_AMQP_MANAGEMENT_01_024: [ `amqp_management_destroy` shall free all the resources allocated by `amqp_management_create`. ]*/
AzureIoTClient 23:1111ee8bcba4 861 if (amqp_management->amqp_management_state != AMQP_MANAGEMENT_STATE_IDLE)
AzureIoTClient 6:641a9672db08 862 {
AzureIoTClient 23:1111ee8bcba4 863 (void)amqp_management_close(amqp_management);
AzureIoTClient 6:641a9672db08 864 }
Azure.IoT Build 0:6ae2f7bca550 865
AzureIoTClient 23:1111ee8bcba4 866 /* Codes_SRS_AMQP_MANAGEMENT_01_028: [ `amqp_management_destroy` shall free the message sender by calling `messagesender_destroy`. ]*/
AzureIoTClient 23:1111ee8bcba4 867 messagesender_destroy(amqp_management->message_sender);
AzureIoTClient 23:1111ee8bcba4 868 /* Codes_SRS_AMQP_MANAGEMENT_01_029: [ `amqp_management_destroy` shall free the message receiver by calling `messagereceiver_destroy`. ]*/
AzureIoTClient 23:1111ee8bcba4 869 messagereceiver_destroy(amqp_management->message_receiver);
AzureIoTClient 23:1111ee8bcba4 870 /* Codes_SRS_AMQP_MANAGEMENT_01_027: [ `amqp_management_destroy` shall free the sender and receiver links by calling `link_destroy`. ]*/
AzureIoTClient 6:641a9672db08 871 link_destroy(amqp_management->sender_link);
AzureIoTClient 6:641a9672db08 872 link_destroy(amqp_management->receiver_link);
AzureIoTClient 39:e7c983378f41 873 free(amqp_management->status_code_key_name);
AzureIoTClient 39:e7c983378f41 874 free(amqp_management->status_description_key_name);
AzureIoTClient 23:1111ee8bcba4 875 /* Codes_SRS_AMQP_MANAGEMENT_01_026: [ `amqp_management_destroy` shall free the singly linked list by calling `singlylinkedlist_destroy`. ]*/
AzureIoTClient 23:1111ee8bcba4 876 singlylinkedlist_destroy(amqp_management->pending_operations);
AzureIoTClient 21:f9c433d8e6ca 877 free(amqp_management);
AzureIoTClient 6:641a9672db08 878 }
Azure.IoT Build 0:6ae2f7bca550 879 }
Azure.IoT Build 0:6ae2f7bca550 880
AzureIoTClient 22:524bded3f7a8 881 int amqp_management_open_async(AMQP_MANAGEMENT_HANDLE amqp_management, ON_AMQP_MANAGEMENT_OPEN_COMPLETE on_amqp_management_open_complete, void* on_amqp_management_open_complete_context, ON_AMQP_MANAGEMENT_ERROR on_amqp_management_error, void* on_amqp_management_error_context)
Azure.IoT Build 0:6ae2f7bca550 882 {
AzureIoTClient 6:641a9672db08 883 int result;
Azure.IoT Build 0:6ae2f7bca550 884
AzureIoTClient 23:1111ee8bcba4 885 /* Codes_SRS_AMQP_MANAGEMENT_01_044: [ `on_amqp_management_open_complete_context` and `on_amqp_management_error_context` shall be allowed to be NULL. ]*/
AzureIoTClient 23:1111ee8bcba4 886 if ((amqp_management == NULL) ||
AzureIoTClient 23:1111ee8bcba4 887 (on_amqp_management_open_complete == NULL) ||
AzureIoTClient 23:1111ee8bcba4 888 (on_amqp_management_error == NULL))
AzureIoTClient 6:641a9672db08 889 {
AzureIoTClient 23:1111ee8bcba4 890 /* Codes_SRS_AMQP_MANAGEMENT_01_038: [ If `amqp_management`, `on_amqp_management_open_complete` or `on_amqp_management_error` is NULL, `amqp_management_open_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 891 LogError("Bad arguments: amqp_management = %p, on_amqp_management_open_complete = %p, on_amqp_management_error = %p",
AzureIoTClient 23:1111ee8bcba4 892 amqp_management,
AzureIoTClient 23:1111ee8bcba4 893 on_amqp_management_open_complete,
AzureIoTClient 23:1111ee8bcba4 894 on_amqp_management_error);
AzureIoTClient 23:1111ee8bcba4 895 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 896 }
AzureIoTClient 23:1111ee8bcba4 897 else if (amqp_management->amqp_management_state != AMQP_MANAGEMENT_STATE_IDLE)
AzureIoTClient 23:1111ee8bcba4 898 {
AzureIoTClient 23:1111ee8bcba4 899 /* Codes_SRS_AMQP_MANAGEMENT_01_043: [ If the AMQP management instance is already OPEN or OPENING, `amqp_management_open_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 900 LogError("AMQP management instance already OPEN");
AzureIoTClient 19:000ab4e6a2c1 901 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 902 }
AzureIoTClient 6:641a9672db08 903 else
AzureIoTClient 6:641a9672db08 904 {
AzureIoTClient 23:1111ee8bcba4 905 /* Codes_SRS_AMQP_MANAGEMENT_01_036: [ `amqp_management_open_async` shall start opening the AMQP management instance and save the callbacks so that they can be called when opening is complete. ]*/
AzureIoTClient 22:524bded3f7a8 906 amqp_management->on_amqp_management_open_complete = on_amqp_management_open_complete;
AzureIoTClient 22:524bded3f7a8 907 amqp_management->on_amqp_management_open_complete_context = on_amqp_management_open_complete_context;
AzureIoTClient 22:524bded3f7a8 908 amqp_management->on_amqp_management_error = on_amqp_management_error;
AzureIoTClient 22:524bded3f7a8 909 amqp_management->on_amqp_management_error_context = on_amqp_management_error_context;
AzureIoTClient 22:524bded3f7a8 910 amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_OPENING;
AzureIoTClient 22:524bded3f7a8 911
AzureIoTClient 23:1111ee8bcba4 912 /* Codes_SRS_AMQP_MANAGEMENT_01_040: [ `amqp_management_open_async` shall open the message receiver by calling `messagereceiver_open`. ]*/
AzureIoTClient 6:641a9672db08 913 if (messagereceiver_open(amqp_management->message_receiver, on_message_received, amqp_management) != 0)
AzureIoTClient 6:641a9672db08 914 {
AzureIoTClient 23:1111ee8bcba4 915 /* Codes_SRS_AMQP_MANAGEMENT_01_042: [ If `messagereceiver_open` fails, `amqp_management_open_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 916 LogError("Failed opening message receiver");
AzureIoTClient 22:524bded3f7a8 917 amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 19:000ab4e6a2c1 918 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 919 }
AzureIoTClient 6:641a9672db08 920 else
AzureIoTClient 6:641a9672db08 921 {
AzureIoTClient 23:1111ee8bcba4 922 /* Codes_SRS_AMQP_MANAGEMENT_01_039: [ `amqp_management_open_async` shall open the message sender by calling `messagesender_open`. ]*/
AzureIoTClient 6:641a9672db08 923 if (messagesender_open(amqp_management->message_sender) != 0)
AzureIoTClient 6:641a9672db08 924 {
AzureIoTClient 23:1111ee8bcba4 925 /* Codes_SRS_AMQP_MANAGEMENT_01_041: [ If `messagesender_open` fails, `amqp_management_open_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 926 LogError("Failed opening message sender");
AzureIoTClient 22:524bded3f7a8 927 amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 23:1111ee8bcba4 928 (void)messagereceiver_close(amqp_management->message_receiver);
AzureIoTClient 19:000ab4e6a2c1 929 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 930 }
AzureIoTClient 6:641a9672db08 931 else
AzureIoTClient 6:641a9672db08 932 {
AzureIoTClient 23:1111ee8bcba4 933 /* Codes_SRS_AMQP_MANAGEMENT_01_037: [ On success it shall return 0. ]*/
AzureIoTClient 6:641a9672db08 934 result = 0;
AzureIoTClient 6:641a9672db08 935 }
AzureIoTClient 6:641a9672db08 936 }
AzureIoTClient 6:641a9672db08 937 }
Azure.IoT Build 0:6ae2f7bca550 938
AzureIoTClient 6:641a9672db08 939 return result;
Azure.IoT Build 0:6ae2f7bca550 940 }
Azure.IoT Build 0:6ae2f7bca550 941
AzureIoTClient 22:524bded3f7a8 942 int amqp_management_close(AMQP_MANAGEMENT_HANDLE amqp_management)
Azure.IoT Build 0:6ae2f7bca550 943 {
AzureIoTClient 6:641a9672db08 944 int result;
Azure.IoT Build 0:6ae2f7bca550 945
AzureIoTClient 6:641a9672db08 946 if (amqp_management == NULL)
AzureIoTClient 6:641a9672db08 947 {
AzureIoTClient 23:1111ee8bcba4 948 /* Codes_SRS_AMQP_MANAGEMENT_01_047: [ If `amqp_management` is NULL, `amqp_management_close` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 949 LogError("NULL amqp_management");
AzureIoTClient 23:1111ee8bcba4 950 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 951 }
AzureIoTClient 23:1111ee8bcba4 952 else if (amqp_management->amqp_management_state == AMQP_MANAGEMENT_STATE_IDLE)
AzureIoTClient 23:1111ee8bcba4 953 {
AzureIoTClient 23:1111ee8bcba4 954 /* Codes_SRS_AMQP_MANAGEMENT_01_049: [ `amqp_management_close` on an AMQP management instance that is not OPEN, shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 955 LogError("AMQP management instance not open");
AzureIoTClient 19:000ab4e6a2c1 956 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 957 }
AzureIoTClient 6:641a9672db08 958 else
AzureIoTClient 6:641a9672db08 959 {
AzureIoTClient 23:1111ee8bcba4 960 /* Codes_SRS_AMQP_MANAGEMENT_01_045: [ `amqp_management_close` shall close the AMQP management instance. ]*/
AzureIoTClient 23:1111ee8bcba4 961 /* Codes_SRS_AMQP_MANAGEMENT_01_050: [ `amqp_management_close` shall close the message sender by calling `messagesender_close`. ]*/
AzureIoTClient 23:1111ee8bcba4 962 if (messagesender_close(amqp_management->message_sender) != 0)
AzureIoTClient 6:641a9672db08 963 {
AzureIoTClient 23:1111ee8bcba4 964 /* Codes_SRS_AMQP_MANAGEMENT_01_052: [ If `messagesender_close` fails, `amqp_management_close` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 965 LogError("messagesender_close failed");
AzureIoTClient 23:1111ee8bcba4 966 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 967 }
AzureIoTClient 23:1111ee8bcba4 968 /* Codes_SRS_AMQP_MANAGEMENT_01_051: [ `amqp_management_close` shall close the message receiver by calling `messagereceiver_close`. ]*/
AzureIoTClient 23:1111ee8bcba4 969 else if (messagereceiver_close(amqp_management->message_receiver) != 0)
AzureIoTClient 23:1111ee8bcba4 970 {
AzureIoTClient 23:1111ee8bcba4 971 /* Codes_SRS_AMQP_MANAGEMENT_01_053: [ If `messagereceiver_close` fails, `amqp_management_close` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 972 LogError("messagereceiver_close failed");
AzureIoTClient 19:000ab4e6a2c1 973 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 974 }
AzureIoTClient 6:641a9672db08 975 else
AzureIoTClient 6:641a9672db08 976 {
AzureIoTClient 23:1111ee8bcba4 977 LIST_ITEM_HANDLE list_item_handle = singlylinkedlist_get_head_item(amqp_management->pending_operations);
AzureIoTClient 23:1111ee8bcba4 978 while (list_item_handle != NULL)
AzureIoTClient 23:1111ee8bcba4 979 {
AzureIoTClient 23:1111ee8bcba4 980 OPERATION_MESSAGE_INSTANCE* operation_message = (OPERATION_MESSAGE_INSTANCE*)singlylinkedlist_item_get_value(list_item_handle);
AzureIoTClient 23:1111ee8bcba4 981 if (operation_message == NULL)
AzureIoTClient 23:1111ee8bcba4 982 {
AzureIoTClient 23:1111ee8bcba4 983 LogError("Cannot obtain pending operation");
AzureIoTClient 23:1111ee8bcba4 984 }
AzureIoTClient 23:1111ee8bcba4 985 else
AzureIoTClient 23:1111ee8bcba4 986 {
AzureIoTClient 23:1111ee8bcba4 987 /* Codes_SRS_AMQP_MANAGEMENT_01_054: [ All pending operations shall be indicated complete with the code `AMQP_MANAGEMENT_EXECUTE_OPERATION_INSTANCE_CLOSED`. ]*/
AzureIoTClient 39:e7c983378f41 988 operation_message->on_execute_operation_complete(operation_message->callback_context, AMQP_MANAGEMENT_EXECUTE_OPERATION_INSTANCE_CLOSED, 0, NULL, NULL);
AzureIoTClient 23:1111ee8bcba4 989 free(operation_message);
AzureIoTClient 23:1111ee8bcba4 990 }
AzureIoTClient 23:1111ee8bcba4 991
AzureIoTClient 23:1111ee8bcba4 992 if (singlylinkedlist_remove(amqp_management->pending_operations, list_item_handle) != 0)
AzureIoTClient 23:1111ee8bcba4 993 {
AzureIoTClient 23:1111ee8bcba4 994 LogError("Cannot remove item");
AzureIoTClient 23:1111ee8bcba4 995 }
AzureIoTClient 23:1111ee8bcba4 996
AzureIoTClient 23:1111ee8bcba4 997 list_item_handle = singlylinkedlist_get_head_item(amqp_management->pending_operations);
AzureIoTClient 23:1111ee8bcba4 998 }
AzureIoTClient 23:1111ee8bcba4 999
AzureIoTClient 23:1111ee8bcba4 1000 if (amqp_management->amqp_management_state == AMQP_MANAGEMENT_STATE_OPENING)
AzureIoTClient 23:1111ee8bcba4 1001 {
AzureIoTClient 23:1111ee8bcba4 1002 /* Codes_SRS_AMQP_MANAGEMENT_01_048: [ `amqp_management_close` on an AMQP management instance that is OPENING shall trigger the `on_amqp_management_open_complete` callback with `AMQP_MANAGEMENT_OPEN_CANCELLED`, while also passing the context passed in `amqp_management_open_async`. ]*/
AzureIoTClient 23:1111ee8bcba4 1003 amqp_management->on_amqp_management_open_complete(amqp_management->on_amqp_management_open_complete_context, AMQP_MANAGEMENT_OPEN_CANCELLED);
AzureIoTClient 23:1111ee8bcba4 1004 }
AzureIoTClient 23:1111ee8bcba4 1005
AzureIoTClient 22:524bded3f7a8 1006 amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
AzureIoTClient 23:1111ee8bcba4 1007
AzureIoTClient 23:1111ee8bcba4 1008 /* Codes_SRS_AMQP_MANAGEMENT_01_046: [ On success it shall return 0. ]*/
AzureIoTClient 6:641a9672db08 1009 result = 0;
AzureIoTClient 6:641a9672db08 1010 }
AzureIoTClient 6:641a9672db08 1011 }
Azure.IoT Build 0:6ae2f7bca550 1012
AzureIoTClient 6:641a9672db08 1013 return result;
Azure.IoT Build 0:6ae2f7bca550 1014 }
Azure.IoT Build 0:6ae2f7bca550 1015
AzureIoTClient 22:524bded3f7a8 1016 int amqp_management_execute_operation_async(AMQP_MANAGEMENT_HANDLE amqp_management, const char* operation, const char* type, const char* locales, MESSAGE_HANDLE message, ON_AMQP_MANAGEMENT_EXECUTE_OPERATION_COMPLETE on_execute_operation_complete, void* on_execute_operation_complete_context)
Azure.IoT Build 0:6ae2f7bca550 1017 {
AzureIoTClient 6:641a9672db08 1018 int result;
AzureIoTClient 6:641a9672db08 1019
AzureIoTClient 6:641a9672db08 1020 if ((amqp_management == NULL) ||
AzureIoTClient 23:1111ee8bcba4 1021 (operation == NULL) ||
AzureIoTClient 23:1111ee8bcba4 1022 (type == NULL) ||
AzureIoTClient 23:1111ee8bcba4 1023 (on_execute_operation_complete == NULL))
AzureIoTClient 6:641a9672db08 1024 {
AzureIoTClient 23:1111ee8bcba4 1025 /* Codes_SRS_AMQP_MANAGEMENT_01_057: [ If `amqp_management`, `operation`, `type` or `on_execute_operation_complete` is NULL, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1026 LogError("Bad arguments: amqp_management = %p, operation = %p, type = %p",
AzureIoTClient 23:1111ee8bcba4 1027 amqp_management, operation, type);
AzureIoTClient 23:1111ee8bcba4 1028 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 1029 }
AzureIoTClient 23:1111ee8bcba4 1030 /* Codes_SRS_AMQP_MANAGEMENT_01_081: [ If `amqp_management_execute_operation_async` is called when not OPEN, it shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1031 else if ((amqp_management->amqp_management_state == AMQP_MANAGEMENT_STATE_IDLE) ||
AzureIoTClient 23:1111ee8bcba4 1032 /* Codes_SRS_AMQP_MANAGEMENT_01_104: [ If `amqp_management_execute_operation_async` is called when the AMQP management is in error, it shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1033 (amqp_management->amqp_management_state == AMQP_MANAGEMENT_STATE_ERROR))
AzureIoTClient 23:1111ee8bcba4 1034 {
AzureIoTClient 23:1111ee8bcba4 1035 LogError("amqp_management_execute_operation_async called while not open or in error");
AzureIoTClient 19:000ab4e6a2c1 1036 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1037 }
AzureIoTClient 6:641a9672db08 1038 else
AzureIoTClient 6:641a9672db08 1039 {
AzureIoTClient 6:641a9672db08 1040 AMQP_VALUE application_properties;
AzureIoTClient 23:1111ee8bcba4 1041 MESSAGE_HANDLE cloned_message;
AzureIoTClient 23:1111ee8bcba4 1042
AzureIoTClient 23:1111ee8bcba4 1043 if (message == NULL)
AzureIoTClient 23:1111ee8bcba4 1044 {
AzureIoTClient 23:1111ee8bcba4 1045 /* Codes_SRS_AMQP_MANAGEMENT_01_102: [ If `message` is NULL, a new message shall be created by calling `message_create`. ]*/
AzureIoTClient 23:1111ee8bcba4 1046 cloned_message = message_create();
AzureIoTClient 23:1111ee8bcba4 1047 }
AzureIoTClient 23:1111ee8bcba4 1048 else
AzureIoTClient 23:1111ee8bcba4 1049 {
AzureIoTClient 23:1111ee8bcba4 1050 /* Codes_SRS_AMQP_MANAGEMENT_01_103: [ Otherwise the existing message shall be cloned by using `message_clone` before being modified accordingly and used for the pending operation. ]*/
AzureIoTClient 23:1111ee8bcba4 1051 cloned_message = message_clone(message);
AzureIoTClient 23:1111ee8bcba4 1052 if (cloned_message == NULL)
AzureIoTClient 23:1111ee8bcba4 1053 {
AzureIoTClient 23:1111ee8bcba4 1054 LogError("Could not clone message");
AzureIoTClient 23:1111ee8bcba4 1055 }
AzureIoTClient 23:1111ee8bcba4 1056 }
AzureIoTClient 23:1111ee8bcba4 1057
AzureIoTClient 23:1111ee8bcba4 1058 if (cloned_message == NULL)
AzureIoTClient 6:641a9672db08 1059 {
AzureIoTClient 19:000ab4e6a2c1 1060 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1061 }
AzureIoTClient 6:641a9672db08 1062 else
AzureIoTClient 6:641a9672db08 1063 {
AzureIoTClient 23:1111ee8bcba4 1064 /* Codes_SRS_AMQP_MANAGEMENT_01_055: [ `amqp_management_execute_operation_async` shall start an AMQP management operation. ]*/
AzureIoTClient 23:1111ee8bcba4 1065 /* Codes_SRS_AMQP_MANAGEMENT_01_082: [ `amqp_management_execute_operation_async` shall obtain the application properties from the message by calling `message_get_application_properties`. ]*/
AzureIoTClient 23:1111ee8bcba4 1066 if (message_get_application_properties(cloned_message, &application_properties) != 0)
AzureIoTClient 6:641a9672db08 1067 {
AzureIoTClient 23:1111ee8bcba4 1068 LogError("Could not get application properties");
AzureIoTClient 19:000ab4e6a2c1 1069 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1070 }
AzureIoTClient 6:641a9672db08 1071 else
AzureIoTClient 6:641a9672db08 1072 {
AzureIoTClient 23:1111ee8bcba4 1073 if (application_properties == NULL)
AzureIoTClient 23:1111ee8bcba4 1074 {
AzureIoTClient 23:1111ee8bcba4 1075 /* Codes_SRS_AMQP_MANAGEMENT_01_083: [ If no application properties were set on the message, a new application properties instance shall be created by calling `amqpvalue_create_map`; ]*/
AzureIoTClient 23:1111ee8bcba4 1076 application_properties = amqpvalue_create_map();
AzureIoTClient 23:1111ee8bcba4 1077 if (application_properties == NULL)
AzureIoTClient 23:1111ee8bcba4 1078 {
AzureIoTClient 23:1111ee8bcba4 1079 LogError("Could not create application properties");
AzureIoTClient 23:1111ee8bcba4 1080 }
AzureIoTClient 23:1111ee8bcba4 1081 }
AzureIoTClient 23:1111ee8bcba4 1082
AzureIoTClient 23:1111ee8bcba4 1083 if (application_properties == NULL)
AzureIoTClient 6:641a9672db08 1084 {
AzureIoTClient 19:000ab4e6a2c1 1085 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1086 }
AzureIoTClient 6:641a9672db08 1087 else
AzureIoTClient 6:641a9672db08 1088 {
AzureIoTClient 23:1111ee8bcba4 1089 /* Codes_SRS_AMQP_MANAGEMENT_01_084: [ For each of the arguments `operation`, `type` and `locales` an AMQP value of type string shall be created by calling `amqpvalue_create_string` in order to be used as key in the application properties map. ]*/
AzureIoTClient 23:1111ee8bcba4 1090 /* Codes_SRS_AMQP_MANAGEMENT_01_085: [ For each of the arguments `operation`, `type` and `locales` an AMQP value of type string containing the argument value shall be created by calling `amqpvalue_create_string` in order to be used as value in the application properties map. ]*/
AzureIoTClient 23:1111ee8bcba4 1091 /* Codes_SRS_AMQP_MANAGEMENT_01_058: [ Request messages have the following application-properties: ]*/
AzureIoTClient 23:1111ee8bcba4 1092 /* Codes_SRS_AMQP_MANAGEMENT_01_059: [ operation string Yes The management operation to be performed. ] */
AzureIoTClient 23:1111ee8bcba4 1093 if ((add_string_key_value_pair_to_map(application_properties, "operation", operation) != 0) ||
AzureIoTClient 23:1111ee8bcba4 1094 /* Codes_SRS_AMQP_MANAGEMENT_01_061: [ type string Yes The Manageable Entity Type of the Manageable Entity to be managed. ]*/
AzureIoTClient 23:1111ee8bcba4 1095 (add_string_key_value_pair_to_map(application_properties, "type", type) != 0) ||
AzureIoTClient 23:1111ee8bcba4 1096 /* Codes_SRS_AMQP_MANAGEMENT_01_093: [ If `locales` is NULL, no key/value pair shall be added for it in the application properties map. ]*/
AzureIoTClient 23:1111ee8bcba4 1097 /* Codes_SRS_AMQP_MANAGEMENT_01_063: [ locales string No A list of locales that the sending peer permits for incoming informational text in response messages. ]*/
AzureIoTClient 23:1111ee8bcba4 1098 ((locales != NULL) && (add_string_key_value_pair_to_map(application_properties, "locales", locales) != 0)))
AzureIoTClient 6:641a9672db08 1099 {
AzureIoTClient 19:000ab4e6a2c1 1100 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1101 }
AzureIoTClient 6:641a9672db08 1102 else
AzureIoTClient 6:641a9672db08 1103 {
AzureIoTClient 23:1111ee8bcba4 1104 /* Codes_SRS_AMQP_MANAGEMENT_01_087: [ The application properties obtained after adding the key/value pairs shall be set on the message by calling `message_set_application_properties`. ]*/
AzureIoTClient 23:1111ee8bcba4 1105 if (message_set_application_properties(cloned_message, application_properties) != 0)
AzureIoTClient 6:641a9672db08 1106 {
AzureIoTClient 23:1111ee8bcba4 1107 /* Codes_SRS_AMQP_MANAGEMENT_01_090: [ If any APIs used to create and set the application properties on the message fails, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1108 LogError("Could not set application properties");
AzureIoTClient 23:1111ee8bcba4 1109 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 1110 }
AzureIoTClient 23:1111ee8bcba4 1111 else if (set_message_id(cloned_message, amqp_management->next_message_id) != 0)
AzureIoTClient 23:1111ee8bcba4 1112 {
AzureIoTClient 19:000ab4e6a2c1 1113 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1114 }
AzureIoTClient 6:641a9672db08 1115 else
AzureIoTClient 6:641a9672db08 1116 {
AzureIoTClient 23:1111ee8bcba4 1117 OPERATION_MESSAGE_INSTANCE* pending_operation_message = (OPERATION_MESSAGE_INSTANCE*)malloc(sizeof(OPERATION_MESSAGE_INSTANCE));
AzureIoTClient 23:1111ee8bcba4 1118 if (pending_operation_message == NULL)
AzureIoTClient 6:641a9672db08 1119 {
AzureIoTClient 19:000ab4e6a2c1 1120 result = __FAILURE__;
AzureIoTClient 6:641a9672db08 1121 }
AzureIoTClient 6:641a9672db08 1122 else
AzureIoTClient 6:641a9672db08 1123 {
AzureIoTClient 23:1111ee8bcba4 1124 LIST_ITEM_HANDLE added_item;
AzureIoTClient 23:1111ee8bcba4 1125 pending_operation_message->callback_context = on_execute_operation_complete_context;
AzureIoTClient 23:1111ee8bcba4 1126 pending_operation_message->on_execute_operation_complete = on_execute_operation_complete;
AzureIoTClient 23:1111ee8bcba4 1127 pending_operation_message->message_id = amqp_management->next_message_id;
AzureIoTClient 23:1111ee8bcba4 1128
AzureIoTClient 23:1111ee8bcba4 1129 /* Codes_SRS_AMQP_MANAGEMENT_01_091: [ Once the request message has been sent, an entry shall be stored in the pending operations list by calling `singlylinkedlist_add`. ]*/
AzureIoTClient 23:1111ee8bcba4 1130 added_item = singlylinkedlist_add(amqp_management->pending_operations, pending_operation_message);
AzureIoTClient 23:1111ee8bcba4 1131 if (added_item == NULL)
AzureIoTClient 23:1111ee8bcba4 1132 {
AzureIoTClient 23:1111ee8bcba4 1133 /* Codes_SRS_AMQP_MANAGEMENT_01_092: [ If `singlylinkedlist_add` fails then `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1134 LogError("Could not add the operation to the pending operations list.");
AzureIoTClient 23:1111ee8bcba4 1135 free(pending_operation_message);
AzureIoTClient 23:1111ee8bcba4 1136 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 1137 }
AzureIoTClient 23:1111ee8bcba4 1138 else
AzureIoTClient 23:1111ee8bcba4 1139 {
AzureIoTClient 23:1111ee8bcba4 1140 /* Codes_SRS_AMQP_MANAGEMENT_01_088: [ `amqp_management_execute_operation_async` shall send the message by calling `messagesender_send`. ]*/
AzureIoTClient 34:6be9c2058664 1141 if (messagesender_send_async(amqp_management->message_sender, cloned_message, NULL, NULL, 0) == NULL)
AzureIoTClient 23:1111ee8bcba4 1142 {
AzureIoTClient 34:6be9c2058664 1143 /* Codes_SRS_AMQP_MANAGEMENT_01_089: [ If `messagesender_send_async` fails, `amqp_management_execute_operation_async` shall fail and return a non-zero value. ]*/
AzureIoTClient 23:1111ee8bcba4 1144 LogError("Could not send request message");
AzureIoTClient 23:1111ee8bcba4 1145 (void)singlylinkedlist_remove(amqp_management->pending_operations, added_item);
AzureIoTClient 23:1111ee8bcba4 1146 free(pending_operation_message);
AzureIoTClient 23:1111ee8bcba4 1147 result = __FAILURE__;
AzureIoTClient 23:1111ee8bcba4 1148 }
AzureIoTClient 23:1111ee8bcba4 1149 else
AzureIoTClient 23:1111ee8bcba4 1150 {
AzureIoTClient 23:1111ee8bcba4 1151 /* Codes_SRS_AMQP_MANAGEMENT_01_107: [ The message Id set on the message properties shall be incremented with each operation. ]*/
AzureIoTClient 23:1111ee8bcba4 1152 amqp_management->next_message_id++;
AzureIoTClient 23:1111ee8bcba4 1153
AzureIoTClient 23:1111ee8bcba4 1154 /* Codes_SRS_AMQP_MANAGEMENT_01_056: [ On success it shall return 0. ]*/
AzureIoTClient 23:1111ee8bcba4 1155 result = 0;
AzureIoTClient 23:1111ee8bcba4 1156 }
AzureIoTClient 23:1111ee8bcba4 1157 }
AzureIoTClient 6:641a9672db08 1158 }
AzureIoTClient 6:641a9672db08 1159 }
AzureIoTClient 6:641a9672db08 1160 }
AzureIoTClient 23:1111ee8bcba4 1161
AzureIoTClient 23:1111ee8bcba4 1162 /* Codes_SRS_AMQP_MANAGEMENT_01_101: [ After setting the application properties, the application properties instance shall be freed by `amqpvalue_destroy`. ]*/
AzureIoTClient 23:1111ee8bcba4 1163 amqpvalue_destroy(application_properties);
AzureIoTClient 6:641a9672db08 1164 }
AzureIoTClient 6:641a9672db08 1165 }
Azure.IoT Build 0:6ae2f7bca550 1166
AzureIoTClient 23:1111ee8bcba4 1167 message_destroy(cloned_message);
AzureIoTClient 6:641a9672db08 1168 }
AzureIoTClient 6:641a9672db08 1169 }
AzureIoTClient 6:641a9672db08 1170 return result;
AzureIoTClient 6:641a9672db08 1171 }
Azure.IoT Build 0:6ae2f7bca550 1172
AzureIoTClient 23:1111ee8bcba4 1173 void amqp_management_set_trace(AMQP_MANAGEMENT_HANDLE amqp_management, bool trace_on)
AzureIoTClient 6:641a9672db08 1174 {
AzureIoTClient 23:1111ee8bcba4 1175 if (amqp_management == NULL)
AzureIoTClient 6:641a9672db08 1176 {
AzureIoTClient 23:1111ee8bcba4 1177 /* Codes_SRS_AMQP_MANAGEMENT_01_163: [ If `amqp_management` is NULL, `amqp_management_set_trace` shal do nothing. ]*/
AzureIoTClient 23:1111ee8bcba4 1178 LogError("NULL amqp_management");
AzureIoTClient 23:1111ee8bcba4 1179 }
AzureIoTClient 23:1111ee8bcba4 1180 else
AzureIoTClient 23:1111ee8bcba4 1181 {
AzureIoTClient 23:1111ee8bcba4 1182 /* Codes_SRS_AMQP_MANAGEMENT_01_161: [ `amqp_management_set_trace` shall call `messagesender_set_trace` to enable/disable tracing on the message sender. ]*/
AzureIoTClient 23:1111ee8bcba4 1183 messagesender_set_trace(amqp_management->message_sender, trace_on);
AzureIoTClient 23:1111ee8bcba4 1184 /* Codes_SRS_AMQP_MANAGEMENT_01_162: [ `amqp_management_set_trace` shall call `messagereceiver_set_trace` to enable/disable tracing on the message receiver. ]*/
AzureIoTClient 23:1111ee8bcba4 1185 messagereceiver_set_trace(amqp_management->message_receiver, trace_on);
AzureIoTClient 6:641a9672db08 1186 }
Azure.IoT Build 0:6ae2f7bca550 1187 }
AzureIoTClient 39:e7c983378f41 1188
AzureIoTClient 39:e7c983378f41 1189 int amqp_management_set_override_status_code_key_name(AMQP_MANAGEMENT_HANDLE amqp_management, const char* override_status_code_key_name)
AzureIoTClient 39:e7c983378f41 1190 {
AzureIoTClient 39:e7c983378f41 1191 int result;
AzureIoTClient 39:e7c983378f41 1192
AzureIoTClient 39:e7c983378f41 1193 /* Codes_SRS_AMQP_MANAGEMENT_01_171: [ If `amqp_management` is NULL, `amqp_management_set_override_status_code_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1194 if ((amqp_management == NULL) ||
AzureIoTClient 39:e7c983378f41 1195 /* Codes_SRS_AMQP_MANAGEMENT_01_172: [ If `override_status_code_key_name` is NULL, `amqp_management_set_override_status_code_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1196 (override_status_code_key_name == NULL))
AzureIoTClient 39:e7c983378f41 1197 {
AzureIoTClient 39:e7c983378f41 1198 LogError("Bad arguments: amqp_management = %p, override_status_code_key_name = %s",
AzureIoTClient 39:e7c983378f41 1199 amqp_management, P_OR_NULL(override_status_code_key_name));
AzureIoTClient 39:e7c983378f41 1200 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 1201 }
AzureIoTClient 39:e7c983378f41 1202 else
AzureIoTClient 39:e7c983378f41 1203 {
AzureIoTClient 39:e7c983378f41 1204 /* Codes_SRS_AMQP_MANAGEMENT_01_167: [ `amqp_management_set_override_status_code_key_name` shall set the status code key name used to parse the status code from the reply messages to `override_status_code_key_name`. ]*/
AzureIoTClient 39:e7c983378f41 1205 /* Codes_SRS_AMQP_MANAGEMENT_01_168: [ `amqp_management_set_override_status_code_key_name` shall copy the `override_status_code_key_name` string. ]*/
AzureIoTClient 39:e7c983378f41 1206 /* Codes_SRS_AMQP_MANAGEMENT_01_169: [ `amqp_management_set_override_status_code_key_name` shall free any string previously used for the status code key name. ]*/
AzureIoTClient 39:e7c983378f41 1207 if (internal_set_status_code_key_name(amqp_management, override_status_code_key_name) != 0)
AzureIoTClient 39:e7c983378f41 1208 {
AzureIoTClient 39:e7c983378f41 1209 /* Codes_SRS_AMQP_MANAGEMENT_01_173: [ If any error occurs in copying the `override_status_code_key_name` string, `amqp_management_set_override_status_code_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1210 LogError("Cannot set status code key name");
AzureIoTClient 39:e7c983378f41 1211 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 1212 }
AzureIoTClient 39:e7c983378f41 1213 else
AzureIoTClient 39:e7c983378f41 1214 {
AzureIoTClient 39:e7c983378f41 1215 /* Codes_SRS_AMQP_MANAGEMENT_01_170: [ On success, `amqp_management_set_override_status_code_key_name` shall return 0. ]*/
AzureIoTClient 39:e7c983378f41 1216 result = 0;
AzureIoTClient 39:e7c983378f41 1217 }
AzureIoTClient 39:e7c983378f41 1218 }
AzureIoTClient 39:e7c983378f41 1219
AzureIoTClient 39:e7c983378f41 1220 return result;
AzureIoTClient 39:e7c983378f41 1221 }
AzureIoTClient 39:e7c983378f41 1222
AzureIoTClient 39:e7c983378f41 1223 int amqp_management_set_override_status_description_key_name(AMQP_MANAGEMENT_HANDLE amqp_management, const char* override_status_description_key_name)
AzureIoTClient 39:e7c983378f41 1224 {
AzureIoTClient 39:e7c983378f41 1225 int result;
AzureIoTClient 39:e7c983378f41 1226
AzureIoTClient 39:e7c983378f41 1227 /* Codes_SRS_AMQP_MANAGEMENT_01_178: [ If `amqp_management` is NULL, `amqp_management_set_override_status_description_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1228 if ((amqp_management == NULL) ||
AzureIoTClient 39:e7c983378f41 1229 /* Tests_SRS_AMQP_MANAGEMENT_01_179: [ If `override_status_description_key_name` is NULL, `amqp_management_set_override_status_description_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1230 (override_status_description_key_name == NULL))
AzureIoTClient 39:e7c983378f41 1231 {
AzureIoTClient 39:e7c983378f41 1232 LogError("Bad arguments: amqp_management = %p, override_status_description_key_name = %s",
AzureIoTClient 39:e7c983378f41 1233 amqp_management, P_OR_NULL(override_status_description_key_name));
AzureIoTClient 39:e7c983378f41 1234 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 1235 }
AzureIoTClient 39:e7c983378f41 1236 else
AzureIoTClient 39:e7c983378f41 1237 {
AzureIoTClient 39:e7c983378f41 1238 /* Codes_SRS_AMQP_MANAGEMENT_01_174: [ `amqp_management_set_override_status_description_key_name` shall set the status description key name used to parse the status description from the reply messages to `over ride_status_description_key_name`.]*/
AzureIoTClient 39:e7c983378f41 1239 /* Codes_SRS_AMQP_MANAGEMENT_01_175: [ `amqp_management_set_override_status_description_key_name` shall copy the `override_status_description_key_name` string. ]*/
AzureIoTClient 39:e7c983378f41 1240 /* Codes_SRS_AMQP_MANAGEMENT_01_176: [ `amqp_management_set_override_status_description_key_name` shall free any string previously used for the status description key name. ]*/
AzureIoTClient 39:e7c983378f41 1241 /* Codes_SRS_AMQP_MANAGEMENT_01_177: [ On success, `amqp_management_set_override_status_description_key_name` shall return 0. ]*/
AzureIoTClient 39:e7c983378f41 1242 if (internal_set_status_description_key_name(amqp_management, override_status_description_key_name) != 0)
AzureIoTClient 39:e7c983378f41 1243 {
AzureIoTClient 39:e7c983378f41 1244 /* Codes_SRS_AMQP_MANAGEMENT_01_180: [ If any error occurs in copying the `override_status_description_key_name` string, `amqp_management_set_override_status_description_key_name` shall fail and return a non-zero value. ]*/
AzureIoTClient 39:e7c983378f41 1245 LogError("Cannot set status description key name");
AzureIoTClient 39:e7c983378f41 1246 result = __FAILURE__;
AzureIoTClient 39:e7c983378f41 1247 }
AzureIoTClient 39:e7c983378f41 1248 else
AzureIoTClient 39:e7c983378f41 1249 {
AzureIoTClient 39:e7c983378f41 1250 result = 0;
AzureIoTClient 39:e7c983378f41 1251 }
AzureIoTClient 39:e7c983378f41 1252 }
AzureIoTClient 39:e7c983378f41 1253
AzureIoTClient 39:e7c983378f41 1254 return result;
AzureIoTClient 39:e7c983378f41 1255 }