Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions examples/companion_radio/AbstractUITask.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#endif

#include "NodePrefs.h"
#include "MyMesh.h"

enum class UIEventType {
none,
Expand All @@ -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;
};
150 changes: 42 additions & 108 deletions examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,6 @@
#define ERR_CODE_FILE_IO_ERROR 5
#define ERR_CODE_ILLEGAL_ARG 6

// Copied from simple_repeater (could probably be shared)
#define CTL_TYPE_NODE_DISCOVER_REQ 0x80
#define CTL_TYPE_NODE_DISCOVER_RESP 0x90

#define MAX_SIGN_DATA_LEN (8 * 1024) // 8K

// Auto-add config bitmask
Expand Down Expand Up @@ -368,10 +364,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
Expand All @@ -395,6 +387,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[]
}

Expand All @@ -412,53 +406,6 @@ int MyMesh::getRecentlyHeard(AdvertPath dest[], int max_num) {
return max_num;
}

#if defined(DISPLAY_CLASS) && !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
int MyMesh::getDiscoveredNodes(DiscoveredNode nodes[], int max_num) {
if (max_num > DISCOVERED_NODES_TABLE_SIZE) max_num = DISCOVERED_NODES_TABLE_SIZE;
if (max_num > disc_nodes_count) max_num = disc_nodes_count;

for (int i = 0; i < max_num; i++) {
nodes[i] = discovered_nodes[i];
}
return max_num;
}

bool MyMesh::requestRepeatersDiscovery() {
uint8_t cmd_bytes[6];
cmd_bytes[0] = CTL_TYPE_NODE_DISCOVER_REQ | 1; // DISCOVER_REQ | prefix only
cmd_bytes[1] = 0xFF; // Repeaters
getRNG()->random(&cmd_bytes[2], 4); // tag
disc_nodes_count = 0;
disc_node_req_tag = *((uint32_t*)&cmd_bytes[2]);
mesh::Packet* req = createControlData(cmd_bytes, sizeof(cmd_bytes));
if (req) {
sendZeroHop(req);
return true;
}
return false;
}

void MyMesh::checkControlDataForPendingDiscovery(uint8_t payload[], size_t p_len) {
if ((p_len < 12)
|| (payload[0] & 0xF0 != CTL_TYPE_NODE_DISCOVER_RESP)
|| (disc_nodes_count >= DISCOVERED_NODES_TABLE_SIZE)
|| (memcmp(&payload[2], &disc_node_req_tag, 4))) {
return;
}
memcpy(&discovered_nodes[disc_nodes_count].pubkey_prefix, &payload[6], 8);
discovered_nodes[disc_nodes_count].type = payload[0] & 0xF;
discovered_nodes[disc_nodes_count].snr_out = ((int8_t)payload[1]) / 4.0;
discovered_nodes[disc_nodes_count].snr_in = _radio->getLastSNR();
ContactInfo* c = lookupContactByPubKey(&payload[6], 8);
if (c != NULL) {
strncpy(discovered_nodes[disc_nodes_count].name, c->name, 32);
} else {
discovered_nodes[disc_nodes_count].name[0] = 0;
}
disc_nodes_count ++;
}
#endif

void MyMesh::onContactPathUpdated(const ContactInfo &contact) {
out_frame[0] = PUSH_CODE_PATH_UPDATED;
memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE);
Expand All @@ -468,6 +415,11 @@ void MyMesh::onContactPathUpdated(const ContactInfo &contact) {
}

ContactInfo* MyMesh::processAck(const uint8_t *data) {
if (_listener) {
uint32_t ack_crc;
memcpy(&ack_crc, data, 4);
_listener->onACKRecv(ack_crc);
}
// see if matches any in a table
for (int i = 0; i < EXPECTED_ACK_TABLE_SIZE; i++) {
if (memcmp(data, &expected_ack_table[i].ack, 4) == 0) { // got an ACK from recipient
Expand Down Expand Up @@ -520,16 +472,10 @@ 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 (_listener) {
_listener->onMessageRecv(pkt, from, txt_type, sender_timestamp, text);
_listener->onQueueSizeChanged(offline_queue_len);
}
#endif
}

bool MyMesh::filterRecvFloodPacket(mesh::Packet* packet) {
Expand Down Expand Up @@ -640,20 +586,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->onChannelMessageRecv(pkt, channel_details, 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,
Expand Down Expand Up @@ -689,6 +631,9 @@ void MyMesh::onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *
frame[0] = PUSH_CODE_MSG_WAITING; // send push 'tickle'
_serial->writeFrame(frame, 1);
}
if (_listener) {
_listener->onChannelDataRecv(pkt, channel, data_type, data, data_len);
}
}

uint8_t MyMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp, const uint8_t *data,
Expand Down Expand Up @@ -736,6 +681,8 @@ uint8_t MyMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_tim
memcpy(&reply[4], telemetry.getBuffer(), tlen);
return 4 + tlen;
}
} else if (_listener) {
return _listener->onUnhandledRequest(contact, sender_timestamp, data, len, reply);
}
return 0; // unknown
}
Expand Down Expand Up @@ -811,6 +758,8 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
memcpy(&out_frame[i], &data[4], len - 4);
i += (len - 4);
_serial->writeFrame(out_frame, i);
} else if (_listener && len > 4) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (_listener && len > 4) {
} else if (_listener && len >= 4) {

_listener->onUnhandledResponse(contact, tag, &data[4], len - 4);
}
}

