MCTP-release/main.h

884 lines
21 KiB
C
Raw Normal View History

2024-04-02 05:00:08 +00:00
/* SPDX-License-Identifier: Apache-2.0 */
/**
* @file mctp.h
*
* @brief Header file for MCTP transport library
*
* @details As per MCTP specification, all MCTP fields are Big Endian
*
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
*
* @date Jan 2024
* @author Barrett Edwards <code@jrlabs.io>
*
* Macro / Enumeration Prefixes
* MCCC - MCTP Control Completion Codes (CC)
* MCCM - MCTP Control Command IDs (CM)
* MCEP - MCTP Control - Get Endpoint EID - Endpoint Typea (EP)
* MCID - Special Endpoint ID values (ID)
* MCIT - MCTP Control - Get Endpoint EID - Endpoint ID Type (IT)
* MCMT - MCTP Message Type Codes (MT)
* MCRM - Run Mode for the MCTP Threads (RM)
* MCSE - MCTP Control Set EID Operations (SE)
* MCLN - Message Data Lengths for MCTP Control Messages (LN)
*
*/
#ifndef _MCTP_H
#define _MCTP_H
/* INCLUDES ==================================================================*/
/* __u8
* __u32
*/
#include <linux/types.h>
/* useconds_t
*/
#include <unistd.h>
/* struct sockaddr_in
*/
#include <netinet/in.h>
/* uuid_t
*/
#include <uuid/uuid.h>
/* timepsec
*/
#include <time.h>
/* sem_t
*/
#include <semaphore.h>
/* MACROS ====================================================================*/
// Serialized length of MCTP Header
#define MCLN_HDR 4
// Serialized length of MCTP BTU
#define MCLN_BTU 64
// Serialized length of MCTP Packet
#define MCLN_PKT (MCLN_HDR + MCLN_BTU)
// Serialized length of MCTP Type
#define MCLN_TYPE 1
// Serialized length of MCTP Control UUID
#define MCLN_UUID 16
#define MCLN_MSG_PAYLOAD 8192
#define MCLN_MSG (MCLN_HDR + MCLN_TYPE + MCLN_MSG_PAYLOAD)
#define MCTP_MAX_INPROCESS_MESSAGES 8
#define MCTP_MAX_PACKET_NUM 1024
#define MCTP_MAX_MESSAGE_NUM 16
#define MCTP_NUM_TAGS 8
#define MCTP_RPQ_SIZE 1024
#define MCTP_TPQ_SIZE 1024
#define MCTP_RMQ_SIZE 128
#define MCTP_TMQ_SIZE 128
#define MCTP_TAQ_SIZE 128
#define MCTP_ACQ_SIZE 128
#define MCTP_PKT_POOL_SIZE 1024
#define MCTP_MSG_POOL_SIZE 128
#define MCTP_ACTION_POOL_SIZE 128
#define MCTP_ACTION_DEFAULT_RETRY_NUM 8
// Verbose bit fields
#define MCTP_VERBOSE_ERROR (0x01 << 0)
#define MCTP_VERBOSE_THREADS (0x01 << 1)
#define MCTP_VERBOSE_STEPS (0x01 << 2)
#define MCTP_VERBOSE_PACKET (0x01 << 3)
#define MCTP_VERBOSE_MESSAGE (0x01 << 4)
/* Action Macros */
#define MCTP_ACTION_DELTA_SEC 0
#define MCTP_ACTION_DELTA_NSEC 100000000
/* Threads Macros */
#define MCTP_THREAD_ERROR_USLEEP 1000
#define MCTP_THREAD_SUBMIT_NSLEEP 1000000
/* MCTP Control Macros */
#define SET_EID_ACCEPTED 0
#define SET_EID_REJECTED 1
// Length of MCTP_VERSIONS[] array
#define MCTP_VERSIONS_NUM 4
/**
* Message Data Lengths for MCTP Control Messages (LN)
* The Response lengths include the 1 byte completion code length
*/
#define MCLN_CTRL 2
#define MCLN_CTRL_SET_EID_REQ 2
#define MCLN_CTRL_SET_EID_RESP 4
#define MCLN_CTRL_GET_EID_REQ 0
#define MCLN_CTRL_GET_EID_RESP 4
#define MCLN_CTRL_GET_UUID_REQ 0
#define MCLN_CTRL_GET_UUID_RESP 17
#define MCLN_CTRL_GET_VER_SUPPORT_REQ 1
#define MCLN_CTRL_GET_VER_SUPPORT_RESP 2
#define MCLN_CTRL_GET_MSG_TYPE_SUPPORT_REQ 0
#define MCLN_CTRL_GET_MSG_TYPE_SUPPORT_RESP 2
/* ENUMERATIONS ==============================================================*/
/*
* MCTP Message Type Codes (MT)
*
* See DSP0239 v1.9.0 Table 1.
*/
enum _MCMT
{
MCMT_CONTROL = 0x00,
MCMT_PLDM = 0x01,
MCMT_NCSI = 0x02,
MCMT_ETHERNET = 0x03,
MCMT_NVMEMI = 0x04,
MCMT_SPDM = 0x05,
MCMT_SECURE = 0x06,
MCMT_CXLFMAPI = 0x07,
MCMT_CXLCCI = 0x08,
MCMT_CSE = 0x70,
MCMT_VDM_PCI = 0x7E,
MCMT_VDM_IANA = 0x7F,
MCMT_MAX = 0xFF
};
#define MCMT_BASE 0xFF
/**
* MCTP Threads Run Mode (RM)
*/
enum _MCRM
{
MCRM_SERVER = 0,
MCRM_CLIENT = 1,
MCRM_MAX
};
/*
* MCTP Control Completion Codes (CC)
*
* See DSP0236 v1.3.0 Table 13.
*/
enum _MCCC
{
MCCC_SUCCESS = 0x00,
MCCC_ERROR = 0x01,
MCCC_ERROR_INVALID_DATA = 0x02,
MCCC_ERROR_INVALID_LENGTH = 0x03,
MCCC_ERROR_NOT_READY = 0x04,
MCCC_ERROR_UNSUPPORTED_CMD = 0x05,
MCCC_MAX = 0x06
/* 0x80 - 0xFF are command specific */
};
/*
* MCTP Control Command IDs (CM)
*
* See DSP0236 v1.3.0 Table 12.
*/
enum _MCCM
{
MCCM_RESERVED = 0x00,
MCCM_SET_ENDPOINT_ID = 0x01,
MCCM_GET_ENDPOINT_ID = 0x02,
MCCM_GET_ENDPOINT_UUID = 0x03,
MCCM_GET_VERSION_SUPPORT = 0x04,
MCCM_GET_MESSAGE_TYPE_SUPPORT = 0x05,
MCCM_GET_VENDOR_MESSAGE_SUPPORT = 0x06,
MCCM_RESOLVE_ENDPOINT_ID = 0x07,
MCCM_ALLOCATE_ENDPOINT_IDS = 0x08,
MCCM_ROUTING_INFO_UPDATE = 0x09,
MCCM_GET_ROUTING_TABLE_ENTRIES = 0x0A,
MCCM_PREPARE_ENDPOINT_DISCOVERY = 0x0B,
MCCM_ENDPOINT_DISCOVERY = 0x0C,
MCCM_DISCOVERY_NOTIFY = 0x0D,
MCCM_GET_NETWORK_ID = 0x0E,
MCCM_QUERY_HOP = 0x0F,
MCCM_RESOLVE_UUID = 0x10,
MCCM_QUERY_RATE_LIMIT = 0x11,
MCCM_REQUEST_TX_RATE_LIMIT = 0x12,
MCCM_UPDATE_RATE_LIMIT = 0x13,
MCCM_QUERY_SUPPORTED_INTERFACES = 0x14,
MCCM_MAX = 0x15
/* 0xF0 - 0xFF are transport specific */
};
/*
* MCTP Control - Get Endpoint EID - Endpoint Type (EP)
*
* DSP0236 1.3.1 Table 15
*/
enum _MCEP
{
MCEP_SIMPLE_ENDPOINT = 0,
MCEP_BRIDGE = 1,
MCEP_MAX
};
/**
* Special Endpoint ID values (ID)
*
* See DSP0236 v1.3.1 Table 2.
*/
enum _MCID
{
MCID_NULL = 0,
MCID_BROADCAST = 0xff
};
/*
* MCTP Control - Get Endpoint EID - Endpoint ID Type (IT)
*
* DSP0236 1.3.1 Table 15
*/
enum _MCIT
{
MCIT_DYNAMIC = 0,
MCIT_STATIC = 1,
MCIT_STATIC_CURRENT = 2,
MCIT_STATIC_DIFFERENT = 3,
MCIT_MAX
};
/*
* MCTP Control Set EID Operations (SE)
*
* DSP0236 1.3.1 Table 14
*/
enum _MCSE
{
MCSE_SET = 0,
MCSE_FORCE = 1,
MCSE_RESET = 2,
MCSE_DISCOVER = 3,
MCSE_MAX
};
/* STRUCTS ===================================================================*/
/*
* MCTP Transport Header
*
* DSP0236 1.3.1 Table 1
*/
struct __attribute__((__packed__)) mctp_hdr
{
__u8 ver : 4; //!< MCTP Header version
__u8 rsvd1 : 4;
__u8 dest; //!< Destination Endpoint ID
__u8 src; //!< Source Endpoint ID
__u8 tag : 3; //!< tag to track outstanding commands
__u8 owner : 1; //!< Requester is the originator of this cmd
__u8 seq : 2; //!< Packet Sequence number modulo 4
__u8 eom : 1; //!< End of Message flag
__u8 som : 1; //!< Start of Message flag
};
/*
* MCTP Packet
*
* This is a packed structure for transmission
*
* DSP0236 1.3.1 Table 1
*/
struct __attribute__((__packed__)) mctp_pkt
{
struct mctp_hdr hdr;
__u8 payload[MCLN_BTU];
};
/**
* MCTP Packet Wrapper object for software use. Not packed. Cannot be sent directly
*/
struct mctp_pkt_wrapper
{
struct timespec ts; //!< Time when this packet was received
struct mctp_pkt_wrapper* next; //!< The next mctp_packet in a linked list
struct mctp_pkt pkt; //!< The data of this object
};
/*
* MCTP Type Header
*
* DSP0236 1.3.1 Table 1
*/
struct __attribute__((__packed__)) mctp_type
{
__u8 type :7; //!< MCTP Message Type [MCMT]
__u8 IC :1; //!< Integrity Check Field
};
/**
* MCTP Message
*
* DSP0236 1.3.1 Table 1
*/
struct mctp_msg
{
__u8 src;
__u8 dst;
__u8 type;
__u8 owner;
__u8 tag;
__u16 len;
struct timespec ts;
__u8 payload[MCLN_MSG_PAYLOAD];
};
/**
* State of the MCTP endpoint
*
* This is used to track MCTP related configuration
*/
struct mctp_state
{
__u8 eid;
__u8 bus_owner_eid;
__u32 verbose;
uuid_t uuid;
};
/*
* MCPT Control Message Fields (Request)
* DSP0236 1.3.1 Table 10
*/
struct __attribute__((__packed__)) mctp_ctrl
{
__u8 inst : 5; //!< Instance ID
__u8 rsvd : 1;
__u8 datagram : 1; //!< Datagram bit
__u8 req : 1; //!< Request Bit
__u8 cmd; //!< MCTP Control Command [MCCM]
};
/*
* MCTP Control - Set EID Request
*
* DSP0236 1.3.1 Table 14
*/
struct __attribute__((__packed__)) mctp_ctrl_set_eid_req
{
__u8 operation : 2;
__u8 rsvd1 : 6;
__u8 eid;
};
/*
* MCTP Control - Set EID response
*
* DSP0236 1.3.1 Table 14
*/
struct __attribute__((__packed__)) mctp_ctrl_set_eid_resp
{
__u8 comp_code;
__u8 allocation : 2;
__u8 rsvd2 : 2;
__u8 assignment : 2;
__u8 rsvd1 : 2;
__u8 eid;
__u8 pool_size;
};
/*
* MCTP Control - Get Endpoint ID Response
*
* DSP0236 1.3.1 Table 15
*/
struct __attribute__((__packed__)) mctp_ctrl_get_eid_resp
{
__u8 comp_code; // MCCC
__u8 eid;
__u8 id_type : 2; // MCIT
__u8 rsvd2 : 2;
__u8 endpoint_type : 2; // MCEP
__u8 rsvd1 : 2;
__u8 medium_specific;
};
/*
* MCTP Control - Get UUID Response
*
* DSP0236 1.3.1 Table 16
*/
struct __attribute__((__packed__)) mctp_ctrl_get_uuid_resp
{
__u8 comp_code; // MCCC
__u8 uuid[16];
};
/*
* MCTP Control - Version Support
*
* This struct is used in the global variable to define what versions the emulator supports
* This is not serialized over the wire
* It is used in a linked list
*
* DSP0236 1.3.1 Table 18
*/
struct __attribute__((__packed__)) mctp_version
{
__u8 major;
__u8 minor;
__u8 update;
__u8 alpha;
__u8 type; // MCTC
struct mctp_version *next_entry;
struct mctp_version *next_type;
};
/*
* MCTP Control - Version Support
*
* This struct is sent over the wire.
*
* DSP0236 1.3.1 Table 18
*/
struct __attribute__((__packed__)) mctp_ver
{
__u8 major;
__u8 minor;
__u8 update;
__u8 alpha;
};
/*
* MCTP Control - Get Version Support Request
*
* This struct is sent over the wire.
*
* DSP0236 1.3.1 Table 18
*/
struct __attribute__((__packed__)) mctp_ctrl_get_ver_req
{
__u8 type;
};
/*
* MCTP Control - Get Version Support Response
*
* This struct is sent over the wire.
*
* DSP0236 1.3.1 Table 18
*/
struct __attribute__((__packed__)) mctp_ctrl_get_ver_resp
{
__u8 comp_code; // MCCC
__u8 count; // Number of entries returned
struct mctp_ver versions[15]; // Versions supported
};
/*
* MCTP Control - Get Message Type Support Response
*
* This struct is sent over the wire.
*
* DSP0236 1.3.1 Table 18
*/
struct __attribute__((__packed__)) mctp_ctrl_get_msg_type_resp
{
__u8 comp_code; // MCCC
__u8 count; // Number of entries returned
__u8 list[59]; // Versions supported
};
/**
* MCTP Control Message Object
*/
struct __attribute__((__packed__)) mctp_ctrl_msg
{
struct mctp_ctrl hdr; //!< MCTP Control Message Header
union {
struct mctp_ctrl_set_eid_req set_eid_req;
struct mctp_ctrl_set_eid_resp set_eid_rsp;
struct mctp_ctrl_get_eid_resp get_eid_rsp;
struct mctp_ctrl_get_uuid_resp get_uuid_rsp;
struct mctp_ctrl_get_ver_req get_ver_req;
struct mctp_ctrl_get_ver_resp get_ver_rsp;
struct mctp_ctrl_get_msg_type_resp get_msg_type_rsp;
} obj;
__u8 len; //!< Object Payload length in bytes
};
/* Establish there is an mctp object so other objects can have a pointer to it */
struct mctp;
/**
* Submission action object
*/
struct mctp_action
{
struct mctp_msg *req; //!< Request Message payload
struct mctp_msg *rsp; //!< Response Message payload
struct mctp_pkt_wrapper *pw;//!< Linked list of packets
struct timespec created; //!< Time stamp when action was created
struct timespec submitted; //!< Time of last submission
struct timespec completed; //!< Time when response was received
int valid; //!< Bool if this object is 1=valid or 0=not
int completion_code; //!< 0=Success, Failure Code otherwise
int num; //!< Number of transmission attempted
int max; //!< Maximum number of transmission attempts
void *user_data; //!< Pointer to user data kept with action until completion
sem_t *sem; //!< Semaphore to pend on until action has completed
struct timespec timeout; //!< Absolute time when the semaphore will expire
//!< Function to call when this action is submitted
void (*fn_submitted)(struct mctp *m, struct mctp_action *a);
//!< Function to call when this action has completed
void (*fn_completed)(struct mctp *m, struct mctp_action *a);
//!< Function to call if this action fails to complete
void (*fn_failed)(struct mctp *m, struct mctp_action *a);
};
/**
* Object passed to Socket Writer thread function
*/
struct socket_writer
{
// Parent pointer
struct mctp *m;
// State fields
__u32 loop;
// Thread fields
pid_t threadid;
// State fields
__u64 packet_count;
__u64 dropped_count;
};
/**
* Object passed to Packet Writer thread function
*/
struct packet_writer
{
// Parent pointer
struct mctp *m;
// State fields
__u32 loop;
// Thread fields
pid_t threadid;
useconds_t sleep_usec;
// State fields
__u8 pkt_seq;
__u64 packet_count;
__u64 message_count;
};
/**
* Object passed to Message Handler thread function
*/
struct message_handler
{
// Parent pointer
struct mctp *m;
// State fields
__u32 loop;
// Thread fields
pid_t threadid;
useconds_t sleep_usec;
};
/**
* Object passed to Packet Reader thread function
*/
struct packet_reader
{
// Parent pointer
struct mctp *m;
// Thread fields
pid_t threadid;
// State fields
__u32 loop;
__u8 pkt_seq;
__u64 packet_count;
__u64 message_count;
__u64 dropped_version;
__u64 dropped_seqnum;
__u64 dropped_noeom;
__u64 dropped_nosom;
__u64 dropped_wrongto;
// In process Messages
struct mctp_msg *tags[MCTP_NUM_TAGS];
};
/**
* Object passed to Socket Reader thread function
*/
struct socket_reader
{
// Parent pointer
struct mctp *m;
// Thread fields
pid_t threadid;
useconds_t sleep_usec;
// State fields
__u32 loop;
__u64 sleep_count;
__u64 packet_count;
__u64 dropped_count;
};
/**
* Object passed to Connection Handler thread function
*/
struct connection_handler
{
struct mctp *m;
pid_t threadid;
__u32 loop;
int dontblock;
sem_t *sem;
};
/**
* Object passed to Submission Thread function
*/
struct submission_thread
{
struct mctp *m; //!< Parent pointer
pid_t threadid; //!< Threadid of this thread
__u32 loop; //!< Thread step / loop counter
struct timespec action_delta; //!< Relative time to wait on an action before resubmitting
struct timespec thread_delta; //!< Relative time for thread to wait when sleeping
struct timespec thread_timeout; //!< Absolute time when to wake from pthread_cond_wait()
pthread_mutex_t mtx; //!< Thread sleep mutex
pthread_cond_t cond; //!< Thread sleep condition
int wake; //!< Request to wake the thread
};
/**
* Object passed to Action Completion Thread function
*/
struct completion_thread
{
struct mctp *m; //!< Parent pointer
pid_t threadid; //!< Threadid of this thread
__u32 loop; //!< Thread step / loop counter
__u64 completed_actions; //!< Number of actions completed
__u64 successful_actions; //!< Number of actions that completed successfully
__u64 failed_actions; //!< Number of actions that failed
};
/**
* State representation of a set of MCTP threads
*/
struct mctp
{
struct mctp_state state;
uuid_t uuid;
struct mctp_version *mctp_versions;
int (*handlers[MCMT_MAX]) (struct mctp *m, struct mctp_action *ma);
// Thread control
pthread_mutex_t mtx;
pthread_cond_t cond; // Condition to wake up main thread if there is a failure with the worker threads
__u32 verbose;
int use_threads;
int wait;
int all_threads_started;
int stop_threads;
int dummy;
// Outstanding commands array
struct mctp_action *tags[MCTP_NUM_TAGS];
pthread_mutex_t tags_mtx;
// Thread handles
pthread_t pt_ch; //!< PThread handle for Connection Thread
pthread_t pt_sr; //!< PThread handle for Socket Reader Thread
pthread_t pt_pr; //!< PThread handle for Packet Reader Thread
pthread_t pt_mh; //!< PThread handle for Message Handler Thread
pthread_t pt_pw; //!< PThread handle for Packet Writer Thread
pthread_t pt_sw; //!< PThread handle for Socket Writer Thread
pthread_t pt_st; //!< PThread handle for Submission Thread
pthread_t pt_ct; //!< PThread handle for Action Completion Thread
// Thread state
struct connection_handler ch;
struct socket_reader sr;
struct packet_reader pr;
struct message_handler mh;
struct packet_writer pw;
struct socket_writer sw;
struct submission_thread st;
struct completion_thread ct;
// Thread functions
void *(*fn_sr)(void *arg);
void *(*fn_pr)(void *arg);
void *(*fn_mh)(void *arg);
void *(*fn_pw)(void *arg);
void *(*fn_sw)(void *arg);
void *(*fn_st)(void *arg);
void *(*fn_ct)(void *arg);
// Object Pools
struct ptr_queue *pkts;
struct ptr_queue *msgs;
struct ptr_queue *actions;
// Queue fields
struct ptr_queue *rpq; //!< Receive Packet Queue
struct ptr_queue *tpq; //!< Transmit Packet Queue
struct ptr_queue *rmq; //!< Receive Message Queue
struct ptr_queue *tmq; //!< Transmit Message Queue
struct ptr_queue *taq; //!< Transmit Action Queue
struct ptr_queue *acq; //!< Action Completed Queue
// Socket fields
int port;
int mode;
int sock;
int conn;
socklen_t client_len;
struct sockaddr_in sa_server;
struct sockaddr_in sa_client;
};
/* GLOBAL VARIABLES ==========================================================*/
/* PROTOTYPES ================================================================*/
/* External API */
struct mctp *mctp_init();
int mctp_run(struct mctp *m, int port, __u32 address, int mode, int use_threads, int dontblock);
int mctp_stop(struct mctp *m);
void mctp_request_stop(struct mctp *m);
int mctp_free(struct mctp *m);
void mctp_retire(struct mctp* m, struct mctp_action *a);
/**
* Submit an object for transmission
*
* Call will pend on a semaphore for a time sepcified in timespec delta if provided.
* If delta is not provided, call will submit and return immediately
*
* @param m struct mctp*
* @param type mctp message type
* @param obj Pointer to serialized data buffer to send
* @param len Length of object in bytes
* @param retry Number of attempts to send the object. -1=forever, -2=default
* @param delta struct timespec* Time to wait for a response.
* @param user_data void* to a user data object to keep with the action until completion
* @param fn_submitted Function to call when action is submitted to tmq
* @param fn_completed Function to call when response to action is received
* @param fn_failed Function to call when retry attempts have elapsed
* @return struct mctp_action* of the action submitted. NULL on error and sets errno
*
* STEPS
* 1: Validate inputs
* 2. Prepare message
* 3. Prepare action
* 4. Submit action
*/
struct mctp_action *mctp_submit(
struct mctp *m,
int type,
void *obj,
size_t len,
int retry,
struct timespec *delta,
void *user_data,
void (*fn_submitted)(struct mctp *m, struct mctp_action *a),
void (*fn_completed)(struct mctp *m, struct mctp_action *a),
void (*fn_failed)(struct mctp *m, struct mctp_action *a)
);
// Verbosity levels
void mctp_set_verbosity(struct mctp *m, __u32 level);
__u32 mctp_get_verbosity(struct mctp *m);
int mctp_set_version(struct mctp *m, __u8 type, __u8 major, __u8 minor, __u8 update, __u8 alpha);
void mctp_prnt_ver(struct mctp_version *mv, int indent);
int mctp_sprnt_ver(char *buf, struct mctp_version *mv);
int vercmp(struct mctp_version *lhs, struct mctp_version *rhs);
// Set handlers
void mctp_set_handler(struct mctp *m, int type, int (*func)(struct mctp *m, struct mctp_action *ma));
void mctp_set_mh(struct mctp *m, void *(*fn)(void*arg));
// Functions to populate common MCTP structs
void mctp_fill_msg_hdr(struct mctp_msg *mm, __u8 dest, __u8 src, __u8 owner, __u8 tag);
void mctp_fill_ctrl(struct mctp_msg *mm, __u8 req, __u8 datagram, __u8 inst, __u8 cmd);
int mctp_ctrl_fill_get_eid(struct mctp_ctrl_msg *m);
int mctp_ctrl_fill_get_type(struct mctp_ctrl_msg *m);
int mctp_ctrl_fill_get_ver(struct mctp_ctrl_msg *m, int type);
int mctp_ctrl_fill_get_uuid(struct mctp_ctrl_msg *m);
int mctp_ctrl_fill_set_eid(struct mctp_ctrl_msg *m, int eid);
int mctp_pkt_count(struct mctp_msg *mm);
/* MCTP Control Message Functions */
int mctp_ctrl_handler(struct mctp *m, struct mctp_action *ma);
struct mctp_ctrl *mctp_get_ctrl(struct mctp_msg *mm);
__u8 *mctp_get_ctrl_payload(struct mctp_msg *mm);
unsigned int mctp_len_ctrl(__u8 *ptr);
/* Thread Functions */
void *mctp_connection_handler(void *arg);
void *mctp_socket_reader(void *arg);
void *mctp_packet_reader(void *arg);
void *mctp_message_handler(void *arg);
void *mctp_socket_writer(void *arg);
void *mctp_packet_writer(void *arg);
void *mctp_submission_thread(void *arg);
void *mctp_completion_thread(void *arg);
/* Print methods for mctp objects*/
void mctp_prnt_hdr(struct mctp_hdr *mh);
void mctp_prnt_pkt_wrapper(struct mctp_pkt_wrapper *pw);
void mctp_prnt_pkt(struct mctp_pkt *mp);
void mctp_prnt_type(struct mctp_type *mt);
void mctp_prnt_msg(struct mctp_msg *mm);
void mctp_prnt_state(struct mctp_state *ms);
/* Return a string representation of enum entries */
const char *mcmt(unsigned u);
const char *mcrm(unsigned u);
const char *mccc(unsigned u);
const char *mccm(unsigned u);
const char *mcep(unsigned u);
const char *mcid(unsigned u);
const char *mcit(unsigned u);
const char *mcse(unsigned u);
#endif //ifndef _MCTP_H