firmware/src/plugins/CannedMessagePlugin.cpp

287 lines
8.2 KiB
C++
Raw Normal View History

2022-01-04 18:42:28 +00:00
#include "configuration.h"
#include "CannedMessagePlugin.h"
#include "MeshService.h"
2022-01-13 07:08:16 +00:00
// TODO: reuse defined from Screen.cpp
#define FONT_SMALL ArialMT_Plain_10
#define FONT_MEDIUM ArialMT_Plain_16
#define FONT_LARGE ArialMT_Plain_24
2022-01-13 11:51:36 +00:00
// Remove Canned message screen if no action is taken for some milliseconds
#define INACTIVATE_AFTER_MS 20000
2022-01-13 07:08:16 +00:00
2022-01-04 18:42:28 +00:00
CannedMessagePlugin *cannedMessagePlugin;
2022-01-11 15:02:55 +00:00
CannedMessagePlugin::CannedMessagePlugin()
2022-01-09 09:08:31 +00:00
: SinglePortPlugin("canned", PortNum_TEXT_MESSAGE_APP),
concurrency::OSThread("CannedMessagePlugin")
2022-01-04 18:42:28 +00:00
{
2022-01-12 08:26:42 +00:00
if (radioConfig.preferences.canned_message_plugin_enabled)
{
if(this->splitConfiguredMessages() <= 0)
{
radioConfig.preferences.canned_message_plugin_enabled = false;
DEBUG_MSG("CannedMessagePlugin: No messages are configured. Plugin is disabled\n");
return;
}
2022-01-11 15:02:55 +00:00
this->inputObserver.observe(inputBroker);
}
2022-01-04 18:42:28 +00:00
}
2022-01-12 08:26:42 +00:00
/**
* @brief Items in array this->messages will be set to be pointing on the right
* starting points of the string this->messageStore
2022-01-12 08:26:42 +00:00
*
* @return int Returns the number of messages found.
*/
int CannedMessagePlugin::splitConfiguredMessages()
{
int messageIndex = 0;
int i = 0;
strncpy(
this->messageStore,
radioConfig.preferences.canned_message_plugin_messages,
CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE);
2022-01-13 11:51:36 +00:00
this->messages[messageIndex++] =
this->messageStore;
2022-01-13 11:51:36 +00:00
int upTo =
strlen(this->messageStore) - 1;
2022-01-12 08:26:42 +00:00
while (i < upTo)
{
if (this->messageStore[i] == '|')
2022-01-12 08:26:42 +00:00
{
// Message ending found, replace it with string-end character.
this->messageStore[i] = '\0';
2022-01-13 11:51:36 +00:00
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
2022-01-12 08:26:42 +00:00
if (messageIndex >= CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT)
{
this->messagesCount = messageIndex;
return this->messagesCount;
}
// Next message starts after pipe (|) just found.
this->messages[messageIndex++] =
(this->messageStore + i + 1);
2022-01-12 08:26:42 +00:00
}
i += 1;
}
if (strlen(this->messages[messageIndex-1]) > 0)
{
2022-01-13 11:51:36 +00:00
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
2022-01-12 08:26:42 +00:00
this->messagesCount = messageIndex;
}
else
{
this->messagesCount = messageIndex-1;
}
return this->messagesCount;
}
2022-01-09 09:08:31 +00:00
int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
2022-01-04 18:42:28 +00:00
{
2022-01-12 08:26:42 +00:00
if (
2022-01-16 22:18:40 +00:00
(strlen(radioConfig.preferences.canned_message_plugin_allow_input_source) > 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, event->source) != 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, "_any") != 0))
2022-01-11 15:02:55 +00:00
{
2022-01-13 13:06:10 +00:00
// Event source is not accepted.
2022-01-11 15:02:55 +00:00
return 0;
}
2022-01-12 08:26:42 +00:00
2022-01-09 09:08:31 +00:00
bool validEvent = false;
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_UP))
2022-01-09 09:08:31 +00:00
{
2022-01-09 20:14:23 +00:00
DEBUG_MSG("Canned message event UP\n");
2022-01-09 09:08:31 +00:00
this->action = CANNED_MESSAGE_ACTION_UP;
validEvent = true;
}
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_DOWN))
2022-01-09 09:08:31 +00:00
{
2022-01-09 20:14:23 +00:00
DEBUG_MSG("Canned message event DOWN\n");
2022-01-09 09:08:31 +00:00
this->action = CANNED_MESSAGE_ACTION_DOWN;
validEvent = true;
}
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_SELECT))
2022-01-09 09:08:31 +00:00
{
2022-01-09 20:14:23 +00:00
DEBUG_MSG("Canned message event Select\n");
2022-01-09 09:08:31 +00:00
this->action = CANNED_MESSAGE_ACTION_SELECT;
validEvent = true;
}
2022-01-04 18:42:28 +00:00
2022-01-09 09:08:31 +00:00
if (validEvent)
{
// Let runOnce to be called immediately.
2022-01-13 11:51:36 +00:00
setIntervalFromNow(0);
2022-01-09 09:08:31 +00:00
}
2022-01-04 18:42:28 +00:00
2022-01-09 09:08:31 +00:00
return 0;
2022-01-04 18:42:28 +00:00
}
2022-01-04 18:43:06 +00:00
void CannedMessagePlugin::sendText(NodeNum dest,
const char* message,
bool wantReplies)
2022-01-04 18:42:28 +00:00
{
MeshPacket *p = allocDataPacket();
p->to = dest;
2022-01-13 11:51:36 +00:00
p->want_ack = true;
2022-01-04 21:02:16 +00:00
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
2022-01-12 08:26:42 +00:00
if (radioConfig.preferences.canned_message_plugin_send_bell)
{
p->decoded.payload.bytes[p->decoded.payload.size-1] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character
p->decoded.payload.size++;
}
2022-01-04 18:42:28 +00:00
// 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);
service.sendToMesh(p);
}
int32_t CannedMessagePlugin::runOnce()
{
2022-01-12 08:26:42 +00:00
if (!radioConfig.preferences.canned_message_plugin_enabled)
{
return 30000; // TODO: should return MAX_VAL
}
2022-01-09 20:14:23 +00:00
DEBUG_MSG("Check status\n");
2022-01-13 08:19:36 +00:00
UIFrameEvent e = {false, true};
2022-01-04 21:02:16 +00:00
if (this->sendingState == SENDING_STATE_ACTIVE)
{
// TODO: might have some feedback of sendig state
this->sendingState = SENDING_STATE_NONE;
2022-01-13 11:51:36 +00:00
e.frameChanged = true;
2022-01-13 08:19:36 +00:00
this->notifyObservers(&e);
2022-01-04 21:02:16 +00:00
}
2022-01-09 09:08:31 +00:00
else if ((this->action != CANNED_MESSAGE_ACTION_NONE)
2022-01-04 18:43:06 +00:00
&& (this->currentMessageIndex == -1))
2022-01-04 18:42:28 +00:00
{
2022-01-04 18:43:06 +00:00
this->currentMessageIndex = 0;
2022-01-05 14:52:08 +00:00
DEBUG_MSG("First touch.\n");
2022-01-13 08:19:36 +00:00
e.frameChanged = true;
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
else if (this->action == CANNED_MESSAGE_ACTION_SELECT)
2022-01-04 18:42:28 +00:00
{
2022-01-04 18:43:06 +00:00
sendText(
NODENUM_BROADCAST,
2022-01-12 08:26:42 +00:00
this->messages[this->currentMessageIndex],
2022-01-04 18:43:06 +00:00
true);
2022-01-04 21:02:16 +00:00
this->sendingState = SENDING_STATE_ACTIVE;
this->currentMessageIndex = -1;
2022-01-13 08:19:36 +00:00
this->notifyObservers(&e);
2022-01-04 21:02:16 +00:00
return 2000;
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
else if (this->action == CANNED_MESSAGE_ACTION_UP)
2022-01-04 18:42:28 +00:00
{
this->currentMessageIndex = getPrevIndex();
2022-01-12 08:26:42 +00:00
DEBUG_MSG("MOVE UP");
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
else if (this->action == CANNED_MESSAGE_ACTION_DOWN)
2022-01-04 18:42:28 +00:00
{
this->currentMessageIndex = this->getNextIndex();
2022-01-12 08:26:42 +00:00
DEBUG_MSG("MOVE DOWN");
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
if (this->action != CANNED_MESSAGE_ACTION_NONE)
2022-01-04 18:43:06 +00:00
{
2022-01-13 11:51:36 +00:00
this->lastTouchMillis = millis();
2022-01-09 09:08:31 +00:00
this->action = CANNED_MESSAGE_ACTION_NONE;
2022-01-13 08:19:36 +00:00
this->notifyObservers(&e);
2022-01-13 11:51:36 +00:00
return INACTIVATE_AFTER_MS;
}
if ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)
{
// Reset plugin
DEBUG_MSG("Reset due the lack of activity.\n");
e.frameChanged = true;
this->currentMessageIndex = -1;
this->sendingState = SENDING_STATE_NONE;
this->notifyObservers(&e);
2022-01-04 18:43:06 +00:00
}
2022-01-12 08:26:42 +00:00
return 30000; // TODO: should return MAX_VAL
2022-01-04 18:42:28 +00:00
}
const char* CannedMessagePlugin::getCurrentMessage()
2022-01-04 18:42:28 +00:00
{
2022-01-12 08:26:42 +00:00
return this->messages[this->currentMessageIndex];
2022-01-09 09:08:31 +00:00
}
const char* CannedMessagePlugin::getPrevMessage()
2022-01-09 09:08:31 +00:00
{
2022-01-12 08:26:42 +00:00
return this->messages[this->getPrevIndex()];
2022-01-09 09:08:31 +00:00
}
const char* CannedMessagePlugin::getNextMessage()
2022-01-09 09:08:31 +00:00
{
2022-01-12 08:26:42 +00:00
return this->messages[this->getNextIndex()];
2022-01-09 09:08:31 +00:00
}
bool CannedMessagePlugin::shouldDraw()
{
2022-01-13 07:08:16 +00:00
if (!radioConfig.preferences.canned_message_plugin_enabled)
{
return false;
}
2022-01-09 09:08:31 +00:00
return (currentMessageIndex != -1) || (this->sendingState != SENDING_STATE_NONE);
}
cannedMessagePluginSendigState CannedMessagePlugin::getSendingState()
{
return this->sendingState;
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
int CannedMessagePlugin::getNextIndex()
2022-01-04 18:42:28 +00:00
{
2022-01-12 08:26:42 +00:00
if (this->currentMessageIndex >= (this->messagesCount -1))
2022-01-04 18:42:28 +00:00
{
2022-01-09 09:08:31 +00:00
return 0;
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
else
2022-01-04 18:42:28 +00:00
{
2022-01-09 09:08:31 +00:00
return this->currentMessageIndex + 1;
2022-01-04 18:42:28 +00:00
}
}
2022-01-09 09:08:31 +00:00
int CannedMessagePlugin::getPrevIndex()
2022-01-04 18:42:28 +00:00
{
2022-01-09 09:08:31 +00:00
if (this->currentMessageIndex <= 0)
2022-01-04 18:42:28 +00:00
{
2022-01-12 08:26:42 +00:00
return this->messagesCount - 1;
2022-01-04 18:42:28 +00:00
}
2022-01-09 09:08:31 +00:00
else
2022-01-04 18:42:28 +00:00
{
2022-01-09 09:08:31 +00:00
return this->currentMessageIndex - 1;
2022-01-04 18:42:28 +00:00
}
2022-01-13 07:08:16 +00:00
}
void CannedMessagePlugin::drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
if (cannedMessagePlugin->getSendingState() == SENDING_STATE_NONE)
{
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y, cannedMessagePlugin->getPrevMessage());
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y + 8, cannedMessagePlugin->getCurrentMessage());
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y + 24, cannedMessagePlugin->getNextMessage());
}
else
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(display->getWidth()/2 + x, 0 + y + 12, "Sending...");
}
}