Het klassenmodel¶
CONTRACT · IMPLEMENTATIE · ZELFSTANDIG · GRENSGEVALLEN
De 196 klassen van MeshCore vallen in drie soorten uiteen: klassen die
vastleggen wat een ander onderdeel mag verwachten, klassen die zo'n afspraak
implementeren, en klassen die op zichzelf staan. Dit hoofdstuk beschrijft die
driedeling, benoemt wat een contract wél en niet is, en loopt de 119 klassen
uit de gedeelde broncode stuk voor stuk langs. De 77 uit variants/ staan als
samenvatting aan het eind.
[!NOTE] Bron. Deze pagina is geverifieerd tegen de firmware zelf:
MeshCorev1.16.0, commit03b6ef4, 28 juli 2026 — elke klasse in de tabellen is nagelopen op bestand en regelnummer insrc/,examples/envariants/.
Wat een contract is¶
Een contract is een klasse die uitsluitend bestaat om vast te leggen wat een
ander onderdeel mag verwachten. Hij bevat geen werkende code, alleen de
opsomming van wat een implementatie moet kunnen, plus soms een
standaardantwoord voor het geval de hardware iets niet kan. In C++ herken je
hem aan virtuele methoden, waarvan de verplichte op = 0 eindigen.
Drie eigenschappen maken iets tot contract:
- Het beschrijft, het doet niet.
Radioweet niet hoe je een SX1262 aanstuurt; het legt vast dat er iets moet zijn dat bytes verstuurt. - De gebruiker kent alleen het contract. De pakketafhandeling houdt een
Radio*vast en heeft geen idee welke chip eraan hangt. - Implementaties zijn onderling verwisselbaar. Elke klasse die het contract implementeert, kan elke andere vervangen zonder dat de gebruiker verandert.
De logische kant van dit verhaal — welke afspraken er zijn en wat ze beloven — staat in Contracten. Hier gaat het om de klassen die ze dragen.
Wat geen contract is¶
Een basisklasse waar gedeelde code in zit, is geen contract maar een
gemeenschappelijke ouder. ESP32Board is zo'n geval: hij implementeert het
bordcontract en biedt code die de afgeleide bordklassen erven. Hij staat
daarom in groep 2, niet in groep 1.
Het onderscheid is niet altijd scherp. BridgeBase en RadioLibWrapper zijn
allebei een implementatie én een ouder: ze implementeren AbstractBridge
respectievelijk mesh::Radio, en er hangen weer klassen onder die van hen
erven. Wie de driedeling als een harde indeling leest, komt bij die twee in de
problemen. Ze staan in groep 2 omdat ze een contract implementeren; dat ze er
zelf ook kinderen onder hebben, verandert niets aan die eigenschap.
Zelfstandig is alles wat geen contract is en er ook geen implementeert:
klassen die één ding doen en waar niets van af hangt. ClientACL beheert de
rechtenlijst, RegionMap zet regiocodes om, Packet is een gegevensobject.
Ze zijn niet vervangbaar omdat er niets is dat ze zou moeten kunnen vervangen.
Een leerzaam geval is CustomSX1262. Die staat in groep 3, niet in groep 2.
De klasse erft van RadioLibs SX1262 en implementeert geen MeshCore-contract;
het is CustomSX1262Wrapper die dat doet, via RadioLibWrapper. Dat
verklaart waarom er twee klassen per radiochip zijn: één die de chipdriver
aanpast, één die het resultaat in het MeshCore-contract giet. Zie
Radiorealisatie.
De verdeling¶
De gedeelde broncode telt 119 klassen: 14 interfaceklassen, 50 implementatieklassen en 55 zelfstandige klassen.
| Groep | Aantal | Kenmerk |
|---|---|---|
| 1 — interfaceklassen | 14 | Alleen virtuele methoden, geen werkende code |
| 2 — implementatieklassen | 50 | Erft van een klasse uit groep 1 |
| 3 — zelfstandig | 55 | Geen contract, implementeert er ook geen |
Groep 1 — interfaceklassen (14)¶
| Klasse | Plek |
|---|---|
DataStoreHost |
examples/companion_radio/DataStore.h r.8 |
MillisecondClock |
src/Dispatcher.h r.14 |
Radio |
src/Dispatcher.h r.22 |
PacketManager |
src/Dispatcher.h r.85 |
MeshTables |
src/Mesh.h r.16 |
MainBoard |
src/MeshCore.h r.45 |
RTCClock |
src/MeshCore.h r.80 |
RNG |
src/Utils.h r.9 |
AbstractBridge |
src/helpers/AbstractBridge.h r.5 |
BaseSerialInterface |
src/helpers/BaseSerialInterface.h r.7 |
CommonCLICallbacks |
src/helpers/CommonCLI.h r.68 |
SensorManager |
src/helpers/SensorManager.h r.12 |
LocationProvider |
src/helpers/sensors/LocationProvider.h r.6 |
DisplayDriver |
src/helpers/ui/DisplayDriver.h r.6 |
Twee dingen vallen op aan deze lijst.
SensorManager en LocationProvider staan niet in src/ maar in
src/helpers/. Dat is geen vergissing: het zijn contracten die pas nodig
werden toen sensoren erbij kwamen, en ze zijn niet naar de kern verhuisd.
CommonCLICallbacks en DataStoreHost draaien de afhankelijkheid om. Ze
worden gedefinieerd door de laag die eronder zit, maar geïmplementeerd door de
applicatie erboven — MyMesh in examples/simple_repeater/ implementeert
CommonCLICallbacks, zodat de bediening in src/helpers/CommonCLI.cpp
iets kan aanroepen zonder te weten welke applicatie draait. De onderliggende
laag roept de bovenliggende aan zonder hem te kennen.
Groep 2 — implementatieklassen (50)¶
| Klasse | Contract | Plek | Erft van |
|---|---|---|---|
ESP32Board |
Bord | src/helpers/ESP32Board.h r.18 |
mesh::MainBoard |
MeshadventurerBoard |
Bord | src/helpers/MeshadventurerBoard.h r.20 |
ESP32Board |
NRF52Board |
Bord | src/helpers/NRF52Board.h r.27 |
mesh::MainBoard |
NRF52BoardDCDC |
Bord | src/helpers/NRF52Board.h r.74 |
NRF52Board |
STM32Board |
Bord | src/helpers/stm32/STM32Board.h r.6 |
mesh::MainBoard |
TBeamBoard |
Bord | src/helpers/esp32/TBeamBoard.h r.91 |
ESP32Board |
BridgeBase |
Brug | src/helpers/bridges/BridgeBase.h r.21 |
AbstractBridge |
ESPNowBridge |
Brug | src/helpers/bridges/ESPNowBridge.h r.42 |
BridgeBase |
RS232Bridge |
Brug | src/helpers/bridges/RS232Bridge.h r.47 |
BridgeBase |
SimpleMeshTables |
Gezien-tabel | src/helpers/SimpleMeshTables.h r.11 |
mesh::MeshTables |
LocalIdentity |
Identiteit | src/Identity.h r.54 |
Identity |
AutoDiscoverRTCClock |
Klok | src/helpers/AutoDiscoverRTCClock.h r.7 |
mesh::RTCClock |
ESP32RTCClock |
Klok | src/helpers/ESP32Board.h r.160 |
mesh::RTCClock |
VolatileRTCClock |
Klok | src/helpers/ArduinoHelpers.h r.6 |
mesh::RTCClock |
ArduinoSerialInterface |
Koppelvlak | src/helpers/ArduinoSerialInterface.h r.6 |
BaseSerialInterface |
SerialBLEInterface |
Koppelvlak | src/helpers/esp32/SerialBLEInterface.h r.9 |
BaseSerialInterface, BLESecurityCallbacks, BLEServerCallbacks, BLECharacteristicCallbacks |
SerialBLEInterface |
Koppelvlak | src/helpers/nrf52/SerialBLEInterface.h r.10 |
BaseSerialInterface |
SerialWifiInterface |
Koppelvlak | src/helpers/esp32/SerialWifiInterface.h r.6 |
BaseSerialInterface |
MicroNMEALocationProvider |
Locatie | src/helpers/sensors/MicroNMEALocationProvider.h r.36 |
LocationProvider |
RAK12500LocationProvider |
Locatie | src/helpers/sensors/EnvironmentSensorManager.cpp r.177 |
LocationProvider |
BaseChatMesh |
Mesh | src/helpers/BaseChatMesh.h r.59 |
mesh::Mesh |
MyMesh |
Mesh | examples/simple_secure_chat/main.cpp r.73 |
BaseChatMesh, ContactVisitor |
MyMesh |
Mesh | examples/simple_repeater/MyMesh.h r.83 |
mesh::Mesh, CommonCLICallbacks |
MyMesh |
Mesh | examples/simple_room_server/MyMesh.h r.91 |
mesh::Mesh, CommonCLICallbacks |
MyMesh |
Mesh | examples/simple_sensor/main.cpp r.8 |
SensorMesh |
MyMesh |
Mesh | examples/companion_radio/MyMesh.h r.87 |
BaseChatMesh, DataStoreHost |
SensorMesh |
Mesh | examples/simple_sensor/SensorMesh.h r.49 |
mesh::Mesh, CommonCLICallbacks |
ArduinoMillis |
Millisecondeklok | src/helpers/ArduinoHelpers.h r.22 |
mesh::MillisecondClock |
StaticPoolPacketManager |
Pakketpool | src/helpers/StaticPoolPacketManager.h r.21 |
mesh::PacketManager |
CustomLLCC68Wrapper |
Radio | src/helpers/radiolib/CustomLLCC68Wrapper.h r.7 |
RadioLibWrapper |
CustomLR1110Wrapper |
Radio | src/helpers/radiolib/CustomLR1110Wrapper.h r.7 |
RadioLibWrapper |
CustomSTM32WLxWrapper |
Radio | src/helpers/radiolib/CustomSTM32WLxWrapper.h r.8 |
RadioLibWrapper |
CustomSX1262Wrapper |
Radio | src/helpers/radiolib/CustomSX1262Wrapper.h r.11 |
RadioLibWrapper |
CustomSX1268Wrapper |
Radio | src/helpers/radiolib/CustomSX1268Wrapper.h r.11 |
RadioLibWrapper |
CustomSX1276Wrapper |
Radio | src/helpers/radiolib/CustomSX1276Wrapper.h r.10 |
RadioLibWrapper |
ESPNOWRadio |
Radio | src/helpers/esp32/ESPNOWRadio.h r.5 |
mesh::Radio |
RadioLibWrapper |
Radio | src/helpers/radiolib/RadioLibWrappers.h r.6 |
mesh::Radio |
E213Display |
Scherm | src/helpers/ui/E213Display.h r.12 |
DisplayDriver |
E290Display |
Scherm | src/helpers/ui/E290Display.h r.12 |
DisplayDriver |
GxEPDDisplay |
Scherm | src/helpers/ui/GxEPDDisplay.h r.19 |
DisplayDriver |
LGFXDisplay |
Scherm | src/helpers/ui/LGFXDisplay.h r.12 |
DisplayDriver |
NullDisplayDriver |
Scherm | src/helpers/ui/NullDisplayDriver.h r.5 |
DisplayDriver |
SSD1306Display |
Scherm | src/helpers/ui/SSD1306Display.h r.18 |
DisplayDriver |
ST7735Display |
Scherm | src/helpers/ui/ST7735Display.h r.10 |
DisplayDriver |
ST7789Display |
Scherm | src/helpers/ui/ST7789Display.h r.9 |
DisplayDriver |
ST7789LCDDisplay |
Scherm | src/helpers/ui/ST7789LCDDisplay.h r.10 |
DisplayDriver |
U8g2Display |
Scherm | src/helpers/ui/U8g2Display.h r.19 |
DisplayDriver |
EnvironmentSensorManager |
Sensorbeheer | src/helpers/sensors/EnvironmentSensorManager.h r.7 |
SensorManager |
RadioNoiseListener |
Entropiebron | src/helpers/radiolib/RadioLibWrappers.h r.74 |
mesh::RNG |
StdRNG |
Entropiebron | src/helpers/ArduinoHelpers.h r.27 |
mesh::RNG |
[!NOTE] De kolom Erft van geeft de basisklassen zoals ze in de declaratie staan, zonder het toegangsniveau. Eén uitzondering is het vermelden waard:
NRF52BoardDCDCerftvirtual public NRF52Board. Die virtuele overerving is nodig omdat er dertig bordklassen invariants/onder hangen die langs twee wegen bijNRF52Boarduitkomen; zondervirtualzou elk van die borden twee kopieën van de basisklasse krijgen.
SerialBLEInterface en MyMesh komen meer dan eens voor. Dat is geen fout in
de tabel: het zijn verschillende klassen met dezelfde naam, in verschillende
bestanden, en per build compileert er precies één van. SerialBLEInterface
bestaat twee keer — één voor ESP32, één voor nRF52 — en MyMesh vijf keer,
één per applicatie die er een nodig heeft.
Groep 3 — zelfstandig (55)¶
| Klasse | Plek |
|---|---|
AbstractUITask |
examples/companion_radio/AbstractUITask.h r.25 |
DataStore |
examples/companion_radio/DataStore.h r.16 |
SplashScreen |
examples/companion_radio/ui-new/UITask.cpp r.34 |
HomeScreen |
examples/companion_radio/ui-new/UITask.cpp r.86 |
MsgPreviewScreen |
examples/companion_radio/ui-new/UITask.cpp r.466 |
UITask |
examples/companion_radio/ui-new/UITask.h r.25 |
Button |
examples/companion_radio/ui-orig/Button.h r.12 |
UITask |
examples/companion_radio/ui-orig/UITask.h r.17 |
ScrollingStatusBar |
examples/companion_radio/ui-tiny/ScrollingStatusBar.h r.18 |
SplashScreen |
examples/companion_radio/ui-tiny/UITask.cpp r.34 |
HomeScreen |
examples/companion_radio/ui-tiny/UITask.cpp r.90 |
UITask |
examples/companion_radio/ui-tiny/UITask.h r.28 |
KissModem |
examples/kiss_modem/KissModem.h r.100 |
RateLimiter |
examples/simple_repeater/RateLimiter.h r.5 |
UITask |
examples/simple_repeater/UITask.h r.6 |
UITask |
examples/simple_room_server/UITask.h r.6 |
TimeSeriesData |
examples/simple_sensor/TimeSeriesData.h r.11 |
UITask |
examples/simple_sensor/UITask.h r.6 |
Dispatcher |
src/Dispatcher.h r.116 |
Identity |
src/Identity.h r.11 |
GroupChannel |
src/Mesh.h r.7 |
Mesh |
src/Mesh.h r.26 |
Packet |
src/Packet.h r.42 |
Utils |
src/Utils.h r.19 |
AdvertDataBuilder |
src/helpers/AdvertDataHelpers.h r.19 |
AdvertDataParser |
src/helpers/AdvertDataHelpers.h r.43 |
AdvertTimeHelper |
src/helpers/AdvertDataHelpers.h r.68 |
ContactVisitor |
src/helpers/BaseChatMesh.h r.23 |
ContactsIterator |
src/helpers/BaseChatMesh.h r.30 |
ClientACL |
src/helpers/ClientACL.h r.40 |
CommonCLI |
src/helpers/CommonCLI.h r.117 |
IdentityStore |
src/helpers/IdentityStore.h r.14 |
RTC_RX8130CE |
src/helpers/RTC_RX8130CE.h r.9 |
RefCountedDigitalPin |
src/helpers/RefCountedDigitalPin.h r.5 |
BufStream |
src/helpers/RegionMap.cpp r.7 |
RegionMap |
src/helpers/RegionMap.h r.23 |
PacketQueue |
src/helpers/StaticPoolPacketManager.h r.5 |
StatsFormatHelper |
src/helpers/StatsFormatHelper.h r.5 |
TransportKeyStore |
src/helpers/TransportKeyStore.h r.16 |
StrHelper |
src/helpers/TxtDataHelpers.h r.12 |
CustomLLCC68 |
src/helpers/radiolib/CustomLLCC68.h r.8 |
CustomLR1110 |
src/helpers/radiolib/CustomLR1110.h r.6 |
CustomSTM32WLx |
src/helpers/radiolib/CustomSTM32WLx.h r.8 |
CustomSX1262 |
src/helpers/radiolib/CustomSX1262.h r.8 |
CustomSX1268 |
src/helpers/radiolib/CustomSX1268.h r.8 |
CustomSX1276 |
src/helpers/radiolib/CustomSX1276.h r.11 |
LPPReader |
src/helpers/sensors/LPPDataHelpers.h r.66 |
LPPWriter |
src/helpers/sensors/LPPDataHelpers.h r.175 |
GenericVibration |
src/helpers/ui/GenericVibration.h r.21 |
MomentaryButton |
src/helpers/ui/MomentaryButton.h r.11 |
String |
src/helpers/ui/OLEDDisplay.h r.50 |
OLEDDisplay |
src/helpers/ui/OLEDDisplay.h r.159 |
OLEDDisplay |
src/helpers/ui/OLEDDisplay.h r.161 |
ST7789Spi |
src/helpers/ui/ST7789Spi.h r.96 |
UIScreen |
src/helpers/ui/UIScreen.h r.17 |
[!NOTE]
OLEDDisplaykomt twee keer voor insrc/helpers/ui/OLEDDisplay.h, op regel 159 en 161, achter een#if— de ene versie erft vanStream.Stringop regel 50 in datzelfde bestand is een vooruitverwijzing uit meegeleverde code. Beide zijn geen MeshCore-ontwerp maar overgenomen code van ThingPulse; zie De broncodestructuur.
De 77 uit variants/¶
variants/ telt 77 klassendeclaraties onder 73 unieke namen — vier namen
komen in meer dan één variantmap voor. Ze zijn niet stuk voor stuk
uitgeschreven, omdat ze alle hetzelfde doen: een contract implementeren met de
pinbezetting van één bord.
| Contract dat wordt geïmplementeerd | Klassen |
|---|---|
| Bord | 65 |
| Sensorbeheer | 7 |
| Scherm | 3 |
| Entropiebron | 2 |
De 65 bordklassen implementeren alle hetzelfde contract op dezelfde manier.
Vier ervan zijn wél apart het noemen waard, omdat ze de enige
RP2040-bordklassen zijn: die familie heeft als enige geen gedeelde bordklasse
in src/helpers/.
| RP2040-bordklasse | Plek |
|---|---|
RAK11310Board |
variants/rak11310/RAK11310Board.h r.15 |
PicoWBoard |
variants/rpi_picow/PicoWBoard.h r.11 |
WaveshareBoard |
variants/waveshare_rp2040_lora/WaveshareBoard.h r.27 |
XiaoRP2040Board |
variants/xiao_rp2040/XiaoRP2040Board.h r.25 |
Alle andere bordklassen erven van een gedeelde ouder — 30 van
NRF52BoardDCDC, 23 van ESP32Board, 3 van NRF52Board, 3 van
STM32Board, plus enkele van HeltecV3Board en TBeamBoard. Deze vier
erven rechtstreeks van mesh::MainBoard en schrijven dus zelf uit wat de
andere 61 van hun ouder krijgen.
Narekenen¶
De aantallen in dit hoofdstuk komen uit tools/design-overview.py:
python3 tools/design-overview.py /pad/naar/MeshCore --classes
Het script telt elke regel van de vorm class Naam { … of
class Naam : basis { … met de accolade op dezelfde regel. struct telt niet
mee, voorwaartse declaraties zonder body evenmin.