Skip to content

Commit 19978d6

Browse files
author
Laura J
committed
Merge branch 'dev' into t114-power-consumption
2 parents a16e011 + f9f1c2e commit 19978d6

File tree

5 files changed

+213
-52
lines changed

5 files changed

+213
-52
lines changed

build_as_lib.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,14 @@
1515
# add build and include dirs according to CPPDEFINES
1616
for item in menv.get("CPPDEFINES", []):
1717

18-
# STM32
19-
if isinstance(item, str) and item == "STM32_PLATFORM":
20-
menv.Append(CPPPATH=[realpath("src/helpers/stm32")])
21-
menv.Append(BUILD_FLAGS=["-I src/helpers/stm32"])
18+
# PLATFORM HANDLING
19+
if item == "STM32_PLATFORM":
2220
src_filter.append("+<helpers/stm32/*>")
23-
24-
# ESP32
25-
elif isinstance(item, str) and item == "ESP32":
26-
menv.Append(CPPPATH=[realpath("src/helpers/esp32")])
27-
menv.Append(BUILD_FLAGS=["-I src/helpers/esp32"])
21+
elif item == "ESP32":
2822
src_filter.append("+<helpers/esp32/*>")
29-
30-
# NRF52
31-
elif isinstance(item, str) and item == "NRF52_PLATFORM":
32-
menv.Append(CPPPATH=[realpath("src/helpers/nrf52")])
33-
menv.Append(BUILD_FLAGS=["-I src/helpers/nrf52"])
23+
elif item == "NRF52_PLATFORM":
3424
src_filter.append("+<helpers/nrf52/*>")
35-
36-
# RP2040
37-
elif isinstance(item, str) and item == "RP2040_PLATFORM":
38-
menv.Append(CPPPATH=[realpath("src/helpers/rp2040")])
39-
menv.Append(BUILD_FLAGS=["-I src/helpers/rp2040"])
25+
elif item == "RP2040_PLATFORM":
4026
src_filter.append("+<helpers/rp2040/*>")
4127

4228
# DISPLAY HANDLING
@@ -50,19 +36,29 @@
5036
# VARIANTS HANDLING
5137
elif isinstance(item, tuple) and item[0] == "MC_VARIANT":
5238
variant_name = item[1]
53-
menv.Append(BUILD_FLAGS=[f"-I variants/{variant_name}"])
5439
src_filter.append(f"+<../variants/{variant_name}>")
5540

5641
# INCLUDE EXAMPLE CODE IN BUILD (to provide your own support files without touching the tree)
5742
elif isinstance(item, tuple) and item[0] == "BUILD_EXAMPLE":
5843
example_name = item[1]
59-
src_filter.append(f"+<../examples/{example_name}>")
44+
src_filter.append(f"+<../examples/{example_name}/*.cpp>")
6045

6146
# EXCLUDE A SOURCE FILE FROM AN EXAMPLE (must be placed after example name or boom)
6247
elif isinstance(item, tuple) and item[0] == "EXCLUDE_FROM_EXAMPLE":
6348
exclude_name = item[1]
49+
if example_name is None:
50+
print("***** PLEASE DEFINE EXAMPLE FIRST *****")
51+
break
6452
src_filter.append(f"-<../examples/{example_name}/{exclude_name}>")
6553

54+
# DEAL WITH UI VARIANT FOR AN EXAMPLE
55+
elif isinstance(item, tuple) and item[0] == "MC_UI_FLAVOR":
56+
ui_flavor = item[1]
57+
if example_name is None:
58+
print("***** PLEASE DEFINE EXAMPLE FIRST *****")
59+
break
60+
src_filter.append(f"+<../examples/{example_name}/{ui_flavor}/*.cpp>")
61+
6662
menv.Replace(SRC_FILTER=src_filter)
6763

6864
#print (menv.Dump())

examples/simple_sensor/SensorMesh.cpp

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,23 @@ void SensorMesh::getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) {
613613
}
614614
}
615615

