#pragma once #include #include #include // ZEPHCORE: neutralize STM32 CMSIS peripheral-instance macros (RNG, AES, ...) // that collide with portable mesh identifiers. No-op off STM32. #include #define MAX_HASH_SIZE 8 #define PUB_KEY_SIZE 32 #define PRV_KEY_SIZE 64 #define SEED_SIZE 32 #define SIGNATURE_SIZE 64 #define MAX_ADVERT_DATA_SIZE 32 #define CIPHER_KEY_SIZE 16 #define CIPHER_BLOCK_SIZE 16 // V1 #define CIPHER_MAC_SIZE 2 #define PATH_HASH_SIZE 1 #define MAX_PACKET_PAYLOAD 184 #define MAX_GROUP_DATA_LENGTH (MAX_PACKET_PAYLOAD - CIPHER_BLOCK_SIZE - 3) #define MAX_PATH_SIZE 64 #define MAX_TRANS_UNIT 255 #if MESH_DEBUG && ARDUINO #include #define MESH_DEBUG_PRINT(F, ...) Serial.printf("DEBUG: " F, ##__VA_ARGS__) #define MESH_DEBUG_PRINTLN(F, ...) Serial.printf("DEBUG: " F "\n", ##__VA_ARGS__) #elif defined(__ZEPHYR__) // ZEPHCORE: upstream's debug prints become Zephyr debug logs, compiled out // unless the file's log module is at DBG. The using file must register a // log module (LOG_MODULE_REGISTER / LOG_MODULE_DECLARE). #include #define MESH_DEBUG_PRINT(F, ...) LOG_DBG(F, ##__VA_ARGS__) #define MESH_DEBUG_PRINTLN(F, ...) LOG_DBG(F, ##__VA_ARGS__) #else #define MESH_DEBUG_PRINT(...) {} #define MESH_DEBUG_PRINTLN(...) {} #endif #if BRIDGE_DEBUG && ARDUINO #define BRIDGE_DEBUG_PRINTLN(F, ...) Serial.printf("%s BRIDGE: " F, getLogDateTime(), ##__VA_ARGS__) #else #define BRIDGE_DEBUG_PRINTLN(...) {} #endif namespace mesh { #define BD_STARTUP_NORMAL 0 // getStartupReason() codes #define BD_STARTUP_RX_PACKET 1 class MainBoard { public: virtual uint16_t getBattMilliVolts() = 0; virtual float getMCUTemperature() { return NAN; } virtual bool setAdcMultiplier(float multiplier) { return false; }; virtual float getAdcMultiplier() const { return 0.0f; } virtual const char* getManufacturerName() const = 0; virtual void onBeforeTransmit() { } virtual void onAfterTransmit() { } // ZEPHCORE: a valid packet has just been received. Unlike the transmit pair // this is a single edge, not a window: the packet is already over by the time // the radio reports it, so an LED implementation fires a one-shot. virtual void onPacketReceived() { } virtual void reboot() = 0; virtual void powerOff() { /* no op */ } // ZEPHCORE: no onBootComplete() (Arduino setup() hook) and no getIRQGpio() // (Arduino sleep-wake pin) -- nothing on Zephyr would call them. virtual void sleep(uint32_t secs) { /* no op */ } virtual uint32_t getGpio() { return 0; } virtual void setGpio(uint32_t values) {} virtual uint8_t getStartupReason() const = 0; virtual bool getBootloaderVersion(char* version, size_t max_len) { return false; } virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported // Power management interface (boards with power management override these) // ZEPHCORE: no isPwrMgtInitialised() / getWakeLpcompSupported() -- upstream's // nRF52 Arduino power manager; Zephyr PM covers this. virtual bool isExternalPowered() { return false; } // True while a board can identify an active battery-charging source. virtual bool isChargerActive() { return false; } // Optional, source-specific power detection. Boards that can distinguish a USB // supply from a solar charger override these; defaults keep every other board // unaffected (the generic CLI prints "n/a" when a capability is absent). virtual bool hasUsbPowerDetect() const { return false; } virtual bool isUsbPowered() { return false; } virtual bool hasSolarChargerDetect() const { return false; } virtual bool isSolarChargerActive() { return false; } virtual uint16_t getBootVoltage() { return 0; } virtual uint32_t getResetReason() const { return 0; } virtual const char* getResetReasonString(uint32_t reason) { return "Not available"; } virtual uint8_t getShutdownReason() const { return 0; } virtual const char* getShutdownReasonString(uint8_t reason) { return "Not available"; } virtual bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) { return false; } // ZEPHCORE: no loop() -- upstream polls it from the Arduino main loop. The mesh // thread here is event-driven and never polls; a board with periodic work owns // a timer or work item. Left out so a port calling board.loop() fails to // compile instead of silently doing nothing. }; /** * An abstraction of the device's Realtime Clock. */ class RTCClock { uint32_t last_unique; protected: RTCClock() { last_unique = 0; } public: /** * \returns the current time. in UNIX epoch seconds. */ virtual uint32_t getCurrentTime() = 0; /** * \param time current time in UNIX epoch seconds. */ virtual void setCurrentTime(uint32_t time) = 0; /** * override in classes that need to periodically update internal state */ virtual void tick() { /* no op */} uint32_t getCurrentTimeUnique() { uint32_t t = getCurrentTime(); if (t <= last_unique) { return ++last_unique; } return last_unique = t; } }; }