A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Mon Jun 11 15:39:52 2018 -0700
Revision:
43:4c1e4e94cdd3
Parent:
41:0e723f9cbd89
Child:
46:01f7ca900e07
1.2.5

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