// SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012-2024 Scott Penrose and WII5 Buoy contributors // // This file is part of WII5 Buoy firmware. // See LICENSE for full terms. /** * @file WII5Communications.h * @brief High-level communications dispatcher: orchestrates Iridium send/receive flows. */ #ifndef WII5Communications_h #define WII5Communications_h #include #include enum WII5COMMUNICATIONS_STEPS { WII5COMMUNICATIONS_DISABLED, WII5COMMUNICATIONS_IDLE, WII5COMMUNICATIONS_PREPARE, WII5COMMUNICATIONS_IRIDIUM_START, WII5COMMUNICATIONS_JUMP, WII5COMMUNICATIONS_FIND, WII5COMMUNICATIONS_SD_NEXT, WII5COMMUNICATIONS_SD_BLOCK, WII5COMMUNICATIONS_IRIDIUM_SEND, WII5COMMUNICATIONS_IRIDIUM_SEND_WAIT, WII5COMMUNICATIONS_END }; /** * @brief Communications orchestration: manages a state machine across * Iridium send/receive cycles, including pulling messages from SD blocks * and splitting them across multiple SBD frames when too large. * * Three orthogonal modes: * - autoMode: scan SD for unsent metadata and push it * - simpleMode: only send what's explicitly requested * - testMode: smoke-test the comms path without burning satellite minutes * * Plus a `disabled` master switch. */ class WII5Communications : public WII5Mode { public: WII5Communications() {} /** @brief Is the comms state machine actively in a send/receive cycle? */ bool isRunning(); /** @brief One-time bring-up. */ void begin(); /** @brief State-machine tick: drives Iridium and SD interactions. */ void loop(); /** @brief Begin a new comms cycle (send pending data). */ void start(); /** @brief Abort the current comms cycle and idle. */ void stop(); /** @brief Hint to autoMode that the SD card has fresh data worth scanning. */ void signalSD(); /** @brief Queue a BinData message of type `t`, optionally pulled from given SD blocks. */ void sendBinModeType(uint32_t t, uint32_t recordCount, uint32_t mdBlock = 0, uint32_t resultsBlock = 0); /** @brief Send arbitrary buffered text (bypasses the BinData frame). */ void sendText(void *buf = NULL, uint16_t bufSize = 0); /** @brief Send the most recent error as an SBD message. */ void sendError(); /** @brief Find an SD record matching (binType, recordCount) for retransmission. */ void findRecord(uint32_t t, uint32_t recordCount); /** @brief Enable test mode (no real Iridium traffic). */ void setTESTING(); /** @brief Enable autoMode: periodically scan SD and push new data. */ void setAutoMode(); /** @brief Enable simpleMode: send only what is explicitly requested. */ void setSimpleMode(); /** @brief Is autoMode currently the active mode? */ bool getAutoMode(); /** @brief Is simpleMode currently the active mode? */ bool getSimpleMode(); /** @brief Master enable/disable; returns previous state. */ bool setDisabled(bool in); protected: // Mode - These are actually mutually exclusive - disabled | noiridium | auto | test bool disabled; bool autoMode; bool metadataScan; bool testMode; elapsedMillis lastSuccess; // Send a message elapsedMillis requestWait; uint32_t requestBinType; uint32_t requestRecordCount; uint32_t requestMetadataBlock; uint32_t requestResultsBlock; uint8_t sdCardId; bool updateStatus; uint32_t sdStartBlock; uint32_t sdCurrentBlock; uint8_t countSucces; uint8_t countFailed; uint16_t countSend; bool waitStatus; uint32_t sdDone; uint32_t sdTried; uint32_t findBinType; uint32_t findRecordCount; // Loop bool first; elapsedMillis displayWait; elapsedMillis wait; WII5COMMUNICATIONS_STEPS step; WII5COMMUNICATIONS_STEPS lastStep; uint32_t minutes; // since midnight. // State of the split to smaller chunks uint8_t binNextBit; uint8_t binCount; uint32_t binType; // The block we are working on uint32_t mainBinType; uint32_t metadataBlock; uint32_t resultsBlock; uint32_t mainRecordCount; }; extern WII5Communications wii5Communications; #endif