Skip to content

Instantly share code, notes, and snippets.

@phillipberndt
Created January 15, 2016 16:00
Show Gist options
  • Save phillipberndt/fcb01bad5cd18b4ebb2f to your computer and use it in GitHub Desktop.
Save phillipberndt/fcb01bad5cd18b4ebb2f to your computer and use it in GitHub Desktop.
Bluez 5 support for a2dp-alsa
Patch for a2dp-alsa sinks to work with Bluez 5
By Phillip Berndt <[email protected]>
This is a patch for
http://www.lightofdawn.org/blog/?viewDetailed=00032
to work with Bluez 5.x. The changes are mostly what the original author
described, thanks a lot for the detailled description!
Note that this is a destructive patch; it breaks Bluez 4
support. Also, --source is untested.
diff -Nru a2dp-alsa/Makefile a2dp-alsa-patched/Makefile
--- a2dp-alsa/Makefile 2013-06-26 11:23:11.000000000 +0200
+++ a2dp-alsa-patched/Makefile 2016-01-08 08:41:53.586987778 +0100
@@ -1,5 +1,5 @@
CFLAGS := $(CFLAGS) -O0 -g -DDEBUG -Wall
-LDFLAGS := $(LDFLAGS)
+LDFLAGS := $(LDFLAGS) -pthread
all: a2dp-alsa libsbc.a a2dp-buffer
diff -Nru a2dp-alsa/a2dp-alsa.c a2dp-alsa-patched/a2dp-alsa.c
--- a2dp-alsa/a2dp-alsa.c 2013-06-26 14:30:39.000000000 +0200
+++ a2dp-alsa-patched/a2dp-alsa.c 2016-01-15 16:55:31.683957399 +0100
@@ -156,39 +156,8 @@
DBusError err;
char *s, *method = FIND_ADAPTER;
- dbus_error_init(&err);
- debug_print("Getting object path for adapter %s\n", device);
-
- // create a new method call msg
- if (!device) method = DEFAULT_ADAPTER;
- msg = dbus_message_new_method_call("org.bluez",
- "/", // object to call on
- "org.bluez.Manager", // interface to call on
- method); // method name
-
- // append arguments
- dbus_message_iter_init_append(msg, &iter);
- if (device) dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &device);
-
- // send message and wait for reply, -1 means wait forever
- reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &err);
- handle_dbus_error (&err, __FUNCTION__, __LINE__);
- if (!reply) {
- fprintf(stderr, "Reply Null\n");
- return 0;
- }
-
- // read the parameters
- if (dbus_message_iter_init(reply, &iter) &&
- DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&iter))
- dbus_message_iter_get_basic(&iter, &s);
- else return 0;
-
- // free reply and close connection
- debug_print("Object path for %s is %s\n", device, s);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- *dev_path = strdup (s);
+ // org.bluez.Manager has been removed; just use hci0
+ *dev_path = strdup ("/org/bluez/hci0");
return 1;
}
@@ -268,7 +237,7 @@
dbus_error_init(&err);
msg = dbus_message_new_method_call("org.bluez",
bt_object, // object to call on
- "org.bluez.Media", // interface to call on
+ "org.bluez.Media1", // interface to call on
"RegisterEndpoint"); // method name
//build the parameters
@@ -319,12 +288,8 @@
dbus_error_init(&err);
msg = dbus_message_new_method_call("org.bluez",
transport_path, // object to call on
- "org.bluez.MediaTransport", // interface to call on
+ "org.bluez.MediaTransport1", // interface to call on
"Acquire"); // method name
-
- //build the parameters
- dbus_message_iter_init_append (msg, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &access_type);
//make the call
reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &err);
@@ -371,12 +336,8 @@
dbus_error_init(&err);
msg = dbus_message_new_method_call("org.bluez",
transport_path, // object to call on
- "org.bluez.MediaTransport", // interface to call on
+ "org.bluez.MediaTransport1", // interface to call on
"Release"); // method name
-
- //build the parameters
- dbus_message_iter_init_append (msg, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &access_type);
//make the call
reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &err);
@@ -806,7 +767,7 @@
*********************/
#define audiosink_property_changed audiosource_property_changed
void audiosource_property_changed (DBusConnection *conn, DBusMessage *msg, int write, io_thread_tcb_s **io_threads_table) {
- DBusMessageIter iter, itervariant;
+ DBusMessageIter iter, itervariant, iterarray, iterdict;
char *key;
char *dev_path;
char *state;
@@ -816,11 +777,18 @@
dbus_message_iter_init (msg, &iter);
dbus_message_iter_get_basic (&iter, &key);
- if (strcasecmp (key, "State") != 0) return; //we are only interested in this.
+ if (strcasecmp (key, "org.bluez.MediaTransport1") != 0) return; //we are only interested in this.
if (!dbus_message_iter_next(&iter)) goto fail;
- dbus_message_iter_recurse(&iter, &itervariant);
+
+ dbus_message_iter_recurse(&iter, &iterarray);
+ dbus_message_iter_recurse(&iterarray, &iterdict);
+ dbus_message_iter_get_basic(&iterdict, &state);
+ if(strcasecmp(state, "State") != 0) return;
+ if(!dbus_message_iter_next(&iterdict)) goto fail;
+ dbus_message_iter_recurse(&iterdict, &itervariant);
if (dbus_message_iter_get_arg_type(&itervariant) != DBUS_TYPE_STRING) goto fail;
+
dbus_message_iter_get_basic (&itervariant, &state);
dev_path = (char *)dbus_message_get_path (msg);
@@ -830,7 +798,7 @@
if (!head) return;
io_data = head;
do {
- if (strcasecmp (dev_path, io_data->dev_path) == 0 &&
+ if (strncasecmp (dev_path, io_data->dev_path, strlen(io_data->dev_path)) == 0 &&
io_data->write == write)
break;
else io_data = io_data->hh.next;
@@ -839,34 +807,20 @@
//decode state & transition
new_state = transition = -1;
- if ( strcasecmp (state, "connected") == 0 ) new_state = STATE_CONNECTED;
- else if ( strcasecmp (state, "playing") == 0 ) new_state = STATE_PLAYING;
+ if ( strcasecmp (state, "pending") == 0 ) new_state = STATE_CONNECTED;
+ else if ( strcasecmp (state, "active") == 0 ) new_state = STATE_PLAYING;
else if ( strcasecmp (state, "disconnected") == 0 ) new_state = STATE_DISCONNECTED;
if (new_state >= 0) {
- transition = io_data->prev_state << 4 | new_state;
io_data->prev_state = new_state;
}
-
- //our treatment of sink and source is a bit different
- switch (write) {
- case 0: // bt sink: bt --> alsa
- when_to_acquire = STATE_CONNECTED << 4 | STATE_PLAYING;
- when_to_release = STATE_PLAYING << 4 | STATE_CONNECTED;
- break;
-
- case 1: // bt source: alsa --> bt
- when_to_acquire = STATE_DISCONNECTED << 4 | STATE_CONNECTED;
- when_to_release = STATE_CONNECTED << 4 | STATE_DISCONNECTED;
- break;
- }
-
+
//acquire or release transport depending on the transitions
- if (transition == when_to_acquire) {
+ if (new_state == STATE_CONNECTED) {
if (transport_acquire (conn, io_data->transport_path, &io_data->fd, &io_data->read_mtu, &io_data->write_mtu)) {
debug_print ("fd: %d read mtu %d write mtu %d\n", io_data->fd, io_data->read_mtu, io_data->write_mtu);
io_thread_set_command (io_data, IO_CMD_RUNNING);
}
- } else if (transition == when_to_release) {
+ } else if (new_state == STATE_DISCONNECTED) {
transport_release (conn, io_data->transport_path);
io_thread_set_command (io_data, IO_CMD_IDLE);
}
@@ -1294,11 +1248,11 @@
// 3. capture signals
if (run_sink) { // bt --> alsa
- dbus_bus_add_match (system_bus, "type='signal',interface='org.bluez.AudioSource',member='PropertyChanged'", &err);
+ dbus_bus_add_match (system_bus, "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'", &err);
handle_dbus_error (&err, __FUNCTION__, __LINE__);
}
if (run_source) { // alsa --> bt
- dbus_bus_add_match (system_bus, "type='signal',interface='org.bluez.AudioSink',member='PropertyChanged'", &err);
+ dbus_bus_add_match (system_bus, "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'", &err);
handle_dbus_error (&err, __FUNCTION__, __LINE__);
}
@@ -1307,17 +1261,17 @@
while (!quit && (msg = dbus_connection_pop_message (system_bus))) { //get the message
// dispatch
reply = NULL;
- if (dbus_message_is_signal (msg, "org.bluez.AudioSource", "PropertyChanged")) // bt --> alsa
+ if (dbus_message_is_signal (msg, "org.freedesktop.DBus.Properties", "PropertiesChanged")) // bt --> alsa
audiosource_property_changed (system_bus, msg, 0, &io_threads_table);
- else if (dbus_message_is_signal (msg, "org.bluez.AudioSink", "PropertyChanged")) // alsa --> bt
+ else if (dbus_message_is_signal (msg, "org.freedesktop.DBus.Properties", "PropertiesChanged")) // alsa --> bt
audiosink_property_changed (system_bus, msg, 1, &io_threads_table);
- else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint", "SetConfiguration"))
+ else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint1", "SetConfiguration"))
reply = endpoint_set_configuration (msg, &io_threads_table);
- else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint", "SelectConfiguration"))
+ else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint1", "SelectConfiguration"))
reply = endpoint_select_configuration (msg);
- else if(dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint", "ClearConfiguration"))
+ else if(dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint1", "ClearConfiguration"))
reply = endpoint_clear_configuration (msg, &io_threads_table);
- else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint", "Release"))
+ else if (dbus_message_is_method_call (msg, "org.bluez.MediaEndpoint1", "Release"))
{ reply = endpoint_release (msg); quit=1; }
if (reply) {
// send the reply
@miaoichi
Copy link

miaoichi commented Apr 18, 2018

Nice work, it is workable on Bluez-5.49.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment