Merge branch 'meshtastic:master' into master

This commit is contained in:
joshpirihi 2022-02-26 10:26:04 +13:00 committed by GitHub
commit 961cadd550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1017 additions and 279 deletions

76
.github/ISSUE_TEMPLATE/Bug Report.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: dropdown
id: category
attributes:
label: Category
description: How would you catagorize this issue?
multiple: true
options:
- Hardware Compatibility
- BLE
- Serial
- WiFi
- Other
validations:
required: true
- type: dropdown
id: hardware
attributes:
label: Hardware
description: What hardware are you encountering this issue on?
multiple: true
options:
- Not Applicable
- T-Beam
- T-Beam 0.7
- T-Lora v1
- T-Lora v1.3
- T-Lora v2 1.6
- T-Echo
- Rak4631
- Rak11200
- Heltec v1
- Heltec v2
- Heltec v2.1
- Relay v1
- Relay v2
- DIY
- Other
validations:
required: true
- type: input
id: version
attributes:
label: Firmware Version
description: This can be found on the device's screen or via one of the apps.
placeholder: x.x.x.yyyyyyy
validations:
required: true
- type: textarea
id: body
attributes:
label: Description
description: Please provide details on what steps you performed for this to happen.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: If you have any log output to help in diagnosing your bug, please provide it here.
render: Shell
validations:
required: false

View File

