OSDN Git Service

android/ipc: Add message handling for audio IPC
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 31 Dec 2013 10:39:09 +0000 (12:39 +0200)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 7 Jan 2014 11:37:53 +0000 (13:37 +0200)
This adds audio_ipc_register and audio_ipc_unregister and adapt
ipc_handle_msg to be able to handle audio services messages.

android/audio-ipc.c
android/audio-ipc.h
android/audio-msg.h
android/ipc.c
android/ipc.h

index b537f21..0c5433a 100644 (file)
 
 static GIOChannel *audio_io = NULL;
 
+static struct service_handler service;
+
 static gboolean audio_watch_cb(GIOChannel *io, GIOCondition cond,
                                                        gpointer user_data)
 {
        char buf[BLUEZ_AUDIO_MTU];
        ssize_t ret;
-       int fd;
+       int fd, err;
 
        if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
                info("Audio IPC: command socket closed");
@@ -61,6 +63,13 @@ static gboolean audio_watch_cb(GIOChannel *io, GIOCondition cond,
                goto fail;
        }
 
+       err = ipc_handle_msg(&service, AUDIO_SERVICE_ID, buf, ret);
+       if (err < 0) {
+               error("Audio IPC: failed to handle message (%s)",
+                                                       strerror(-err));
+               goto fail;
+       }
+
        return TRUE;
 
 fail:
@@ -102,3 +111,15 @@ void audio_ipc_cleanup(void)
                audio_io = NULL;
        }
 }
+
+void audio_ipc_register(const struct ipc_handler *handlers, uint8_t size)
+{
+       service.handler = handlers;
+       service.size = size;
+}
+
+void audio_ipc_unregister(void)
+{
+       service.handler = NULL;
+       service.size = 0;
+}
index 769bfd6..1dfa245 100644 (file)
@@ -23,3 +23,6 @@
 
 void audio_ipc_init(void);
 void audio_ipc_cleanup(void);
+
+void audio_ipc_register(const struct ipc_handler *handlers, uint8_t size);
+void audio_ipc_unregister(void);
index d5b4099..1ec2520 100644 (file)
@@ -24,3 +24,5 @@
 #define BLUEZ_AUDIO_MTU 1024
 
 static const char BLUEZ_AUDIO_SK_PATH[] = "\0bluez_audio_socket";
+
+#define AUDIO_SERVICE_ID               0
index 8a91248..1499962 100644 (file)
 #include "ipc.h"
 #include "log.h"
 
-struct service_handler {
-       const struct ipc_handler *handler;
-       uint8_t size;
-};
-
 static struct service_handler services[HAL_SERVICE_ID_MAX + 1];
 
 static GIOChannel *cmd_io = NULL;
 static GIOChannel *notif_io = NULL;
 
-static void ipc_handle_msg(const void *buf, ssize_t len)
+int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
+                                               const void *buf, ssize_t len)
 {
        const struct hal_hdr *msg = buf;
        const struct ipc_handler *handler;
 
        if (len < (ssize_t) sizeof(*msg)) {
-               error("IPC: message too small (%zd bytes), terminating", len);
-               raise(SIGTERM);
-               return;
+               DBG("message too small (%zd bytes)", len);
+               return -EBADMSG;
        }
 
        if (len != (ssize_t) (sizeof(*msg) + msg->len)) {
-               error("IPC: message malformed (%zd bytes), terminating", len);
-               raise(SIGTERM);
-               return;
+               DBG("message malformed (%zd bytes)", len);
+               return -EBADMSG;
        }
 
        /* if service is valid */
-       if (msg->service_id > HAL_SERVICE_ID_MAX) {
-               error("IPC: unknown service (0x%x), terminating",
-                                                       msg->service_id);
-               raise(SIGTERM);
-               return;
+       if (msg->service_id > max_index) {
+               DBG("unknown service (0x%x)", msg->service_id);
+               return -EOPNOTSUPP;
        }
 
        /* if service is registered */
-       if (!services[msg->service_id].handler) {
-               error("IPC: unregistered service (0x%x), terminating",
-                                                       msg->service_id);
-               raise(SIGTERM);
-               return;
+       if (!handlers[msg->service_id].handler) {
+               DBG("service not registered (0x%x)", msg->service_id);
+               return -EOPNOTSUPP;
        }
 
        /* if opcode is valid */
        if (msg->opcode == HAL_OP_STATUS ||
-                       msg->opcode > services[msg->service_id].size) {
-               error("IPC: invalid opcode 0x%x for service 0x%x, terminating",
-                                               msg->opcode, msg->service_id);
-               raise(SIGTERM);
-               return;
+                       msg->opcode > handlers[msg->service_id].size) {
+               DBG("invalid opcode 0x%x for service 0x%x", msg->opcode,
+                                                       msg->service_id);
+               return -EOPNOTSUPP;
        }
 
        /* opcode is table offset + 1 */
@@ -98,13 +87,14 @@ static void ipc_handle_msg(const void *buf, ssize_t len)
        /* if payload size is valid */
        if ((handler->var_len && handler->data_len > msg->len) ||
                        (!handler->var_len && handler->data_len != msg->len)) {
-               error("IPC: size invalid opcode 0x%x service 0x%x, terminating",
+               DBG("invalid size for opcode 0x%x service 0x%x",
                                                msg->service_id, msg->opcode);
-               raise(SIGTERM);
-               return;
+               return -EMSGSIZE;
        }
 
        handler->handler(msg->payload, msg->len);
+
+       return 0;
 }
 
 static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
@@ -112,7 +102,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 {
        char buf[BLUEZ_HAL_MTU];
        ssize_t ret;
-       int fd;
+       int fd, err;
 
        if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
                info("IPC: command socket closed, terminating");
@@ -128,7 +118,13 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
                goto fail;
        }
 
-       ipc_handle_msg(buf, ret);
+       err = ipc_handle_msg(services, HAL_SERVICE_ID_MAX, buf, ret);
+       if (err < 0) {
+               error("IPC: failed to handle message, terminating (%s)",
+                                                       strerror(-err));
+               goto fail;
+       }
+
        return TRUE;
 
 fail:
index 02ad6bb..7b8bdeb 100644 (file)
@@ -26,9 +26,17 @@ struct ipc_handler {
        bool var_len;
        size_t data_len;
 };
+
+struct service_handler {
+       const struct ipc_handler *handler;
+       uint8_t size;
+};
+
 void ipc_init(void);
 void ipc_cleanup(void);
 GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb);
+int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
+                                               const void *buf, ssize_t len);
 
 void ipc_send_rsp(uint8_t service_id, uint8_t opcode, uint8_t status);
 void ipc_send_rsp_full(uint8_t service_id, uint8_t opcode, uint16_t len,