From: Janos Kovacs Date: Tue, 15 May 2012 18:58:08 +0000 (+0300) Subject: replying AudioManager method calls; getting 'connect' and 'disconnect' work X-Git-Tag: build/2012-06-20.155507~49 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b26f6008e5a989c9f318917d71696533c9d54be1;p=profile%2Fivi%2Fpulseaudio-module-murphy-ivi.git replying AudioManager method calls; getting 'connect' and 'disconnect' work --- diff --git a/src/audiomgr.c b/src/audiomgr.c index 72e3391..ff047d3 100644 --- a/src/audiomgr.c +++ b/src/audiomgr.c @@ -42,6 +42,7 @@ #define MS_MUTED 1 #define MS_UNMUTED 2 + typedef struct { const char *name; uint16_t id; @@ -100,6 +101,32 @@ void pa_audiomgr_domain_registered(struct userdata *u, } } +void pa_audiomgr_connect(struct userdata *u, struct am_connect_data *cd) +{ + struct am_ack_data ad; + int err = E_OK; + + memset(&ad, 0, sizeof(ad)); + ad.handle = cd->handle; + ad.param1 = cd->connection; + ad.error = err; + + pa_policy_dbusif_acknowledge(u, AUDIOMGR_CONNECT_ACK, &ad); +} + +void pa_audiomgr_disconnect(struct userdata *u, struct am_connect_data *cd) +{ + struct am_ack_data ad; + int err = E_OK; + + memset(&ad, 0, sizeof(ad)); + ad.handle = cd->handle; + ad.param1 = cd->connection; + ad.error = err; + + pa_policy_dbusif_acknowledge(u, AUDIOMGR_DISCONNECT_ACK, &ad); +} + static pa_bool_t register_sink(struct userdata *u) { struct pa_audiomgr *am = u->audiomgr; diff --git a/src/audiomgr.h b/src/audiomgr.h index 59698d8..c20fb6d 100644 --- a/src/audiomgr.h +++ b/src/audiomgr.h @@ -3,6 +3,31 @@ #include "userdata.h" +#define AUDIOMGR_CONNECT "asyncConnect" +#define AUDIOMGR_DISCONNECT "asyncDisconnect" + +#define AUDIOMGR_CONNECT_ACK "ackConnect" +#define AUDIOMGR_DISCONNECT_ACK "ackDisconnect" +#define AUDIOMGR_SETSINKVOL_ACK "ackSetSinkVolume" +#define AUDIOMGR_SETSRCVOL_ACK "ackSetSourceVolume" +#define AUDIOMGR_SINKVOLTICK_ACK "ackSinkVolumeTick" +#define AUDIOMGR_SRCVOLTICK_ACK "ackSourceVolumeTick" +#define AUDIOMGR_SETSINKPROP_ACK "ackSetSinkSoundProperty" + +/* error codes */ +#define E_OK 0 +#define E_UNKNOWN 1 +#define E_OUT_OF_RANGE 2 +#define E_NOT_USED 3 +#define E_DATABSE_ERROR 4 +#define E_ALREADY_EXISTS 5 +#define E_NO_CHANGE 6 +#define E_NOT_POSSIBLE 7 +#define E_NON_EXISTENT 8 +#define E_ABORTED 9 +#define E_WRONG_FORMAT 10 + + struct pa_audiomgr; struct am_register_data { @@ -22,11 +47,28 @@ struct am_register_data { uint16_t interrupt; /* 1=off, 2=interrupted */ }; +struct am_connect_data { + uint16_t handle; + uint16_t connection; + uint16_t source; + uint16_t sink; + int16_t format; +}; + +struct am_ack_data { + uint32_t handle; + uint16_t param1; + uint16_t param2; + uint16_t error; +}; + struct pa_audiomgr *pa_audiomgr_init(struct userdata *); void pa_audiomgr_done(struct userdata *); void pa_audiomgr_domain_registered(struct userdata *, const char *, uint16_t, uint16_t); +void pa_audiomgr_connect(struct userdata *, struct am_connect_data *); +void pa_audiomgr_disconnect(struct userdata *, struct am_connect_data *); #endif diff --git a/src/dbusif.c b/src/dbusif.c index 6026c72..50fd76f 100644 --- a/src/dbusif.c +++ b/src/dbusif.c @@ -36,14 +36,6 @@ #define PULSE_DBUS_NAME "org.genivi.pulse" -#define AUDIOMGR_CONNECT_ACK "ackConnect" -#define AUDIOMGR_DISCONNECT_ACK "ackDisconnect" -#define AUDIOMGR_SETSINKVOL_ACK "ackSetSinkVolume" -#define AUDIOMGR_SETSRCVOL_ACK "ackSetSourceVolume" -#define AUDIOMGR_SINKVOLTICK_ACK "ackSinkVolumeTick" -#define AUDIOMGR_SRCVOLTICK_ACK "ackSourceVolumeTick" -#define AUDIOMGR_SETSINKPROP_ACK "ackSetSinkSoundProperty" - #define POLICY_DECISION "decision" #define POLICY_STREAM_INFO "stream_info" #define POLICY_ACTIONS "audio_actions" @@ -63,6 +55,8 @@ typedef void (*pending_cb_t)(struct userdata *, const char *, DBusMessage *, void *); +typedef pa_bool_t (*method_t)(struct userdata *, DBusMessage *); + struct pending { PA_LLIST_FIELDS(struct pending); @@ -93,6 +87,7 @@ struct pa_policy_dbusif { + struct actdsc { /* action descriptor */ const char *name; int (*parser)(struct userdata *u, DBusMessageIter *iter); @@ -161,6 +156,8 @@ static pa_bool_t build_sound_properties(DBusMessageIter *, struct am_register_data *); static pa_bool_t build_connection_formats(DBusMessageIter *, struct am_register_data *); +static pa_bool_t dbusif_connect(struct userdata *, DBusMessage *); +static pa_bool_t dbusif_disconnect(struct userdata *, DBusMessage *); @@ -923,7 +920,6 @@ static int signal_status(struct userdata *u, uint32_t txid, uint32_t status) fail: dbus_message_unref(msg); /* should cope with NULL msg */ - return -1; } @@ -936,23 +932,71 @@ static DBusHandlerResult audiomgr_method_handler(DBusConnection *conn, DBusMessage *msg, void *arg) { - struct userdata *u = (struct userdata *)arg; - const char *method; + struct dispatch { + const char *name; + method_t method; + }; + + static struct dispatch dispatch_tbl[] = { + { AUDIOMGR_CONNECT , dbusif_connect }, + { AUDIOMGR_DISCONNECT, dbusif_disconnect }, + { NULL, NULL } + }; + + struct userdata *u = (struct userdata *)arg; + struct dispatch *d; + const char *name; + method_t method; + uint32_t serial; + dbus_int16_t errcod; + DBusMessage *reply; + pa_bool_t success; pa_assert(conn); pa_assert(msg); pa_assert(u); - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL) { - method = dbus_message_get_member(msg); + name = dbus_message_get_member(msg); + serial = dbus_message_get_serial(msg); - pa_assert(method); + pa_assert(name); + + for (method = NULL, d = dispatch_tbl; d->name; d++) { + if (!strcmp(name, d->name)) { + method = d->method; + break; + } + } + + errcod = method ? E_OK : E_NOT_POSSIBLE; + reply = dbus_message_new_method_return(msg); - pa_log_debug("**** Kakukk: '%s'", method); + // dbus_message_set_reply_serial(reply, serial); + + success = dbus_message_append_args(reply, + DBUS_TYPE_INT16, &errcod, + DBUS_TYPE_INVALID); + + if (!success || !dbus_connection_send(conn, reply, NULL)) + pa_log("%s: failed to reply '%s'", __FILE__, name); + else + pa_log_debug("'%s' replied (%d)", name, errcod); - return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_unref(reply); + + if (method) + d->method(u, msg); + else + pa_log_info("%s: unsupported '%s' method ignored", __FILE__, name); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + pa_log_debug("got some unexpected type of D-Bus message"); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -1070,13 +1114,13 @@ static int register_to_audiomgr(struct pa_policy_dbusif *dbusif, return success; } -void pa_policy_dbusif_domain_complete(struct userdata *u, uint16_t domain_id) +pa_bool_t pa_policy_dbusif_domain_complete(struct userdata *u, uint16_t domain) { - dbus_int32_t id32 = domain_id; + dbus_int32_t id32 = domain; struct pa_policy_dbusif *dbusif; DBusConnection *conn; DBusMessage *msg; - int success; + pa_bool_t success; pa_assert(u); pa_assert_se((dbusif = u->dbusif)); @@ -1084,7 +1128,7 @@ void pa_policy_dbusif_domain_complete(struct userdata *u, uint16_t domain_id) pa_log_debug("%s: completing registration for domain %u", - __FILE__, domain_id); + __FILE__, domain); msg = dbus_message_new_method_call(dbusif->amnam, dbusif->amrpath, @@ -1097,7 +1141,6 @@ void pa_policy_dbusif_domain_complete(struct userdata *u, uint16_t domain_id) goto getout; } - success = dbus_message_append_args(msg, DBUS_TYPE_INT32, &id32, DBUS_TYPE_INVALID); @@ -1129,6 +1172,12 @@ static void audiomgr_register_cb(struct userdata *u, dbus_uint16_t object_id; dbus_uint16_t state; int success; + const char *objtype; + + pa_assert(u); + pa_assert(method); + pa_assert(reply); + pa_assert(data); if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { success = dbus_message_get_args(reply, NULL, @@ -1148,11 +1197,17 @@ static void audiomgr_register_cb(struct userdata *u, DBUS_TYPE_INVALID); if (!success) { - pa_log("got broken message from AudioManager.Registration failed"); + pa_log("got broken message from AudioManager. " + "Registration failed"); } else { - pa_log_info("AudioManager replied to registration: objectID: %u", - object_id); + if (!strncasecmp("register", method, 8)) + objtype = method + 8; + else + objtype = method; + + pa_log_info("AudioManager replied to registration: %sID: %u", + objtype, object_id); } } } @@ -1310,6 +1365,112 @@ pa_bool_t pa_policy_dbusif_register(struct userdata *u, const char *method, return success; } +static pa_bool_t dbusif_connect(struct userdata *u, DBusMessage *msg) +{ + struct am_connect_data ac; + int success; + + pa_assert(u); + pa_assert(msg); + + memset(&ac, 0, sizeof(ac)); + + success = dbus_message_get_args(msg, NULL, + DBUS_TYPE_UINT16, &ac.handle, + DBUS_TYPE_UINT16, &ac.connection, + DBUS_TYPE_UINT16, &ac.source, + DBUS_TYPE_UINT16, &ac.sink, + DBUS_TYPE_INT16 , &ac.format, + DBUS_TYPE_INVALID); + if (!success) { + pa_log("%s: got broken connect message from AudioManager. " + "Ignoring it", __FILE__); + return FALSE; + } + + pa_log_debug("AudioManager connect(%u|%u|%u|%u|%d)", + ac.handle, ac.connection, ac.source, ac.sink, ac.format); + + pa_audiomgr_connect(u, &ac); + + return TRUE; +} + +static pa_bool_t dbusif_disconnect(struct userdata *u, DBusMessage *msg) +{ + struct am_connect_data ac; + int success; + + pa_assert(u); + pa_assert(msg); + + memset(&ac, 0, sizeof(ac)); + + success = dbus_message_get_args(msg, NULL, + DBUS_TYPE_UINT16, &ac.handle, + DBUS_TYPE_UINT16, &ac.connection, + DBUS_TYPE_INVALID); + if (!success) { + pa_log("%s: got broken disconnect message from AudioManager. " + "Ignoring it", __FILE__); + return FALSE; + } + + pa_log_debug("AudioManager disconnect(%u|%u)", ac.handle, ac.connection); + + pa_audiomgr_disconnect(u, &ac); + + return TRUE; +} + +pa_bool_t pa_policy_dbusif_acknowledge(struct userdata *u, const char *method, + struct am_ack_data *ad) +{ + struct pa_policy_dbusif *dbusif; + DBusConnection *conn; + DBusMessage *msg; + pa_bool_t success; + + pa_assert(u); + pa_assert(method); + pa_assert_se((dbusif = u->dbusif)); + pa_assert_se((conn = pa_dbus_connection_get(dbusif->conn))); + + pa_log_debug("%s: sending %s", __FILE__, method); + + msg = dbus_message_new_method_call(dbusif->amnam, + dbusif->amrpath, + dbusif->amrnam, + method); + if (msg == NULL) { + pa_log("%s: Failed to create D-Bus message for '%s'", + __FILE__, method); + success = FALSE; + goto getout; + } + + success = dbus_message_append_args(msg, + DBUS_TYPE_UINT16, &ad->handle, + DBUS_TYPE_UINT16, &ad->param1, + DBUS_TYPE_UINT16, &ad->error, + DBUS_TYPE_INVALID); + if (!success) { + pa_log("%s: Failed to build D-Bus message message '%s'", + __FILE__, method); + goto getout; + } + + if (!dbus_connection_send(conn, msg, NULL)) { + pa_log("%s: Failed to send D-Bus message '%s'", __FILE__, method); + goto getout; + } + + getout: + dbus_message_unref(msg); + return success; + return success; +} + /* * Local Variables: diff --git a/src/dbusif.h b/src/dbusif.h index 4f45d3a..e6e958a 100644 --- a/src/dbusif.h +++ b/src/dbusif.h @@ -14,6 +14,7 @@ struct pa_policy_dbusif; struct am_register_data; +struct am_ack_data; struct pa_policy_dbusif *pa_policy_dbusif_init(struct userdata *, const char *, const char *, const char *, @@ -23,11 +24,11 @@ void pa_policy_dbusif_send_device_state(struct userdata *,char *,char **,int); void pa_policy_dbusif_send_media_status(struct userdata *, const char *, const char *, int); -void pa_policy_dbusif_domain_complete(struct userdata *, uint16_t); +pa_bool_t pa_policy_dbusif_domain_complete(struct userdata *, uint16_t); pa_bool_t pa_policy_dbusif_register(struct userdata *, const char *, struct am_register_data *); - - +pa_bool_t pa_policy_dbusif_acknowledge(struct userdata *, const char *, + struct am_ack_data *); #endif