diff --git a/docs/cli_commands.md b/docs/cli_commands.md index f4b1eb91b..4b5c4a484 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -1153,24 +1153,28 @@ Repeater only. Lets a repeater decrypt channels it holds the key for, inspect th --- -#### Block a keyword +#### Block or unblock a keyword **Usage:** - `filter block ` +- `filter unblock ` **Parameters:** - `keyword`: Text to match (case-insensitive substring) against the whole message. Max 23 characters. -**Note:** Matches anywhere in the message — both the body and the sender name — so a blocked word can't be hidden in a self-declared sender name. +**Note:** Matches anywhere in the message — both the body and the sender name — so a blocked word can't be hidden in a self-declared sender name. `filter unblock ` removes a single keyword; give it the exact term as stored (`filter list` shows them under `K:`). --- -#### Block a sender name +#### Block or unblock a sender name **Usage:** - `filter sender ` +- `filter unsender ` **Parameters:** - `name`: Text to match (case-insensitive substring) against the sender's display name. Max 23 characters. +**Note:** `filter unsender ` removes a single sender; give it the exact term as stored (`filter list` shows them under `S:`). + --- #### Clear or reset filter terms diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 8d4d80468..2f12491dd 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -722,6 +722,18 @@ bool MyMesh::removeFilterChannel(const char *psk) { return false; // no channel with that key } +// Remove an exact term from a keyword/sender list (shift the rest down). +static bool removeFilterTerm(char terms[][FILTER_TERM_LEN], uint8_t &count, const char *val) { + for (int i = 0; i < count; i++) { + if (strcmp(terms[i], val) == 0) { + for (int j = i; j < count - 1; j++) memcpy(terms[j], terms[j + 1], FILTER_TERM_LEN); + count--; + return true; + } + } + return false; +} + int MyMesh::searchChannelsByHash(const uint8_t *hash, mesh::GroupChannel channels[], int max_matches) { int n = 0; for (int i = 0; i < num_filter_channels && n < max_matches; i++) { @@ -931,6 +943,28 @@ void MyMesh::handleFilterCommand(char *command, char *reply) { sprintf(reply, "OK - %d sender(s)", num_block_senders); return; } + if (memcmp(arg, "unblock ", 8) == 0) { + char *val = arg + 8; + while (*val == ' ') val++; + if (removeFilterTerm(block_keywords, num_block_keywords, val)) { + saveChannelFilter(); + sprintf(reply, "OK - %d keyword(s)", num_block_keywords); + } else { + strcpy(reply, "Err - keyword not found"); + } + return; + } + if (memcmp(arg, "unsender ", 9) == 0) { + char *val = arg + 9; + while (*val == ' ') val++; + if (removeFilterTerm(block_senders, num_block_senders, val)) { + saveChannelFilter(); + sprintf(reply, "OK - %d sender(s)", num_block_senders); + } else { + strcpy(reply, "Err - sender not found"); + } + return; + } if (strcmp(arg, "clear") == 0) { num_block_keywords = 0; num_block_senders = 0; @@ -944,7 +978,7 @@ void MyMesh::handleFilterCommand(char *command, char *reply) { strcpy(reply, "OK - filter reset"); return; } - strcpy(reply, "Err - usage: filter [list|stats [reset]|channel <#name|b64|hex|public|remove |clear>|block |sender |clear|reset]"); + strcpy(reply, "Err - usage: filter [list|stats [reset]|channel <#name|b64|hex|public|remove |clear>|block/unblock |sender/unsender |clear|reset]"); } #endif // WITH_CHANNEL_FILTER