@ -1,38 +0,0 @@
---
name: Bug report or feature proposal
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
Please - if you just have a question (i.e. not a bug report or a feature proposal), post in our [forum](https://meshtastic.discourse.group/) instead.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Device info:**
- Device model: [e.g. TBEAM]
- Software Version [e.g. 0.7.8]
**Smartphone information (if relevant):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- App Version [e.g. 0.7.2]
**Additional context**
Add any other context about the problem here.

View File

@ -37,6 +37,7 @@ jobs:
- board: meshtastic-diy-v1
- board: rak4631_5005
- board: rak4631_19003
- board: rak4631_5005_eink
- board: t-echo
runs-on: ubuntu-latest
@ -162,6 +163,7 @@ jobs:
include:
- board: rak4631_5005
- board: rak4631_19003
- board: rak4631_5005_eink
- board: t-echo
runs-on: ubuntu-latest

View File

@ -37,7 +37,7 @@ jobs:
# if: steps.cache-pip.outputs.cache-hit != 'true'
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
pip install -U platformio meshtastic adafruit-nrfutil littlefs-python
- name: Upgrade platformio
run: |

72
README-docker.md Normal file
View File

@ -0,0 +1,72 @@
## What is Docker used for
Developers can simulate Device hardware by compiling and running
a linux native binary application. If you do not own a Linux
machine, or you just want to separate things, you might want
to run simulator inside a docker container
## The Image
To build docker image, type
`docker build -t meshtastic/device .`
## Usage
To run a container, type
`docker run --rm -p 4403:4403 meshtastic/device`
or, to get an interactive shell on the docker created container:
`docker run -it -p 4403:4403 meshtastic/device bash`
You might want to mount your local development folder:
`docker run -it --mount type=bind,source=/PathToMyProjects/Meshtastic/Meshtastic-device-mybranch,target=/Meshtastic-device-mybranch -p 4403:4403 meshtastic/device bash`
## Build the native application
Linux native application should be built inside the container.
For this you must run container with interactive console
"-it", as seen above.
First, some environment variables need to be set up with command:
`. ~/.platformio/penv/bin/activate`
You also want to make some adjustments in the bin/build-all.sh to conform the amd64 build:
```
sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' bin/build-all.sh
sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' bin/build-all.sh
sed -i 's/echo "Building SPIFFS.*/exit/' bin/build-all.sh
```
You can build amd64 image with command
`bin/build-all.sh`
## Executing the application interactively
The built binary file should be found under name
`release/latest/bins/universal/meshtastic_linux_amd64`.
If this is not the case, you can also use direct program name:
`.pio/build/native/program`
To use python cli against exposed port 4403,
type this in the host machine:
`meshtastic --info --host localhost`
## Stop the container
Run this to get the ID:
`docker ps`
Stop the container with command:
`docker kill <id>`
> Tip: you can just use the first few characters of the ID in docker commands

View File

@ -7,8 +7,12 @@
Update Instructions
[Using Meshtastic Flasher](https://meshtastic.org/docs/getting-started/meshtastic-flasher)
Manual Method
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32)
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
For developer information and specific building instructions, please see the [developer doccumentation](https://meshtastic.org/docs/developers)
For developer information and specific building instructions, please see the [developer documentation](https://meshtastic.org/docs/developers)

View File

@ -9,7 +9,7 @@ BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-
#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
BOARDS_NRF52="rak4631_5005 rak4631_19003 t-echo"
BOARDS_NRF52="rak4631_5005 rak4631_5005_eink rak4631_19003 t-echo"
#BOARDS_NRF52=""
OUTDIR=release/latest

View File

@ -8,6 +8,10 @@ from readprops import readProps
Import("env")
env.Replace( MKSPIFFSTOOL=env.get("PROJECT_DIR") + '/bin/mklittlefs.py' )
try:
import littlefs
except ImportError:
env.Execute("$PYTHONEXE -m pip install --user littlefs-python")
Import("projenv")

View File

@ -1,17 +0,0 @@
To build:
docker build -t meshtastic/device .
To run:
docker run --rm -p 4403:4403 meshtastic/device
or, to get a shell on the docker image:
docker run -it meshtastic/device bash
To use python cli against it:
meshtastic --info --host localhost
To stop:
# run this to get id
docker ps
# tip: you can just use the first few characters of the id in the next command
docker kill <id>

View File

@ -23,8 +23,9 @@ default_envs = tbeam
;default_envs = t-echo
;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 = rak4631
;default_envs = rak4630
;default_envs = rak4631_5005
;default_envs = rak4631_5005_eink
;default_envs = rak4631_19003
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1

2
proto

@ -1 +1 @@
Subproject commit 6a66f8b1f81815e62279ff66dea908112583e6ab
Subproject commit 30e147a55ce27199cb638a1d82e0b88adc8f5385

View File

@ -9,14 +9,45 @@
#define COLORED GxEPD_BLACK
#define UNCOLORED GxEPD_WHITE
#if defined(TTGO_T_ECHO)
#define TECHO_DISPLAY_MODEL GxEPD2_154_D67
#elif defined(RAK4630)
//GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
#define TECHO_DISPLAY_MODEL GxEPD2_213_B74
//4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
//2.9 inch 296x128 - GxEPD2_290_T5D
//#define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
//1.54 inch 200x200 - GxEPD2_154_M09
//#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
{
#if defined(TTGO_T_ECHO)
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
#elif defined(RAK4630)
//GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
setGeometry(GEOMETRY_RAWMODE, 250, 122);
//GxEPD2_420_M01
//setGeometry(GEOMETRY_RAWMODE, 300, 400);
//GxEPD2_290_T5D
//setGeometry(GEOMETRY_RAWMODE, 296, 128);
//GxEPD2_154_M09
//setGeometry(GEOMETRY_RAWMODE, 200, 200);
#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
}
@ -40,8 +71,8 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
for (uint8_t y = 0; y < displayHeight; y++) {
for (uint8_t x = 0; x < displayWidth; x++) {
for (uint64_t y = 0; y < displayHeight; y++) {
for (uint64_t x = 0; x < displayWidth; x++) {
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
auto b = buffer[x + (y / 8) * displayWidth];
@ -50,9 +81,28 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
}
}
DEBUG_MSG("Updating eink... ");
#if defined(TTGO_T_ECHO)
DEBUG_MSG("Updating T-ECHO E-Paper... ");
#elif defined(RAK4630)
DEBUG_MSG("Updating RAK4361_5005 E-Paper... ");
#endif
#if defined(TTGO_T_ECHO)
// ePaper.Reset(); // wake the screen from sleep
adafruitDisplay->display(false); // FIXME, use partial update mode
#elif defined(RAK4630)
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->display(false); // FIXME, use partial update mode
//Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
// 1.54 inch 200x200 - GxEPD2_154_M09
// 2.9 inch 296x128 - GxEPD2_290_T5D
// 4.2 inch 300x400 - GxEPD2_420_M01
//adafruitDisplay->nextPage();
#endif
// Put screen to sleep to save power (possibly not necessary because we already did poweroff inside of display)
adafruitDisplay->hibernate();
DEBUG_MSG("done\n");
@ -97,14 +147,33 @@ bool EInkDisplay::connect()
pinMode(PIN_EINK_EN, OUTPUT);
#endif
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS,
PIN_EINK_DC,
PIN_EINK_RES,
PIN_EINK_BUSY, SPI1);
#if defined(TTGO_T_ECHO)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init();
adafruitDisplay->setRotation(3);
}
#elif defined(RAK4630)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->setRotation(3);
//For 1.54, 2.9 and 4.2
//adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
#endif
//adafruitDisplay->setFullWindow();
//adafruitDisplay->fillScreen(UNCOLORED);
//adafruitDisplay->drawCircle(100, 100, 20, COLORED);

View File

@ -226,6 +226,7 @@ std::vector<MeshPlugin *> MeshPlugin::GetMeshPluginsWithUIFrames()
{
std::vector<MeshPlugin *> pluginsWithUIFrames;
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i;
if (pi.wantUIFrame()) {
@ -233,13 +234,14 @@ std::vector<MeshPlugin *> MeshPlugin::GetMeshPluginsWithUIFrames()
pluginsWithUIFrames.push_back(&pi);
}
}
}
return pluginsWithUIFrames;
}
void MeshPlugin::observeUIEvents(
Observer<const UIFrameEvent *> *observer)
{
std::vector<MeshPlugin *> pluginsWithUIFrames;
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i;
Observable<const UIFrameEvent *> *observable =
@ -249,4 +251,32 @@ void MeshPlugin::observeUIEvents(
observer->observe(observable);
}
}
}
}
AdminMessageHandleResult MeshPlugin::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
{
AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED;
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i;
AdminMessageHandleResult h = pi.handleAdminMessageForPlugin(mp, request, response);
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE)
{
// In case we have a response it always has priority.
DEBUG_MSG("Reply prepared by plugin '%s' of variant: %d\n",
pi.name,
response->which_variant);
handled = h;
}
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
(h == AdminMessageHandleResult::HANDLED))
{
// In case the message is handled it should be populated, but will not overwrite
// a result with response.
handled = h;
}
}
}
return handled;
}

View File

