in common/recipes-core/asd_1.4.3/files/daemon/asd_msg.c [2095:2274]
STATUS process_i2c_messages(ASD_MSG* state, struct asd_message* in_msg)
{
int response_cnt = 0;
STATUS status;
int size;
struct packet_data packet;
uint8_t* data_ptr;
uint8_t cmd;
bool i2c_command_pending = false;
bool force_stop = false;
if (!state || !in_msg)
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C, ASD_LogOption_None,
"Invalid process_i2c_messages input.");
return ST_ERR;
}
I2C_Msg_Builder* builder = I2CMsgBuilder();
if (!builder)
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C, ASD_LogOption_None,
"Invalid process_i2c_messages input.");
status = ST_ERR;
}
else
{
size = get_message_size(in_msg);
if (size == -1)
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C, ASD_LogOption_None,
"Failed to process i2c message because "
"get message size failed.");
status = ST_ERR;
}
else
{
memset(&state->out_msg.header, 0, sizeof(struct message_header));
memset(&state->out_msg.buffer, 0, MAX_DATA_SIZE);
if (memcpy_safe(&state->out_msg.header,
sizeof(struct message_header), &in_msg->header,
sizeof(struct message_header)))
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_JTAG,
ASD_LogOption_None, "memcpy_safe: message header to \
out msg header copy failed.");
}
status = i2c_msg_initialize(builder);
if (status != ST_OK)
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C,
ASD_LogOption_None,
"Failed to initialize i2c msg builder.");
}
else
{
#ifdef ENABLE_DEBUG_LOGGING
ASD_log(ASD_LogLevel_Debug, ASD_LogStream_I2C,
ASD_LogOption_None, "NetReq tag: %d size: %d",
in_msg->header.tag, size);
ASD_log_buffer(ASD_LogLevel_Debug, ASD_LogStream_I2C,
ASD_LogOption_None, in_msg->buffer, (size_t)size,
"NetReq");
#endif
packet.next_data = in_msg->buffer;
packet.used = 0;
packet.total = size;
while (packet.used < packet.total)
{
data_ptr = get_packet_data(&packet, 1);
cmd = *data_ptr;
if (cmd == I2C_WRITE_CFG_BUS_SELECT)
{
status =
do_bus_select_command(state->i2c_handler, &packet);
}
else if (cmd == I2C_WRITE_CFG_SCLK)
{
status =
do_set_sclk_command(state->i2c_handler, &packet);
}
else if (cmd >= I2C_READ_MIN && cmd <= I2C_READ_MAX)
{
status =
do_read_command(cmd, builder, &packet, &force_stop);
i2c_command_pending = true;
}
else if (cmd >= I2C_WRITE_MIN && cmd <= I2C_WRITE_MAX)
{
status = do_write_command(cmd, builder, &packet,
&force_stop);
i2c_command_pending = true;
}
else
{
// Unknown Command
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C,
ASD_LogOption_None,
"Encountered unknown i2c command 0x%02x",
(int)cmd);
status = ST_ERR;
break;
}
if (status != ST_OK)
break;
// if a i2c command is pending and
// either we are done looping through
// all commands, or the force stop bit
// was set, then we need to also flush
// the commands
if (i2c_command_pending &&
((packet.used == packet.total) || force_stop))
{
i2c_command_pending = false;
force_stop = false;
status = i2c_read_write(state->i2c_handler,
builder->msg_set);
if (status != ST_OK)
{
ASD_log(ASD_LogLevel_Error, ASD_LogStream_I2C,
ASD_LogOption_None,
"i2c_read_write failed, %d, assuming NAK",
status);
}
status = build_responses(state, &response_cnt, builder,
(status == ST_OK));
if (status != ST_OK)
{
ASD_log(
ASD_LogLevel_Error, ASD_LogStream_I2C,
ASD_LogOption_None,
"i2c_read_write failed to parse i2c responses"
", %d",
status);
break;
}
status = i2c_msg_reset(builder);
if (status != ST_OK)
{
ASD_log(
ASD_LogLevel_Error, ASD_LogStream_I2C,
ASD_LogOption_None,
"i2c_msg_reset failed to reset response builder"
", %d",
status);
break;
}
}
}
}
}
}
if (status == ST_OK)
{
state->out_msg.header.size_lsb = (uint32_t)(response_cnt & 0xFF);
state->out_msg.header.size_msb = (uint32_t)((response_cnt >> 8) & 0x1F);
state->out_msg.header.cmd_stat = ASD_SUCCESS;
status = send_response(state, &state->out_msg);
if (status != ST_OK)
{
ASD_log(ASD_LogLevel_Error | ASD_LogOption_No_Remote,
ASD_LogStream_I2C, ASD_LogOption_None,
"Failed to send message back on the socket - "
"process_i2c_message");
}
}
if (builder)
{
i2c_msg_deinitialize(builder);
free(builder);
}
return status;
}