Преглед изворни кода

PcMonitor: Fix for new BLE API (req pairing again, different MAC)

Willy-JL пре 1 година
родитељ
комит
4b11f03634
4 измењених фајлова са 195 додато и 11 уклоњено
  1. 114 0
      pc_monitor/helpers/ble_serial.c
  2. 53 0
      pc_monitor/helpers/ble_serial.h
  3. 26 10
      pc_monitor/pc_monitor.c
  4. 2 1
      pc_monitor/pc_monitor.h

+ 114 - 0
pc_monitor/helpers/ble_serial.c

@@ -0,0 +1,114 @@
+#include "ble_serial.h"
+
+#include <gap.h>
+#include <furi_ble/profile_interface.h>
+#include <services/serial_service.h>
+#include <furi.h>
+
+typedef struct {
+    FuriHalBleProfileBase base;
+
+    BleServiceSerial* serial_svc;
+} BleProfileSerial;
+_Static_assert(offsetof(BleProfileSerial, base) == 0, "Wrong layout");
+
+static FuriHalBleProfileBase* ble_profile_serial_start(FuriHalBleProfileParams profile_params) {
+    UNUSED(profile_params);
+
+    BleProfileSerial* profile = malloc(sizeof(BleProfileSerial));
+
+    profile->base.config = ble_profile_serial;
+
+    profile->serial_svc = ble_svc_serial_start();
+
+    return &profile->base;
+}
+
+static void ble_profile_serial_stop(FuriHalBleProfileBase* profile) {
+    furi_check(profile);
+    furi_check(profile->config == ble_profile_serial);
+
+    BleProfileSerial* serial_profile = (BleProfileSerial*)profile;
+    ble_svc_serial_stop(serial_profile->serial_svc);
+}
+
+static GapConfig serial_template_config = {
+    .adv_service_uuid = 0x3080,
+    .appearance_char = 0x8600,
+    .bonding_mode = true,
+    .pairing_method = GapPairingPinCodeShow,
+    .conn_param = {
+        .conn_int_min = 0x18, // 30 ms
+        .conn_int_max = 0x24, // 45 ms
+        .slave_latency = 0,
+        .supervisor_timeout = 0,
+    }};
+
+static void
+    ble_profile_serial_get_config(GapConfig* config, FuriHalBleProfileParams profile_params) {
+    BleProfileSerialParams* serial_profile_params = profile_params;
+
+    furi_check(config);
+    memcpy(config, &serial_template_config, sizeof(GapConfig));
+    // Set mac address
+    memcpy(config->mac_address, furi_hal_version_get_ble_mac(), sizeof(config->mac_address));
+
+    // Change MAC address for HID profile
+    config->mac_address[2]++;
+    if(serial_profile_params) {
+        config->mac_address[0] ^= serial_profile_params->mac_xor;
+        config->mac_address[1] ^= serial_profile_params->mac_xor >> 8;
+    }
+
+    // Set advertise name
+    memset(config->adv_name, 0, sizeof(config->adv_name));
+
+    const char* clicker_str = "Serial";
+    if(serial_profile_params && serial_profile_params->device_name_prefix) {
+        clicker_str = serial_profile_params->device_name_prefix;
+    }
+    // We don't have Flipper in BLE name, use printf instead of replace
+    FuriString* name = furi_string_alloc_printf(
+        "%c%s %s",
+        furi_hal_version_get_ble_local_device_name_ptr()[0],
+        clicker_str,
+        furi_hal_version_get_ble_local_device_name_ptr() + 1);
+    if(furi_string_size(name) >= sizeof(config->adv_name)) {
+        furi_string_left(name, sizeof(config->adv_name) - 1);
+    }
+    memcpy(config->adv_name, furi_string_get_cstr(name), furi_string_size(name));
+    furi_string_free(name);
+
+    config->adv_service_uuid |= furi_hal_version_get_hw_color();
+}
+
+static const FuriHalBleProfileTemplate profile_callbacks = {
+    .start = ble_profile_serial_start,
+    .stop = ble_profile_serial_stop,
+    .get_gap_config = ble_profile_serial_get_config,
+};
+
+const FuriHalBleProfileTemplate* ble_profile_serial = &profile_callbacks;
+
+void ble_profile_serial_set_event_callback(
+    FuriHalBleProfileBase* profile,
+    uint16_t buff_size,
+    FuriHalBtSerialCallback callback,
+    void* context) {
+    furi_check(profile && (profile->config == ble_profile_serial));
+
+    BleProfileSerial* serial_profile = (BleProfileSerial*)profile;
+    ble_svc_serial_set_callbacks(serial_profile->serial_svc, buff_size, callback, context);
+}
+
+bool ble_profile_serial_tx(FuriHalBleProfileBase* profile, uint8_t* data, uint16_t size) {
+    furi_check(profile && (profile->config == ble_profile_serial));
+
+    BleProfileSerial* serial_profile = (BleProfileSerial*)profile;
+
+    if(size > BLE_PROFILE_SERIAL_PACKET_SIZE_MAX) {
+        return false;
+    }
+
+    return ble_svc_serial_update_tx(serial_profile->serial_svc, data, size);
+}