@ -21,6 +21,19 @@ enum class ProcessMessage
STOP = 1,
};
/**
* Used by plugins to return the result of the AdminMessage handling.
* If request is handled, then plugin should return HANDLED,
* If response is also prepared for the request, then HANDLED_WITH_RESPONSE
* should be returned.
*/
enum class AdminMessageHandleResult
{
NOT_HANDLED = 0,
HANDLED = 1,
HANDLED_WITH_RESPONSE = 2,
};
/*
* This struct is used by Screen to figure out whether screen frame should be updated.
*/
@ -57,6 +70,8 @@ class MeshPlugin
static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames();
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
static AdminMessageHandleResult handleAdminMessageForAllPlugins(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response);
#ifndef NO_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
#endif
@ -135,6 +150,19 @@ class MeshPlugin
/// Send an error response for the specified packet.
MeshPacket *allocErrorResponse(Routing_Error err, const MeshPacket *p);
/**
* @brief An admin message arrived to AdminPlugin. Plugin was asked whether it want to handle the request.
*
* @param mp The mesh packet arrived.
* @param request The AdminMessage request extracted from the packet.
* @param response The prepared response
* @return AdminMessageHandleResult
* HANDLED if message was handled
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
*/
virtual AdminMessageHandleResult handleAdminMessageForPlugin(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) { return AdminMessageHandleResult::NOT_HANDLED; };
private:
/**
* If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow

View File

@ -34,6 +34,7 @@ NodeDB nodeDB;
// we have plenty of ram so statically alloc this tempbuf (for now)
EXT_RAM_ATTR DeviceState devicestate;
MyNodeInfo &myNodeInfo = devicestate.my_node;
GroupInfo &ourGroupInfo = devicestate.group_info;
RadioConfig radioConfig;
ChannelFile channelFile;

View File

@ -11,6 +11,7 @@
extern DeviceState devicestate;
extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo;
extern GroupInfo &ourGroupInfo;
extern RadioConfig radioConfig;
extern User &owner;

View File

@ -1,4 +1,3 @@
#include "configuration.h"
#include "PhoneAPI.h"
#include "Channels.h"
#include "GPS.h"
@ -6,6 +5,7 @@
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RadioInterface.h"
#include "configuration.h"
#include <assert.h>
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE

View File

@ -24,6 +24,7 @@ class PhoneAPI
STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config
// (disconnected)
STATE_SEND_MY_INFO, // send our my info record
STATE_SEND_GROUPS,
// STATE_SEND_RADIO, // in 1.2 we now send this as a regular mesh packet
// STATE_SEND_OWNER, no need to send Owner specially, it is just part of the nodedb
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client

View File

@ -4,7 +4,6 @@
#ifndef PB_ADMIN_PB_H_INCLUDED
#define PB_ADMIN_PB_H_INCLUDED
#include <pb.h>
#include "cannedmessages.pb.h"
#include "channel.pb.h"
#include "mesh.pb.h"
#include "radioconfig.pb.h"
@ -31,20 +30,17 @@ typedef struct _AdminMessage {
bool exit_simulator;
int32_t reboot_seconds;
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;
CannedMessagePluginMessagePart2 get_canned_message_plugin_part2_response;
char get_canned_message_plugin_part2_response[201];
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;
CannedMessagePluginMessagePart4 get_canned_message_plugin_part4_response;
bool get_canned_message_plugin_part5_request;
CannedMessagePluginMessagePart5 get_canned_message_plugin_part5_response;
CannedMessagePluginMessagePart1 set_canned_message_plugin_part1;
CannedMessagePluginMessagePart2 set_canned_message_plugin_part2;
CannedMessagePluginMessagePart3 set_canned_message_plugin_part3;
CannedMessagePluginMessagePart4 set_canned_message_plugin_part4;
CannedMessagePluginMessagePart5 set_canned_message_plugin_part5;
char get_canned_message_plugin_part4_response[201];
char set_canned_message_plugin_part1[201];
char set_canned_message_plugin_part2[201];
char set_canned_message_plugin_part3[201];
char set_canned_message_plugin_part4[201];
int32_t shutdown_seconds;
};
} AdminMessage;
@ -80,13 +76,10 @@ extern "C" {
#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_response_tag 43
#define AdminMessage_get_canned_message_plugin_part5_request_tag 44
#define AdminMessage_get_canned_message_plugin_part5_response_tag 45
#define AdminMessage_set_canned_message_plugin_part1_tag 46
#define AdminMessage_set_canned_message_plugin_part2_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_set_canned_message_plugin_part1_tag 44
#define AdminMessage_set_canned_message_plugin_part2_tag 45
#define AdminMessage_set_canned_message_plugin_part3_tag 46
#define AdminMessage_set_canned_message_plugin_part4_tag 47
#define AdminMessage_shutdown_seconds_tag 51
/* 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, 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, 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, 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, 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, MESSAGE, (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, MESSAGE, (variant,get_canned_message_plugin_part5_response,get_canned_message_plugin_part5_response), 45) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 46) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 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, STRING, (variant,get_canned_message_plugin_part4_response,get_canned_message_plugin_part4_response), 43) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 44) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 45) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part3,set_canned_message_plugin_part3), 46) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part4,set_canned_message_plugin_part4), 47) \
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
#define AdminMessage_CALLBACK 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_channel_response_MSGTYPE Channel
#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;
@ -145,7 +125,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
#define AdminMessage_fields &AdminMessage_msg
/* Maximum encoded size of messages (where known) */
#define AdminMessage_size 804
#define AdminMessage_size 601
#ifdef __cplusplus
} /* extern "C" */

View File

@ -6,19 +6,7 @@
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(CannedMessagePluginMessagePart1, CannedMessagePluginMessagePart1, AUTO)
PB_BIND(CannedMessagePluginMessagePart2, CannedMessagePluginMessagePart2, AUTO)
PB_BIND(CannedMessagePluginMessagePart3, CannedMessagePluginMessagePart3, AUTO)
PB_BIND(CannedMessagePluginMessagePart4, CannedMessagePluginMessagePart4, AUTO)
PB_BIND(CannedMessagePluginMessagePart5, CannedMessagePluginMessagePart5, AUTO)
PB_BIND(CannedMessagePluginConfig, CannedMessagePluginConfig, 2)

View File

