Closed lizziemac closed 11 months ago
Not really sure if I fully understand what you are doing exactly. Please change some relevant code....
What I can say in general is that binc_device_disconnect is an async method. You have to wait for the disconnect to complete before doing anything else. You should certainly not remove that device before the disconnect is completed. If you do that you will not receive the callback because you erased the device from the internal 'administration'.....
Sure, here's the full context, although I think you may have already given me the hint I need by waiting for the disconnect to complete before deleting the device:
const char *on_local_char_write(const Application *application,
const char *address, const char *service_uuid,
const char *char_uuid, GByteArray *byte_array) {
if ((g_str_equal(char_uuid, DISCONNECT_CHAR_UUID))) {
LOGI("Disconnect requested: disconnecting from central device");
Device *device =
binc_adapter_get_device_by_address(default_adapter, address);
LOGI("Device is %s", binc_device_get_path(device));
if (device == NULL) {
LOGE("Failed to get device by address");
return BLUEZ_ERROR_FAILED;
}
binc_device_disconnect(device);
binc_adapter_remove_device(default_adapter, device);
// TODO: consider async disconnect to enable a happy return value?
return NULL; // This command will always fail
}
}
ok so I changed my logic to the following:
// main
// ....
// Setup callback for device connection state changes
binc_adapter_set_remote_central_cb(default_adapter,
&on_central_state_changed);
// ...
const char *on_local_char_write(const Application *application,
const char *address, const char *service_uuid,
const char *char_uuid, GByteArray *byte_array) {
if ((g_str_equal(char_uuid, DISCONNECT_CHAR_UUID))) {
LOGI("Disconnect requested: disconnecting from central device");
Device *device =
binc_adapter_get_device_by_address(default_adapter, address);
LOGI("Device is %s", binc_device_get_path(device));
if (device == NULL) {
LOGE("Failed to get device by address");
return BLUEZ_ERROR_FAILED;
}
binc_device_disconnect(device);
return NULL; // This command will always fail
}
}
void on_central_state_changed(Adapter *adapter, Device *device) {
LOGI("device '%s' is now %s", binc_device_get_name(device),
binc_device_get_connection_state_name(device));
ConnectionState state = binc_device_get_connection_state(device);
if (state == CONNECTED) {
binc_adapter_stop_advertising(adapter, advertisement);
} else if (state == DISCONNECTED) {
// remove the device from the adapter
binc_adapter_remove_device(adapter, device);
// restart advertising
binc_adapter_start_advertising(adapter, advertisement);
}
}
But I'm never reaching the callback. Is this the right callback to use when disconnecting from the central device, as the peripheral? Interestingly though, I no longer need to forget the device, which is ideal! I just need to make sure I can resume advertising on disconnect.
Actually, it does hit it occasionally now - I just needed to reboot my device to see the benefit of not removing it except in the callback. thanks for the guidance!
Hi there Martijn!
Due to some client SDK issues for central devices, notably iOS, I need to have the peripheral disconnect itself. So far I've tried, in a specifically defined disconnect characteristic:
No cache for <central MAC address>
when looking in/var/log/messages
)Am I on the right track? Is there a different disconnect command or order of operations I should use? Also, is there a callback I can set for when the peripheral connection state changes? The central state change callback isn't called when just calling
binc_device_disconnect
.I appreciate any input you may have, and I hope you're having a good day!
Liz