xref: /openbmc/libpldm/README.md (revision 762b34a9)
1# libpldm
2
3This is a library which deals with the encoding and decoding of PLDM messages.
4It should be possible to use this library by projects other than OpenBMC, and
5hence certain constraints apply to it:
6
7- keeping it light weight
8- implementation in C
9- minimal dynamic memory allocations
10- endian-safe
11- no OpenBMC specific dependencies
12
13Source files are named according to the PLDM Type, for eg base.[h/c], fru.[h/c],
14etc.
15
16Given a PLDM command "foo", the library will provide the following API: For the
17Requester function:
18
19```c
20encode_foo_req() - encode a foo request
21decode_foo_resp() - decode a response to foo
22```
23
24For the Responder function:
25
26```c
27decode_foo_req() - decode a foo request
28encode_foo_resp() - encode a response to foo
29```
30
31The library also provides API to pack and unpack PLDM headers.
32
33## To Build
34
35Need `meson` and `ninja`. Alternatively, source an OpenBMC ARM/x86 SDK.
36
37```sh
38meson setup builddir && ninja -C builddir
39```
40
41## To run unit tests
42
43The simplest way of running the tests is as described by the meson man page:
44
45```sh
46meson setup builddir && meson test -C builddir
47```
48
49## Working with `libpldm`
50
51The ABIs (symbols, generally functions) exposed by the library are separated
52into three categories:
53
541. Stable
552. Testing
563. Deprecated
57
58Applications depending on `libpldm` should aim to only use functions from the
59stable category. However, this may not always be possible. What to do when
60required functions fall into the deprecated or testing categories is outlined
61below.
62
63### What does it mean to mark a function as stable?
64
65Marking a function as stable makes the following promise to users of the
66library:
67
68> We will not remove or change the symbol name, argument count, argument types,
69> return type, or interpretation of relevant values for the function before
70> first marking it as `LIBPLDM_ABI_DEPRECATED` and then subsequently creating a
71> tagged release
72
73Marking a function as stable does _not_ promise that it is free of
74implementation bugs. It is just a promise that the prototype won't change
75without notice.
76
77Given this, it is always okay to implement functions marked stable in terms of
78functions marked testing inside of libpldm. If we remove or change the prototype
79of a function marked testing the only impact is that we need to fix up any call
80sites of that function in the same patch.
81
82### The ABI lifecycle
83
84```mermaid
85---
86title: libpldm symbol lifecycle
87---
88stateDiagram-v2
89    direction LR
90    [*] --> Testing: Add
91    Testing --> Testing: Change
92    Testing --> [*]: Remove
93    Testing --> Stable: Stabilise
94    Stable --> Deprecated: Deprecate
95    Deprecated --> [*]: Remove
96```
97
98The ABI of the library produced by the build is controlled using the `abi` meson
99option. The following use cases determine how the `abi` option should be
100specified:
101
102| Use Case    | Meson Configuration               |
103| ----------- | --------------------------------- |
104| Production  | `-Dabi=deprecated,stable`         |
105| Maintenance | `-Dabi=stable`                    |
106| Development | `-Dabi=deprecated,stable,testing` |
107
108### Maintenance
109
110Applications and libraries that depend on `libpldm` can identify how to migrate
111off of deprecated APIs by constraining the library ABI to the stable category.
112This will force the compiler identify any call-sites that try to link against
113deprecated symbols.
114
115### Development
116
117Applications and libraries often require functionality that doesn't yet exist in
118`libpldm`. The work is thus in two parts:
119
1201. Add the required APIs to `libpldm`
1212. Use the new APIs from `libpldm` in the dependent application or library
122
123Adding APIs to a library is a difficult task. Generally, once an API is exposed
124in the library's ABI, any changes to the API risk breaking applications already
125making use of it. To make sure we have more than one shot at getting an API
126right, all new APIs must first be exposed in the testing category. Concretely:
127
128Patches adding new APIs MUST mark them as testing and MUST NOT mark them as
129stable.
130
131### Marking functions as testing, stable or deprecated
132
133Three macros are provided through `config.h` (automatically included for all
134translation units) to mark functions as testing, stable or deprecated:
135
1361. `LIBPLDM_ABI_TESTING`
1372. `LIBPLDM_ABI_STABLE`
1383. `LIBPLDM_ABI_DEPRECATED`
139
140These annotations go immediately before your function signature:
141
142```c
143LIBPLDM_ABI_TESTING
144pldm_requester_rc_t pldm_transport_send_msg(struct pldm_transport *transport,
145					    pldm_tid_t tid,
146					    const void *pldm_req_msg,
147					    size_t req_msg_len)
148{
149    ...
150}
151```
152
153### Requirements for stabilising a function
154
155As mentioned above, all new functions must first be added in the testing
156category (using the `LIBPLDM_ABI_TESTING` annotation).
157
158To move a function from the testing category to the stable category, its
159required that patches demonstrating use of the function in a dependent
160application or library be linked in the commit message of the stabilisation
161change. We require this to demonstrate that the implementer has considered its
162use in context _before_ preventing us from making changes to the API.
163
164### Building a dependent application or library against a testing ABI
165
166Meson is broadly used in the OpenBMC ecosystem, the historical home of
167`libpldm`. Meson's subprojects are a relatively painless way of managing
168dependencies for the purpose of developing complex applications and libraries.
169Use of `libpldm` as a subproject is both supported and encouraged.
170
171`libpldm`'s ABI can be controlled from a parent project through meson's
172subproject configuration syntax:
173
174```shell
175$ meson setup ... -Dlibpldm:abi=deprecated,stable,testing ...
176```
177
178## OEM/vendor-specific functions
179
180This will support OEM or vendor-specific functions and semantic information.
181Following directory structure has to be used:
182
183```text
184 libpldm
185    |---- include/libpldm
186    |        |---- oem/<oem_name>/libpldm
187    |                    |----<oem based .h files>
188    |---- src
189    |        |---- oem/<oem_name>
190    |                    |----<oem based .c files>
191    |---- tests
192    |        |---- oem/<oem_name>
193    |                    |----<oem based test files>
194
195```
196
197<oem_name> - This folder must be created with the name of the OEM/vendor in
198lower case.
199
200Header files & source files having the oem functionality for the libpldm library
201should be placed under the respective folder hierarchy as mentioned in the above
202figure. They must be adhering to the rules mentioned under the libpldm section
203above.
204
205Once the above is done a meson option has to be created in `meson.options` with
206its mapped compiler flag to enable conditional compilation.
207
208For consistency would recommend using "oem-<oem_name>".
209
210The `meson.build` and the corresponding source file(s) will need to incorporate
211the logic of adding its mapped compiler flag to allow conditional compilation of
212the code.
213
214## Requester APIs
215
216The pldm requester API's are present in `src/requester` folder and they are
217intended to provide API's to interact with the desired underlying transport
218layer to send/receive pldm messages.
219
220**NOTE** : In the current state, the requester API's in the repository only
221works with [specific transport mechanism](https://github.com/openbmc/libmctp) &
222these are going to change in future & probably aren't appropriate to be writing
223code against.
224