+ 53 - 0
pc_monitor/helpers/ble_serial.h

@@ -0,0 +1,53 @@
+#pragma once
+
+#include <furi_ble/profile_interface.h>
+
+#include <services/serial_service.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 
+ * Optional arguments to pass along with profile template as 
+ * FuriHalBleProfileParams for tuning profile behavior 
+ **/
+typedef struct {
+    const char* device_name_prefix; /**< Prefix for device name. Length must be less than 8 */
+    uint16_t mac_xor; /**< XOR mask for device address, for uniqueness */
+} BleProfileSerialParams;
+
+#define BLE_PROFILE_SERIAL_PACKET_SIZE_MAX BLE_SVC_SERIAL_DATA_LEN_MAX
+
+/** Serial service callback type */
+typedef SerialServiceEventCallback FuriHalBtSerialCallback;
+
+/** Serial profile descriptor */
+extern const FuriHalBleProfileTemplate* ble_profile_serial;
+
+/** Send data through BLE
+ *
+ * @param profile       Profile instance
+ * @param data          data buffer
+ * @param size          data buffer size
+ *
+ * @return      true on success
+ */
+bool ble_profile_serial_tx(FuriHalBleProfileBase* profile, uint8_t* data, uint16_t size);
+
+/** Set Serial service events callback
+ *
+ * @param profile       Profile instance
+ * @param buffer_size   Applicaition buffer size
+ * @param calback       FuriHalBtSerialCallback instance
+ * @param context       pointer to context
+ */
+void ble_profile_serial_set_event_callback(
+    FuriHalBleProfileBase* profile,
+    uint16_t buff_size,
+    FuriHalBtSerialCallback callback,
+    void* context);
+
+#ifdef __cplusplus
+}
+#endif

+ 26 - 10
pc_monitor/pc_monitor.c

@@ -163,16 +163,25 @@ int32_t pc_monitor_app(void* p) {
     UNUSED(p);
     PcMonitorApp* app = pc_monitor_alloc();
 
-    if(furi_hal_bt_is_active()) {
-        furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_callback, app);
-        furi_hal_bt_start_advertising();
+    bt_disconnect(app->bt);
 
-        app->bt_state = BtStateWaiting;
-        FURI_LOG_D(TAG, "Bluetooth is active!");
-    } else {
-        app->bt_state = BtStateInactive;
-        FURI_LOG_W(TAG, "Please, enable the Bluetooth and restart the app");
-    }
+    // Wait 2nd core to update nvm storage
+    furi_delay_ms(200);
+
+    BleProfileSerialParams params = {
+        .device_name_prefix = "PC Mon",
+        .mac_xor = 0x0002,
+    };
+    app->ble_serial_profile = bt_profile_start(app->bt, ble_profile_serial, &params);
+
+    furi_check(app->ble_serial_profile);
+
+    ble_profile_serial_set_event_callback(
+        app->ble_serial_profile, BT_SERIAL_BUFFER_SIZE, bt_serial_callback, app);
+    furi_hal_bt_start_advertising();
+
+    app->bt_state = BtStateWaiting;
+    FURI_LOG_D(TAG, "Bluetooth is active!");
 
     // Main loop
     InputEvent event;
@@ -186,7 +195,14 @@ int32_t pc_monitor_app(void* p) {
             app->bt_state = BtStateLost;
     }
 
-    furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
+    ble_profile_serial_set_event_callback(app->ble_serial_profile, 0, NULL, NULL);
+
+    bt_disconnect(app->bt);
+
+    // Wait 2nd core to update nvm storage
+    furi_delay_ms(200);
+
+    furi_check(bt_profile_restore_default(app->bt));
 
     pc_monitor_free(app);
 

+ 2 - 1
pc_monitor/pc_monitor.h

@@ -3,7 +3,7 @@
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal_bt.h>
-#include <furi_hal_bt_serial.h>
+#include "helpers/ble_serial.h"
 #include <bt/bt_service/bt.h>
 #include <gui/gui.h>
 #include <gui/elements.h>
@@ -48,6 +48,7 @@ typedef struct {
     FuriMutex* app_mutex;
     FuriMessageQueue* event_queue;
     NotificationApp* notification;
+    FuriHalBleProfileBase* ble_serial_profile;
 
     BtState bt_state;
     DataStruct data;