@ -10,25 +10,12 @@
#endif
/* Struct definitions */
typedef struct _CannedMessagePluginMessagePart1 {
char text[200];
} CannedMessagePluginMessagePart1;
typedef struct _CannedMessagePluginMessagePart2 {
char text[200];
} CannedMessagePluginMessagePart2;
typedef struct _CannedMessagePluginMessagePart3 {
char text[200];
} CannedMessagePluginMessagePart3;
typedef struct _CannedMessagePluginMessagePart4 {
char text[200];
} CannedMessagePluginMessagePart4;
typedef struct _CannedMessagePluginMessagePart5 {
char text[200];
} CannedMessagePluginMessagePart5;
typedef struct _CannedMessagePluginConfig {
char messagesPart1[201];
char messagesPart2[201];
char messagesPart3[201];
char messagesPart4[201];
} CannedMessagePluginConfig;
#ifdef __cplusplus
@ -36,69 +23,31 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define CannedMessagePluginMessagePart1_init_default {""}
#define CannedMessagePluginMessagePart2_init_default {""}
#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 {""}
#define CannedMessagePluginConfig_init_default {"", "", "", ""}
#define CannedMessagePluginConfig_init_zero {"", "", "", ""}
/* Field tags (for use in manual encoding/decoding) */
#define CannedMessagePluginMessagePart1_text_tag 1
#define CannedMessagePluginMessagePart2_text_tag 1
#define CannedMessagePluginMessagePart3_text_tag 1
#define CannedMessagePluginMessagePart4_text_tag 1
#define CannedMessagePluginMessagePart5_text_tag 1
#define CannedMessagePluginConfig_messagesPart1_tag 11
#define CannedMessagePluginConfig_messagesPart2_tag 12
#define CannedMessagePluginConfig_messagesPart3_tag 13
#define CannedMessagePluginConfig_messagesPart4_tag 14
/* Struct field encoding specification for nanopb */
#define CannedMessagePluginMessagePart1_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart1_CALLBACK NULL
#define CannedMessagePluginMessagePart1_DEFAULT NULL
#define CannedMessagePluginConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, messagesPart1, 11) \
X(a, STATIC, SINGULAR, STRING, messagesPart2, 12) \
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) \
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;
extern const pb_msgdesc_t CannedMessagePluginConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define CannedMessagePluginMessagePart1_fields &CannedMessagePluginMessagePart1_msg
#define CannedMessagePluginMessagePart2_fields &CannedMessagePluginMessagePart2_msg
#define CannedMessagePluginMessagePart3_fields &CannedMessagePluginMessagePart3_msg
#define CannedMessagePluginMessagePart4_fields &CannedMessagePluginMessagePart4_msg
#define CannedMessagePluginMessagePart5_fields &CannedMessagePluginMessagePart5_msg
#define CannedMessagePluginConfig_fields &CannedMessagePluginConfig_msg
/* Maximum encoded size of messages (where known) */
#define CannedMessagePluginMessagePart1_size 202
#define CannedMessagePluginMessagePart2_size 202
#define CannedMessagePluginMessagePart3_size 202
#define CannedMessagePluginMessagePart4_size 202
#define CannedMessagePluginMessagePart5_size 202
#define CannedMessagePluginConfig_size 812
#ifdef __cplusplus
} /* extern "C" */

View File

@ -27,16 +27,13 @@ typedef struct _DeviceState {
NodeInfo node_db[32];
pb_size_t receive_queue_count;
MeshPacket receive_queue[1];
bool has_group_info;
GroupInfo group_info;
bool has_rx_text_message;
MeshPacket rx_text_message;
uint32_t version;
bool no_save;
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;
@ -45,9 +42,9 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define DeviceState_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, 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, GroupInfo_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 DeviceState_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, 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, GroupInfo_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}}
/* Field tags (for use in manual encoding/decoding) */
@ -56,15 +53,11 @@ extern "C" {
#define DeviceState_owner_tag 3
#define DeviceState_node_db_tag 4
#define DeviceState_receive_queue_tag 5
#define DeviceState_group_info_tag 6
#define DeviceState_rx_text_message_tag 7
#define DeviceState_version_tag 8
#define DeviceState_no_save_tag 9
#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 */
#define DeviceState_FIELDLIST(X, a) \
@ -72,21 +65,18 @@ X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \
X(a, STATIC, REPEATED, MESSAGE, node_db, 4) \
X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, group_info, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
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)
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
#define DeviceState_CALLBACK NULL
#define DeviceState_DEFAULT NULL
#define DeviceState_my_node_MSGTYPE MyNodeInfo
#define DeviceState_owner_MSGTYPE User
#define DeviceState_node_db_MSGTYPE NodeInfo
#define DeviceState_receive_queue_MSGTYPE MeshPacket
#define DeviceState_group_info_MSGTYPE GroupInfo
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
#define ChannelFile_FIELDLIST(X, a) \
@ -103,7 +93,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
#define ChannelFile_fields &ChannelFile_msg
/* Maximum encoded size of messages (where known) */
#define DeviceState_size 10985
#define DeviceState_size 10162
#define ChannelFile_size 832
#ifdef __cplusplus

View File

@ -27,6 +27,9 @@ PB_BIND(MeshPacket, MeshPacket, 2)
PB_BIND(NodeInfo, NodeInfo, AUTO)
PB_BIND(GroupInfo, GroupInfo, AUTO)
PB_BIND(MyNodeInfo, MyNodeInfo, 2)

View File

