diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml new file mode 100644 index 000000000..b8c24ab2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug Report.yml @@ -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 diff --git a/.github/ISSUE_TEMPLATE/bug-report-or-feature-proposal.md b/.github/ISSUE_TEMPLATE/bug-report-or-feature-proposal.md deleted file mode 100644 index 42f3b0d2c..000000000 --- a/.github/ISSUE_TEMPLATE/bug-report-or-feature-proposal.md +++ /dev/null @@ -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. diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 59894f873..fcc33ca23 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6412bcddf..da7dfcf18 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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: | diff --git a/README-docker.md b/README-docker.md new file mode 100644 index 000000000..8c7b8eab5 --- /dev/null +++ b/README-docker.md @@ -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 ` + +> Tip: you can just use the first few characters of the ID in docker commands + diff --git a/README.md b/README.md index e7da82ea3..65aed143b 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/bin/build-all.sh b/bin/build-all.sh index 07b99df90..ee9fdac29 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -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 @@ -108,4 +108,4 @@ echo Generating $ARCHIVEDIR/elfs-$VERSION.zip rm -f $ARCHIVEDIR/elfs-$VERSION.zip zip --junk-paths $ARCHIVEDIR/elfs-$VERSION.zip $OUTDIR/elfs/universal/firmware-*-$VERSION.* -echo BUILT ALL \ No newline at end of file +echo BUILT ALL diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index 1443f6d4f..d4117b4b8 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -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") diff --git a/docker.txt b/docker.txt deleted file mode 100644 index af2c9c0b0..000000000 --- a/docker.txt +++ /dev/null @@ -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 - diff --git a/platformio.ini b/platformio.ini index e3258f9cf..f6e3eedd0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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 @@ -266,4 +267,4 @@ monitor_port = /dev/ttyUSB0 monitor_speed = 115200 # For experimenting with RAM sizes -# board_build.ldscript = linker/nrf52840_s140_sim832.ld \ No newline at end of file +# board_build.ldscript = linker/nrf52840_s140_sim832.ld diff --git a/proto b/proto index 6a66f8b1f..30e147a55 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 6a66f8b1f81815e62279ff66dea908112583e6ab +Subproject commit 30e147a55ce27199cb638a1d82e0b88adc8f5385 diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp index f93453dd4..4c030b60c 100644 --- a/src/graphics/EInkDisplay2.cpp +++ b/src/graphics/EInkDisplay2.cpp @@ -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 *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(*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(*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); diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index 985a7060f..180e1ebfd 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -179,7 +179,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src) if (!pluginFound) DEBUG_MSG("No plugins interested in portnum=%d, src=%s\n", - mp.decoded.portnum, + mp.decoded.portnum, (src == RX_SRC_LOCAL) ? "LOCAL":"REMOTE"); } @@ -226,11 +226,13 @@ std::vector MeshPlugin::GetMeshPluginsWithUIFrames() { std::vector pluginsWithUIFrames; - for (auto i = plugins->begin(); i != plugins->end(); ++i) { - auto &pi = **i; - if (pi.wantUIFrame()) { - DEBUG_MSG("Plugin wants a UI Frame\n"); - pluginsWithUIFrames.push_back(&pi); + if (plugins) { + for (auto i = plugins->begin(); i != plugins->end(); ++i) { + auto &pi = **i; + if (pi.wantUIFrame()) { + DEBUG_MSG("Plugin wants a UI Frame\n"); + pluginsWithUIFrames.push_back(&pi); + } } } return pluginsWithUIFrames; @@ -239,14 +241,42 @@ std::vector MeshPlugin::GetMeshPluginsWithUIFrames() void MeshPlugin::observeUIEvents( Observer *observer) { - std::vector pluginsWithUIFrames; - for (auto i = plugins->begin(); i != plugins->end(); ++i) { - auto &pi = **i; - Observable *observable = - pi.getUIFrameObservable(); - if (observable != NULL) { - DEBUG_MSG("Plugin wants a UI Frame\n"); - observer->observe(observable); + if (plugins) { + for (auto i = plugins->begin(); i != plugins->end(); ++i) { + auto &pi = **i; + Observable *observable = + pi.getUIFrameObservable(); + if (observable != NULL) { + DEBUG_MSG("Plugin wants a UI Frame\n"); + 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; +} diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index 456769dc0..8d59aa508 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -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 GetMeshPluginsWithUIFrames(); static void observeUIEvents(Observer *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 diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 0587b9457..9bdae9011 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -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; diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 86ab874e8..f5937b3fb 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -11,6 +11,7 @@ extern DeviceState devicestate; extern ChannelFile channelFile; extern MyNodeInfo &myNodeInfo; +extern GroupInfo &ourGroupInfo; extern RadioConfig radioConfig; extern User &owner; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 4f434fa1f..ca794036f 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -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 #if FromRadio_size > MAX_TO_FROM_RADIO_SIZE diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 5a4ca381d..684f683f8 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -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 diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h index 77518b60f..c313f9f55 100644 --- a/src/mesh/generated/admin.pb.h +++ b/src/mesh/generated/admin.pb.h @@ -4,7 +4,6 @@ #ifndef PB_ADMIN_PB_H_INCLUDED #define PB_ADMIN_PB_H_INCLUDED #include -#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" */ diff --git a/src/mesh/generated/cannedmessages.pb.c b/src/mesh/generated/cannedmessages.pb.c index 16563446e..e36eff981 100644 --- a/src/mesh/generated/cannedmessages.pb.c +++ b/src/mesh/generated/cannedmessages.pb.c @@ -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) diff --git a/src/mesh/generated/cannedmessages.pb.h b/src/mesh/generated/cannedmessages.pb.h index 0f1b0786e..ec8a42123 100644 --- a/src/mesh/generated/cannedmessages.pb.h +++ b/src/mesh/generated/cannedmessages.pb.h @@ -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" */ diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index a298579bb..d384e7e57 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -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 diff --git a/src/mesh/generated/mesh.pb.c b/src/mesh/generated/mesh.pb.c index 6846dc540..90eca5068 100644 --- a/src/mesh/generated/mesh.pb.c +++ b/src/mesh/generated/mesh.pb.c @@ -27,6 +27,9 @@ PB_BIND(MeshPacket, MeshPacket, 2) PB_BIND(NodeInfo, NodeInfo, AUTO) +PB_BIND(GroupInfo, GroupInfo, AUTO) + + PB_BIND(MyNodeInfo, MyNodeInfo, 2) diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index 8e98195ed..f04b3f426 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -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 diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 26eec9ed6..67b5df03d 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -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, diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index b8850d05c..af24b5184 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -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" */ diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index b64ea2814..4eb6cb7e5 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -390,6 +390,9 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res) res->println("Web server is running.

The content you are looking for can't be found. Please see: FAQ.

admin"); + + 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..."); } } diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 1101ad1cd..208bd6c25 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -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; diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp index 3886cb232..2f1893a87 100644 --- a/src/plugins/AdminPlugin.cpp +++ b/src/plugins/AdminPlugin.cpp @@ -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: - // 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); + 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) diff --git a/src/plugins/CannedMessagePlugin.cpp b/src/plugins/CannedMessagePlugin.cpp index b209187ad..a6b9a23f4 100644 --- a/src/plugins/CannedMessagePlugin.cpp +++ b/src/plugins/CannedMessagePlugin.cpp @@ -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,28 +12,40 @@ // 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); } - this->inputObserver.observe(inputBroker); } } /** * @brief Items in array this->messages will be set to be pointing on the right * starting points of the string this->messageStore - * + * * @return int Returns the number of messages found. */ int CannedMessagePlugin::splitConfiguredMessages() @@ -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 = @@ -51,13 +75,14 @@ int CannedMessagePlugin::splitConfiguredMessages() while (i < upTo) { - if (this->messageStore[i] == '|') + if (this->messageStore[i] == '|') { // Message ending found, replace it with string-end character. this->messageStore[i] = '\0'; 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(); + } +} diff --git a/src/plugins/CannedMessagePlugin.h b/src/plugins/CannedMessagePlugin.h index 1f7dcf42e..2cb6e0730 100644 --- a/src/plugins/CannedMessagePlugin.h +++ b/src/plugins/CannedMessagePlugin.h @@ -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* 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; diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 429a15bb6..c979ce9da 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -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 @@ -30,14 +29,13 @@ void setupPlugins() nodeInfoPlugin = new NodeInfoPlugin(); positionPlugin = new PositionPlugin(); textMessagePlugin = new TextMessagePlugin(); - + // Note: if the rest of meshtastic doesn't need to explicitly use your plugin, you do not need to assign the instance // to a global variable. new RemoteHardwarePlugin(); new ReplyPlugin(); - rotaryEncoderInterruptImpl1 = - new RotaryEncoderInterruptImpl1(); + rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); rotaryEncoderInterruptImpl1->init(); cannedMessagePlugin = new CannedMessagePlugin(); #ifndef PORTDUINO diff --git a/variants/WisCore_RAK4631_E-Paper_Board/platformio.ini b/variants/WisCore_RAK4631_E-Paper_Board/platformio.ini new file mode 100644 index 000000000..19855006b --- /dev/null +++ b/variants/WisCore_RAK4631_E-Paper_Board/platformio.ini @@ -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 diff --git a/variants/WisCore_RAK4631_E-Paper_Board/variant.cpp b/variants/WisCore_RAK4631_E-Paper_Board/variant.cpp new file mode 100644 index 000000000..5b9288319 --- /dev/null +++ b/variants/WisCore_RAK4631_E-Paper_Board/variant.cpp @@ -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); +} diff --git a/variants/WisCore_RAK4631_E-Paper_Board/variant.h b/variants/WisCore_RAK4631_E-Paper_Board/variant.h new file mode 100644 index 000000000..4b5d21add --- /dev/null +++ b/variants/WisCore_RAK4631_E-Paper_Board/variant.h @@ -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 diff --git a/variants/t-echo/platformio.ini b/variants/t-echo/platformio.ini index 495eaf91a..9714b0268 100644 --- a/variants/t-echo/platformio.ini +++ b/variants/t-echo/platformio.ini @@ -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 \ No newline at end of file +;upload_protocol = fs