Expand Down Expand Up @@ -850,9 +799,6 @@ void MyMesh::onControlDataRecv(mesh::Packet *packet) {
MESH_DEBUG_PRINTLN("onControlDataRecv(), payload_len too long: %d", packet->payload_len);
return;
}
#if defined(DISPLAY_CLASS) && !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
checkControlDataForPendingDiscovery(packet->payload, packet->payload_len);
#endif
int i = 0;
out_frame[i++] = PUSH_CODE_CONTROL_DATA;
out_frame[i++] = (int8_t)(_radio->getLastSNR() * 4);
Expand All @@ -866,6 +812,8 @@ void MyMesh::onControlDataRecv(mesh::Packet *packet) {
} else {
MESH_DEBUG_PRINTLN("onControlDataRecv(), data received while app offline");
}

if (_listener) _listener->onControlDataRecv(packet);
}

void MyMesh::onRawDataRecv(mesh::Packet *packet) {
Expand All @@ -886,6 +834,9 @@ void MyMesh::onRawDataRecv(mesh::Packet *packet) {
} else {
MESH_DEBUG_PRINTLN("onRawDataRecv(), data received while app offline");
}
if (_listener) {
_listener->onRawDataRecv(packet);
}
}

void MyMesh::onTraceRecv(mesh::Packet *packet, uint32_t tag, uint32_t auth_code, uint8_t flags,
Expand Down Expand Up @@ -916,6 +867,9 @@ void MyMesh::onTraceRecv(mesh::Packet *packet, uint32_t tag, uint32_t auth_code,
} else {
MESH_DEBUG_PRINTLN("onTraceRecv(), data received while app offline");
}
if (_listener) {
_listener->onTraceRecv(packet, tag, auth_code, flags, path_snrs, path_hashes, path_len);
}
}

uint32_t MyMesh::calcFloodTimeoutMillisFor(uint32_t pkt_airtime_millis) const {
Expand All @@ -930,9 +884,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;
Expand Down Expand Up @@ -975,7 +929,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
#endif
}

void MyMesh::begin(bool has_display) {
void MyMesh::begin() {
BaseChatMesh::begin();

if (!_store->loadMainIdentity(self_id)) {
Expand Down Expand Up @@ -1027,29 +981,12 @@ void MyMesh::begin(bool has_display) {
_prefs.gps_enabled = constrain(_prefs.gps_enabled, 0, 1); // Ensure boolean 0 or 1
_prefs.gps_interval = constrain(_prefs.gps_interval, 0, 86400); // Max 24 hours

#ifdef BLE_PIN_CODE // 123456 by default
if (_prefs.ble_pin == 0) {
#ifdef DISPLAY_CLASS
if (has_display && BLE_PIN_CODE == 123456) {
StdRNG rng;
_active_ble_pin = rng.nextInt(100000, 999999); // random pin each session
} else {
_active_ble_pin = BLE_PIN_CODE; // otherwise static pin
}
#else
_active_ble_pin = BLE_PIN_CODE; // otherwise static pin
#endif
} else {
_active_ble_pin = _prefs.ble_pin;
}
#else
_active_ble_pin = 0;
#endif
_active_ble_pin = _prefs.ble_pin;

resetContacts();
_store->loadContacts(this);
bootstrapRTCfromContacts();
addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure public channel
_store->loadChannels(this);

radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
Expand All @@ -1071,6 +1008,9 @@ NodePrefs *MyMesh::getNodePrefs() {
uint32_t MyMesh::getBLEPin() {
return _active_ble_pin;
}
void MyMesh::setBLEPin(uint32_t active_pin) {
_active_ble_pin = active_pin;
}

struct FreqRange {
uint32_t lower_freq, upper_freq;
Expand Down Expand Up @@ -1463,9 +1403,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);
Expand Down Expand Up @@ -2466,10 +2404,6 @@ void MyMesh::loop() {
saveContacts();
dirty_contacts_expiry = 0;
}

#ifdef DISPLAY_CLASS
if (_ui) _ui->setHasConnection(_serial->isConnected());
#endif
}

bool MyMesh::advert() {
Expand Down
Loading
Loading