@ -140,8 +140,14 @@ typedef struct _Data {
uint32_t request_id;
uint32_t reply_id;
bool is_tapback;
uint8_t group_id;
} Data;
typedef struct _GroupInfo {
pb_size_t group_count;
char group[10][17];
} GroupInfo;
typedef struct _LogRecord {
char message[64];
uint32_t time;
@ -269,6 +275,7 @@ typedef struct _FromRadio {
uint32_t config_complete_id;
bool rebooted;
MeshPacket packet;
GroupInfo groups;
};
} FromRadio;
@ -334,9 +341,10 @@ extern "C" {
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
#define GroupInfo_init_default {0, {"", "", "", "", "", "", "", "", "", ""}}
#define MyNodeInfo_init_default {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
@ -346,9 +354,10 @@ extern "C" {
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
#define GroupInfo_init_zero {0, {"", "", "", "", "", "", "", "", "", ""}}
#define MyNodeInfo_init_zero {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
@ -364,6 +373,8 @@ extern "C" {
#define Data_request_id_tag 6
#define Data_reply_id_tag 7
#define Data_is_tapback_tag 8
#define Data_group_id_tag 9
#define GroupInfo_group_tag 1
#define LogRecord_message_tag 1
#define LogRecord_time_tag 2
#define LogRecord_source_tag 3
@ -449,6 +460,7 @@ extern "C" {
#define FromRadio_config_complete_id_tag 8
#define FromRadio_rebooted_tag 9
#define FromRadio_packet_tag 11
#define FromRadio_groups_tag 12
#define ToRadio_packet_tag 2
#define ToRadio_peer_info_tag 3
#define ToRadio_want_config_id_tag 100
@ -518,7 +530,8 @@ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, BOOL, is_tapback, 8)
X(a, STATIC, SINGULAR, BOOL, is_tapback, 8) \
X(a, STATIC, SINGULAR, UINT32, group_id, 9)
#define Data_CALLBACK NULL
#define Data_DEFAULT NULL
@ -551,6 +564,11 @@ X(a, STATIC, SINGULAR, FLOAT, snr, 7)
#define NodeInfo_user_MSGTYPE User
#define NodeInfo_position_MSGTYPE Position
#define GroupInfo_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, STRING, group, 1)
#define GroupInfo_CALLBACK NULL
#define GroupInfo_DEFAULT NULL
#define MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
@ -587,13 +605,15 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,groups,groups), 12)
#define FromRadio_CALLBACK NULL
#define FromRadio_DEFAULT NULL
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
#define FromRadio_payloadVariant_groups_MSGTYPE GroupInfo
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \
@ -618,6 +638,7 @@ extern const pb_msgdesc_t Routing_msg;
extern const pb_msgdesc_t Data_msg;
extern const pb_msgdesc_t MeshPacket_msg;
extern const pb_msgdesc_t NodeInfo_msg;
extern const pb_msgdesc_t GroupInfo_msg;
extern const pb_msgdesc_t MyNodeInfo_msg;
extern const pb_msgdesc_t LogRecord_msg;
extern const pb_msgdesc_t FromRadio_msg;
@ -632,6 +653,7 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
#define Data_fields &Data_msg
#define MeshPacket_fields &MeshPacket_msg
#define NodeInfo_fields &NodeInfo_msg
#define GroupInfo_fields &GroupInfo_msg
#define MyNodeInfo_fields &MyNodeInfo_msg
#define LogRecord_fields &LogRecord_msg
#define FromRadio_fields &FromRadio_msg
@ -643,13 +665,14 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
#define User_size 97
#define RouteDiscovery_size 40
#define Routing_size 42
#define Data_size 267
#define MeshPacket_size 318
#define Data_size 270
#define MeshPacket_size 321
#define NodeInfo_size 271
#define GroupInfo_size 180
#define MyNodeInfo_size 434
#define LogRecord_size 81
#define FromRadio_size 443
#define ToRadio_size 321
#define ToRadio_size 324
#define ToRadio_PeerInfo_size 8
#ifdef __cplusplus

View File

@ -20,6 +20,7 @@ typedef enum _PortNum {
PortNum_ADMIN_APP = 6,
PortNum_REPLY_APP = 32,
PortNum_IP_TUNNEL_APP = 33,
PortNum_GROUP_APP = 34,
PortNum_SERIAL_APP = 64,
PortNum_STORE_FORWARD_APP = 65,
PortNum_RANGE_TEST_APP = 66,

View File

@ -186,7 +186,6 @@ typedef struct _RadioConfig_UserPreferences {
InputEventChar rotary1_event_press;
bool canned_message_plugin_enabled;
char canned_message_plugin_allow_input_source[16];
char canned_message_plugin_messages[200];
bool canned_message_plugin_send_bell;
bool mqtt_encryption_enabled;
float adc_multiplier_override;
@ -238,9 +237,9 @@ extern "C" {
/* Initializer values for message structs */
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0, 0, 0}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", 0, 0, 0}
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0, 0, 0}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", 0, 0, 0}
/* Field tags (for use in manual encoding/decoding) */
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
@ -322,7 +321,6 @@ extern "C" {
#define RadioConfig_UserPreferences_rotary1_event_press_tag 166
#define RadioConfig_UserPreferences_canned_message_plugin_enabled_tag 170
#define RadioConfig_UserPreferences_canned_message_plugin_allow_input_source_tag 171
#define RadioConfig_UserPreferences_canned_message_plugin_messages_tag 172
#define RadioConfig_UserPreferences_canned_message_plugin_send_bell_tag 173
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175
@ -415,7 +413,6 @@ X(a, STATIC, SINGULAR, UENUM, rotary1_event_ccw, 165) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_press, 166) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_enabled, 170) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_allow_input_source, 171) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_messages, 172) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_send_bell, 173) \
X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 175)
@ -430,8 +427,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
/* Maximum encoded size of messages (where known) */
#define RadioConfig_size 801
#define RadioConfig_UserPreferences_size 798
#define RadioConfig_size 598
#define RadioConfig_UserPreferences_size 595
#ifdef __cplusplus
} /* extern "C" */

View File

@ -390,6 +390,9 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
res->println("Web server is running.<br><br>The content you are looking for can't be found. Please see: <a "
"href=https://meshtastic.org/docs/getting-started/faq#wifi--web-browser>FAQ</a>.<br><br><a "
"href=/admin>admin</a>");
return;
} else {
res->setHeader("Content-Encoding", "gzip");
}
@ -427,6 +430,7 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
return;
} else {
DEBUG_MSG("ERROR: This should not have happened...\n");
res->println("ERROR: This should not have happened...");
}
}

View File

