Invalid read of size 4
at 0x468370: btd_service_connecting_complete (service.c:315)
by 0x41B70F: session_ct_init_control (avrcp.c:2790)
by 0x41B1E0: state_changed (avrcp.c:2933)
by 0x418054: avctp_set_state (avctp.c:548)
by 0x41A2E4: avctp_connect_cb (avctp.c:1201)
by 0x44F989: accept_cb (btio.c:201)
by 0x4E77044: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x4E77377: g_main_context_iterate.isra.24 (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x4E77771: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x40A8EE: main (main.c:583)
Address 0x20 is not stack'd, malloc'd or (recently) free'd
If no A2DP is found assume the controller is the initiator as the
target should not be able to initate a connection.
When there is an incoming connection to AVCTP PSM, there is no way to
know if the remote UUID corresponds to AVRCP_REMOTE_UUID or
AVRCP_TARGET_UUID. Therefore both UUIDs should be reported to the core.
Without this patch, a crash has been observed with the iPhone 5
immediately after pairing.
With MPRIS the player can disable support for certain control using
properties such as CanPlay, CanPause..., in this case these methods
should not be called and the code should fallback to uinput method.
From AV/C spec 1.23, page 76:
"A command with the pressed value is valid for two seconds from the time
when a target sends back a response of the command. The controller shall
continue sending pressed value with identical operation id value in the
operation_id field while the command is wished to stay valid. Either if
the target has not received the pressed command within two seconds or the
target receives the pressed command with another operation id, then the
target regards that the released command was sent but missed to receive."
The timer field can be used to detect if the key is currectly active
instead of relying on a pointer that needs to be allocated for every
single key press.
There were two groups of missing error messages in the documentation:
* For org.bluez.Device1.DisconnectProfile:
This method could certainly call btd_error_not_supported or
btd_error_failed returning those errors.
* For org.bluez.Device1.Pair:
The pairing process could certainly call new_authentication_return
which can return (and actualy does) five other different errors.
This patch makes the autopair plugin try a fixed "0000" pincode for
keyboards that reject the pincode too fast (less than 500ms). This too
short delay rejecting the pincode means that the user didn't have time
to type the random pincode in the bluetooth keyboard and was the
keyboard who actually rejected it.
One of the interesting values for pincode plugins is the timeout of a
bonding attempt. For keyboards supporting any random pincode as long as
it is also typed in the keyboard, the timeout until it fails is in the
order of the seconds to allow the user type the pincode on the bluetooth
keyboard. In the case of a dumb keyboard accepting only a fixed pincode
the timeout before the keyboard fails is in the order of a fraction of a
second.
This patch computes the elapsed time between the pairing started or the
pin code was sent to the device and the device returns with an error.
This measured duration is exposed in milliseconds to the plugins when
retrying the bonding attempt.
The autopair plugin tries standard pincodes for different devices with
dumb pincodes. It also generates a random 6 digit pincode for keyboards
that support any pincode but fallbacks to the agent call in case the
random generated pincode didn't work.
This patch splits the bonding process in an interative process
consisting of one or more "bonding attempts". The user/agent starts a
new "bonding" that may involve several rounds of "bonding attempts" with
the device before it gets back to the user/agent.
Some functions were split in two parts to reflect this change. When a
bonding attempt fails with an authentication error and a pin code was
provided, a new bonding attempt is initiated (after a short delay) to
retry with the next function (or next call to the same function) in the
pincode callback list. If no pin code was provided to the device, no
retry is attempted and the authentication error is returned to the
client. This effectively allows a plugin try different pincodes for the
same device during the same bonding.
In order to retry a bonding we need a timer that will perform the retry,
we need to stash the status of the bonding request so we can use it
again. In the case of a retrying bonding attempt we need to not tear
down the temporary D-Bus device object on the adapter.
The plugin's pin code callback doesn't know about the pairing process.
It just provides a pin code based on the information provided to this
function. Although limited state could be added through other new
callbacks, this fix achieves this by providing more information to the
callback itself. The new argument "attempt" states the pin callback
attempt of the particular plugin for the current pairing of the device.
This allows a plugin to try different pincodes for the same device in
the same pairing process.
To signal that the plugin doesn't provide any pin code for the provided
device the current implementation returns 0 (an empty pin code).
Analogously, with this fix, a plugin should return 0 when it doesn't
have any other pin code to provide for the given device.
The current pincode callback list on the adapter keeps track of all the
pincode callbacks registered by a plugin for that adapter and calls each
one until one provides a pincode for the current bonding. This mechanism
forgets about what happened with previous bonding attempts and pushes
the status track to the plugin side.
This patch creates an iterator struct (struct pincb_iter) that keeps
track of the last function called and the number of times called. This
will allow to provide more information about the bonding status to the
pincode callback.
From D-Bus documentation for dbus_connection_send_with_reply():
"Warning: if the connection is disconnected or you try to send Unix file
descriptors on a connection that does not support them, the
DBusPendingCall will be set to NULL, so be careful with this."
Fix these errors when killing D-Bus daemon with the client still
running:
process 5712: arguments to dbus_pending_call_set_notify() were
incorrect, assertion "pending != NULL" failed in file
../../dbus/dbus-pending-call.c line 596.
This is normally a bug in some application using the D-Bus library.
process 5712: arguments to dbus_pending_call_unref() were incorrect,
assertion "pending != NULL" failed in file
../../dbus/dbus-pending-call.c line 572.
This is normally a bug in some application using the D-Bus library.
Fix this crash if D-Bus exits while the client is still connected to it:
==5570== Invalid read of size 1
==5570== at 0x402D28E: strcmp (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5570== by 0x4070E22: g_str_equal (ghash.c:1704)
==5570== by 0x8055F61: message_filter (client.c:1123)
==5570== by 0x4141500: dbus_connection_dispatch (in
/lib/i386-linux-gnu/libdbus-1.so.3.5.8)
==5570== by 0x80506F7: message_dispatch (mainloop.c:76)
==5570== by 0x4081A7E: g_timeout_dispatch (gmain.c:3882)
==5570== by 0x4080D85: g_main_context_dispatch (gmain.c:2539)
==5570== by 0x4081124: g_main_context_iterate.isra.21 (gmain.c:3146)
==5570== by 0x408156A: g_main_loop_run (gmain.c:3340)
==5570== by 0x41BF4D2: (below main) (libc-start.c:226)
==5570== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5570==
==5570==
update_found_devices() could attempt to update a device with new information
containing only a short verstion of the name. If the struct eir_data passed
has a short or NULL name, it will never update a previous name and will
also trigger a "HCI Command: Remote Name Request" if the previous name was
unknown.
Remotely initiated connections need to be associated to a service
instance to avoid the following crash as reported by Vinicius Costa:
bluetoothd[14366]: src/profile.c:ext_confirm() incoming connect from A0:4E:04:F6:F5:05
bluetoothd[14366]: src/profile.c:ext_confirm() hfp_hf authorizing connection from A0:4E:04:F6:F5:05
bluetoothd[14366]: src/agent.c:agent_ref() 0x6a85e0: ref=2
bluetoothd[14366]: src/agent.c:agent_authorize_service() authorize service request was sent for /org/bluez/hci0/dev_A0_4E_04_F6_F5_05
bluetoothd[14366]: src/profile.c:ext_svc_complete() Services resolved for A0:4E:04:F6:F5:05
bluetoothd[14366]: src/profile.c:ext_svc_complete() Services resolved but still waiting for authorization
bluetoothd[14366]: src/profile.c:ext_auth() A0:4E:04:F6:F5:05 authorized to connect to hfp_hf
bluetoothd[14366]: src/agent.c:agent_unref() 0x6a85e0: ref=1
bluetoothd[14366]: src/profile.c:ext_connect() hfp_hf connected to A0:4E:04:F6:F5:05
Program received signal SIGSEGV, Segmentation fault.
btd_service_connecting_complete (service=0x0, err=err@entry=0) at src/service.c:315
315 if (service->state != BTD_SERVICE_STATE_DISCONNECTED &&
Message might not contain State field and CPS needs to be set to
unknown before processing message from neard. This fix processing
RequestOOB called without parameters.
If endpoint exit while a request is pending, e.g. due to a crash, the
callback should be called with ret set to NULL otherwise the code that
has generated the request will not notice the request has been canceled
leaving the endpoint unusable.
Invalid read of size 8
at 0x42F4B2: connection_unregister (connection.c:643)
by 0x466CE6: service_shutdown (service.c:174)
by 0x467B70: remove_service (device.c:963)
by 0x32C3863CAC: g_slist_foreach (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x32C3863CCA: g_slist_free_full (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x46CABC: device_remove (device.c:2331)
by 0x45E229: adapter_remove_device.constprop.44 (adapter.c:1049)
by 0x45E31D: remove_device (adapter.c:2134)
by 0x40CC80: process_message.isra.4 (object.c:258)
by 0x32C641D9C4: ??? (in /usr/lib64/libdbus-1.so.3.7.2)
by 0x32C640FC1F: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.2)
by 0x40A807: message_dispatch (mainloop.c:76)
Address 0x54e6e38 is 8 bytes inside a block of size 16 free'd
at 0x4A077E6: free (vg_replace_malloc.c:446)
by 0x32C384D79E: g_free (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x40DCA9: remove_interface (object.c:656)
by 0x40DF09: g_dbus_unregister_interface (object.c:1413)
by 0x466CE6: service_shutdown (service.c:174)
by 0x467B70: remove_service (device.c:963)
by 0x32C3863CAC: g_slist_foreach (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x32C3863CCA: g_slist_free_full (in /usr/lib64/libglib-2.0.so.0.3400.2)
by 0x46CABC: device_remove (device.c:2331)
by 0x45E229: adapter_remove_device.constprop.44 (adapter.c:1049)
by 0x45E31D: remove_device (adapter.c:2134)
by 0x40CC80: process_message.isra.4 (object.c:258)
If a paired and connected audio device is disconnected, the
avrcp_disconnect() could create a new avctp session that will keep
a reference to the corresponding btd_device, preventing it to be
removed as explained below. This fix prevents avrcp_disconnect()
to create a new and disconnected avctp session when it doesn't
exists.
Calling org.bluez.Device1.Disconnect on an audio device like the
"Monster ClarityHD" will cause first a a2dp_sink_disconnect() call,
and then a sink_disconnect() call.
This will change the state of the existing avdtp session to
AVCTP_STATE_DISCONNECTED triggering a series of callback calls.
Among those, the avdtp_set_state() function will call the registered
avdtp_callbacks, including avdtp_state_callback() which in turns
updates the disconnected state using sink_set_state(). This function
will call the registered sink_callbacks, including device_sink_cb().
By this point, the device_sink_cb() will attempt a avrcp_disconnect()
over a session that was already disconnected before by the device's
diconnect_cb(). This new avrcp_disconnect() causes the avctp_get() to
create a new avctp session that holds a reference to the disconnecting
btd_device.
Steps to reproduce using bluetoothctl:
1. Pair and Connect a Monter ClarityHD audio device.
2. Play some music on it.
3. Disconnect the device.
4. Remove the device.
The "remove" command succeeds, but bluetoothd does not sends a removal
signal ([DEL] message) for that device.
Calling g_dbus_client_new followed by g_dbus_client_set_proxy_handlers
cause two calls to GetManagedObjects in a row as GetNameOwner reply is
asyncronously it triggers the second call because the handlers have
been set by g_dbus_client_set_proxy_handlers.