mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-16 07:42:37 +00:00
Compare commits
39 Commits
no-arduino
...
v1.2.62.3d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ddd74edf6 | ||
|
|
186d7f7d33 | ||
|
|
456f8ab7e8 | ||
|
|
d551c17546 | ||
|
|
af4027e8c8 | ||
|
|
3df0fdd239 | ||
|
|
8510ef3ad0 | ||
|
|
ee419f8b9b | ||
|
|
ab959ded0e | ||
|
|
2a76a5527a | ||
|
|
58d91f0a4b | ||
|
|
e09aafa13f | ||
|
|
aca95248ee | ||
|
|
d81c1c08ee | ||
|
|
317ce2c9cd | ||
|
|
b2827597fd | ||
|
|
6af182228c | ||
|
|
1246c7bb1e | ||
|
|
e6731e28c1 | ||
|
|
d57ac39b02 | ||
|
|
67bc6b1419 | ||
|
|
d328823c03 | ||
|
|
7178d3a2fd | ||
|
|
a0f60f1d07 | ||
|
|
b177313e2d | ||
|
|
53d47146b2 | ||
|
|
f7c6955736 | ||
|
|
9a87e1b53e | ||
|
|
f1478a7c93 | ||
|
|
8fd5d83980 | ||
|
|
5895aaa259 | ||
|
|
1787712a5a | ||
|
|
596a73c0a0 | ||
|
|
d56f8c631b | ||
|
|
682f988c2a | ||
|
|
ce20a2b566 | ||
|
|
d0fc836f0b | ||
|
|
d542267e4a | ||
|
|
756317e7e0 |
23
.github/workflows/main_matrix.yml
vendored
23
.github/workflows/main_matrix.yml
vendored
@@ -1,8 +1,8 @@
|
|||||||
name: Continuous Integration
|
name: Continuous Integration PR Checks (1.2 Legacy)
|
||||||
on:
|
on:
|
||||||
# # Triggers the workflow on push but only for the master branch
|
# # Triggers the workflow on push but only for the master branch
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ 1.2-legacy ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- '**.yml'
|
- '**.yml'
|
||||||
@@ -10,7 +10,7 @@ on:
|
|||||||
|
|
||||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
branches: [ master ]
|
branches: [ 1.2-legacy ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- '**.yml'
|
- '**.yml'
|
||||||
@@ -38,6 +38,7 @@ jobs:
|
|||||||
- board: rak4631_5005
|
- board: rak4631_5005
|
||||||
- board: rak4631_19003
|
- board: rak4631_19003
|
||||||
- board: t-echo
|
- board: t-echo
|
||||||
|
- board: nano-g1
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -77,6 +78,16 @@ jobs:
|
|||||||
- name: Check ${{ matrix.board }}
|
- name: Check ${{ matrix.board }}
|
||||||
run: bin/check-all.sh ${{ matrix.board }}
|
run: bin/check-all.sh ${{ matrix.board }}
|
||||||
|
|
||||||
|
after-checks:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check]
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
build-esp32:
|
build-esp32:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -93,6 +104,7 @@ jobs:
|
|||||||
- board: heltec-v2.1
|
- board: heltec-v2.1
|
||||||
- board: tbeam0.7
|
- board: tbeam0.7
|
||||||
- board: meshtastic-diy-v1
|
- board: meshtastic-diy-v1
|
||||||
|
- board: nano-g1
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -328,5 +340,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
artifacts-branch: artifacts
|
artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
|
||||||
|
artifacts-repo: meshtastic/artifacts
|
||||||
|
artifacts-branch: device
|
||||||
|
artifacts-dir: pr
|
||||||
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
|
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -1,13 +1,13 @@
|
|||||||
name: Make Release
|
name: Make Release
|
||||||
on:
|
on:
|
||||||
# Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on.
|
# Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on.
|
||||||
workflow_dispatch:
|
#workflow_dispatch:
|
||||||
# inputs:
|
# inputs:
|
||||||
|
|
||||||
# Only want to run if version.properties is bumped in master
|
# Only want to run if version.properties is bumped in master
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- 1.2-legacy
|
||||||
paths:
|
paths:
|
||||||
- 'version.properties'
|
- 'version.properties'
|
||||||
|
|
||||||
|
|||||||
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,6 +1,7 @@
|
|||||||
[submodule "proto"]
|
[submodule "proto"]
|
||||||
path = proto
|
path = proto
|
||||||
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
||||||
|
branch = 1.2-legacy
|
||||||
[submodule "sdk-nrfxlib"]
|
[submodule "sdk-nrfxlib"]
|
||||||
path = sdk-nrfxlib
|
path = sdk-nrfxlib
|
||||||
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ set -e
|
|||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=`bin/buildinfo.py long`
|
||||||
SHORT_VERSION=`bin/buildinfo.py short`
|
SHORT_VERSION=`bin/buildinfo.py short`
|
||||||
|
|
||||||
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1"
|
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1"
|
||||||
#BOARDS_ESP32=tbeam
|
#BOARDS_ESP32=tbeam
|
||||||
|
|
||||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ default_envs = tbeam
|
|||||||
;default_envs = t-echo
|
;default_envs = t-echo
|
||||||
;default_envs = nrf52840dk-geeksville
|
;default_envs = nrf52840dk-geeksville
|
||||||
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||||
;default_envs = rak4631
|
;default_envs = rak4631_5005
|
||||||
;default_envs = rak4630
|
;default_envs = rak4631_5005_eink
|
||||||
|
;default_envs = rak4631_19003
|
||||||
|
;default_envs = nano-g1
|
||||||
;default_envs = meshtastic-diy-v1
|
;default_envs = meshtastic-diy-v1
|
||||||
;default_envs = meshtastic-diy-v1.1
|
;default_envs = meshtastic-diy-v1.1
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ debug_tool = jlink
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306
|
||||||
https://github.com/meshtastic/OneButton.git#3bcba9492d01e2a8a86f46700ab16f96dd2cf1f5 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||||
https://github.com/meshtastic/arduino-fsm.git
|
https://github.com/meshtastic/arduino-fsm.git
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||||
@@ -121,7 +123,7 @@ lib_deps =
|
|||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = espressif32
|
platform = espressif32@3.5.0
|
||||||
src_filter =
|
src_filter =
|
||||||
${arduino_base.src_filter} -<nrf52/>
|
${arduino_base.src_filter} -<nrf52/>
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
@@ -262,6 +264,3 @@ upload_protocol = jlink
|
|||||||
monitor_port = /dev/ttyUSB0
|
monitor_port = /dev/ttyUSB0
|
||||||
; this board's serial chip can only run at 115200, not faster
|
; this board's serial chip can only run at 115200, not faster
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
# For experimenting with RAM sizes
|
|
||||||
# board_build.ldscript = linker/nrf52840_s140_sim832.ld
|
|
||||||
2
proto
2
proto
Submodule proto updated: 2930129e8e...c851209e0b
@@ -279,6 +279,12 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||||
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||||
|
|
||||||
|
// Inputbroker
|
||||||
|
powerFSM.add_transition(&stateLS, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||||
|
powerFSM.add_transition(&stateNB, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||||
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||||
|
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
|
||||||
|
|
||||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
||||||
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define EVENT_POWER_DISCONNECTED 14
|
#define EVENT_POWER_DISCONNECTED 14
|
||||||
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
|
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
|
||||||
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
|
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
|
||||||
|
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
|
||||||
|
|
||||||
extern Fsm powerFSM;
|
extern Fsm powerFSM;
|
||||||
extern State statePOWER, stateSERIAL;
|
extern State statePOWER, stateSERIAL;
|
||||||
|
|||||||
@@ -230,6 +230,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define HW_VENDOR HardwareModel_T_ECHO
|
#define HW_VENDOR HardwareModel_T_ECHO
|
||||||
|
|
||||||
|
#elif defined(NANO_G1)
|
||||||
|
|
||||||
|
#define HW_VENDOR HardwareModel_NANO_G1
|
||||||
|
|
||||||
#elif NRF52_SERIES
|
#elif NRF52_SERIES
|
||||||
|
|
||||||
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
|
#include "PowerFSM.h" // needed for event trigger
|
||||||
|
|
||||||
InputBroker *inputBroker;
|
InputBroker *inputBroker;
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ void InputBroker::registerSource(Observable<const InputEvent *> *source)
|
|||||||
|
|
||||||
int InputBroker::handleInputEvent(const InputEvent *event)
|
int InputBroker::handleInputEvent(const InputEvent *event)
|
||||||
{
|
{
|
||||||
|
powerFSM.trigger(EVENT_INPUT);
|
||||||
this->notifyObservers(event);
|
this->notifyObservers(event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
|||||||
}
|
}
|
||||||
else if (this->action == ROTARY_ACTION_CCW)
|
else if (this->action == ROTARY_ACTION_CCW)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Rotary event CW\n");
|
DEBUG_MSG("Rotary event CCW\n");
|
||||||
e.inputEvent = this->_eventCcw;
|
e.inputEvent = this->_eventCcw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ void RotaryEncoderInterruptBase::intAHandler()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->rotaryLevelA = currentLevelA;
|
this->rotaryLevelA = currentLevelA;
|
||||||
intHandler(
|
this->rotaryStateCCW = intHandler(
|
||||||
currentLevelA == HIGH,
|
currentLevelA == HIGH,
|
||||||
this->rotaryLevelB,
|
this->rotaryLevelB,
|
||||||
ROTARY_ACTION_CCW,
|
ROTARY_ACTION_CCW,
|
||||||
|
|||||||
@@ -295,8 +295,12 @@ class ButtonThread : public OSThread
|
|||||||
static void userButtonPressed()
|
static void userButtonPressed()
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("press!\n");
|
// DEBUG_MSG("press!\n");
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
if ((BUTTON_PIN != radioConfig.preferences.rotary1_pin_press) || !radioConfig.preferences.canned_message_plugin_enabled) {
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
static void userButtonPressedLong()
|
static void userButtonPressedLong()
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("Long press!\n");
|
// DEBUG_MSG("Long press!\n");
|
||||||
@@ -710,6 +714,8 @@ void powerCommandsCheck()
|
|||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
DEBUG_MSG("Rebooting for update\n");
|
DEBUG_MSG("Rebooting for update\n");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
|
#elif NRF52_SERIES
|
||||||
|
NVIC_SystemReset();
|
||||||
#else
|
#else
|
||||||
DEBUG_MSG("FIXME implement reboot for this platform");
|
DEBUG_MSG("FIXME implement reboot for this platform");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -71,17 +71,7 @@ int MeshService::handleFromRadio(const MeshPacket *mp)
|
|||||||
printPacket("Forwarding to phone", mp);
|
printPacket("Forwarding to phone", mp);
|
||||||
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
||||||
|
|
||||||
fromNum++;
|
sendToPhone((MeshPacket *)mp);
|
||||||
|
|
||||||
if (toPhoneQueue.numFree() == 0) {
|
|
||||||
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
|
|
||||||
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
|
||||||
if (d)
|
|
||||||
releaseToPool(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
MeshPacket *copied = packetPool.allocCopy(*mp);
|
|
||||||
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -161,12 +151,16 @@ bool MeshService::cancelSending(PacketId id)
|
|||||||
return router->cancelSending(nodeDB.getNodeNum(), id);
|
return router->cancelSending(nodeDB.getNodeNum(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshService::sendToMesh(MeshPacket *p, RxSource src)
|
void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone)
|
||||||
{
|
{
|
||||||
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
|
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
|
||||||
|
|
||||||
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
||||||
router->sendLocal(p, src);
|
router->sendLocal(p, src);
|
||||||
|
|
||||||
|
if (ccToPhone) {
|
||||||
|
sendToPhone(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||||
@@ -213,6 +207,20 @@ NodeInfo *MeshService::refreshMyNodeInfo()
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshService::sendToPhone(MeshPacket *p) {
|
||||||
|
if (toPhoneQueue.numFree() == 0) {
|
||||||
|
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
|
||||||
|
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
||||||
|
if (d)
|
||||||
|
releaseToPool(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPacket *copied = packetPool.allocCopy(*p);
|
||||||
|
perhapsDecode(copied);
|
||||||
|
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
|
||||||
|
fromNum++;
|
||||||
|
}
|
||||||
|
|
||||||
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||||
{
|
{
|
||||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class MeshService
|
|||||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
||||||
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
||||||
/// cache
|
/// cache
|
||||||
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL);
|
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL, bool ccToPhone = false);
|
||||||
|
|
||||||
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
|
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
|
||||||
bool cancelSending(PacketId id);
|
bool cancelSending(PacketId id);
|
||||||
@@ -83,6 +83,9 @@ class MeshService
|
|||||||
/// Pull the latest power and time info into my nodeinfo
|
/// Pull the latest power and time info into my nodeinfo
|
||||||
NodeInfo *refreshMyNodeInfo();
|
NodeInfo *refreshMyNodeInfo();
|
||||||
|
|
||||||
|
/// Send a packet to the phone
|
||||||
|
void sendToPhone(MeshPacket *p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
||||||
/// returns 0 to allow futher processing
|
/// returns 0 to allow futher processing
|
||||||
|
|||||||
@@ -97,6 +97,14 @@ bool NodeDB::resetRadioConfig()
|
|||||||
nvs_flash_erase();
|
nvs_flash_erase();
|
||||||
#endif
|
#endif
|
||||||
#ifdef NRF52_SERIES
|
#ifdef NRF52_SERIES
|
||||||
|
|
||||||
|
// first, remove the "/prefs" (this removes most prefs)
|
||||||
|
FS.rmdir_r("/prefs");
|
||||||
|
// second, install default state (this will deal with the duplicate mac address issue)
|
||||||
|
installDefaultDeviceState();
|
||||||
|
// third, write to disk
|
||||||
|
saveToDisk();
|
||||||
|
|
||||||
Bluefruit.begin();
|
Bluefruit.begin();
|
||||||
|
|
||||||
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
||||||
@@ -105,6 +113,7 @@ bool NodeDB::resetRadioConfig()
|
|||||||
|
|
||||||
Bluefruit.Periph.clearBonds();
|
Bluefruit.Periph.clearBonds();
|
||||||
Bluefruit.Central.clearBonds();
|
Bluefruit.Central.clearBonds();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
didFactoryReset = true;
|
didFactoryReset = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class PhoneAPI
|
|||||||
|
|
||||||
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
||||||
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
||||||
void close();
|
virtual void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a ToRadio protobuf
|
* Handle a ToRadio protobuf
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ bool perhapsDecode(MeshPacket *p)
|
|||||||
if (p->which_payloadVariant == MeshPacket_decoded_tag)
|
if (p->which_payloadVariant == MeshPacket_decoded_tag)
|
||||||
return true; // If packet was already decoded just return
|
return true; // If packet was already decoded just return
|
||||||
|
|
||||||
assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
//assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
||||||
|
|
||||||
// Try to find a channel that works with this hash
|
// Try to find a channel that works with this hash
|
||||||
for (ChannelIndex chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
|
for (ChannelIndex chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#ifndef PB_ADMIN_PB_H_INCLUDED
|
#ifndef PB_ADMIN_PB_H_INCLUDED
|
||||||
#define PB_ADMIN_PB_H_INCLUDED
|
#define PB_ADMIN_PB_H_INCLUDED
|
||||||
#include <pb.h>
|
#include <pb.h>
|
||||||
#include "cannedmessages.pb.h"
|
|
||||||
#include "channel.pb.h"
|
#include "channel.pb.h"
|
||||||
#include "mesh.pb.h"
|
#include "mesh.pb.h"
|
||||||
#include "radioconfig.pb.h"
|
#include "radioconfig.pb.h"
|
||||||
@@ -31,20 +30,17 @@ typedef struct _AdminMessage {
|
|||||||
bool exit_simulator;
|
bool exit_simulator;
|
||||||
int32_t reboot_seconds;
|
int32_t reboot_seconds;
|
||||||
bool get_canned_message_plugin_part1_request;
|
bool get_canned_message_plugin_part1_request;
|
||||||
CannedMessagePluginMessagePart1 get_canned_message_plugin_part1_response;
|
char get_canned_message_plugin_part1_response[201];
|
||||||
bool get_canned_message_plugin_part2_request;
|
bool get_canned_message_plugin_part2_request;
|
||||||
CannedMessagePluginMessagePart2 get_canned_message_plugin_part2_response;
|
char get_canned_message_plugin_part2_response[201];
|
||||||
bool get_canned_message_plugin_part3_request;
|
bool get_canned_message_plugin_part3_request;
|
||||||
CannedMessagePluginMessagePart3 get_canned_message_plugin_part3_response;
|
char get_canned_message_plugin_part3_response[201];
|
||||||
bool get_canned_message_plugin_part4_request;
|
bool get_canned_message_plugin_part4_request;
|
||||||
CannedMessagePluginMessagePart4 get_canned_message_plugin_part4_response;
|
char get_canned_message_plugin_part4_response[201];
|
||||||
bool get_canned_message_plugin_part5_request;
|
char set_canned_message_plugin_part1[201];
|
||||||
CannedMessagePluginMessagePart5 get_canned_message_plugin_part5_response;
|
char set_canned_message_plugin_part2[201];
|
||||||
CannedMessagePluginMessagePart1 set_canned_message_plugin_part1;
|
char set_canned_message_plugin_part3[201];
|
||||||
CannedMessagePluginMessagePart2 set_canned_message_plugin_part2;
|
char set_canned_message_plugin_part4[201];
|
||||||
CannedMessagePluginMessagePart3 set_canned_message_plugin_part3;
|
|
||||||
CannedMessagePluginMessagePart4 set_canned_message_plugin_part4;
|
|
||||||
CannedMessagePluginMessagePart5 set_canned_message_plugin_part5;
|
|
||||||
int32_t shutdown_seconds;
|
int32_t shutdown_seconds;
|
||||||
};
|
};
|
||||||
} AdminMessage;
|
} AdminMessage;
|
||||||
@@ -80,13 +76,10 @@ extern "C" {
|
|||||||
#define AdminMessage_get_canned_message_plugin_part3_response_tag 41
|
#define AdminMessage_get_canned_message_plugin_part3_response_tag 41
|
||||||
#define AdminMessage_get_canned_message_plugin_part4_request_tag 42
|
#define AdminMessage_get_canned_message_plugin_part4_request_tag 42
|
||||||
#define AdminMessage_get_canned_message_plugin_part4_response_tag 43
|
#define AdminMessage_get_canned_message_plugin_part4_response_tag 43
|
||||||
#define AdminMessage_get_canned_message_plugin_part5_request_tag 44
|
#define AdminMessage_set_canned_message_plugin_part1_tag 44
|
||||||
#define AdminMessage_get_canned_message_plugin_part5_response_tag 45
|
#define AdminMessage_set_canned_message_plugin_part2_tag 45
|
||||||
#define AdminMessage_set_canned_message_plugin_part1_tag 46
|
#define AdminMessage_set_canned_message_plugin_part3_tag 46
|
||||||
#define AdminMessage_set_canned_message_plugin_part2_tag 47
|
#define AdminMessage_set_canned_message_plugin_part4_tag 47
|
||||||
#define AdminMessage_set_canned_message_plugin_part3_tag 48
|
|
||||||
#define AdminMessage_set_canned_message_plugin_part4_tag 49
|
|
||||||
#define AdminMessage_set_canned_message_plugin_part5_tag 50
|
|
||||||
#define AdminMessage_shutdown_seconds_tag 51
|
#define AdminMessage_shutdown_seconds_tag 51
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
@@ -105,20 +98,17 @@ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio)
|
|||||||
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
|
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
|
||||||
X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) \
|
X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part1_request,get_canned_message_plugin_part1_request), 36) \
|
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part1_request,get_canned_message_plugin_part1_request), 36) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part1_response,get_canned_message_plugin_part1_response), 37) \
|
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part1_response,get_canned_message_plugin_part1_response), 37) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part2_request,get_canned_message_plugin_part2_request), 38) \
|
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part2_request,get_canned_message_plugin_part2_request), 38) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part2_response,get_canned_message_plugin_part2_response), 39) \
|
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part2_response,get_canned_message_plugin_part2_response), 39) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part3_request,get_canned_message_plugin_part3_request), 40) \
|
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part3_request,get_canned_message_plugin_part3_request), 40) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part3_response,get_canned_message_plugin_part3_response), 41) \
|
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part3_response,get_canned_message_plugin_part3_response), 41) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part4_request,get_canned_message_plugin_part4_request), 42) \
|
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part4_request,get_canned_message_plugin_part4_request), 42) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part4_response,get_canned_message_plugin_part4_response), 43) \
|
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part4_response,get_canned_message_plugin_part4_response), 43) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part5_request,get_canned_message_plugin_part5_request), 44) \
|
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 44) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part5_response,get_canned_message_plugin_part5_response), 45) \
|
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 45) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 46) \
|
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part3,set_canned_message_plugin_part3), 46) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 47) \
|
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part4,set_canned_message_plugin_part4), 47) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part3,set_canned_message_plugin_part3), 48) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part4,set_canned_message_plugin_part4), 49) \
|
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part5,set_canned_message_plugin_part5), 50) \
|
|
||||||
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
|
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
|
||||||
#define AdminMessage_CALLBACK NULL
|
#define AdminMessage_CALLBACK NULL
|
||||||
#define AdminMessage_DEFAULT NULL
|
#define AdminMessage_DEFAULT NULL
|
||||||
@@ -128,16 +118,6 @@ X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds),
|
|||||||
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
|
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
|
||||||
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
|
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
|
||||||
#define AdminMessage_variant_get_owner_response_MSGTYPE User
|
#define AdminMessage_variant_get_owner_response_MSGTYPE User
|
||||||
#define AdminMessage_variant_get_canned_message_plugin_part1_response_MSGTYPE CannedMessagePluginMessagePart1
|
|
||||||
#define AdminMessage_variant_get_canned_message_plugin_part2_response_MSGTYPE CannedMessagePluginMessagePart2
|
|
||||||
#define AdminMessage_variant_get_canned_message_plugin_part3_response_MSGTYPE CannedMessagePluginMessagePart3
|
|
||||||
#define AdminMessage_variant_get_canned_message_plugin_part4_response_MSGTYPE CannedMessagePluginMessagePart4
|
|
||||||
#define AdminMessage_variant_get_canned_message_plugin_part5_response_MSGTYPE CannedMessagePluginMessagePart5
|
|
||||||
#define AdminMessage_variant_set_canned_message_plugin_part1_MSGTYPE CannedMessagePluginMessagePart1
|
|
||||||
#define AdminMessage_variant_set_canned_message_plugin_part2_MSGTYPE CannedMessagePluginMessagePart2
|
|
||||||
#define AdminMessage_variant_set_canned_message_plugin_part3_MSGTYPE CannedMessagePluginMessagePart3
|
|
||||||
#define AdminMessage_variant_set_canned_message_plugin_part4_MSGTYPE CannedMessagePluginMessagePart4
|
|
||||||
#define AdminMessage_variant_set_canned_message_plugin_part5_MSGTYPE CannedMessagePluginMessagePart5
|
|
||||||
|
|
||||||
extern const pb_msgdesc_t AdminMessage_msg;
|
extern const pb_msgdesc_t AdminMessage_msg;
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,7 @@
|
|||||||
#error Regenerate this file with the current version of nanopb generator.
|
#error Regenerate this file with the current version of nanopb generator.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PB_BIND(CannedMessagePluginMessagePart1, CannedMessagePluginMessagePart1, AUTO)
|
PB_BIND(CannedMessagePluginConfig, CannedMessagePluginConfig, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(CannedMessagePluginMessagePart2, CannedMessagePluginMessagePart2, AUTO)
|
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(CannedMessagePluginMessagePart3, CannedMessagePluginMessagePart3, AUTO)
|
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(CannedMessagePluginMessagePart4, CannedMessagePluginMessagePart4, AUTO)
|
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(CannedMessagePluginMessagePart5, CannedMessagePluginMessagePart5, AUTO)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,25 +10,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
typedef struct _CannedMessagePluginMessagePart1 {
|
typedef struct _CannedMessagePluginConfig {
|
||||||
char text[200];
|
char messagesPart1[201];
|
||||||
} CannedMessagePluginMessagePart1;
|
char messagesPart2[201];
|
||||||
|
char messagesPart3[201];
|
||||||
typedef struct _CannedMessagePluginMessagePart2 {
|
char messagesPart4[201];
|
||||||
char text[200];
|
} CannedMessagePluginConfig;
|
||||||
} CannedMessagePluginMessagePart2;
|
|
||||||
|
|
||||||
typedef struct _CannedMessagePluginMessagePart3 {
|
|
||||||
char text[200];
|
|
||||||
} CannedMessagePluginMessagePart3;
|
|
||||||
|
|
||||||
typedef struct _CannedMessagePluginMessagePart4 {
|
|
||||||
char text[200];
|
|
||||||
} CannedMessagePluginMessagePart4;
|
|
||||||
|
|
||||||
typedef struct _CannedMessagePluginMessagePart5 {
|
|
||||||
char text[200];
|
|
||||||
} CannedMessagePluginMessagePart5;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -36,69 +23,31 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define CannedMessagePluginMessagePart1_init_default {""}
|
#define CannedMessagePluginConfig_init_default {"", "", "", ""}
|
||||||
#define CannedMessagePluginMessagePart2_init_default {""}
|
#define CannedMessagePluginConfig_init_zero {"", "", "", ""}
|
||||||
#define CannedMessagePluginMessagePart3_init_default {""}
|
|
||||||
#define CannedMessagePluginMessagePart4_init_default {""}
|
|
||||||
#define CannedMessagePluginMessagePart5_init_default {""}
|
|
||||||
#define CannedMessagePluginMessagePart1_init_zero {""}
|
|
||||||
#define CannedMessagePluginMessagePart2_init_zero {""}
|
|
||||||
#define CannedMessagePluginMessagePart3_init_zero {""}
|
|
||||||
#define CannedMessagePluginMessagePart4_init_zero {""}
|
|
||||||
#define CannedMessagePluginMessagePart5_init_zero {""}
|
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define CannedMessagePluginMessagePart1_text_tag 1
|
#define CannedMessagePluginConfig_messagesPart1_tag 11
|
||||||
#define CannedMessagePluginMessagePart2_text_tag 1
|
#define CannedMessagePluginConfig_messagesPart2_tag 12
|
||||||
#define CannedMessagePluginMessagePart3_text_tag 1
|
#define CannedMessagePluginConfig_messagesPart3_tag 13
|
||||||
#define CannedMessagePluginMessagePart4_text_tag 1
|
#define CannedMessagePluginConfig_messagesPart4_tag 14
|
||||||
#define CannedMessagePluginMessagePart5_text_tag 1
|
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define CannedMessagePluginMessagePart1_FIELDLIST(X, a) \
|
#define CannedMessagePluginConfig_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, STRING, text, 1)
|
X(a, STATIC, SINGULAR, STRING, messagesPart1, 11) \
|
||||||
#define CannedMessagePluginMessagePart1_CALLBACK NULL
|
X(a, STATIC, SINGULAR, STRING, messagesPart2, 12) \
|
||||||
#define CannedMessagePluginMessagePart1_DEFAULT NULL
|
X(a, STATIC, SINGULAR, STRING, messagesPart3, 13) \
|
||||||
|
X(a, STATIC, SINGULAR, STRING, messagesPart4, 14)
|
||||||
|
#define CannedMessagePluginConfig_CALLBACK NULL
|
||||||
|
#define CannedMessagePluginConfig_DEFAULT NULL
|
||||||
|
|
||||||
#define CannedMessagePluginMessagePart2_FIELDLIST(X, a) \
|
extern const pb_msgdesc_t CannedMessagePluginConfig_msg;
|
||||||
X(a, STATIC, SINGULAR, STRING, text, 1)
|
|
||||||
#define CannedMessagePluginMessagePart2_CALLBACK NULL
|
|
||||||
#define CannedMessagePluginMessagePart2_DEFAULT NULL
|
|
||||||
|
|
||||||
#define CannedMessagePluginMessagePart3_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, text, 1)
|
|
||||||
#define CannedMessagePluginMessagePart3_CALLBACK NULL
|
|
||||||
#define CannedMessagePluginMessagePart3_DEFAULT NULL
|
|
||||||
|
|
||||||
#define CannedMessagePluginMessagePart4_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, text, 1)
|
|
||||||
#define CannedMessagePluginMessagePart4_CALLBACK NULL
|
|
||||||
#define CannedMessagePluginMessagePart4_DEFAULT NULL
|
|
||||||
|
|
||||||
#define CannedMessagePluginMessagePart5_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, text, 1)
|
|
||||||
#define CannedMessagePluginMessagePart5_CALLBACK NULL
|
|
||||||
#define CannedMessagePluginMessagePart5_DEFAULT NULL
|
|
||||||
|
|
||||||
extern const pb_msgdesc_t CannedMessagePluginMessagePart1_msg;
|
|
||||||
extern const pb_msgdesc_t CannedMessagePluginMessagePart2_msg;
|
|
||||||
extern const pb_msgdesc_t CannedMessagePluginMessagePart3_msg;
|
|
||||||
extern const pb_msgdesc_t CannedMessagePluginMessagePart4_msg;
|
|
||||||
extern const pb_msgdesc_t CannedMessagePluginMessagePart5_msg;
|
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define CannedMessagePluginMessagePart1_fields &CannedMessagePluginMessagePart1_msg
|
#define CannedMessagePluginConfig_fields &CannedMessagePluginConfig_msg
|
||||||
#define CannedMessagePluginMessagePart2_fields &CannedMessagePluginMessagePart2_msg
|
|
||||||
#define CannedMessagePluginMessagePart3_fields &CannedMessagePluginMessagePart3_msg
|
|
||||||
#define CannedMessagePluginMessagePart4_fields &CannedMessagePluginMessagePart4_msg
|
|
||||||
#define CannedMessagePluginMessagePart5_fields &CannedMessagePluginMessagePart5_msg
|
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define CannedMessagePluginMessagePart1_size 202
|
#define CannedMessagePluginConfig_size 812
|
||||||
#define CannedMessagePluginMessagePart2_size 202
|
|
||||||
#define CannedMessagePluginMessagePart3_size 202
|
|
||||||
#define CannedMessagePluginMessagePart4_size 202
|
|
||||||
#define CannedMessagePluginMessagePart5_size 202
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -43,11 +43,6 @@ typedef struct _DeviceState {
|
|||||||
uint32_t version;
|
uint32_t version;
|
||||||
bool no_save;
|
bool no_save;
|
||||||
bool did_gps_reset;
|
bool did_gps_reset;
|
||||||
char canned_message_plugin_message_part1[200];
|
|
||||||
char canned_message_plugin_message_part2[200];
|
|
||||||
char canned_message_plugin_message_part3[200];
|
|
||||||
char canned_message_plugin_message_part4[200];
|
|
||||||
char canned_message_plugin_message_part5[200];
|
|
||||||
} DeviceState;
|
} DeviceState;
|
||||||
|
|
||||||
|
|
||||||
@@ -58,11 +53,11 @@ extern "C" {
|
|||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define LegacyRadioConfig_init_default {false, LegacyRadioConfig_LegacyPreferences_init_default}
|
#define LegacyRadioConfig_init_default {false, LegacyRadioConfig_LegacyPreferences_init_default}
|
||||||
#define LegacyRadioConfig_LegacyPreferences_init_default {_RegionCode_MIN}
|
#define LegacyRadioConfig_LegacyPreferences_init_default {_RegionCode_MIN}
|
||||||
#define DeviceState_init_default {false, LegacyRadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, "", "", "", "", ""}
|
#define DeviceState_init_default {false, LegacyRadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||||
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
|
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
|
||||||
#define LegacyRadioConfig_init_zero {false, LegacyRadioConfig_LegacyPreferences_init_zero}
|
#define LegacyRadioConfig_init_zero {false, LegacyRadioConfig_LegacyPreferences_init_zero}
|
||||||
#define LegacyRadioConfig_LegacyPreferences_init_zero {_RegionCode_MIN}
|
#define LegacyRadioConfig_LegacyPreferences_init_zero {_RegionCode_MIN}
|
||||||
#define DeviceState_init_zero {false, LegacyRadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, "", "", "", "", ""}
|
#define DeviceState_init_zero {false, LegacyRadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||||
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
|
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
@@ -78,11 +73,6 @@ extern "C" {
|
|||||||
#define DeviceState_version_tag 8
|
#define DeviceState_version_tag 8
|
||||||
#define DeviceState_no_save_tag 9
|
#define DeviceState_no_save_tag 9
|
||||||
#define DeviceState_did_gps_reset_tag 11
|
#define DeviceState_did_gps_reset_tag 11
|
||||||
#define DeviceState_canned_message_plugin_message_part1_tag 13
|
|
||||||
#define DeviceState_canned_message_plugin_message_part2_tag 14
|
|
||||||
#define DeviceState_canned_message_plugin_message_part3_tag 15
|
|
||||||
#define DeviceState_canned_message_plugin_message_part4_tag 16
|
|
||||||
#define DeviceState_canned_message_plugin_message_part5_tag 17
|
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define LegacyRadioConfig_FIELDLIST(X, a) \
|
#define LegacyRadioConfig_FIELDLIST(X, a) \
|
||||||
@@ -105,12 +95,7 @@ X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
|
|||||||
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
|
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
|
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
|
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
|
||||||
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part1, 13) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part2, 14) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part3, 15) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part4, 16) \
|
|
||||||
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part5, 17)
|
|
||||||
#define DeviceState_CALLBACK NULL
|
#define DeviceState_CALLBACK NULL
|
||||||
#define DeviceState_DEFAULT NULL
|
#define DeviceState_DEFAULT NULL
|
||||||
#define DeviceState_legacyRadio_MSGTYPE LegacyRadioConfig
|
#define DeviceState_legacyRadio_MSGTYPE LegacyRadioConfig
|
||||||
@@ -140,7 +125,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define LegacyRadioConfig_size 4
|
#define LegacyRadioConfig_size 4
|
||||||
#define LegacyRadioConfig_LegacyPreferences_size 2
|
#define LegacyRadioConfig_LegacyPreferences_size 2
|
||||||
#define DeviceState_size 11014
|
#define DeviceState_size 10002
|
||||||
#define ChannelFile_size 832
|
#define ChannelFile_size 832
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ typedef enum _HardwareModel {
|
|||||||
HardwareModel_ANDROID_SIM = 38,
|
HardwareModel_ANDROID_SIM = 38,
|
||||||
HardwareModel_DIY_V1 = 39,
|
HardwareModel_DIY_V1 = 39,
|
||||||
HardwareModel_RAK11200 = 40,
|
HardwareModel_RAK11200 = 40,
|
||||||
|
HardwareModel_NANO_G1 = 41,
|
||||||
HardwareModel_PRIVATE_HW = 255
|
HardwareModel_PRIVATE_HW = 255
|
||||||
} HardwareModel;
|
} HardwareModel;
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ typedef enum _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType {
|
|||||||
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22 = 4,
|
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22 = 4,
|
||||||
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280 = 5,
|
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280 = 5,
|
||||||
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680 = 6,
|
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680 = 6,
|
||||||
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808 = 7
|
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808 = 7,
|
||||||
|
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3 = 8
|
||||||
} RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType;
|
} RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
@@ -225,8 +226,8 @@ typedef struct _RadioConfig {
|
|||||||
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
|
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
|
||||||
|
|
||||||
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11
|
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11
|
||||||
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808
|
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3
|
||||||
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808+1))
|
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3+1))
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -755,7 +755,7 @@ void handleUpdateSPIFFS(HTTPRequest *req, HTTPResponse *res)
|
|||||||
if (!TARUnpacker->tarStreamExpander(streamptr, streamSize, SPIFFS, "/static")) {
|
if (!TARUnpacker->tarStreamExpander(streamptr, streamSize, SPIFFS, "/static")) {
|
||||||
res->printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
res->printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||||
Serial.printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
Serial.printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||||
|
client->stop();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -773,6 +773,7 @@ void handleUpdateSPIFFS(HTTPRequest *req, HTTPResponse *res)
|
|||||||
} else {
|
} else {
|
||||||
res->printf("Failed to establish http connection\n");
|
res->printf("Failed to establish http connection\n");
|
||||||
Serial.println("Failed to establish http connection");
|
Serial.println("Failed to establish http connection");
|
||||||
|
client->stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ void __attribute__((noreturn)) __assert_func(const char *file, int line, const c
|
|||||||
{
|
{
|
||||||
DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func, failedexpr);
|
DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func, failedexpr);
|
||||||
// debugger_break(); FIXME doesn't work, possibly not for segger
|
// debugger_break(); FIXME doesn't work, possibly not for segger
|
||||||
while (1)
|
// Reboot cpu
|
||||||
; // FIXME, reboot!
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getMacAddr(uint8_t *dmac)
|
void getMacAddr(uint8_t *dmac)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "CannedMessagePlugin.h"
|
#include "CannedMessagePlugin.h"
|
||||||
|
#include "PowerFSM.h" // neede for button bypass
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
|
|
||||||
// TODO: reuse defined from Screen.cpp
|
// TODO: reuse defined from Screen.cpp
|
||||||
@@ -111,9 +112,14 @@ int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
|
|||||||
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_SELECT))
|
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_SELECT))
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Canned message event Select\n");
|
DEBUG_MSG("Canned message event Select\n");
|
||||||
|
// when inactive, call the onebutton shortpress instead. Activate Module only on up/down
|
||||||
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) {
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
}else{
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (validEvent)
|
if (validEvent)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,7 +121,9 @@ void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies)
|
|||||||
p->priority = MeshPacket_Priority_BACKGROUND;
|
p->priority = MeshPacket_Priority_BACKGROUND;
|
||||||
prevPacketId = p->id;
|
prevPacketId = p->id;
|
||||||
|
|
||||||
service.sendToMesh(p);
|
|
||||||
|
//send to the mesh, and the phone
|
||||||
|
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t PositionPlugin::runOnce()
|
int32_t PositionPlugin::runOnce()
|
||||||
|
|||||||
@@ -36,3 +36,7 @@ cstyleCast
|
|||||||
// ignore stuff that is not ours
|
// ignore stuff that is not ours
|
||||||
*:.pio/*
|
*:.pio/*
|
||||||
*:*/libdeps/*
|
*:*/libdeps/*
|
||||||
|
|
||||||
|
// these two caused issues
|
||||||
|
missingOverride
|
||||||
|
virtualCallInConstructor
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
//#define GPS_TX_PIN 12 // not connected
|
//#define GPS_TX_PIN 12 // not connected
|
||||||
|
|
||||||
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
||||||
|
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
|
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
|
||||||
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
|
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
|
||||||
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
|
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
|
||||||
|
|
||||||
|
|||||||
8
variants/nano-g1/platformio.ini
Normal file
8
variants/nano-g1/platformio.ini
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
; The 1.0 release of the nano-g1 board
|
||||||
|
[env:nano-g1]
|
||||||
|
extends = esp32_base
|
||||||
|
board = ttgo-t-beam
|
||||||
|
lib_deps =
|
||||||
|
${esp32_base.lib_deps}
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags} -D NANO_G1 -I variants/nano-g1
|
||||||
32
variants/nano-g1/variant.h
Normal file
32
variants/nano-g1/variant.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
|
||||||
|
|
||||||
|
#define I2C_SDA 21
|
||||||
|
#define I2C_SCL 22
|
||||||
|
|
||||||
|
#define BUTTON_PIN 36 // The middle button GPIO on the Nano G1
|
||||||
|
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
|
||||||
|
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
|
||||||
|
|
||||||
|
// common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
||||||
|
// not found then probe for SX1262
|
||||||
|
#define USE_RF95
|
||||||
|
#define USE_SX1262
|
||||||
|
|
||||||
|
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||||
|
#define LORA_RESET 23
|
||||||
|
#define LORA_DIO1 33 // SX1262 IRQ
|
||||||
|
#define LORA_DIO2 32 // SX1262 BUSY
|
||||||
|
#define LORA_DIO3 // Not connected on PCB
|
||||||
|
|
||||||
|
#ifdef USE_SX1262
|
||||||
|
#define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead
|
||||||
|
#define SX126X_DIO1 LORA_DIO1
|
||||||
|
#define SX126X_BUSY LORA_DIO2
|
||||||
|
#define SX126X_RESET LORA_RESET
|
||||||
|
#define SX126X_E22 // Not really an E22
|
||||||
|
// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
|
||||||
|
// code)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// different screen
|
||||||
|
#define USE_SH1106
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 1
|
major = 1
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 55
|
build = 62
|
||||||
|
|||||||
Reference in New Issue
Block a user