Skip to content

Commit 98b524b

Browse files
author
Scott Powell
committed
Merge branch 'dev' into rep-room-acl
2 parents 5ccacb2 + a288ac0 commit 98b524b

File tree

13 files changed

+146
-165
lines changed

13 files changed

+146
-165
lines changed

examples/companion_radio/MyMesh.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ void MyMesh::onContactPathUpdated(const ContactInfo &contact) {
294294
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
295295
}
296296

297-
bool MyMesh::processAck(const uint8_t *data) {
297+
ContactInfo* MyMesh::processAck(const uint8_t *data) {
298298
// see if matches any in a table
299299
for (int i = 0; i < EXPECTED_ACK_TABLE_SIZE; i++) {
300300
if (memcmp(data, &expected_ack_table[i].ack, 4) == 0) { // got an ACK from recipient
@@ -306,7 +306,7 @@ bool MyMesh::processAck(const uint8_t *data) {
306306

307307
// NOTE: the same ACK can be received multiple times!
308308
expected_ack_table[i].ack = 0; // clear expected hash, now that we have received ACK
309-
return true;
309+
return expected_ack_table[i].contact;
310310
}
311311
}
312312
return checkConnectionsAck(data);
@@ -825,6 +825,7 @@ void MyMesh::handleCmdFrame(size_t len) {
825825
if (expected_ack) {
826826
expected_ack_table[next_ack_idx].msg_sent = _ms->getMillis(); // add to circular table
827827
expected_ack_table[next_ack_idx].ack = expected_ack;
828+
expected_ack_table[next_ack_idx].contact = recipient;
828829
next_ack_idx = (next_ack_idx + 1) % EXPECTED_ACK_TABLE_SIZE;
829830
}
830831

examples/companion_radio/MyMesh.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {
112112
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;
113113
void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override;
114114
void onContactPathUpdated(const ContactInfo &contact) override;
115-
bool processAck(const uint8_t *data) override;
115+
ContactInfo* processAck(const uint8_t *data) override;
116116
void queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packet *pkt, uint32_t sender_timestamp,
117117
const uint8_t *extra, int extra_len, const char *text);
118118

@@ -205,6 +205,7 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {
205205
struct AckTableEntry {
206206
unsigned long msg_sent;
207207
uint32_t ack;
208+
ContactInfo* contact;
208209
};
209210
#define EXPECTED_ACK_TABLE_SIZE 8
210211
AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table

examples/simple_secure_chat/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,18 +217,18 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
217217
saveContacts();
218218
}
219219

220-
bool processAck(const uint8_t *data) override {
220+
ContactInfo* processAck(const uint8_t *data) override {
221221
if (memcmp(data, &expected_ack_crc, 4) == 0) { // got an ACK from recipient
222222
Serial.printf(" Got ACK! (round trip: %d millis)\n", _ms->getMillis() - last_msg_sent);
223223
// NOTE: the same ACK can be received multiple times!
224224
expected_ack_crc = 0; // reset our expected hash, now that we have received ACK
225-
return true;
225+
return NULL; // TODO: really should return ContactInfo pointer
226226
}
227227

228228
//uint32_t crc;
229229
//memcpy(&crc, data, 4);
230230
//MESH_DEBUG_PRINTLN("unknown ACK received: %08X (expected: %08X)", crc, expected_ack_crc);
231-
return false;
231+
return NULL;
232232
}
233233

234234
void onMessageRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) override {

src/helpers/BaseChatMesh.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
158158
data[len] = 0; // need to make a C string again, with null terminator
159159

160160
if (flags == TXT_TYPE_PLAIN) {
161+
from.lastmod = getRTCClock()->getCurrentTime(); // update last heard time
161162
onMessageRecv(from, packet, timestamp, (const char *) &data[5]); // let UI know
162163

163164
uint32_t ack_hash; // calc truncated hash of the message timestamp + text + sender pub_key, to prove to sender that we got it
@@ -184,6 +185,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
184185
if (timestamp > from.sync_since) { // make sure 'sync_since' is up-to-date
185186
from.sync_since = timestamp;
186187
}
188+
from.lastmod = getRTCClock()->getCurrentTime(); // update last heard time
187189
onSignedMessageRecv(from, packet, timestamp, &data[5], (const char *) &data[9]); // let UI know
188190

189191
uint32_t ack_hash; // calc truncated hash of the message timestamp + text + OUR pub_key, to prove to sender that we got it
@@ -223,6 +225,10 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
223225
}
224226
} else if (type == PAYLOAD_TYPE_RESPONSE && len > 0) {
225227
onContactResponse(from, data, len);
228+
if (packet->isRouteFlood() && from.out_path_len >= 0) {
229+
// we have direct path, but other node is still sending flood response, so maybe they didn't receive reciprocal path properly(?)
230+
handleReturnPathRetry(from, packet->path, packet->path_len);
231+
}
226232
}
227233
}
228234

@@ -248,7 +254,7 @@ bool BaseChatMesh::onContactPathRecv(ContactInfo& from, uint8_t* in_path, uint8_
248254

249255
if (extra_type == PAYLOAD_TYPE_ACK && extra_len >= 4) {
250256
// also got an encoded ACK!
251-
if (processAck(extra)) {
257+
if (processAck(extra) != NULL) {
252258
txt_send_timeout = 0; // matched one we're waiting for, cancel timeout timer
253259
}
254260
} else if (extra_type == PAYLOAD_TYPE_RESPONSE && extra_len > 0) {
@@ -258,12 +264,25 @@ bool BaseChatMesh::onContactPathRecv(ContactInfo& from, uint8_t* in_path, uint8_
258264
}
259265

260266
void BaseChatMesh::onAckRecv(mesh::Packet* packet, uint32_t ack_crc) {
261-
if (processAck((uint8_t *)&ack_crc)) {
267+
ContactInfo* from;
268+
if ((from = processAck((uint8_t *)&ack_crc)) != NULL) {
262269
txt_send_timeout = 0; // matched one we're waiting for, cancel timeout timer
263270
packet->markDoNotRetransmit(); // ACK was for this node, so don't retransmit
271+
272+
if (packet->isRouteFlood() && from->out_path_len >= 0) {
273+
// we have direct path, but other node is still sending flood, so maybe they didn't receive reciprocal path properly(?)
274+
handleReturnPathRetry(*from, packet->path, packet->path_len);
275+
}
264276
}
265277
}
266278

279+
void BaseChatMesh::handleReturnPathRetry(const ContactInfo& contact, const uint8_t* path, uint8_t path_len) {
280+
// NOTE: simplest impl is just to re-send a reciprocal return path to sender (DIRECTLY)
281+
// override this method in various firmwares, if there's a better strategy
282+
mesh::Packet* rpath = createPathReturn(contact.id, contact.shared_secret, path, path_len, 0, NULL, 0);
283+
if (rpath) sendDirect(rpath, contact.out_path, contact.out_path_len, 3000); // 3 second delay
284+
}
285+
267286
#ifdef MAX_GROUP_CHANNELS
268287
int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) {
269288
int n = 0;
@@ -550,7 +569,7 @@ void BaseChatMesh::markConnectionActive(const ContactInfo& contact) {
550569
}
551570
}
552571

553-
bool BaseChatMesh::checkConnectionsAck(const uint8_t* data) {
572+
ContactInfo* BaseChatMesh::checkConnectionsAck(const uint8_t* data) {
554573
for (int i = 0; i < MAX_CONNECTIONS; i++) {
555574
if (connections[i].keep_alive_millis > 0 && memcmp(&connections[i].expected_ack, data, 4) == 0) {
556575
// yes, got an ack for our keep_alive request!
@@ -559,10 +578,12 @@ bool BaseChatMesh::checkConnectionsAck(const uint8_t* data) {
559578

560579
// re-schedule next KEEP_ALIVE, now that we have heard from server
561580
connections[i].next_ping = futureMillis(connections[i].keep_alive_millis);
562-
return true; // yes, a match
581+
582+
auto id = &connections[i].server_id;
583+
return lookupContactByPubKey(id->pub_key, PUB_KEY_SIZE); // yes, a match
563584
}
564585
}
565-
return false; /// no match
586+
return NULL; /// no match
566587
}
567588

568589
void BaseChatMesh::checkConnections() {

src/helpers/BaseChatMesh.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class BaseChatMesh : public mesh::Mesh {
9393
// 'UI' concepts, for sub-classes to implement
9494
virtual bool isAutoAddEnabled() const { return true; }
9595
virtual void onDiscoveredContact(ContactInfo& contact, bool is_new, uint8_t path_len, const uint8_t* path) = 0;
96-
virtual bool processAck(const uint8_t *data) = 0;
96+
virtual ContactInfo* processAck(const uint8_t *data) = 0;
9797
virtual void onContactPathUpdated(const ContactInfo& contact) = 0;
9898
virtual 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);
9999
virtual void onMessageRecv(const ContactInfo& contact, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) = 0;
@@ -105,6 +105,7 @@ class BaseChatMesh : public mesh::Mesh {
105105
virtual void onChannelMessageRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, const char *text) = 0;
106106
virtual uint8_t onContactRequest(const ContactInfo& contact, uint32_t sender_timestamp, const uint8_t* data, uint8_t len, uint8_t* reply) = 0;
107107
virtual void onContactResponse(const ContactInfo& contact, const uint8_t* data, uint8_t len) = 0;
108+
virtual void handleReturnPathRetry(const ContactInfo& contact, const uint8_t* path, uint8_t path_len);
108109

109110
// storage concepts, for sub-classes to override/implement
110111
virtual int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) { return 0; } // not implemented
@@ -127,7 +128,7 @@ class BaseChatMesh : public mesh::Mesh {
127128
void stopConnection(const uint8_t* pub_key);
128129
bool hasConnectionTo(const uint8_t* pub_key);
129130
void markConnectionActive(const ContactInfo& contact);
130-
bool checkConnectionsAck(const uint8_t* data);
131+
ContactInfo* checkConnectionsAck(const uint8_t* data);
131132
void checkConnections();
132133

133134
public:

src/helpers/nrf52/SerialBLEInterface.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ static SerialBLEInterface* instance;
44

55
void SerialBLEInterface::onConnect(uint16_t connection_handle) {
66
BLE_DEBUG_PRINTLN("SerialBLEInterface: connected");
7-
if(instance){
8-
instance->_isDeviceConnected = true;
9-
// no need to stop advertising on connect, as the ble stack does this automatically
10-
}
7+
// we now set _isDeviceConnected=true in onSecured callback instead
118
}
129

1310
void SerialBLEInterface::onDisconnect(uint16_t connection_handle, uint8_t reason) {
@@ -18,6 +15,14 @@ void SerialBLEInterface::onDisconnect(uint16_t connection_handle, uint8_t reason
1815
}
1916
}
2017

18+
void SerialBLEInterface::onSecured(uint16_t connection_handle) {
19+
BLE_DEBUG_PRINTLN("SerialBLEInterface: onSecured");
20+
if(instance){
21+
instance->_isDeviceConnected = true;
22+
// no need to stop advertising on connect, as the ble stack does this automatically
23+
}
24+
}
25+
2126
void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) {
2227

2328
instance = this;
@@ -36,6 +41,7 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) {
3641

3742
Bluefruit.Periph.setConnectCallback(onConnect);
3843
Bluefruit.Periph.setDisconnectCallback(onDisconnect);
44+
Bluefruit.Security.setSecuredCallback(onSecured);
3945

4046
// To be consistent OTA DFU should be added first if it exists
4147
//bledfu.begin();
@@ -80,7 +86,7 @@ void SerialBLEInterface::startAdv() {
8086
* https://developer.apple.com/library/content/qa/qa1931/_index.html
8187
*/
8288
Bluefruit.Advertising.restartOnDisconnect(false); // don't restart automatically as we handle it in onDisconnect
83-
Bluefruit.Advertising.setInterval(32, 1600);
89+
Bluefruit.Advertising.setInterval(32, 244);
8490
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
8591
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
8692

src/helpers/nrf52/SerialBLEInterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class SerialBLEInterface : public BaseSerialInterface {
2525
void clearBuffers() { send_queue_len = 0; }
2626
static void onConnect(uint16_t connection_handle);
2727
static void onDisconnect(uint16_t connection_handle, uint8_t reason);
28+
static void onSecured(uint16_t connection_handle);
2829

2930
public:
3031
SerialBLEInterface() {

variants/xiao_nrf52/XiaoNrf52Board.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
#ifdef XIAO_NRF52
22

33
#include <Arduino.h>
4-
#include "XiaoNrf52Board.h"
5-
6-
#include <bluefruit.h>
74
#include <Wire.h>
5+
#include <bluefruit.h>
6+
7+
#include "XiaoNrf52Board.h"
88

99
static BLEDfu bledfu;
1010

11-
static void connect_callback(uint16_t conn_handle)
12-
{
11+
static void connect_callback(uint16_t conn_handle) {
1312
(void)conn_handle;
1413
MESH_DEBUG_PRINTLN("BLE client connected");
1514
}
1615

17-
static void disconnect_callback(uint16_t conn_handle, uint8_t reason)
18-
{
16+
static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
1917
(void)conn_handle;
2018
(void)reason;
2119

@@ -41,12 +39,12 @@ void XiaoNrf52Board::begin() {
4139
digitalWrite(P_LORA_TX_LED, HIGH);
4240
#endif
4341

44-
// pinMode(SX126X_POWER_EN, OUTPUT);
45-
// digitalWrite(SX126X_POWER_EN, HIGH);
46-
delay(10); // give sx1262 some time to power up
42+
// pinMode(SX126X_POWER_EN, OUTPUT);
43+
// digitalWrite(SX126X_POWER_EN, HIGH);
44+
delay(10); // give sx1262 some time to power up
4745
}
4846

49-
bool XiaoNrf52Board::startOTAUpdate(const char* id, char reply[]) {
47+
bool XiaoNrf52Board::startOTAUpdate(const char *id, char reply[]) {
5048
// Config the peripheral connection with maximum bandwidth
5149
// more SRAM required by SoftDevice
5250
// Note: All config***() function must be called before begin()
@@ -86,10 +84,8 @@ bool XiaoNrf52Board::startOTAUpdate(const char* id, char reply[]) {
8684
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
8785

8886
strcpy(reply, "OK - started");
89-
return true;
9087

91-
92-
return false;
88+
return true;
9389
}
9490

9591
#endif

variants/xiao_nrf52/XiaoNrf52Board.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,6 @@
55

66
#ifdef XIAO_NRF52
77

8-
// redefine lora pins if using the S3 variant of SX1262 board
9-
#ifdef SX1262_XIAO_S3_VARIANT
10-
#undef P_LORA_DIO_1
11-
#undef P_LORA_BUSY
12-
#undef P_LORA_RESET
13-
#undef P_LORA_NSS
14-
#undef SX126X_RXEN
15-
#define P_LORA_DIO_1 D0
16-
#define P_LORA_BUSY D1
17-
#define P_LORA_RESET D2
18-
#define P_LORA_NSS D3
19-
#define SX126X_RXEN D4
20-
#endif
21-
228
class XiaoNrf52Board : public mesh::MainBoard {
239
protected:
2410
uint8_t startup_reason;
@@ -40,13 +26,13 @@ class XiaoNrf52Board : public mesh::MainBoard {
4026
// Please read befor going further ;)
4127
// https://wiki.seeedstudio.com/XIAO_BLE#q3-what-are-the-considerations-when-using-xiao-nrf52840-sense-for-battery-charging
4228

43-
// We can't drive VBAT_ENABLE to HIGH as long
29+
// We can't drive VBAT_ENABLE to HIGH as long
4430
// as we don't know wether we are charging or not ...
4531
// this is a 3mA loss (4/1500)
4632
digitalWrite(VBAT_ENABLE, LOW);
4733
int adcvalue = 0;
4834
analogReadResolution(12);
49-
analogReference(AR_INTERNAL_3_0);
35+
analogReference(AR_INTERNAL_3_0);
5036
delay(10);
5137
adcvalue = analogRead(PIN_VBAT);
5238
return (adcvalue * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096;

0 commit comments

Comments
 (0)