Просмотр исходного кода

Add chat entry and leave messages

twisted_pear 2 лет назад
Родитель
Сommit
c7d2249ad0
1 измененных файлов с 71 добавлено и 36 удалено
  1. 71 36
      esubghz_chat.c

+ 71 - 36
esubghz_chat.c

@@ -32,6 +32,7 @@
 #define TICK_INTERVAL 50
 #define MESSAGE_COMPLETION_TIMEOUT 500
 #define TIMEOUT_BETWEEN_MESSAGES 500
+#define CHAT_LEAVE_DELAY 10
 
 #define KBD_UNLOCK_CNT 3
 #define KBD_UNLOCK_TIMEOUT 1000
@@ -173,6 +174,44 @@ static void post_rx(ESubGhzChatState *state, size_t rx_size)
 	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
 }
 
+/* Reads the message from msg_input, encrypts it if necessary and then
+ * transmits it. */
+static void tx_msg_input(ESubGhzChatState *state)
+{
+	/* encrypt message if necessary */
+	size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
+	size_t tx_size = msg_len;
+	if (state->encrypted) {
+		tx_size += IV_BYTES + TAG_BYTES;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+
+		furi_hal_random_fill_buf(state->tx_buffer, IV_BYTES);
+		gcm_crypt_and_tag(&(state->gcm_ctx), ENCRYPT,
+				state->tx_buffer, IV_BYTES,
+				NULL, 0,
+				(unsigned char *)
+				furi_string_get_cstr(state->msg_input),
+				state->tx_buffer + IV_BYTES,
+				msg_len,
+				state->tx_buffer + IV_BYTES + msg_len,
+				TAG_BYTES);
+	} else {
+		tx_size += 2;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+		memcpy(state->tx_buffer,
+				furi_string_get_cstr(state->msg_input),
+				msg_len);
+
+		/* append \r\n for compat with Sub-GHz CLI chat */
+		state->tx_buffer[msg_len] = '\r';
+		state->tx_buffer[msg_len + 1] = '\n';
+	}
+
+	/* transmit */
+	subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer,
+			tx_size);
+}
+
 /* Sends FreqEntered event to scene manager and displays the frequency in the
  * text box. */
 static void freq_input_cb(void *context)
@@ -225,7 +264,8 @@ static bool freq_input_validator(const char *text, FuriString *error,
 
 /* Sends PassEntered event to scene manager and displays whether or not
  * encryption has been enabled in the text box. Also clears the text input
- * buffer to remove the password and starts the Sub-GHz worker. */
+ * buffer to remove the password and starts the Sub-GHz worker. After starting
+ * the worker a join message is transmitted. */
 static void pass_input_cb(void *context)
 {
 	furi_assert(context);
@@ -241,6 +281,16 @@ static void pass_input_cb(void *context)
 	subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
 			state->frequency);
 
+	/* concatenate the name prefix and join message */
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, " joined chat.");
+
+	/* encrypt and transmit message */
+	tx_msg_input(state);
+
+	/* clear message input buffer */
+	furi_string_set_char(state->msg_input, 0, 0);
+
 	scene_manager_handle_custom_event(state->scene_manager,
 			ESubGhzChatEvent_PassEntered);
 }
@@ -318,48 +368,19 @@ static void chat_input_cb(void *context)
 
 	/* concatenate the name prefix and the actual message */
 	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, ": ");
 	furi_string_cat_str(state->msg_input, state->text_input_store);
 
 	/* append the message to the chat box */
 	furi_string_cat_printf(state->chat_box_store, "\n%s",
 		furi_string_get_cstr(state->msg_input));
 
-	/* encrypt message if necessary */
-	size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
-	size_t tx_size = msg_len;
-	if (state->encrypted) {
-		tx_size += IV_BYTES + TAG_BYTES;
-		furi_check(tx_size <= sizeof(state->tx_buffer));
-
-		furi_hal_random_fill_buf(state->tx_buffer, IV_BYTES);
-		gcm_crypt_and_tag(&(state->gcm_ctx), ENCRYPT,
-				state->tx_buffer, IV_BYTES,
-				NULL, 0,
-				(unsigned char *)
-				furi_string_get_cstr(state->msg_input),
-				state->tx_buffer + IV_BYTES,
-				msg_len,
-				state->tx_buffer + IV_BYTES + msg_len,
-				TAG_BYTES);
-	} else {
-		tx_size += 2;
-		furi_check(tx_size <= sizeof(state->tx_buffer));
-		memcpy(state->tx_buffer,
-				furi_string_get_cstr(state->msg_input),
-				msg_len);
-
-		/* append \r\n for compat with Sub-GHz CLI chat */
-		state->tx_buffer[msg_len] = '\r';
-		state->tx_buffer[msg_len + 1] = '\n';
-	}
+	/* encrypt and transmit message */
+	tx_msg_input(state);
 
 	/* clear message input buffer */
 	furi_string_set_char(state->msg_input, 0, 0);
 
-	/* transmit */
-	subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer,
-			tx_size);
-
 	/* switch to text box view */
 	scene_manager_handle_custom_event(state->scene_manager,
 			ESubGhzChatEvent_MsgEntered);
@@ -577,7 +598,22 @@ static bool scene_on_event_chat_input(void* context, SceneManagerEvent event)
 		break;
 
 	case SceneManagerEventTypeBack:
-		/* stop the application if the user presses back here */
+		/* stop the application and send a leave message if the user
+		 * presses back here */
+
+		/* concatenate the name prefix and leave message */
+		furi_string_set(state->msg_input, state->name_prefix);
+		furi_string_cat_str(state->msg_input, " left chat.");
+
+		/* encrypt and transmit message */
+		tx_msg_input(state);
+
+		/* clear message input buffer */
+		furi_string_set_char(state->msg_input, 0, 0);
+
+		/* wait for leave message to be delivered */
+                furi_delay_ms(CHAT_LEAVE_DELAY);
+
 		view_dispatcher_stop(state->view_dispatcher);
 		consumed = true;
 		break;
@@ -984,8 +1020,7 @@ int32_t esubghz_chat(void)
 	state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
 
 	/* set chat name prefix */
-	// TODO: handle escape chars here somehow
-	furi_string_printf(state->name_prefix, "\033[0;33m%s\033[0m: ",
+	furi_string_printf(state->name_prefix, "%s",
 			furi_hal_version_get_name_ptr());
 
 	/* get notification record, we use this to make the flipper vibrate */