@ -175,6 +175,9 @@ bool initWifi(bool forceSoftAP)
{
forcedSoftAP = forceSoftAP;
// strcpy(radioConfig.preferences.wifi_ssid, "meshtastic");
// strcpy(radioConfig.preferences.wifi_password, "meshtastic!");
if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) {
const char *wifiName = radioConfig.preferences.wifi_ssid;
const char *wifiPsw = radioConfig.preferences.wifi_password;

View File

@ -63,6 +63,9 @@ void AdminPlugin::handleGetRadio(const MeshPacket &req)
bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
{
// if handled == false, then let others look at this message also if they want
bool handled = false;
assert(r);
switch (r->which_variant) {
case AdminMessage_set_owner_tag:
@ -119,11 +122,25 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
#endif
default:
AdminMessage response = AdminMessage_init_default;
AdminMessageHandleResult handleResult = MeshPlugin::handleAdminMessageForAllPlugins(mp, r, &response);
if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE)
{
myReply = allocDataProtobuf(response);
}
else if (mp.decoded.want_response)
{
DEBUG_MSG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_variant);
}
else if (handleResult != AdminMessageHandleResult::HANDLED)
{
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant);
}
break;
}
return false; // Let others look at this message also if they want
return handled;
}
void AdminPlugin::handleSetOwner(const User &o)

View File

