-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(split): allow central to connect to multiple peripherals #836
Conversation
@@ -337,15 +362,20 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c | |||
} | |||
} | |||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) | |||
else if (settings_name_steq(name, "peripheral_address", &next) && !next) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line will solve multiple problems i have currently with my split setup
Most likely some additional changes would be needed for settings reset. It's not clear how that should be implemented, perhaps just loop and delete |
// index and no additional action is necessary. | ||
if (!bt_addr_le_cmp(&peripheral_addrs[i], addr)) { | ||
return i; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the recorded peripheral appears after slot i+1
, and takes i
th slot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand what i+1
you are referring to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the addr
is actually recorded at some slot j
, where j
> i
, but somehow the i
th slot is open, so the addr
takes away the i
th slot as well.
This may be a rare case, and j
th slot anyhow could be recycled for the addr
should trigger disconnected
function in normal cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slot 0 is filled, then slot 1 is filled, and so on. There is no code to delete just a single ble/peripheral_addresses/%d
setting so it's not possible to have i
open and j
occupied where i < j
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple minor items, but on a whole, LGTM.
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, split_central_device_found); | ||
// Start scanning otherwise. | ||
is_scanning = true; | ||
int err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, split_central_device_found); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now, but ideally a future enhancement will add a backoff on scanning, since multi-peripheral setups are more likely to have one of them only on some of the time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm exploring this,
bt_le_scan_start(&test_scan_params, split_central_device_found)
where,
static struct bt_le_scan_param test_scan_params = {
.type = BT_LE_SCAN_TYPE_PASSIVE,
.options = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
.interval = BT_GAP_SCAN_FAST_INTERVAL,
.window = BT_GAP_SCAN_FAST_WINDOW,
.timeout = 1500,
.interval_coded = 0,
.window_coded = 0,
};
Setting any timeout
> 0 will cause zmk to hang. .timeout = 0
will work just fine,
[00:00:00.770,935] <dbg> zmk: zmk_usb_get_conn_state: state: 1
[00:00:00.770,965] <dbg> zmk: get_selected_endpoint: No endpoints are ready.
[00:00:01.081,146] <inf> usb_hid: Device configured
[00:00:01.081,207] <dbg> zmk: zmk_usb_get_conn_state: state: 3
[00:00:01.081,237] <dbg> zmk: zmk_usb_get_conn_state: state: 3
[00:00:01.081,237] <dbg> zmk: get_selected_endpoint: Only USB is ready.
[00:00:01.081,237] <dbg> zmk: zmk_endpoints_send_report: usage page 0x07
[00:00:01.081,268] <dbg> zmk: zmk_endpoints_send_report: usage page 0x0C
[00:00:01.081,298] <inf> zmk: Endpoint changed: 0
[00:00:01.081,359] <dbg> zmk: destination_connection: Address pointer 0x20008fdf
[00:00:01.081,359] <wrn> zmk: Not sending, no active address for current profile
[00:00:01.081,390] <dbg> zmk: destination_connection: Address pointer 0x20008fdf
[00:00:01.081,390] <wrn> zmk: Not sending, no active address for current profile
Any ideas? I was hoping to register scan callbacks where after the 15s timeout, scanning is restarted with new params with a longer interval and window and an indefinite timeout.
Is there a reason for this section of code https://github.com/zmkfirmware/zmk/blob/main/app/src/split/bluetooth/central.c#L403-L411? It's not clear to me why I would consider getting rid of the lookup and having slicemk@44e0e7b#diff-18de66983adf7197deaf9e826c4087b486beb147e0ab19445d41a85ba7be9fe0R374-R384. |
IIRC, at least with Zephyr from several versions ago when I first wrote this, some times we would end up having an existing connection, after the scanning first discovers the advertising info, we and we needed to handle both scenarios:
If we can test this thoroughly and see this no longer happening with the stack, we should simplify this, for sure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few final code nitpicks. I will try to get to testing this soon.
app/src/ble.c
Outdated
LOG_ERR("Failed to handle peripheral address from settings (err %d)", err); | ||
return err; | ||
int i = atoi(next); | ||
if (i >= ZMK_BLE_SPLIT_PERIPHERAL_COUNT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be bullet proof here, should check for i < 0
as well.
My suggestion is to only handle a new connection when the If there is an existing connection, Will have an updated PR shortly. |
3aa5b79
to
42d83f5
Compare
I have been testing this (on the latest one as of this comment) and it's working well. @xudongzheng would you please consider pushing on top of the current commit instead of re-writing history with the force pushes? Makes it a little easier to explore the changes and can always be squashed when merging. Also, see my comment above RE scan timeout. |
42d83f5
to
d26b0ff
Compare
8ca9d3b
to
3751612
Compare
@xudongzheng, I have been testing this PR on my daily driver split keyboard for pretty much as long as it has existed. I often run into a particular latency issue where keypresses from each half will arrive out of order, making it difficult to type quickly. It is very similar in description to #1633. Have you had any such issues and any success in troubleshooting them? |
@bezmi The first thing to try is placing the dongle right between the two keyboard halves. If it works fine there, it's likely a signal issue and not a firmware issue. You can bump the Bluetooth TX power as is typically recommended for ZMK. |
@xudongzheng Can you please rebase now that your refactor #1815 is in? Code looks good w/ your latest push, will test here then merge, barring any problems appearing. Thanks! |
@xudongzheng See the pre-commit check issue please on this. |
@petejohanson Oops, somehow missed that. The new commit seems to pass all the commit checks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested on a pair of ZMK Uno/DK kits set up as splits. Works fine, and I know others have leveraged for a while for "dongle mode" as well.
This is a great first step toward fully supported BLE dongle mode, which will need still more docs, and build fixes to make doing so more seamless.
Thanks for sticking w/ this!
This addresses #314 and #609.
This might also affect #281 and #718.