Fix mouse coordinates, sequence BLE discovery/encryption, and prevent mouse from disabling on-screen keyboard
This commit is contained in:
@@ -815,7 +815,9 @@ static error_t api_scan_start(struct Device* device) {
|
||||
|
||||
struct ble_gap_disc_params disc_params = {};
|
||||
disc_params.passive = 0;
|
||||
disc_params.filter_duplicates = 1;
|
||||
disc_params.filter_duplicates = 0;
|
||||
disc_params.itvl = 160; // 100 ms
|
||||
disc_params.window = 160; // 100 ms
|
||||
|
||||
uint8_t own_addr_type;
|
||||
ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
|
||||
@@ -21,6 +21,14 @@ constexpr auto* TAG = "esp32_ble_scan";
|
||||
// Using BleCtx* (not Device*) so we avoid keeping a static Device reference.
|
||||
static BleCtx* s_scan_ctx = nullptr;
|
||||
|
||||
struct LoggedDevice {
|
||||
ble_addr_t addr;
|
||||
bool has_name;
|
||||
};
|
||||
constexpr size_t MAX_LOGGED_DEVICES = 128;
|
||||
static LoggedDevice s_logged_devices[MAX_LOGGED_DEVICES];
|
||||
static size_t s_logged_count = 0;
|
||||
|
||||
// ---- Scan data helpers ----
|
||||
|
||||
void ble_scan_clear_results(struct Device* device) {
|
||||
@@ -28,6 +36,8 @@ void ble_scan_clear_results(struct Device* device) {
|
||||
xSemaphoreTake(ctx->scan_mutex, portMAX_DELAY);
|
||||
ctx->scan_count = 0;
|
||||
memset(ctx->scan_results, 0, sizeof(ctx->scan_results));
|
||||
s_logged_count = 0;
|
||||
memset(s_logged_devices, 0, sizeof(s_logged_devices));
|
||||
xSemaphoreGive(ctx->scan_mutex);
|
||||
}
|
||||
|
||||
@@ -49,7 +59,8 @@ int ble_gap_disc_event_handler(struct ble_gap_event* event, void* arg) {
|
||||
record.connected = false;
|
||||
|
||||
struct ble_hs_adv_fields fields;
|
||||
if (ble_hs_adv_parse_fields(&fields, disc.data, disc.length_data) == 0) {
|
||||
bool parsed_fields = (ble_hs_adv_parse_fields(&fields, disc.data, disc.length_data) == 0);
|
||||
if (parsed_fields) {
|
||||
if (fields.name != nullptr && fields.name_len > 0) {
|
||||
size_t copy_len = std::min<size_t>(fields.name_len, BT_NAME_MAX);
|
||||
memcpy(record.name, fields.name, copy_len);
|
||||
@@ -57,6 +68,7 @@ int ble_gap_disc_event_handler(struct ble_gap_event* event, void* arg) {
|
||||
}
|
||||
}
|
||||
|
||||
bool should_publish = false;
|
||||
{
|
||||
xSemaphoreTake(ctx->scan_mutex, portMAX_DELAY);
|
||||
bool found = false;
|
||||
@@ -65,32 +77,99 @@ int ble_gap_disc_event_handler(struct ble_gap_event* event, void* arg) {
|
||||
// Deduplicate: merge name from SCAN_RSP without clobbering ADV_IND name
|
||||
if (record.name[0] != '\0') {
|
||||
memcpy(ctx->scan_results[i].name, record.name, BT_NAME_MAX + 1);
|
||||
} else {
|
||||
// If this packet doesn't have a name, keep the previously discovered name
|
||||
memcpy(record.name, ctx->scan_results[i].name, BT_NAME_MAX + 1);
|
||||
}
|
||||
ctx->scan_results[i].rssi = record.rssi;
|
||||
found = true;
|
||||
should_publish = (record.name[0] != '\0');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && ctx->scan_count < 64) {
|
||||
if (!found && record.name[0] != '\0' && ctx->scan_count < 64) {
|
||||
ctx->scan_results[ctx->scan_count] = record;
|
||||
ctx->scan_addrs[ctx->scan_count] = disc.addr; // full addr (type+val)
|
||||
ctx->scan_count++;
|
||||
should_publish = true;
|
||||
}
|
||||
xSemaphoreGive(ctx->scan_mutex);
|
||||
}
|
||||
|
||||
struct BtEvent e = {};
|
||||
e.type = BT_EVENT_PEER_FOUND;
|
||||
e.peer = record;
|
||||
ble_publish_event(device, e);
|
||||
// USB Serial logging for unique devices
|
||||
bool logged_already = false;
|
||||
size_t found_idx = 0;
|
||||
for (size_t i = 0; i < s_logged_count; ++i) {
|
||||
if (s_logged_devices[i].addr.type == disc.addr.type &&
|
||||
memcmp(s_logged_devices[i].addr.val, disc.addr.val, BT_ADDR_LEN) == 0) {
|
||||
logged_already = true;
|
||||
found_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool name_updated = false;
|
||||
if (logged_already) {
|
||||
if (!s_logged_devices[found_idx].has_name && record.name[0] != '\0') {
|
||||
s_logged_devices[found_idx].has_name = true;
|
||||
name_updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!logged_already && s_logged_count < MAX_LOGGED_DEVICES) {
|
||||
s_logged_devices[s_logged_count].addr = disc.addr;
|
||||
s_logged_devices[s_logged_count].has_name = (record.name[0] != '\0');
|
||||
s_logged_count++;
|
||||
}
|
||||
|
||||
if (!logged_already || name_updated) {
|
||||
char mac_str[18];
|
||||
snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
disc.addr.val[5], disc.addr.val[4], disc.addr.val[3],
|
||||
disc.addr.val[2], disc.addr.val[1], disc.addr.val[0]);
|
||||
|
||||
char extra_info[128] = "";
|
||||
int pos = 0;
|
||||
if (parsed_fields) {
|
||||
if (fields.appearance_is_present) {
|
||||
pos += snprintf(extra_info + pos, sizeof(extra_info) - pos, " App:0x%04x", fields.appearance);
|
||||
}
|
||||
if (fields.num_uuids16 > 0) {
|
||||
pos += snprintf(extra_info + pos, sizeof(extra_info) - pos, " UUID16:%d", (int)fields.num_uuids16);
|
||||
if (fields.uuids16 != nullptr) {
|
||||
uint16_t u16 = fields.uuids16[0].value;
|
||||
pos += snprintf(extra_info + pos, sizeof(extra_info) - pos, "(0x%04x)", (int)u16);
|
||||
}
|
||||
}
|
||||
if (fields.num_uuids128 > 0) {
|
||||
pos += snprintf(extra_info + pos, sizeof(extra_info) - pos, " UUID128:%d", (int)fields.num_uuids128);
|
||||
}
|
||||
if (fields.mfg_data_len > 0) {
|
||||
pos += snprintf(extra_info + pos, sizeof(extra_info) - pos, " Mfg:%d", (int)fields.mfg_data_len);
|
||||
}
|
||||
}
|
||||
LOG_I(TAG, "[BLE SCAN] Unique Device: MAC=%s RSSI=%d Name=%s%s%s",
|
||||
mac_str, (int)record.rssi, record.name[0] ? record.name : "<null>",
|
||||
extra_info, name_updated ? " (Name Updated)" : "");
|
||||
}
|
||||
|
||||
if (should_publish) {
|
||||
struct BtEvent e = {};
|
||||
e.type = BT_EVENT_PEER_FOUND;
|
||||
e.peer = record;
|
||||
ble_publish_event(device, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE:
|
||||
LOG_I(TAG, "Scan complete (reason=%d)", event->disc_complete.reason);
|
||||
// Keep scan_active=true; resolveNextUnnamedPeer clears it and fires ScanFinished
|
||||
// once name resolution finishes, so the UI spinner stays active throughout.
|
||||
ble_resolve_next_unnamed_peer(device, 0);
|
||||
ble_set_scan_active(device, false);
|
||||
{
|
||||
struct BtEvent e = {};
|
||||
e.type = BT_EVENT_SCAN_FINISHED;
|
||||
ble_publish_event(device, e);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user