in src/connection.c [280:450]
static int send_open_frame(CONNECTION_HANDLE connection)
{
int result;
/* Codes_S_R_S_CONNECTION_01_151: [The connection max_frame_size setting shall be passed down to the frame_codec when the Open frame is sent.] */
if (frame_codec_set_max_frame_size(connection->frame_codec, connection->max_frame_size) != 0)
{
LogError("Cannot set max frame size");
/* Codes_S_R_S_CONNECTION_01_207: [If frame_codec_set_max_frame_size fails the connection shall be closed and the state set to END.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
/* Codes_S_R_S_CONNECTION_01_134: [The container id field shall be filled with the container id specified in connection_create.] */
OPEN_HANDLE open_performative = open_create(connection->container_id);
if (open_performative == NULL)
{
LogError("Cannot create OPEN performative");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
/* Codes_S_R_S_CONNECTION_01_137: [The max_frame_size connection setting shall be set in the open frame by using open_set_max_frame_size.] */
if (open_set_max_frame_size(open_performative, connection->max_frame_size) != 0)
{
LogError("Cannot set max frame size");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
/* Codes_S_R_S_CONNECTION_01_139: [The channel_max connection setting shall be set in the open frame by using open_set_channel_max.] */
else if (open_set_channel_max(open_performative, connection->channel_max) != 0)
{
LogError("Cannot set max channel");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
/* Codes_S_R_S_CONNECTION_01_142: [If no idle_timeout value has been specified, no value shall be stamped in the open frame (no call to open_set_idle_time_out shall be made).] */
else if ((connection->idle_timeout_specified) &&
/* Codes_S_R_S_CONNECTION_01_141: [If idle_timeout has been specified by a call to connection_set_idle_timeout, then that value shall be stamped in the open frame.] */
(open_set_idle_time_out(open_performative, connection->idle_timeout) != 0))
{
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
/* Codes_S_R_S_CONNECTION_01_136: [If no hostname value has been specified, no value shall be stamped in the open frame (no call to open_set_hostname shall be made).] */
else if ((connection->host_name != NULL) &&
/* Codes_S_R_S_CONNECTION_01_135: [If hostname has been specified by a call to connection_set_hostname, then that value shall be stamped in the open frame.] */
(open_set_hostname(open_performative, connection->host_name) != 0))
{
LogError("Cannot set hostname");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
/* Codes_S_R_S_CONNECTION_01_243: [If no properties value has been specified, no value shall be stamped in the open frame (no call to open_set_properties shall be made).] */
else if ((connection->properties != NULL) &&
/* Codes_S_R_S_CONNECTION_01_244: [If properties has been specified by a call to connection_set_properties, then that value shall be stamped in the open frame.] */
(open_set_properties(open_performative, connection->properties) != 0))
{
LogError("Cannot set properties");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
AMQP_VALUE open_performative_value = amqpvalue_create_open(open_performative);
if (open_performative_value == NULL)
{
LogError("Cannot create OPEN AMQP value");
/* Codes_S_R_S_CONNECTION_01_208: [If the open frame cannot be constructed, the connection shall be closed and set to the END state.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
/* Codes_S_R_S_CONNECTION_01_002: [Each AMQP connection begins with an exchange of capabilities and limitations, including the maximum frame size.] */
/* Codes_S_R_S_CONNECTION_01_004: [After establishing or accepting a TCP connection and sending the protocol header, each peer MUST send an open frame before sending any other frames.] */
/* Codes_S_R_S_CONNECTION_01_005: [The open frame describes the capabilities and limits of that peer.] */
/* Codes_S_R_S_CONNECTION_01_205: [Sending the AMQP OPEN frame shall be done by calling amqp_frame_codec_begin_encode_frame with channel number 0, the actual performative payload and 0 as payload_size.] */
/* Codes_S_R_S_CONNECTION_01_006: [The open frame can only be sent on channel 0.] */
connection->on_send_complete = NULL;
connection->on_send_complete_callback_context = NULL;
if (amqp_frame_codec_encode_frame(connection->amqp_frame_codec, 0, open_performative_value, NULL, 0, on_bytes_encoded, connection) != 0)
{
LogError("amqp_frame_codec_encode_frame failed");
/* Codes_S_R_S_CONNECTION_01_206: [If sending the frame fails, the connection shall be closed and state set to END.] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
if (connection->is_trace_on == 1)
{
log_outgoing_frame(open_performative_value);
}
/* Codes_S_R_S_CONNECTION_01_046: [OPEN SENT In this state the connection headers have been exchanged. An open frame has been sent to the peer but no open frame has yet been received.] */
connection_set_state(connection, CONNECTION_STATE_OPEN_SENT);
result = 0;
}
amqpvalue_destroy(open_performative_value);
}
}
open_destroy(open_performative);
}
}
return result;
}