xref: /openbmc/libmctp/README.md (revision fa3bc56a7495c827ed0ce337f2a946971d5d3ce6)
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