Merge pull request #1232 from prampec/extend_canned_message_length

Canned message - Extend messages length
This commit is contained in:
Jm Casler 2022-02-21 22:10:40 -08:00 committed by GitHub
commit ef2bc2b9fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 431 additions and 190 deletions

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 =
@ -250,3 +252,31 @@ void MeshPlugin::observeUIEvents(
}
}
}
}
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

@ -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

@ -34,11 +34,6 @@ typedef struct _DeviceState {
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;
@ -47,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, GroupInfo_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, GroupInfo_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) */
@ -63,11 +58,6 @@ extern "C" {
#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) \
@ -79,12 +69,7 @@ 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
@ -108,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 11174
#define DeviceState_size 10162
#define ChannelFile_size 832
#ifdef __cplusplus

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

@ -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,23 +12,35 @@
// 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);
}
}
}
/**
* @brief Items in array this->messages will be set to be pointing on the right
@ -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;