Skip to content
Open
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
54 changes: 54 additions & 0 deletions examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@
#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 @@ -403,6 +407,53 @@ 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 Down Expand Up @@ -783,6 +834,9 @@ 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 Down
28 changes: 28 additions & 0 deletions examples/companion_radio/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ struct AdvertPath {
uint8_t path[MAX_PATH_SIZE];
};

#if defined(DISPLAY_CLASS) && !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
struct DiscoveredNode {
uint8_t pubkey_prefix[9];
float snr_in;
float snr_out;
char name[32];
uint8_t type;
};
#endif

class MyMesh : public BaseChatMesh, public DataStoreHost {
public:
MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui=NULL);
Expand All @@ -102,6 +112,11 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {

int getRecentlyHeard(AdvertPath dest[], int max_num);

#if defined(DISPLAY_CLASS) && !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
bool requestRepeatersDiscovery();
int getDiscoveredNodes(DiscoveredNode nodes[], int max_num);
#endif

protected:
float getAirtimeBudgetFactor() const override;
int getInterferenceThreshold() const override;
Expand Down Expand Up @@ -256,6 +271,19 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {

#define ADVERT_PATH_TABLE_SIZE 16
AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table

#if defined(DISPLAY_CLASS) && !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
#ifdef UI_RECENT_LIST_SIZE
#define DISCOVERED_NODES_TABLE_SIZE UI_RECENT_LIST_SIZE
#else
#define DISCOVERED_NODES_TABLE_SIZE 4
#endif
DiscoveredNode discovered_nodes[DISCOVERED_NODES_TABLE_SIZE]; // not circular, latest discovered nodes are not kept
uint32_t disc_node_req_tag = 0;
uint32_t disc_nodes_count = 0;

void checkControlDataForPendingDiscovery(uint8_t payload[], size_t p_len);
#endif
};

extern MyMesh the_mesh;
62 changes: 61 additions & 1 deletion examples/companion_radio/ui-new/UITask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#define LONG_PRESS_MILLIS 1200

// Used both for recent adverts and discovered nodes
#ifndef UI_RECENT_LIST_SIZE
#define UI_RECENT_LIST_SIZE 4
#endif
Expand Down Expand Up @@ -101,6 +102,9 @@ class HomeScreen : public UIScreen {
#endif
#if UI_SENSORS_PAGE == 1
SENSORS,
#endif
#if !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
DISCOVERY,
#endif
SHUTDOWN,
Count // keep as last
Expand All @@ -113,7 +117,11 @@ class HomeScreen : public UIScreen {
uint8_t _page;
bool _shutdown_init;
AdvertPath recent[UI_RECENT_LIST_SIZE];

#if !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
DiscoveredNode discovered[UI_RECENT_LIST_SIZE];
uint32_t discovery_req_time = 0;
bool discovery_disp_names = true; // by default desplay names if available (removes SNR_O)
#endif

void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) {
// Convert millivolts to percentage
Expand Down Expand Up @@ -458,6 +466,40 @@ class HomeScreen : public UIScreen {
}
if (sensors_scroll) sensors_scroll_offset = (sensors_scroll_offset+1)%sensors_nb;
else sensors_scroll_offset = 0;
#endif
#if !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
} else if (_page == HomePage::DISCOVERY) {
int count = the_mesh.getDiscoveredNodes(discovered, UI_RECENT_LIST_SIZE);
display.setColor(UIColor::primary_txt);
int y = 20;
for (int i = 0; i < count; i++, y += 11) {
char name[32];
auto a = &discovered[i];
if ((a->name[0] == 0) || !discovery_disp_names) {
mesh::Utils::toHex(name, a->pubkey_prefix, 4);
} else {
strncpy(name, a->name, 32);
}
char filtered_name[sizeof(name)];
char snr_s[12];
if (strlen(name) <= 8) { // display snr_o
sprintf(snr_s, "%02.1f>%02.1f", a->snr_out, a->snr_in);
} else {
sprintf(snr_s, "%02.1f", a->snr_in);
}
int snr_width = display.getTextWidth(snr_s);
int max_name_width = display.width() - snr_width - 1;
display.translateUTF8ToBlocks(filtered_name, name, sizeof(filtered_name));
display.drawTextEllipsized(0, y, max_name_width, filtered_name);
display.setCursor(display.width() - snr_width - 1, y);
display.print(snr_s);
}
if (millis() < discovery_req_time + 5000) {
return 1000; // more frequent updates just after req
} else if (count < UI_RECENT_LIST_SIZE -1) { // show only 5 sec after last disc
y = 10 + 11 * UI_RECENT_LIST_SIZE;
display.drawTextCentered(display.width() / 2, y, "discover: " PRESS_LABEL);
}
#endif
} else if (_page == HomePage::SHUTDOWN) {
display.setColor(UIColor::corp_blue);
Expand All @@ -484,6 +526,11 @@ class HomeScreen : public UIScreen {
if (_page == HomePage::RECENT) {
_task->showAlert("Recent adverts", 800);
}
#if !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
if (_page == HomePage::DISCOVERY) {
_task->showAlert("Repeater disc", 800);
}
#endif
return true;
}
if (c == KEY_ENTER && _page == HomePage::BLUETOOTH) {
Expand Down Expand Up @@ -515,6 +562,19 @@ class HomeScreen : public UIScreen {
next_sensors_refresh=0;
return true;
}
#endif
#if !(defined(UI_NO_DISCOVER_SCREEN) && (UI_NO_DISCOVER_SCREEN + 0 != 0))
if (c == KEY_ENTER && _page == HomePage::DISCOVERY) {
if (millis() > discovery_req_time + 5000) { // rate limiter
the_mesh.requestRepeatersDiscovery();
discovery_req_time = millis();
}
return true;
}
if (c == KEY_SELECT && _page == HomePage::DISCOVERY) {
discovery_disp_names = !discovery_disp_names;
return true;
}
#endif
if (c == KEY_ENTER && _page == HomePage::SHUTDOWN) {
_shutdown_init = true; // need to wait for button to be released
Expand Down
4 changes: 0 additions & 4 deletions examples/simple_repeater/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ struct RepeaterStats {
uint32_t n_recv_errors;
};

#ifndef MAX_CLIENTS
#define MAX_CLIENTS 32
#endif

struct NeighbourInfo {
mesh::Identity id;
uint32_t advert_timestamp;
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/ClientACL.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct ClientInfo {
};

#ifndef MAX_CLIENTS
#define MAX_CLIENTS 20
#define MAX_CLIENTS 32
#endif

class ClientACL {
Expand Down
Loading