A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Committer:
AzureIoTClient
Date:
Fri Jul 29 15:58:39 2016 -0700
Revision:
6:641a9672db08
Parent:
0:6ae2f7bca550
Child:
15:5db103709f20
1.0.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:6ae2f7bca550 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:6ae2f7bca550 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:6ae2f7bca550 3
Azure.IoT Build 0:6ae2f7bca550 4 #include <stdlib.h>
Azure.IoT Build 0:6ae2f7bca550 5 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 0:6ae2f7bca550 6 #include <crtdbg.h>
Azure.IoT Build 0:6ae2f7bca550 7 #endif
Azure.IoT Build 0:6ae2f7bca550 8 #include <stdint.h>
Azure.IoT Build 0:6ae2f7bca550 9 #include <stddef.h>
Azure.IoT Build 0:6ae2f7bca550 10 #include <string.h>
Azure.IoT Build 0:6ae2f7bca550 11 #include "azure_uamqp_c/sasl_frame_codec.h"
Azure.IoT Build 0:6ae2f7bca550 12 #include "azure_uamqp_c/frame_codec.h"
Azure.IoT Build 0:6ae2f7bca550 13 #include "azure_uamqp_c/amqpalloc.h"
Azure.IoT Build 0:6ae2f7bca550 14 #include "azure_uamqp_c/amqpvalue.h"
Azure.IoT Build 0:6ae2f7bca550 15 #include "azure_uamqp_c/amqp_definitions.h"
Azure.IoT Build 0:6ae2f7bca550 16
Azure.IoT Build 0:6ae2f7bca550 17 /* Requirements implemented by design or by other modules */
Azure.IoT Build 0:6ae2f7bca550 18 /* Codes_SRS_SASL_FRAME_CODEC_01_011: [A SASL frame has a type code of 0x01.] */
Azure.IoT Build 0:6ae2f7bca550 19 /* Codes_SRS_SASL_FRAME_CODEC_01_016: [The maximum size of a SASL frame is defined by MIN-MAX-FRAME-SIZE.] */
Azure.IoT Build 0:6ae2f7bca550 20
Azure.IoT Build 0:6ae2f7bca550 21 #define MIX_MAX_FRAME_SIZE 512
Azure.IoT Build 0:6ae2f7bca550 22
Azure.IoT Build 0:6ae2f7bca550 23 typedef enum SASL_FRAME_DECODE_STATE_TAG
Azure.IoT Build 0:6ae2f7bca550 24 {
Azure.IoT Build 0:6ae2f7bca550 25 SASL_FRAME_DECODE_FRAME,
Azure.IoT Build 0:6ae2f7bca550 26 SASL_FRAME_DECODE_ERROR
Azure.IoT Build 0:6ae2f7bca550 27 } SASL_FRAME_DECODE_STATE;
Azure.IoT Build 0:6ae2f7bca550 28
Azure.IoT Build 0:6ae2f7bca550 29 typedef struct SASL_FRAME_CODEC_INSTANCE_TAG
Azure.IoT Build 0:6ae2f7bca550 30 {
Azure.IoT Build 0:6ae2f7bca550 31 FRAME_CODEC_HANDLE frame_codec;
Azure.IoT Build 0:6ae2f7bca550 32
Azure.IoT Build 0:6ae2f7bca550 33 /* decode */
Azure.IoT Build 0:6ae2f7bca550 34 ON_SASL_FRAME_RECEIVED on_sasl_frame_received;
Azure.IoT Build 0:6ae2f7bca550 35 ON_SASL_FRAME_CODEC_ERROR on_sasl_frame_codec_error;
Azure.IoT Build 0:6ae2f7bca550 36 void* callback_context;
Azure.IoT Build 0:6ae2f7bca550 37 AMQPVALUE_DECODER_HANDLE decoder;
Azure.IoT Build 0:6ae2f7bca550 38 SASL_FRAME_DECODE_STATE decode_state;
Azure.IoT Build 0:6ae2f7bca550 39 AMQP_VALUE decoded_sasl_frame_value;
Azure.IoT Build 0:6ae2f7bca550 40 } SASL_FRAME_CODEC_INSTANCE;
Azure.IoT Build 0:6ae2f7bca550 41
Azure.IoT Build 0:6ae2f7bca550 42 static void amqp_value_decoded(void* context, AMQP_VALUE decoded_value)
Azure.IoT Build 0:6ae2f7bca550 43 {
Azure.IoT Build 0:6ae2f7bca550 44 SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 45 AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(decoded_value);
Azure.IoT Build 0:6ae2f7bca550 46
Azure.IoT Build 0:6ae2f7bca550 47 if (descriptor == NULL)
Azure.IoT Build 0:6ae2f7bca550 48 {
Azure.IoT Build 0:6ae2f7bca550 49 sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 50
Azure.IoT Build 0:6ae2f7bca550 51 /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 52 sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 53 }
Azure.IoT Build 0:6ae2f7bca550 54 else
Azure.IoT Build 0:6ae2f7bca550 55 {
Azure.IoT Build 0:6ae2f7bca550 56 /* Codes_SRS_SASL_FRAME_CODEC_01_009: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides=“sasl-frame”.] */
Azure.IoT Build 0:6ae2f7bca550 57 if (!is_sasl_mechanisms_type_by_descriptor(descriptor) &&
Azure.IoT Build 0:6ae2f7bca550 58 !is_sasl_init_type_by_descriptor(descriptor) &&
Azure.IoT Build 0:6ae2f7bca550 59 !is_sasl_challenge_type_by_descriptor(descriptor) &&
Azure.IoT Build 0:6ae2f7bca550 60 !is_sasl_response_type_by_descriptor(descriptor) &&
Azure.IoT Build 0:6ae2f7bca550 61 !is_sasl_outcome_type_by_descriptor(descriptor))
Azure.IoT Build 0:6ae2f7bca550 62 {
Azure.IoT Build 0:6ae2f7bca550 63 sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 64
Azure.IoT Build 0:6ae2f7bca550 65 /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 66 sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 67 }
Azure.IoT Build 0:6ae2f7bca550 68 else
Azure.IoT Build 0:6ae2f7bca550 69 {
Azure.IoT Build 0:6ae2f7bca550 70 sasl_frame_codec_instance->decoded_sasl_frame_value = decoded_value;
Azure.IoT Build 0:6ae2f7bca550 71 }
Azure.IoT Build 0:6ae2f7bca550 72 }
Azure.IoT Build 0:6ae2f7bca550 73 }
Azure.IoT Build 0:6ae2f7bca550 74
Azure.IoT Build 0:6ae2f7bca550 75 static void frame_received(void* context, const unsigned char* type_specific, uint32_t type_specific_size, const unsigned char* frame_body, uint32_t frame_body_size)
Azure.IoT Build 0:6ae2f7bca550 76 {
Azure.IoT Build 0:6ae2f7bca550 77 SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)context;
Azure.IoT Build 0:6ae2f7bca550 78
Azure.IoT Build 0:6ae2f7bca550 79 /* Codes_SRS_SASL_FRAME_CODEC_01_006: [Bytes 6 and 7 of the header are ignored.] */
Azure.IoT Build 0:6ae2f7bca550 80 (void)type_specific;
Azure.IoT Build 0:6ae2f7bca550 81 /* Codes_SRS_SASL_FRAME_CODEC_01_007: [The extended header is ignored.] */
Azure.IoT Build 0:6ae2f7bca550 82
Azure.IoT Build 0:6ae2f7bca550 83 /* Codes_SRS_SASL_FRAME_CODEC_01_008: [The maximum size of a SASL frame is defined by MIN-MAX-FRAME-SIZE.] */
Azure.IoT Build 0:6ae2f7bca550 84 if ((type_specific_size + frame_body_size + 6 > MIX_MAX_FRAME_SIZE) ||
Azure.IoT Build 0:6ae2f7bca550 85 /* Codes_SRS_SASL_FRAME_CODEC_01_010: [Receipt of an empty frame is an irrecoverable error.] */
Azure.IoT Build 0:6ae2f7bca550 86 (frame_body_size == 0))
Azure.IoT Build 0:6ae2f7bca550 87 {
Azure.IoT Build 0:6ae2f7bca550 88 /* error */
Azure.IoT Build 0:6ae2f7bca550 89
Azure.IoT Build 0:6ae2f7bca550 90 /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 91 sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 92 }
Azure.IoT Build 0:6ae2f7bca550 93 else
Azure.IoT Build 0:6ae2f7bca550 94 {
Azure.IoT Build 0:6ae2f7bca550 95 switch (sasl_frame_codec_instance->decode_state)
Azure.IoT Build 0:6ae2f7bca550 96 {
Azure.IoT Build 0:6ae2f7bca550 97 default:
Azure.IoT Build 0:6ae2f7bca550 98 case SASL_FRAME_DECODE_ERROR:
Azure.IoT Build 0:6ae2f7bca550 99 /* error */
Azure.IoT Build 0:6ae2f7bca550 100 break;
Azure.IoT Build 0:6ae2f7bca550 101
Azure.IoT Build 0:6ae2f7bca550 102 case SASL_FRAME_DECODE_FRAME:
Azure.IoT Build 0:6ae2f7bca550 103 sasl_frame_codec_instance->decoded_sasl_frame_value = NULL;
Azure.IoT Build 0:6ae2f7bca550 104
Azure.IoT Build 0:6ae2f7bca550 105 /* Codes_SRS_SASL_FRAME_CODEC_01_039: [sasl_frame_codec shall decode the sasl-frame value as a described type.] */
Azure.IoT Build 0:6ae2f7bca550 106 /* Codes_SRS_SASL_FRAME_CODEC_01_048: [Receipt of an empty frame is an irrecoverable error.] */
Azure.IoT Build 0:6ae2f7bca550 107 while ((frame_body_size > 0) &&
Azure.IoT Build 0:6ae2f7bca550 108 (sasl_frame_codec_instance->decoded_sasl_frame_value == NULL) &&
Azure.IoT Build 0:6ae2f7bca550 109 (sasl_frame_codec_instance->decode_state != SASL_FRAME_DECODE_ERROR))
Azure.IoT Build 0:6ae2f7bca550 110 {
Azure.IoT Build 0:6ae2f7bca550 111 /* Codes_SRS_SASL_FRAME_CODEC_01_040: [Decoding the sasl-frame type shall be done by feeding the bytes to the decoder create in sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 112 if (amqpvalue_decode_bytes(sasl_frame_codec_instance->decoder, frame_body, 1) != 0)
Azure.IoT Build 0:6ae2f7bca550 113 {
Azure.IoT Build 0:6ae2f7bca550 114 sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 115 }
Azure.IoT Build 0:6ae2f7bca550 116 else
Azure.IoT Build 0:6ae2f7bca550 117 {
Azure.IoT Build 0:6ae2f7bca550 118 frame_body_size--;
Azure.IoT Build 0:6ae2f7bca550 119 frame_body++;
Azure.IoT Build 0:6ae2f7bca550 120 }
Azure.IoT Build 0:6ae2f7bca550 121 }
Azure.IoT Build 0:6ae2f7bca550 122
Azure.IoT Build 0:6ae2f7bca550 123 /* Codes_SRS_SASL_FRAME_CODEC_01_009: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides=“sasl-frame”.] */
Azure.IoT Build 0:6ae2f7bca550 124 if (frame_body_size > 0)
Azure.IoT Build 0:6ae2f7bca550 125 {
Azure.IoT Build 0:6ae2f7bca550 126 sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR;
Azure.IoT Build 0:6ae2f7bca550 127
Azure.IoT Build 0:6ae2f7bca550 128 /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 129 sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context);
Azure.IoT Build 0:6ae2f7bca550 130 }
Azure.IoT Build 0:6ae2f7bca550 131
Azure.IoT Build 0:6ae2f7bca550 132 if (sasl_frame_codec_instance->decode_state == SASL_FRAME_DECODE_ERROR)
Azure.IoT Build 0:6ae2f7bca550 133 {
Azure.IoT Build 0:6ae2f7bca550 134 /* error */
Azure.IoT Build 0:6ae2f7bca550 135 }
Azure.IoT Build 0:6ae2f7bca550 136 else
Azure.IoT Build 0:6ae2f7bca550 137 {
Azure.IoT Build 0:6ae2f7bca550 138 /* Codes_SRS_SASL_FRAME_CODEC_01_041: [Once the sasl frame is decoded, the callback on_sasl_frame_received shall be called.] */
Azure.IoT Build 0:6ae2f7bca550 139 /* Codes_SRS_SASL_FRAME_CODEC_01_042: [The decoded sasl-frame value and the context passed in sasl_frame_codec_create shall be passed to on_sasl_frame_received.] */
Azure.IoT Build 0:6ae2f7bca550 140 sasl_frame_codec_instance->on_sasl_frame_received(sasl_frame_codec_instance->callback_context, sasl_frame_codec_instance->decoded_sasl_frame_value);
Azure.IoT Build 0:6ae2f7bca550 141 }
Azure.IoT Build 0:6ae2f7bca550 142 break;
Azure.IoT Build 0:6ae2f7bca550 143 }
Azure.IoT Build 0:6ae2f7bca550 144 }
Azure.IoT Build 0:6ae2f7bca550 145 }
Azure.IoT Build 0:6ae2f7bca550 146
Azure.IoT Build 0:6ae2f7bca550 147 static int encode_bytes(void* context, const unsigned char* bytes, size_t length)
Azure.IoT Build 0:6ae2f7bca550 148 {
Azure.IoT Build 0:6ae2f7bca550 149 PAYLOAD* payload = (PAYLOAD*)context;
Azure.IoT Build 0:6ae2f7bca550 150 (void)memcpy((unsigned char*)payload->bytes + payload->length, bytes, length);
Azure.IoT Build 0:6ae2f7bca550 151 payload->length += length;
Azure.IoT Build 0:6ae2f7bca550 152 return 0;
Azure.IoT Build 0:6ae2f7bca550 153 }
Azure.IoT Build 0:6ae2f7bca550 154
Azure.IoT Build 0:6ae2f7bca550 155 SASL_FRAME_CODEC_HANDLE sasl_frame_codec_create(FRAME_CODEC_HANDLE frame_codec, ON_SASL_FRAME_RECEIVED on_sasl_frame_received, ON_SASL_FRAME_CODEC_ERROR on_sasl_frame_codec_error, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 156 {
Azure.IoT Build 0:6ae2f7bca550 157 SASL_FRAME_CODEC_INSTANCE* result;
Azure.IoT Build 0:6ae2f7bca550 158
Azure.IoT Build 0:6ae2f7bca550 159 /* Codes_SRS_SASL_FRAME_CODEC_01_019: [If any of the arguments frame_codec, on_sasl_frame_received or on_sasl_frame_codec_error is NULL, sasl_frame_codec_create shall return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 160 if ((frame_codec == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 161 (on_sasl_frame_received == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 162 (on_sasl_frame_codec_error == NULL))
Azure.IoT Build 0:6ae2f7bca550 163 {
Azure.IoT Build 0:6ae2f7bca550 164 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 165 }
Azure.IoT Build 0:6ae2f7bca550 166 else
Azure.IoT Build 0:6ae2f7bca550 167 {
Azure.IoT Build 0:6ae2f7bca550 168 /* Codes_SRS_SASL_FRAME_CODEC_01_018: [sasl_frame_codec_create shall create an instance of an sasl_frame_codec and return a non-NULL handle to it.] */
Azure.IoT Build 0:6ae2f7bca550 169 result = (SASL_FRAME_CODEC_INSTANCE*)amqpalloc_malloc(sizeof(SASL_FRAME_CODEC_INSTANCE));
Azure.IoT Build 0:6ae2f7bca550 170 if (result != NULL)
Azure.IoT Build 0:6ae2f7bca550 171 {
Azure.IoT Build 0:6ae2f7bca550 172 result->frame_codec = frame_codec;
Azure.IoT Build 0:6ae2f7bca550 173 result->on_sasl_frame_received = on_sasl_frame_received;
Azure.IoT Build 0:6ae2f7bca550 174 result->on_sasl_frame_codec_error = on_sasl_frame_codec_error;
Azure.IoT Build 0:6ae2f7bca550 175 result->callback_context = callback_context;
Azure.IoT Build 0:6ae2f7bca550 176 result->decode_state = SASL_FRAME_DECODE_FRAME;
Azure.IoT Build 0:6ae2f7bca550 177
Azure.IoT Build 0:6ae2f7bca550 178 /* Codes_SRS_SASL_FRAME_CODEC_01_022: [sasl_frame_codec_create shall create a decoder to be used for decoding SASL values.] */
Azure.IoT Build 0:6ae2f7bca550 179 result->decoder = amqpvalue_decoder_create(amqp_value_decoded, result);
Azure.IoT Build 0:6ae2f7bca550 180 if (result->decoder == NULL)
Azure.IoT Build 0:6ae2f7bca550 181 {
Azure.IoT Build 0:6ae2f7bca550 182 /* Codes_SRS_SASL_FRAME_CODEC_01_023: [If creating the decoder fails, sasl_frame_codec_create shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 183 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 184 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 185 }
Azure.IoT Build 0:6ae2f7bca550 186 else
Azure.IoT Build 0:6ae2f7bca550 187 {
Azure.IoT Build 0:6ae2f7bca550 188 /* Codes_SRS_SASL_FRAME_CODEC_01_020: [sasl_frame_codec_create shall subscribe for SASL frames with the given frame_codec.] */
Azure.IoT Build 0:6ae2f7bca550 189 /* Codes_SRS_SASL_FRAME_CODEC_01_001: [A SASL frame has a type code of 0x01.] */
Azure.IoT Build 0:6ae2f7bca550 190 if (frame_codec_subscribe(frame_codec, FRAME_TYPE_SASL, frame_received, result) != 0)
Azure.IoT Build 0:6ae2f7bca550 191 {
Azure.IoT Build 0:6ae2f7bca550 192 /* Codes_SRS_SASL_FRAME_CODEC_01_021: [If subscribing for SASL frames fails, sasl_frame_codec_create shall fail and return NULL.] */
Azure.IoT Build 0:6ae2f7bca550 193 amqpvalue_decoder_destroy(result->decoder);
Azure.IoT Build 0:6ae2f7bca550 194 amqpalloc_free(result);
Azure.IoT Build 0:6ae2f7bca550 195 result = NULL;
Azure.IoT Build 0:6ae2f7bca550 196 }
Azure.IoT Build 0:6ae2f7bca550 197 }
Azure.IoT Build 0:6ae2f7bca550 198 }
Azure.IoT Build 0:6ae2f7bca550 199 }
Azure.IoT Build 0:6ae2f7bca550 200
Azure.IoT Build 0:6ae2f7bca550 201 return result;
Azure.IoT Build 0:6ae2f7bca550 202 }
Azure.IoT Build 0:6ae2f7bca550 203
Azure.IoT Build 0:6ae2f7bca550 204 void sasl_frame_codec_destroy(SASL_FRAME_CODEC_HANDLE sasl_frame_codec)
Azure.IoT Build 0:6ae2f7bca550 205 {
Azure.IoT Build 0:6ae2f7bca550 206 /* Codes_SRS_SASL_FRAME_CODEC_01_026: [If sasl_frame_codec is NULL, sasl_frame_codec_destroy shall do nothing.] */
Azure.IoT Build 0:6ae2f7bca550 207 if (sasl_frame_codec != NULL)
Azure.IoT Build 0:6ae2f7bca550 208 {
Azure.IoT Build 0:6ae2f7bca550 209 /* Codes_SRS_SASL_FRAME_CODEC_01_025: [sasl_frame_codec_destroy shall free all resources associated with the sasl_frame_codec instance.] */
Azure.IoT Build 0:6ae2f7bca550 210 SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)sasl_frame_codec;
Azure.IoT Build 0:6ae2f7bca550 211
Azure.IoT Build 0:6ae2f7bca550 212 /* Codes_SRS_SASL_FRAME_CODEC_01_027: [sasl_frame_codec_destroy shall unsubscribe from receiving SASL frames from the frame_codec that was passed to sasl_frame_codec_create.] */
Azure.IoT Build 0:6ae2f7bca550 213 (void)frame_codec_unsubscribe(sasl_frame_codec_instance->frame_codec, FRAME_TYPE_SASL);
Azure.IoT Build 0:6ae2f7bca550 214
Azure.IoT Build 0:6ae2f7bca550 215 /* Codes_SRS_SASL_FRAME_CODEC_01_028: [The decoder created in sasl_frame_codec_create shall be destroyed by sasl_frame_codec_destroy.] */
Azure.IoT Build 0:6ae2f7bca550 216 amqpvalue_decoder_destroy(sasl_frame_codec_instance->decoder);
Azure.IoT Build 0:6ae2f7bca550 217 amqpalloc_free(sasl_frame_codec_instance);
Azure.IoT Build 0:6ae2f7bca550 218 }
Azure.IoT Build 0:6ae2f7bca550 219 }
Azure.IoT Build 0:6ae2f7bca550 220
Azure.IoT Build 0:6ae2f7bca550 221 /* Codes_SRS_SASL_FRAME_CODEC_01_029: [sasl_frame_codec_encode_frame shall encode the frame header and sasl_frame_value AMQP value in a SASL frame and on success it shall return 0.] */
Azure.IoT Build 0:6ae2f7bca550 222 int sasl_frame_codec_encode_frame(SASL_FRAME_CODEC_HANDLE sasl_frame_codec, const AMQP_VALUE sasl_frame_value, ON_BYTES_ENCODED on_bytes_encoded, void* callback_context)
Azure.IoT Build 0:6ae2f7bca550 223 {
Azure.IoT Build 0:6ae2f7bca550 224 int result;
Azure.IoT Build 0:6ae2f7bca550 225 SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)sasl_frame_codec;
Azure.IoT Build 0:6ae2f7bca550 226
Azure.IoT Build 0:6ae2f7bca550 227 /* Codes_SRS_SASL_FRAME_CODEC_01_030: [If sasl_frame_codec or sasl_frame_value is NULL, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 228 if ((sasl_frame_codec == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 229 (sasl_frame_value == NULL))
Azure.IoT Build 0:6ae2f7bca550 230 {
Azure.IoT Build 0:6ae2f7bca550 231 /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 232 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 233 }
Azure.IoT Build 0:6ae2f7bca550 234 else
Azure.IoT Build 0:6ae2f7bca550 235 {
Azure.IoT Build 0:6ae2f7bca550 236 AMQP_VALUE descriptor;
Azure.IoT Build 0:6ae2f7bca550 237 uint64_t sasl_frame_descriptor_ulong;
Azure.IoT Build 0:6ae2f7bca550 238 size_t encoded_size;
Azure.IoT Build 0:6ae2f7bca550 239
Azure.IoT Build 0:6ae2f7bca550 240 if (((descriptor = amqpvalue_get_inplace_descriptor(sasl_frame_value)) == NULL) ||
Azure.IoT Build 0:6ae2f7bca550 241 (amqpvalue_get_ulong(descriptor, &sasl_frame_descriptor_ulong) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 242 /* Codes_SRS_SASL_FRAME_CODEC_01_047: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides=“sasl-frame”.] */
Azure.IoT Build 0:6ae2f7bca550 243 (sasl_frame_descriptor_ulong < SASL_MECHANISMS) ||
Azure.IoT Build 0:6ae2f7bca550 244 (sasl_frame_descriptor_ulong > SASL_OUTCOME))
Azure.IoT Build 0:6ae2f7bca550 245 {
Azure.IoT Build 0:6ae2f7bca550 246 /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 247 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 248 }
Azure.IoT Build 0:6ae2f7bca550 249 /* Codes_SRS_SASL_FRAME_CODEC_01_032: [The payload frame size shall be computed based on the encoded size of the sasl_frame_value and its fields.] */
Azure.IoT Build 0:6ae2f7bca550 250 /* Codes_SRS_SASL_FRAME_CODEC_01_033: [The encoded size of the sasl_frame_value and its fields shall be obtained by calling amqpvalue_get_encoded_size.] */
Azure.IoT Build 0:6ae2f7bca550 251 else if ((amqpvalue_get_encoded_size(sasl_frame_value, &encoded_size) != 0) ||
Azure.IoT Build 0:6ae2f7bca550 252 /* Codes_SRS_SASL_FRAME_CODEC_01_016: [The maximum size of a SASL frame is defined by MIN-MAX-FRAME-SIZE.] */
Azure.IoT Build 0:6ae2f7bca550 253 (encoded_size > MIX_MAX_FRAME_SIZE - 8))
Azure.IoT Build 0:6ae2f7bca550 254 {
Azure.IoT Build 0:6ae2f7bca550 255 /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 256 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 257 }
Azure.IoT Build 0:6ae2f7bca550 258 else
Azure.IoT Build 0:6ae2f7bca550 259 {
Azure.IoT Build 0:6ae2f7bca550 260 unsigned char* sasl_frame_bytes = (unsigned char*)amqpalloc_malloc(encoded_size);
Azure.IoT Build 0:6ae2f7bca550 261 if (sasl_frame_bytes == NULL)
Azure.IoT Build 0:6ae2f7bca550 262 {
Azure.IoT Build 0:6ae2f7bca550 263 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 264 }
Azure.IoT Build 0:6ae2f7bca550 265 else
Azure.IoT Build 0:6ae2f7bca550 266 {
AzureIoTClient 6:641a9672db08 267 PAYLOAD payload;
AzureIoTClient 6:641a9672db08 268
AzureIoTClient 6:641a9672db08 269 payload.bytes = sasl_frame_bytes;
AzureIoTClient 6:641a9672db08 270 payload.length = 0;
Azure.IoT Build 0:6ae2f7bca550 271
Azure.IoT Build 0:6ae2f7bca550 272 if (amqpvalue_encode(sasl_frame_value, encode_bytes, &payload) != 0)
Azure.IoT Build 0:6ae2f7bca550 273 {
Azure.IoT Build 0:6ae2f7bca550 274 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 275 }
Azure.IoT Build 0:6ae2f7bca550 276 else
Azure.IoT Build 0:6ae2f7bca550 277 {
Azure.IoT Build 0:6ae2f7bca550 278 /* Codes_SRS_SASL_FRAME_CODEC_01_031: [sasl_frame_codec_encode_frame shall encode the frame header and its contents by using frame_codec_encode_frame.] */
Azure.IoT Build 0:6ae2f7bca550 279 /* Codes_SRS_SASL_FRAME_CODEC_01_012: [Bytes 6 and 7 of the header are ignored.] */
Azure.IoT Build 0:6ae2f7bca550 280 /* Codes_SRS_SASL_FRAME_CODEC_01_013: [Implementations SHOULD set these to 0x00.] */
Azure.IoT Build 0:6ae2f7bca550 281 /* Codes_SRS_SASL_FRAME_CODEC_01_014: [The extended header is ignored.] */
Azure.IoT Build 0:6ae2f7bca550 282 /* Codes_SRS_SASL_FRAME_CODEC_01_015: [Implementations SHOULD therefore set DOFF to 0x02.] */
Azure.IoT Build 0:6ae2f7bca550 283 if (frame_codec_encode_frame(sasl_frame_codec_instance->frame_codec, FRAME_TYPE_SASL, &payload, 1, NULL, 0, on_bytes_encoded, callback_context) != 0)
Azure.IoT Build 0:6ae2f7bca550 284 {
Azure.IoT Build 0:6ae2f7bca550 285 /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */
Azure.IoT Build 0:6ae2f7bca550 286 result = __LINE__;
Azure.IoT Build 0:6ae2f7bca550 287 }
Azure.IoT Build 0:6ae2f7bca550 288 else
Azure.IoT Build 0:6ae2f7bca550 289 {
Azure.IoT Build 0:6ae2f7bca550 290 result = 0;
Azure.IoT Build 0:6ae2f7bca550 291 }
Azure.IoT Build 0:6ae2f7bca550 292 }
Azure.IoT Build 0:6ae2f7bca550 293
Azure.IoT Build 0:6ae2f7bca550 294 amqpalloc_free(sasl_frame_bytes);
Azure.IoT Build 0:6ae2f7bca550 295 }
Azure.IoT Build 0:6ae2f7bca550 296 }
Azure.IoT Build 0:6ae2f7bca550 297 }
Azure.IoT Build 0:6ae2f7bca550 298
Azure.IoT Build 0:6ae2f7bca550 299 return result;
Azure.IoT Build 0:6ae2f7bca550 300 }