bluetooth: Set off profile on SCO disconnect

Sends a message from IO thread to main thread using pa_msgobject when POLLERR
or POLLHUP is received on SCO socket.
This commit is contained in:
Frédéric Dalleau 2011-10-04 09:37:24 +02:00 committed by Arun Raghavan
parent 2c213607e2
commit 2f24a6e627

View file

@ -126,6 +126,15 @@ struct hsp_info {
pa_hook_slot *source_state_changed_slot; 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 { struct userdata {
pa_core *core; pa_core *core;
pa_module *module; pa_module *module;
@ -148,6 +157,7 @@ struct userdata {
pa_rtpoll *rtpoll; pa_rtpoll *rtpoll;
pa_rtpoll_item *rtpoll_item; pa_rtpoll_item *rtpoll_item;
pa_thread *thread; pa_thread *thread;
bluetooth_msg *msg;
uint64_t read_index, write_index; uint64_t read_index, write_index;
pa_usec_t started_at; pa_usec_t started_at;
@ -176,6 +186,11 @@ struct userdata {
pa_bool_t filter_added; 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_PLAYBACK_A2DP (25*PA_USEC_PER_MSEC)
#define FIXED_LATENCY_RECORD_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) #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; 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 */ /* Run from IO thread */
static int hsp_process_render(struct userdata *u) { static int hsp_process_render(struct userdata *u) {
int ret = 0; int ret = 0;
@ -1721,6 +1753,7 @@ static void thread_func(void *userdata) {
fail: fail:
/* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */ /* 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_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); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
finish: finish:
@ -2881,6 +2914,12 @@ int pa__init(pa_module* m) {
if (add_card(u, device) < 0) if (add_card(u, device) < 0)
goto fail; 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)) { if (!dbus_connection_add_filter(pa_dbus_connection_get(u->connection), filter_cb, u, NULL)) {
pa_log_error("Failed to add filter function"); pa_log_error("Failed to add filter function");
goto fail; goto fail;
@ -2981,6 +3020,9 @@ void pa__done(pa_module *m) {
pa_dbus_connection_unref(u->connection); pa_dbus_connection_unref(u->connection);
} }
if (u->msg)
pa_xfree(u->msg);
if (u->card) if (u->card)
pa_card_free(u->card); pa_card_free(u->card);