diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2013-12-31 12:39:09 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2014-01-07 13:37:53 +0200 |
commit | 1829216bab0483720c22e7672f72846c4fca31d3 (patch) | |
tree | eccd93fba58bb6302e551bc330290da0ea12971e /android/ipc.c | |
parent | 294bfb100148c7554f0c3edf51f5bbf494b8f3c6 (diff) | |
download | bluez-1829216bab0483720c22e7672f72846c4fca31d3.tar.gz |
android/ipc: Add message handling for audio IPC
This adds audio_ipc_register and audio_ipc_unregister and adapt
ipc_handle_msg to be able to handle audio services messages.
Diffstat (limited to 'android/ipc.c')
-rw-r--r-- | android/ipc.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/android/ipc.c b/android/ipc.c index 8a9124829..14999627b 100644 --- a/android/ipc.c +++ b/android/ipc.c @@ -40,56 +40,45 @@ #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: |