@@ -49,6 +49,9 @@ static ble_scan_mode_t scan_mode = SCAN_MODE_NORMAL;
4949static int64_t additional_scan_start_time = 0 ;
5050#define ADDITIONAL_SCAN_TIMEOUT_MS 10000 /* 10 second timeout for additional scan */
5151
52+ #define MOUTHPAD_COMPANY_ID 0x4147
53+ #define MOUTHPAD_MFR_DATA_PAYLOAD "MP1"
54+
5255/* Track if any bonded devices are advertising in current scan session */
5356static bool bonded_device_seen_advertising = false;
5457
@@ -64,6 +67,7 @@ struct device_uuid_state {
6467 bt_addr_le_t addr ;
6568 bool has_hid ;
6669 bool has_nus ;
70+ bool has_mfr_data ;
6771 int8_t rssi ;
6872 int64_t timestamp ;
6973};
@@ -74,6 +78,7 @@ static K_MUTEX_DEFINE(tracked_devices_mutex);
7478/* Device type detection */
7579static bool is_nus_device (const struct bt_scan_device_info * device_info );
7680static bool is_hid_device (const struct bt_scan_device_info * device_info );
81+ static bool is_mouthpad_manufacturer_data (const struct bt_scan_device_info * device_info );
7782
7883/* Callback functions for external modules */
7984static ble_central_connected_cb_t connected_cb ;
@@ -310,6 +315,11 @@ static void scan_filter_match(struct bt_scan_device_info *device_info,
310315 struct bt_scan_filter_match * filter_match ,
311316 bool connectable )
312317{
318+ /* Ignore callbacks if we are no longer actively scanning */
319+ if (connection_state != BLE_CENTRAL_STATE_SCANNING ) {
320+ return ;
321+ }
322+
313323 char addr [BT_ADDR_LE_STR_LEN ];
314324
315325 bt_addr_le_to_str (device_info -> recv_info -> addr , addr , sizeof (addr ));
@@ -354,6 +364,7 @@ static void scan_filter_match(struct bt_scan_device_info *device_info,
354364
355365 if (has_hid ) dev_state -> has_hid = true;
356366 if (has_nus ) dev_state -> has_nus = true;
367+ if (is_mouthpad_manufacturer_data (device_info )) dev_state -> has_mfr_data = true;
357368 dev_state -> rssi = rssi ;
358369 dev_state -> timestamp = k_uptime_get ();
359370
@@ -368,6 +379,11 @@ static void scan_filter_match(struct bt_scan_device_info *device_info,
368379 return ;
369380 }
370381
382+ if (!is_bonded && !dev_state -> has_mfr_data ) {
383+ LOG_DBG ("Skipping device %s: missing expected manufacturer data" , addr );
384+ return ;
385+ }
386+
371387 /* CRITICAL: Set connecting state IMMEDIATELY before any logging or processing
372388 * This ensures status queries return CONNECTING as soon as we decide to connect */
373389 connection_state = BLE_CENTRAL_STATE_CONNECTING ;
@@ -835,6 +851,39 @@ static bool is_hid_device(const struct bt_scan_device_info *device_info)
835851 return ctx .found ;
836852}
837853
854+ static bool mfr_data_search_cb (struct bt_data * data , void * user_data )
855+ {
856+ bool * found = (bool * )user_data ;
857+
858+ if (data -> type == BT_DATA_MANUFACTURER_DATA ) {
859+ if (data -> data_len >= 2 + sizeof (MOUTHPAD_MFR_DATA_PAYLOAD ) - 1 &&
860+ sys_get_le16 (data -> data ) == MOUTHPAD_COMPANY_ID &&
861+ memcmp (data -> data + 2 , MOUTHPAD_MFR_DATA_PAYLOAD ,
862+ sizeof (MOUTHPAD_MFR_DATA_PAYLOAD ) - 1 ) == 0 ) {
863+ LOG_INF ("Manufacturer data matches" );
864+ * found = true;
865+ return false; /* stop parsing */
866+ }
867+ LOG_INF ("Manufacturer data does not match expected values" );
868+ }
869+
870+ return true; /* continue parsing */
871+ }
872+
873+ static bool is_mouthpad_manufacturer_data (const struct bt_scan_device_info * device_info )
874+ {
875+ bool found = false;
876+
877+ if (device_info -> adv_data ) {
878+ struct net_buf_simple_state state ;
879+ net_buf_simple_save (device_info -> adv_data , & state );
880+ bt_data_parse (device_info -> adv_data , mfr_data_search_cb , & found );
881+ net_buf_simple_restore (device_info -> adv_data , & state );
882+ }
883+
884+ return found ;
885+ }
886+
838887
839888/* Scan work handler */
840889static void scan_work_handler (struct k_work * item )
0 commit comments