/* 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.] */ 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) { int result; SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)sasl_frame_codec; /* 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.] */ if ((sasl_frame_codec == NULL) || (sasl_frame_value == NULL)) { /* 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.] */ result = __LINE__; } else { AMQP_VALUE descriptor; uint64_t sasl_frame_descriptor_ulong; size_t encoded_size; if (((descriptor = amqpvalue_get_inplace_descriptor(sasl_frame_value)) == NULL) || (amqpvalue_get_ulong(descriptor, &sasl_frame_descriptor_ulong) != 0) || /* 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”.] */ (sasl_frame_descriptor_ulong < SASL_MECHANISMS) || (sasl_frame_descriptor_ulong > SASL_OUTCOME)) { /* 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.] */ result = __LINE__; } /* 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.] */ /* 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.] */ else if ((amqpvalue_get_encoded_size(sasl_frame_value, &encoded_size) != 0) || /* Codes_SRS_SASL_FRAME_CODEC_01_016: [The maximum size of a SASL frame is defined by MIN-MAX-FRAME-SIZE.] */ (encoded_size > MIX_MAX_FRAME_SIZE - 8)) { /* 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.] */ result = __LINE__; } else { unsigned char* sasl_frame_bytes = (unsigned char*)amqpalloc_malloc(encoded_size); if (sasl_frame_bytes == NULL) { result = __LINE__; } else { PAYLOAD payload; payload.bytes = sasl_frame_bytes; payload.length = 0; if (amqpvalue_encode(sasl_frame_value, encode_bytes, &payload) != 0) { result = __LINE__; } else { /* 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.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_012: [Bytes 6 and 7 of the header are ignored.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_013: [Implementations SHOULD set these to 0x00.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_014: [The extended header is ignored.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_015: [Implementations SHOULD therefore set DOFF to 0x02.] */ if (frame_codec_encode_frame(sasl_frame_codec_instance->frame_codec, FRAME_TYPE_SASL, &payload, 1, NULL, 0, on_bytes_encoded, callback_context) != 0) { /* 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.] */ result = __LINE__; } else { result = 0; } } amqpalloc_free(sasl_frame_bytes); } } } return result; }
static SEND_ONE_MESSAGE_RESULT send_one_message(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_WITH_CALLBACK* message_with_callback, MESSAGE_HANDLE message) { SEND_ONE_MESSAGE_RESULT result; size_t encoded_size; size_t total_encoded_size = 0; MESSAGE_BODY_TYPE message_body_type; message_format message_format; if ((message_get_body_type(message, &message_body_type) != 0) || (message_get_message_format(message, &message_format) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { // header HEADER_HANDLE header; AMQP_VALUE header_amqp_value; PROPERTIES_HANDLE properties; AMQP_VALUE properties_amqp_value; AMQP_VALUE application_properties; AMQP_VALUE application_properties_value; AMQP_VALUE body_amqp_value = NULL; size_t body_data_count; message_get_header(message, &header); header_amqp_value = amqpvalue_create_header(header); if (header != NULL) { amqpvalue_get_encoded_size(header_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // properties message_get_properties(message, &properties); properties_amqp_value = amqpvalue_create_properties(properties); if (properties != NULL) { amqpvalue_get_encoded_size(properties_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // application properties message_get_application_properties(message, &application_properties); application_properties_value = amqpvalue_create_application_properties(application_properties); if (application_properties != NULL) { amqpvalue_get_encoded_size(application_properties_value, &encoded_size); total_encoded_size += encoded_size; } result = SEND_ONE_MESSAGE_OK; // body - amqp data switch (message_body_type) { default: result = SEND_ONE_MESSAGE_ERROR; break; case MESSAGE_BODY_TYPE_VALUE: { AMQP_VALUE message_body_amqp_value; if (message_get_inplace_body_amqp_value(message, &message_body_amqp_value) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { body_amqp_value = amqpvalue_create_amqp_value(message_body_amqp_value); if ((body_amqp_value == NULL) || (amqpvalue_get_encoded_size(body_amqp_value, &encoded_size) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } } break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; if (message_get_body_amqp_data_count(message, &body_data_count) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_get_encoded_size(body_amqp_data, &encoded_size) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } amqpvalue_destroy(body_amqp_data); } } } } break; } } if (result == 0) { void* data_bytes = amqpalloc_malloc(total_encoded_size); PAYLOAD payload = { data_bytes, 0 }; result = SEND_ONE_MESSAGE_OK; if (header != NULL) { if (amqpvalue_encode(header_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Header:", header_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (properties != NULL)) { if (amqpvalue_encode(properties_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Properties:", properties_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (application_properties != NULL)) { if (amqpvalue_encode(application_properties_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Application properties:", application_properties_value); } if (result == SEND_ONE_MESSAGE_OK) { switch (message_body_type) { case MESSAGE_BODY_TYPE_VALUE: { if (amqpvalue_encode(body_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Body - amqp value:", body_amqp_value); break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_encode(body_amqp_data, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; break; } amqpvalue_destroy(body_amqp_data); } } } break; } } } if (result == SEND_ONE_MESSAGE_OK) { message_with_callback->message_send_state = MESSAGE_SEND_STATE_PENDING; switch (link_transfer(message_sender_instance->link, message_format, &payload, 1, on_delivery_settled, message_with_callback)) { default: case LINK_TRANSFER_ERROR: if (message_with_callback->on_message_send_complete != NULL) { message_with_callback->on_message_send_complete(message_with_callback->context, MESSAGE_SEND_ERROR); } result = SEND_ONE_MESSAGE_ERROR; break; case LINK_TRANSFER_BUSY: message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT; result = SEND_ONE_MESSAGE_BUSY; break; case LINK_TRANSFER_OK: result = SEND_ONE_MESSAGE_OK; break; } } amqpalloc_free(data_bytes); if (body_amqp_value != NULL) { amqpvalue_destroy(body_amqp_value); } amqpvalue_destroy(application_properties); amqpvalue_destroy(application_properties_value); amqpvalue_destroy(properties_amqp_value); properties_destroy(properties); } } return result; }
int amqp_frame_codec_encode_frame(AMQP_FRAME_CODEC_HANDLE amqp_frame_codec, uint16_t channel, const AMQP_VALUE performative, const PAYLOAD* payloads, size_t payload_count, ON_BYTES_ENCODED on_bytes_encoded, void* callback_context) { int result; /* Codes_SRS_AMQP_FRAME_CODEC_01_024: [If frame_codec, performative or on_bytes_encoded is NULL, amqp_frame_codec_encode_frame shall fail and return a non-zero value.] */ if ((amqp_frame_codec == NULL) || (performative == NULL) || (on_bytes_encoded == NULL)) { result = __LINE__; } else { AMQP_VALUE descriptor; uint64_t performative_ulong; size_t encoded_size; if (((descriptor = amqpvalue_get_inplace_descriptor(performative)) == NULL) || (amqpvalue_get_ulong(descriptor, &performative_ulong) != 0) || /* Codes_SRS_AMQP_FRAME_CODEC_01_008: [The performative MUST be one of those defined in section 2.7 and is encoded as a described type in the AMQP type system.] */ (performative_ulong < AMQP_OPEN) || (performative_ulong > AMQP_CLOSE)) { /* Codes_SRS_AMQP_FRAME_CODEC_01_029: [If any error occurs during encoding, amqp_frame_codec_encode_frame shall fail and return a non-zero value.] */ result = __LINE__; } /* Codes_SRS_AMQP_FRAME_CODEC_01_027: [The encoded size of the performative and its fields shall be obtained by calling amqpvalue_get_encoded_size.] */ else if (amqpvalue_get_encoded_size(performative, &encoded_size) != 0) { /* Codes_SRS_AMQP_FRAME_CODEC_01_029: [If any error occurs during encoding, amqp_frame_codec_encode_frame shall fail and return a non-zero value.] */ result = __LINE__; } else { unsigned char* amqp_performative_bytes = (unsigned char*)amqpalloc_malloc(encoded_size); if (amqp_performative_bytes == NULL) { result = __LINE__; } else { PAYLOAD* new_payloads = (PAYLOAD*)amqpalloc_malloc(sizeof(PAYLOAD) * (payload_count + 1)); if (new_payloads == NULL) { result = __LINE__; } else { /* Codes_SRS_AMQP_FRAME_CODEC_01_070: [The payloads argument for frame_codec_encode_frame shall be made of the payload for the encoded performative and the payloads passed to amqp_frame_codec_encode_frame.] */ /* Codes_SRS_AMQP_FRAME_CODEC_01_028: [The encode result for the performative shall be placed in a PAYLOAD structure.] */ new_payloads[0].bytes = amqp_performative_bytes; new_payloads[0].length = 0; if (payload_count > 0) { (void)memcpy(new_payloads + 1, payloads, sizeof(PAYLOAD) * payload_count); } if (amqpvalue_encode(performative, encode_bytes, &new_payloads[0]) != 0) { result = __LINE__; } else { unsigned char channel_bytes[2]; channel_bytes[0] = channel >> 8; channel_bytes[1] = channel & 0xFF; /* Codes_SRS_AMQP_FRAME_CODEC_01_005: [Bytes 6 and 7 of an AMQP frame contain the channel number ] */ /* Codes_SRS_AMQP_FRAME_CODEC_01_025: [amqp_frame_codec_encode_frame shall encode the frame header by using frame_codec_encode_frame.] */ /* Codes_SRS_AMQP_FRAME_CODEC_01_006: [The frame body is defined as a performative followed by an opaque payload.] */ if (frame_codec_encode_frame(amqp_frame_codec->frame_codec, FRAME_TYPE_AMQP, new_payloads, payload_count + 1, channel_bytes, sizeof(channel_bytes), on_bytes_encoded, callback_context) != 0) { /* Codes_SRS_AMQP_FRAME_CODEC_01_029: [If any error occurs during encoding, amqp_frame_codec_encode_frame shall fail and return a non-zero value.] */ result = __LINE__; } else { /* Codes_SRS_AMQP_FRAME_CODEC_01_022: [amqp_frame_codec_begin_encode_frame shall encode the frame header and AMQP performative in an AMQP frame and on success it shall return 0.] */ result = 0; } } amqpalloc_free(new_payloads); } amqpalloc_free(amqp_performative_bytes); } } } return result; }