A small memory footprint AMQP implimentation
Dependents: iothub_client_sample_amqp remote_monitoring simplesample_amqp
cbs.c@47:365a93fdb5bb, 2018-10-04 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Thu Oct 04 09:16:13 2018 -0700
- Revision:
- 47:365a93fdb5bb
- Parent:
- 46:01f7ca900e07
1.2.10
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 0:6ae2f7bca550 | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 0:6ae2f7bca550 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 0:6ae2f7bca550 | 3 | |
Azure.IoT Build | 0:6ae2f7bca550 | 4 | #include <stdlib.h> |
AzureIoTClient | 6:641a9672db08 | 5 | #include <stdbool.h> |
Azure.IoT Build | 0:6ae2f7bca550 | 6 | #include <stdio.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 | 21:f9c433d8e6ca | 10 | #include "azure_c_shared_utility/singlylinkedlist.h" |
AzureIoTClient | 27:d74f1cea23e1 | 11 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 12 | #include "azure_uamqp_c/cbs.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 13 | #include "azure_uamqp_c/amqp_management.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 14 | #include "azure_uamqp_c/session.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 15 | |
AzureIoTClient | 21:f9c433d8e6ca | 16 | typedef enum CBS_STATE_TAG |
AzureIoTClient | 21:f9c433d8e6ca | 17 | { |
AzureIoTClient | 21:f9c433d8e6ca | 18 | CBS_STATE_CLOSED, |
AzureIoTClient | 21:f9c433d8e6ca | 19 | CBS_STATE_OPENING, |
AzureIoTClient | 21:f9c433d8e6ca | 20 | CBS_STATE_OPEN, |
AzureIoTClient | 21:f9c433d8e6ca | 21 | CBS_STATE_ERROR |
AzureIoTClient | 21:f9c433d8e6ca | 22 | } CBS_STATE; |
AzureIoTClient | 21:f9c433d8e6ca | 23 | |
AzureIoTClient | 21:f9c433d8e6ca | 24 | typedef struct CBS_OPERATION_TAG |
AzureIoTClient | 21:f9c433d8e6ca | 25 | { |
AzureIoTClient | 21:f9c433d8e6ca | 26 | ON_CBS_OPERATION_COMPLETE on_cbs_operation_complete; |
AzureIoTClient | 21:f9c433d8e6ca | 27 | void* on_cbs_operation_complete_context; |
AzureIoTClient | 21:f9c433d8e6ca | 28 | SINGLYLINKEDLIST_HANDLE pending_operations; |
AzureIoTClient | 21:f9c433d8e6ca | 29 | } CBS_OPERATION; |
AzureIoTClient | 21:f9c433d8e6ca | 30 | |
Azure.IoT Build | 0:6ae2f7bca550 | 31 | typedef struct CBS_INSTANCE_TAG |
Azure.IoT Build | 0:6ae2f7bca550 | 32 | { |
AzureIoTClient | 6:641a9672db08 | 33 | AMQP_MANAGEMENT_HANDLE amqp_management; |
AzureIoTClient | 21:f9c433d8e6ca | 34 | CBS_STATE cbs_state; |
AzureIoTClient | 21:f9c433d8e6ca | 35 | ON_CBS_OPEN_COMPLETE on_cbs_open_complete; |
AzureIoTClient | 21:f9c433d8e6ca | 36 | void* on_cbs_open_complete_context; |
AzureIoTClient | 21:f9c433d8e6ca | 37 | ON_CBS_ERROR on_cbs_error; |
AzureIoTClient | 21:f9c433d8e6ca | 38 | void* on_cbs_error_context; |
AzureIoTClient | 21:f9c433d8e6ca | 39 | SINGLYLINKEDLIST_HANDLE pending_operations; |
Azure.IoT Build | 0:6ae2f7bca550 | 40 | } CBS_INSTANCE; |
Azure.IoT Build | 0:6ae2f7bca550 | 41 | |
Azure.IoT Build | 0:6ae2f7bca550 | 42 | static int add_string_key_value_pair_to_map(AMQP_VALUE map, const char* key, const char* value) |
Azure.IoT Build | 0:6ae2f7bca550 | 43 | { |
AzureIoTClient | 6:641a9672db08 | 44 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 45 | |
AzureIoTClient | 6:641a9672db08 | 46 | AMQP_VALUE key_value = amqpvalue_create_string(key); |
AzureIoTClient | 21:f9c433d8e6ca | 47 | if (key_value == NULL) |
AzureIoTClient | 6:641a9672db08 | 48 | { |
AzureIoTClient | 21:f9c433d8e6ca | 49 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 50 | LogError("Failed creating value for property key %s", key); |
AzureIoTClient | 19:000ab4e6a2c1 | 51 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 52 | } |
AzureIoTClient | 6:641a9672db08 | 53 | else |
AzureIoTClient | 6:641a9672db08 | 54 | { |
AzureIoTClient | 6:641a9672db08 | 55 | AMQP_VALUE value_value = amqpvalue_create_string(value); |
AzureIoTClient | 6:641a9672db08 | 56 | if (value_value == NULL) |
AzureIoTClient | 6:641a9672db08 | 57 | { |
AzureIoTClient | 21:f9c433d8e6ca | 58 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 59 | LogError("Failed creating value for property value %s", value); |
AzureIoTClient | 19:000ab4e6a2c1 | 60 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 61 | } |
AzureIoTClient | 6:641a9672db08 | 62 | else |
AzureIoTClient | 6:641a9672db08 | 63 | { |
AzureIoTClient | 6:641a9672db08 | 64 | if (amqpvalue_set_map_value(map, key_value, value_value) != 0) |
AzureIoTClient | 6:641a9672db08 | 65 | { |
AzureIoTClient | 21:f9c433d8e6ca | 66 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 67 | LogError("Failed inserting key/value pair in the map"); |
AzureIoTClient | 19:000ab4e6a2c1 | 68 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 69 | } |
AzureIoTClient | 6:641a9672db08 | 70 | else |
AzureIoTClient | 6:641a9672db08 | 71 | { |
AzureIoTClient | 6:641a9672db08 | 72 | result = 0; |
AzureIoTClient | 6:641a9672db08 | 73 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 74 | |
AzureIoTClient | 21:f9c433d8e6ca | 75 | amqpvalue_destroy(value_value); |
AzureIoTClient | 6:641a9672db08 | 76 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 77 | |
AzureIoTClient | 21:f9c433d8e6ca | 78 | amqpvalue_destroy(key_value); |
AzureIoTClient | 6:641a9672db08 | 79 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 80 | |
AzureIoTClient | 6:641a9672db08 | 81 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 82 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 83 | |
AzureIoTClient | 22:524bded3f7a8 | 84 | static void on_underlying_amqp_management_open_complete(void* context, AMQP_MANAGEMENT_OPEN_RESULT open_result) |
Azure.IoT Build | 0:6ae2f7bca550 | 85 | { |
AzureIoTClient | 21:f9c433d8e6ca | 86 | if (context == NULL) |
AzureIoTClient | 6:641a9672db08 | 87 | { |
AzureIoTClient | 22:524bded3f7a8 | 88 | /* Codes_SRS_CBS_01_105: [ When `on_amqp_management_open_complete` is called with NULL `context`, it shall do nothing. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 89 | LogError("on_underlying_amqp_management_open_complete called with NULL context"); |
AzureIoTClient | 6:641a9672db08 | 90 | } |
AzureIoTClient | 6:641a9672db08 | 91 | else |
AzureIoTClient | 6:641a9672db08 | 92 | { |
AzureIoTClient | 21:f9c433d8e6ca | 93 | CBS_HANDLE cbs = (CBS_HANDLE)context; |
AzureIoTClient | 21:f9c433d8e6ca | 94 | |
AzureIoTClient | 22:524bded3f7a8 | 95 | switch (cbs->cbs_state) |
AzureIoTClient | 6:641a9672db08 | 96 | { |
AzureIoTClient | 22:524bded3f7a8 | 97 | default: |
AzureIoTClient | 22:524bded3f7a8 | 98 | LogError("AMQP management open complete in unknown state"); |
AzureIoTClient | 22:524bded3f7a8 | 99 | break; |
AzureIoTClient | 22:524bded3f7a8 | 100 | |
AzureIoTClient | 22:524bded3f7a8 | 101 | case CBS_STATE_CLOSED: |
AzureIoTClient | 22:524bded3f7a8 | 102 | case CBS_STATE_ERROR: |
AzureIoTClient | 22:524bded3f7a8 | 103 | LogError("Unexpected AMQP management open complete"); |
AzureIoTClient | 22:524bded3f7a8 | 104 | break; |
AzureIoTClient | 22:524bded3f7a8 | 105 | |
AzureIoTClient | 22:524bded3f7a8 | 106 | case CBS_STATE_OPEN: |
AzureIoTClient | 22:524bded3f7a8 | 107 | LogError("Unexpected AMQP management open complete in OPEN"); |
AzureIoTClient | 22:524bded3f7a8 | 108 | /* Codes_SRS_CBS_01_109: [ When `on_amqp_management_open_complete` is called when the CBS is OPEN, the callback `on_cbs_error` shall be called and the `on_cbs_error_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 109 | cbs->cbs_state = CBS_STATE_ERROR; |
AzureIoTClient | 22:524bded3f7a8 | 110 | cbs->on_cbs_error(cbs->on_cbs_error_context); |
AzureIoTClient | 22:524bded3f7a8 | 111 | break; |
AzureIoTClient | 22:524bded3f7a8 | 112 | |
AzureIoTClient | 22:524bded3f7a8 | 113 | case CBS_STATE_OPENING: |
AzureIoTClient | 22:524bded3f7a8 | 114 | { |
AzureIoTClient | 22:524bded3f7a8 | 115 | switch (open_result) |
AzureIoTClient | 21:f9c433d8e6ca | 116 | { |
AzureIoTClient | 21:f9c433d8e6ca | 117 | default: |
AzureIoTClient | 22:524bded3f7a8 | 118 | LogError("Unknown AMQP management state"); |
AzureIoTClient | 22:524bded3f7a8 | 119 | |
AzureIoTClient | 22:524bded3f7a8 | 120 | case AMQP_MANAGEMENT_OPEN_ERROR: |
AzureIoTClient | 22:524bded3f7a8 | 121 | cbs->cbs_state = CBS_STATE_CLOSED; |
AzureIoTClient | 22:524bded3f7a8 | 122 | /* Codes_SRS_CBS_01_113: [ When `on_amqp_management_open_complete` reports a failure, the underlying AMQP management shall be closed by calling `amqp_management_close`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 123 | (void)amqp_management_close(cbs->amqp_management); |
AzureIoTClient | 22:524bded3f7a8 | 124 | /* Codes_SRS_CBS_01_107: [ If CBS is OPENING and `open_result` is `AMQP_MANAGEMENT_OPEN_ERROR` the callback `on_cbs_open_complete` shall be called with `CBS_OPEN_ERROR` and the `on_cbs_open_complete_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 125 | cbs->on_cbs_open_complete(cbs->on_cbs_open_complete_context, CBS_OPEN_ERROR); |
AzureIoTClient | 21:f9c433d8e6ca | 126 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 127 | |
AzureIoTClient | 22:524bded3f7a8 | 128 | case AMQP_MANAGEMENT_OPEN_CANCELLED: |
AzureIoTClient | 22:524bded3f7a8 | 129 | cbs->cbs_state = CBS_STATE_CLOSED; |
AzureIoTClient | 22:524bded3f7a8 | 130 | /* Codes_SRS_CBS_01_113: [ When `on_amqp_management_open_complete` reports a failure, the underlying AMQP management shall be closed by calling `amqp_management_close`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 131 | (void)amqp_management_close(cbs->amqp_management); |
AzureIoTClient | 22:524bded3f7a8 | 132 | /* Codes_SRS_CBS_01_108: [ If CBS is OPENING and `open_result` is `AMQP_MANAGEMENT_OPEN_CANCELLED` the callback `on_cbs_open_complete` shall be called with `CBS_OPEN_CANCELLED` and the `on_cbs_open_complete_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 133 | cbs->on_cbs_open_complete(cbs->on_cbs_open_complete_context, CBS_OPEN_CANCELLED); |
AzureIoTClient | 21:f9c433d8e6ca | 134 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 135 | |
AzureIoTClient | 22:524bded3f7a8 | 136 | case AMQP_MANAGEMENT_OPEN_OK: |
AzureIoTClient | 22:524bded3f7a8 | 137 | /* Codes_SRS_CBS_01_106: [ If CBS is OPENING and `open_result` is `AMQP_MANAGEMENT_OPEN_OK` the callback `on_cbs_open_complete` shall be called with `CBS_OPEN_OK` and the `on_cbs_open_complete_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 138 | cbs->cbs_state = CBS_STATE_OPEN; |
AzureIoTClient | 22:524bded3f7a8 | 139 | cbs->on_cbs_open_complete(cbs->on_cbs_open_complete_context, CBS_OPEN_OK); |
AzureIoTClient | 21:f9c433d8e6ca | 140 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 141 | } |
AzureIoTClient | 22:524bded3f7a8 | 142 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 143 | } |
AzureIoTClient | 21:f9c433d8e6ca | 144 | } |
AzureIoTClient | 21:f9c433d8e6ca | 145 | } |
AzureIoTClient | 21:f9c433d8e6ca | 146 | } |
AzureIoTClient | 21:f9c433d8e6ca | 147 | |
AzureIoTClient | 22:524bded3f7a8 | 148 | static void on_underlying_amqp_management_error(void* context) |
AzureIoTClient | 21:f9c433d8e6ca | 149 | { |
AzureIoTClient | 21:f9c433d8e6ca | 150 | if (context == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 151 | { |
AzureIoTClient | 22:524bded3f7a8 | 152 | /* Codes_SRS_CBS_01_110: [ When `on_amqp_management_error` is called with NULL `context`, it shall do nothing. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 153 | LogError("on_underlying_amqp_management_error called with NULL context"); |
AzureIoTClient | 22:524bded3f7a8 | 154 | } |
AzureIoTClient | 22:524bded3f7a8 | 155 | else |
AzureIoTClient | 22:524bded3f7a8 | 156 | { |
AzureIoTClient | 22:524bded3f7a8 | 157 | CBS_HANDLE cbs = (CBS_HANDLE)context; |
AzureIoTClient | 22:524bded3f7a8 | 158 | |
AzureIoTClient | 22:524bded3f7a8 | 159 | switch (cbs->cbs_state) |
AzureIoTClient | 22:524bded3f7a8 | 160 | { |
AzureIoTClient | 22:524bded3f7a8 | 161 | default: |
AzureIoTClient | 22:524bded3f7a8 | 162 | LogError("AMQP management error in unknown state"); |
AzureIoTClient | 22:524bded3f7a8 | 163 | break; |
AzureIoTClient | 22:524bded3f7a8 | 164 | |
AzureIoTClient | 22:524bded3f7a8 | 165 | case CBS_STATE_CLOSED: |
AzureIoTClient | 22:524bded3f7a8 | 166 | LogError("Unexpected AMQP error in CLOSED state"); |
AzureIoTClient | 22:524bded3f7a8 | 167 | break; |
AzureIoTClient | 22:524bded3f7a8 | 168 | |
AzureIoTClient | 22:524bded3f7a8 | 169 | case CBS_STATE_OPENING: |
AzureIoTClient | 22:524bded3f7a8 | 170 | cbs->cbs_state = CBS_STATE_CLOSED; |
AzureIoTClient | 22:524bded3f7a8 | 171 | /* Codes_SRS_CBS_01_114: [ Additionally the underlying AMQP management shall be closed by calling `amqp_management_close`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 172 | (void)amqp_management_close(cbs->amqp_management); |
AzureIoTClient | 22:524bded3f7a8 | 173 | /* Codes_SRS_CBS_01_111: [ If CBS is OPENING the callback `on_cbs_open_complete` shall be called with `CBS_OPEN_ERROR` and the `on_cbs_open_complete_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 174 | cbs->on_cbs_open_complete(cbs->on_cbs_open_complete_context, CBS_OPEN_ERROR); |
AzureIoTClient | 22:524bded3f7a8 | 175 | break; |
AzureIoTClient | 22:524bded3f7a8 | 176 | |
AzureIoTClient | 22:524bded3f7a8 | 177 | case CBS_STATE_OPEN: |
AzureIoTClient | 22:524bded3f7a8 | 178 | /* Codes_SRS_CBS_01_112: [ If CBS is OPEN the callback `on_cbs_error` shall be called and the `on_cbs_error_context` shall be passed as argument. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 179 | cbs->cbs_state = CBS_STATE_ERROR; |
AzureIoTClient | 22:524bded3f7a8 | 180 | cbs->on_cbs_error(cbs->on_cbs_error_context); |
AzureIoTClient | 22:524bded3f7a8 | 181 | break; |
AzureIoTClient | 22:524bded3f7a8 | 182 | } |
AzureIoTClient | 22:524bded3f7a8 | 183 | } |
AzureIoTClient | 22:524bded3f7a8 | 184 | } |
AzureIoTClient | 22:524bded3f7a8 | 185 | |
AzureIoTClient | 39:e7c983378f41 | 186 | static void on_amqp_management_execute_operation_complete(void* context, AMQP_MANAGEMENT_EXECUTE_OPERATION_RESULT execute_operation_result, unsigned int status_code, const char* status_description, MESSAGE_HANDLE message) |
AzureIoTClient | 22:524bded3f7a8 | 187 | { |
AzureIoTClient | 22:524bded3f7a8 | 188 | if (context == NULL) |
AzureIoTClient | 22:524bded3f7a8 | 189 | { |
AzureIoTClient | 22:524bded3f7a8 | 190 | /* Codes_SRS_CBS_01_091: [ When `on_amqp_management_execute_operation_complete` is called with a NULL context it shall do nothing. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 191 | LogError("on_amqp_management_execute_operation_complete called with NULL context"); |
AzureIoTClient | 21:f9c433d8e6ca | 192 | } |
AzureIoTClient | 21:f9c433d8e6ca | 193 | else |
AzureIoTClient | 21:f9c433d8e6ca | 194 | { |
AzureIoTClient | 21:f9c433d8e6ca | 195 | /* Codes_SRS_CBS_01_103: [ The `context` shall be used to obtain the pending operation information stored in the pending operations linked list by calling `singlylinkedlist_item_get_value`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 196 | CBS_OPERATION* cbs_operation = (CBS_OPERATION*)singlylinkedlist_item_get_value((LIST_ITEM_HANDLE)context); |
AzureIoTClient | 21:f9c433d8e6ca | 197 | CBS_OPERATION_RESULT cbs_operation_result; |
AzureIoTClient | 21:f9c433d8e6ca | 198 | |
AzureIoTClient | 39:e7c983378f41 | 199 | (void)message; |
AzureIoTClient | 39:e7c983378f41 | 200 | |
AzureIoTClient | 21:f9c433d8e6ca | 201 | if (cbs_operation == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 202 | { |
AzureIoTClient | 21:f9c433d8e6ca | 203 | LogError("NULL cbs_operation"); |
AzureIoTClient | 6:641a9672db08 | 204 | } |
AzureIoTClient | 6:641a9672db08 | 205 | else |
AzureIoTClient | 6:641a9672db08 | 206 | { |
AzureIoTClient | 22:524bded3f7a8 | 207 | switch (execute_operation_result) |
AzureIoTClient | 6:641a9672db08 | 208 | { |
AzureIoTClient | 21:f9c433d8e6ca | 209 | default: |
AzureIoTClient | 21:f9c433d8e6ca | 210 | cbs_operation_result = CBS_OPERATION_RESULT_CBS_ERROR; |
AzureIoTClient | 21:f9c433d8e6ca | 211 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 212 | |
AzureIoTClient | 22:524bded3f7a8 | 213 | case AMQP_MANAGEMENT_EXECUTE_OPERATION_FAILED_BAD_STATUS: |
AzureIoTClient | 23:1111ee8bcba4 | 214 | /* Tests_SRS_CBS_01_094: [ When `on_amqp_management_execute_operation_complete` is called with `AMQP_MANAGEMENT_EXECUTE_OPERATION_FAILED_BAD_STATUS`, the associated cbs operation complete callback shall be called with `CBS_OPERATION_RESULT_OPERATION_FAILED` and passing the `on_cbs_put_token_complete_context` as the context argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 215 | cbs_operation_result = CBS_OPERATION_RESULT_OPERATION_FAILED; |
AzureIoTClient | 21:f9c433d8e6ca | 216 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 217 | |
AzureIoTClient | 23:1111ee8bcba4 | 218 | case AMQP_MANAGEMENT_EXECUTE_OPERATION_INSTANCE_CLOSED: |
AzureIoTClient | 23:1111ee8bcba4 | 219 | /* Tests_SRS_CBS_01_115: [ When `on_amqp_management_execute_operation_complete` is called with `AMQP_MANAGEMENT_EXECUTE_OPERATION_INSTANCE_CLOSED`, the associated cbs operation complete callback shall be called with `CBS_OPERATION_RESULT_INSTANCE_CLOSED` and passing the `on_cbs_put_token_complete_context` as the context argument. ]*/ |
AzureIoTClient | 23:1111ee8bcba4 | 220 | cbs_operation_result = CBS_OPERATION_RESULT_INSTANCE_CLOSED; |
AzureIoTClient | 23:1111ee8bcba4 | 221 | break; |
AzureIoTClient | 23:1111ee8bcba4 | 222 | |
AzureIoTClient | 22:524bded3f7a8 | 223 | case AMQP_MANAGEMENT_EXECUTE_OPERATION_ERROR: |
AzureIoTClient | 23:1111ee8bcba4 | 224 | /* Tests_SRS_CBS_01_093: [ When `on_amqp_management_execute_operation_complete` is called with `AMQP_MANAGEMENT_EXECUTE_OPERATION_ERROR`, the associated cbs operation complete callback shall be called with `CBS_OPERATION_RESULT_CBS_ERROR` and passing the `on_cbs_put_token_complete_context` as the context argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 225 | cbs_operation_result = CBS_OPERATION_RESULT_CBS_ERROR; |
AzureIoTClient | 21:f9c433d8e6ca | 226 | break; |
AzureIoTClient | 21:f9c433d8e6ca | 227 | |
AzureIoTClient | 22:524bded3f7a8 | 228 | case AMQP_MANAGEMENT_EXECUTE_OPERATION_OK: |
AzureIoTClient | 23:1111ee8bcba4 | 229 | /* Codes_SRS_CBS_01_092: [ When `on_amqp_management_execute_operation_complete` is called with `AMQP_MANAGEMENT_EXECUTE_OPERATION_OK`, the associated cbs operation complete callback shall be called with `CBS_OPERATION_RESULT_OK` and passing the `on_cbs_put_token_complete_context` as the context argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 230 | cbs_operation_result = CBS_OPERATION_RESULT_OK; |
AzureIoTClient | 21:f9c433d8e6ca | 231 | break; |
AzureIoTClient | 6:641a9672db08 | 232 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 233 | |
AzureIoTClient | 21:f9c433d8e6ca | 234 | /* Codes_SRS_CBS_01_095: [ `status_code` and `status_description` shall be passed as they are to the cbs operation complete callback. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 235 | /* Codes_SRS_CBS_01_014: [ The response message has the following application-properties: ]*/ |
AzureIoTClient | 28:add19eb7defa | 236 | /* Codes_SRS_CBS_01_013: [ status-code No int HTTP response code [RFC2616]. ]*/ |
AzureIoTClient | 28:add19eb7defa | 237 | /* Codes_SRS_CBS_01_015: [ status-description Yes string Description of the status. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 238 | /* Codes_SRS_CBS_01_016: [ The body of the message MUST be empty. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 239 | /* Codes_SRS_CBS_01_026: [ The response message has the following application-properties: ]*/ |
AzureIoTClient | 28:add19eb7defa | 240 | /* Codes_SRS_CBS_01_027: [ status-code Yes int HTTP response code [RFC2616]. ]*/ |
AzureIoTClient | 28:add19eb7defa | 241 | /* Codes_SRS_CBS_01_028: [ status-description No string Description of the status. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 242 | /* Codes_SRS_CBS_01_029: [ The body of the message MUST be empty. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 243 | cbs_operation->on_cbs_operation_complete(cbs_operation->on_cbs_operation_complete_context, cbs_operation_result, status_code, status_description); |
Azure.IoT Build | 0:6ae2f7bca550 | 244 | |
AzureIoTClient | 21:f9c433d8e6ca | 245 | /* Codes_SRS_CBS_01_102: [ The pending operation shall be removed from the pending operations list by calling `singlylinkedlist_remove`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 246 | if (singlylinkedlist_remove(cbs_operation->pending_operations, (LIST_ITEM_HANDLE)context) != 0) |
AzureIoTClient | 6:641a9672db08 | 247 | { |
AzureIoTClient | 21:f9c433d8e6ca | 248 | LogError("Failed removing operation from the pending list"); |
AzureIoTClient | 6:641a9672db08 | 249 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 250 | |
AzureIoTClient | 21:f9c433d8e6ca | 251 | /* Codes_SRS_CBS_01_096: [ The `context` for the operation shall also be freed. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 252 | free(cbs_operation); |
AzureIoTClient | 6:641a9672db08 | 253 | } |
AzureIoTClient | 6:641a9672db08 | 254 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 255 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 256 | |
AzureIoTClient | 21:f9c433d8e6ca | 257 | CBS_HANDLE cbs_create(SESSION_HANDLE session) |
Azure.IoT Build | 0:6ae2f7bca550 | 258 | { |
AzureIoTClient | 39:e7c983378f41 | 259 | CBS_INSTANCE* cbs; |
Azure.IoT Build | 0:6ae2f7bca550 | 260 | |
AzureIoTClient | 6:641a9672db08 | 261 | if (session == NULL) |
AzureIoTClient | 6:641a9672db08 | 262 | { |
AzureIoTClient | 21:f9c433d8e6ca | 263 | /* Codes_SRS_CBS_01_033: [** If `session` is NULL then `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 264 | LogError("NULL session handle"); |
AzureIoTClient | 39:e7c983378f41 | 265 | cbs = NULL; |
AzureIoTClient | 6:641a9672db08 | 266 | } |
AzureIoTClient | 6:641a9672db08 | 267 | else |
AzureIoTClient | 6:641a9672db08 | 268 | { |
AzureIoTClient | 39:e7c983378f41 | 269 | cbs = (CBS_INSTANCE*)malloc(sizeof(CBS_INSTANCE)); |
AzureIoTClient | 39:e7c983378f41 | 270 | if (cbs == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 271 | { |
AzureIoTClient | 21:f9c433d8e6ca | 272 | /* Codes_SRS_CBS_01_076: [ If allocating memory for the new handle fails, `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 273 | LogError("Cannot allocate memory for cbs instance."); |
AzureIoTClient | 21:f9c433d8e6ca | 274 | } |
AzureIoTClient | 21:f9c433d8e6ca | 275 | else |
AzureIoTClient | 6:641a9672db08 | 276 | { |
AzureIoTClient | 21:f9c433d8e6ca | 277 | /* Codes_SRS_CBS_01_097: [ `cbs_create` shall create a singly linked list for pending operations by calling `singlylinkedlist_create`. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 278 | cbs->pending_operations = singlylinkedlist_create(); |
AzureIoTClient | 39:e7c983378f41 | 279 | if (cbs->pending_operations == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 280 | { |
AzureIoTClient | 21:f9c433d8e6ca | 281 | /* Codes_SRS_CBS_01_101: [ If `singlylinkedlist_create` fails, `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 282 | LogError("Cannot allocate pending operations list."); |
AzureIoTClient | 21:f9c433d8e6ca | 283 | } |
AzureIoTClient | 21:f9c433d8e6ca | 284 | else |
AzureIoTClient | 6:641a9672db08 | 285 | { |
AzureIoTClient | 22:524bded3f7a8 | 286 | /* Codes_SRS_CBS_01_034: [ `cbs_create` shall create an AMQP management handle by calling `amqp_management_create`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 287 | /* Codes_SRS_CBS_01_002: [ Tokens are communicated between AMQP peers by sending specially-formatted AMQP messages to the Claims-based Security Node. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 288 | /* Codes_SRS_CBS_01_003: [ The mechanism follows the scheme defined in the AMQP Management specification [AMQPMAN]. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 289 | cbs->amqp_management = amqp_management_create(session, "$cbs"); |
AzureIoTClient | 39:e7c983378f41 | 290 | if (cbs->amqp_management == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 291 | { |
AzureIoTClient | 39:e7c983378f41 | 292 | LogError("Cannot create AMQP management instance for the $cbs node."); |
AzureIoTClient | 21:f9c433d8e6ca | 293 | } |
AzureIoTClient | 21:f9c433d8e6ca | 294 | else |
AzureIoTClient | 21:f9c433d8e6ca | 295 | { |
AzureIoTClient | 39:e7c983378f41 | 296 | /* Codes_SRS_CBS_01_116: [ If setting the override key names fails, then `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 297 | if (amqp_management_set_override_status_code_key_name(cbs->amqp_management, "status-code") != 0) |
AzureIoTClient | 39:e7c983378f41 | 298 | { |
AzureIoTClient | 39:e7c983378f41 | 299 | /* Codes_SRS_CBS_01_116: [ If setting the override key names fails, then `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 300 | LogError("Cannot set the override status code key name"); |
AzureIoTClient | 39:e7c983378f41 | 301 | } |
AzureIoTClient | 39:e7c983378f41 | 302 | else |
AzureIoTClient | 39:e7c983378f41 | 303 | { |
AzureIoTClient | 39:e7c983378f41 | 304 | /* Codes_SRS_CBS_01_118: [ `cbs_create` shall set the override status description key name on the AMQP management handle to `status-description` by calling `amqp_management_set_override_status_description_key_name`. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 305 | if (amqp_management_set_override_status_description_key_name(cbs->amqp_management, "status-description") != 0) |
AzureIoTClient | 39:e7c983378f41 | 306 | { |
AzureIoTClient | 39:e7c983378f41 | 307 | /* Codes_SRS_CBS_01_116: [ If setting the override key names fails, then `cbs_create` shall fail and return NULL. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 308 | LogError("Cannot set the override status description key name"); |
AzureIoTClient | 39:e7c983378f41 | 309 | } |
AzureIoTClient | 39:e7c983378f41 | 310 | else |
AzureIoTClient | 39:e7c983378f41 | 311 | { |
AzureIoTClient | 39:e7c983378f41 | 312 | /* Codes_SRS_CBS_01_001: [ `cbs_create` shall create a new CBS instance and on success return a non-NULL handle to it. ]*/ |
AzureIoTClient | 39:e7c983378f41 | 313 | cbs->cbs_state = CBS_STATE_CLOSED; |
AzureIoTClient | 39:e7c983378f41 | 314 | |
AzureIoTClient | 39:e7c983378f41 | 315 | goto all_ok; |
AzureIoTClient | 39:e7c983378f41 | 316 | } |
AzureIoTClient | 39:e7c983378f41 | 317 | } |
AzureIoTClient | 39:e7c983378f41 | 318 | |
AzureIoTClient | 39:e7c983378f41 | 319 | amqp_management_destroy(cbs->amqp_management); |
AzureIoTClient | 21:f9c433d8e6ca | 320 | } |
AzureIoTClient | 39:e7c983378f41 | 321 | |
AzureIoTClient | 39:e7c983378f41 | 322 | singlylinkedlist_destroy(cbs->pending_operations); |
AzureIoTClient | 6:641a9672db08 | 323 | } |
AzureIoTClient | 39:e7c983378f41 | 324 | |
AzureIoTClient | 39:e7c983378f41 | 325 | free(cbs); |
AzureIoTClient | 39:e7c983378f41 | 326 | cbs = NULL; |
AzureIoTClient | 6:641a9672db08 | 327 | } |
AzureIoTClient | 6:641a9672db08 | 328 | } |
AzureIoTClient | 46:01f7ca900e07 | 329 | |
AzureIoTClient | 39:e7c983378f41 | 330 | all_ok: |
AzureIoTClient | 39:e7c983378f41 | 331 | return cbs; |
Azure.IoT Build | 0:6ae2f7bca550 | 332 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 333 | |
Azure.IoT Build | 0:6ae2f7bca550 | 334 | void cbs_destroy(CBS_HANDLE cbs) |
Azure.IoT Build | 0:6ae2f7bca550 | 335 | { |
AzureIoTClient | 21:f9c433d8e6ca | 336 | if (cbs == NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 337 | { |
AzureIoTClient | 21:f9c433d8e6ca | 338 | /* Codes_SRS_CBS_01_037: [ If `cbs` is NULL, `cbs_destroy` shall do nothing. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 339 | LogError("NULL cbs handle"); |
AzureIoTClient | 21:f9c433d8e6ca | 340 | } |
AzureIoTClient | 21:f9c433d8e6ca | 341 | else |
AzureIoTClient | 6:641a9672db08 | 342 | { |
AzureIoTClient | 21:f9c433d8e6ca | 343 | LIST_ITEM_HANDLE first_pending_operation; |
AzureIoTClient | 21:f9c433d8e6ca | 344 | |
AzureIoTClient | 21:f9c433d8e6ca | 345 | /* Codes_SRS_CBS_01_100: [ If the CBS instance is not closed, all actions performed by `cbs_close` shall be performed. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 346 | if (cbs->cbs_state != CBS_STATE_CLOSED) |
AzureIoTClient | 21:f9c433d8e6ca | 347 | { |
AzureIoTClient | 22:524bded3f7a8 | 348 | (void)amqp_management_close(cbs->amqp_management); |
AzureIoTClient | 21:f9c433d8e6ca | 349 | } |
AzureIoTClient | 21:f9c433d8e6ca | 350 | |
AzureIoTClient | 21:f9c433d8e6ca | 351 | /* Codes_SRS_CBS_01_036: [ `cbs_destroy` shall free all resources associated with the handle `cbs`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 352 | /* Codes_SRS_CBS_01_038: [ `cbs_destroy` shall free the AMQP management handle created in `cbs_create` by calling `amqp_management_destroy`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 353 | amqp_management_destroy(cbs->amqp_management); |
AzureIoTClient | 21:f9c433d8e6ca | 354 | |
AzureIoTClient | 21:f9c433d8e6ca | 355 | /* Codes_SRS_CBS_01_099: [ All pending operations shall be freed. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 356 | while ((first_pending_operation = singlylinkedlist_get_head_item(cbs->pending_operations)) != NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 357 | { |
AzureIoTClient | 21:f9c433d8e6ca | 358 | CBS_OPERATION* pending_operation = (CBS_OPERATION*)singlylinkedlist_item_get_value(first_pending_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 359 | if (pending_operation != NULL) |
AzureIoTClient | 21:f9c433d8e6ca | 360 | { |
AzureIoTClient | 23:1111ee8bcba4 | 361 | pending_operation->on_cbs_operation_complete(pending_operation->on_cbs_operation_complete_context, CBS_OPERATION_RESULT_INSTANCE_CLOSED, 0, NULL); |
AzureIoTClient | 21:f9c433d8e6ca | 362 | free(pending_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 363 | } |
AzureIoTClient | 21:f9c433d8e6ca | 364 | |
AzureIoTClient | 21:f9c433d8e6ca | 365 | singlylinkedlist_remove(cbs->pending_operations, first_pending_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 366 | } |
AzureIoTClient | 21:f9c433d8e6ca | 367 | |
AzureIoTClient | 21:f9c433d8e6ca | 368 | /* Codes_SRS_CBS_01_098: [ `cbs_destroy` shall free the pending operations list by calling `singlylinkedlist_destroy`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 369 | singlylinkedlist_destroy(cbs->pending_operations); |
AzureIoTClient | 21:f9c433d8e6ca | 370 | free(cbs); |
AzureIoTClient | 6:641a9672db08 | 371 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 372 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 373 | |
AzureIoTClient | 21:f9c433d8e6ca | 374 | int cbs_open_async(CBS_HANDLE cbs, ON_CBS_OPEN_COMPLETE on_cbs_open_complete, void* on_cbs_open_complete_context, ON_CBS_ERROR on_cbs_error, void* on_cbs_error_context) |
Azure.IoT Build | 0:6ae2f7bca550 | 375 | { |
AzureIoTClient | 6:641a9672db08 | 376 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 377 | |
AzureIoTClient | 21:f9c433d8e6ca | 378 | /* Codes_SRS_CBS_01_042: [ `on_cbs_open_complete_context` and `on_cbs_error_context` shall be allowed to be NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 379 | if ((cbs == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 380 | (on_cbs_open_complete == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 381 | (on_cbs_error == NULL)) |
AzureIoTClient | 6:641a9672db08 | 382 | { |
AzureIoTClient | 21:f9c433d8e6ca | 383 | /* Codes_SRS_CBS_01_040: [ If any of the arguments `cbs`, `on_cbs_open_complete` or `on_cbs_error` is NULL, then `cbs_open_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 384 | LogError("Bad arguments: cbs = %p, on_cbs_open_complete = %p, on_cbs_error = %p", |
AzureIoTClient | 21:f9c433d8e6ca | 385 | cbs, on_cbs_open_complete, on_cbs_error); |
AzureIoTClient | 21:f9c433d8e6ca | 386 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 387 | } |
AzureIoTClient | 21:f9c433d8e6ca | 388 | else if (cbs->cbs_state != CBS_STATE_CLOSED) |
AzureIoTClient | 21:f9c433d8e6ca | 389 | { |
AzureIoTClient | 21:f9c433d8e6ca | 390 | /* Codes_SRS_CBS_01_043: [ `cbs_open_async` while already open or opening shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 391 | LogError("cbs instance already open"); |
AzureIoTClient | 19:000ab4e6a2c1 | 392 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 393 | } |
AzureIoTClient | 6:641a9672db08 | 394 | else |
AzureIoTClient | 6:641a9672db08 | 395 | { |
AzureIoTClient | 22:524bded3f7a8 | 396 | /* Codes_SRS_CBS_01_078: [ The cbs instance shall be considered OPENING until the `on_amqp_management_open_complete` callback is called by the AMQP management instance indicating that the open has completed (succesfull or not). ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 397 | cbs->cbs_state = CBS_STATE_OPENING; |
AzureIoTClient | 21:f9c433d8e6ca | 398 | cbs->on_cbs_open_complete = on_cbs_open_complete; |
AzureIoTClient | 21:f9c433d8e6ca | 399 | cbs->on_cbs_open_complete_context = on_cbs_open_complete_context; |
AzureIoTClient | 21:f9c433d8e6ca | 400 | cbs->on_cbs_error = on_cbs_error; |
AzureIoTClient | 21:f9c433d8e6ca | 401 | cbs->on_cbs_error_context = on_cbs_error_context; |
AzureIoTClient | 21:f9c433d8e6ca | 402 | |
AzureIoTClient | 22:524bded3f7a8 | 403 | /* Codes_SRS_CBS_01_039: [ `cbs_open_async` shall open the cbs communication by calling `amqp_management_open_async` on the AMQP management handle created in `cbs_create`. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 404 | if (amqp_management_open_async(cbs->amqp_management, on_underlying_amqp_management_open_complete, cbs, on_underlying_amqp_management_error, cbs) != 0) |
AzureIoTClient | 6:641a9672db08 | 405 | { |
AzureIoTClient | 22:524bded3f7a8 | 406 | /* Codes_SRS_CBS_01_041: [ If `amqp_management_open_async` fails, shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 19:000ab4e6a2c1 | 407 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 408 | } |
AzureIoTClient | 6:641a9672db08 | 409 | else |
AzureIoTClient | 6:641a9672db08 | 410 | { |
AzureIoTClient | 21:f9c433d8e6ca | 411 | /* Codes_SRS_CBS_01_077: [ On success, `cbs_open_async` shall return 0. ]*/ |
AzureIoTClient | 6:641a9672db08 | 412 | result = 0; |
AzureIoTClient | 6:641a9672db08 | 413 | } |
AzureIoTClient | 6:641a9672db08 | 414 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 415 | |
AzureIoTClient | 6:641a9672db08 | 416 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 417 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 418 | |
Azure.IoT Build | 0:6ae2f7bca550 | 419 | int cbs_close(CBS_HANDLE cbs) |
Azure.IoT Build | 0:6ae2f7bca550 | 420 | { |
AzureIoTClient | 6:641a9672db08 | 421 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 422 | |
AzureIoTClient | 6:641a9672db08 | 423 | if (cbs == NULL) |
AzureIoTClient | 6:641a9672db08 | 424 | { |
AzureIoTClient | 21:f9c433d8e6ca | 425 | /* Codes_SRS_CBS_01_045: [ If the argument `cbs` is NULL, `cbs_close` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 426 | LogError("NULL cbs handle"); |
AzureIoTClient | 21:f9c433d8e6ca | 427 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 428 | } |
AzureIoTClient | 21:f9c433d8e6ca | 429 | else if (cbs->cbs_state == CBS_STATE_CLOSED) |
AzureIoTClient | 21:f9c433d8e6ca | 430 | { |
AzureIoTClient | 21:f9c433d8e6ca | 431 | /* Codes_SRS_CBS_01_047: [ `cbs_close` when closed shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 432 | /* Codes_SRS_CBS_01_048: [ `cbs_close` when not opened shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 433 | LogError("Already closed"); |
AzureIoTClient | 19:000ab4e6a2c1 | 434 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 435 | } |
AzureIoTClient | 6:641a9672db08 | 436 | else |
AzureIoTClient | 6:641a9672db08 | 437 | { |
AzureIoTClient | 22:524bded3f7a8 | 438 | /* Codes_SRS_CBS_01_044: [ `cbs_close` shall close the CBS instance by calling `amqp_management_close` on the underlying AMQP management handle. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 439 | if (amqp_management_close(cbs->amqp_management) != 0) |
AzureIoTClient | 6:641a9672db08 | 440 | { |
AzureIoTClient | 22:524bded3f7a8 | 441 | /* Codes_SRS_CBS_01_046: [ If `amqp_management_close` fails, `cbs_close` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 442 | LogError("Failed closing AMQP management instance"); |
AzureIoTClient | 19:000ab4e6a2c1 | 443 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 444 | } |
AzureIoTClient | 6:641a9672db08 | 445 | else |
AzureIoTClient | 6:641a9672db08 | 446 | { |
AzureIoTClient | 21:f9c433d8e6ca | 447 | if (cbs->cbs_state == CBS_STATE_OPENING) |
AzureIoTClient | 21:f9c433d8e6ca | 448 | { |
AzureIoTClient | 21:f9c433d8e6ca | 449 | /* Codes_SRS_CBS_01_079: [ If `cbs_close` is called while OPENING, the `on_cbs_open_complete` callback shall be called with `CBS_OPEN_CANCELLED`, while passing the `on_cbs_open_complete_context` as argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 450 | cbs->on_cbs_open_complete(cbs->on_cbs_open_complete_context, CBS_OPEN_CANCELLED); |
AzureIoTClient | 21:f9c433d8e6ca | 451 | } |
AzureIoTClient | 21:f9c433d8e6ca | 452 | |
AzureIoTClient | 21:f9c433d8e6ca | 453 | cbs->cbs_state = CBS_STATE_CLOSED; |
AzureIoTClient | 21:f9c433d8e6ca | 454 | |
AzureIoTClient | 21:f9c433d8e6ca | 455 | /* Codes_SRS_CBS_01_080: [ On success, `cbs_close` shall return 0. ]*/ |
AzureIoTClient | 6:641a9672db08 | 456 | result = 0; |
AzureIoTClient | 6:641a9672db08 | 457 | } |
AzureIoTClient | 6:641a9672db08 | 458 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 459 | |
AzureIoTClient | 6:641a9672db08 | 460 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 461 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 462 | |
AzureIoTClient | 21:f9c433d8e6ca | 463 | int cbs_put_token_async(CBS_HANDLE cbs, const char* type, const char* audience, const char* token, ON_CBS_OPERATION_COMPLETE on_cbs_put_token_complete, void* on_cbs_put_token_complete_context) |
Azure.IoT Build | 0:6ae2f7bca550 | 464 | { |
AzureIoTClient | 6:641a9672db08 | 465 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 466 | |
AzureIoTClient | 21:f9c433d8e6ca | 467 | /* Codes_SRS_CBS_01_083: [ `on_cbs_put_token_complete_context` shall be allowed to be NULL. ]*/ |
AzureIoTClient | 6:641a9672db08 | 468 | if ((cbs == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 469 | (type == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 470 | (audience == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 471 | (token == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 472 | (on_cbs_put_token_complete == NULL)) |
AzureIoTClient | 6:641a9672db08 | 473 | { |
AzureIoTClient | 21:f9c433d8e6ca | 474 | /* Codes_SRS_CBS_01_050: [ If any of the arguments `cbs`, `type`, `audience`, `token` or `on_cbs_put_token_complete` is NULL `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 475 | LogError("Bad arguments: cbs = %p, type = %p, audience = %p, token = %p, on_cbs_put_token_complete = %p", |
AzureIoTClient | 21:f9c433d8e6ca | 476 | cbs, type, audience, token, on_cbs_put_token_complete); |
AzureIoTClient | 21:f9c433d8e6ca | 477 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 478 | } |
AzureIoTClient | 21:f9c433d8e6ca | 479 | else if ((cbs->cbs_state == CBS_STATE_CLOSED) || |
AzureIoTClient | 21:f9c433d8e6ca | 480 | (cbs->cbs_state == CBS_STATE_ERROR)) |
AzureIoTClient | 21:f9c433d8e6ca | 481 | { |
AzureIoTClient | 21:f9c433d8e6ca | 482 | /* Codes_SRS_CBS_01_058: [ If `cbs_put_token_async` is called when the CBS instance is not yet open or in error, it shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 483 | LogError("put token called while closed or in error"); |
AzureIoTClient | 19:000ab4e6a2c1 | 484 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 485 | } |
AzureIoTClient | 6:641a9672db08 | 486 | else |
AzureIoTClient | 6:641a9672db08 | 487 | { |
AzureIoTClient | 21:f9c433d8e6ca | 488 | /* Codes_SRS_CBS_01_049: [ `cbs_put_token_async` shall construct a request message for the `put-token` operation. ]*/ |
AzureIoTClient | 6:641a9672db08 | 489 | MESSAGE_HANDLE message = message_create(); |
AzureIoTClient | 6:641a9672db08 | 490 | if (message == NULL) |
AzureIoTClient | 6:641a9672db08 | 491 | { |
AzureIoTClient | 21:f9c433d8e6ca | 492 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 493 | LogError("message_create failed"); |
AzureIoTClient | 19:000ab4e6a2c1 | 494 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 495 | } |
AzureIoTClient | 6:641a9672db08 | 496 | else |
AzureIoTClient | 6:641a9672db08 | 497 | { |
AzureIoTClient | 6:641a9672db08 | 498 | AMQP_VALUE token_value = amqpvalue_create_string(token); |
AzureIoTClient | 6:641a9672db08 | 499 | if (token_value == NULL) |
AzureIoTClient | 6:641a9672db08 | 500 | { |
AzureIoTClient | 21:f9c433d8e6ca | 501 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 502 | LogError("Failed creating token AMQP value"); |
AzureIoTClient | 19:000ab4e6a2c1 | 503 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 504 | } |
AzureIoTClient | 6:641a9672db08 | 505 | else |
AzureIoTClient | 6:641a9672db08 | 506 | { |
AzureIoTClient | 21:f9c433d8e6ca | 507 | /* Codes_SRS_CBS_01_009: [ The body of the message MUST contain the token. ]*/ |
AzureIoTClient | 6:641a9672db08 | 508 | if (message_set_body_amqp_value(message, token_value) != 0) |
AzureIoTClient | 6:641a9672db08 | 509 | { |
AzureIoTClient | 21:f9c433d8e6ca | 510 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 511 | LogError("Failed setting the token in the message body"); |
AzureIoTClient | 19:000ab4e6a2c1 | 512 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 513 | } |
AzureIoTClient | 6:641a9672db08 | 514 | else |
AzureIoTClient | 6:641a9672db08 | 515 | { |
AzureIoTClient | 6:641a9672db08 | 516 | AMQP_VALUE application_properties = amqpvalue_create_map(); |
AzureIoTClient | 6:641a9672db08 | 517 | if (application_properties == NULL) |
AzureIoTClient | 6:641a9672db08 | 518 | { |
AzureIoTClient | 21:f9c433d8e6ca | 519 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 520 | LogError("Failed creating application properties map"); |
AzureIoTClient | 19:000ab4e6a2c1 | 521 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 522 | } |
AzureIoTClient | 6:641a9672db08 | 523 | else |
AzureIoTClient | 6:641a9672db08 | 524 | { |
AzureIoTClient | 6:641a9672db08 | 525 | if (add_string_key_value_pair_to_map(application_properties, "name", audience) != 0) |
AzureIoTClient | 6:641a9672db08 | 526 | { |
AzureIoTClient | 19:000ab4e6a2c1 | 527 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 528 | } |
AzureIoTClient | 6:641a9672db08 | 529 | else |
AzureIoTClient | 6:641a9672db08 | 530 | { |
AzureIoTClient | 6:641a9672db08 | 531 | if (message_set_application_properties(message, application_properties) != 0) |
AzureIoTClient | 6:641a9672db08 | 532 | { |
AzureIoTClient | 21:f9c433d8e6ca | 533 | /* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 534 | LogError("Failed setting message application properties"); |
AzureIoTClient | 19:000ab4e6a2c1 | 535 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 536 | } |
AzureIoTClient | 6:641a9672db08 | 537 | else |
AzureIoTClient | 6:641a9672db08 | 538 | { |
AzureIoTClient | 21:f9c433d8e6ca | 539 | CBS_OPERATION* cbs_operation = (CBS_OPERATION*)malloc(sizeof(CBS_OPERATION)); |
AzureIoTClient | 21:f9c433d8e6ca | 540 | if (cbs_operation == NULL) |
AzureIoTClient | 6:641a9672db08 | 541 | { |
AzureIoTClient | 21:f9c433d8e6ca | 542 | LogError("Failed allocating CBS operation instance"); |
AzureIoTClient | 19:000ab4e6a2c1 | 543 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 544 | } |
AzureIoTClient | 6:641a9672db08 | 545 | else |
AzureIoTClient | 6:641a9672db08 | 546 | { |
AzureIoTClient | 21:f9c433d8e6ca | 547 | LIST_ITEM_HANDLE list_item; |
AzureIoTClient | 21:f9c433d8e6ca | 548 | |
AzureIoTClient | 21:f9c433d8e6ca | 549 | cbs_operation->on_cbs_operation_complete = on_cbs_put_token_complete; |
AzureIoTClient | 21:f9c433d8e6ca | 550 | cbs_operation->on_cbs_operation_complete_context = on_cbs_put_token_complete_context; |
AzureIoTClient | 21:f9c433d8e6ca | 551 | cbs_operation->pending_operations = cbs->pending_operations; |
AzureIoTClient | 21:f9c433d8e6ca | 552 | |
AzureIoTClient | 21:f9c433d8e6ca | 553 | list_item = singlylinkedlist_add(cbs->pending_operations, cbs_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 554 | if (list_item == NULL) |
AzureIoTClient | 6:641a9672db08 | 555 | { |
AzureIoTClient | 21:f9c433d8e6ca | 556 | free(cbs_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 557 | LogError("Failed adding pending operation to list"); |
AzureIoTClient | 19:000ab4e6a2c1 | 558 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 559 | } |
AzureIoTClient | 6:641a9672db08 | 560 | else |
AzureIoTClient | 6:641a9672db08 | 561 | { |
AzureIoTClient | 22:524bded3f7a8 | 562 | /* Codes_SRS_CBS_01_051: [ `cbs_put_token_async` shall start the AMQP management operation by calling `amqp_management_execute_operation_async`, while passing to it: ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 563 | /* Codes_SRS_CBS_01_052: [ The `amqp_management` argument shall be the one for the AMQP management instance created in `cbs_create`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 564 | /* Codes_SRS_CBS_01_053: [ The `operation` argument shall be `put-token`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 565 | /* Codes_SRS_CBS_01_054: [ The `type` argument shall be set to the `type` argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 566 | /* Codes_SRS_CBS_01_055: [ The `locales` argument shall be set to NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 567 | /* Codes_SRS_CBS_01_056: [ The `message` argument shall be the message constructed earlier according to the CBS spec. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 568 | /* Codes_SRS_CBS_01_057: [ The arguments `on_execute_operation_complete` and `context` shall be set to a callback that is to be called by the AMQP management module when the operation is complete. ]*/ |
AzureIoTClient | 28:add19eb7defa | 569 | /* Codes_SRS_CBS_01_005: [ operation No string "put-token" ]*/ |
AzureIoTClient | 28:add19eb7defa | 570 | /* Codes_SRS_CBS_01_006: [ Type No string The type of the token being put, e.g., "amqp:jwt". ]*/ |
AzureIoTClient | 28:add19eb7defa | 571 | /* Codes_SRS_CBS_01_007: [ name No string The "audience" to which the token applies. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 572 | if (amqp_management_execute_operation_async(cbs->amqp_management, "put-token", type, NULL, message, on_amqp_management_execute_operation_complete, list_item) != 0) |
AzureIoTClient | 21:f9c433d8e6ca | 573 | { |
AzureIoTClient | 21:f9c433d8e6ca | 574 | singlylinkedlist_remove(cbs->pending_operations, list_item); |
AzureIoTClient | 21:f9c433d8e6ca | 575 | free(cbs_operation); |
AzureIoTClient | 22:524bded3f7a8 | 576 | /* Codes_SRS_CBS_01_084: [ If `amqp_management_execute_operation_async` fails `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 577 | LogError("Failed starting AMQP management operation"); |
AzureIoTClient | 21:f9c433d8e6ca | 578 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 579 | } |
AzureIoTClient | 21:f9c433d8e6ca | 580 | else |
AzureIoTClient | 21:f9c433d8e6ca | 581 | { |
AzureIoTClient | 21:f9c433d8e6ca | 582 | /* Codes_SRS_CBS_01_081: [ On success `cbs_put_token_async` shall return 0. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 583 | result = 0; |
AzureIoTClient | 21:f9c433d8e6ca | 584 | } |
AzureIoTClient | 6:641a9672db08 | 585 | } |
AzureIoTClient | 6:641a9672db08 | 586 | } |
AzureIoTClient | 6:641a9672db08 | 587 | } |
AzureIoTClient | 6:641a9672db08 | 588 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 589 | |
AzureIoTClient | 6:641a9672db08 | 590 | amqpvalue_destroy(application_properties); |
AzureIoTClient | 6:641a9672db08 | 591 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 592 | |
AzureIoTClient | 6:641a9672db08 | 593 | amqpvalue_destroy(token_value); |
AzureIoTClient | 6:641a9672db08 | 594 | } |
AzureIoTClient | 6:641a9672db08 | 595 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 596 | |
AzureIoTClient | 6:641a9672db08 | 597 | message_destroy(message); |
AzureIoTClient | 6:641a9672db08 | 598 | } |
AzureIoTClient | 6:641a9672db08 | 599 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 600 | |
AzureIoTClient | 6:641a9672db08 | 601 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 602 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 603 | |
AzureIoTClient | 21:f9c433d8e6ca | 604 | int cbs_delete_token_async(CBS_HANDLE cbs, const char* type, const char* audience, ON_CBS_OPERATION_COMPLETE on_cbs_delete_token_complete, void* on_cbs_delete_token_complete_context) |
Azure.IoT Build | 0:6ae2f7bca550 | 605 | { |
AzureIoTClient | 6:641a9672db08 | 606 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 607 | |
AzureIoTClient | 21:f9c433d8e6ca | 608 | /* Codes_SRS_CBS_01_086: [ `on_cbs_delete_token_complete_context` shall be allowed to be NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 609 | if ((cbs == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 610 | (type == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 611 | (audience == NULL) || |
AzureIoTClient | 21:f9c433d8e6ca | 612 | (on_cbs_delete_token_complete == NULL)) |
AzureIoTClient | 6:641a9672db08 | 613 | { |
AzureIoTClient | 21:f9c433d8e6ca | 614 | /* Codes_SRS_CBS_01_060: [ If any of the arguments `cbs`, `type`, `audience` or `on_cbs_delete_token_complete` is NULL `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 615 | LogError("Bad arguments: cbs = %p, type = %p, audience = %p, on_cbs_delete_token_complete = %p", |
AzureIoTClient | 21:f9c433d8e6ca | 616 | cbs, type, audience, on_cbs_delete_token_complete); |
AzureIoTClient | 21:f9c433d8e6ca | 617 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 618 | } |
AzureIoTClient | 21:f9c433d8e6ca | 619 | else if ((cbs->cbs_state == CBS_STATE_CLOSED) || |
AzureIoTClient | 21:f9c433d8e6ca | 620 | (cbs->cbs_state == CBS_STATE_ERROR)) |
AzureIoTClient | 21:f9c433d8e6ca | 621 | { |
AzureIoTClient | 21:f9c433d8e6ca | 622 | /* Codes_SRS_CBS_01_067: [ If `cbs_delete_token_async` is called when the CBS instance is not yet open or in error, it shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 623 | LogError("put token called while closed or in error"); |
AzureIoTClient | 19:000ab4e6a2c1 | 624 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 625 | } |
AzureIoTClient | 6:641a9672db08 | 626 | else |
AzureIoTClient | 6:641a9672db08 | 627 | { |
AzureIoTClient | 21:f9c433d8e6ca | 628 | /* Codes_SRS_CBS_01_025: [ The body of the message MUST be empty. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 629 | /* Codes_SRS_CBS_01_059: [ `cbs_delete_token_async` shall construct a request message for the `delete-token` operation. ]*/ |
AzureIoTClient | 6:641a9672db08 | 630 | MESSAGE_HANDLE message = message_create(); |
AzureIoTClient | 6:641a9672db08 | 631 | if (message == NULL) |
AzureIoTClient | 6:641a9672db08 | 632 | { |
AzureIoTClient | 21:f9c433d8e6ca | 633 | /* Codes_SRS_CBS_01_071: [ If constructing the message fails, `cbs_delete_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 634 | LogError("message_create failed"); |
AzureIoTClient | 19:000ab4e6a2c1 | 635 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 636 | } |
AzureIoTClient | 6:641a9672db08 | 637 | else |
AzureIoTClient | 6:641a9672db08 | 638 | { |
AzureIoTClient | 6:641a9672db08 | 639 | AMQP_VALUE application_properties = amqpvalue_create_map(); |
AzureIoTClient | 6:641a9672db08 | 640 | if (application_properties == NULL) |
AzureIoTClient | 6:641a9672db08 | 641 | { |
AzureIoTClient | 21:f9c433d8e6ca | 642 | /* Codes_SRS_CBS_01_071: [ If constructing the message fails, `cbs_delete_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 643 | LogError("Failed creating application properties map"); |
AzureIoTClient | 19:000ab4e6a2c1 | 644 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 645 | } |
AzureIoTClient | 6:641a9672db08 | 646 | else |
AzureIoTClient | 6:641a9672db08 | 647 | { |
AzureIoTClient | 6:641a9672db08 | 648 | if (add_string_key_value_pair_to_map(application_properties, "name", audience) != 0) |
AzureIoTClient | 6:641a9672db08 | 649 | { |
AzureIoTClient | 19:000ab4e6a2c1 | 650 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 651 | } |
AzureIoTClient | 6:641a9672db08 | 652 | else |
AzureIoTClient | 6:641a9672db08 | 653 | { |
AzureIoTClient | 21:f9c433d8e6ca | 654 | /* Codes_SRS_CBS_01_021: [ The request message has the following application-properties: ]*/ |
AzureIoTClient | 6:641a9672db08 | 655 | if (message_set_application_properties(message, application_properties) != 0) |
AzureIoTClient | 6:641a9672db08 | 656 | { |
AzureIoTClient | 21:f9c433d8e6ca | 657 | /* Codes_SRS_CBS_01_071: [ If constructing the message fails, `cbs_delete_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 658 | LogError("Failed setting message application properties"); |
AzureIoTClient | 19:000ab4e6a2c1 | 659 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 660 | } |
AzureIoTClient | 6:641a9672db08 | 661 | else |
AzureIoTClient | 6:641a9672db08 | 662 | { |
AzureIoTClient | 21:f9c433d8e6ca | 663 | CBS_OPERATION* cbs_operation = (CBS_OPERATION*)malloc(sizeof(CBS_OPERATION)); |
AzureIoTClient | 21:f9c433d8e6ca | 664 | if (cbs_operation == NULL) |
AzureIoTClient | 6:641a9672db08 | 665 | { |
AzureIoTClient | 21:f9c433d8e6ca | 666 | LogError("Failed allocating CBS operation instance"); |
AzureIoTClient | 19:000ab4e6a2c1 | 667 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 668 | } |
AzureIoTClient | 6:641a9672db08 | 669 | else |
AzureIoTClient | 6:641a9672db08 | 670 | { |
AzureIoTClient | 21:f9c433d8e6ca | 671 | LIST_ITEM_HANDLE list_item; |
AzureIoTClient | 21:f9c433d8e6ca | 672 | |
AzureIoTClient | 21:f9c433d8e6ca | 673 | cbs_operation->on_cbs_operation_complete = on_cbs_delete_token_complete; |
AzureIoTClient | 21:f9c433d8e6ca | 674 | cbs_operation->on_cbs_operation_complete_context = on_cbs_delete_token_complete_context; |
AzureIoTClient | 21:f9c433d8e6ca | 675 | cbs_operation->pending_operations = cbs->pending_operations; |
AzureIoTClient | 21:f9c433d8e6ca | 676 | |
AzureIoTClient | 21:f9c433d8e6ca | 677 | list_item = singlylinkedlist_add(cbs->pending_operations, cbs_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 678 | if (list_item == NULL) |
AzureIoTClient | 6:641a9672db08 | 679 | { |
AzureIoTClient | 21:f9c433d8e6ca | 680 | free(cbs_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 681 | LogError("Failed adding pending operation to list"); |
AzureIoTClient | 19:000ab4e6a2c1 | 682 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 683 | } |
AzureIoTClient | 6:641a9672db08 | 684 | else |
AzureIoTClient | 6:641a9672db08 | 685 | { |
AzureIoTClient | 22:524bded3f7a8 | 686 | /* Codes_SRS_CBS_01_061: [ `cbs_delete_token_async` shall start the AMQP management operation by calling `amqp_management_execute_operation_async`, while passing to it: ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 687 | /* Codes_SRS_CBS_01_085: [ The `amqp_management` argument shall be the one for the AMQP management instance created in `cbs_create`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 688 | /* Codes_SRS_CBS_01_062: [ The `operation` argument shall be `delete-token`. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 689 | /* Codes_SRS_CBS_01_063: [ The `type` argument shall be set to the `type` argument. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 690 | /* Codes_SRS_CBS_01_064: [ The `locales` argument shall be set to NULL. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 691 | /* Codes_SRS_CBS_01_065: [ The `message` argument shall be the message constructed earlier according to the CBS spec. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 692 | /* Codes_SRS_CBS_01_066: [ The arguments `on_operation_complete` and `context` shall be set to a callback that is to be called by the AMQP management module when the operation is complete. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 693 | /* Codes_SRS_CBS_01_020: [ To instruct a peer to delete a token associated with a specific audience, a "delete-token" message can be sent to the CBS Node ]*/ |
AzureIoTClient | 28:add19eb7defa | 694 | /* Codes_SRS_CBS_01_022: [ operation Yes string "delete-token" ]*/ |
AzureIoTClient | 28:add19eb7defa | 695 | /* Codes_SRS_CBS_01_023: [ Type Yes string The type of the token being deleted, e.g., "amqp:jwt". ]*/ |
AzureIoTClient | 28:add19eb7defa | 696 | /* Codes_SRS_CBS_01_024: [ name Yes string The "audience" of the token being deleted. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 697 | if (amqp_management_execute_operation_async(cbs->amqp_management, "delete-token", type, NULL, message, on_amqp_management_execute_operation_complete, list_item) != 0) |
AzureIoTClient | 21:f9c433d8e6ca | 698 | { |
AzureIoTClient | 22:524bded3f7a8 | 699 | /* Codes_SRS_CBS_01_087: [ If `amqp_management_execute_operation_async` fails `cbs_put_token_async` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 700 | singlylinkedlist_remove(cbs->pending_operations, list_item); |
AzureIoTClient | 21:f9c433d8e6ca | 701 | free(cbs_operation); |
AzureIoTClient | 21:f9c433d8e6ca | 702 | LogError("Failed starting AMQP management operation"); |
AzureIoTClient | 21:f9c433d8e6ca | 703 | result = __FAILURE__; |
AzureIoTClient | 21:f9c433d8e6ca | 704 | } |
AzureIoTClient | 21:f9c433d8e6ca | 705 | else |
AzureIoTClient | 21:f9c433d8e6ca | 706 | { |
AzureIoTClient | 21:f9c433d8e6ca | 707 | /* Codes_SRS_CBS_01_082: [ On success `cbs_delete_token_async` shall return 0. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 708 | result = 0; |
AzureIoTClient | 21:f9c433d8e6ca | 709 | } |
AzureIoTClient | 6:641a9672db08 | 710 | } |
AzureIoTClient | 6:641a9672db08 | 711 | } |
AzureIoTClient | 6:641a9672db08 | 712 | } |
AzureIoTClient | 6:641a9672db08 | 713 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 714 | |
AzureIoTClient | 6:641a9672db08 | 715 | amqpvalue_destroy(application_properties); |
AzureIoTClient | 6:641a9672db08 | 716 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 717 | |
AzureIoTClient | 6:641a9672db08 | 718 | message_destroy(message); |
AzureIoTClient | 6:641a9672db08 | 719 | } |
AzureIoTClient | 6:641a9672db08 | 720 | } |
AzureIoTClient | 6:641a9672db08 | 721 | return result; |
AzureIoTClient | 6:641a9672db08 | 722 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 723 | |
AzureIoTClient | 21:f9c433d8e6ca | 724 | int cbs_set_trace(CBS_HANDLE cbs, bool trace_on) |
AzureIoTClient | 6:641a9672db08 | 725 | { |
AzureIoTClient | 21:f9c433d8e6ca | 726 | int result; |
AzureIoTClient | 21:f9c433d8e6ca | 727 | |
AzureIoTClient | 21:f9c433d8e6ca | 728 | if (cbs == NULL) |
AzureIoTClient | 6:641a9672db08 | 729 | { |
AzureIoTClient | 21:f9c433d8e6ca | 730 | /* Codes_SRS_CBS_01_090: [ If the argument `cbs` is NULL, `cbs_set_trace` shall fail and return a non-zero value. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 731 | LogError("NULL cbs handle"); |
AzureIoTClient | 21:f9c433d8e6ca | 732 | result = __FAILURE__; |
AzureIoTClient | 6:641a9672db08 | 733 | } |
AzureIoTClient | 21:f9c433d8e6ca | 734 | else |
AzureIoTClient | 21:f9c433d8e6ca | 735 | { |
AzureIoTClient | 22:524bded3f7a8 | 736 | /* Codes_SRS_CBS_01_088: [ `cbs_set_trace` shall enable or disable tracing by calling `amqp_management_set_trace` to pass down the `trace_on` value. ]*/ |
AzureIoTClient | 22:524bded3f7a8 | 737 | amqp_management_set_trace(cbs->amqp_management, trace_on); |
AzureIoTClient | 21:f9c433d8e6ca | 738 | |
AzureIoTClient | 21:f9c433d8e6ca | 739 | /* Codes_SRS_CBS_01_089: [ On success, `cbs_set_trace` shall return 0. ]*/ |
AzureIoTClient | 21:f9c433d8e6ca | 740 | result = 0; |
AzureIoTClient | 21:f9c433d8e6ca | 741 | } |
AzureIoTClient | 21:f9c433d8e6ca | 742 | |
AzureIoTClient | 21:f9c433d8e6ca | 743 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 744 | } |