Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update libngf server communication.
  • Loading branch information
Juho Hämäläinen committed Nov 30, 2012
1 parent ab06a32 commit b8ef214
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 52 deletions.
108 changes: 62 additions & 46 deletions libngf/client.c
Expand Up @@ -48,6 +48,8 @@
/** DBus method call that is sent to us when the event state changes */
#define NGF_DBUS_INTERNAL_STATUS "Status"

#define NGF_DBUS_MATCH "type='signal',interface='" NGF_DBUS_IFACE "',member='" NGF_DBUS_INTERNAL_STATUS "', path='" NGF_DBUS_PATH "'"

typedef struct _NgfReply NgfReply;
typedef struct _NgfEvent NgfEvent;

Expand All @@ -56,16 +58,17 @@ struct _NgfReply
LIST_INIT (NgfReply)

DBusPendingCall *pending;
uint32_t event_id;
uint32_t client_event_id;
int stop_set;
};

struct _NgfEvent
{
LIST_INIT (NgfEvent)

uint32_t event_id;
uint32_t policy_id;
uint32_t client_event_id;
uint32_t server_event_id;
int stopping;
};

struct _NgfClient
Expand All @@ -79,13 +82,14 @@ struct _NgfClient
NgfEvent *active_events;
};

static void _free_active_event (NgfEvent *event, void *userdata);

