Sends a message from IO thread to main thread using pa_msgobject when POLLERR or POLLHUP is received on SCO socket. --- src/modules/bluetooth/module-bluetooth-device.c | 42 +++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 4d1969b..d90f779 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -126,6 +126,15 @@ struct hsp_info { pa_hook_slot *source_state_changed_slot; }; +struct bluetooth_msg { + pa_msgobject parent; + pa_card *card; +}; + +typedef struct bluetooth_msg bluetooth_msg; +PA_DEFINE_PRIVATE_CLASS(bluetooth_msg, pa_msgobject); +#define BLUETOOTH_MSG(o) (bluetooth_msg_cast(o)) + struct userdata { pa_core *core; pa_module *module; @@ -148,6 +157,7 @@ struct userdata { pa_rtpoll *rtpoll; pa_rtpoll_item *rtpoll_item; pa_thread *thread; + bluetooth_msg *msg; uint64_t read_index, write_index; pa_usec_t started_at; @@ -176,6 +186,11 @@ struct userdata { pa_bool_t filter_added; }; +enum { + BLUETOOTH_MESSAGE_SET_PROFILE, + BLUETOOTH_MESSAGE_MAX +}; + #define FIXED_LATENCY_PLAYBACK_A2DP (25*PA_USEC_PER_MSEC) #define FIXED_LATENCY_RECORD_A2DP (25*PA_USEC_PER_MSEC) #define FIXED_LATENCY_PLAYBACK_HSP (125*PA_USEC_PER_MSEC) @@ -1115,6 +1130,23 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off return (r < 0 || !failed) ? r : -1; } +/* Called from main thread context */ +static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct bluetooth_msg *u = BLUETOOTH_MSG(obj); + + switch (code) { + case BLUETOOTH_MESSAGE_SET_PROFILE: { + const char *profile = data; + pa_log_debug("Switch profile to %s requested", profile); + + if (pa_card_set_profile(u->card, profile, FALSE) < 0) + pa_log_debug("Failed to switch profile to %s", profile); + break; + } + } + return 0; +} + /* Run from IO thread */ static int hsp_process_render(struct userdata *u) { int ret = 0; @@ -1721,6 +1753,7 @@ static void thread_func(void *userdata) { fail: /* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */ pa_log_debug("IO thread failed"); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_SET_PROFILE, "off", 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: @@ -2881,6 +2914,12 @@ int pa__init(pa_module* m) { if (add_card(u, device) < 0) goto fail; + if (!(u->msg = pa_msgobject_new(bluetooth_msg))) + goto fail; + + u->msg->parent.process_msg = device_process_msg; + u->msg->card = u->card; + if (!dbus_connection_add_filter(pa_dbus_connection_get(u->connection), filter_cb, u, NULL)) { pa_log_error("Failed to add filter function"); goto fail; @@ -2981,6 +3020,9 @@ void pa__done(pa_module *m) { pa_dbus_connection_unref(u->connection); } + if (u->msg) + pa_xfree(u->msg); + if (u->card) pa_card_free(u->card); -- 1.7.4.1