Skip to content

Commit d69f73a

Browse files
docs: pre-publish polish, governance files, working-tree leak cleanup
- README: image paths switch to absolute raw.githubusercontent.com URLs so they resolve on the ESP Component Registry; ESP Component Registry badge added; Install sections refreshed to reflect that midi2cpp ships on Arduino Library Manager, PlatformIO Registry, and ESP Component Registry; v0.2.0 references bumped to v0.3.1; recipe path fix (rp2040-promicro-ump-test-bench). - CHANGELOG: drop reference to internal design heritage notes. - examples/t-display-s3-shield-host-midi2: drop absolute path from lib_extra_dirs; recipe now resolves midi2cpp from the parent only. - CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md added, mirroring the governance set already published with midi2.
1 parent 068811a commit d69f73a

6 files changed

Lines changed: 167 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ patterns shipped under `examples/`.
131131
allocates in two narrow places (`m2bridge::begin()` slot tables and
132132
`std::function` callback storage), so the wrapper is now described
133133
as `static-by-default`. The C99 core (midi2) remains strictly
134-
zero-allocation. Same shift applied to the logo and to the
135-
`.intern/decisoes.md` design heritage notes.
134+
zero-allocation. Same shift applied to the logo.
136135
- **README "Manual vendor" path** rewritten: pre-v0.2 builds vendored
137136
a single `midi2cpp/src/midi2.{h,c}` copy; today the consumer
138137
downloads both repositories side by side and adds `midi2/dist/`

CODE_OF_CONDUCT.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Code of Conduct
2+
3+
## Our pledge
4+
5+
We are committed to providing a welcoming and respectful environment for everyone.
6+
7+
## Standards
8+
9+
- Be respectful and constructive
10+
- Focus on technical merit
11+
- Accept feedback gracefully
12+
- No harassment, trolling, or personal attacks
13+
14+
## Enforcement
15+
16+
Unacceptable behavior may be reported to the maintainers. All complaints will be reviewed.
17+
18+
This project follows the spirit of the [Contributor Covenant](https://www.contributor-covenant.org/).

CONTRIBUTING.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Contributing to midi2cpp
2+
3+
Thank you for your interest in contributing to midi2cpp.
4+
5+
## Reporting Issues
6+
7+
Open an issue with:
8+
- What you expected
9+
- What happened
10+
- Minimal code to reproduce
11+
- Platform, board, and toolchain version (Pico SDK / ESP-IDF / TinyUSB CMake / PlatformIO)
12+
13+
## Code Contributions
14+
15+
1. Fork the repository
16+
2. Create a branch (`git checkout -b fix/description`)
17+
3. Make your changes
18+
4. Run host tests:
19+
```bash
20+
cmake -B build -DMIDI2CPP_BUILD_TESTS=ON
21+
cmake --build build --parallel
22+
ctest --test-dir build --output-on-failure
23+
```
24+
5. Run sanitizers locally:
25+
```bash
26+
cmake -B build-asan -DMIDI2CPP_BUILD_TESTS=ON \
27+
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-sanitize-recover=all -O1 -g" \
28+
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined"
29+
cmake --build build-asan --parallel
30+
ctest --test-dir build-asan --output-on-failure
31+
```
32+
6. Open a pull request with a clear description
33+
34+
## Code Style
35+
36+
- **C++17 strict** (`-Wall -Wextra -Wpedantic -Werror`, zero warnings on GCC and Clang)
37+
- **Static-by-default** -- the hot path is allocation-free; init-time `new` is allowed only inside `m2bridge` for the per-slot tables. The C99 core (midi2) stays strictly zero-allocation
38+
- **Caller-provided platform hooks** -- write fn, monotonic clock, RNG, USB mount/alt are caller-supplied; no `<Arduino.h>`, `pico/time.h`, `esp_timer.h` or USB stack header is included by the library
39+
- **Naming**: `m2device` / `m2host` / `m2bridge` / `m2ci` aliases; class methods camelCase; preprocessor macros `MIDI2CPP_*`
40+
- **Every new public method needs a test** -- host-side unit tests under `tests/`
41+
- **C++17 standard library only** -- `<cstdint>`, `<cstring>`, `<functional>`, `<array>`. No exceptions, no RTTI assumptions
42+
- **Comments**: explain _why_, not _what_. Reference the spec section when handling a UMP or MIDI-CI message
43+
44+
## Adding a Hardware Recipe
45+
46+
Recipes live under `examples/<board-role>-midi2/` and follow a consistent layout:
47+
48+
- `README.md` (banner, USB identity, build, validation, spec coverage table)
49+
- `idf/`, `pio/`, or top-level `CMakeLists.txt` depending on the build system
50+
- `src/` (board glue, USB descriptors, showcase main)
51+
- `board/` (banner image, schematic, datasheet)
52+
- `monitor/` (screenshots from MIDI tooling that prove the recipe runs)
53+
- A fresh USB PID from the project pool
54+
55+
The simplest way to add a new recipe is to copy the closest existing one under `examples/` and adapt the board glue, USB descriptors, and showcase main to the new target.
56+
57+
## Testing
58+
59+
```bash
60+
cmake -B build -DMIDI2CPP_BUILD_TESTS=ON
61+
cmake --build build --parallel
62+
ctest --test-dir build --output-on-failure # all tests
63+
arduino-cli compile examples/HelloMIDI2 --fqbn rp2040:rp2040:rpipico # Arduino path
64+
```
65+
66+
CI runs host tests on Linux + macOS, strict warnings (gcc + clang), arduino-cli compile of `HelloMIDI2.ino`, and the Pico SDK build of `examples/rp2040-midi2`.
67+
68+
## Spec References
69+
70+
midi2cpp wraps the [midi2](https://github.com/sauloverissimo/midi2) C99 core, which implements:
71+
72+
- **UMP messages**: M2-104-UM v1.1.2
73+
- **MIDI-CI messages**: M2-101-UM v1.2
74+
- **Value scaling**: M2-115-U v1.0.2
75+
76+
When adding or modifying message handling, reference the spec section in code comments.
77+
78+
## License
79+
80+
By contributing, you agree that your contributions will be licensed under the MIT License.

README.md

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### MIDI 2.0 engine for embedded systems
44

5-
![midi2cpp](logo_midi2cpp.png)
5+
![midi2cpp](https://raw.githubusercontent.com/sauloverissimo/midi2cpp/main/logo_midi2cpp.png)
66

77
*C++17, callback-first, static-by-default, depends on midi2, MIT.* From DIY to professional products.
88

@@ -13,6 +13,7 @@
1313
[![Arduino](https://img.shields.io/badge/Arduino-IDE-00979D.svg)](https://www.arduino.cc/)
1414
[![PlatformIO](https://img.shields.io/badge/PlatformIO-Registry-FF7F00.svg)](https://registry.platformio.org/libraries/sauloverissimo/midi2cpp)
1515
[![ESP-IDF](https://img.shields.io/badge/ESP--IDF-v5.4-E7352C.svg)](https://docs.espressif.com/projects/esp-idf/en/stable/)
16+
[![ESP Component Registry](https://components.espressif.com/components/sauloverissimo/midi2cpp/badge.svg)](https://components.espressif.com/components/sauloverissimo/midi2cpp)
1617
[![Pico SDK](https://img.shields.io/badge/Pico_SDK-2.0-C51A4A.svg)](https://github.com/raspberrypi/pico-sdk)
1718
[![CMake](https://img.shields.io/badge/CMake-3.16%2B-064F8C.svg)](https://cmake.org/)
1819
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
@@ -165,7 +166,7 @@ Validated on real hardware against forks and PRs maintained internally while the
165166
| **Raspberry Pi Pico** | RP2040 | ✅ | - | - | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB | TinyUSB PR #3571, recipe in [`examples/rp2040-midi2`](examples/rp2040-midi2) |
166167
| **Waveshare RP2040 Pi Zero** | RP2040 | ✅ | - | - | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB | TinyUSB PR #3571, recipe in [`examples/waveshare-rp2040-midi2`](examples/waveshare-rp2040-midi2) |
167168
| **Adafruit Feather RP2040 USB Host** | RP2040 | ✅ | ✅ | ✅ | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB, PIO-USB | TinyUSB PR #3571 + Pico-PIO-USB `675543b` (handshake delay fix), recipes in [`adafruit-feather-rp2040-host-midi2`](examples/adafruit-feather-rp2040-host-midi2) and [`adafruit-feather-rp2040-bridge-midi2`](examples/adafruit-feather-rp2040-bridge-midi2) |
168-
| **RP2040 Pro Micro (Tenstar Robot)** | RP2040 | ✅ | - | - | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB | TinyUSB PR #3571, deterministic UMP emitter for Windows MIDI Services testing in [`ump-test-bench-rp2040`](examples/ump-test-bench-rp2040) |
169+
| **RP2040 Pro Micro (Tenstar Robot)** | RP2040 | ✅ | - | - | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB | TinyUSB PR #3571, deterministic UMP emitter for Windows MIDI Services testing in [`rp2040-promicro-ump-test-bench`](examples/rp2040-promicro-ump-test-bench) |
169170
| **Waveshare RP2350-USB-A** | RP2350 | ✅ | ✅ | ✅ | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB, PIO-USB on GP12/GP13 | TinyUSB PR #3571 + Pico-PIO-USB `675543b` + R13 hardware mod for host mode (desolder the 1.5 kΩ pull-up on USB-A D+), recipes in [`waveshare-rp2350-usb-a-midi2`](examples/waveshare-rp2350-usb-a-midi2) (device) and [`waveshare-rp2350-usb-a-bridge-midi2`](examples/waveshare-rp2350-usb-a-bridge-midi2) (bridge) |
170171
| **SparkFun Pro Micro RP2350** | RP2350 | ✅ | - | - | ![override](https://img.shields.io/badge/-override-blueviolet.svg) TinyUSB | TinyUSB PR #3571, recipe in [`sparkfun-promicro-rp2350-midi2`](examples/sparkfun-promicro-rp2350-midi2) |
171172
| Raspberry Pi Pico 2 | RP2350 | ✅ | ✅ | - | - | TinyUSB PR #3571 |
@@ -197,9 +198,9 @@ By role: 10 device, 4 host, 4 bridge, 1 multi-transport (BLE + ESP-NOW, no USB P
197198
198199
### Arduino IDE
199200
200-
Once midi2cpp is published to the [Arduino Library Manager](https://github.com/arduino/library-registry), the IDE install becomes: search `midi2cpp`, click Install. The dependency on `midi2` (already on the Library Manager) is resolved automatically.
201+
Listed on the [Arduino Library Manager](https://github.com/arduino/library-registry). The IDE install path: search the manager, click Install. The dependency on `midi2` is resolved automatically.
201202
202-
Until then, install manually:
203+
Manual install (mirror, or while the manager index is propagating):
203204
204205
```bash
205206
git clone https://github.com/sauloverissimo/midi2cpp.git ~/Arduino/libraries/midi2cpp
@@ -209,43 +210,52 @@ Then install `midi2` via Library Manager (search `midi2`, click Install).
209210

210211
### PlatformIO
211212

212-
Once midi2cpp is published to the [PlatformIO Registry](https://registry.platformio.org/):
213+
Published on the [PlatformIO Registry](https://registry.platformio.org/libraries/sauloverissimo/midi2cpp):
213214

214215
```ini
215-
lib_deps = sauloverissimo/midi2cpp @ ^0.2.0
216+
lib_deps = sauloverissimo/midi2cpp @ ^0.3.1
216217
```
217218

218-
Until then, use the git URL pinned by tag:
219+
Or pin by git tag:
219220

220221
```ini
221222
lib_deps =
222-
https://github.com/sauloverissimo/midi2cpp.git#v0.2.0
223+
https://github.com/sauloverissimo/midi2cpp.git#v0.3.1
223224
```
224225

225226
Either way, `midi2` is resolved transitively via the manifest declaration in `library.json`.
226227

227228
### ESP-IDF component
228229

229-
Two paths, depending on whether midi2cpp lives inside the project tree or alongside it:
230+
Published on the [ESP Component Registry](https://components.espressif.com/components/sauloverissimo/midi2cpp). Two install paths, depending on whether midi2cpp comes from the registry or lives inside the project tree:
230231

231-
**As a local component** (current pattern in [`examples/`](examples/)):
232+
**Via the Component Manager** (recommended):
233+
234+
```yaml
235+
# main/idf_component.yml
236+
dependencies:
237+
idf: ">=5.0"
238+
sauloverissimo/midi2cpp: ">=0.3.1"
239+
```
240+
241+
`midi2` is pulled transitively through `midi2cpp`'s manifest. `idf.py reconfigure` drops both into `managed_components/`.
242+
243+
**As a local component** (vendoring pattern, useful when iterating on the wrapper):
232244

233245
```bash
234246
# from your IDF project root
235247
git clone https://github.com/sauloverissimo/midi2cpp.git components/midi2cpp
236248
```
237249

238-
Declare midi2 in `main/idf_component.yml` so the Component Manager pulls it next to `managed_components/`:
250+
Then declare `midi2` in `main/idf_component.yml`:
239251

240252
```yaml
241253
dependencies:
242-
idf: ">=5.4"
243-
midi2:
244-
git: https://github.com/sauloverissimo/midi2.git
245-
version: ">=0.3.4"
254+
idf: ">=5.0"
255+
sauloverissimo/midi2: ">=0.3.4"
246256
```
247257

248-
`main/CMakeLists.txt` lists `midi2` (and any of `midi2cpp`'s wrapper sources you use) in its `idf_component_register(...)` block. The seven ESP-IDF recipes under [`examples/`](examples/) ship working templates for device, host and bridge roles.
258+
`main/CMakeLists.txt` lists `midi2cpp` in its `idf_component_register(... REQUIRES midi2cpp ...)` block. The seven ESP-IDF recipes under [`examples/`](examples/) ship working templates for device, host and bridge roles.
249259

250260
### CMake FetchContent
251261

@@ -254,7 +264,7 @@ include(FetchContent)
254264
FetchContent_Declare(
255265
midi2cpp
256266
GIT_REPOSITORY https://github.com/sauloverissimo/midi2cpp.git
257-
GIT_TAG v0.2.0
267+
GIT_TAG v0.3.1
258268
)
259269
FetchContent_MakeAvailable(midi2cpp)
260270
```
@@ -301,7 +311,7 @@ Async, callback-first, copy-paste-ready. Same shape as MIDI 1.0 Arduino librarie
301311

302312
midi2cpp: platform layer of a 4-layer MIDI 2.0 stack:
303313

304-
![midi2cpp](architecture.png)
314+
![midi2cpp](https://raw.githubusercontent.com/sauloverissimo/midi2cpp/main/architecture.png)
305315

306316
The sketch touches the top. The rest is invisible until needed.
307317

SECURITY.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Security Policy
2+
3+
## Supported Versions
4+
5+
| Version | Supported |
6+
|---------|-----------|
7+
| latest | Yes |
8+
9+
## Reporting a Vulnerability
10+
11+
If you discover a security vulnerability, please report it privately:
12+
13+
1. **Do not** open a public issue
14+
2. Email: sauloverissimo@gmail.com
15+
3. Include: description, steps to reproduce, potential impact
16+
17+
You will receive a response within 48 hours. Confirmed vulnerabilities will be patched and disclosed responsibly.
18+
19+
## Scope
20+
21+
midi2cpp is a C++17 wrapper over the [midi2](https://github.com/sauloverissimo/midi2) C99 core. It carries no network, file, or OS access of its own; the library reads UMP words from a caller-wired transport, dispatches them to typed callbacks, and writes UMP words back. Security concerns are limited to:
22+
23+
- Buffer overflows in SysEx7 / SysEx8 reassembly or MIDI-CI message parsing
24+
- Integer overflows in value scaling, length calculations, or per-slot bridge windows
25+
- Malformed UMP or MIDI-CI input causing unexpected behavior
26+
- Out-of-bounds reads when parsing variable-length fields (Profiles, PE data)
27+
- Use-after-free in the `m2bridge` slot table when the platform tears down a slot mid-feed
28+
29+
## Mitigations
30+
31+
- The host test suite (7 executables under `tests/`) runs under AddressSanitizer and UndefinedBehaviorSanitizer locally and in CI
32+
- The `test_midi2_bridge` suite specifically exercises the heap allocations inside `m2bridge::begin()` (50x construct/begin/destruct cycles) under ASan
33+
- Input length is validated before accessing message fields
34+
- Multi-byte field access uses explicit bounds checks
35+
- The C99 core (midi2) is strictly zero-allocation, eliminating use-after-free and double-free classes there
36+
- midi2cpp's `new` allocations live only inside `m2bridge::begin()` and are released in the destructor

examples/t-display-s3-shield-host-midi2/pio/platformio.ini

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ build_flags =
4848
-DLGFX_USE_V1
4949

5050
; Pull midi2cpp from the parent of this recipe via lib_extra_dirs.
51-
; ESP32_Host_MIDI is consumed from a local working tree (v6.0 internal,
52-
; not yet published). When v6.0 ships, swap this for the github URL form
53-
; pinned to v6.0.0.
54-
lib_extra_dirs = ../../.., /home/shared/workspaces/github
51+
; ESP32_Host_MIDI is pulled from PlatformIO Registry once v6.0 ships;
52+
; until then, drop a checkout next to the project root or extend
53+
; lib_extra_dirs locally.
54+
lib_extra_dirs = ../../..
5555

5656
lib_deps =
5757
sauloverissimo/midi2 @ ^0.3.4

0 commit comments

Comments
 (0)