@ -1,6 +1,8 @@
#include "configuration.h"
#include "CannedMessagePlugin.h"
#include "MeshService.h"
#include "FSCommon.h"
#include "mesh/generated/cannedmessages.pb.h"
// TODO: reuse defined from Screen.cpp
#define FONT_SMALL ArialMT_Plain_10
@ -10,22 +12,34 @@
// Remove Canned message screen if no action is taken for some milliseconds
#define INACTIVATE_AFTER_MS 20000
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
CannedMessagePluginConfig cannedMessagePluginConfig;
CannedMessagePlugin *cannedMessagePlugin;
// TODO: move it into NodeDB.h!
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
extern bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct);
CannedMessagePlugin::CannedMessagePlugin()
: SinglePortPlugin("canned", PortNum_TEXT_MESSAGE_APP),
concurrency::OSThread("CannedMessagePlugin")
{
if (radioConfig.preferences.canned_message_plugin_enabled)
{
this->loadProtoForPlugin();
if(this->splitConfiguredMessages() <= 0)
{
radioConfig.preferences.canned_message_plugin_enabled = false;
DEBUG_MSG("CannedMessagePlugin: No messages are configured. Plugin is disabled\n");
return;
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
}
else
{
DEBUG_MSG("CannedMessagePlugin is enabled\n");
this->inputObserver.observe(inputBroker);
}
}
}
/**
@ -39,11 +53,21 @@ int CannedMessagePlugin::splitConfiguredMessages()
int messageIndex = 0;
int i = 0;
strncpy(
// collect all the message parts
strcpy(
this->messageStore,
radioConfig.preferences.canned_message_plugin_messages,
CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE);
cannedMessagePluginConfig.messagesPart1);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart2);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart3);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart4);
// The first message points to the beginning of the store.
this->messages[messageIndex++] =
this->messageStore;
int upTo =
@ -58,6 +82,7 @@ int CannedMessagePlugin::splitConfiguredMessages()
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
// hit our max messages, bail
if (messageIndex >= CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT)
{
this->messagesCount = messageIndex;
@ -72,6 +97,7 @@ int CannedMessagePlugin::splitConfiguredMessages()
}
if (strlen(this->messages[messageIndex-1]) > 0)
{
// We have a last message.
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
this->messagesCount = messageIndex;
@ -92,6 +118,9 @@ int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, "_any") != 0))
{
// Event source is not accepted.
// Event only accepted if source matches the configured one, or
// the configured one is "_any" (or if there is no configured
// source at all)
return 0;
}
@ -140,9 +169,6 @@ void CannedMessagePlugin::sendText(NodeNum dest,
p->decoded.payload.size++;
}
// PacketId prevPacketId = p->id; // In case we need it later.
DEBUG_MSG("Sending message id=%d, msg=%.*s\n",
p->id, p->decoded.payload.size, p->decoded.payload.bytes);
@ -152,6 +178,7 @@ void CannedMessagePlugin::sendText(NodeNum dest,
int32_t CannedMessagePlugin::runOnce()
{
if ((!radioConfig.preferences.canned_message_plugin_enabled)
|| (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)
|| (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE))
{
return 30000; // TODO: should return MAX_VAL
@ -180,7 +207,7 @@ int32_t CannedMessagePlugin::runOnce()
else if (this->currentMessageIndex == -1)
{
this->currentMessageIndex = 0;
DEBUG_MSG("First touch.\n");
DEBUG_MSG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
e.frameChanged = true;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
}
@ -199,13 +226,13 @@ int32_t CannedMessagePlugin::runOnce()
{
this->currentMessageIndex = getPrevIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE UP\n");
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
}
else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN)
{
this->currentMessageIndex = this->getNextIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE DOWN\n");
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
}
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE)
@ -286,3 +313,226 @@ void CannedMessagePlugin::drawFrame(
}
}
void CannedMessagePlugin::loadProtoForPlugin()
{
if (!loadProto(cannedMessagesConfigFile, CannedMessagePluginConfig_size, sizeof(cannedMessagesConfigFile), CannedMessagePluginConfig_fields, &cannedMessagePluginConfig)) {
installDefaultCannedMessagePluginConfig();
}
}
/**
* @brief Save the plugin config to file.
*
* @return true On success.
* @return false On error.
*/
bool CannedMessagePlugin::saveProtoForPlugin()
{
bool okay = true;
#ifdef FS
FS.mkdir("/prefs");
#endif
okay &= saveProto(cannedMessagesConfigFile, CannedMessagePluginConfig_size, sizeof(CannedMessagePluginConfig), CannedMessagePluginConfig_fields, &cannedMessagePluginConfig);
return okay;
}
/**
* @brief Fill configuration with default values.
*/
void CannedMessagePlugin::installDefaultCannedMessagePluginConfig()
{
memset(cannedMessagePluginConfig.messagesPart1, 0, sizeof(cannedMessagePluginConfig.messagesPart1));
memset(cannedMessagePluginConfig.messagesPart2, 0, sizeof(cannedMessagePluginConfig.messagesPart2));
memset(cannedMessagePluginConfig.messagesPart3, 0, sizeof(cannedMessagePluginConfig.messagesPart3));
memset(cannedMessagePluginConfig.messagesPart4, 0, sizeof(cannedMessagePluginConfig.messagesPart4));
}
/**
* @brief An admin message arrived to AdminPlugin. We are asked whether we want to handle that.
*
* @param mp The mesh packet arrived.
* @param request The AdminMessage request extracted from the packet.
* @param response The prepared response
* @return AdminMessageHandleResult HANDLED if message was handled
* HANDLED_WITH_RESULT if a result is also prepared.
*/
AdminMessageHandleResult CannedMessagePlugin::handleAdminMessageForPlugin(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
{
AdminMessageHandleResult result;
switch (request->which_variant) {
case AdminMessage_get_canned_message_plugin_part1_request_tag:
DEBUG_MSG("Client is getting radio canned message part1\n");
this->handleGetCannedMessagePluginPart1(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part2_request_tag:
DEBUG_MSG("Client is getting radio canned message part2\n");
this->handleGetCannedMessagePluginPart2(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part3_request_tag:
DEBUG_MSG("Client is getting radio canned message part3\n");
this->handleGetCannedMessagePluginPart3(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part4_request_tag:
DEBUG_MSG("Client is getting radio canned message part4\n");
this->handleGetCannedMessagePluginPart4(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_set_canned_message_plugin_part1_tag:
DEBUG_MSG("Client is setting radio canned message part 1\n");
this->handleSetCannedMessagePluginPart1(
request->set_canned_message_plugin_part1);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part2_tag:
DEBUG_MSG("Client is setting radio canned message part 2\n");
this->handleSetCannedMessagePluginPart2(
request->set_canned_message_plugin_part2);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part3_tag:
DEBUG_MSG("Client is setting radio canned message part 3\n");
this->handleSetCannedMessagePluginPart3(
request->set_canned_message_plugin_part3);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part4_tag:
DEBUG_MSG("Client is setting radio canned message part 4\n");
this->handleSetCannedMessagePluginPart4(
request->set_canned_message_plugin_part4);
result = AdminMessageHandleResult::HANDLED;
break;
default:
result = AdminMessageHandleResult::NOT_HANDLED;
}
return result;
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart1(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart1\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part1_response_tag;
strcpy(
response->get_canned_message_plugin_part1_response,
cannedMessagePluginConfig.messagesPart1);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart2(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart2\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part2_response_tag;
strcpy(
response->get_canned_message_plugin_part2_response,
cannedMessagePluginConfig.messagesPart2);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart3(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart3\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part3_response_tag;
strcpy(
response->get_canned_message_plugin_part3_response,
cannedMessagePluginConfig.messagesPart3);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart4(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart4\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part4_response_tag;
strcpy(
response->get_canned_message_plugin_part4_response,
cannedMessagePluginConfig.messagesPart4);
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart1(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart1, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart1, from_msg);
DEBUG_MSG("*** from_msg.text:%s\n", from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart2(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart2, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart2, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart3(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart3, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart3, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart4(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart4, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart4, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
}
}

View File

@ -1,24 +1,24 @@
#pragma once
#include "SinglePortPlugin.h"
#include "ProtobufPlugin.h"
#include "input/InputBroker.h"
enum cannedMessagePluginRunState
{
CANNED_MESSAGE_RUN_STATE_DISABLED,
CANNED_MESSAGE_RUN_STATE_INACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTIVE,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
};
#define CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT 50
/**
* Due to config-packet size restrictions we cannot have user configuration bigger
* than Constants_DATA_PAYLOAD_LEN bytes.
* Sum of CannedMessagePluginConfig part sizes.
*/
#define CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE 200
#define CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE 800
class CannedMessagePlugin :
public SinglePortPlugin,
@ -38,6 +38,16 @@ class CannedMessagePlugin :
void eventDown();
void eventSelect();
void handleGetCannedMessagePluginPart1(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart2(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart3(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart4(const MeshPacket &req, AdminMessage *response);
void handleSetCannedMessagePluginPart1(const char *from_msg);
void handleSetCannedMessagePluginPart2(const char *from_msg);
void handleSetCannedMessagePluginPart3(const char *from_msg);
void handleSetCannedMessagePluginPart4(const char *from_msg);
protected:
virtual int32_t runOnce() override;
@ -56,11 +66,18 @@ class CannedMessagePlugin :
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() override { return this; }
virtual void drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
virtual AdminMessageHandleResult handleAdminMessageForPlugin(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) override;
void loadProtoForPlugin();
bool saveProtoForPlugin();
void installDefaultCannedMessagePluginConfig();
int currentMessageIndex = -1;
cannedMessagePluginRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
char messageStore[CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE];
char messageStore[CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE+1];
char *messages[CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT];
int messagesCount = 0;
unsigned long lastTouchMillis = 0;

View File

@ -1,22 +1,21 @@
#include "configuration.h"
#include "input/InputBroker.h"
#include "input/RotaryEncoderInterruptImpl1.h"
#include "plugins/AdminPlugin.h"
#include "plugins/CannedMessagePlugin.h"
#include "plugins/ExternalNotificationPlugin.h"
#include "plugins/NodeInfoPlugin.h"
#include "plugins/PositionPlugin.h"
#include "plugins/RemoteHardwarePlugin.h"
#include "plugins/ReplyPlugin.h"
#include "plugins/TextMessagePlugin.h"
#include "plugins/TextMessagePlugin.h"
#include "plugins/RoutingPlugin.h"
#include "plugins/AdminPlugin.h"
#include "plugins/CannedMessagePlugin.h"
#include "plugins/TextMessagePlugin.h"
#ifndef PORTDUINO
#include "plugins/EnvironmentalMeasurement/EnvironmentalMeasurementPlugin.h"
#endif
#ifndef NO_ESP32
#include "plugins/esp32/SerialPlugin.h"
#include "plugins/esp32/RangeTestPlugin.h"
#include "plugins/esp32/SerialPlugin.h"
#include "plugins/esp32/StoreForwardPlugin.h"
#endif
@ -36,8 +35,7 @@ void setupPlugins()
new RemoteHardwarePlugin();
new ReplyPlugin();
rotaryEncoderInterruptImpl1 =
new RotaryEncoderInterruptImpl1();
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
rotaryEncoderInterruptImpl1->init();
cannedMessagePlugin = new CannedMessagePlugin();
#ifndef PORTDUINO

View File

@ -0,0 +1,9 @@
[env:rak4631_5005_eink]
extends = nrf52840_base
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_E-Paper_Board -D RAK_BASE_5005
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_E-Paper_Board>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/ZinggJM/GxEPD2.git
debug_tool = jlink

View File

@ -0,0 +1,43 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
#include "nrf.h"
const uint32_t g_ADigitalPinMap[] =
{
// P0
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// LED1 & LED2
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);
pinMode(PIN_LED2, OUTPUT);
ledOff(PIN_LED2);
}

View File

@ -0,0 +1,232 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_RAK4630_
#define _VARIANT_RAK4630_
#define RAK4630
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
// define USE_LFRC // Board uses RC for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (6)
#define NUM_ANALOG_OUTPUTS (0)
// LEDs
#define PIN_LED1 (35)
#define PIN_LED2 (36)
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
#define LED_GREEN PIN_LED1
#define LED_BLUE PIN_LED2
#define LED_STATE_ON 1 // State when LED is litted
/*
* Buttons
*/
#ifdef RAK_BASE_5005
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
#define BUTTON_NEED_PULLUP
#endif
#define PIN_BUTTON2 12
#define PIN_BUTTON3 24
#define PIN_BUTTON4 25
/*
* Analog pins
*/
#define PIN_A0 (5)
#define PIN_A1 (31)
#define PIN_A2 (28)
#define PIN_A3 (29)
#define PIN_A4 (30)
#define PIN_A5 (31)
#define PIN_A6 (0xff)
#define PIN_A7 (0xff)
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
static const uint8_t A6 = PIN_A6;
static const uint8_t A7 = PIN_A7;
#define ADC_RESOLUTION 14
// Other pins
#define PIN_AREF (2)
#define PIN_NFC1 (9)
#define PIN_NFC2 (10)
static const uint8_t AREF = PIN_AREF;
/*
* Serial interfaces
*/
#define PIN_SERIAL1_RX (15)
#define PIN_SERIAL1_TX (16)
// Connected to Jlink CDC
#define PIN_SERIAL2_RX (8)
#define PIN_SERIAL2_TX (6)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 2
#define PIN_SPI_MISO (45)
#define PIN_SPI_MOSI (44)
#define PIN_SPI_SCK (43)
#define PIN_SPI1_MISO (29) // (0 + 29)
#define PIN_SPI1_MOSI (30) // (0 + 30)
#define PIN_SPI1_SCK (3) // (0 + 3)
static const uint8_t SS = 42;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* eink display pins
*/
#define PIN_EINK_EN (0 + 2) // (0 + 2) Note: this is really just backlight power
#define PIN_EINK_CS (0 + 26)
#define PIN_EINK_BUSY (0 + 4)
#define PIN_EINK_DC (0 + 17)
#define PIN_EINK_RES (-1)
#define PIN_EINK_SCLK (0 + 3)
#define PIN_EINK_MOSI (0 + 30) // also called SDI
// Controls power for the eink display - Board power is enabled either by VBUS from USB or the CPU asserting PWR_ON
// FIXME - I think this is actually just the board power enable - it enables power to the CPU also
//#define PIN_EINK_PWR_ON (-1)
#define HAS_EINK
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (13)
#define PIN_WIRE_SCL (14)
// QSPI Pins
#define PIN_QSPI_SCK 3
#define PIN_QSPI_CS 26
#define PIN_QSPI_IO0 30
#define PIN_QSPI_IO1 29
#define PIN_QSPI_IO2 28
#define PIN_QSPI_IO3 2
// On-board QSPI Flash
#define EXTERNAL_FLASH_DEVICES IS25LP080D
#define EXTERNAL_FLASH_USE_QSPI
/* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
RAK5005-O <-> nRF52840
IO1 <-> P0.17 (Arduino GPIO number 17)
IO2 <-> P1.02 (Arduino GPIO number 34)
IO3 <-> P0.21 (Arduino GPIO number 21)
IO4 <-> P0.04 (Arduino GPIO number 4)
IO5 <-> P0.09 (Arduino GPIO number 9)
IO6 <-> P0.10 (Arduino GPIO number 10)
SW1 <-> P0.01 (Arduino GPIO number 1)
A0 <-> P0.04/AIN2 (Arduino Analog A2
A1 <-> P0.31/AIN7 (Arduino Analog A7
SPI_CS <-> P0.26 (Arduino GPIO number 26)
*/
// RAK4630 LoRa module
#define USE_SX1262
#define SX126X_CS (42)
#define SX126X_DIO1 (47)
#define SX126X_BUSY (46)
#define SX126X_RESET (38)
#define SX126X_TXEN (39)
#define SX126X_RXEN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// RAK1910 GPS module
// If using the wisblock GPS module and pluged into Port A on WisBlock base
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
// IO2 is hooked to GPS RESET = gpio 34, but it can not be used to this because IO2 is ALSO used to control 3V3_S power (1 is on).
// Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34)
#define PIN_GPS_EN (34)
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
#ifdef RAK_BASE_5005
#define GPS_RX_PIN PIN_SERIAL1_RX
#define GPS_TX_PIN PIN_SERIAL1_TX
#endif
// Battery
// The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#define VBAT_MV_PER_LSB (0.73242188F)
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
#define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (1.73)
// Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP //REAL_VBAT_MV_PER_LSB
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif

View File

@ -12,6 +12,6 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/geeksville/GxEPD2.git
https://github.com/meshtastic/GxEPD2
adafruit/Adafruit BusIO
;upload_protocol = fs