diff --git a/examples/companion_radio/AbstractUITask.h b/examples/companion_radio/AbstractUITask.h index b25b1442f..d927c1a3f 100644 --- a/examples/companion_radio/AbstractUITask.h +++ b/examples/companion_radio/AbstractUITask.h @@ -12,6 +12,7 @@ #endif #include "NodePrefs.h" +#include "MyMesh.h" enum class UIEventType { none, @@ -22,25 +23,21 @@ enum class UIEventType { ack }; -class AbstractUITask { +class AbstractUITask : public MyMesh::Listener { protected: mesh::MainBoard* _board; MultiSerialInterface* _interfaceManager; - bool _connected; AbstractUITask(mesh::MainBoard* board, MultiSerialInterface* interfaceManager) : _board(board), _interfaceManager(interfaceManager) { - _connected = false; } public: - void setHasConnection(bool connected) { _connected = connected; } - bool hasConnection() const { return _connected; } + bool hasConnection() const { return _interfaceManager->isConnected(); } uint16_t getBattMilliVolts() const { return _board->getBattMilliVolts(); } bool isBluetoothEnabled() const { return _interfaceManager->isBluetoothEnabled(); } void enableBluetooth() { _interfaceManager->enableBluetooth(); } void disableBluetooth() { _interfaceManager->disableBluetooth(); } - virtual void msgRead(int msgcount) = 0; - virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0; + virtual void notify(UIEventType t = UIEventType::none) = 0; virtual void loop() = 0; }; diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 01a7473a0..7becb0dfc 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -368,10 +368,6 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE); _serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE); } - } else { -#ifdef DISPLAY_CLASS - if (_ui) _ui->notify(UIEventType::newContactMessage); -#endif } // add inbound-path to mem cache @@ -395,6 +391,8 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path p->path_len = mesh::Packet::copyPath(p->path, path, path_len); } + if (_listener) _listener->onDiscoveredContact(contact, is_new, path_len, path); + if (!is_new) dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY); // only schedule lazy write for contacts that are in contacts[] } @@ -520,16 +518,12 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe _serial->writeFrame(frame, 1); } -#ifdef DISPLAY_CLASS // we only want to show text messages on display, not cli data bool should_display = txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_SIGNED_PLAIN; - if (should_display && _ui) { - _ui->newMsg(path_len, from.name, text, offline_queue_len); - if (!_serial->isConnected()) { - _ui->notify(UIEventType::contactMessage); - } + if (should_display && _listener) { + _listener->onMessageRecv(path_len, from.name, text); + _listener->onQueueSizeChanged(offline_queue_len); } -#endif } bool MyMesh::filterRecvFloodPacket(mesh::Packet* packet) { @@ -640,20 +634,16 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe uint8_t frame[1]; frame[0] = PUSH_CODE_MSG_WAITING; // send push 'tickle' _serial->writeFrame(frame, 1); - } else { -#ifdef DISPLAY_CLASS - if (_ui) _ui->notify(UIEventType::channelMessage); -#endif } -#ifdef DISPLAY_CLASS - // Get the channel name from the channel index - const char *channel_name = "Unknown"; - ChannelDetails channel_details; - if (getChannel(channel_idx, channel_details)) { - channel_name = channel_details.name; + if (_listener) { + // Get the channel name from the channel index + ChannelDetails channel_details; + if (!getChannel(channel_idx, channel_details)) { + strcpy(channel_details.name, "Unknown"); + } + _listener->onChannelMsgRecv(channel_details, path_len, text); + _listener->onQueueSizeChanged(offline_queue_len); } - if (_ui) _ui->newMsg(path_len, channel_name, text, offline_queue_len); -#endif } void MyMesh::onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint16_t data_type, @@ -930,9 +920,9 @@ uint32_t MyMesh::calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t void MyMesh::onSendTimeout() {} -MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui) +MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store) : BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables), - _serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui), _iter(0) { + _serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _listener(NULL), _iter(0) { _iter_started = false; _cli_rescue = false; cli_command[0] = 0; @@ -1463,9 +1453,7 @@ void MyMesh::handleCmdFrame(size_t len) { int out_len; if ((out_len = getFromOfflineQueue(out_frame)) > 0) { _serial->writeFrame(out_frame, out_len); -#ifdef DISPLAY_CLASS - if (_ui) _ui->msgRead(offline_queue_len); -#endif + if (_listener) _listener->onQueueSizeChanged(offline_queue_len); } else { out_frame[0] = RESP_CODE_NO_MORE_MESSAGES; _serial->writeFrame(out_frame, 1); @@ -2466,10 +2454,6 @@ void MyMesh::loop() { saveContacts(); dirty_contacts_expiry = 0; } - -#ifdef DISPLAY_CLASS - if (_ui) _ui->setHasConnection(_serial->isConnected()); -#endif } bool MyMesh::advert() { diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index 3b98a4f67..be7bc40a5 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -2,7 +2,6 @@ #include #include -#include "AbstractUITask.h" /*------------ Frame Protocol --------------*/ #define FIRMWARE_VER_CODE 14 @@ -96,10 +95,19 @@ struct DiscoveredNode { class MyMesh : public BaseChatMesh, public DataStoreHost { public: - MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui=NULL); + class Listener { + public: + virtual void onMessageRecv(uint8_t path_len, const char* from_name, const char* text) = 0; + virtual void onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) = 0; + virtual void onQueueSizeChanged(int msgcount) = 0; + virtual void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) = 0; + }; + + MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store); void begin(bool has_display); void startInterface(BaseSerialInterface &serial); + void setListener(Listener* listener) { _listener = listener; } const char *getNodeName(); NodePrefs *getNodePrefs(); @@ -237,7 +245,7 @@ private: uint32_t pending_telemetry, pending_discovery; // pending _TELEMETRY_REQ uint32_t pending_req; // pending _BINARY_REQ BaseSerialInterface *_serial; - AbstractUITask* _ui; + Listener* _listener; ContactsIterator _iter; uint32_t _iter_filter_since; diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 6dc9acdc3..857acf451 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -114,11 +114,7 @@ MultiSerialInterface interface_manager; StdRNG fast_rng; SimpleMeshTables tables; -MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store - #ifdef DISPLAY_CLASS - , &ui_task - #endif -); +MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store); /* END GLOBAL OBJECTS */ @@ -285,6 +281,7 @@ void setup() { #ifdef DISPLAY_CLASS ui_task.begin(disp, &sensors, the_mesh.getNodePrefs()); // still want to pass this in as dependency, as prefs might be moved + the_mesh.setListener(&ui_task); #endif board.onBootComplete(); diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 53ae480cf..fc6707e29 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -751,17 +751,7 @@ switch(t){ #endif } - -void UITask::msgRead(int msgcount) { - _msgcount = msgcount; - if (msgcount == 0) { - gotoHomeScreen(); - } -} - -void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) { - _msgcount = msgcount; - +void UITask::onMessageRecv(uint8_t path_len, const char* from_name, const char* text) { ((MsgPreviewScreen *) msg_preview)->addPreview(path_len, from_name, text); setCurrScreen(msg_preview); @@ -774,6 +764,42 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i _next_refresh = 100; // trigger refresh } } + + if (!hasConnection()) { + notify(UIEventType::contactMessage); + } +} + +void UITask::onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) { + ((MsgPreviewScreen *) msg_preview)->addPreview(path_len, channel_details.name, text); + setCurrScreen(msg_preview); + + if (_display != NULL) { + if (!_display->isOn() && !hasConnection()) { + _display->turnOn(); + } + if (_display->isOn()) { + _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer + _next_refresh = 100; // trigger refresh + } + } + + if (!hasConnection()) { + notify(UIEventType::channelMessage); + } +} + +void UITask::onQueueSizeChanged(int msgcount) { + _msgcount = msgcount; + if (msgcount == 0) { + gotoHomeScreen(); + } +} + +void UITask::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) { + if (!hasConnection()) { + notify(UIEventType::newContactMessage); + } } void UITask::userLedHandler() { diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index 52d3ffa13..e12009538 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -90,10 +90,13 @@ public: bool getGPSState(); void toggleGPS(); + // MyMesh::Listener + void onMessageRecv(uint8_t path_len, const char* from_name, const char* text) override; + void onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) override; + void onQueueSizeChanged(int offline_queue_size) override; + void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override; // from AbstractUITask - void msgRead(int msgcount) override; - void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override; void notify(UIEventType t = UIEventType::none) override; void loop() override; diff --git a/examples/companion_radio/ui-orig/UITask.cpp b/examples/companion_radio/ui-orig/UITask.cpp index b49b05dd1..08c845874 100644 --- a/examples/companion_radio/ui-orig/UITask.cpp +++ b/examples/companion_radio/ui-orig/UITask.cpp @@ -126,7 +126,7 @@ switch(t){ // Serial.println((int) t); } -void UITask::msgRead(int msgcount) { +void UITask::onQueueSizeChanged(int msgcount) { _msgcount = msgcount; if (msgcount == 0) { clearMsgPreview(); @@ -139,9 +139,7 @@ void UITask::clearMsgPreview() { _need_refresh = true; } -void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) { - _msgcount = msgcount; - +void UITask::onMessageRecv(uint8_t path_len, const char* from_name, const char* text) { #ifdef HAS_DRV2605 vibration.trigger(); // vibrate even while the app is connected (honors quiet + cooldown) #endif @@ -158,10 +156,45 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i _display->turnOn(); } if (_display->isOn()) { - _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer - _need_refresh = true; + _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer + _need_refresh = true; } } + if (!hasConnection()) { + notify(UIEventType::contactMessage); + } +} + +void UITask::onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) { +#ifdef HAS_DRV2605 + vibration.trigger(); // vibrate even while the app is connected (honors quiet + cooldown) +#endif + + if (path_len == 0xFF) { + sprintf(_origin, "(F) %s", channel_details.name); + } else { + sprintf(_origin, "(%d) %s", (uint32_t) path_len, channel_details.name); + } + StrHelper::strncpy(_msg, text, sizeof(_msg)); + + if (_display != NULL) { + if (!_display->isOn() && !hasConnection()) { + _display->turnOn(); + } + if (_display->isOn()) { + _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer + _need_refresh = true; + } + } + if (!hasConnection()) { + notify(UIEventType::channelMessage); + } +} + +void UITask::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) { + if (!hasConnection()) { + notify(UIEventType::newContactMessage); + } } void UITask::renderBatteryIndicator(uint16_t batteryMilliVolts) { @@ -262,7 +295,7 @@ void UITask::renderCurrScreen() { _display->print(tmp); // BT pin - if (!_connected && the_mesh.getBLEPin() != 0) { + if (!hasConnection() && the_mesh.getBLEPin() != 0) { _display->setColor(UIColor::warning_txt); _display->setTextSize(2); _display->setCursor(0, 43); diff --git a/examples/companion_radio/ui-orig/UITask.h b/examples/companion_radio/ui-orig/UITask.h index 02d126e8f..381414791 100644 --- a/examples/companion_radio/ui-orig/UITask.h +++ b/examples/companion_radio/ui-orig/UITask.h @@ -70,9 +70,13 @@ public: bool hasDisplay() const { return _display != NULL; } void clearMsgPreview(); + // MyMesh::Listener + void onMessageRecv(uint8_t path_len, const char* from_name, const char* text) override; + void onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) override; + void onQueueSizeChanged(int offline_queue_size) override; + void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override; + // from AbstractUITask - void msgRead(int msgcount) override; - void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override; void notify(UIEventType t = UIEventType::none) override; void loop() override; diff --git a/examples/companion_radio/ui-tiny/UITask.cpp b/examples/companion_radio/ui-tiny/UITask.cpp index 9ecd66f12..8a8b77b53 100644 --- a/examples/companion_radio/ui-tiny/UITask.cpp +++ b/examples/companion_radio/ui-tiny/UITask.cpp @@ -503,16 +503,14 @@ switch(t){ } -void UITask::msgRead(int msgcount) { +void UITask::onQueueSizeChanged(int msgcount) { _msgcount = msgcount; if (msgcount == 0) { gotoHomeScreen(); } } -void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) { - _msgcount = msgcount; - +void UITask::onMessageRecv(uint8_t path_len, const char* from_name, const char* text) { if (_display != NULL) { if (!_display->isOn() && !hasConnection()) { _display->turnOn(); @@ -522,6 +520,30 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i _next_refresh = 100; // trigger refresh } } + if (!hasConnection()) { + notify(UIEventType::contactMessage); + } +} + +void UITask::onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) { + if (_display != NULL) { + if (!_display->isOn() && !hasConnection()) { + _display->turnOn(); + } + if (_display->isOn()) { + _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer + _next_refresh = 100; // trigger refresh + } + } + if (!hasConnection()) { + notify(UIEventType::channelMessage); + } +} + +void UITask::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) { + if (!hasConnection()) { + notify(UIEventType::newContactMessage); + } } void UITask::userLedHandler() { diff --git a/examples/companion_radio/ui-tiny/UITask.h b/examples/companion_radio/ui-tiny/UITask.h index dc689478e..925e8d719 100644 --- a/examples/companion_radio/ui-tiny/UITask.h +++ b/examples/companion_radio/ui-tiny/UITask.h @@ -98,10 +98,13 @@ public: bool getGPSState(); void toggleGPS(); + // MyMesh::Listener + void onMessageRecv(uint8_t path_len, const char* from_name, const char* text) override; + void onChannelMsgRecv(ChannelDetails& channel_details, uint8_t path_len, const char* text) override; + void onQueueSizeChanged(int offline_queue_size) override; + void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override; // from AbstractUITask - void msgRead(int msgcount) override; - void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override; void notify(UIEventType t = UIEventType::none) override; void loop() override;