616+
void SensorMesh::sendAckTo(const ContactInfo& dest, uint32_t ack_hash) {
617+
if (dest.out_path_len < 0) {
618+
mesh::Packet* ack = createAck(ack_hash);
619+
if (ack) sendFlood(ack, TXT_ACK_DELAY);
620+
} else {
621+
uint32_t d = TXT_ACK_DELAY;
622+
if (getExtraAckTransmitCount() > 0) {
623+
mesh::Packet* a1 = createMultiAck(ack_hash, 1);
624+
if (a1) sendDirect(a1, dest.out_path, dest.out_path_len, d);
625+
d += 300;
626+
}
627+
628+
mesh::Packet* a2 = createAck(ack_hash);
629+
if (a2) sendDirect(a2, dest.out_path, dest.out_path_len, d);
630+
}
631+
}
632+
616633
void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) {
617634
int i = matching_peer_indexes[sender_idx];
618635
if (i < 0 || i >= num_contacts) {
@@ -656,45 +673,71 @@ void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_i
656673
memcpy(&sender_timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong)
657674
uint flags = (data[4] >> 2); // message attempt number, and other flags
658675

659-
if (!(flags == TXT_TYPE_CLI_DATA)) {
660-
MESH_DEBUG_PRINTLN("onPeerDataRecv: unsupported text type received: flags=%02x", (uint32_t)flags);
661-
} else if (sender_timestamp > from.last_timestamp) { // prevent replay attacks
662-
from.last_timestamp = sender_timestamp;
663-
from.last_activity = getRTCClock()->getCurrentTime();
664-
665-
// len can be > original length, but 'text' will be padded with zeroes
666-
data[len] = 0; // need to make a C string again, with null terminator
667-
668-
uint8_t temp[166];
669-
char *command = (char *) &data[5];
670-
char *reply = (char *) &temp[5];
671-
handleCommand(sender_timestamp, command, reply);
672-
673-
int text_len = strlen(reply);
674-
if (text_len > 0) {
675-
uint32_t timestamp = getRTCClock()->getCurrentTimeUnique();
676-
if (timestamp == sender_timestamp) {
677-
// WORKAROUND: the two timestamps need to be different, in the CLI view
678-
timestamp++;
679-
}
680-
memcpy(temp, &timestamp, 4); // mostly an extra blob to help make packet_hash unique
681-
temp[4] = (TXT_TYPE_CLI_DATA << 2);
682-
683-
auto reply = createDatagram(PAYLOAD_TYPE_TXT_MSG, from.id, secret, temp, 5 + text_len);
684-
if (reply) {
685-
if (from.out_path_len < 0) {
686-
sendFlood(reply, CLI_REPLY_DELAY_MILLIS);
676+
if (sender_timestamp > from.last_timestamp) { // prevent replay attacks
677+
if (flags == TXT_TYPE_PLAIN) {
678+
bool handled = handleIncomingMsg(from, sender_timestamp, &data[5], flags, len - 5);
679+
if (handled) { // if msg was handled then send an ack
680+
uint32_t ack_hash; // calc truncated hash of the message timestamp + text + sender pub_key, to prove to sender that we got it
681+
mesh::Utils::sha256((uint8_t *) &ack_hash, 4, data, 5 + strlen((char *)&data[5]), from.id.pub_key, PUB_KEY_SIZE);
682+
683+
if (packet->isRouteFlood()) {
684+
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
685+
mesh::Packet* path = createPathReturn(from.id, secret, packet->path, packet->path_len,
686+
PAYLOAD_TYPE_ACK, (uint8_t *) &ack_hash, 4);
687+
if (path) sendFlood(path, TXT_ACK_DELAY);
687688
} else {
688-
sendDirect(reply, from.out_path, from.out_path_len, CLI_REPLY_DELAY_MILLIS);
689+
sendAckTo(from, ack_hash);
690+
}
691+
}
692+
} else if (flags == TXT_TYPE_CLI_DATA) {
693+
from.last_timestamp = sender_timestamp;
694+
from.last_activity = getRTCClock()->getCurrentTime();
695+
696+
// len can be > original length, but 'text' will be padded with zeroes
697+
data[len] = 0; // need to make a C string again, with null terminator
698+
699+
uint8_t temp[166];
700+
char *command = (char *) &data[5];
701+
char *reply = (char *) &temp[5];
702+
handleCommand(sender_timestamp, command, reply);
703+
704+
int text_len = strlen(reply);
705+
if (text_len > 0) {
706+
uint32_t timestamp = getRTCClock()->getCurrentTimeUnique();
707+
if (timestamp == sender_timestamp) {
708+
// WORKAROUND: the two timestamps need to be different, in the CLI view
709+
timestamp++;
710+
}
711+
memcpy(temp, &timestamp, 4); // mostly an extra blob to help make packet_hash unique
712+
temp[4] = (TXT_TYPE_CLI_DATA << 2);
713+
714+
auto reply = createDatagram(PAYLOAD_TYPE_TXT_MSG, from.id, secret, temp, 5 + text_len);
715+
if (reply) {
716+
if (from.out_path_len < 0) {
717+
sendFlood(reply, CLI_REPLY_DELAY_MILLIS);
718+
} else {
719+
sendDirect(reply, from.out_path, from.out_path_len, CLI_REPLY_DELAY_MILLIS);
720+
}
689721
}
690722
}
723+
} else {
724+
MESH_DEBUG_PRINTLN("onPeerDataRecv: unsupported text type received: flags=%02x", (uint32_t)flags);
691725
}
692726
} else {
693727
MESH_DEBUG_PRINTLN("onPeerDataRecv: possible replay attack detected");
694728
}
695729
}
696730
}
697731

732+
bool SensorMesh::handleIncomingMsg(ContactInfo& from, uint32_t timestamp, uint8_t* data, uint flags, size_t len) {
733+
MESH_DEBUG_PRINT("handleIncomingMsg: unhandled msg from ");
734+
#ifdef MESH_DEBUG
735+
mesh::Utils::printHex(Serial, from.id.pub_key, PUB_KEY_SIZE);
736+
Serial.printf(": %s\n", data);
737+
#endif
738+
return false;
739+
}
740+
698741
bool SensorMesh::onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) {
699742
int i = matching_peer_indexes[sender_idx];
700743
if (i < 0 || i >= num_contacts) {

examples/simple_sensor/SensorMesh.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ class SensorMesh : public mesh::Mesh, public CommonCLICallbacks {
140140
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override;
141141
bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
142142
void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override;
143-
143+
virtual bool handleIncomingMsg(ContactInfo& from, uint32_t timestamp, uint8_t* data, uint flags, size_t len);
144+
void sendAckTo(const ContactInfo& dest, uint32_t ack_hash);
144145
private:
145146
FILESYSTEM* _fs;
146147
unsigned long next_local_advert, next_flood_advert;

variants/t1000-e/platformio.ini

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,65 @@ build_src_filter = ${nrf52840_t1000e.build_src_filter}
3434
debug_tool = jlink
3535
upload_protocol = nrfutil
3636

37+
[env:t1000e_repeater]
38+
extends = t1000-e
39+
build_flags = ${t1000-e.build_flags}
40+
-I examples/companion_radio/ui-orig
41+
-D ADVERT_NAME='"t1000-e Repeater"'
42+
-D ADVERT_LAT=0.0
43+
-D ADVERT_LON=0.0
44+
-D ADMIN_PASSWORD='"password"'
45+
-D MAX_NEIGHBOURS=8
46+
; -D MESH_PACKET_LOGGING=1
47+
; -D MESH_DEBUG=1
48+
-D RX_BOOSTED_GAIN=true
49+
-D RF_SWITCH_TABLE
50+
build_src_filter = ${t1000-e.build_src_filter}
51+
+<../examples/simple_repeater>
52+
lib_deps = ${t1000-e.lib_deps}
53+
stevemarple/MicroNMEA @ ^2.0.6
54+
55+
[env:t1000e_room_server]
56+
extends = t1000-e
57+
build_flags = ${t1000-e.build_flags}
58+
-I examples/companion_radio/ui-orig
59+
-D ADVERT_NAME='"t1000-e Room"'
60+
-D ADVERT_LAT=0.0
61+
-D ADVERT_LON=0.0
62+
-D ADMIN_PASSWORD='"password"'
63+
-D ROOM_PASSWORD='"hello"'
64+
; -D MESH_PACKET_LOGGING=1
65+
; -D MESH_DEBUG=1
66+
-D RX_BOOSTED_GAIN=true
67+
-D RF_SWITCH_TABLE
68+
build_src_filter = ${t1000-e.build_src_filter}
69+
+<../examples/simple_room_server>
70+
lib_deps = ${t1000-e.lib_deps}
71+
stevemarple/MicroNMEA @ ^2.0.6
72+
73+
[env:t1000e_companion_radio_usb]
74+
extends = t1000-e
75+
build_flags = ${t1000-e.build_flags}
76+
-I examples/companion_radio/ui-orig
77+
-D MAX_CONTACTS=100
78+
-D MAX_GROUP_CHANNELS=8
79+
; -D MESH_PACKET_LOGGING=1
80+
; -D MESH_DEBUG=1
81+
-D OFFLINE_QUEUE_SIZE=256
82+
-D RX_BOOSTED_GAIN=true
83+
-D RF_SWITCH_TABLE
84+
-D DISPLAY_CLASS=NullDisplayDriver
85+
-D PIN_BUZZER=25
86+
-D PIN_BUZZER_EN=37 ; P1/5 - required for T1000-E
87+
build_src_filter = ${t1000-e.build_src_filter}
88+
+<helpers/ui/buzzer.cpp>
89+
+<../examples/companion_radio/*.cpp>
90+
+<../examples/companion_radio/ui-orig/*.cpp>
91+
lib_deps = ${t1000-e.lib_deps}
92+
densaugeo/base64 @ ~1.4.0
93+
stevemarple/MicroNMEA @ ^2.0.6
94+
end2endzone/NonBlockingRTTTL@^1.3.0
95+
3796
[env:t1000e_companion_radio_ble]
3897
extends = t1000-e
3998
build_flags = ${t1000-e.build_flags}
@@ -58,4 +117,4 @@ build_src_filter = ${t1000-e.build_src_filter}
58117
lib_deps = ${t1000-e.lib_deps}
59118
densaugeo/base64 @ ~1.4.0
60119
stevemarple/MicroNMEA @ ^2.0.6
61-
end2endzone/NonBlockingRTTTL@^1.3.0
120+
end2endzone/NonBlockingRTTTL@^1.3.0

variants/xiao_c6/platformio.ini

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,65 @@ build_src_filter = ${Meshimi.build_src_filter}
121121
lib_deps =
122122
${Meshimi.lib_deps}
123123
densaugeo/base64 @ ~1.4.0
124+
125+
; WHY2025 badge variant
126+
; requires soldering 2 pins between the esp32-C6 and the lora chip as shown here: https://wiki.why2025.org/Project:Meshtastic_on_the_WHY2025_badge
127+
; also requires wiping the esp32-P4
128+
[WHY2025_badge]
129+
extends = Xiao_C6
130+
board_build.partitions = default_8MB.csv
131+
board_upload.flash_size = 8MB
132+
board_upload.maximum_size = 8388608
133+
build_flags =
134+
${Xiao_C6.build_flags}
135+
-D P_LORA_SCLK=6
136+
-D P_LORA_MISO=2
137+
-D P_LORA_MOSI=7
138+
-D P_LORA_NSS=4
139+
-D P_LORA_DIO_1=5
140+
-D P_LORA_BUSY=11
141+
-D P_LORA_RESET=1
142+
-D SX126X_TXEN=3
143+
-UPIN_BOARD_SDA
144+
-UPIN_BOARD_SCL
145+
-UP_LORA_TX_LED
146+
-USX126X_RXEN
147+
-USX126X_DIO2_AS_RF_SWITCH
148+
-USX126X_DIO3_TCXO_VOLTAGE
149+
150+
[env:WHY2025_badge_Repeater]
151+
extends = WHY2025_badge
152+
build_src_filter = ${WHY2025_badge.build_src_filter}
153+
+<../examples/simple_repeater/main.cpp>
154+
build_flags =
155+
${WHY2025_badge.build_flags}
156+
-D ADVERT_NAME='"WHY2025 Badge Repeater"'
157+
-D ADVERT_LAT=0.0
158+
-D ADVERT_LON=0.0
159+
-D ADMIN_PASSWORD='"password"'
160+
-D MAX_NEIGHBOURS=8
161+
; -D MESH_PACKET_LOGGING=1
162+
; -D MESH_DEBUG=1
163+
lib_deps =
164+
${WHY2025_badge.lib_deps}
165+
; ${esp32_ota.lib_deps}
166+
167+
[env:WHY2025_badge_companion_radio_ble]
168+
extends = WHY2025_badge
169+
build_flags = ${WHY2025_badge.build_flags}
170+
-D MAX_CONTACTS=100
171+
-D MAX_GROUP_CHANNELS=8
172+
-D BLE_PIN_CODE=123456
173+
-D BLE_DEBUG_LOGGING=1
174+
-D OFFLINE_QUEUE_SIZE=256
175+
-D ENABLE_PRIVATE_KEY_IMPORT=1
176+
-D ENABLE_PRIVATE_KEY_EXPORT=1
177+
; -D MESH_PACKET_LOGGING=1
178+
; -D MESH_DEBUG=1
179+
build_src_filter = ${WHY2025_badge.build_src_filter}
180+
+<helpers/esp32/*.cpp>
181+
-<helpers/esp32/ESPNOWRadio.cpp>
182+
+<../examples/companion_radio/*.cpp>
183+
lib_deps =
184+
${WHY2025_badge.lib_deps}
185+
densaugeo/base64 @ ~1.4.0

0 commit comments

Comments
 (0)