Since commit c89b589a58, D-Bus >= 1.4.0 is
required. This version already contains Unix FD passing support,
therefore code that checks for DBUS_TYPE_UNIX_FD definition is
unnecessary.
This function is starting to be too long and needs to be split.
After this patch, the resulting code should be exactly equivalent as the
previous implementation.
Several transports may exist for each endpoint, for example if several
HFGW are connected. This should be exposed to the endpoint as one
transport each.
If get_setting is called before set_setting, mp->settings would be
NULL resulting in GLib assertion. Hashmap is now allocated in
media_player_create instead of on-demand allocation in set_setting.
external/bluetooth/bluez/audio/media.c:get_setting() Equalizer
CRITICAL **: g_hash_table_lookup: assertion `hash_table != NULL' failed
If pending connection will stay after state has been changed to
HEADSET_STATE_DISCONNECTED, then crash may happen (e.g. when hs_connect
will be called quickly again after that) To avoid that kind of problems
using headset_shutdown, which does necessary cleanup first (finalizes
pending connections) and after that changes state to
HEADSET_STATE_DISCONNECTED.
When registering for TRACK_CHANGED event, CT expects the track's UID in
the INTERIM and CHANGED responses. According to AVRCP 1.3 spec, there
are only 2 possible values:
1) 0: there's a track selected
2) UINT32_MAX: there's no track selected
AVRCP 1.4 reserves the value UINT64_MAX for the second case. Since this
later value is the one used in certification process for best IOP
we return UINT64_MAX instead of the former.
This implementation allows to pass PTS test TP/NFY/BV-05-C.
If we use the same hash table to set the new metadata, we have 2
undesired behaviors:
1) New track may contain fields from previous track if it didn't set all
the fields
2) If we fail on parsing the signal, we will still change some of the
fields
This fixes the following compilation error with GLib on 32-bit sytems:
audio/media.c: In function 'get_setting':
audio/media.c:1109:44: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
audio/media.c: In function 'set_setting':
audio/media.c:1132:41: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
Crash is caused by not removed freed player from the list:
Invalid read of size 8
at 0x13E7B5: media_adapter_find_player (media.c:861)
by 0x13FEBC: register_player (media.c:1561)
by 0x120DFE: process_message (object.c:224)
by 0x4F6E9A0: ??? (in /lib64/libdbus-1.so.3.5.6)
by 0x4F6092F: dbus_connection_dispatch (in /lib64/libdbus-1.so.3.5.6)
by 0x11F787: message_dispatch (mainloop.c:80)
by 0x4C762CA: ??? (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C74ADC: g_main_context_dispatch (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C752D7: ??? (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C75824: g_main_loop_run (in /lib64/libglib-2.0.so.0.3000.0)
by 0x11EE4B: main (main.c:485)
Address 0x642ef30 is 16 bytes inside a block of size 80 free'd
at 0x4A0662E: free (vg_replace_malloc.c:366)
by 0x4C7B7F2: g_free (in /lib64/libglib-2.0.so.0.3000.0)
by 0x12D292: player_destroy (avrcp.c:1099)
by 0x120C38: service_filter (watch.c:477)
by 0x120950: message_filter (watch.c:527)
by 0x4F608E5: dbus_connection_dispatch (in /lib64/libdbus-1.so.3.5.6)
by 0x11F787: message_dispatch (mainloop.c:80)
by 0x4C762CA: ??? (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C74ADC: g_main_context_dispatch (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C752D7: ??? (in /lib64/libglib-2.0.so.0.3000.0)
by 0x4C75824: g_main_loop_run (in /lib64/libglib-2.0.so.0.3000.0)
by 0x11EE4B: main (main.c:485)
When a HFPHS endpoint is created, media will start to watch for
HandsfreeGateway state changes. media call SetConfiguration upon
connection and ClearConfiguration upon disconnection.
If SetConfiguration call fails, the headset or gateway for which
SetConfiguration is called is disconnected. This will free any
pending request, but this does not prevent the request to
terminate (endpoint_reply) and try to free itself once again.
Note that a copy of the freed pointer is tested which has not
been updated.
This also fix the circular dependency of media.c and a2dp.c
Invalid read of size 8
at 0x4EA8CC2: g_slice_free_chain_with_offset (in /lib64/libglib-2.0.so.0.2908.0)
by 0x13AF33: path_free (media.c:417)
by 0x11EB39: remove_interface (object.c:563)
by 0x11F360: g_dbus_unregister_interface (object.c:715)
by 0x120C49: media_server_remove (manager.c:1098)
by 0x4EA9826: g_slist_foreach (in /lib64/libglib-2.0.so.0.2908.0)
by 0x178915: adapter_remove (adapter.c:2326)
by 0x17535F: btd_manager_unregister_adapter (manager.c:293)
by 0x154081: device_event (hciops.c:2643)
by 0x1543C1: io_stack_event (hciops.c:2763)
by 0x4E8C88C: g_main_context_dispatch (in /lib64/libglib-2.0.so.0.2908.0)
by 0x4E8D087: ??? (in /lib64/libglib-2.0.so.0.2908.0)
Address 0x63f6638 is 8 bytes inside a block of size 16 free'd
at 0x4A055FE: free (vg_replace_malloc.c:366)
by 0x4E938F2: g_free (in /lib64/libglib-2.0.so.0.2908.0)
by 0x4EA854E: g_slice_free1 (in /lib64/libglib-2.0.so.0.2908.0)
by 0x4EA930C: g_slist_remove (in /lib64/libglib-2.0.so.0.2908.0)
by 0x13AE53: media_endpoint_remove (media.c:118)
by 0x4EA9826: g_slist_foreach (in /lib64/libglib-2.0.so.0.2908.0)
by 0x4EA984A: g_slist_free_full (in /lib64/libglib-2.0.so.0.2908.0)
by 0x13AF33: path_free (media.c:417)
by 0x11EB39: remove_interface (object.c:563)
by 0x11F360: g_dbus_unregister_interface (object.c:715)
by 0x120C49: media_server_remove (manager.c:1098)
by 0x4EA9826: g_slist_foreach (in /lib64/libglib-2.0.so.0.2908.0)
Under some circumstances (such as terminating bluetoothd during music is
streamed) endpoint object may be destroyed (memory for endpoint object is
internally freed, directly by "media_endpoint_remove") after invoking
"media_transport_destroy" (in "media_endpoint_clear_configuration") to
destroy transport object (memory for transport object is directly freed by
"media_transport_free"). It leads to invalid write issue (reported by
valgrind) after assignment "endpoint->transport = NULL", since "endpoint"
is "alias" pointer to endpoint object which is already out of date
(memory for endpoint object has been already freed).
This patch prevents from this issue by ensuring that assignment
"endpoint->transport = NULL" would be executed when endpoint object
certainly exists.
Function media_endpoint_create returns pointer to structure. In
conditional expression it is safer to compare returned value with NULL
and not with gboolean as it is done in register_endpoint function.
Since media driver uses a2dp to register its sep and store a pointer,
this pointer may be invalid/freed when media driver is unregistered.
To fix this now a2dp will also release any sep registered using media
API.
It also protect from future changes on the order of drivers removal by
checking if pointers (sep or endpoint) are still available in the list
before removing them.
'Protocol not supported' error code is added to the registration of A2DP
end-points. Error response org.bluez.Error.NotSupported instead of
org.bluez.Error.InvalidArguments is used when SEP registration fails due
to disabled corresponding interface in audio.conf.
When parsing endpoint properties application my not have set some of the
mandatory properties, also the size of capability is now initialized with
0 so if the codec doesn't have any capabilities (e.g. pcm) the variable
won't be used uninitialized.
HFP/HSP can be connected when registering an endpoint which is different
than on a2dp where the sep cannot be configured already since it wasn't
available before.
This cause some clients like PulseAudio to fail to find a proper
transport since connected state is send before transport configuration
is set.
To fix this now SetConfiguration is called early on when headset is still
in connecting phase, this matches sink/source where SetConfiguration is
also called before connected.