static int connection_byte_received()

in src/connection.c [630:713]


static int connection_byte_received(CONNECTION_HANDLE connection, unsigned char b)
{
    int result;

    switch (connection->connection_state)
    {
    default:
        LogError("Unknown connection state: %d", (int)connection->connection_state);
        result = MU_FAILURE;
        break;

    /* Codes_S_R_S_CONNECTION_01_039: [START In this state a connection exists, but nothing has been sent or received. This is the state an implementation would be in immediately after performing a socket connect or socket accept.] */
    case CONNECTION_STATE_START:

    /* Codes_S_R_S_CONNECTION_01_041: [HDR SENT In this state the connection header has been sent to the peer but no connection header has been received.] */
    case CONNECTION_STATE_HDR_SENT:
        if (b != amqp_header[connection->header_bytes_received])
        {
            /* Codes_S_R_S_CONNECTION_01_089: [If the incoming and outgoing protocol headers do not match, both peers MUST close their outgoing stream] */
            if (xio_close(connection->io, NULL, NULL) != 0)
            {
                LogError("xio_close failed");
            }

            connection_set_state(connection, CONNECTION_STATE_END);
            result = MU_FAILURE;
        }
        else
        {
            connection->header_bytes_received++;
            if (connection->header_bytes_received == sizeof(amqp_header))
            {
                if (connection->is_trace_on == 1)
                {
                    LOG(AZ_LOG_TRACE, LOG_LINE, "<- Header (AMQP 0.1.0.0)");
                }

                connection_set_state(connection, CONNECTION_STATE_HDR_EXCH);

                if (send_open_frame(connection) != 0)
                {
                    LogError("Cannot send open frame");
                    connection_set_state(connection, CONNECTION_STATE_END);
                }
            }

            result = 0;
        }
        break;

    /* Codes_S_R_S_CONNECTION_01_040: [HDR RCVD In this state the connection header has been received from the peer but a connection header has not been sent.] */
    case CONNECTION_STATE_HDR_RCVD:

    /* Codes_S_R_S_CONNECTION_01_042: [HDR EXCH In this state the connection header has been sent to the peer and a connection header has been received from the peer.] */
    /* we should not really get into this state, but just in case, we would treat that in the same way as HDR_RCVD */
    case CONNECTION_STATE_HDR_EXCH:

    /* Codes_S_R_S_CONNECTION_01_045: [OPEN RCVD In this state the connection headers have been exchanged. An open frame has been received from the peer but an open frame has not been sent.] */
    case CONNECTION_STATE_OPEN_RCVD:

    /* 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.] */
    case CONNECTION_STATE_OPEN_SENT:

    /* Codes_S_R_S_CONNECTION_01_048: [OPENED In this state the connection header and the open frame have been both sent and received.] */
    case CONNECTION_STATE_OPENED:
        /* Codes_S_R_S_CONNECTION_01_212: [After the initial handshake has been done all bytes received from the io instance shall be passed to the frame_codec for decoding by calling frame_codec_receive_bytes.] */
        if (frame_codec_receive_bytes(connection->frame_codec, &b, 1) != 0)
        {
            LogError("Cannot process received bytes");
            /* Codes_S_R_S_CONNECTION_01_218: [The error amqp:internal-error shall be set in the error.condition field of the CLOSE frame.] */
            /* Codes_S_R_S_CONNECTION_01_219: [The error description shall be set to an implementation defined string.] */
            close_connection_with_error(connection, "amqp:internal-error", "connection_byte_received::frame_codec_receive_bytes failed", NULL);
            result = MU_FAILURE;
        }
        else
        {
            result = 0;
        }

        break;
    }

    return result;
}