| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- #pragma once
- #include <Arduino.h>
- #include <Mesh.h>
- #include "AbstractUITask.h"
- /*------------ Frame Protocol --------------*/
- #define FIRMWARE_VER_CODE 7
- #ifndef FIRMWARE_BUILD_DATE
- #define FIRMWARE_BUILD_DATE "2 Oct 2025"
- #endif
- #ifndef FIRMWARE_VERSION
- #define FIRMWARE_VERSION "v1.9.1"
- #endif
- #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
- #include <InternalFileSystem.h>
- #elif defined(RP2040_PLATFORM)
- #include <LittleFS.h>
- #elif defined(ESP32)
- #include <SPIFFS.h>
- #endif
- #include "DataStore.h"
- #include "NodePrefs.h"
- #include <RTClib.h>
- #include <helpers/ArduinoHelpers.h>
- #include <helpers/BaseSerialInterface.h>
- #include <helpers/IdentityStore.h>
- #include <helpers/SimpleMeshTables.h>
- #include <helpers/StaticPoolPacketManager.h>
- #include <target.h>
- /* ---------------------------------- CONFIGURATION ------------------------------------- */
- #ifndef LORA_FREQ
- #define LORA_FREQ 915.0
- #endif
- #ifndef LORA_BW
- #define LORA_BW 250
- #endif
- #ifndef LORA_SF
- #define LORA_SF 10
- #endif
- #ifndef LORA_CR
- #define LORA_CR 5
- #endif
- #ifndef LORA_TX_POWER
- #define LORA_TX_POWER 20
- #endif
- #ifndef MAX_LORA_TX_POWER
- #define MAX_LORA_TX_POWER LORA_TX_POWER
- #endif
- #ifndef MAX_CONTACTS
- #define MAX_CONTACTS 100
- #endif
- #ifndef OFFLINE_QUEUE_SIZE
- #define OFFLINE_QUEUE_SIZE 16
- #endif
- #ifndef BLE_NAME_PREFIX
- #define BLE_NAME_PREFIX "MeshCore-"
- #endif
- #include <helpers/BaseChatMesh.h>
- /* -------------------------------------------------------------------------------------- */
- #define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
- #define REQ_TYPE_KEEP_ALIVE 0x02
- #define REQ_TYPE_GET_TELEMETRY_DATA 0x03
- struct AdvertPath {
- uint8_t pubkey_prefix[7];
- uint8_t path_len;
- char name[32];
- uint32_t recv_timestamp;
- uint8_t path[MAX_PATH_SIZE];
- };
- class MyMesh : public BaseChatMesh, public DataStoreHost {
- public:
- MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui=NULL);
- void begin(bool has_display);
- void startInterface(BaseSerialInterface &serial);
- const char *getNodeName();
- NodePrefs *getNodePrefs();
- uint32_t getBLEPin();
- void loop();
- void handleCmdFrame(size_t len);
- bool advert();
- void enterCLIRescue();
- int getRecentlyHeard(AdvertPath dest[], int max_num);
- protected:
- float getAirtimeBudgetFactor() const override;
- int getInterferenceThreshold() const override;
- int calcRxDelay(float score, uint32_t air_time) const override;
- uint8_t getExtraAckTransmitCount() const override;
- void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override;
- bool isAutoAddEnabled() const override;
- bool onContactPathRecv(ContactInfo& from, uint8_t* in_path, uint8_t in_path_len, uint8_t* out_path, uint8_t out_path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
- void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override;
- void onContactPathUpdated(const ContactInfo &contact) override;
- ContactInfo* processAck(const uint8_t *data) override;
- void queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packet *pkt, uint32_t sender_timestamp,
- const uint8_t *extra, int extra_len, const char *text);
- void onMessageRecv(const ContactInfo &from, mesh::Packet *pkt, uint32_t sender_timestamp,
- const char *text) override;
- void onCommandDataRecv(const ContactInfo &from, mesh::Packet *pkt, uint32_t sender_timestamp,
- const char *text) override;
- void onSignedMessageRecv(const ContactInfo &from, mesh::Packet *pkt, uint32_t sender_timestamp,
- const uint8_t *sender_prefix, const char *text) override;
- void onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint32_t timestamp,
- const char *text) override;
- uint8_t onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp, const uint8_t *data,
- uint8_t len, uint8_t *reply) override;
- void onContactResponse(const ContactInfo &contact, const uint8_t *data, uint8_t len) override;
- void onRawDataRecv(mesh::Packet *packet) override;
- void onTraceRecv(mesh::Packet *packet, uint32_t tag, uint32_t auth_code, uint8_t flags,
- const uint8_t *path_snrs, const uint8_t *path_hashes, uint8_t path_len) override;
- uint32_t calcFloodTimeoutMillisFor(uint32_t pkt_airtime_millis) const override;
- uint32_t calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t path_len) const override;
- void onSendTimeout() override;
- // DataStoreHost methods
- bool onContactLoaded(const ContactInfo& contact) override { return addContact(contact); }
- bool getContactForSave(uint32_t idx, ContactInfo& contact) override { return getContactByIdx(idx, contact); }
- bool onChannelLoaded(uint8_t channel_idx, const ChannelDetails& ch) override { return setChannel(channel_idx, ch); }
- bool getChannelForSave(uint8_t channel_idx, ChannelDetails& ch) override { return getChannel(channel_idx, ch); }
- void clearPendingReqs() {
- pending_login = pending_status = pending_telemetry = pending_discovery = pending_req = 0;
- }
- private:
- void writeOKFrame();
- void writeErrFrame(uint8_t err_code);
- void writeDisabledFrame();
- void writeContactRespFrame(uint8_t code, const ContactInfo &contact);
- void updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len);
- void addToOfflineQueue(const uint8_t frame[], int len);
- int getFromOfflineQueue(uint8_t frame[]);
- int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override {
- return _store->getBlobByKey(key, key_len, dest_buf);
- }
- bool putBlobByKey(const uint8_t key[], int key_len, const uint8_t src_buf[], int len) override {
- return _store->putBlobByKey(key, key_len, src_buf, len);
- }
- void checkCLIRescueCmd();
- void checkSerialInterface();
- // helpers, short-cuts
- void savePrefs() { _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon); }
- void saveChannels() { _store->saveChannels(this); }
- void saveContacts() { _store->saveContacts(this); }
- private:
- DataStore* _store;
- NodePrefs _prefs;
- uint32_t pending_login;
- uint32_t pending_status;
- uint32_t pending_telemetry, pending_discovery; // pending _TELEMETRY_REQ
- uint32_t pending_req; // pending _BINARY_REQ
- BaseSerialInterface *_serial;
- AbstractUITask* _ui;
- ContactsIterator _iter;
- uint32_t _iter_filter_since;
- uint32_t _most_recent_lastmod;
- uint32_t _active_ble_pin;
- bool _iter_started;
- bool _cli_rescue;
- char cli_command[80];
- uint8_t app_target_ver;
- uint8_t *sign_data;
- uint32_t sign_data_len;
- unsigned long dirty_contacts_expiry;
- uint8_t cmd_frame[MAX_FRAME_SIZE + 1];
- uint8_t out_frame[MAX_FRAME_SIZE + 1];
- CayenneLPP telemetry;
- struct Frame {
- uint8_t len;
- uint8_t buf[MAX_FRAME_SIZE];
- bool isChannelMsg() const;
- };
- int offline_queue_len;
- Frame offline_queue[OFFLINE_QUEUE_SIZE];
- struct AckTableEntry {
- unsigned long msg_sent;
- uint32_t ack;
- ContactInfo* contact;
- };
- #define EXPECTED_ACK_TABLE_SIZE 8
- AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table
- int next_ack_idx;
- #define ADVERT_PATH_TABLE_SIZE 16
- AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
- };
- extern MyMesh the_mesh;
|