static void
_send_stop_event (DBusConnection *connection,
uint32_t policy_id)
uint32_t server_event_id)
{
DBusMessage *msg = NULL;
DBusMessageIter sub;
dbus_uint32_t serial = 0;

if ((msg = dbus_message_new_method_call (NGF_DBUS_NAME,
NGF_DBUS_PATH,
Expand All @@ -96,9 +100,9 @@ _send_stop_event (DBusConnection *connection,
}

dbus_message_iter_init_append (msg, &sub);
dbus_message_iter_append_basic (&sub, DBUS_TYPE_UINT32, &policy_id);
dbus_message_iter_append_basic (&sub, DBUS_TYPE_UINT32, &server_event_id);

dbus_connection_send (connection, msg, &serial);
dbus_connection_send (connection, msg, NULL);
dbus_message_unref (msg);
}

Expand All @@ -113,7 +117,6 @@ _pending_play_reply (DBusPendingCall *pending,

DBusMessage *msg = NULL;
DBusMessageIter iter;
uint32_t policy_id = 0;

for (reply_iter = client->pending_replies; reply_iter; reply_iter = reply_iter->next) {
if (reply_iter->pending == pending) {
Expand All @@ -125,44 +128,48 @@ _pending_play_reply (DBusPendingCall *pending,
if (reply == NULL)
goto done;

msg = dbus_pending_call_steal_reply (pending);

if (dbus_message_is_error (msg, DBUS_ERROR_FAILED)) {
client->callback (client, reply->client_event_id, NGF_EVENT_FAILED, client->userdata);
goto done;
}

event = (NgfEvent*) malloc (sizeof (NgfEvent));
memset (event, 0, sizeof (NgfEvent));
event->event_id = reply->event_id;
event->client_event_id = reply->client_event_id;

msg = dbus_pending_call_steal_reply (pending);
dbus_message_iter_init (msg, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) {
if (client->callback)
client->callback (client, event->event_id, NGF_EVENT_FAILED, client->userdata);
client->callback (client, event->client_event_id, NGF_EVENT_FAILED, client->userdata);
free (event);

goto done;
}

dbus_message_iter_get_basic (&iter, &policy_id);
dbus_message_iter_get_basic (&iter, &event->server_event_id);

if (policy_id > 0) {
if (event->server_event_id > 0) {
if (reply->stop_set) {
_send_stop_event (client->connection, policy_id);
_send_stop_event (client->connection, event->server_event_id);
free (event);

goto done;
}

event->policy_id = policy_id;

LIST_APPEND (client->active_events, event);
} else {
if (client->callback)
client->callback (client, event->event_id, NGF_EVENT_FAILED, client->userdata);
client->callback (client, event->client_event_id, NGF_EVENT_FAILED, client->userdata);
free (event);
goto done;
}

done:
if (msg)
dbus_message_unref (msg);
dbus_message_unref (msg);

if (reply) {
LIST_REMOVE (client->pending_replies, reply);
free (reply);
Expand All @@ -180,42 +187,43 @@ _message_filter_cb (DBusConnection *connection,

DBusError error;
NgfEvent *event = NULL;
uint32_t policy_id = 0;
uint32_t server_event_id = 0;
uint32_t state = 0;
int success = 0;

if (!dbus_message_is_method_call (msg, NGF_DBUS_IFACE, NGF_DBUS_INTERNAL_STATUS))
if (!dbus_message_is_signal (msg, NGF_DBUS_IFACE, NGF_DBUS_INTERNAL_STATUS)) {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

dbus_error_init (&error);
success = dbus_message_get_args (msg, &error,
DBUS_TYPE_UINT32, &policy_id, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
DBUS_TYPE_UINT32, &server_event_id, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);

if (!success) {
dbus_error_free (&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

/* Try to find a matching policy id from the active events. */
/* Try to find a matching server event id from the active events. */

for (event = client->active_events; event; event = event->next) {
if (event->policy_id == policy_id) {
if (event->server_event_id == server_event_id) {

/* Trigger the callback, if specified, and remove the event from
active events. */

if (client->callback)
client->callback (client, event->event_id, state, client->userdata);
client->callback (client, event->client_event_id, state, client->userdata);

if (state == NGF_EVENT_COMPLETED || state == NGF_EVENT_FAILED) {
LIST_REMOVE (client->active_events, event);
free (event);
_free_active_event (event, NULL);
}
break;
}
}

return DBUS_HANDLER_RESULT_HANDLED;
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

NgfClient*
Expand All @@ -238,6 +246,9 @@ ngf_client_create (NgfTransport transport,
if (!c->connection)
goto failed;

dbus_connection_ref (c->connection);

dbus_bus_add_match (c->connection, NGF_DBUS_MATCH, NULL);
dbus_connection_add_filter (c->connection, _message_filter_cb, c, NULL);
return c;

Expand All @@ -250,7 +261,11 @@ static void
_stop_active_event (NgfEvent *event, void *userdata)
{
NgfClient *client = (NgfClient*) userdata;
_send_stop_event (client->connection, event->policy_id);
if (event->stopping)
return;

event->stopping = 1;
_send_stop_event (client->connection, event->server_event_id);
}

static void
Expand All @@ -277,18 +292,23 @@ ngf_client_destroy (NgfClient *client)
if (client == NULL)
return;

/* Free and stop any active event. */
/* Stop any active events. */
LIST_FOREACH (client->active_events, _stop_active_event, client);
LIST_FOREACH (client->active_events, _free_active_event, client);

/* Free any pending replies. */
LIST_FOREACH (client->pending_replies, _free_pending_reply, client);


if (client->connection) {
dbus_connection_flush (client->connection);
dbus_connection_remove_filter (client->connection, _message_filter_cb, client);
dbus_bus_remove_match (client->connection, NGF_DBUS_MATCH, NULL);
dbus_connection_unref (client->connection);
client->connection = NULL;
}

LIST_FOREACH (client->active_events, _free_active_event, client);

free (client);
}

Expand Down Expand Up @@ -364,12 +384,12 @@ ngf_client_play_event (NgfClient *client,
NgfReply *reply = NULL;

DBusMessageIter iter, sub;
uint32_t event_id = 0;
uint32_t client_event_id = 0;

if (client == NULL || event == NULL)
return 0;

event_id = ++client->play_id;
client_event_id = ++client->play_id;

/* Send the actual message to the service. */

Expand Down Expand Up @@ -399,18 +419,18 @@ ngf_client_play_event (NgfClient *client,
memset (reply, 0, sizeof (NgfReply));

reply->pending = pending;
reply->event_id = event_id;
reply->client_event_id = client_event_id;

LIST_APPEND (client->pending_replies, reply);

dbus_pending_call_set_notify (pending, _pending_play_reply, client, NULL);

return event_id;
return client_event_id;
}

void
ngf_client_stop_event (NgfClient *client,
uint32_t id)
uint32_t client_event_id)
{
NgfEvent *event = NULL;
NgfReply *reply = NULL;
Expand All @@ -422,10 +442,8 @@ ngf_client_stop_event (NgfClient *client,

event = client->active_events;
while (event) {
if (event->event_id == id) {
if (event->client_event_id == client_event_id) {
_stop_active_event (event, client);
LIST_REMOVE (client->active_events, event);
_free_active_event (event, client);
break;
}

Expand All @@ -436,7 +454,7 @@ ngf_client_stop_event (NgfClient *client,

reply = client->pending_replies;
while (reply) {
if (reply->event_id == id) {
if (reply->client_event_id == client_event_id) {
reply->stop_set = TRUE;
break;
}
Expand All @@ -462,7 +480,7 @@ _pause_active_event (NgfClient *client,
}

dbus_message_iter_init_append (msg, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &event->policy_id);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &event->server_event_id);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &pause);

dbus_connection_send (client->connection, msg, NULL);
Expand All @@ -471,17 +489,16 @@ _pause_active_event (NgfClient *client,

void
ngf_client_pause_event (NgfClient *client,
uint32_t id)
uint32_t client_event_id)
{
NgfEvent *event = NULL;
NgfReply *reply = NULL;

if (client == NULL)
return;

event = client->active_events;
while (event) {
if (event->event_id == id) {
if (event->client_event_id == client_event_id) {
_pause_active_event (client, event, 1);
break;
}
Expand All @@ -492,17 +509,16 @@ ngf_client_pause_event (NgfClient *client,

void
ngf_client_resume_event (NgfClient *client,
uint32_t id)
uint32_t client_event_id)
{
NgfEvent *event = NULL;
NgfReply *reply = NULL;

if (client == NULL)
return;

event = client->active_events;
while (event) {
if (event->event_id == id) {
if (event->client_event_id == client_event_id) {
_pause_active_event (client, event, 0);
break;
}
Expand Down
18 changes: 12 additions & 6 deletions libngf/client.h
Expand Up @@ -39,20 +39,26 @@ typedef enum _NgfTransport

typedef enum _NgfEventState
{
/** Event fails when we are unable to get resources for it or we just can't play it. */
NGF_EVENT_FAILED = 0,

/** Event is completed when the event has been played or cancelled by higher priority event. */
NGF_EVENT_COMPLETED = 0,
NGF_EVENT_COMPLETED = 1,

/** Event fails when we are unable to get resources for it or we just can't play it. */
NGF_EVENT_FAILED = 1,
/** Event is in playing state when playback is successfully started or continued. */
NGF_EVENT_PLAYING = 2,

/** Event is in paused state when pause is called. */
NGF_EVENT_PAUSED = 3,

/** Event is busy, because there is a more higher priority event playing. */
NGF_EVENT_BUSY = (1 << 1),
NGF_EVENT_BUSY = (1 << 2),

/** Event will be played using a long tone */
NGF_EVENT_LONG = (1 << 2),
NGF_EVENT_LONG = (1 << 3),

/** Event will be played using a short tone */
NGF_EVENT_SHORT = (1 << 3)
NGF_EVENT_SHORT = (1 << 4)
} NgfEventState;

/** Internal client structure. */
Expand Down

0 comments on commit b8ef214

Please sign in to comment.