core/cmd_interface/cmd_channel.h (65 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. #ifndef CMD_CHANNEL_H_ #define CMD_CHANNEL_H_ #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include "platform_api.h" #include "mctp/mctp_base_protocol.h" #include "status/rot_status.h" /** * The maximum size for a single packet sent or received through a command channel. */ #define CMD_MAX_PACKET_SIZE MCTP_BASE_PROTOCOL_MAX_PACKET_LEN /** * Valid states for a packet. */ enum { CMD_VALID_PACKET = 0, /**< Valid command packet. */ CMD_OVERFLOW_PACKET, /**< This packet is part of an overflow condition. */ CMD_NACK_PACKET, /**< NACK should be sent, disregard packet data. */ CMD_NO_RESPONSE, /**< No response needed. */ CMD_RX_ERROR, /**< There was a channel error while receiving the packet data. */ }; /** * Information for a single command packet. */ struct cmd_packet { uint8_t data[CMD_MAX_PACKET_SIZE]; /**< Buffer for packet data. */ size_t pkt_size; /**< Total size of the packet data. */ uint8_t dest_addr; /**< The destination address for the packet. This is assumed to be a 7-bit address compatible with I2C. */ uint8_t state; /**< The packet state. */ platform_clock pkt_timeout; /**< Time at which processing for the packet must be completed. */ bool timeout_valid; /**< Flag indicating if a packet timeout has been set. */ }; /** * Information for a single command message. */ struct cmd_message { uint8_t *data; /**< Buffer for the message data. */ size_t msg_size; /**< Total size of the message data. */ size_t pkt_size; /**< Size of each packet in the message. */ uint8_t dest_addr; /**< The destination address for the message. */ }; struct mctp_interface; /** * Variable state context for the command channel interface */ struct cmd_channel_state { platform_mutex lock; /**< Synchronization for message transmission. */ bool overflow; /**< Flag if the channel is in an overflow condition. */ }; /** * Defines the interface for a communication channel to send and receive command packets. * * Channels must be implemented to allow for simultaneous receive and send calls. This will * enable senders to be transmitting messages while the channel is blocked waiting to receive * packets. */ struct cmd_channel { /** * Receive a command packet from a communication channel. This call will block until a packet * has been received or the timeout has expired. * * @param channel The channel to receive a packet from. * @param packet Output for the packet data being received. * @param ms_timeout The amount of time to wait for a received packet, in milliseconds. A * negative value will wait forever, and a value of 0 will return immediately. * * @return 0 if a packet was successfully received or an error code. */ int (*receive_packet) (const struct cmd_channel *channel, struct cmd_packet *packet, int ms_timeout); /** * Send a command packet over a communication channel. * * Returning from this function does not guarantee the packet has been fully transmitted. * Depending on the channel implementation, it is possible the packet is still in flight with * the data buffered in the channel driver. * * @param channel The channel to send a packet on. * @param packet The packet to send. * * @return 0 if the the packet was successfully sent or an error code. */ int (*send_packet) (const struct cmd_channel *channel, const struct cmd_packet *packet); struct cmd_channel_state *state; /**< Variable context for the command channel. */ int id; /**< ID for the command channel. */ }; int cmd_channel_get_id (const struct cmd_channel *channel); int cmd_channel_validate_packet_for_send (const struct cmd_packet *packet); int cmd_channel_receive_and_process (const struct cmd_channel *channel, const struct mctp_interface *mctp, int ms_timeout); int cmd_channel_send_message (const struct cmd_channel *channel, const struct cmd_message *message); /* Internal functions for use by derived types. */ int cmd_channel_init (struct cmd_channel *channel, struct cmd_channel_state *state, int id); int cmd_channel_init_state (const struct cmd_channel *channel); void cmd_channel_release (const struct cmd_channel *channel); #define CMD_CHANNEL_ERROR(code) ROT_ERROR (ROT_MODULE_CMD_CHANNEL, code) /** * Error codes that can be generated by a command channel. */ enum { CMD_CHANNEL_INVALID_ARGUMENT = CMD_CHANNEL_ERROR (0x00), /**< Input parameter is null or not valid. */ CMD_CHANNEL_NO_MEMORY = CMD_CHANNEL_ERROR (0x01), /**< Memory allocation failed. */ CMD_CHANNEL_RX_FAILED = CMD_CHANNEL_ERROR (0x02), /**< Error receiving a packet. */ CMD_CHANNEL_TX_FAILED = CMD_CHANNEL_ERROR (0x03), /**< Error sending a packet. */ CMD_CHANNEL_RX_TIMEOUT = CMD_CHANNEL_ERROR (0x04), /**< No packet was received within the specified time. */ CMD_CHANNEL_TX_TIMEOUT = CMD_CHANNEL_ERROR (0x05), /**< Packet transmission timed out. */ CMD_CHANNEL_PKT_OVERFLOW = CMD_CHANNEL_ERROR (0x06), /**< Packet overflow encountered. */ CMD_CHANNEL_INVALID_PKT_STATE = CMD_CHANNEL_ERROR (0x07), /**< Packet state is not valid. */ CMD_CHANNEL_PKT_EXPIRED = CMD_CHANNEL_ERROR (0x08), /**< The timeout on a received packet has expired. */ CMD_CHANNEL_INVALID_PKT_SIZE = CMD_CHANNEL_ERROR (0x09), /**< The packet size is larger than the buffer. */ CMD_CHANNEL_TX_ABORTED = CMD_CHANNEL_ERROR (0x0a), /**< Packet transmission was aborted. */ }; #endif /* CMD_CHANNEL_H_ */