Skip to content

Commit 62242cd

Browse files
authored
Merge pull request #1 from ssbc/esp32-config
added new functionality: select LoRa plan via button (long) click
2 parents 32810be + 4f642c5 commit 62242cd

9 files changed

Lines changed: 659 additions & 496 deletions

File tree

esp32/loramesh-TBeam/bipf.cpp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -495,16 +495,29 @@ struct bipf_s* str2bipf(char *s) // returns addr of a static (!) BIPF obj
495495
return &e;
496496
}
497497

498-
String bipf2String(struct bipf_s *bptr)
498+
String bipf2String(struct bipf_s *bptr, char *nl, int lev)
499499
{
500-
String v;
500+
String v, indent, r = nl;
501501
struct bipf_s **pp;
502502

503+
indent = "";
504+
if (nl)
505+
for (int i = 0; i < lev; i++)
506+
indent += " ";
507+
else
508+
r = "";
509+
503510
switch (bptr->typ) {
504511
case BIPF_BYTES:
505-
return "0x...";
506-
case BIPF_STRING:
507-
return "\"" + String(bptr->u.str) + "\"";
512+
return "#" + String(to_hex(bptr->u.buf, bptr->cnt));
513+
case BIPF_STRING: {
514+
char *c_str = (char*) malloc(bptr->cnt+1);
515+
memcpy(c_str, bptr->u.str, bptr->cnt);
516+
c_str[bptr->cnt] = '\0';
517+
String s(c_str);
518+
free(c_str);
519+
return "\"" + s + "\"";
520+
}
508521
case BIPF_BOOLNONE:
509522
if (bptr->u.i < 0)
510523
return "none";
@@ -516,24 +529,28 @@ String bipf2String(struct bipf_s *bptr)
516529
case BIPF_INT:
517530
return String(bptr->u.i);
518531
case BIPF_LIST:
519-
v = "[";
532+
if (bptr->cnt == 0)
533+
return "[]";
534+
v = "[" + r;
520535
pp = bptr->u.list;
521536
for (int i = 0; i < bptr->cnt; i++) {
522-
if (v.length() != 1)
523-
v += ",";
524-
v += bipf2String(*pp++);
537+
if (i > 0)
538+
v += "," + r;
539+
v += indent + bipf2String(*pp++, nl, lev+1);
525540
}
526-
return v + "]";
541+
return v + r + indent + "]";
527542
case BIPF_DICT:
528-
v = "{";
543+
if (bptr->cnt == 0)
544+
return "{}";
545+
v = "{" + r;
529546
pp = bptr->u.dict;
530547
for (int i = 0; i < bptr->cnt; i++) {
531-
if (v.length() != 1)
532-
v += ",";
533-
v += bipf2String(*pp++) + ":";
534-
v += bipf2String(*pp++);
548+
if (i > 0)
549+
v += "," + r;
550+
v += indent + bipf2String(*pp++, nl, lev+1) + (nl ? ": " : ":");
551+
v += bipf2String(*pp++, nl, lev+1);
535552
}
536-
return v + "}";
553+
return v + r + indent + "}";
537554
default:
538555
// Serial.println("can't render typ=" + String(bptr->typ));
539556
break;

esp32/loramesh-TBeam/bipf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ unsigned char* bipf_dumps(struct bipf_s *bptr, int *len);
5959
struct bipf_s* bipf_loads(unsigned char *buf, int len);
6060

6161
struct bipf_s* str2bipf(char *s); // return static bipf_s for s
62-
struct String bipf2String(struct bipf_s *bptr);
62+
struct String bipf2String(struct bipf_s *bptr, char *nl=NULL, int lev=0);
6363

6464
#endif // _INCLUDE_BIPF_H
6565

esp32/loramesh-TBeam/cmd.h

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,40 @@
33
// tinySSB for ESP32
44
// Aug 2022 <christian.tschudin@unibas.ch>
55

6+
// --------------------------------------------------------------------------
7+
8+
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
9+
{
10+
Serial.printf("Listing directory: %s\r\n", dirname);
11+
12+
File root = fs.open(dirname);
13+
if (!root) {
14+
Serial.println("- failed to open directory");
15+
return;
16+
}
17+
if (!root.isDirectory()) {
18+
Serial.println(" - not a directory");
19+
return;
20+
}
21+
22+
File file = root.openNextFile();
23+
int cnt = 0;
24+
while (file) {
25+
cnt++;
26+
if (file.isDirectory()) {
27+
Serial.printf(" DIR : %s\r\n", file.name());
28+
if (levels)
29+
listDir(fs, file.path(), levels -1);
30+
} else
31+
Serial.printf(" FILE: %s\tSIZE: %d\r\n", file.name(), file.size());
32+
file = root.openNextFile();
33+
}
34+
if (cnt == 0)
35+
Serial.printf(" EMPTY\r\n");
36+
}
37+
38+
// --------------------------------------------------------------------------
39+
640
void cmd_rx(String cmd) {
741
cmd.toLowerCase();
842
cmd.trim();
@@ -17,6 +51,7 @@ void cmd_rx(String cmd) {
1751
Serial.println(" d dump DMXT and CHKT");
1852
Serial.println(" f list file system");
1953
Serial.println(" g dump GOset");
54+
Serial.println(" i pretty print the confIg values");
2055
Serial.println(" k+<key> add new key (globally)");
2156
Serial.println(" k-<key> remove key (globally)");
2257
#if defined(LORA_LOG)
@@ -100,14 +135,20 @@ void cmd_rx(String cmd) {
100135
case 'f': // Directory dump
101136
Serial.printf("File system: %d total bytes, %d used\r\n",
102137
MyFS.totalBytes(), MyFS.usedBytes());
103-
listDir(MyFS, FEED_DIR, 2);
138+
listDir(MyFS, "/", 2); // FEED_DIR, 2);
104139
break;
105140
case 'g': // GOset dump
106141
Serial.printf("GOset: %d entries\r\n", theGOset->goset_len);
107142
for (int i = 0; i < theGOset->goset_len; i++)
108143
Serial.printf("%2d %s\r\n", i,
109144
to_hex(theGOset->get_key(i), GOSET_KEY_LEN, 0));
110145
break;
146+
case 'i': { // config values
147+
// FIXME: we should not print the mgmt signing key to the console ?
148+
String s = bipf2String(the_config, "\r\n", 0);
149+
Serial.printf("Configuration values:\r\n%s\r\n", s.c_str());
150+
break;
151+
}
111152
case 'k': { // allow/deny key
112153
if (cmd.length() != 2 * GOSET_KEY_LEN + 2) { Serial.printf("invalid key length\r\n"); break; }
113154
if (!(cmd[1] == '+' or cmd[1] == '-')) { Serial.printf("invalid command: %s\r\n", cmd[1]); break; }
@@ -121,16 +162,16 @@ void cmd_rx(String cmd) {
121162
#if defined(LORA_LOG)
122163
case 'l': // list Log file
123164
lora_log.close();
124-
lora_log = MyFS.open("/lora_log.txt", FILE_READ);
165+
lora_log = MyFS.open(LORA_LOG_FILENAME, FILE_READ);
125166
while (lora_log.available()) {
126167
Serial.write(lora_log.read());
127168
}
128169
lora_log.close();
129-
lora_log = MyFS.open("/lora_log.txt", FILE_APPEND);
170+
lora_log = MyFS.open(LORA_LOG_FILENAME, FILE_APPEND);
130171
break;
131172
case 'm': // empty Log file
132173
lora_log.close();
133-
lora_log = MyFS.open("/lora_log.txt", FILE_WRITE);
174+
lora_log = MyFS.open(LORA_LOG_FILENAME, FILE_WRITE);
134175
break;
135176
#endif
136177
case 'r': // reset
@@ -174,6 +215,8 @@ void cmd_rx(String cmd) {
174215
Serial.printf("sending reboot request to %s\r\n", to_hex(id, MGMT_ID_LEN, 0));
175216
mgmt_send_request('x', id);
176217
} else {
218+
lora_log.printf(">> reboot cmd\n");
219+
lora_log.close();
177220
Serial.println("rebooting ...\n");
178221
esp_restart();
179222
}

esp32/loramesh-TBeam/config.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
// (c) 2023 <christian.tschudin@unibas.ch>
55

66
#include <Arduino.h>
7+
#include <sodium/crypto_auth.h>
78

89
#include "config.h"
910

1011
#define LORA_TX_POWER 20
1112
#define LORA_tSSB_SYNC 0x58 // for "SB, Scuttlebutt". see https://forum.lora-developers.semtech.com/t/sx1272-and-sx1262-lora-sync-word-compatibility/988
1213

1314
struct lora_config_s lora_configs[] = {
15+
// FIXME: these values are copying TNN values - we should step around these
1416
{"AU915.a", 917500000, 500000, 8, 5, LORA_tSSB_SYNC, LORA_TX_POWER},
1517
{"AU915.b", 917500000, 125000, 7, 5, LORA_tSSB_SYNC, LORA_TX_POWER},
1618
{"EU868.a", 868300000, 250000, 7, 5, LORA_tSSB_SYNC, LORA_TX_POWER},
@@ -25,28 +27,47 @@ short lora_configs_size = sizeof(lora_configs) / sizeof(struct lora_config_s);
2527

2628
struct bipf_s* config_load() // returns a BIPF dict with the persisted config dict
2729
{
28-
if (!MyFS.exists(CONFIG_FILENAME)) { // define some defaults
30+
File f = MyFS.open(CONFIG_FILENAME, "rb");
31+
32+
if (f == NULL) { // define some defaults
2933
struct bipf_s *dict = bipf_mkDict();
30-
bipf_dict_set(dict, bipf_mkString("lora_plan"), bipf_mkString("AU915.a"));
34+
35+
bipf_dict_set(dict, bipf_mkString("bubbles"),
36+
bipf_mkList()); // empty list of bubble publ keys
37+
38+
bipf_dict_set(dict, bipf_mkString("lora_plan"),
39+
bipf_mkString("AU915.a"));
40+
41+
unsigned char key[crypto_auth_hmacsha512_KEYBYTES]; // 48B
42+
memset(key, 1, crypto_auth_hmacsha512_KEYBYTES); // default is #0101...
43+
bipf_dict_set(dict, bipf_mkString("mgmt_sign_key"),
44+
bipf_mkBytes(key, crypto_auth_hmacsha512_KEYBYTES));
45+
46+
config_save(dict);
3147
return dict;
3248
}
3349

34-
File f = MyFS.open(CONFIG_FILENAME);
3550
int len = f.size();
3651
unsigned char *buf = (unsigned char*) malloc(len);
3752
f.read(buf, len);
3853
f.close();
3954
struct bipf_s *dict = bipf_loads(buf, len);
55+
// FIXME: we should not print the mgmt signing key to the console ?
56+
Serial.printf("loaded config %s\r\n", bipf2String(dict,"\r\n").c_str());
4057
free(buf);
4158
return dict;
4259
}
4360

4461
void config_save(struct bipf_s *dict) // persist the BIPF dict
4562
{
63+
// FIXME: we should not print the mgmt signing key to the console
64+
// Serial.printf("storing config %s\r\n", bipf2String(dict).c_str());
4665
int len = bipf_encodingLength(dict);
4766
unsigned char *buf = (unsigned char*) malloc(len);
48-
if (!buf)
67+
if (!buf) {
68+
Serial.printf("malloc failed\n");
4969
return;
70+
}
5071
bipf_encode(buf, dict);
5172
File f = MyFS.open(CONFIG_FILENAME, "wb");
5273
f.write(buf, len);

esp32/loramesh-TBeam/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ extern short lora_configs_size;
116116
// "lora_plan": "US915", // i.e., the lora config is specified by plan name
117117
// }
118118

119-
#define CONFIG_FILENAME "config.bipf"
119+
#define CONFIG_FILENAME "/config.bipf"
120120

121121
struct bipf_s* config_load(); // returns a BIPF dict with the persisted config dict
122122
void config_save(struct bipf_s *dict); // persist the BIPF dict

esp32/loramesh-TBeam/hw_setup.h

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ TinyGPSPlus gps;
3434
HardwareSerial GPS(1);
3535
#endif
3636

37-
Button2 userButton;
3837
unsigned char my_mac[6];
3938

4039
// -------------------------------------------------------------------
@@ -49,26 +48,20 @@ unsigned char my_mac[6];
4948

5049
// -------------------------------------------------------------------
5150

52-
static unsigned char OLED_state = HIGH;
5351

54-
void OLED_toggle() {
55-
OLED_state = OLED_state ? LOW : HIGH;
56-
#if !defined(NO_OLED)
57-
if (OLED_state == LOW) theDisplay.displayOff();
58-
else theDisplay.displayOn();
59-
#endif
60-
}
61-
62-
void pressed(Button2& btn) {
63-
// Serial.println("pressed");
64-
OLED_toggle();
65-
}
52+
void hw_setup() // T-BEAM or Heltec LoRa32v2
53+
{
54+
// Serial.begin(BAUD_RATE);
6655

67-
// -------------------------------------------------------------------
56+
Serial.println("\n** Starting Scuttlebutt vPub (LoRa, WiFi, BLE) with GOset **\n");
6857

58+
// -------------------------------------------------------------------
59+
if (!MyFS.begin(true)) { // FORMAT_SPIFFS_IF_FAILED)){
60+
Serial.println("LittleFS Mount Failed, partition was reformatted");
61+
// return;
62+
}
63+
// MyFS.format(); // uncomment and run once after a change in partition size
6964

70-
void hw_setup() // T-BEAM or Heltec LoRa32v2
71-
{
7265
the_config = config_load();
7366
the_lora_config = lora_configs;
7467
struct bipf_s k = { BIPF_STRING, 9, {.str = "lora_plan"} };
@@ -81,8 +74,6 @@ void hw_setup() // T-BEAM or Heltec LoRa32v2
8174
}
8275
}
8376

84-
// Serial.begin(BAUD_RATE);
85-
8677
#if defined(WIFI_LoRa_32_V2) || defined(WIFI_LORA_32_V2)
8778
Heltec.begin(true /*DisplayEnable Enable*/,
8879
true /*Heltec.Heltec.Heltec.LoRa Disable*/,
@@ -158,24 +149,11 @@ void hw_setup() // T-BEAM or Heltec LoRa32v2
158149
LoRa.receive();
159150
#endif
160151

161-
// pinMode(BUTTON_PIN, INPUT);
162-
userButton.begin(BUTTON_PIN);
163-
userButton.setPressedHandler(pressed);
164-
165-
Serial.println("\n** Starting Scuttlebutt vPub (LoRa, WiFi, BLE) with GOset **\n");
166152
#if !defined(NO_OLED)
167-
theDisplay.clear();
153+
theDisplay.clear(); // erase silly screen msg from inside the library ...
168154
theDisplay.display();
169155
#endif
170156

171-
172-
// -------------------------------------------------------------------
173-
if (!MyFS.begin(true)) { // FORMAT_SPIFFS_IF_FAILED)){
174-
Serial.println("LittleFS Mount Failed, partition was reformatted");
175-
// return;
176-
}
177-
// MyFS.format(); // uncomment and run once after a change in partition size
178-
179157
// -------------------------------------------------------------------
180158

181159
// esp_read_mac(my_mac, ESP_MAC_WIFI_STA);
@@ -215,32 +193,4 @@ void hw_setup() // T-BEAM or Heltec LoRa32v2
215193
Serial.println();
216194
}
217195

218-
// --------------------------------------------------------------------------
219-
220-
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
221-
{
222-
Serial.printf("Listing directory: %s\r\n", dirname);
223-
224-
File root = fs.open(dirname);
225-
if (!root) {
226-
Serial.println("- failed to open directory");
227-
return;
228-
}
229-
if (!root.isDirectory()) {
230-
Serial.println(" - not a directory");
231-
return;
232-
}
233-
234-
File file = root.openNextFile();
235-
while (file) {
236-
if (file.isDirectory()) {
237-
Serial.printf(" DIR : %s\r\n", file.name());
238-
if (levels)
239-
listDir(fs, file.path(), levels -1);
240-
} else
241-
Serial.printf(" FILE: %s\tSIZE: %d\r\n", file.name(), file.size());
242-
file = root.openNextFile();
243-
}
244-
}
245-
246196
// eof

0 commit comments

Comments
 (0)