Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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