1a68185c4SPatrick Williams# libmctp: Implementation of MCTP (DTMF DSP0236) 24cdc200fSJeremy Kerr 34cdc200fSJeremy KerrThis library is intended to be a portable implementation of the Management 4a68185c4SPatrick WilliamsComponent Transport Protocol (MCTP), as defined by DMTF standard "DSP0236", plus 5a68185c4SPatrick Williamstransport binding specifications. 64cdc200fSJeremy Kerr 7*fa3bc56aSJeremy Kerr## Target usage 8*fa3bc56aSJeremy Kerr 9*fa3bc56aSJeremy Kerr`libmctp` is a library that implements a straightforward MCTP stack. It will be 10*fa3bc56aSJeremy Kerruseful in a two main scenarios: 11*fa3bc56aSJeremy Kerr 12*fa3bc56aSJeremy Kerr- where you are implementing MCTP in an embedded device; or 13*fa3bc56aSJeremy Kerr- where you have Linux system: 14*fa3bc56aSJeremy Kerr - with no kernel MCTP support, 15*fa3bc56aSJeremy Kerr - need a single application implementing all of the MCTP stack; and 16*fa3bc56aSJeremy Kerr - you are providing your own hardware drivers for MCTP transports. 17*fa3bc56aSJeremy Kerr 18*fa3bc56aSJeremy KerrNotably, if you are implementing an MCTP application on Linux, you _almost 19*fa3bc56aSJeremy Kerrcertainly_ want to use the in-kernel MCTP support, which gives you a standard 20*fa3bc56aSJeremy Kerrsockets-based interface to transmit and receive MCTP messages. When using the 21*fa3bc56aSJeremy KerrLinux kernel MCTP support, you do not need to use `libmctp` at all, and can use 22*fa3bc56aSJeremy Kerrthe sockets directly. `libmctp` does not provide functions to interact with the 23*fa3bc56aSJeremy Kerrkernel MCTP sockets. 24*fa3bc56aSJeremy Kerr 25*fa3bc56aSJeremy KerrThere is an overview and example code for the in-kernel support in the [MCTP 26*fa3bc56aSJeremy Kerrkernel docs][kernel-mctp], and a general guide in an [introduction to MCTP on 27*fa3bc56aSJeremy KerrLinux][mctp-linux-intro] document. 28*fa3bc56aSJeremy Kerr 29*fa3bc56aSJeremy Kerr[kernel-mctp]: https://docs.kernel.org/networking/mctp.html 30*fa3bc56aSJeremy Kerr[mctp-linux-intro]: 31*fa3bc56aSJeremy Kerr https://codeconstruct.com.au/docs/mctp-on-linux-introduction/ 32*fa3bc56aSJeremy Kerr 33a68185c4SPatrick Williams## Contact 3452f4cb29SAndrew Jeffery 35fecb358bSGeorge Liu- Email: See [OWNERS](OWNERS). Please also Cc <openbmc@lists.ozlabs.org> 36fecb358bSGeorge Liu- Discord: #mctp on <https://discord.gg/69Km47zH98> 37a68185c4SPatrick Williams- IRC: #openbmc on Freenode 3852f4cb29SAndrew Jeffery 39a68185c4SPatrick Williams## API/ABI Stability 4052f4cb29SAndrew Jeffery 41a68185c4SPatrick WilliamsThe APIs and ABI of libmctp are not yet stablised as we continue to explore ways 42a68185c4SPatrick Williamsto present the MCTP protocol to firmware and applications. Please bear with us! 4352f4cb29SAndrew Jeffery 4452f4cb29SAndrew JefferyWhen we approach a complete implementation of DSP0236 we will consider the 4552f4cb29SAndrew Jefferysuitability of the API/ABI for stabilisation. 4652f4cb29SAndrew Jeffery 4752f4cb29SAndrew JefferyIn the mean time, we'd like your feedback on the library's suitability for your 4852f4cb29SAndrew Jefferyenvironment. 494cdc200fSJeremy Kerr 50a68185c4SPatrick Williams## Core API 514cdc200fSJeremy Kerr 524cdc200fSJeremy KerrTo initialise the MCTP stack with a single hardware bus: 534cdc200fSJeremy Kerr 54a68185c4SPatrick Williams- `mctp = mctp_init()`: Initialise the MCTP core 55a68185c4SPatrick Williams- `binding = mctp_<binding>_init()`: Initialise a hardware binding 56a68185c4SPatrick Williams- `mctp_register_bus(mctp, binding, eid)`: Register the hardware binding with 574cdc200fSJeremy Kerr the core, using a predefined EID 584cdc200fSJeremy Kerr 594cdc200fSJeremy KerrThen, register a function call to be invoked when a message is received: 604cdc200fSJeremy Kerr 61a68185c4SPatrick Williams- `mctp_set_rx_all(mctp, function)`: Provide a callback to be invoked when a 624cdc200fSJeremy Kerr MCTP message is received 634cdc200fSJeremy Kerr 644cdc200fSJeremy KerrOr transmit a message: 654cdc200fSJeremy Kerr 66a68185c4SPatrick Williams- `mctp_message_tx(mctp, message, len)`: Transmit a MCTP message 674cdc200fSJeremy Kerr 68a68185c4SPatrick WilliamsThe binding may require you to notify it to receive packets. For example, for 69a68185c4SPatrick Williamsthe serial binding, the `mctp_serial_read()` function should be invoked when the 70a68185c4SPatrick Williamsfile-descriptor for the serial device has data available. 714cdc200fSJeremy Kerr 721a4ec3cdSJeremy Kerr### Bridging 731a4ec3cdSJeremy Kerr 74a68185c4SPatrick Williamslibmctp implements basic support for bridging between two hardware bindings. In 75a68185c4SPatrick Williamsthis mode, bindings may have different MTUs, so packets are reassembled into 761a4ec3cdSJeremy Kerrtheir messages, then the messages are re-packetised for the outgoing binding. 771a4ec3cdSJeremy Kerr 781a4ec3cdSJeremy KerrFor bridging between two endpoints, use the `mctp_bridge_busses()` function: 791a4ec3cdSJeremy Kerr 80a68185c4SPatrick Williams- `mctp = mctp_init()`: Initialise the MCTP core 81a68185c4SPatrick Williams- `b1 = mctp_<binding>_init(); b2 = mctp_<binding>_init()`: Initialise two 82a68185c4SPatrick Williams hardware bindings 83a68185c4SPatrick Williams- `mctp_bridge_busses(mctp, b1, b2)`: Setup bridge 841a4ec3cdSJeremy Kerr 85a68185c4SPatrick WilliamsNote that no EIDs are defined here; the bridge does not deliver any messages to 86a68185c4SPatrick Williamsa local rx callback, and messages are bridged as-is. 871a4ec3cdSJeremy Kerr 88a68185c4SPatrick Williams## Binding API 893b36d17cSJeremy Kerr 903b36d17cSJeremy KerrHardware bindings provide a method for libmctp to send and receive packets 91a68185c4SPatrick Williamsto/from hardware. A binding defines a hardware specific structure 92a68185c4SPatrick Williams(`struct mctp_binding_<name>`), which wraps the generic binding 93a68185c4SPatrick Williams(`struct mctp_binding`): 943b36d17cSJeremy Kerr 953b36d17cSJeremy Kerr struct mctp_binding_foo { 963b36d17cSJeremy Kerr struct mctp_binding binding; 973b36d17cSJeremy Kerr /* hardware-specific members here... */ 983b36d17cSJeremy Kerr }; 993b36d17cSJeremy Kerr 100a68185c4SPatrick WilliamsThe binding code then provides a method (`_init`) to allocate and initialise the 101a68185c4SPatrick Williamsbinding; this may be of any prototype (calling code will know what arguments to 102a68185c4SPatrick Williamspass): 1033b36d17cSJeremy Kerr 1043b36d17cSJeremy Kerr struct mctp_binding_foo *mctp_binding_foo_init(void); 1053b36d17cSJeremy Kerr 1063b36d17cSJeremy Kerror maybe the `foo` binding needs a path argument: 1073b36d17cSJeremy Kerr 1083b36d17cSJeremy Kerr struct mctp_binding_foo *mctp_binding_foo_init(const char *path); 1093b36d17cSJeremy Kerr 1103b36d17cSJeremy KerrThe binding then needs to provide a function (`_core`) to convert the 1113b36d17cSJeremy Kerrhardware-specific struct to the libmctp generic core struct 1123b36d17cSJeremy Kerr 1133b36d17cSJeremy Kerr struct mctp_binding *mctp_binding_foo_core(struct mctp_binding_foo *b); 1143b36d17cSJeremy Kerr 1153b36d17cSJeremy Kerr(Implementations of this will usually be fairly consistent, just returning 116a68185c4SPatrick Williams`b->binding`). Callers can then use that generic pointer to register the binding 117a68185c4SPatrick Williamswith the core: 1183b36d17cSJeremy Kerr 1193b36d17cSJeremy Kerr struct mctp_binding *binding = mctp_binding_foo_core(foo); 1203b36d17cSJeremy Kerr mctp_register_bus(mctp, binding, 8); 1213b36d17cSJeremy Kerr 122a68185c4SPatrick Williams## Integration 1232f7e05bdSJeremy Kerr 1242f7e05bdSJeremy KerrThe libmctp code is intended to be integrated into other codebases by two 1252f7e05bdSJeremy Kerrmethods: 1262f7e05bdSJeremy Kerr 127a68185c4SPatrick Williams1. as a simple library (`libmctp.{a,so}`) which can be compiled separately and 128a68185c4SPatrick Williams linked into the containing project 1292f7e05bdSJeremy Kerr 1302f7e05bdSJeremy Kerr2. as a set of sources to be included into the containing project (either 1312f7e05bdSJeremy Kerr imported, or as a git subtree/submodule) 1322f7e05bdSJeremy Kerr 13356886e7fSPatrick WilliamsFor (1), you can use the top-level makefile to produce `libmctp.a`. 1342f7e05bdSJeremy Kerr 1352f7e05bdSJeremy KerrFor (2), the `Makefile.inc` file provides the minimum set of dependencies to 1362f7e05bdSJeremy Kerreither build libmctp.a, or just the actual object files (`LIBMCTP_OBS`), which 1372f7e05bdSJeremy Kerryou can include into your existing make definitions. You'll want to set 1382f7e05bdSJeremy Kerr`LIBMTCP_DIR` to refer to the subdirectory that contains that makefile, so we 1392f7e05bdSJeremy Kerrcan set the correct paths to sources. 1402f7e05bdSJeremy Kerr 141a68185c4SPatrick Williams## Environment configuration 1424cdc200fSJeremy Kerr 1434cdc200fSJeremy KerrThis library is intended to be portable to be used in a range of environments, 1444cdc200fSJeremy Kerrbut the main targets are: 1454cdc200fSJeremy Kerr 1464cdc200fSJeremy Kerr- Linux userspace, typically for BMC use-cases 1474cdc200fSJeremy Kerr- Low-level firmware environments 1484cdc200fSJeremy Kerr 1494cdc200fSJeremy KerrFor the latter, we need to support customisation of the functions that libmctp 1504cdc200fSJeremy Kerruses (for example, POSIX file IO is not available). 1514cdc200fSJeremy Kerr 152c7e764a2SJeremy KerrIn order to support these, we have a few compile-time definitions: 1534cdc200fSJeremy Kerr 154a68185c4SPatrick Williams- `MCTP_HAVE_FILEIO`: define if POSIX file io is available, allowing the serial 155a68185c4SPatrick Williams hardware binding to access char devices for IO. 1564cdc200fSJeremy Kerr 157a68185c4SPatrick Williams- `MCTP_HAVE_SYSLOG`: allow logging to syslog, through the `vsyslog` call. 1584cdc200fSJeremy Kerr 159a68185c4SPatrick Williams- `MCTP_DEFAULT_ALLOC`: set default allocator functions (malloc, free, realloc), 160a68185c4SPatrick Williams so that applications do not have to provide their own. 1613cb4eee4SJeremy Kerr 162a68185c4SPatrick Williams## TODO 1634cdc200fSJeremy Kerr 16424db71fbSJeremy Kerr- Partial packet queue transmit 1654cdc200fSJeremy Kerr- Control messages 1664cdc200fSJeremy Kerr- Message- and packet-buffer pools and preallocation 1674cdc200fSJeremy Kerr- C++ API 1684cdc200fSJeremy Kerr- Non-file-based serial binding 169