Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkorpionm <85568270+Skorpionm@users.noreply.github.com>2021-12-08 16:42:01 +0300
committerGitHub <noreply@github.com>2021-12-08 16:42:01 +0300
commitf0aed7e58331557fe41b7617b8dff49b63645f40 (patch)
treed9f0365ea6846a3c9909f8de4c8ba66ca967b7b3 /applications/subghz
parent7170864fe41f783ea84892f2e326ab120e2ee446 (diff)
SubGhz: add GFSK modulation, refactoring subghz_chat (#866)
* SubGhz: add GFSK modulation, refactoring subghz_chat * SubGhz: off echo subghz_chat * SubGhz: subghz_chat add sending and receiving formatted text, translation of the chat to events * SubGhz: add UTF support in subghz_chat_worker_alloc Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/subghz')
-rw-r--r--applications/subghz/helpers/subghz_chat.c141
-rw-r--r--applications/subghz/helpers/subghz_chat.h29
-rw-r--r--applications/subghz/subghz_cli.c157
3 files changed, 279 insertions, 48 deletions
diff --git a/applications/subghz/helpers/subghz_chat.c b/applications/subghz/helpers/subghz_chat.c
new file mode 100644
index 00000000..15e08dde
--- /dev/null
+++ b/applications/subghz/helpers/subghz_chat.c
@@ -0,0 +1,141 @@
+#include "subghz_chat.h"
+#include <lib/subghz/subghz_tx_rx_worker.h>
+
+#define TAG "SubGhzChat"
+#define SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES 500
+
+struct SubGhzChatWorker {
+ FuriThread* thread;
+ SubGhzTxRxWorker* subghz_txrx;
+
+ volatile bool worker_running;
+ volatile bool worker_stoping;
+ osMessageQueueId_t event_queue;
+ uint32_t last_time_rx_data;
+};
+
+/** Worker thread
+ *
+ * @param context
+ * @return exit code
+ */
+static int32_t subghz_chat_worker_thread(void* context) {
+ SubGhzChatWorker* instance = context;
+ FURI_LOG_I(TAG, "Worker start");
+ char c;
+ SubghzChatEvent event;
+ event.event = SubghzChatEventUserEntrance;
+ osMessageQueuePut(instance->event_queue, &event, 0, 0);
+ while(instance->worker_running) {
+ if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, osWaitForever) == 1) {
+ event.event = SubghzChatEventInputData;
+ event.c = c;
+ osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever);
+ }
+ }
+
+ FURI_LOG_I(TAG, "Worker stop");
+ return 0;
+}
+
+static void subghz_chat_worker_update_rx_event_chat(void* context) {
+ furi_assert(context);
+ SubGhzChatWorker* instance = context;
+ SubghzChatEvent event;
+ if((millis() - instance->last_time_rx_data) > SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES) {
+ event.event = SubghzChatEventNewMessage;
+ osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever);
+ }
+ instance->last_time_rx_data = millis();
+ event.event = SubghzChatEventRXData;
+ osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever);
+}
+
+SubGhzChatWorker* subghz_chat_worker_alloc() {
+ SubGhzChatWorker* instance = furi_alloc(sizeof(SubGhzChatWorker));
+
+ instance->thread = furi_thread_alloc();
+ furi_thread_set_name(instance->thread, "SubghzChat");
+ furi_thread_set_stack_size(instance->thread, 2048);
+ furi_thread_set_context(instance->thread, instance);
+ furi_thread_set_callback(instance->thread, subghz_chat_worker_thread);
+ instance->subghz_txrx = subghz_tx_rx_worker_alloc();
+ instance->event_queue = osMessageQueueNew(80, sizeof(SubghzChatEvent), NULL);
+ return instance;
+}
+
+void subghz_chat_worker_free(SubGhzChatWorker* instance) {
+ furi_assert(instance);
+ furi_assert(!instance->worker_running);
+ osMessageQueueDelete(instance->event_queue);
+ subghz_tx_rx_worker_free(instance->subghz_txrx);
+ furi_thread_free(instance->thread);
+
+ free(instance);
+}
+
+bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency) {
+ furi_assert(instance);
+ furi_assert(!instance->worker_running);
+ bool res = false;
+
+ if(subghz_tx_rx_worker_start(instance->subghz_txrx, frequency)) {
+ osMessageQueueReset(instance->event_queue);
+ subghz_tx_rx_worker_set_callback_have_read(
+ instance->subghz_txrx, subghz_chat_worker_update_rx_event_chat, instance);
+
+ instance->worker_running = true;
+ instance->last_time_rx_data = 0;
+
+ res = furi_thread_start(instance->thread);
+ }
+ return res;
+}
+
+void subghz_chat_worker_stop(SubGhzChatWorker* instance) {
+ furi_assert(instance);
+ furi_assert(instance->worker_running);
+ if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) {
+ subghz_tx_rx_worker_stop(instance->subghz_txrx);
+ }
+
+ instance->worker_running = false;
+
+ furi_thread_join(instance->thread);
+}
+
+bool subghz_chat_worker_is_running(SubGhzChatWorker* instance) {
+ furi_assert(instance);
+ return instance->worker_running;
+}
+
+SubghzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance) {
+ furi_assert(instance);
+ SubghzChatEvent event;
+ if(osMessageQueueGet(instance->event_queue, &event, NULL, osWaitForever) == osOK) {
+ return event;
+ } else {
+ event.event = SubghzChatEventNoEvent;
+ return event;
+ }
+}
+
+void subghz_chat_worker_put_event_chat(SubGhzChatWorker* instance, SubghzChatEvent* event) {
+ furi_assert(instance);
+ osMessageQueuePut(instance->event_queue, event, 0, osWaitForever);
+}
+
+size_t subghz_chat_worker_available(SubGhzChatWorker* instance) {
+ furi_assert(instance);
+ return subghz_tx_rx_worker_available(instance->subghz_txrx);
+}
+
+size_t subghz_chat_worker_read(SubGhzChatWorker* instance, uint8_t* data, size_t size) {
+ furi_assert(instance);
+ return subghz_tx_rx_worker_read(instance->subghz_txrx, data, size);
+}
+
+bool subghz_chat_worker_write(SubGhzChatWorker* instance, uint8_t* data, size_t size) {
+ furi_assert(instance);
+ return subghz_tx_rx_worker_write(instance->subghz_txrx, data, size);
+} \ No newline at end of file
diff --git a/applications/subghz/helpers/subghz_chat.h b/applications/subghz/helpers/subghz_chat.h
new file mode 100644
index 00000000..89f82ef3
--- /dev/null
+++ b/applications/subghz/helpers/subghz_chat.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "../subghz_i.h"
+
+typedef struct SubGhzChatWorker SubGhzChatWorker;
+
+typedef enum {
+ SubghzChatEventNoEvent,
+ SubghzChatEventUserEntrance,
+ SubghzChatEventUserExit,
+ SubghzChatEventInputData,
+ SubghzChatEventRXData,
+ SubghzChatEventNewMessage,
+} SubghzChatEventType;
+
+typedef struct {
+ SubghzChatEventType event;
+ char c;
+} SubghzChatEvent;
+
+SubGhzChatWorker* subghz_chat_worker_alloc();
+void subghz_chat_worker_free(SubGhzChatWorker* instance);
+bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency);
+void subghz_chat_worker_stop(SubGhzChatWorker* instance);
+bool subghz_chat_worker_is_running(SubGhzChatWorker* instance);
+SubghzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance);
+void subghz_chat_worker_put_event_chat(SubGhzChatWorker* instance, SubghzChatEvent* event);
+size_t subghz_chat_worker_available(SubGhzChatWorker* instance);
+size_t subghz_chat_worker_read(SubGhzChatWorker* instance, uint8_t* data, size_t size);
+bool subghz_chat_worker_write(SubGhzChatWorker* instance, uint8_t* data, size_t size);
diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c
index 2578fb26..2f9d698e 100644
--- a/applications/subghz/subghz_cli.c
+++ b/applications/subghz/subghz_cli.c
@@ -9,7 +9,8 @@
#include <lib/subghz/subghz_keystore.h>
#include <lib/subghz/protocols/subghz_protocol_common.h>
#include <lib/subghz/protocols/subghz_protocol_princeton.h>
-#include <lib/subghz/subghz_tx_rx_worker.h>
+
+#include "helpers/subghz_chat.h"
#include <notification/notification-messages.h>
@@ -377,23 +378,34 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) {
return;
}
- SubGhzTxRxWorker* subghz_txrx = subghz_tx_rx_worker_alloc();
- subghz_tx_rx_worker_start(subghz_txrx, frequency);
+ SubGhzChatWorker* subghz_chat = subghz_chat_worker_alloc();
+ if(!subghz_chat_worker_start(subghz_chat, frequency)) {
+ printf("Startup error SubGhzChatWorker\r\n");
+
+ if(subghz_chat_worker_is_running(subghz_chat)) {
+ subghz_chat_worker_stop(subghz_chat);
+ subghz_chat_worker_free(subghz_chat);
+ }
+ return;
+ }
printf("Receiving at frequency %lu Hz\r\n", frequency);
printf("Press CTRL+C to stop\r\n");
furi_hal_power_suppress_charge_enter();
+
size_t message_max_len = 64;
uint8_t message[64] = {0};
string_t input;
string_init(input);
string_t name;
string_init(name);
+ string_t output;
+ string_init(output);
string_t sysmsg;
string_init(sysmsg);
- char c;
bool exit = false;
+ SubghzChatEvent chat_event;
NotificationApp* notification = furi_record_open("notification");
@@ -402,71 +414,120 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) {
printf("%s", string_get_cstr(input));
fflush(stdout);
- string_printf(sysmsg, "\033[0;34m%s joined chat.\033[0m", furi_hal_version_get_name_ptr());
- subghz_tx_rx_worker_write(
- subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg)));
-
while(!exit) {
- if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) {
- if(c == CliSymbolAsciiETX) {
+ chat_event = subghz_chat_worker_get_event_chat(subghz_chat);
+ switch(chat_event.event) {
+ case SubghzChatEventInputData:
+ if(chat_event.c == CliSymbolAsciiETX) {
printf("\r\n");
- exit = true;
+ chat_event.event = SubghzChatEventUserExit;
+ subghz_chat_worker_put_event_chat(subghz_chat, &chat_event);
break;
- } else if((c >= 0x20 && c < 0x7F) || (c >= 0x80 && c < 0xF0)) {
- putc(c, stdout);
- fflush(stdout);
- string_push_back(input, c);
- } else if((c == CliSymbolAsciiBackspace) || (c == CliSymbolAsciiDel)) {
- size_t len = string_size(input);
- if(len > string_size(name)) {
+ } else if(
+ (chat_event.c == CliSymbolAsciiBackspace) || (chat_event.c == CliSymbolAsciiDel)) {
+ size_t len = string_length_u(input);
+ if(len > string_length_u(name)) {
printf("%s", "\e[D\e[1P");
fflush(stdout);
- string_set_strn(input, string_get_cstr(input), len - 1);
+ //delete 1 char UTF
+ const char* str = string_get_cstr(input);
+ size_t size = 0;
+ m_str1ng_utf8_state_e s = M_STRING_UTF8_STARTING;
+ string_unicode_t u = 0;
+ string_reset(sysmsg);
+ while(*str) {
+ m_str1ng_utf8_decode(*str, &s, &u);
+ if((s == M_STRING_UTF8_ERROR) || s == M_STRING_UTF8_STARTING) {
+ string_push_u(sysmsg, u);
+ if(++size >= len - 1) break;
+ s = M_STRING_UTF8_STARTING;
+ }
+ str++;
+ }
+ string_set(input, sysmsg);
}
- } else if(c == CliSymbolAsciiCR) {
+ } else if(chat_event.c == CliSymbolAsciiCR) {
printf("\r\n");
- subghz_tx_rx_worker_write(
- subghz_txrx, (uint8_t*)string_get_cstr(input), strlen(string_get_cstr(input)));
+ string_push_back(input, '\r');
+ string_push_back(input, '\n');
+ while(!subghz_chat_worker_write(
+ subghz_chat,
+ (uint8_t*)string_get_cstr(input),
+ strlen(string_get_cstr(input)))) {
+ delay(10);
+ }
+
string_printf(input, "%s", string_get_cstr(name));
printf("%s", string_get_cstr(input));
fflush(stdout);
+ } else if(chat_event.c == CliSymbolAsciiLF) {
+ //cut out the symbol \n
+ } else {
+ putc(chat_event.c, stdout);
+ fflush(stdout);
+ string_push_back(input, chat_event.c);
+ break;
+ case SubghzChatEventRXData:
+ do {
+ memset(message, 0x00, message_max_len);
+ size_t len = subghz_chat_worker_read(subghz_chat, message, message_max_len);
+ for(size_t i = 0; i < len; i++) {
+ string_push_back(output, message[i]);
+ if(message[i] == '\n') {
+ printf("\r");
+ for(uint8_t i = 0; i < 80; i++) {
+ printf(" ");
+ }
+ printf("\r %s", string_get_cstr(output));
+ printf("%s", string_get_cstr(input));
+ fflush(stdout);
+ string_reset(output);
+ }
+ }
+ } while(subghz_chat_worker_available(subghz_chat));
+ break;
+ case SubghzChatEventNewMessage:
+ notification_message(notification, &sequence_single_vibro);
+ break;
+ case SubghzChatEventUserEntrance:
+ string_printf(
+ sysmsg,
+ "\033[0;34m%s joined chat.\033[0m\r\n",
+ furi_hal_version_get_name_ptr());
+ subghz_chat_worker_write(
+ subghz_chat,
+ (uint8_t*)string_get_cstr(sysmsg),
+ strlen(string_get_cstr(sysmsg)));
+ break;
+ case SubghzChatEventUserExit:
+ string_printf(
+ sysmsg, "\033[0;31m%s left chat.\033[0m\r\n", furi_hal_version_get_name_ptr());
+ subghz_chat_worker_write(
+ subghz_chat,
+ (uint8_t*)string_get_cstr(sysmsg),
+ strlen(string_get_cstr(sysmsg)));
+ delay(10);
+ exit = true;
+ break;
+ default:
+ FURI_LOG_W("SubGhzChat", "Error event");
+ break;
}
}
-
- if(subghz_tx_rx_worker_available(subghz_txrx)) {
- memset(message, 0x00, message_max_len);
- subghz_tx_rx_worker_read(subghz_txrx, message, message_max_len);
- printf("\r");
- for(uint8_t i = 0; i < 80; i++) {
- printf(" ");
- }
-
- printf("\r %s\r\n", message);
-
- printf("%s", string_get_cstr(input));
- fflush(stdout);
-
- notification_message(notification, &sequence_single_vibro);
- }
- osDelay(1);
}
- string_printf(sysmsg, "\033[0;31m%s left chat.\033[0m", furi_hal_version_get_name_ptr());
- subghz_tx_rx_worker_write(
- subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg)));
- osDelay(10);
-
- printf("\r\nExit chat\r\n");
string_clear(input);
string_clear(name);
+ string_clear(output);
string_clear(sysmsg);
furi_hal_power_suppress_charge_exit();
furi_record_close("notification");
- if(subghz_tx_rx_worker_is_running(subghz_txrx)) {
- subghz_tx_rx_worker_stop(subghz_txrx);
- subghz_tx_rx_worker_free(subghz_txrx);
+ if(subghz_chat_worker_is_running(subghz_chat)) {
+ subghz_chat_worker_stop(subghz_chat);
+ subghz_chat_worker_free(subghz_chat);
}
+ printf("\r\nExit chat\r\n");
}
static void subghz_cli_command(Cli* cli, string_t args, void* context) {