All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] android: Refactor IPC init
@ 2014-02-28 13:09 Szymon Janc
  2014-02-28 13:09 ` [PATCH 2/6] android: Add support for registering disconnect callback in IPC Szymon Janc
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This allows to pass socket path and max service ID while initializaing
IPC. This is first step to allow use it both for BT and Audio HALs.
---
 android/a2dp.c      |  27 +++++++----
 android/a2dp.h      |   2 +-
 android/avrcp.c     |  52 +++++++++++----------
 android/avrcp.h     |   2 +-
 android/bluetooth.c | 113 +++++++++++++++++++++++++-------------------
 android/bluetooth.h |   2 +-
 android/handsfree.c |  65 ++++++++++++++------------
 android/handsfree.h |   2 +-
 android/hidhost.c   |  61 +++++++++++++-----------
 android/hidhost.h   |   2 +-
 android/ipc.c       | 132 +++++++++++++++++++++++++++++++++-------------------
 android/ipc.h       |  24 ++++++----
 android/main.c      |  41 +++++++++-------
 android/pan.c       |  32 +++++++------
 android/pan.h       |   2 +-
 android/socket.c    |  26 +++++++----
 android/socket.h    |   2 +-
 android/test-ipc.c  |  44 ++++++++++++------
 18 files changed, 374 insertions(+), 257 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 5d7dc78..b05d4bd 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -39,9 +39,9 @@
 #include "lib/sdp_lib.h"
 #include "profiles/audio/a2dp-codecs.h"
 #include "src/log.h"
-#include "a2dp.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "a2dp.h"
 #include "utils.h"
 #include "bluetooth.h"
 #include "avdtp.h"
@@ -63,6 +63,8 @@ static uint32_t record_id = 0;
 static guint audio_retry_id = 0;
 static bool audio_retrying = false;
 
+static struct ipc *hal_ipc = NULL;
+
 struct a2dp_preset {
 	void *data;
 	int8_t len;
@@ -226,8 +228,8 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
 	bdaddr2android(&dev->dst, ev.bdaddr);
 	ev.state = state;
 
-	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, sizeof(ev),
-									&ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE,
+							sizeof(ev), &ev);
 
 	if (state != HAL_A2DP_STATE_DISCONNECTED)
 		return;
@@ -253,8 +255,8 @@ static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
 	bdaddr2android(&setup->dev->dst, ev.bdaddr);
 	ev.state = state;
 
-	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE, sizeof(ev),
-									&ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE,
+							sizeof(ev), &ev);
 }
 
 static void disconnect_cb(void *user_data)
@@ -597,7 +599,7 @@ static void bt_a2dp_connect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status);
 }
 
 static void bt_a2dp_disconnect(const void *buf, uint16_t len)
@@ -631,7 +633,8 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
+									status);
 }
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -1540,7 +1543,7 @@ retry:
 						audio_disconnected);
 }
 
-bool bt_a2dp_register(const bdaddr_t *addr)
+bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	GError *err = NULL;
 	sdp_record_t *rec;
@@ -1573,7 +1576,9 @@ bool bt_a2dp_register(const bdaddr_t *addr)
 	}
 	record_id = rec->handle;
 
-	ipc_register(HAL_SERVICE_ID_A2DP, cmd_handlers,
+	hal_ipc = ipc;
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
 	bt_audio_register(audio_disconnected);
@@ -1600,7 +1605,9 @@ void bt_a2dp_unregister(void)
 	g_slist_free_full(devices, a2dp_device_free);
 	devices = NULL;
 
-	ipc_unregister(HAL_SERVICE_ID_A2DP);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP);
+	hal_ipc = NULL;
+
 	audio_ipc_unregister();
 
 	bt_adapter_remove_record(record_id);
diff --git a/android/a2dp.h b/android/a2dp.h
index e626e41..b41a178 100644
--- a/android/a2dp.h
+++ b/android/a2dp.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_a2dp_register(const bdaddr_t *addr);
+bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_a2dp_unregister(void);
diff --git a/android/avrcp.c b/android/avrcp.c
index 8ff70b4..678c321 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -33,12 +33,12 @@
 #include "lib/sdp.h"
 #include "lib/sdp_lib.h"
 #include "src/log.h"
-#include "bluetooth.h"
 #include "avctp.h"
-#include "avrcp.h"
 #include "avrcp-lib.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "bluetooth.h"
+#include "avrcp.h"
 
 #define L2CAP_PSM_AVCTP 0x17
 
@@ -51,6 +51,7 @@ static bdaddr_t adapter_addr;
 static uint32_t record_id = 0;
 static GSList *devices = NULL;
 static GIOChannel *server = NULL;
+static struct ipc *hal_ipc = NULL;
 
 struct avrcp_device {
 	bdaddr_t	dst;
@@ -62,79 +63,79 @@ static void handle_get_play_status(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_GET_PLAY_STATUS, HAL_STATUS_FAILED);
 }
 
 static void handle_list_player_attrs(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_LIST_PLAYER_ATTRS, HAL_STATUS_FAILED);
 }
 
 static void handle_list_player_values(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_LIST_PLAYER_VALUES, HAL_STATUS_FAILED);
 }
 
 static void handle_get_player_attrs(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_GET_PLAYER_ATTRS, HAL_STATUS_FAILED);
 }
 
 static void handle_get_player_attrs_text(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT, HAL_STATUS_FAILED);
 }
 
 static void handle_get_player_values_text(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, HAL_STATUS_FAILED);
 }
 
 static void handle_get_element_attrs_text(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, HAL_STATUS_FAILED);
 }
 
 static void handle_set_player_attrs_value(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE, HAL_STATUS_FAILED);
 }
 
 static void handle_register_notification(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_REGISTER_NOTIFICATION,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_OP_AVRCP_REGISTER_NOTIFICATION, HAL_STATUS_FAILED);
 }
 
 static void handle_set_volume(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
 							HAL_STATUS_FAILED);
 }
 
@@ -363,7 +364,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	DBG("%s connected", address);
 }
 
-bool bt_avrcp_register(const bdaddr_t *addr)
+bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	GError *err = NULL;
 	sdp_record_t *rec;
@@ -396,7 +397,9 @@ bool bt_avrcp_register(const bdaddr_t *addr)
 	}
 	record_id = rec->handle;
 
-	ipc_register(HAL_SERVICE_ID_AVRCP, cmd_handlers,
+	hal_ipc = ipc;
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_AVRCP, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
 	return true;
@@ -415,7 +418,8 @@ void bt_avrcp_unregister(void)
 	g_slist_free_full(devices, avrcp_device_free);
 	devices = NULL;
 
-	ipc_unregister(HAL_SERVICE_ID_AVRCP);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_AVRCP);
+	hal_ipc = NULL;
 
 	bt_adapter_remove_record(record_id);
 	record_id = 0;
diff --git a/android/avrcp.h b/android/avrcp.h
index 1fcd953..3dcffeb 100644
--- a/android/avrcp.h
+++ b/android/avrcp.h
@@ -21,7 +21,7 @@
  *
  */
 
-bool bt_avrcp_register(const bdaddr_t *addr);
+bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_avrcp_unregister(void);
 
 void bt_avrcp_connect(const bdaddr_t *dst);
diff --git a/android/bluetooth.c b/android/bluetooth.c
index ac4c213..26493f7 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -145,6 +145,8 @@ static GSList *cached_devices = NULL;
 /* This list contains addresses which are asked for records */
 static GSList *browse_reqs;
 
+static struct ipc *hal_ipc = NULL;
+
 static void store_adapter_config(void)
 {
 	GKeyFile *key_file;
@@ -390,8 +392,8 @@ static  void send_adapter_property(uint8_t type, uint16_t len, const void *val)
 	ev->props[0].len = len;
 	memcpy(ev->props[0].val, val, len);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_PROPS_CHANGED,
-							sizeof(buf), buf);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf);
 }
 
 static void adapter_name_changed(const uint8_t *name)
@@ -440,8 +442,8 @@ static void powered_changed(void)
 
 	DBG("%u", ev.state);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_STATE_CHANGED,
-							sizeof(ev), &ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_STATE_CHANGED, sizeof(ev), &ev);
 }
 
 static uint8_t settings2scan_mode(void)
@@ -594,8 +596,8 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 	ev.state = state;
 	bdaddr2android(addr, ev.bdaddr);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_BOND_STATE_CHANGED,
-							sizeof(ev), &ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev);
 }
 
 static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
@@ -647,8 +649,8 @@ static  void send_device_property(const bdaddr_t *bdaddr, uint8_t type,
 	ev->props[0].len = len;
 	memcpy(ev->props[0].val, val, len);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_REMOTE_DEVICE_PROPS,
-							sizeof(buf), buf);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), buf);
 }
 
 static void send_device_uuids_notif(struct device *dev)
@@ -883,7 +885,7 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
 	hal_ev.class_of_dev = dev->class;
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
 						sizeof(hal_ev), &hal_ev);
 }
 
@@ -901,7 +903,7 @@ static void send_ssp_request(const bdaddr_t *addr, uint8_t variant,
 	ev.pairing_variant = variant;
 	ev.passkey = passkey;
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST,
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST,
 							sizeof(ev), &ev);
 }
 
@@ -1010,7 +1012,7 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
 		cp.state = HAL_DISCOVERY_STATE_STOPPED;
 	}
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH,
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
 			HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(cp), &cp);
 }
 
@@ -1106,8 +1108,8 @@ static void update_new_device(struct device *dev, int8_t rssi,
 		ev->num_props++;
 	}
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND, size,
-									buf);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND,
+								size, buf);
 }
 
 static void update_device(struct device *dev, int8_t rssi,
@@ -1147,7 +1149,7 @@ static void update_device(struct device *dev, int8_t rssi,
 	}
 
 	if (ev->num_props)
-		ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH,
+		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
 					HAL_EV_REMOTE_DEVICE_PROPS, size, buf);
 }
 
@@ -1259,8 +1261,8 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
 	hal_ev.state = HAL_ACL_STATE_CONNECTED;
 	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ACL_STATE_CHANGED,
-						sizeof(hal_ev), &hal_ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
 }
 
 static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
@@ -1279,8 +1281,8 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
 	hal_ev.state = HAL_ACL_STATE_DISCONNECTED;
 	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ACL_STATE_CHANGED,
-						sizeof(hal_ev), &hal_ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
 }
 
 static uint8_t status_mgmt2hal(uint8_t mgmt)
@@ -1502,8 +1504,8 @@ static uint8_t get_adapter_uuids(void)
 		p += sizeof(uint128_t);
 	}
 
-	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_PROPS_CHANGED,
-							sizeof(buf), ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev);
 
 	return HAL_STATUS_SUCCESS;
 }
@@ -2387,7 +2389,8 @@ static void handle_get_adapter_prop_cmd(const void *buf, uint16_t len)
 		error("Failed to get adapter property (type %u status %u)",
 							cmd->type, status);
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP,
+									status);
 }
 
 static void get_adapter_properties(void)
@@ -2538,7 +2541,8 @@ static void handle_set_adapter_prop_cmd(const void *buf, uint16_t len)
 		error("Failed to set adapter property (type %u status %u)",
 							cmd->type, status);
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP,
+									status);
 }
 
 static void pair_device_complete(uint8_t status, uint16_t length,
@@ -2579,7 +2583,8 @@ static void handle_create_bond_cmd(const void *buf, uint16_t len)
 						HAL_BOND_STATE_BONDING);
 
 fail:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND,
+									status);
 }
 
 static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
@@ -2597,7 +2602,8 @@ static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
 	else
 		status = HAL_STATUS_FAILED;
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND,
+									status);
 }
 
 static void unpair_device_complete(uint8_t status, uint16_t length,
@@ -2631,7 +2637,8 @@ static void handle_remove_bond_cmd(const void *buf, uint16_t len)
 	else
 		status = HAL_STATUS_FAILED;
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND,
+									status);
 }
 
 static void handle_pin_reply_cmd(const void *buf, uint16_t len)
@@ -2682,7 +2689,8 @@ static void handle_pin_reply_cmd(const void *buf, uint16_t len)
 
 	status = HAL_STATUS_SUCCESS;
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY,
+									status);
 }
 
 static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
@@ -2770,7 +2778,8 @@ static void handle_ssp_reply_cmd(const void *buf, uint16_t len)
 		break;
 	}
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY,
+									status);
 }
 
 static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
@@ -2783,8 +2792,8 @@ static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
 
 	status = browse_remote_sdp(&addr);
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICES,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+					HAL_OP_GET_REMOTE_SERVICES, status);
 }
 
 static uint8_t get_device_uuids(struct device *dev)
@@ -2907,7 +2916,7 @@ static void handle_enable_cmd(const void *buf, uint16_t len)
 
 	status = HAL_STATUS_SUCCESS;
 reply:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
 }
 
 static void handle_disable_cmd(const void *buf, uint16_t len)
@@ -2929,15 +2938,15 @@ static void handle_disable_cmd(const void *buf, uint16_t len)
 
 	status = HAL_STATUS_SUCCESS;
 reply:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
 }
 
 static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
 {
 	get_adapter_properties();
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS,
-							HAL_STATUS_SUCCESS);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_OP_GET_ADAPTER_PROPS, HAL_STATUS_SUCCESS);
 }
 
 static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
@@ -2960,8 +2969,8 @@ static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROPS,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+					HAL_OP_GET_REMOTE_DEVICE_PROPS, status);
 }
 
 static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
@@ -3017,8 +3026,8 @@ static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
 							cmd->type, status);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROP,
-								status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+					HAL_OP_GET_REMOTE_DEVICE_PROP, status);
 }
 
 static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val,
@@ -3088,8 +3097,8 @@ static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len)
 							cmd->type, status);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_REMOTE_DEVICE_PROP,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+					HAL_OP_SET_REMOTE_DEVICE_PROP, status);
 }
 
 static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
@@ -3098,8 +3107,8 @@ static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
 
 	error("get_remote_service_record not supported");
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICE_REC,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_OP_GET_REMOTE_SERVICE_REC, HAL_STATUS_FAILED);
 }
 
 static void handle_start_discovery_cmd(const void *buf, uint16_t len)
@@ -3123,7 +3132,8 @@ static void handle_start_discovery_cmd(const void *buf, uint16_t len)
 
 	status = HAL_STATUS_SUCCESS;
 reply:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY,
+									status);
 }
 
 static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
@@ -3148,7 +3158,8 @@ static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 reply:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY,
+									status);
 }
 
 static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
@@ -3181,7 +3192,8 @@ static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
 	close(fd);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF,
+									status);
 }
 
 static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
@@ -3198,7 +3210,7 @@ static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
 
 	/* TODO */
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
 							HAL_STATUS_FAILED);
 }
 
@@ -3216,7 +3228,7 @@ static void handle_le_test_mode_cmd(const void *buf, uint16_t len)
 
 	/* TODO */
 
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
 							HAL_STATUS_FAILED);
 }
 
@@ -3272,11 +3284,13 @@ static const struct ipc_handler cmd_handlers[] = {
 	{ handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) },
 };
 
-void bt_bluetooth_register(void)
+void bt_bluetooth_register(struct ipc *ipc)
 {
 	DBG("");
 
-	ipc_register(HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
+	hal_ipc = ipc;
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 }
 
@@ -3290,5 +3304,6 @@ void bt_bluetooth_unregister(void)
 	g_slist_free_full(cached_devices, (GDestroyNotify) free_device);
 	cached_devices = NULL;
 
-	ipc_unregister(HAL_SERVICE_ID_CORE);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
+	hal_ipc = NULL;
 }
diff --git a/android/bluetooth.h b/android/bluetooth.h
index 8ab34f6..fbc850d 100644
--- a/android/bluetooth.h
+++ b/android/bluetooth.h
@@ -31,7 +31,7 @@ void bt_bluetooth_cleanup(void);
 
 void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
 
-void bt_bluetooth_register(void);
+void bt_bluetooth_register(struct ipc *ipc);
 void bt_bluetooth_unregister(void);
 
 int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint);
diff --git a/android/handsfree.c b/android/handsfree.c
index 60bff91..ef8c776 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -38,11 +38,11 @@
 #include "src/uuid-helper.h"
 #include "src/shared/hfp.h"
 #include "btio/btio.h"
+#include "hal-msg.h"
+#include "ipc.h"
 #include "handsfree.h"
 #include "bluetooth.h"
 #include "src/log.h"
-#include "hal-msg.h"
-#include "ipc.h"
 #include "utils.h"
 
 #define HFP_AG_CHANNEL 13
@@ -56,6 +56,7 @@ static struct {
 
 static bdaddr_t adapter_addr;
 static uint32_t record_id = 0;
+static struct ipc *hal_ipc = NULL;
 
 static GIOChannel *server = NULL;
 
@@ -75,8 +76,8 @@ static void device_set_state(uint8_t state)
 	bdaddr2android(&device.bdaddr, ev.bdaddr);
 	ev.state = state;
 
-	ipc_send_notif(HAL_SERVICE_ID_HANDSFREE, HAL_EV_HANDSFREE_CONN_STATE,
-							sizeof(ev), &ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+				HAL_EV_HANDSFREE_CONN_STATE, sizeof(ev), &ev);
 }
 
 static void device_init(const bdaddr_t *bdaddr)
@@ -281,8 +282,8 @@ static void handle_connect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+					HAL_OP_HANDSFREE_CONNECT, status);
 }
 
 static void handle_disconnect(const void *buf, uint16_t len)
@@ -317,23 +318,23 @@ static void handle_disconnect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_DISCONNECT,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+					HAL_OP_HANDSFREE_DISCONNECT, status);
 }
 
 static void handle_connect_audio(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT_AUDIO,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_CONNECT_AUDIO, HAL_STATUS_FAILED);
 }
 
 static void handle_disconnect_audio(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 			HAL_OP_HANDSFREE_DISCONNECT_AUDIO, HAL_STATUS_FAILED);
 }
 
@@ -341,31 +342,31 @@ static void handle_start_vr(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_START_VR,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+				HAL_OP_HANDSFREE_START_VR, HAL_STATUS_FAILED);
 }
 
 static void handle_stop_vr(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_STOP_VR,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+				HAL_OP_HANDSFREE_STOP_VR, HAL_STATUS_FAILED);
 }
 
 static void handle_volume_control(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_VOLUME_CONTROL,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_VOLUME_CONTROL, HAL_STATUS_FAILED);
 }
 
 static void handle_device_status_notif(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
 					HAL_STATUS_FAILED);
 }
@@ -374,23 +375,23 @@ static void handle_cops(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_COPS_RESPONSE,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_FAILED);
 }
 
 static void handle_cind(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CIND_RESPONSE,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_FAILED);
 }
 
 static void handle_formatted_at_resp(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
 					HAL_STATUS_FAILED);
 }
@@ -399,23 +400,23 @@ static void handle_at_resp(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_AT_RESPONSE,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_AT_RESPONSE, HAL_STATUS_FAILED);
 }
 
 static void handle_clcc_resp(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CLCC_RESPONSE,
-							HAL_STATUS_FAILED);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+			HAL_OP_HANDSFREE_CLCC_RESPONSE, HAL_STATUS_FAILED);
 }
 
 static void handle_phone_state_change(const void *buf, uint16_t len)
 {
 	DBG("");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_OP_HANDSFREE_PHONE_STATE_CHANGE,
 					HAL_STATUS_FAILED);
 }
@@ -530,7 +531,7 @@ static sdp_record_t *handsfree_ag_record(void)
 	return record;
 }
 
-bool bt_handsfree_register(const bdaddr_t *addr)
+bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	sdp_record_t *rec;
 	GError *err = NULL;
@@ -563,7 +564,8 @@ bool bt_handsfree_register(const bdaddr_t *addr)
 	}
 	record_id = rec->handle;
 
-	ipc_register(HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
+	hal_ipc = ipc;
+	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
 	return true;
@@ -580,7 +582,8 @@ void bt_handsfree_unregister(void)
 {
 	DBG("");
 
-	ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE);
+	hal_ipc = NULL;
 
 	if (server) {
 		g_io_channel_shutdown(server, TRUE, NULL);
diff --git a/android/handsfree.h b/android/handsfree.h
index e3fdd70..3ede819 100644
--- a/android/handsfree.h
+++ b/android/handsfree.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_handsfree_register(const bdaddr_t *addr);
+bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_handsfree_unregister(void);
diff --git a/android/hidhost.c b/android/hidhost.c
index fd5ea4d..0c6eb7d 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -81,6 +81,8 @@ static GIOChannel *ctrl_io = NULL;
 static GIOChannel *intr_io = NULL;
 static GSList *devices = NULL;
 
+static struct ipc *hal_ipc = NULL;
+
 struct hid_device {
 	bdaddr_t	dst;
 	uint8_t		state;
@@ -303,8 +305,8 @@ static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
 	bdaddr2android(&dev->dst, ev.bdaddr);
 	ev.state = state;
 
-	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_CONN_STATE,
-							sizeof(ev), &ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev);
 }
 
 static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
@@ -362,8 +364,8 @@ static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
 		ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
 	}
 
-	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_PROTO_MODE,
-							sizeof(ev), &ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev);
 }
 
 static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
@@ -405,8 +407,8 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
 	}
 
 send:
-	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_GET_REPORT,
-								ev_len, ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev);
 	g_free(ev);
 }
 
@@ -430,9 +432,8 @@ static void bt_hid_notify_virtual_unplug(struct hid_device *dev,
 		ev.status = HAL_HIDHOST_STATUS_OK;
 	}
 
-	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_VIRTUAL_UNPLUG,
-							sizeof(ev), &ev);
-
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HIDHOST_VIRTUAL_UNPLUG, sizeof(ev), &ev);
 }
 
 static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
@@ -515,8 +516,8 @@ static void bt_hid_set_info(struct hid_device *dev)
 	memset(ev.descr, 0, sizeof(ev.descr));
 	memcpy(ev.descr, dev->rd_data, ev.descr_len);
 
-	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO, sizeof(ev),
-									&ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
+							sizeof(ev), &ev);
 }
 
 static int uhid_create(struct hid_device *dev)
@@ -806,7 +807,8 @@ static void bt_hid_connect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
+									status);
 }
 
 static void bt_hid_disconnect(const void *buf, uint16_t len)
@@ -841,7 +843,8 @@ static void bt_hid_disconnect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT,
+									status);
 }
 
 static void bt_hid_virtual_unplug(const void *buf, uint16_t len)
@@ -894,8 +897,8 @@ static void bt_hid_virtual_unplug(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_VIRTUAL_UNPLUG,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+					HAL_OP_HIDHOST_VIRTUAL_UNPLUG, status);
 }
 
 static void bt_hid_info(const void *buf, uint16_t len)
@@ -914,7 +917,7 @@ static void bt_hid_info(const void *buf, uint16_t len)
 	 * once device is created with HID internals. */
 	DBG("Not supported");
 
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
 							HAL_STATUS_UNSUPPORTED);
 }
 
@@ -964,8 +967,8 @@ static void bt_hid_get_protocol(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_PROTOCOL,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+					HAL_OP_HIDHOST_GET_PROTOCOL, status);
 }
 
 static void bt_hid_set_protocol(const void *buf, uint16_t len)
@@ -1014,8 +1017,8 @@ static void bt_hid_set_protocol(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_PROTOCOL,
-									status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
+					HAL_OP_HIDHOST_SET_PROTOCOL, status);
 }
 
 static void bt_hid_get_report(const void *buf, uint16_t len)
@@ -1081,7 +1084,8 @@ static void bt_hid_get_report(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT,
+									status);
 }
 
 static void bt_hid_set_report(const void *buf, uint16_t len)
@@ -1158,7 +1162,8 @@ static void bt_hid_set_report(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT,
+									status);
 }
 
 static void bt_hid_send_data(const void *buf, uint16_t len)
@@ -1224,7 +1229,8 @@ static void bt_hid_send_data(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA,
+									status);
 }
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -1323,7 +1329,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	}
 }
 
-bool bt_hid_register(const bdaddr_t *addr)
+bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	GError *err = NULL;
 
@@ -1358,7 +1364,9 @@ bool bt_hid_register(const bdaddr_t *addr)
 		return false;
 	}
 
-	ipc_register(HAL_SERVICE_ID_HIDHOST, cmd_handlers,
+	hal_ipc = ipc;
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_HIDHOST, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
 	return true;
@@ -1383,5 +1391,6 @@ void bt_hid_unregister(void)
 		intr_io = NULL;
 	}
 
-	ipc_unregister(HAL_SERVICE_ID_HIDHOST);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HIDHOST);
+	hal_ipc = NULL;
 }
diff --git a/android/hidhost.h b/android/hidhost.h
index 5c3c801..1017195 100644
--- a/android/hidhost.h
+++ b/android/hidhost.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_hid_register(const bdaddr_t *addr);
+bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_hid_unregister(void);
diff --git a/android/ipc.c b/android/ipc.c
index 4a3a60d..3d6e2a3 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -40,13 +40,19 @@
 #include "ipc.h"
 #include "src/log.h"
 
-static struct service_handler services[HAL_SERVICE_ID_MAX + 1];
+struct ipc {
+	struct service_handler *services;
+	int service_max;
 
-static GIOChannel *cmd_io = NULL;
-static GIOChannel *notif_io = NULL;
+	const char *path;
+	size_t size;
 
-static guint cmd_watch = 0;
-static guint notif_watch = 0;
+	GIOChannel *cmd_io;
+	guint cmd_watch;
+
+	GIOChannel *notif_io;
+	guint notif_watch;
+};
 
 int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 						const void *buf, ssize_t len)
@@ -103,6 +109,8 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
+	struct ipc *ipc = user_data;
+
 	char buf[BLUEZ_HAL_MTU];
 	ssize_t ret;
 	int fd, err;
@@ -121,7 +129,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 		goto fail;
 	}
 
-	err = ipc_handle_msg(services, HAL_SERVICE_ID_MAX, buf, ret);
+	err = ipc_handle_msg(ipc->services, ipc->service_max, buf, ret);
 	if (err < 0) {
 		error("IPC: failed to handle message, terminating (%s)",
 							strerror(-err));
@@ -181,6 +189,8 @@ GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
 static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
+	struct ipc *ipc = user_data;
+
 	DBG("");
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
@@ -191,11 +201,11 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
 
 	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 
-	notif_watch = g_io_add_watch(io, cond, notif_watch_cb, NULL);
+	ipc->notif_watch = g_io_add_watch(io, cond, notif_watch_cb, ipc);
 
 	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 
-	cmd_watch = g_io_add_watch(cmd_io, cond, cmd_watch_cb, NULL);
+	ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc);
 
 	info("IPC: successfully connected");
 
@@ -205,6 +215,8 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
 static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
+	struct ipc *ipc = user_data;
+
 	DBG("");
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
@@ -213,45 +225,62 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
 		return FALSE;
 	}
 
-	notif_io = ipc_connect(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						notif_connect_cb, NULL);
-	if (!notif_io)
+	ipc->notif_io = ipc_connect(ipc->path, ipc->size, notif_connect_cb,
+									ipc);
+	if (!ipc->notif_io)
 		raise(SIGTERM);
 
 	return FALSE;
 }
 
-void ipc_init(void)
+struct ipc *ipc_init(const char *path, size_t size, int max_service_id)
 {
-	cmd_io = ipc_connect(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						cmd_connect_cb, NULL);
-	if (!cmd_io)
-		raise(SIGTERM);
+	struct ipc *ipc;
+
+	ipc = g_new0(struct ipc, 1);
+
+	ipc->services = g_new0(struct service_handler, max_service_id + 1);
+	ipc->service_max = max_service_id;
+
+	ipc->path = path;
+	ipc->size = size;
+
+	ipc->cmd_io = ipc_connect(path, size, cmd_connect_cb, ipc);
+	if (!ipc->cmd_io) {
+		g_free(ipc->services);
+		g_free(ipc);
+		return NULL;
+	}
+
+	return ipc;
 }
 
-void ipc_cleanup(void)
+void ipc_cleanup(struct ipc *ipc)
 {
-	if (cmd_watch) {
-		g_source_remove(cmd_watch);
-		cmd_watch = 0;
+	if (ipc->cmd_watch) {
+		g_source_remove(ipc->cmd_watch);
+		ipc->cmd_watch = 0;
 	}
 
-	if (cmd_io) {
-		g_io_channel_shutdown(cmd_io, TRUE, NULL);
-		g_io_channel_unref(cmd_io);
-		cmd_io = NULL;
+	if (ipc->cmd_io) {
+		g_io_channel_shutdown(ipc->cmd_io, TRUE, NULL);
+		g_io_channel_unref(ipc->cmd_io);
+		ipc->cmd_io = NULL;
 	}
 
-	if (notif_watch) {
-		g_source_remove(notif_watch);
-		notif_watch = 0;
+	if (ipc->notif_watch) {
+		g_source_remove(ipc->notif_watch);
+		ipc->notif_watch = 0;
 	}
 
-	if (notif_io) {
-		g_io_channel_shutdown(notif_io, TRUE, NULL);
-		g_io_channel_unref(notif_io);
-		notif_io = NULL;
+	if (ipc->notif_io) {
+		g_io_channel_shutdown(ipc->notif_io, TRUE, NULL);
+		g_io_channel_unref(ipc->notif_io);
+		ipc->notif_io = NULL;
 	}
+
+	g_free(ipc->services);
+	g_free(ipc);
 }
 
 void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
@@ -299,12 +328,13 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 	}
 }
 
-void ipc_send_rsp(uint8_t service_id, uint8_t opcode, uint8_t status)
+void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+								uint8_t status)
 {
 	struct hal_status s;
 	int sk;
 
-	sk = g_io_channel_unix_get_fd(cmd_io);
+	sk = g_io_channel_unix_get_fd(ipc->cmd_io);
 
 	if (status == HAL_STATUS_SUCCESS) {
 		ipc_send(sk, service_id, opcode, 0, NULL, -1);
@@ -316,32 +346,38 @@ void ipc_send_rsp(uint8_t service_id, uint8_t opcode, uint8_t status)
 	ipc_send(sk, service_id, HAL_OP_STATUS, sizeof(s), &s, -1);
 }
 
-void ipc_send_rsp_full(uint8_t service_id, uint8_t opcode, uint16_t len,
-							void *param, int fd)
+void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+					uint16_t len, void *param, int fd)
 {
-	ipc_send(g_io_channel_unix_get_fd(cmd_io), service_id, opcode, len,
+	ipc_send(g_io_channel_unix_get_fd(ipc->cmd_io), service_id, opcode, len,
 								param, fd);
 }
 
-void ipc_send_notif(uint8_t service_id, uint8_t opcode,  uint16_t len,
-								void *param)
+void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+						uint16_t len, void *param)
 {
-	if (!notif_io)
+	if (!ipc || !ipc->notif_io)
 		return;
 
-	ipc_send(g_io_channel_unix_get_fd(notif_io), service_id, opcode, len,
-								param, -1);
+	ipc_send(g_io_channel_unix_get_fd(ipc->notif_io), service_id, opcode,
+								len, param, -1);
 }
 
-void ipc_register(uint8_t service, const struct ipc_handler *handlers,
-								uint8_t size)
+void ipc_register(struct ipc *ipc, uint8_t service,
+			const struct ipc_handler *handlers, uint8_t size)
 {
-	services[service].handler = handlers;
-	services[service].size = size;
+	if (service > ipc->service_max)
+		return;
+
+	ipc->services[service].handler = handlers;
+	ipc->services[service].size = size;
 }
 
-void ipc_unregister(uint8_t service)
+void ipc_unregister(struct ipc *ipc, uint8_t service)
 {
-	services[service].handler = NULL;
-	services[service].size = 0;
+	if (service > ipc->service_max)
+		return;
+
+	ipc->services[service].handler = NULL;
+	ipc->services[service].size = 0;
 }
diff --git a/android/ipc.h b/android/ipc.h
index cfa4018..601301c 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -32,20 +32,24 @@ struct service_handler {
 	uint8_t size;
 };
 
-void ipc_init(void);
-void ipc_cleanup(void);
+struct ipc;
+
+struct ipc *ipc_init(const char *path, size_t size, int max_service_id);
+void ipc_cleanup(struct ipc *ipc);
+
 GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
 							void *user_data);
 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,
-							void *param, int fd);
-void ipc_send_notif(uint8_t service_id, uint8_t opcode,  uint16_t len,
-								void *param);
+void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+								uint8_t status);
+void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+					uint16_t len, void *param, int fd);
+void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
+						uint16_t len, void *param);
 void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 							void *param, int fd);
-void ipc_register(uint8_t service, const struct ipc_handler *handlers,
-								uint8_t size);
-void ipc_unregister(uint8_t service);
+void ipc_register(struct ipc *ipc, uint8_t service,
+			const struct ipc_handler *handlers, uint8_t size);
+void ipc_unregister(struct ipc *ipc, uint8_t service);
diff --git a/android/main.c b/android/main.c
index aca6351..9f22486 100644
--- a/android/main.c
+++ b/android/main.c
@@ -48,11 +48,11 @@
 
 #include "lib/bluetooth.h"
 
+#include "ipc.h"
 #include "bluetooth.h"
 #include "socket.h"
 #include "hidhost.h"
 #include "hal-msg.h"
-#include "ipc.h"
 #include "a2dp.h"
 #include "pan.h"
 #include "avrcp.h"
@@ -67,6 +67,8 @@ static bdaddr_t adapter_bdaddr;
 
 static GMainLoop *event_loop;
 
+static struct ipc *hal_ipc = NULL;
+
 static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
 
 static void service_register(const void *buf, uint16_t len)
@@ -81,43 +83,43 @@ static void service_register(const void *buf, uint16_t len)
 
 	switch (m->service_id) {
 	case HAL_SERVICE_ID_BLUETOOTH:
-		bt_bluetooth_register();
+		bt_bluetooth_register(hal_ipc);
 
 		break;
 	case HAL_SERVICE_ID_SOCKET:
-		bt_socket_register(&adapter_bdaddr);
+		bt_socket_register(hal_ipc, &adapter_bdaddr);
 
 		break;
 	case HAL_SERVICE_ID_HIDHOST:
-		if (!bt_hid_register(&adapter_bdaddr)) {
+		if (!bt_hid_register(hal_ipc, &adapter_bdaddr)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_A2DP:
-		if (!bt_a2dp_register(&adapter_bdaddr)) {
+		if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_PAN:
-		if (!bt_pan_register(&adapter_bdaddr)) {
+		if (!bt_pan_register(hal_ipc, &adapter_bdaddr)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_AVRCP:
-		if (!bt_avrcp_register(&adapter_bdaddr)) {
+		if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_HANDSFREE:
-		if (!bt_handsfree_register(&adapter_bdaddr)) {
+		if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
@@ -136,7 +138,8 @@ static void service_register(const void *buf, uint16_t len)
 	info("Service ID=%u registered", m->service_id);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+								status);
 }
 
 static void service_unregister(const void *buf, uint16_t len)
@@ -186,7 +189,8 @@ static void service_unregister(const void *buf, uint16_t len)
 	info("Service ID=%u unregistered", m->service_id);
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+								status);
 }
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -240,7 +244,15 @@ static void adapter_ready(int err, const bdaddr_t *addr)
 
 	info("Adapter initialized");
 
-	ipc_init();
+	hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
+							HAL_SERVICE_ID_MAX);
+	if (!hal_ipc) {
+		error("Failed to initialize IPC");
+		exit(EXIT_FAILURE);
+	}
+
+	ipc_register(hal_ipc, HAL_SERVICE_ID_CORE, cmd_handlers,
+						G_N_ELEMENTS(cmd_handlers));
 }
 
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
@@ -464,9 +476,6 @@ int main(int argc, char *argv[])
 	/* Use params: mtu = 0, flags = 0 */
 	start_sdp_server(0, 0);
 
-	ipc_register(HAL_SERVICE_ID_CORE, cmd_handlers,
-						G_N_ELEMENTS(cmd_handlers));
-
 	DBG("Entering main loop");
 
 	event_loop = g_main_loop_new(NULL, FALSE);
@@ -480,12 +489,12 @@ int main(int argc, char *argv[])
 
 	cleanup_services();
 
-	ipc_cleanup();
 	stop_sdp_server();
 	bt_bluetooth_cleanup();
 	g_main_loop_unref(event_loop);
 
-	ipc_unregister(HAL_SERVICE_ID_CORE);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
+	ipc_cleanup(hal_ipc);
 
 	info("Exit");
 
diff --git a/android/pan.c b/android/pan.c
index cfc03bc..b4a3494 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -49,11 +49,11 @@
 #include "profiles/network/bnep.h"
 #include "src/log.h"
 
-#include "pan.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "utils.h"
 #include "bluetooth.h"
+#include "pan.h"
 
 #define SVC_HINT_NETWORKING 0x02
 
@@ -64,6 +64,7 @@
 static bdaddr_t adapter_addr;
 GSList *devices = NULL;
 uint8_t local_role = HAL_PAN_ROLE_NONE;
+static struct ipc *hal_ipc = NULL;
 
 struct pan_device {
 	char		iface[16];
@@ -247,8 +248,8 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
 	ev.remote_role = dev->role;
 	ev.status = HAL_STATUS_SUCCESS;
 
-	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
-									&ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE,
+							sizeof(ev), &ev);
 	if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
 		pan_device_remove(dev);
 }
@@ -270,8 +271,8 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
 	else
 		memcpy(ev.name, dev->iface, sizeof(dev->iface));
 
-	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE, sizeof(ev),
-									&ev);
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE,
+							sizeof(ev), &ev);
 }
 
 static void bnep_disconn_cb(void *data)
@@ -414,7 +415,7 @@ static void bt_pan_connect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
 }
 
 static void bt_pan_disconnect(const void *buf, uint16_t len)
@@ -444,7 +445,8 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT,
+									status);
 }
 
 static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond,
@@ -676,7 +678,7 @@ static void bt_pan_enable(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 reply:
-	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
 }
 
 static void bt_pan_get_role(const void *buf, uint16_t len)
@@ -686,8 +688,8 @@ static void bt_pan_get_role(const void *buf, uint16_t len)
 	DBG("");
 
 	rsp.local_role = local_role;
-	ipc_send_rsp_full(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, sizeof(rsp),
-								&rsp, -1);
+	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE,
+							sizeof(rsp), &rsp, -1);
 }
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -776,7 +778,7 @@ static sdp_record_t *pan_record(void)
 	return record;
 }
 
-bool bt_pan_register(const bdaddr_t *addr)
+bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	sdp_record_t *rec;
 	int err;
@@ -813,7 +815,9 @@ bool bt_pan_register(const bdaddr_t *addr)
 	}
 
 	nap_dev.record_id = rec->handle;
-	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
+
+	hal_ipc = ipc;
+	ipc_register(hal_ipc, HAL_SERVICE_ID_PAN, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
 	return true;
@@ -829,7 +833,9 @@ void bt_pan_unregister(void)
 
 	bnep_cleanup();
 
-	ipc_unregister(HAL_SERVICE_ID_PAN);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_PAN);
+	hal_ipc = NULL;
+
 	bt_adapter_remove_record(nap_dev.record_id);
 	nap_dev.record_id = 0;
 	destroy_nap_device();
diff --git a/android/pan.h b/android/pan.h
index 72a7eab..2045ac5 100644
--- a/android/pan.h
+++ b/android/pan.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_pan_register(const bdaddr_t *addr);
+bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_pan_unregister(void);
diff --git a/android/socket.c b/android/socket.c
index 655ee40..d463255 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -38,11 +38,11 @@
 #include "src/sdpd.h"
 #include "src/log.h"
 
-#include "bluetooth.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
 #include "ipc.h"
 #include "utils.h"
+#include "bluetooth.h"
 #include "socket.h"
 
 #define RFCOMM_CHANNEL_MAX 30
@@ -60,6 +60,7 @@
 #define MAP_MSG_TYPE_SMS_CDMA	0x04
 #define DEFAULT_MAS_MSG_TYPE	(MAP_MSG_TYPE_SMS_GSM | MAP_MSG_TYPE_SMS_CDMA)
 
+static struct ipc *hal_ipc = NULL;
 struct rfcomm_sock {
 	int channel;	/* RFCOMM channel */
 	BtIOSecLevel sec_level;
@@ -862,13 +863,14 @@ static void handle_listen(const void *buf, uint16_t len)
 	if (status != HAL_STATUS_SUCCESS)
 		goto failed;
 
-	ipc_send_rsp_full(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, 0, NULL,
-								hal_sock);
+	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
+							0, NULL, hal_sock);
 	close(hal_sock);
 	return ;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
+									status);
 }
 
 static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
@@ -1106,13 +1108,14 @@ static void handle_connect(const void *buf, uint16_t len)
 	if (status != HAL_STATUS_SUCCESS)
 		goto failed;
 
-	ipc_send_rsp_full(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, 0,
-							 NULL, hal_sock);
+	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
+							0, NULL, hal_sock);
 	close(hal_sock);
 	return;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, status);
+	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
+									status);
 
 }
 
@@ -1123,7 +1126,7 @@ static const struct ipc_handler cmd_handlers[] = {
 	{ handle_connect, false, sizeof(struct hal_cmd_socket_connect) },
 };
 
-void bt_socket_register(const bdaddr_t *addr)
+void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	size_t i;
 
@@ -1137,7 +1140,9 @@ void bt_socket_register(const bdaddr_t *addr)
 			servers[profiles[i].channel].reserved = true;
 
 	bacpy(&adapter_addr, addr);
-	ipc_register(HAL_SERVICE_ID_SOCKET, cmd_handlers,
+
+	hal_ipc = ipc;
+	ipc_register(hal_ipc, HAL_SERVICE_ID_SOCKET, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 }
 
@@ -1155,5 +1160,6 @@ void bt_socket_unregister(void)
 
 	memset(servers, 0, sizeof(servers));
 
-	ipc_unregister(HAL_SERVICE_ID_SOCKET);
+	ipc_unregister(hal_ipc, HAL_SERVICE_ID_SOCKET);
+	hal_ipc = NULL;
 }
diff --git a/android/socket.h b/android/socket.h
index d41616f..d3ed9b4 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -30,5 +30,5 @@ struct hal_sock_connect_signal {
 
 void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
 
-void bt_socket_register(const bdaddr_t *addr);
+void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr);
 void bt_socket_unregister(void);
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 8dd53a1..054af84 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -43,6 +43,8 @@
 #include "android/hal-msg.h"
 #include "android/ipc.h"
 
+static struct ipc *ipc = NULL;
+
 struct test_data {
 	uint32_t expected_signal;
 	const void *cmd;
@@ -283,11 +285,15 @@ static void test_init(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc_init();
+	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
+							HAL_SERVICE_ID_MAX);
+
+	g_assert(ipc);
 
 	execute_context(context);
 
-	ipc_cleanup();
+	ipc_cleanup(ipc);
+	ipc = NULL;
 }
 
 static gboolean send_cmd(gpointer user_data)
@@ -310,7 +316,7 @@ static gboolean register_service(gpointer user_data)
 	struct context *context = user_data;
 	const struct test_data *test_data = context->data;
 
-	ipc_register(test_data->service, test_data->handlers,
+	ipc_register(ipc, test_data->service, test_data->handlers,
 						test_data->handlers_size);
 
 	return FALSE;
@@ -321,7 +327,7 @@ static gboolean unregister_service(gpointer user_data)
 	struct context *context = user_data;
 	const struct test_data *test_data = context->data;
 
-	ipc_unregister(test_data->service);
+	ipc_unregister(ipc, test_data->service);
 
 	return FALSE;
 }
@@ -330,13 +336,17 @@ static void test_cmd(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc_init();
+	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
+							HAL_SERVICE_ID_MAX);
+
+	g_assert(ipc);
 
 	g_idle_add(send_cmd, context);
 
 	execute_context(context);
 
-	ipc_cleanup();
+	ipc_cleanup(ipc);
+	ipc = NULL;
 }
 
 static void test_cmd_reg(gconstpointer data)
@@ -344,23 +354,30 @@ static void test_cmd_reg(gconstpointer data)
 	struct context *context = create_context(data);
 	const struct test_data *test_data = context->data;
 
-	ipc_init();
+	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
+							HAL_SERVICE_ID_MAX);
+
+	g_assert(ipc);
 
 	g_idle_add(register_service, context);
 	g_idle_add(send_cmd, context);
 
 	execute_context(context);
 
-	ipc_unregister(test_data->service);
+	ipc_unregister(ipc, test_data->service);
 
-	ipc_cleanup();
+	ipc_cleanup(ipc);
+	ipc = NULL;
 }
 
 static void test_cmd_reg_1(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc_init();
+	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
+							HAL_SERVICE_ID_MAX);
+
+	g_assert(ipc);
 
 	g_idle_add(register_service, context);
 	g_idle_add(unregister_service, context);
@@ -368,17 +385,18 @@ static void test_cmd_reg_1(gconstpointer data)
 
 	execute_context(context);
 
-	ipc_cleanup();
+	ipc_cleanup(ipc);
+	ipc = NULL;
 }
 
 static void test_cmd_handler_1(const void *buf, uint16_t len)
 {
-	ipc_send_rsp(0, 1, 0);
+	ipc_send_rsp(ipc, 0, 1, 0);
 }
 
 static void test_cmd_handler_2(const void *buf, uint16_t len)
 {
-	ipc_send_rsp(0, 2, 0);
+	ipc_send_rsp(ipc, 0, 2, 0);
 }
 
 static void test_cmd_handler_invalid(const void *buf, uint16_t len)
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] android: Add support for registering disconnect callback in IPC
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
@ 2014-02-28 13:09 ` Szymon Janc
  2014-02-28 13:09 ` [PATCH 3/6] android/unit: Update test-ipc with disconnect handler support Szymon Janc
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Allow to register callback which is called in case of IPC failure
(eg malformed message) or disconnection. This makes caller responsible
for performing expected action in such case.
---
 android/ipc.c      | 106 ++++++++++++++++++++++++++++++++++-------------------
 android/ipc.h      |   5 ++-
 android/main.c     |   7 +++-
 android/test-ipc.c |   8 ++--
 4 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/android/ipc.c b/android/ipc.c
index 3d6e2a3..a996935 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -52,8 +52,42 @@ struct ipc {
 
 	GIOChannel *notif_io;
 	guint notif_watch;
+
+	ipc_disconnect_cb disconnect_cb;
+	void *disconnect_cb_data;
 };
 
+static void ipc_disconnect(struct ipc *ipc, bool in_cleanup)
+{
+	if (ipc->cmd_watch) {
+		g_source_remove(ipc->cmd_watch);
+		ipc->cmd_watch = 0;
+	}
+
+	if (ipc->cmd_io) {
+		g_io_channel_shutdown(ipc->cmd_io, TRUE, NULL);
+		g_io_channel_unref(ipc->cmd_io);
+		ipc->cmd_io = NULL;
+	}
+
+	if (ipc->notif_watch) {
+		g_source_remove(ipc->notif_watch);
+		ipc->notif_watch = 0;
+	}
+
+	if (ipc->notif_io) {
+		g_io_channel_shutdown(ipc->notif_io, TRUE, NULL);
+		g_io_channel_unref(ipc->notif_io);
+		ipc->notif_io = NULL;
+	}
+
+	if (in_cleanup)
+		return;
+
+	if (ipc->disconnect_cb)
+		ipc->disconnect_cb(ipc->disconnect_cb_data);
+}
+
 int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 						const void *buf, ssize_t len)
 {
@@ -116,7 +150,9 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 	int fd, err;
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-		info("IPC: command socket closed, terminating");
+		info("IPC: command socket closed");
+
+		ipc->cmd_watch = 0;
 		goto fail;
 	}
 
@@ -124,30 +160,34 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 
 	ret = read(fd, buf, sizeof(buf));
 	if (ret < 0) {
-		error("IPC: command read failed, terminating (%s)",
-							strerror(errno));
+		error("IPC: command read failed (%s)", strerror(errno));
 		goto fail;
 	}
 
 	err = ipc_handle_msg(ipc->services, ipc->service_max, buf, ret);
 	if (err < 0) {
-		error("IPC: failed to handle message, terminating (%s)",
-							strerror(-err));
+		error("IPC: failed to handle message (%s)", strerror(-err));
 		goto fail;
 	}
 
 	return TRUE;
 
 fail:
-	raise(SIGTERM);
+	ipc_disconnect(ipc, false);
+
 	return FALSE;
 }
 
 static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
-	info("IPC: notification socket closed, terminating");
-	raise(SIGTERM);
+	struct ipc *ipc = user_data;
+
+	info("IPC: notification socket closed");
+
+	ipc->notif_watch = 0;
+
+	ipc_disconnect(ipc, false);
 
 	return FALSE;
 }
@@ -194,8 +234,10 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
 	DBG("");
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-		error("IPC: notification socket connect failed, terminating");
-		raise(SIGTERM);
+		error("IPC: notification socket connect failed");
+
+		ipc_disconnect(ipc, false);
+
 		return FALSE;
 	}
 
@@ -220,20 +262,25 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
 	DBG("");
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-		error("IPC: command socket connect failed, terminating");
-		raise(SIGTERM);
-		return FALSE;
+		error("IPC: command socket connect failed");
+		goto failed;
 	}
 
 	ipc->notif_io = ipc_connect(ipc->path, ipc->size, notif_connect_cb,
 									ipc);
 	if (!ipc->notif_io)
-		raise(SIGTERM);
+		goto failed;
+
+	return FALSE;
+
+failed:
+	ipc_disconnect(ipc, false);
 
 	return FALSE;
 }
 
-struct ipc *ipc_init(const char *path, size_t size, int max_service_id)
+struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
+					ipc_disconnect_cb cb, void *cb_data)
 {
 	struct ipc *ipc;
 
@@ -252,32 +299,15 @@ struct ipc *ipc_init(const char *path, size_t size, int max_service_id)
 		return NULL;
 	}
 
+	ipc->disconnect_cb = cb;
+	ipc->disconnect_cb_data = cb_data;
+
 	return ipc;
 }
 
 void ipc_cleanup(struct ipc *ipc)
 {
-	if (ipc->cmd_watch) {
-		g_source_remove(ipc->cmd_watch);
-		ipc->cmd_watch = 0;
-	}
-
-	if (ipc->cmd_io) {
-		g_io_channel_shutdown(ipc->cmd_io, TRUE, NULL);
-		g_io_channel_unref(ipc->cmd_io);
-		ipc->cmd_io = NULL;
-	}
-
-	if (ipc->notif_watch) {
-		g_source_remove(ipc->notif_watch);
-		ipc->notif_watch = 0;
-	}
-
-	if (ipc->notif_io) {
-		g_io_channel_shutdown(ipc->notif_io, TRUE, NULL);
-		g_io_channel_unref(ipc->notif_io);
-		ipc->notif_io = NULL;
-	}
+	ipc_disconnect(ipc, true);
 
 	g_free(ipc->services);
 	g_free(ipc);
@@ -323,7 +353,9 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 	}
 
 	if (sendmsg(sk, &msg, 0) < 0) {
-		error("IPC send failed, terminating :%s", strerror(errno));
+		error("IPC send failed :%s", strerror(errno));
+
+		/* TODO disconnect IPC here when this function becomes static */
 		raise(SIGTERM);
 	}
 }
diff --git a/android/ipc.h b/android/ipc.h
index 601301c..63b751d 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -34,7 +34,10 @@ struct service_handler {
 
 struct ipc;
 
-struct ipc *ipc_init(const char *path, size_t size, int max_service_id);
+typedef void (*ipc_disconnect_cb) (void *data);
+
+struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
+					ipc_disconnect_cb cb, void *cb_data);
 void ipc_cleanup(struct ipc *ipc);
 
 GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
diff --git a/android/main.c b/android/main.c
index 9f22486..01f0b92 100644
--- a/android/main.c
+++ b/android/main.c
@@ -228,6 +228,11 @@ static void stop_bluetooth(void)
 	g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, quit_eventloop, NULL);
 }
 
+static void ipc_disconnected(void *data)
+{
+	stop_bluetooth();
+}
+
 static void adapter_ready(int err, const bdaddr_t *addr)
 {
 	if (err < 0) {
@@ -245,7 +250,7 @@ static void adapter_ready(int err, const bdaddr_t *addr)
 	info("Adapter initialized");
 
 	hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-							HAL_SERVICE_ID_MAX);
+				HAL_SERVICE_ID_MAX, ipc_disconnected, NULL);
 	if (!hal_ipc) {
 		error("Failed to initialize IPC");
 		exit(EXIT_FAILURE);
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 054af84..9b736a2 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -286,7 +286,7 @@ static void test_init(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-							HAL_SERVICE_ID_MAX);
+						HAL_SERVICE_ID_MAX, NULL, NULL);
 
 	g_assert(ipc);
 
@@ -337,7 +337,7 @@ static void test_cmd(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-							HAL_SERVICE_ID_MAX);
+						HAL_SERVICE_ID_MAX, NULL, NULL);
 
 	g_assert(ipc);
 
@@ -355,7 +355,7 @@ static void test_cmd_reg(gconstpointer data)
 	const struct test_data *test_data = context->data;
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-							HAL_SERVICE_ID_MAX);
+						HAL_SERVICE_ID_MAX, NULL, NULL);
 
 	g_assert(ipc);
 
@@ -375,7 +375,7 @@ static void test_cmd_reg_1(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-							HAL_SERVICE_ID_MAX);
+						HAL_SERVICE_ID_MAX, NULL, NULL);
 
 	g_assert(ipc);
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] android/unit: Update test-ipc with disconnect handler support
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
  2014-02-28 13:09 ` [PATCH 2/6] android: Add support for registering disconnect callback in IPC Szymon Janc
@ 2014-02-28 13:09 ` Szymon Janc
  2014-02-28 13:09 ` [PATCH 4/6] android: Add support for disabling notifications in IPC Szymon Janc
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/test-ipc.c | 117 ++++++++++++++++-------------------------------------
 1 file changed, 34 insertions(+), 83 deletions(-)

diff --git a/android/test-ipc.c b/android/test-ipc.c
index 9b736a2..2f211fd 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -35,7 +35,6 @@
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <sys/signalfd.h>
 
 #include <glib.h>
 #include "src/shared/util.h"
@@ -43,10 +42,8 @@
 #include "android/hal-msg.h"
 #include "android/ipc.h"
 
-static struct ipc *ipc = NULL;
-
 struct test_data {
-	uint32_t expected_signal;
+	bool disconnect;
 	const void *cmd;
 	uint16_t cmd_size;
 	uint8_t service;
@@ -65,13 +62,13 @@ struct context {
 
 	GIOChannel *cmd_io;
 	GIOChannel *notif_io;
-	GIOChannel *signal_io;
-
-	guint signal_source;
 
 	const struct test_data *data;
 };
 
+
+static struct ipc *ipc = NULL;
+
 static void context_quit(struct context *context)
 {
 	g_main_loop_quit(context->main_loop);
@@ -92,13 +89,13 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
 		.len = 0,
 	};
 
-	g_assert(test_data->expected_signal == 0);
-
 	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
-		g_assert(FALSE);
+		g_assert(test_data->disconnect);
 		return FALSE;
 	}
 
+	g_assert(!test_data->disconnect);
+
 	sk = g_io_channel_unix_get_fd(io);
 
 	g_assert(read(sk, buf, sizeof(buf)) == sizeof(struct hal_hdr));
@@ -112,11 +109,16 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
 static gboolean notif_watch(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
+	struct context *context = user_data;
+	const struct test_data *test_data = context->data;
+
 	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
-		g_assert(FALSE);
+		g_assert(test_data->disconnect);
 		return FALSE;
 	}
 
+	g_assert(!test_data->disconnect);
+
 	return TRUE;
 }
 
@@ -162,62 +164,6 @@ static gboolean connect_handler(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 }
 
-static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
-							gpointer user_data)
-{
-	struct context *context = user_data;
-	const struct test_data *test_data = context->data;
-	struct signalfd_siginfo si;
-	ssize_t result;
-	int fd;
-
-	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
-		return FALSE;
-
-	fd = g_io_channel_unix_get_fd(channel);
-
-	result = read(fd, &si, sizeof(si));
-	if (result != sizeof(si))
-		return FALSE;
-
-	g_assert(test_data->expected_signal == si.ssi_signo);
-	context_quit(context);
-	return TRUE;
-}
-
-static guint setup_signalfd(gpointer user_data)
-{
-	GIOChannel *channel;
-	guint source;
-	sigset_t mask;
-	int ret;
-	int fd;
-
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGINT);
-	sigaddset(&mask, SIGTERM);
-
-	ret = sigprocmask(SIG_BLOCK, &mask, NULL);
-	g_assert(ret == 0);
-
-	fd = signalfd(-1, &mask, 0);
-	g_assert(fd >= 0);
-
-	channel = g_io_channel_unix_new(fd);
-
-	g_io_channel_set_close_on_unref(channel, TRUE);
-	g_io_channel_set_encoding(channel, NULL, NULL);
-	g_io_channel_set_buffered(channel, FALSE);
-
-	source = g_io_add_watch(channel,
-				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				signal_handler, user_data);
-
-	g_io_channel_unref(channel);
-
-	return source;
-}
-
 static struct context *create_context(gconstpointer data)
 {
 	struct context *context = g_new0(struct context, 1);
@@ -228,9 +174,6 @@ static struct context *create_context(gconstpointer data)
 	context->main_loop = g_main_loop_new(NULL, FALSE);
 	g_assert(context->main_loop);
 
-	context->signal_source = setup_signalfd(context);
-	g_assert(context->signal_source);
-
 	sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
 	g_assert(sk >= 0);
 
@@ -272,7 +215,6 @@ static void execute_context(struct context *context)
 	g_io_channel_unref(context->notif_io);
 
 	g_source_remove(context->notif_source);
-	g_source_remove(context->signal_source);
 	g_source_remove(context->cmd_source);
 	g_source_remove(context->source);
 
@@ -281,6 +223,15 @@ static void execute_context(struct context *context)
 	g_free(context);
 }
 
+static void disconnected(void *data)
+{
+	struct context *context = data;
+
+	g_assert(context->data->disconnect);
+
+	context_quit(context);
+}
+
 static void test_init(gconstpointer data)
 {
 	struct context *context = create_context(data);
@@ -337,7 +288,7 @@ static void test_cmd(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						HAL_SERVICE_ID_MAX, NULL, NULL);
+				HAL_SERVICE_ID_MAX, disconnected, context);
 
 	g_assert(ipc);
 
@@ -355,7 +306,7 @@ static void test_cmd_reg(gconstpointer data)
 	const struct test_data *test_data = context->data;
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						HAL_SERVICE_ID_MAX, NULL, NULL);
+				HAL_SERVICE_ID_MAX, disconnected, context);
 
 	g_assert(ipc);
 
@@ -375,7 +326,7 @@ static void test_cmd_reg_1(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						HAL_SERVICE_ID_MAX, NULL, NULL);
+				HAL_SERVICE_ID_MAX, disconnected, context);
 
 	g_assert(ipc);
 
@@ -401,7 +352,7 @@ static void test_cmd_handler_2(const void *buf, uint16_t len)
 
 static void test_cmd_handler_invalid(const void *buf, uint16_t len)
 {
-	raise(SIGTERM);
+	g_assert(false);
 }
 
 static const struct test_data test_init_1 = {};
@@ -421,7 +372,7 @@ static const struct hal_hdr test_cmd_2_hdr = {
 static const struct test_data test_cmd_service_invalid_1 = {
 	.cmd = &test_cmd_1_hdr,
 	.cmd_size = sizeof(test_cmd_1_hdr),
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -442,7 +393,7 @@ static const struct test_data test_cmd_service_invalid_2 = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct ipc_handler cmd_handlers_invalid_2[] = {
@@ -477,7 +428,7 @@ static const struct test_data test_cmd_opcode_invalid_1 = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct test_data test_cmd_hdr_invalid = {
@@ -486,7 +437,7 @@ static const struct test_data test_cmd_hdr_invalid = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 #define VARDATA_EX1 "some data example"
@@ -533,7 +484,7 @@ static const struct test_data test_cmd_vardata_invalid_1 = {
 	.service = 0,
 	.handlers = cmd_vardata_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct hal_hdr test_cmd_service_offrange_hdr = {
@@ -548,7 +499,7 @@ static const struct test_data test_cmd_service_offrange = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct vardata test_cmd_invalid_data_1 = {
@@ -564,7 +515,7 @@ static const struct test_data test_cmd_msg_invalid_1 = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 static const struct vardata test_cmd_invalid_data_2 = {
@@ -580,7 +531,7 @@ static const struct test_data test_cmd_msg_invalid_2 = {
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-	.expected_signal = SIGTERM
+	.disconnect = true,
 };
 
 int main(int argc, char *argv[])
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] android: Add support for disabling notifications in IPC
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
  2014-02-28 13:09 ` [PATCH 2/6] android: Add support for registering disconnect callback in IPC Szymon Janc
  2014-02-28 13:09 ` [PATCH 3/6] android/unit: Update test-ipc with disconnect handler support Szymon Janc
@ 2014-02-28 13:09 ` Szymon Janc
  2014-02-28 13:09 ` [PATCH 5/6] android/a2dp: Use common IPC for audio socket Szymon Janc
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/ipc.c      | 29 ++++++++++++++++++++---------
 android/ipc.h      |  1 +
 android/main.c     |  3 ++-
 android/test-ipc.c |  8 ++++----
 4 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/android/ipc.c b/android/ipc.c
index a996935..fa44e3f 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -50,6 +50,7 @@ struct ipc {
 	GIOChannel *cmd_io;
 	guint cmd_watch;
 
+	bool notifications;
 	GIOChannel *notif_io;
 	guint notif_watch;
 
@@ -249,7 +250,7 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
 
 	ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc);
 
-	info("IPC: successfully connected");
+	info("IPC: successfully connected (with notifications)");
 
 	return FALSE;
 }
@@ -263,23 +264,31 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
 		error("IPC: command socket connect failed");
-		goto failed;
+		ipc_disconnect(ipc, false);
+
+		return FALSE;
 	}
 
-	ipc->notif_io = ipc_connect(ipc->path, ipc->size, notif_connect_cb,
-									ipc);
-	if (!ipc->notif_io)
-		goto failed;
+	if (ipc->notifications) {
+		ipc->notif_io = ipc_connect(ipc->path, ipc->size,
+							notif_connect_cb, ipc);
+		if (!ipc->notif_io)
+			ipc_disconnect(ipc, false);
 
-	return FALSE;
+		return FALSE;
+	}
 
-failed:
-	ipc_disconnect(ipc, false);
+	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc);
+
+	info("IPC: successfully connected (without notifications)");
 
 	return FALSE;
 }
 
 struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
+					bool notifications,
 					ipc_disconnect_cb cb, void *cb_data)
 {
 	struct ipc *ipc;
@@ -292,6 +301,8 @@ struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
 	ipc->path = path;
 	ipc->size = size;
 
+	ipc->notifications = notifications;
+
 	ipc->cmd_io = ipc_connect(path, size, cmd_connect_cb, ipc);
 	if (!ipc->cmd_io) {
 		g_free(ipc->services);
diff --git a/android/ipc.h b/android/ipc.h
index 63b751d..d46dbbf 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -37,6 +37,7 @@ struct ipc;
 typedef void (*ipc_disconnect_cb) (void *data);
 
 struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
+					bool notifications,
 					ipc_disconnect_cb cb, void *cb_data);
 void ipc_cleanup(struct ipc *ipc);
 
diff --git a/android/main.c b/android/main.c
index 01f0b92..bd1bcb9 100644
--- a/android/main.c
+++ b/android/main.c
@@ -250,7 +250,8 @@ static void adapter_ready(int err, const bdaddr_t *addr)
 	info("Adapter initialized");
 
 	hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-				HAL_SERVICE_ID_MAX, ipc_disconnected, NULL);
+						HAL_SERVICE_ID_MAX, true,
+						ipc_disconnected, NULL);
 	if (!hal_ipc) {
 		error("Failed to initialize IPC");
 		exit(EXIT_FAILURE);
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 2f211fd..6172991 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -237,7 +237,7 @@ static void test_init(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-						HAL_SERVICE_ID_MAX, NULL, NULL);
+					HAL_SERVICE_ID_MAX, true, NULL, NULL);
 
 	g_assert(ipc);
 
@@ -288,7 +288,7 @@ static void test_cmd(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-				HAL_SERVICE_ID_MAX, disconnected, context);
+			HAL_SERVICE_ID_MAX, true, disconnected, context);
 
 	g_assert(ipc);
 
@@ -306,7 +306,7 @@ static void test_cmd_reg(gconstpointer data)
 	const struct test_data *test_data = context->data;
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-				HAL_SERVICE_ID_MAX, disconnected, context);
+			HAL_SERVICE_ID_MAX, true, disconnected, context);
 
 	g_assert(ipc);
 
@@ -326,7 +326,7 @@ static void test_cmd_reg_1(gconstpointer data)
 	struct context *context = create_context(data);
 
 	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-				HAL_SERVICE_ID_MAX, disconnected, context);
+			HAL_SERVICE_ID_MAX, true, disconnected, context);
 
 	g_assert(ipc);
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] android/a2dp: Use common IPC for audio socket
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
                   ` (2 preceding siblings ...)
  2014-02-28 13:09 ` [PATCH 4/6] android: Add support for disabling notifications in IPC Szymon Janc
@ 2014-02-28 13:09 ` Szymon Janc
  2014-02-28 13:09 ` [PATCH 6/6] android: Create comon header for IPC Szymon Janc
  2014-02-28 14:34 ` [PATCH 1/6] android: Refactor IPC init Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This makes audio HAL to use same code for IPC as BT HAL.
---
 android/Android.mk  |   1 -
 android/Makefile.am |   1 -
 android/a2dp.c      |  73 ++++++++++++++++---------
 android/audio-ipc.c | 155 ----------------------------------------------------
 android/audio-ipc.h |  31 -----------
 android/audio-msg.h |   1 +
 android/ipc.c       |   8 +--
 android/ipc.h       |   7 ---
 8 files changed, 52 insertions(+), 225 deletions(-)
 delete mode 100644 android/audio-ipc.c
 delete mode 100644 android/audio-ipc.h

diff --git a/android/Android.mk b/android/Android.mk
index 82c834b..56b86ba 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -35,7 +35,6 @@ LOCAL_SRC_FILES := \
 	bluez/android/hidhost.c \
 	bluez/android/socket.c \
 	bluez/android/ipc.c \
-	bluez/android/audio-ipc.c \
 	bluez/android/avdtp.c \
 	bluez/android/a2dp.c \
 	bluez/android/avctp.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 232f3f3..05fe372 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -32,7 +32,6 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/bluetooth.h android/bluetooth.c \
 				android/hidhost.h android/hidhost.c \
 				android/ipc.h android/ipc.c \
-				android/audio-ipc.h android/audio-ipc.c \
 				android/avdtp.h android/avdtp.c \
 				android/a2dp.h android/a2dp.c \
 				android/avctp.h android/avctp.c \
diff --git a/android/a2dp.c b/android/a2dp.c
index b05d4bd..8e27413 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -47,7 +47,6 @@
 #include "avdtp.h"
 #include "avrcp.h"
 #include "audio-msg.h"
-#include "audio-ipc.h"
 
 #define L2CAP_PSM_AVDTP 0x19
 #define SVC_HINT_CAPTURING 0x08
@@ -64,6 +63,7 @@ static guint audio_retry_id = 0;
 static bool audio_retrying = false;
 
 static struct ipc *hal_ipc = NULL;
+static struct ipc *audio_ipc = NULL;
 
 struct a2dp_preset {
 	void *data;
@@ -1298,12 +1298,14 @@ static void bt_audio_open(const void *buf, uint16_t len)
 
 	g_slist_free(presets);
 
-	audio_ipc_send_rsp_full(AUDIO_OP_OPEN, sizeof(rsp), &rsp, -1);
+	ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN,
+							sizeof(rsp), &rsp, -1);
 
 	return;
 
 failed:
-	audio_ipc_send_rsp(AUDIO_OP_OPEN, AUDIO_STATUS_FAILED);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN,
+							AUDIO_STATUS_FAILED);
 }
 
 static struct a2dp_endpoint *find_endpoint(uint8_t id)
@@ -1330,14 +1332,16 @@ static void bt_audio_close(const void *buf, uint16_t len)
 	endpoint = find_endpoint(cmd->id);
 	if (!endpoint) {
 		error("Unable to find endpoint %u", cmd->id);
-		audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_FAILED);
+		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE,
+							AUDIO_STATUS_FAILED);
 		return;
 	}
 
 	endpoints = g_slist_remove(endpoints, endpoint);
 	unregister_endpoint(endpoint);
 
-	audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE,
+							AUDIO_STATUS_SUCCESS);
 }
 
 static void bt_stream_open(const void *buf, uint16_t len)
@@ -1353,14 +1357,16 @@ static void bt_stream_open(const void *buf, uint16_t len)
 	setup = find_setup(cmd->id);
 	if (!setup) {
 		error("Unable to find stream for endpoint %u", cmd->id);
-		audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
+		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
+							AUDIO_STATUS_FAILED);
 		return;
 	}
 
 	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu,
 								NULL)) {
 		error("avdtp_stream_get_transport: failed");
-		audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
+		ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
+							AUDIO_STATUS_FAILED);
 		return;
 	}
 
@@ -1371,7 +1377,8 @@ static void bt_stream_open(const void *buf, uint16_t len)
 	rsp->preset->len = setup->preset->len;
 	memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
 
-	audio_ipc_send_rsp_full(AUDIO_OP_OPEN_STREAM, len, rsp, fd);
+	ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
+								len, rsp, fd);
 
 	g_free(rsp);
 }
@@ -1396,12 +1403,14 @@ static void bt_stream_close(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	audio_ipc_send_rsp(AUDIO_OP_CLOSE_STREAM, AUDIO_STATUS_SUCCESS);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM,
+							AUDIO_STATUS_SUCCESS);
 
 	return;
 
 failed:
-	audio_ipc_send_rsp(AUDIO_OP_CLOSE_STREAM, AUDIO_STATUS_FAILED);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM,
+							AUDIO_STATUS_FAILED);
 }
 
 static void bt_stream_resume(const void *buf, uint16_t len)
@@ -1426,12 +1435,14 @@ static void bt_stream_resume(const void *buf, uint16_t len)
 		}
 	}
 
-	audio_ipc_send_rsp(AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_SUCCESS);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM,
+							AUDIO_STATUS_SUCCESS);
 
 	return;
 
 failed:
-	audio_ipc_send_rsp(AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_FAILED);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM,
+							AUDIO_STATUS_FAILED);
 }
 
 static void bt_stream_suspend(const void *buf, uint16_t len)
@@ -1454,12 +1465,14 @@ static void bt_stream_suspend(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	audio_ipc_send_rsp(AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_SUCCESS);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM,
+							AUDIO_STATUS_SUCCESS);
 
 	return;
 
 failed:
-	audio_ipc_send_rsp(AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_FAILED);
+	ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM,
+							AUDIO_STATUS_FAILED);
 }
 
 static const struct ipc_handler audio_handlers[] = {
@@ -1490,26 +1503,33 @@ static void bt_audio_unregister(void)
 	g_slist_free_full(setups, setup_free);
 	setups = NULL;
 
-	audio_ipc_cleanup();
+	ipc_cleanup(audio_ipc);
+	audio_ipc = NULL;
 }
 
-static void bt_audio_register(GDestroyNotify destroy)
+static bool bt_audio_register(ipc_disconnect_cb disconnect)
 {
 	DBG("");
 
-	audio_ipc_init(destroy);
+	audio_ipc = ipc_init(BLUEZ_AUDIO_SK_PATH, sizeof(BLUEZ_AUDIO_SK_PATH),
+				AUDIO_SERVICE_ID_MAX, false, disconnect, NULL);
+	if (!audio_ipc)
+		return false;
+
+	ipc_register(audio_ipc, AUDIO_SERVICE_ID, audio_handlers,
+						G_N_ELEMENTS(audio_handlers));
 
-	audio_ipc_register(audio_handlers, G_N_ELEMENTS(audio_handlers));
+	return true;
 }
 
 static gboolean audio_retry_register(void *data)
 {
-	GDestroyNotify destroy = data;
+	ipc_disconnect_cb cb = data;
 
 	audio_retry_id = 0;
 	audio_retrying = true;
 
-	bt_audio_register(destroy);
+	bt_audio_register(cb);
 
 	return FALSE;
 }
@@ -1581,9 +1601,8 @@ bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr)
 	ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
-	bt_audio_register(audio_disconnected);
-
-	return true;
+	if (bt_audio_register(audio_disconnected))
+		return true;
 
 fail:
 	g_io_channel_shutdown(server, TRUE, NULL);
@@ -1608,8 +1627,6 @@ void bt_a2dp_unregister(void)
 	ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP);
 	hal_ipc = NULL;
 
-	audio_ipc_unregister();
-
 	bt_adapter_remove_record(record_id);
 	record_id = 0;
 
@@ -1619,5 +1636,9 @@ void bt_a2dp_unregister(void)
 		server = NULL;
 	}
 
-	audio_ipc_cleanup();
+	if (audio_ipc) {
+		ipc_unregister(audio_ipc, AUDIO_SERVICE_ID);
+		ipc_cleanup(audio_ipc);
+		audio_ipc = NULL;
+	}
 }
diff --git a/android/audio-ipc.c b/android/audio-ipc.c
deleted file mode 100644
index ce2d86d..0000000
--- a/android/audio-ipc.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stddef.h>
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include "src/log.h"
-#include "ipc.h"
-#include "audio-msg.h"
-#include "audio-ipc.h"
-
-static GIOChannel *audio_io = NULL;
-
-static struct service_handler service;
-
-static gboolean audio_watch_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
-{
-	GDestroyNotify destroy = user_data;
-	char buf[BLUEZ_AUDIO_MTU];
-	ssize_t ret;
-	int fd, err;
-
-	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-		info("Audio IPC: command socket closed");
-		goto fail;
-	}
-
-	fd = g_io_channel_unix_get_fd(io);
-
-	ret = read(fd, buf, sizeof(buf));
-	if (ret < 0) {
-		error("Audio IPC: command read failed (%s)", strerror(errno));
-		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:
-	audio_ipc_cleanup();
-	if (destroy)
-		destroy(NULL);
-	return FALSE;
-}
-
-static gboolean audio_connect_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
-{
-	GDestroyNotify destroy = user_data;
-
-	DBG("");
-
-	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-		error("Audio IPC: socket connect failed");
-		audio_ipc_cleanup();
-		if (destroy)
-			destroy(NULL);
-		return FALSE;
-	}
-
-	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-
-	g_io_add_watch(audio_io, cond, audio_watch_cb, user_data);
-
-	info("Audio IPC: successfully connected");
-
-	return FALSE;
-}
-
-void audio_ipc_init(GDestroyNotify destroy)
-{
-	audio_io = ipc_connect(BLUEZ_AUDIO_SK_PATH, sizeof(BLUEZ_AUDIO_SK_PATH),
-						audio_connect_cb, destroy);
-}
-
-void audio_ipc_cleanup(void)
-{
-	if (audio_io) {
-		g_io_channel_shutdown(audio_io, TRUE, NULL);
-		g_io_channel_unref(audio_io);
-		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;
-}
-
-void audio_ipc_send_rsp(uint8_t opcode, uint8_t status)
-{
-	struct audio_status s;
-	int sk;
-
-	sk = g_io_channel_unix_get_fd(audio_io);
-
-	if (status == AUDIO_STATUS_SUCCESS) {
-		ipc_send(sk, AUDIO_SERVICE_ID, opcode, 0, NULL, -1);
-		return;
-	}
-
-	s.code = status;
-
-	ipc_send(sk, AUDIO_SERVICE_ID, AUDIO_OP_STATUS, sizeof(s), &s, -1);
-}
-
-void audio_ipc_send_rsp_full(uint8_t opcode, uint16_t len, void *param, int fd)
-{
-	ipc_send(g_io_channel_unix_get_fd(audio_io), AUDIO_SERVICE_ID, opcode,
-							len, param, fd);
-}
diff --git a/android/audio-ipc.h b/android/audio-ipc.h
deleted file mode 100644
index 83207c8..0000000
--- a/android/audio-ipc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-void audio_ipc_init(GDestroyNotify destroy);
-void audio_ipc_cleanup(void);
-
-void audio_ipc_register(const struct ipc_handler *handlers, uint8_t size);
-void audio_ipc_unregister(void);
-
-void audio_ipc_send_rsp(uint8_t opcode, uint8_t status);
-void audio_ipc_send_rsp_full(uint8_t opcode, uint16_t len, void *param, int fd);
diff --git a/android/audio-msg.h b/android/audio-msg.h
index 17cde09..d4fc68a 100644
--- a/android/audio-msg.h
+++ b/android/audio-msg.h
@@ -26,6 +26,7 @@
 static const char BLUEZ_AUDIO_SK_PATH[] = "\0bluez_audio_socket";
 
 #define AUDIO_SERVICE_ID		0
+#define AUDIO_SERVICE_ID_MAX		AUDIO_SERVICE_ID
 
 #define AUDIO_STATUS_SUCCESS		0x00
 #define AUDIO_STATUS_FAILED		0x01
diff --git a/android/ipc.c b/android/ipc.c
index fa44e3f..6b14bbe 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -89,7 +89,7 @@ static void ipc_disconnect(struct ipc *ipc, bool in_cleanup)
 		ipc->disconnect_cb(ipc->disconnect_cb_data);
 }
 
-int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
+static int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 						const void *buf, ssize_t len)
 {
 	const struct hal_hdr *msg = buf;
@@ -193,8 +193,8 @@ static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond,
 	return FALSE;
 }
 
-GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
-							void *user_data)
+static GIOChannel *ipc_connect(const char *path, size_t size,
+					GIOFunc connect_cb, void *user_data)
 {
 	struct sockaddr_un addr;
 	GIOCondition cond;
@@ -324,7 +324,7 @@ void ipc_cleanup(struct ipc *ipc)
 	g_free(ipc);
 }
 
-void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
+static void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 							void *param, int fd)
 {
 	struct msghdr msg;
diff --git a/android/ipc.h b/android/ipc.h
index d46dbbf..cc4e92d 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -41,19 +41,12 @@ struct ipc *ipc_init(const char *path, size_t size, int max_service_id,
 					ipc_disconnect_cb cb, void *cb_data);
 void ipc_cleanup(struct ipc *ipc);
 
-GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
-							void *user_data);
-int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
-						const void *buf, ssize_t len);
-
 void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
 								uint8_t status);
 void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
 					uint16_t len, void *param, int fd);
 void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
 						uint16_t len, void *param);
-void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
-							void *param, int fd);
 void ipc_register(struct ipc *ipc, uint8_t service,
 			const struct ipc_handler *handlers, uint8_t size);
 void ipc_unregister(struct ipc *ipc, uint8_t service);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] android: Create comon header for IPC
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
                   ` (3 preceding siblings ...)
  2014-02-28 13:09 ` [PATCH 5/6] android/a2dp: Use common IPC for audio socket Szymon Janc
@ 2014-02-28 13:09 ` Szymon Janc
  2014-02-28 14:34 ` [PATCH 1/6] android: Refactor IPC init Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 13:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This header contains IPC specific structures and code not related to
BT and audio HAL protocols. This allows to fully decouple IPC from
HAL messages.

This is first step to make HAL part of IPC unit-testable and reusable
between BT HAL and audio HAL.
---
 android/a2dp.c          |  1 +
 android/audio-msg.h     |  7 ++----
 android/bluetooth.c     |  7 +++---
 android/hal-audio.c     |  7 +++---
 android/hal-avrcp.c     | 39 +++++++++++++++++----------------
 android/hal-bluetooth.c |  9 ++++----
 android/hal-handsfree.c |  9 ++++----
 android/hal-hidhost.c   |  5 +++--
 android/hal-ipc.c       | 11 +++++-----
 android/hal-msg.h       | 16 ++------------
 android/handsfree.c     |  1 +
 android/hidhost.c       |  1 +
 android/ipc-common.h    | 38 ++++++++++++++++++++++++++++++++
 android/ipc-tester.c    | 58 +++++++++++++++++++++++++------------------------
 android/ipc.c           | 16 +++++++-------
 android/main.c          |  1 +
 android/pan.c           |  1 +
 android/socket.c        |  2 +-
 android/test-ipc.c      | 56 +++++++++++++++++++++++++----------------------
 19 files changed, 163 insertions(+), 122 deletions(-)
 create mode 100644 android/ipc-common.h

diff --git a/android/a2dp.c b/android/a2dp.c
index 8e27413..180d015 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -40,6 +40,7 @@
 #include "profiles/audio/a2dp-codecs.h"
 #include "src/log.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "a2dp.h"
 #include "utils.h"
diff --git a/android/audio-msg.h b/android/audio-msg.h
index d4fc68a..5981355 100644
--- a/android/audio-msg.h
+++ b/android/audio-msg.h
@@ -28,13 +28,10 @@ static const char BLUEZ_AUDIO_SK_PATH[] = "\0bluez_audio_socket";
 #define AUDIO_SERVICE_ID		0
 #define AUDIO_SERVICE_ID_MAX		AUDIO_SERVICE_ID
 
-#define AUDIO_STATUS_SUCCESS		0x00
+#define AUDIO_STATUS_SUCCESS		IPC_STATUS_SUCCESS
 #define AUDIO_STATUS_FAILED		0x01
 
-#define AUDIO_OP_STATUS			0x00
-struct audio_status {
-	uint8_t code;
-} __attribute__((packed));
+#define AUDIO_OP_STATUS			IPC_OP_STATUS
 
 #define AUDIO_OP_OPEN			0x01
 struct audio_preset {
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 26493f7..8ad7d5d 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -46,6 +46,7 @@
 #include "src/sdpd.h"
 #include "src/log.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "utils.h"
 #include "bluetooth.h"
@@ -1062,7 +1063,7 @@ static bool rssi_above_threshold(int old, int new)
 static void update_new_device(struct device *dev, int8_t rssi,
 						const struct eir_data *eir)
 {
-	uint8_t buf[BLUEZ_HAL_MTU];
+	uint8_t buf[IPC_MTU];
 	struct hal_ev_device_found *ev = (void*) buf;
 	bdaddr_t android_bdaddr;
 	uint8_t android_type;
@@ -1115,7 +1116,7 @@ static void update_new_device(struct device *dev, int8_t rssi,
 static void update_device(struct device *dev, int8_t rssi,
 						const struct eir_data *eir)
 {
-	uint8_t buf[BLUEZ_HAL_MTU];
+	uint8_t buf[IPC_MTU];
 	struct hal_ev_remote_device_props *ev = (void *) buf;
 	int size;
 
@@ -1157,7 +1158,7 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 					int8_t rssi, bool confirm,
 					const uint8_t *data, uint8_t data_len)
 {
-	uint8_t buf[BLUEZ_HAL_MTU];
+	uint8_t buf[IPC_MTU];
 	struct eir_data eir;
 	struct device *dev;
 
diff --git a/android/hal-audio.c b/android/hal-audio.c
index e72e097..e1f3f0d 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -33,6 +33,7 @@
 #include <sbc/sbc.h>
 
 #include "audio-msg.h"
+#include "ipc-common.h"
 #include "hal-log.h"
 #include "hal-msg.h"
 #include "../profiles/audio/a2dp-codecs.h"
@@ -614,9 +615,9 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	ssize_t ret;
 	struct msghdr msg;
 	struct iovec iv[2];
-	struct hal_hdr cmd;
+	struct ipc_hdr cmd;
 	char cmsgbuf[CMSG_SPACE(sizeof(int))];
-	struct hal_status s;
+	struct ipc_status s;
 	size_t s_len = sizeof(s);
 
 	pthread_mutex_lock(&sk_mutex);
@@ -708,7 +709,7 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	}
 
 	if (cmd.opcode == AUDIO_OP_STATUS) {
-		struct hal_status *s = rsp;
+		struct ipc_status *s = rsp;
 
 		if (sizeof(*s) != cmd.len) {
 			error("audio: Invalid status length");
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index a11aaa3..46e25a0 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -23,6 +23,7 @@
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "hal-ipc.h"
 
 static const btrc_callbacks_t *cbs = NULL;
@@ -252,7 +253,7 @@ static bt_status_t get_play_status_rsp(btrc_play_status_t status,
 static bt_status_t list_player_app_attr_rsp(int num_attr,
 						btrc_player_attr_t *p_attrs)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_list_player_attrs *cmd = (void *) buf;
 	size_t len;
 
@@ -265,7 +266,7 @@ static bt_status_t list_player_app_attr_rsp(int num_attr,
 		return BT_STATUS_PARM_INVALID;
 
 	len = sizeof(*cmd) + num_attr;
-	if (len > BLUEZ_HAL_MTU)
+	if (len > IPC_MTU)
 		return BT_STATUS_PARM_INVALID;
 
 	cmd->number = num_attr;
@@ -278,7 +279,7 @@ static bt_status_t list_player_app_attr_rsp(int num_attr,
 
 static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_list_player_values *cmd = (void *) buf;
 	size_t len;
 
@@ -292,7 +293,7 @@ static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
 
 	len = sizeof(*cmd) + num_val;
 
-	if (len > BLUEZ_HAL_MTU)
+	if (len > IPC_MTU)
 		return BT_STATUS_PARM_INVALID;
 
 	cmd->number = num_val;
@@ -305,7 +306,7 @@ static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
 
 static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_get_player_attrs *cmd = (void *) buf;
 	size_t len, attrs_len;
 	int i;
@@ -322,7 +323,7 @@ static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
 				sizeof(struct hal_avrcp_player_attr_value);
 	len = sizeof(*cmd) + attrs_len;
 
-	if (len > BLUEZ_HAL_MTU)
+	if (len > IPC_MTU)
 		return BT_STATUS_PARM_INVALID;
 
 	cmd->number = p_vals->num_attr;
@@ -342,7 +343,7 @@ static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len)
 	struct hal_avrcp_player_setting_text *value = (void *) ptr;
 	size_t attr_len = sizeof(*value);
 
-	if (attr_len + *len > BLUEZ_HAL_MTU)
+	if (attr_len + *len > IPC_MTU)
 		return 0;
 
 	value->id = id;
@@ -351,8 +352,8 @@ static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len)
 	*len += attr_len;
 	ptr += attr_len;
 
-	if (value->len + *len > BLUEZ_HAL_MTU)
-		value->len = BLUEZ_HAL_MTU - *len;
+	if (value->len + *len > IPC_MTU)
+		value->len = IPC_MTU - *len;
 
 	memcpy(value->text, text, value->len);
 
@@ -367,7 +368,7 @@ static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr,
 {
 	int i;
 
-	for (i = 0; i < num_attr && *len < BLUEZ_HAL_MTU; i++) {
+	for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
 		int ret;
 
 		ret = write_text(ptr, p_attrs[i].id, p_attrs[i].text, len);
@@ -383,7 +384,7 @@ static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr,
 static bt_status_t get_player_app_attr_text_rsp(int num_attr,
 					btrc_player_setting_text_t *p_attrs)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_get_player_attrs_text *cmd = (void *) buf;
 	uint8_t *ptr;
 	size_t len;
@@ -408,7 +409,7 @@ static bt_status_t get_player_app_attr_text_rsp(int num_attr,
 static bt_status_t get_player_app_value_text_rsp(int num_val,
 					btrc_player_setting_text_t *p_vals)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_get_player_values_text *cmd = (void *) buf;
 	uint8_t *ptr;
 	size_t len;
@@ -436,7 +437,7 @@ static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr,
 {
 	int i;
 
-	for (i = 0; i < num_attr && *len < BLUEZ_HAL_MTU; i++) {
+	for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
 		int ret;
 
 		ret = write_text(ptr, p_attrs[i].attr_id, p_attrs[i].text, len);
@@ -452,7 +453,7 @@ static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr,
 static bt_status_t get_element_attr_rsp(uint8_t num_attr,
 					btrc_element_attr_val_t *p_attrs)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf;
 	size_t len;
 	uint8_t *ptr;
@@ -490,7 +491,7 @@ static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status)
 static bt_status_t play_status_changed_rsp(btrc_notification_type_t type,
 						btrc_play_status_t *play_status)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
 	size_t len;
 
@@ -509,7 +510,7 @@ static bt_status_t play_status_changed_rsp(btrc_notification_type_t type,
 static bt_status_t track_change_rsp(btrc_notification_type_t type,
 							btrc_uid_t *track)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
 	size_t len;
 
@@ -554,7 +555,7 @@ static bt_status_t track_reached_start_rsp(btrc_notification_type_t type)
 static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type,
 							uint32_t *song_pos)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
 	size_t len;
 
@@ -573,7 +574,7 @@ static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type,
 static bt_status_t settings_changed_rsp(btrc_notification_type_t type,
 					btrc_player_settings_t *player_setting)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
 	struct hal_avrcp_player_attr_value *attrs;
 	size_t len, param_len;
@@ -582,7 +583,7 @@ static bt_status_t settings_changed_rsp(btrc_notification_type_t type,
 	param_len = player_setting->num_attr * sizeof(*attrs);
 	len = sizeof(*cmd) + param_len;
 
-	if (len > BLUEZ_HAL_MTU)
+	if (len > IPC_MTU)
 		return BT_STATUS_PARM_INVALID;
 
 	cmd->event = BTRC_EVT_APP_SETTINGS_CHANGED;
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 3160d7b..6871f5d 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -25,6 +25,7 @@
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "hal-ipc.h"
 #include "hal-utils.h"
 
@@ -525,7 +526,7 @@ static int get_adapter_property(bt_property_type_t type)
 
 static int set_adapter_property(const bt_property_t *property)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_set_adapter_prop *cmd = (void *) buf;
 	size_t len;
 
@@ -582,7 +583,7 @@ static int get_remote_device_property(bt_bdaddr_t *remote_addr,
 static int set_remote_device_property(bt_bdaddr_t *remote_addr,
 						const bt_property_t *property)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_set_remote_device_prop *cmd = (void *) buf;
 	size_t len;
 
@@ -792,7 +793,7 @@ static int dut_mode_configure(uint8_t enable)
 
 static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
 {
-	char cmd_buf[BLUEZ_HAL_MTU];
+	char cmd_buf[IPC_MTU];
 	struct hal_cmd_dut_mode_send *cmd = (void *) cmd_buf;
 	size_t len;
 
@@ -813,7 +814,7 @@ static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
 
 static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
 {
-	char cmd_buf[BLUEZ_HAL_MTU];
+	char cmd_buf[IPC_MTU];
 	struct hal_cmd_le_test_mode *cmd = (void *) cmd_buf;
 	size_t len;
 
diff --git a/android/hal-handsfree.c b/android/hal-handsfree.c
index ab65d95..1b150c3 100644
--- a/android/hal-handsfree.c
+++ b/android/hal-handsfree.c
@@ -23,6 +23,7 @@
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "hal-ipc.h"
 
 static const bthf_callbacks_t *cbs = NULL;
@@ -360,7 +361,7 @@ static bt_status_t device_status_notification(bthf_network_state_t state,
 
 static bt_status_t cops_response(const char *cops)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_handsfree_cops_response *cmd = (void *) buf;
 	size_t len;
 
@@ -408,7 +409,7 @@ static bt_status_t cind_response(int svc, int num_active, int num_held,
 
 static bt_status_t formatted_at_response(const char *rsp)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_handsfree_formatted_at_response *cmd = (void *) buf;
 	size_t len;
 
@@ -454,7 +455,7 @@ static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
 					const char *number,
 					bthf_call_addrtype_t type)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_handsfree_clcc_response *cmd = (void *) buf;
 	size_t len;
 
@@ -489,7 +490,7 @@ static bt_status_t phone_state_change(int num_active, int num_held,
 					const char *number,
 					bthf_call_addrtype_t type)
 {
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	struct hal_cmd_handsfree_phone_state_change *cmd = (void *) buf;
 	size_t len;
 
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index dcaf996..c758d2a 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -23,6 +23,7 @@
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "hal-ipc.h"
 
 static const bthh_callbacks_t *cbacks;
@@ -293,7 +294,7 @@ static bt_status_t set_report(bt_bdaddr_t *bd_addr,
 						bthh_report_type_t report_type,
 						char *report)
 {
-	uint8_t buf[BLUEZ_HAL_MTU];
+	uint8_t buf[IPC_MTU];
 	struct hal_cmd_hidhost_set_report *cmd = (void *) buf;
 
 	DBG("");
@@ -317,7 +318,7 @@ static bt_status_t set_report(bt_bdaddr_t *bd_addr,
 
 static bt_status_t send_data(bt_bdaddr_t *bd_addr, char *data)
 {
-	uint8_t buf[BLUEZ_HAL_MTU];
+	uint8_t buf[IPC_MTU];
 	struct hal_cmd_hidhost_send_data *cmd = (void *) buf;
 
 	DBG("");
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 1ba03f5..fda3228 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -31,6 +31,7 @@
 #include "hal.h"
 #include "hal-msg.h"
 #include "hal-log.h"
+#include "ipc-common.h"
 #include "hal-ipc.h"
 
 #define CONNECT_TIMEOUT (5 * 1000)
@@ -64,7 +65,7 @@ void hal_ipc_unregister(uint8_t service)
 
 static void handle_msg(void *buf, ssize_t len)
 {
-	struct hal_hdr *msg = buf;
+	struct ipc_hdr *msg = buf;
 	const struct hal_ipc_handler *handler;
 	uint8_t opcode;
 
@@ -130,7 +131,7 @@ static void *notification_handler(void *data)
 	struct iovec iv;
 	struct cmsghdr *cmsg;
 	char cmsgbuf[CMSG_SPACE(sizeof(int))];
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	ssize_t ret;
 	int fd;
 
@@ -320,9 +321,9 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
 	ssize_t ret;
 	struct msghdr msg;
 	struct iovec iv[2];
-	struct hal_hdr cmd;
+	struct ipc_hdr cmd;
 	char cmsgbuf[CMSG_SPACE(sizeof(int))];
-	struct hal_status s;
+	struct ipc_status s;
 	size_t s_len = sizeof(s);
 
 	if (cmd_sk < 0) {
@@ -418,7 +419,7 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
 	}
 
 	if (cmd.opcode == HAL_OP_STATUS) {
-		struct hal_status *s = rsp;
+		struct ipc_status *s = rsp;
 
 		if (sizeof(*s) != cmd.len) {
 			error("Invalid status length, aborting");
diff --git a/android/hal-msg.h b/android/hal-msg.h
index bde9717..1e12868 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -21,17 +21,8 @@
  *
  */
 
-#define BLUEZ_HAL_MTU 1024
-
 static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
 
-struct hal_hdr {
-	uint8_t  service_id;
-	uint8_t  opcode;
-	uint16_t len;
-	uint8_t  payload[0];
-} __attribute__((packed));
-
 #define HAL_MINIMUM_EVENT		0x81
 
 #define HAL_SERVICE_ID_CORE		0
@@ -49,7 +40,7 @@ struct hal_hdr {
 
 /* Core Service */
 
-#define HAL_STATUS_SUCCESS		0x00
+#define HAL_STATUS_SUCCESS		IPC_STATUS_SUCCESS
 #define HAL_STATUS_FAILED		0x01
 #define HAL_STATUS_NOT_READY		0x02
 #define HAL_STATUS_NOMEM		0x03
@@ -61,10 +52,7 @@ struct hal_hdr {
 #define HAL_STATUS_AUTH_FAILURE		0x09
 #define HAL_STATUS_REMOTE_DEVICE_DOWN	0x0a
 
-#define HAL_OP_STATUS			0x00
-struct hal_status {
-	uint8_t code;
-} __attribute__((packed));
+#define HAL_OP_STATUS			IPC_OP_STATUS
 
 #define HAL_OP_REGISTER_MODULE		0x01
 struct hal_cmd_register_module {
diff --git a/android/handsfree.c b/android/handsfree.c
index ef8c776..81ddcc7 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -39,6 +39,7 @@
 #include "src/shared/hfp.h"
 #include "btio/btio.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "handsfree.h"
 #include "bluetooth.h"
diff --git a/android/hidhost.c b/android/hidhost.c
index 0c6eb7d..e469210 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -44,6 +44,7 @@
 #include "src/log.h"
 
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "hidhost.h"
 #include "utils.h"
diff --git a/android/ipc-common.h b/android/ipc-common.h
new file mode 100644
index 0000000..27736e4
--- /dev/null
+++ b/android/ipc-common.h
@@ -0,0 +1,38 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#define IPC_MTU 1024
+
+#define IPC_STATUS_SUCCESS	0x00
+
+struct ipc_hdr {
+	uint8_t  service_id;
+	uint8_t  opcode;
+	uint16_t len;
+	uint8_t  payload[0];
+} __attribute__((packed));
+
+#define IPC_OP_STATUS		0x00
+struct ipc_status {
+	uint8_t code;
+} __attribute__((packed));
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index eab8ea5..2378101 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -45,6 +45,8 @@
 #include "src/shared/hciemu.h"
 
 #include "hal-msg.h"
+#include "ipc-common.h"
+
 #include <cutils/properties.h>
 
 #define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
@@ -72,7 +74,7 @@ struct generic_data {
 };
 
 struct regmod_msg {
-	struct hal_hdr header;
+	struct ipc_hdr header;
 	struct hal_cmd_register_module cmd;
 } __attribute__((packed));
 
@@ -413,8 +415,8 @@ static gboolean check_for_daemon(gpointer user_data)
 
 static bool setup_module(int service_id)
 {
-	struct hal_hdr response;
-	struct hal_hdr expected_response;
+	struct ipc_hdr response;
+	struct ipc_hdr expected_response;
 
 	struct regmod_msg btmodule_msg = {
 		.header = {
@@ -564,7 +566,7 @@ static void ipc_send_tc(const void *data)
 
 #define test_opcode_valid(_name, _service, _opcode, _len, _servicelist...) \
 	do {								\
-		static struct hal_hdr hdr = {				\
+		static struct ipc_hdr hdr = {				\
 			.service_id = _service,				\
 			.opcode = _opcode,				\
 			.len = _len,					\
@@ -578,8 +580,8 @@ static void ipc_send_tc(const void *data)
 	} while (0)
 
 struct vardata {
-	struct hal_hdr hdr;
-	uint8_t buf[BLUEZ_HAL_MTU];
+	struct ipc_hdr hdr;
+	uint8_t buf[IPC_MTU];
 } __attribute__((packed));
 
 #define test_datasize_valid(_name, _service, _opcode, _hlen, _addatasize, \
@@ -642,24 +644,24 @@ static struct malformed_data3_struct malformed_data3_msg = {
 	. redundant_data = 666,
 };
 
-struct hal_hdr enable_unknown_service_hdr = {
+struct ipc_hdr enable_unknown_service_hdr = {
 	.service_id = HAL_SERVICE_ID_MAX + 1,
 	.opcode = HAL_OP_REGISTER_MODULE,
 	.len = 0,
 };
 
-struct hal_hdr enable_bt_service_hdr = {
+struct ipc_hdr enable_bt_service_hdr = {
 	.service_id = HAL_SERVICE_ID_BLUETOOTH,
 	.opcode = HAL_OP_ENABLE,
 	.len = 0,
 };
 
 struct bt_set_adapter_prop_data {
-	struct hal_hdr hdr;
+	struct ipc_hdr hdr;
 	struct hal_cmd_set_adapter_prop prop;
 
 	/* data placeholder for hal_cmd_set_adapter_prop.val[0] */
-	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+	uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) -
 				sizeof(struct hal_cmd_set_adapter_prop)];
 } __attribute__((packed));
 
@@ -692,11 +694,11 @@ static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_unders = {
 };
 
 struct bt_set_remote_prop_data {
-	struct hal_hdr hdr;
+	struct ipc_hdr hdr;
 	struct hal_cmd_set_remote_device_prop prop;
 
 	/* data placeholder for hal_cmd_set_remote_device_prop.val[0] */
-	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+	uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) -
 				sizeof(struct hal_cmd_set_remote_device_prop)];
 } __attribute__((packed));
 
@@ -727,11 +729,11 @@ static struct bt_set_remote_prop_data bt_set_remote_prop_data_unders = {
 };
 
 struct hidhost_set_info_data {
-	struct hal_hdr hdr;
+	struct ipc_hdr hdr;
 	struct hal_cmd_hidhost_set_info info;
 
 	/* data placeholder for hal_cmd_hidhost_set_info.descr[0] field */
-	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+	uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) -
 				sizeof(struct hal_cmd_hidhost_set_info)];
 } __attribute__((packed));
 
@@ -762,11 +764,11 @@ static struct hidhost_set_info_data hidhost_set_info_data_unders = {
 };
 
 struct hidhost_set_report_data {
-	struct hal_hdr hdr;
+	struct ipc_hdr hdr;
 	struct hal_cmd_hidhost_set_report report;
 
 	/* data placeholder for hal_cmd_hidhost_set_report.data[0] field */
-	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+	uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) -
 				sizeof(struct hal_cmd_hidhost_set_report)];
 } __attribute__((packed));
 
@@ -797,11 +799,11 @@ static struct hidhost_set_report_data hidhost_set_report_data_unders = {
 };
 
 struct hidhost_send_data_data {
-	struct hal_hdr hdr;
+	struct ipc_hdr hdr;
 	struct hal_cmd_hidhost_send_data hiddata;
 
 	/* data placeholder for hal_cmd_hidhost_send_data.data[0] field */
-	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+	uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) -
 				sizeof(struct hal_cmd_hidhost_send_data)];
 } __attribute__((packed));
 
@@ -935,14 +937,14 @@ int main(int argc, char *argv[])
 	test_generic("Data size BT Set Adapter Prop Vardata+",
 			ipc_send_tc, setup, teardown,
 			&bt_set_adapter_prop_data_overs,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_set_adapter_prop) +
 				sizeof(set_name)),
 			HAL_SERVICE_ID_BLUETOOTH);
 	test_generic("Data size BT Set Adapter Prop Vardata+",
 			ipc_send_tc, setup, teardown,
 			&bt_set_adapter_prop_data_unders,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_set_adapter_prop) +
 				sizeof(set_name)),
 			HAL_SERVICE_ID_BLUETOOTH);
@@ -973,14 +975,14 @@ int main(int argc, char *argv[])
 	test_generic("Data size BT Set Remote Prop Vardata+",
 			ipc_send_tc, setup, teardown,
 			&bt_set_remote_prop_data_overs,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_set_remote_device_prop) +
 				sizeof(set_name)),
 			HAL_SERVICE_ID_BLUETOOTH);
 	test_generic("Data size BT Set Remote Prop Vardata-",
 			ipc_send_tc, setup, teardown,
 			&bt_set_remote_prop_data_unders,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_set_remote_device_prop) +
 				sizeof(set_name)),
 			HAL_SERVICE_ID_BLUETOOTH);
@@ -1127,14 +1129,14 @@ int main(int argc, char *argv[])
 	test_generic("Data size HIDHOST Set Info Vardata+",
 			ipc_send_tc, setup, teardown,
 			&hidhost_set_info_data_overs,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_set_info) +
 				sizeof(set_info_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 	test_generic("Data size HIDHOST Set Info Vardata-",
 			ipc_send_tc, setup, teardown,
 			&hidhost_set_info_data_unders,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_set_info) +
 				sizeof(set_info_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
@@ -1173,14 +1175,14 @@ int main(int argc, char *argv[])
 	test_generic("Data size HIDHOST Set Report Vardata+",
 			ipc_send_tc, setup, teardown,
 			&hidhost_set_report_data_overs,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_set_report) +
 				sizeof(set_rep_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 	test_generic("Data size HIDHOST Set Report Vardata-",
 			ipc_send_tc, setup, teardown,
 			&hidhost_set_report_data_unders,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_set_report) +
 				sizeof(set_rep_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
@@ -1195,14 +1197,14 @@ int main(int argc, char *argv[])
 	test_generic("Data size HIDHOST Send Vardata+",
 			ipc_send_tc, setup, teardown,
 			&hidhost_send_data_overs,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_send_data) +
 				sizeof(send_data_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 	test_generic("Data size HIDHOST Send Vardata-",
 			ipc_send_tc, setup, teardown,
 			&hidhost_send_data_unders,
-			(sizeof(struct hal_hdr) +
+			(sizeof(struct ipc_hdr) +
 				sizeof(struct hal_cmd_hidhost_send_data) +
 				sizeof(send_data_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
diff --git a/android/ipc.c b/android/ipc.c
index 6b14bbe..8cd34ea 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -36,7 +36,7 @@
 #include <unistd.h>
 #include <glib.h>
 
-#include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "src/log.h"
 
@@ -92,7 +92,7 @@ static void ipc_disconnect(struct ipc *ipc, bool in_cleanup)
 static 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_hdr *msg = buf;
 	const struct ipc_handler *handler;
 
 	if (len < (ssize_t) sizeof(*msg)) {
@@ -118,7 +118,7 @@ static int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 	}
 
 	/* if opcode is valid */
-	if (msg->opcode == HAL_OP_STATUS ||
+	if (msg->opcode == IPC_OP_STATUS ||
 			msg->opcode > handlers[msg->service_id].size) {
 		DBG("invalid opcode 0x%x for service 0x%x", msg->opcode,
 							msg->service_id);
@@ -146,7 +146,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 {
 	struct ipc *ipc = user_data;
 
-	char buf[BLUEZ_HAL_MTU];
+	char buf[IPC_MTU];
 	ssize_t ret;
 	int fd, err;
 
@@ -329,7 +329,7 @@ static void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 {
 	struct msghdr msg;
 	struct iovec iv[2];
-	struct hal_hdr m;
+	struct ipc_hdr m;
 	char cmsgbuf[CMSG_SPACE(sizeof(int))];
 	struct cmsghdr *cmsg;
 
@@ -374,19 +374,19 @@ static void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
 								uint8_t status)
 {
-	struct hal_status s;
+	struct ipc_status s;
 	int sk;
 
 	sk = g_io_channel_unix_get_fd(ipc->cmd_io);
 
-	if (status == HAL_STATUS_SUCCESS) {
+	if (status == IPC_STATUS_SUCCESS) {
 		ipc_send(sk, service_id, opcode, 0, NULL, -1);
 		return;
 	}
 
 	s.code = status;
 
-	ipc_send(sk, service_id, HAL_OP_STATUS, sizeof(s), &s, -1);
+	ipc_send(sk, service_id, IPC_OP_STATUS, sizeof(s), &s, -1);
 }
 
 void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
diff --git a/android/main.c b/android/main.c
index bd1bcb9..a6742ef 100644
--- a/android/main.c
+++ b/android/main.c
@@ -48,6 +48,7 @@
 
 #include "lib/bluetooth.h"
 
+#include "ipc-common.h"
 #include "ipc.h"
 #include "bluetooth.h"
 #include "socket.h"
diff --git a/android/pan.c b/android/pan.c
index b4a3494..1e404ab 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -50,6 +50,7 @@
 #include "src/log.h"
 
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "utils.h"
 #include "bluetooth.h"
diff --git a/android/socket.c b/android/socket.c
index d463255..ee98b54 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -39,7 +39,7 @@
 #include "src/log.h"
 
 #include "hal-msg.h"
-#include "hal-ipc.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "utils.h"
 #include "bluetooth.h"
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 6172991..bb7d15f 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -39,9 +39,13 @@
 #include <glib.h>
 #include "src/shared/util.h"
 #include "src/log.h"
-#include "android/hal-msg.h"
+#include "android/ipc-common.h"
 #include "android/ipc.h"
 
+static const char HAL_SK_PATH[] = "\0test_hal_socket";
+
+#define SERVICE_ID_MAX 10
+
 struct test_data {
 	bool disconnect;
 	const void *cmd;
@@ -79,11 +83,11 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
 {
 	struct context *context = user_data;
 	const struct test_data *test_data = context->data;
-	const struct hal_hdr *sent_msg = test_data->cmd;
+	const struct ipc_hdr *sent_msg = test_data->cmd;
 	uint8_t buf[128];
 	int sk;
 
-	struct hal_hdr success_resp = {
+	struct ipc_hdr success_resp = {
 		.service_id = sent_msg->service_id,
 		.opcode = sent_msg->opcode,
 		.len = 0,
@@ -98,8 +102,8 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
 
 	sk = g_io_channel_unix_get_fd(io);
 
-	g_assert(read(sk, buf, sizeof(buf)) == sizeof(struct hal_hdr));
-	g_assert(!memcmp(&success_resp, buf, sizeof(struct hal_hdr)));
+	g_assert(read(sk, buf, sizeof(buf)) == sizeof(struct ipc_hdr));
+	g_assert(!memcmp(&success_resp, buf, sizeof(struct ipc_hdr)));
 
 	context_quit(context);
 
@@ -180,7 +184,7 @@ static struct context *create_context(gconstpointer data)
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
 
-	memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+	memcpy(addr.sun_path, HAL_SK_PATH, sizeof(HAL_SK_PATH));
 
 	ret = bind(sk, (struct sockaddr *) &addr, sizeof(addr));
 	g_assert(ret == 0);
@@ -236,8 +240,8 @@ static void test_init(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-					HAL_SERVICE_ID_MAX, true, NULL, NULL);
+	ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX,
+						true, NULL, NULL);
 
 	g_assert(ipc);
 
@@ -287,8 +291,8 @@ static void test_cmd(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-			HAL_SERVICE_ID_MAX, true, disconnected, context);
+	ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX,
+					true, disconnected, context);
 
 	g_assert(ipc);
 
@@ -305,8 +309,8 @@ static void test_cmd_reg(gconstpointer data)
 	struct context *context = create_context(data);
 	const struct test_data *test_data = context->data;
 
-	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-			HAL_SERVICE_ID_MAX, true, disconnected, context);
+	ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX,
+					true, disconnected, context);
 
 	g_assert(ipc);
 
@@ -325,8 +329,8 @@ static void test_cmd_reg_1(gconstpointer data)
 {
 	struct context *context = create_context(data);
 
-	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
-			HAL_SERVICE_ID_MAX, true, disconnected, context);
+	ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX,
+					true, disconnected, context);
 
 	g_assert(ipc);
 
@@ -357,13 +361,13 @@ static void test_cmd_handler_invalid(const void *buf, uint16_t len)
 
 static const struct test_data test_init_1 = {};
 
-static const struct hal_hdr test_cmd_1_hdr = {
+static const struct ipc_hdr test_cmd_1_hdr = {
 	.service_id = 0,
 	.opcode = 1,
 	.len = 0
 };
 
-static const struct hal_hdr test_cmd_2_hdr = {
+static const struct ipc_hdr test_cmd_2_hdr = {
 	.service_id = 0,
 	.opcode = 2,
 	.len = 0
@@ -443,8 +447,8 @@ static const struct test_data test_cmd_hdr_invalid = {
 #define VARDATA_EX1 "some data example"
 
 struct vardata {
-	struct hal_hdr hdr;
-	uint8_t data[BLUEZ_HAL_MTU - sizeof(struct hal_hdr)];
+	struct ipc_hdr hdr;
+	uint8_t data[IPC_MTU - sizeof(struct ipc_hdr)];
 } __attribute__((packed));
 
 static const struct vardata test_cmd_vardata = {
@@ -460,7 +464,7 @@ static const struct ipc_handler cmd_vardata_handlers[] = {
 
 static const struct test_data test_cmd_vardata_valid = {
 	.cmd = &test_cmd_vardata,
-	.cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1),
+	.cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1),
 	.service = 0,
 	.handlers = cmd_vardata_handlers,
 	.handlers_size = 1,
@@ -472,7 +476,7 @@ static const struct ipc_handler cmd_vardata_handlers_valid2[] = {
 
 static const struct test_data test_cmd_vardata_valid_2 = {
 	.cmd = &test_cmd_vardata,
-	.cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1),
+	.cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1),
 	.service = 0,
 	.handlers = cmd_vardata_handlers_valid2,
 	.handlers_size = 1,
@@ -480,22 +484,22 @@ static const struct test_data test_cmd_vardata_valid_2 = {
 
 static const struct test_data test_cmd_vardata_invalid_1 = {
 	.cmd = &test_cmd_vardata,
-	.cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1) - 1,
+	.cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1) - 1,
 	.service = 0,
 	.handlers = cmd_vardata_handlers,
 	.handlers_size = 1,
 	.disconnect = true,
 };
 
-static const struct hal_hdr test_cmd_service_offrange_hdr = {
-	.service_id = HAL_SERVICE_ID_MAX + 1,
+static const struct ipc_hdr test_cmd_service_offrange_hdr = {
+	.service_id = SERVICE_ID_MAX + 1,
 	.opcode = 1,
 	.len = 0
 };
 
 static const struct test_data test_cmd_service_offrange = {
 	.cmd = &test_cmd_service_offrange_hdr,
-	.cmd_size = sizeof(struct hal_hdr),
+	.cmd_size = sizeof(struct ipc_hdr),
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
@@ -511,7 +515,7 @@ static const struct vardata test_cmd_invalid_data_1 = {
 
 static const struct test_data test_cmd_msg_invalid_1 = {
 	.cmd = &test_cmd_invalid_data_1,
-	.cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1) - 1,
+	.cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1) - 1,
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
@@ -527,7 +531,7 @@ static const struct vardata test_cmd_invalid_data_2 = {
 
 static const struct test_data test_cmd_msg_invalid_2 = {
 	.cmd = &test_cmd_invalid_data_2,
-	.cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1),
+	.cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1),
 	.service = 0,
 	.handlers = cmd_handlers,
 	.handlers_size = 1,
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/6] android: Refactor IPC init
  2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
                   ` (4 preceding siblings ...)
  2014-02-28 13:09 ` [PATCH 6/6] android: Create comon header for IPC Szymon Janc
@ 2014-02-28 14:34 ` Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-02-28 14:34 UTC (permalink / raw)
  To: linux-bluetooth

On Friday 28 of February 2014 14:09:24 Szymon Janc wrote:
> This allows to pass socket path and max service ID while initializaing
> IPC. This is first step to allow use it both for BT and Audio HALs.
> ---
>  android/a2dp.c      |  27 +++++++----
>  android/a2dp.h      |   2 +-
>  android/avrcp.c     |  52 +++++++++++----------
>  android/avrcp.h     |   2 +-
>  android/bluetooth.c | 113 +++++++++++++++++++++++++-------------------
>  android/bluetooth.h |   2 +-
>  android/handsfree.c |  65 ++++++++++++++------------
>  android/handsfree.h |   2 +-
>  android/hidhost.c   |  61 +++++++++++++-----------
>  android/hidhost.h   |   2 +-
>  android/ipc.c       | 132 +++++++++++++++++++++++++++++++++-------------------
>  android/ipc.h       |  24 ++++++----
>  android/main.c      |  41 +++++++++-------
>  android/pan.c       |  32 +++++++------
>  android/pan.h       |   2 +-
>  android/socket.c    |  26 +++++++----
>  android/socket.h    |   2 +-
>  android/test-ipc.c  |  44 ++++++++++++------
>  18 files changed, 374 insertions(+), 257 deletions(-)
> 
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 5d7dc78..b05d4bd 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -39,9 +39,9 @@
>  #include "lib/sdp_lib.h"
>  #include "profiles/audio/a2dp-codecs.h"
>  #include "src/log.h"
> -#include "a2dp.h"
>  #include "hal-msg.h"
>  #include "ipc.h"
> +#include "a2dp.h"
>  #include "utils.h"
>  #include "bluetooth.h"
>  #include "avdtp.h"
> @@ -63,6 +63,8 @@ static uint32_t record_id = 0;
>  static guint audio_retry_id = 0;
>  static bool audio_retrying = false;
>  
> +static struct ipc *hal_ipc = NULL;
> +
>  struct a2dp_preset {
>  	void *data;
>  	int8_t len;
> @@ -226,8 +228,8 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
>  	bdaddr2android(&dev->dst, ev.bdaddr);
>  	ev.state = state;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, sizeof(ev),
> -									&ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE,
> +							sizeof(ev), &ev);
>  
>  	if (state != HAL_A2DP_STATE_DISCONNECTED)
>  		return;
> @@ -253,8 +255,8 @@ static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
>  	bdaddr2android(&setup->dev->dst, ev.bdaddr);
>  	ev.state = state;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE, sizeof(ev),
> -									&ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE,
> +							sizeof(ev), &ev);
>  }
>  
>  static void disconnect_cb(void *user_data)
> @@ -597,7 +599,7 @@ static void bt_a2dp_connect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status);
>  }
>  
>  static void bt_a2dp_disconnect(const void *buf, uint16_t len)
> @@ -631,7 +633,8 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
>  	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
> +									status);
>  }
>  
>  static const struct ipc_handler cmd_handlers[] = {
> @@ -1540,7 +1543,7 @@ retry:
>  						audio_disconnected);
>  }
>  
> -bool bt_a2dp_register(const bdaddr_t *addr)
> +bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	GError *err = NULL;
>  	sdp_record_t *rec;
> @@ -1573,7 +1576,9 @@ bool bt_a2dp_register(const bdaddr_t *addr)
>  	}
>  	record_id = rec->handle;
>  
> -	ipc_register(HAL_SERVICE_ID_A2DP, cmd_handlers,
> +	hal_ipc = ipc;
> +
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
>  	bt_audio_register(audio_disconnected);
> @@ -1600,7 +1605,9 @@ void bt_a2dp_unregister(void)
>  	g_slist_free_full(devices, a2dp_device_free);
>  	devices = NULL;
>  
> -	ipc_unregister(HAL_SERVICE_ID_A2DP);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP);
> +	hal_ipc = NULL;
> +
>  	audio_ipc_unregister();
>  
>  	bt_adapter_remove_record(record_id);
> diff --git a/android/a2dp.h b/android/a2dp.h
> index e626e41..b41a178 100644
> --- a/android/a2dp.h
> +++ b/android/a2dp.h
> @@ -21,5 +21,5 @@
>   *
>   */
>  
> -bool bt_a2dp_register(const bdaddr_t *addr);
> +bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_a2dp_unregister(void);
> diff --git a/android/avrcp.c b/android/avrcp.c
> index 8ff70b4..678c321 100644
> --- a/android/avrcp.c
> +++ b/android/avrcp.c
> @@ -33,12 +33,12 @@
>  #include "lib/sdp.h"
>  #include "lib/sdp_lib.h"
>  #include "src/log.h"
> -#include "bluetooth.h"
>  #include "avctp.h"
> -#include "avrcp.h"
>  #include "avrcp-lib.h"
>  #include "hal-msg.h"
>  #include "ipc.h"
> +#include "bluetooth.h"
> +#include "avrcp.h"
>  
>  #define L2CAP_PSM_AVCTP 0x17
>  
> @@ -51,6 +51,7 @@ static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
>  static GSList *devices = NULL;
>  static GIOChannel *server = NULL;
> +static struct ipc *hal_ipc = NULL;
>  
>  struct avrcp_device {
>  	bdaddr_t	dst;
> @@ -62,79 +63,79 @@ static void handle_get_play_status(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_GET_PLAY_STATUS, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_list_player_attrs(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_LIST_PLAYER_ATTRS, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_list_player_values(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_LIST_PLAYER_VALUES, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_get_player_attrs(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_GET_PLAYER_ATTRS, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_get_player_attrs_text(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_get_player_values_text(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_get_element_attrs_text(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_set_player_attrs_value(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_register_notification(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_REGISTER_NOTIFICATION,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
> +			HAL_OP_AVRCP_REGISTER_NOTIFICATION, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_set_volume(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
>  							HAL_STATUS_FAILED);
>  }
>  
> @@ -363,7 +364,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  	DBG("%s connected", address);
>  }
>  
> -bool bt_avrcp_register(const bdaddr_t *addr)
> +bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	GError *err = NULL;
>  	sdp_record_t *rec;
> @@ -396,7 +397,9 @@ bool bt_avrcp_register(const bdaddr_t *addr)
>  	}
>  	record_id = rec->handle;
>  
> -	ipc_register(HAL_SERVICE_ID_AVRCP, cmd_handlers,
> +	hal_ipc = ipc;
> +
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_AVRCP, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
>  	return true;
> @@ -415,7 +418,8 @@ void bt_avrcp_unregister(void)
>  	g_slist_free_full(devices, avrcp_device_free);
>  	devices = NULL;
>  
> -	ipc_unregister(HAL_SERVICE_ID_AVRCP);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_AVRCP);
> +	hal_ipc = NULL;
>  
>  	bt_adapter_remove_record(record_id);
>  	record_id = 0;
> diff --git a/android/avrcp.h b/android/avrcp.h
> index 1fcd953..3dcffeb 100644
> --- a/android/avrcp.h
> +++ b/android/avrcp.h
> @@ -21,7 +21,7 @@
>   *
>   */
>  
> -bool bt_avrcp_register(const bdaddr_t *addr);
> +bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_avrcp_unregister(void);
>  
>  void bt_avrcp_connect(const bdaddr_t *dst);
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index ac4c213..26493f7 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -145,6 +145,8 @@ static GSList *cached_devices = NULL;
>  /* This list contains addresses which are asked for records */
>  static GSList *browse_reqs;
>  
> +static struct ipc *hal_ipc = NULL;
> +
>  static void store_adapter_config(void)
>  {
>  	GKeyFile *key_file;
> @@ -390,8 +392,8 @@ static  void send_adapter_property(uint8_t type, uint16_t len, const void *val)
>  	ev->props[0].len = len;
>  	memcpy(ev->props[0].val, val, len);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_PROPS_CHANGED,
> -							sizeof(buf), buf);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf);
>  }
>  
>  static void adapter_name_changed(const uint8_t *name)
> @@ -440,8 +442,8 @@ static void powered_changed(void)
>  
>  	DBG("%u", ev.state);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_STATE_CHANGED,
> -							sizeof(ev), &ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_ADAPTER_STATE_CHANGED, sizeof(ev), &ev);
>  }
>  
>  static uint8_t settings2scan_mode(void)
> @@ -594,8 +596,8 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
>  	ev.state = state;
>  	bdaddr2android(addr, ev.bdaddr);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_BOND_STATE_CHANGED,
> -							sizeof(ev), &ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev);
>  }
>  
>  static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
> @@ -647,8 +649,8 @@ static  void send_device_property(const bdaddr_t *bdaddr, uint8_t type,
>  	ev->props[0].len = len;
>  	memcpy(ev->props[0].val, val, len);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_REMOTE_DEVICE_PROPS,
> -							sizeof(buf), buf);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), buf);
>  }
>  
>  static void send_device_uuids_notif(struct device *dev)
> @@ -883,7 +885,7 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
>  	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
>  	hal_ev.class_of_dev = dev->class;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
>  						sizeof(hal_ev), &hal_ev);
>  }
>  
> @@ -901,7 +903,7 @@ static void send_ssp_request(const bdaddr_t *addr, uint8_t variant,
>  	ev.pairing_variant = variant;
>  	ev.passkey = passkey;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST,
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST,
>  							sizeof(ev), &ev);
>  }
>  
> @@ -1010,7 +1012,7 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
>  		cp.state = HAL_DISCOVERY_STATE_STOPPED;
>  	}
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH,
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
>  			HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(cp), &cp);
>  }
>  
> @@ -1106,8 +1108,8 @@ static void update_new_device(struct device *dev, int8_t rssi,
>  		ev->num_props++;
>  	}
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND, size,
> -									buf);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND,
> +								size, buf);
>  }
>  
>  static void update_device(struct device *dev, int8_t rssi,
> @@ -1147,7 +1149,7 @@ static void update_device(struct device *dev, int8_t rssi,
>  	}
>  
>  	if (ev->num_props)
> -		ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH,
> +		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
>  					HAL_EV_REMOTE_DEVICE_PROPS, size, buf);
>  }
>  
> @@ -1259,8 +1261,8 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
>  	hal_ev.state = HAL_ACL_STATE_CONNECTED;
>  	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ACL_STATE_CHANGED,
> -						sizeof(hal_ev), &hal_ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
>  }
>  
>  static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
> @@ -1279,8 +1281,8 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
>  	hal_ev.state = HAL_ACL_STATE_DISCONNECTED;
>  	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ACL_STATE_CHANGED,
> -						sizeof(hal_ev), &hal_ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
>  }
>  
>  static uint8_t status_mgmt2hal(uint8_t mgmt)
> @@ -1502,8 +1504,8 @@ static uint8_t get_adapter_uuids(void)
>  		p += sizeof(uint128_t);
>  	}
>  
> -	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_ADAPTER_PROPS_CHANGED,
> -							sizeof(buf), ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev);
>  
>  	return HAL_STATUS_SUCCESS;
>  }
> @@ -2387,7 +2389,8 @@ static void handle_get_adapter_prop_cmd(const void *buf, uint16_t len)
>  		error("Failed to get adapter property (type %u status %u)",
>  							cmd->type, status);
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP,
> +									status);
>  }
>  
>  static void get_adapter_properties(void)
> @@ -2538,7 +2541,8 @@ static void handle_set_adapter_prop_cmd(const void *buf, uint16_t len)
>  		error("Failed to set adapter property (type %u status %u)",
>  							cmd->type, status);
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP,
> +									status);
>  }
>  
>  static void pair_device_complete(uint8_t status, uint16_t length,
> @@ -2579,7 +2583,8 @@ static void handle_create_bond_cmd(const void *buf, uint16_t len)
>  						HAL_BOND_STATE_BONDING);
>  
>  fail:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND,
> +									status);
>  }
>  
>  static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
> @@ -2597,7 +2602,8 @@ static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
>  	else
>  		status = HAL_STATUS_FAILED;
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND,
> +									status);
>  }
>  
>  static void unpair_device_complete(uint8_t status, uint16_t length,
> @@ -2631,7 +2637,8 @@ static void handle_remove_bond_cmd(const void *buf, uint16_t len)
>  	else
>  		status = HAL_STATUS_FAILED;
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND,
> +									status);
>  }
>  
>  static void handle_pin_reply_cmd(const void *buf, uint16_t len)
> @@ -2682,7 +2689,8 @@ static void handle_pin_reply_cmd(const void *buf, uint16_t len)
>  
>  	status = HAL_STATUS_SUCCESS;
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY,
> +									status);
>  }
>  
>  static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
> @@ -2770,7 +2778,8 @@ static void handle_ssp_reply_cmd(const void *buf, uint16_t len)
>  		break;
>  	}
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY,
> +									status);
>  }
>  
>  static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
> @@ -2783,8 +2792,8 @@ static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
>  
>  	status = browse_remote_sdp(&addr);
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICES,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +					HAL_OP_GET_REMOTE_SERVICES, status);
>  }
>  
>  static uint8_t get_device_uuids(struct device *dev)
> @@ -2907,7 +2916,7 @@ static void handle_enable_cmd(const void *buf, uint16_t len)
>  
>  	status = HAL_STATUS_SUCCESS;
>  reply:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
>  }
>  
>  static void handle_disable_cmd(const void *buf, uint16_t len)
> @@ -2929,15 +2938,15 @@ static void handle_disable_cmd(const void *buf, uint16_t len)
>  
>  	status = HAL_STATUS_SUCCESS;
>  reply:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
>  }
>  
>  static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
>  {
>  	get_adapter_properties();
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS,
> -							HAL_STATUS_SUCCESS);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_OP_GET_ADAPTER_PROPS, HAL_STATUS_SUCCESS);
>  }
>  
>  static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
> @@ -2960,8 +2969,8 @@ static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROPS,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +					HAL_OP_GET_REMOTE_DEVICE_PROPS, status);
>  }
>  
>  static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
> @@ -3017,8 +3026,8 @@ static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
>  							cmd->type, status);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROP,
> -								status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +					HAL_OP_GET_REMOTE_DEVICE_PROP, status);
>  }
>  
>  static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val,
> @@ -3088,8 +3097,8 @@ static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len)
>  							cmd->type, status);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_REMOTE_DEVICE_PROP,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +					HAL_OP_SET_REMOTE_DEVICE_PROP, status);
>  }
>  
>  static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
> @@ -3098,8 +3107,8 @@ static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
>  
>  	error("get_remote_service_record not supported");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICE_REC,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
> +			HAL_OP_GET_REMOTE_SERVICE_REC, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_start_discovery_cmd(const void *buf, uint16_t len)
> @@ -3123,7 +3132,8 @@ static void handle_start_discovery_cmd(const void *buf, uint16_t len)
>  
>  	status = HAL_STATUS_SUCCESS;
>  reply:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY,
> +									status);
>  }
>  
>  static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
> @@ -3148,7 +3158,8 @@ static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  reply:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY,
> +									status);
>  }
>  
>  static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
> @@ -3181,7 +3192,8 @@ static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
>  	close(fd);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF,
> +									status);
>  }
>  
>  static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
> @@ -3198,7 +3210,7 @@ static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
>  
>  	/* TODO */
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
>  							HAL_STATUS_FAILED);
>  }
>  
> @@ -3216,7 +3228,7 @@ static void handle_le_test_mode_cmd(const void *buf, uint16_t len)
>  
>  	/* TODO */
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
>  							HAL_STATUS_FAILED);
>  }
>  
> @@ -3272,11 +3284,13 @@ static const struct ipc_handler cmd_handlers[] = {
>  	{ handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) },
>  };
>  
> -void bt_bluetooth_register(void)
> +void bt_bluetooth_register(struct ipc *ipc)
>  {
>  	DBG("");
>  
> -	ipc_register(HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
> +	hal_ipc = ipc;
> +
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  }
>  
> @@ -3290,5 +3304,6 @@ void bt_bluetooth_unregister(void)
>  	g_slist_free_full(cached_devices, (GDestroyNotify) free_device);
>  	cached_devices = NULL;
>  
> -	ipc_unregister(HAL_SERVICE_ID_CORE);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
> +	hal_ipc = NULL;
>  }
> diff --git a/android/bluetooth.h b/android/bluetooth.h
> index 8ab34f6..fbc850d 100644
> --- a/android/bluetooth.h
> +++ b/android/bluetooth.h
> @@ -31,7 +31,7 @@ void bt_bluetooth_cleanup(void);
>  
>  void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
>  
> -void bt_bluetooth_register(void);
> +void bt_bluetooth_register(struct ipc *ipc);
>  void bt_bluetooth_unregister(void);
>  
>  int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint);
> diff --git a/android/handsfree.c b/android/handsfree.c
> index 60bff91..ef8c776 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -38,11 +38,11 @@
>  #include "src/uuid-helper.h"
>  #include "src/shared/hfp.h"
>  #include "btio/btio.h"
> +#include "hal-msg.h"
> +#include "ipc.h"
>  #include "handsfree.h"
>  #include "bluetooth.h"
>  #include "src/log.h"
> -#include "hal-msg.h"
> -#include "ipc.h"
>  #include "utils.h"
>  
>  #define HFP_AG_CHANNEL 13
> @@ -56,6 +56,7 @@ static struct {
>  
>  static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
> +static struct ipc *hal_ipc = NULL;
>  
>  static GIOChannel *server = NULL;
>  
> @@ -75,8 +76,8 @@ static void device_set_state(uint8_t state)
>  	bdaddr2android(&device.bdaddr, ev.bdaddr);
>  	ev.state = state;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_HANDSFREE, HAL_EV_HANDSFREE_CONN_STATE,
> -							sizeof(ev), &ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +				HAL_EV_HANDSFREE_CONN_STATE, sizeof(ev), &ev);
>  }
>  
>  static void device_init(const bdaddr_t *bdaddr)
> @@ -281,8 +282,8 @@ static void handle_connect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +					HAL_OP_HANDSFREE_CONNECT, status);
>  }
>  
>  static void handle_disconnect(const void *buf, uint16_t len)
> @@ -317,23 +318,23 @@ static void handle_disconnect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_DISCONNECT,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +					HAL_OP_HANDSFREE_DISCONNECT, status);
>  }
>  
>  static void handle_connect_audio(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT_AUDIO,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_CONNECT_AUDIO, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_disconnect_audio(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  			HAL_OP_HANDSFREE_DISCONNECT_AUDIO, HAL_STATUS_FAILED);
>  }
>  
> @@ -341,31 +342,31 @@ static void handle_start_vr(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_START_VR,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +				HAL_OP_HANDSFREE_START_VR, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_stop_vr(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_STOP_VR,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +				HAL_OP_HANDSFREE_STOP_VR, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_volume_control(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_VOLUME_CONTROL,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_VOLUME_CONTROL, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_device_status_notif(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
>  					HAL_STATUS_FAILED);
>  }
> @@ -374,23 +375,23 @@ static void handle_cops(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_COPS_RESPONSE,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_cind(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CIND_RESPONSE,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_formatted_at_resp(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
>  					HAL_STATUS_FAILED);
>  }
> @@ -399,23 +400,23 @@ static void handle_at_resp(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_AT_RESPONSE,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_AT_RESPONSE, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_clcc_resp(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CLCC_RESPONSE,
> -							HAL_STATUS_FAILED);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> +			HAL_OP_HANDSFREE_CLCC_RESPONSE, HAL_STATUS_FAILED);
>  }
>  
>  static void handle_phone_state_change(const void *buf, uint16_t len)
>  {
>  	DBG("");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HANDSFREE,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  					HAL_OP_HANDSFREE_PHONE_STATE_CHANGE,
>  					HAL_STATUS_FAILED);
>  }
> @@ -530,7 +531,7 @@ static sdp_record_t *handsfree_ag_record(void)
>  	return record;
>  }
>  
> -bool bt_handsfree_register(const bdaddr_t *addr)
> +bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	sdp_record_t *rec;
>  	GError *err = NULL;
> @@ -563,7 +564,8 @@ bool bt_handsfree_register(const bdaddr_t *addr)
>  	}
>  	record_id = rec->handle;
>  
> -	ipc_register(HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
> +	hal_ipc = ipc;
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
>  	return true;
> @@ -580,7 +582,8 @@ void bt_handsfree_unregister(void)
>  {
>  	DBG("");
>  
> -	ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE);
> +	hal_ipc = NULL;
>  
>  	if (server) {
>  		g_io_channel_shutdown(server, TRUE, NULL);
> diff --git a/android/handsfree.h b/android/handsfree.h
> index e3fdd70..3ede819 100644
> --- a/android/handsfree.h
> +++ b/android/handsfree.h
> @@ -21,5 +21,5 @@
>   *
>   */
>  
> -bool bt_handsfree_register(const bdaddr_t *addr);
> +bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_handsfree_unregister(void);
> diff --git a/android/hidhost.c b/android/hidhost.c
> index fd5ea4d..0c6eb7d 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -81,6 +81,8 @@ static GIOChannel *ctrl_io = NULL;
>  static GIOChannel *intr_io = NULL;
>  static GSList *devices = NULL;
>  
> +static struct ipc *hal_ipc = NULL;
> +
>  struct hid_device {
>  	bdaddr_t	dst;
>  	uint8_t		state;
> @@ -303,8 +305,8 @@ static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
>  	bdaddr2android(&dev->dst, ev.bdaddr);
>  	ev.state = state;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_CONN_STATE,
> -							sizeof(ev), &ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +				HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev);
>  }
>  
>  static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
> @@ -362,8 +364,8 @@ static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
>  		ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
>  	}
>  
> -	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_PROTO_MODE,
> -							sizeof(ev), &ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +				HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev);
>  }
>  
>  static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
> @@ -405,8 +407,8 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
>  	}
>  
>  send:
> -	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_GET_REPORT,
> -								ev_len, ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev);
>  	g_free(ev);
>  }
>  
> @@ -430,9 +432,8 @@ static void bt_hid_notify_virtual_unplug(struct hid_device *dev,
>  		ev.status = HAL_HIDHOST_STATUS_OK;
>  	}
>  
> -	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_VIRTUAL_UNPLUG,
> -							sizeof(ev), &ev);
> -
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +				HAL_EV_HIDHOST_VIRTUAL_UNPLUG, sizeof(ev), &ev);
>  }
>  
>  static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
> @@ -515,8 +516,8 @@ static void bt_hid_set_info(struct hid_device *dev)
>  	memset(ev.descr, 0, sizeof(ev.descr));
>  	memcpy(ev.descr, dev->rd_data, ev.descr_len);
>  
> -	ipc_send_notif(HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO, sizeof(ev),
> -									&ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
> +							sizeof(ev), &ev);
>  }
>  
>  static int uhid_create(struct hid_device *dev)
> @@ -806,7 +807,8 @@ static void bt_hid_connect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
> +									status);
>  }
>  
>  static void bt_hid_disconnect(const void *buf, uint16_t len)
> @@ -841,7 +843,8 @@ static void bt_hid_disconnect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT,
> +									status);
>  }
>  
>  static void bt_hid_virtual_unplug(const void *buf, uint16_t len)
> @@ -894,8 +897,8 @@ static void bt_hid_virtual_unplug(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_VIRTUAL_UNPLUG,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +					HAL_OP_HIDHOST_VIRTUAL_UNPLUG, status);
>  }
>  
>  static void bt_hid_info(const void *buf, uint16_t len)
> @@ -914,7 +917,7 @@ static void bt_hid_info(const void *buf, uint16_t len)
>  	 * once device is created with HID internals. */
>  	DBG("Not supported");
>  
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
>  							HAL_STATUS_UNSUPPORTED);
>  }
>  
> @@ -964,8 +967,8 @@ static void bt_hid_get_protocol(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_PROTOCOL,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +					HAL_OP_HIDHOST_GET_PROTOCOL, status);
>  }
>  
>  static void bt_hid_set_protocol(const void *buf, uint16_t len)
> @@ -1014,8 +1017,8 @@ static void bt_hid_set_protocol(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_PROTOCOL,
> -									status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
> +					HAL_OP_HIDHOST_SET_PROTOCOL, status);
>  }
>  
>  static void bt_hid_get_report(const void *buf, uint16_t len)
> @@ -1081,7 +1084,8 @@ static void bt_hid_get_report(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT,
> +									status);
>  }
>  
>  static void bt_hid_set_report(const void *buf, uint16_t len)
> @@ -1158,7 +1162,8 @@ static void bt_hid_set_report(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT,
> +									status);
>  }
>  
>  static void bt_hid_send_data(const void *buf, uint16_t len)
> @@ -1224,7 +1229,8 @@ static void bt_hid_send_data(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA,
> +									status);
>  }
>  
>  static const struct ipc_handler cmd_handlers[] = {
> @@ -1323,7 +1329,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  	}
>  }
>  
> -bool bt_hid_register(const bdaddr_t *addr)
> +bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	GError *err = NULL;
>  
> @@ -1358,7 +1364,9 @@ bool bt_hid_register(const bdaddr_t *addr)
>  		return false;
>  	}
>  
> -	ipc_register(HAL_SERVICE_ID_HIDHOST, cmd_handlers,
> +	hal_ipc = ipc;
> +
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_HIDHOST, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
>  	return true;
> @@ -1383,5 +1391,6 @@ void bt_hid_unregister(void)
>  		intr_io = NULL;
>  	}
>  
> -	ipc_unregister(HAL_SERVICE_ID_HIDHOST);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HIDHOST);
> +	hal_ipc = NULL;
>  }
> diff --git a/android/hidhost.h b/android/hidhost.h
> index 5c3c801..1017195 100644
> --- a/android/hidhost.h
> +++ b/android/hidhost.h
> @@ -21,5 +21,5 @@
>   *
>   */
>  
> -bool bt_hid_register(const bdaddr_t *addr);
> +bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_hid_unregister(void);
> diff --git a/android/ipc.c b/android/ipc.c
> index 4a3a60d..3d6e2a3 100644
> --- a/android/ipc.c
> +++ b/android/ipc.c
> @@ -40,13 +40,19 @@
>  #include "ipc.h"
>  #include "src/log.h"
>  
> -static struct service_handler services[HAL_SERVICE_ID_MAX + 1];
> +struct ipc {
> +	struct service_handler *services;
> +	int service_max;
>  
> -static GIOChannel *cmd_io = NULL;
> -static GIOChannel *notif_io = NULL;
> +	const char *path;
> +	size_t size;
>  
> -static guint cmd_watch = 0;
> -static guint notif_watch = 0;
> +	GIOChannel *cmd_io;
> +	guint cmd_watch;
> +
> +	GIOChannel *notif_io;
> +	guint notif_watch;
> +};
>  
>  int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
>  						const void *buf, ssize_t len)
> @@ -103,6 +109,8 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
>  static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
>  							gpointer user_data)
>  {
> +	struct ipc *ipc = user_data;
> +
>  	char buf[BLUEZ_HAL_MTU];
>  	ssize_t ret;
>  	int fd, err;
> @@ -121,7 +129,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
>  		goto fail;
>  	}
>  
> -	err = ipc_handle_msg(services, HAL_SERVICE_ID_MAX, buf, ret);
> +	err = ipc_handle_msg(ipc->services, ipc->service_max, buf, ret);
>  	if (err < 0) {
>  		error("IPC: failed to handle message, terminating (%s)",
>  							strerror(-err));
> @@ -181,6 +189,8 @@ GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
>  static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
>  							gpointer user_data)
>  {
> +	struct ipc *ipc = user_data;
> +
>  	DBG("");
>  
>  	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
> @@ -191,11 +201,11 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
>  
>  	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
>  
> -	notif_watch = g_io_add_watch(io, cond, notif_watch_cb, NULL);
> +	ipc->notif_watch = g_io_add_watch(io, cond, notif_watch_cb, ipc);
>  
>  	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
>  
> -	cmd_watch = g_io_add_watch(cmd_io, cond, cmd_watch_cb, NULL);
> +	ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc);
>  
>  	info("IPC: successfully connected");
>  
> @@ -205,6 +215,8 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
>  static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
>  							gpointer user_data)
>  {
> +	struct ipc *ipc = user_data;
> +
>  	DBG("");
>  
>  	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
> @@ -213,45 +225,62 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
>  		return FALSE;
>  	}
>  
> -	notif_io = ipc_connect(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> -						notif_connect_cb, NULL);
> -	if (!notif_io)
> +	ipc->notif_io = ipc_connect(ipc->path, ipc->size, notif_connect_cb,
> +									ipc);
> +	if (!ipc->notif_io)
>  		raise(SIGTERM);
>  
>  	return FALSE;
>  }
>  
> -void ipc_init(void)
> +struct ipc *ipc_init(const char *path, size_t size, int max_service_id)
>  {
> -	cmd_io = ipc_connect(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> -						cmd_connect_cb, NULL);
> -	if (!cmd_io)
> -		raise(SIGTERM);
> +	struct ipc *ipc;
> +
> +	ipc = g_new0(struct ipc, 1);
> +
> +	ipc->services = g_new0(struct service_handler, max_service_id + 1);
> +	ipc->service_max = max_service_id;
> +
> +	ipc->path = path;
> +	ipc->size = size;
> +
> +	ipc->cmd_io = ipc_connect(path, size, cmd_connect_cb, ipc);
> +	if (!ipc->cmd_io) {
> +		g_free(ipc->services);
> +		g_free(ipc);
> +		return NULL;
> +	}
> +
> +	return ipc;
>  }
>  
> -void ipc_cleanup(void)
> +void ipc_cleanup(struct ipc *ipc)
>  {
> -	if (cmd_watch) {
> -		g_source_remove(cmd_watch);
> -		cmd_watch = 0;
> +	if (ipc->cmd_watch) {
> +		g_source_remove(ipc->cmd_watch);
> +		ipc->cmd_watch = 0;
>  	}
>  
> -	if (cmd_io) {
> -		g_io_channel_shutdown(cmd_io, TRUE, NULL);
> -		g_io_channel_unref(cmd_io);
> -		cmd_io = NULL;
> +	if (ipc->cmd_io) {
> +		g_io_channel_shutdown(ipc->cmd_io, TRUE, NULL);
> +		g_io_channel_unref(ipc->cmd_io);
> +		ipc->cmd_io = NULL;
>  	}
>  
> -	if (notif_watch) {
> -		g_source_remove(notif_watch);
> -		notif_watch = 0;
> +	if (ipc->notif_watch) {
> +		g_source_remove(ipc->notif_watch);
> +		ipc->notif_watch = 0;
>  	}
>  
> -	if (notif_io) {
> -		g_io_channel_shutdown(notif_io, TRUE, NULL);
> -		g_io_channel_unref(notif_io);
> -		notif_io = NULL;
> +	if (ipc->notif_io) {
> +		g_io_channel_shutdown(ipc->notif_io, TRUE, NULL);
> +		g_io_channel_unref(ipc->notif_io);
> +		ipc->notif_io = NULL;
>  	}
> +
> +	g_free(ipc->services);
> +	g_free(ipc);
>  }
>  
>  void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
> @@ -299,12 +328,13 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
>  	}
>  }
>  
> -void ipc_send_rsp(uint8_t service_id, uint8_t opcode, uint8_t status)
> +void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +								uint8_t status)
>  {
>  	struct hal_status s;
>  	int sk;
>  
> -	sk = g_io_channel_unix_get_fd(cmd_io);
> +	sk = g_io_channel_unix_get_fd(ipc->cmd_io);
>  
>  	if (status == HAL_STATUS_SUCCESS) {
>  		ipc_send(sk, service_id, opcode, 0, NULL, -1);
> @@ -316,32 +346,38 @@ void ipc_send_rsp(uint8_t service_id, uint8_t opcode, uint8_t status)
>  	ipc_send(sk, service_id, HAL_OP_STATUS, sizeof(s), &s, -1);
>  }
>  
> -void ipc_send_rsp_full(uint8_t service_id, uint8_t opcode, uint16_t len,
> -							void *param, int fd)
> +void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +					uint16_t len, void *param, int fd)
>  {
> -	ipc_send(g_io_channel_unix_get_fd(cmd_io), service_id, opcode, len,
> +	ipc_send(g_io_channel_unix_get_fd(ipc->cmd_io), service_id, opcode, len,
>  								param, fd);
>  }
>  
> -void ipc_send_notif(uint8_t service_id, uint8_t opcode,  uint16_t len,
> -								void *param)
> +void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +						uint16_t len, void *param)
>  {
> -	if (!notif_io)
> +	if (!ipc || !ipc->notif_io)
>  		return;
>  
> -	ipc_send(g_io_channel_unix_get_fd(notif_io), service_id, opcode, len,
> -								param, -1);
> +	ipc_send(g_io_channel_unix_get_fd(ipc->notif_io), service_id, opcode,
> +								len, param, -1);
>  }
>  
> -void ipc_register(uint8_t service, const struct ipc_handler *handlers,
> -								uint8_t size)
> +void ipc_register(struct ipc *ipc, uint8_t service,
> +			const struct ipc_handler *handlers, uint8_t size)
>  {
> -	services[service].handler = handlers;
> -	services[service].size = size;
> +	if (service > ipc->service_max)
> +		return;
> +
> +	ipc->services[service].handler = handlers;
> +	ipc->services[service].size = size;
>  }
>  
> -void ipc_unregister(uint8_t service)
> +void ipc_unregister(struct ipc *ipc, uint8_t service)
>  {
> -	services[service].handler = NULL;
> -	services[service].size = 0;
> +	if (service > ipc->service_max)
> +		return;
> +
> +	ipc->services[service].handler = NULL;
> +	ipc->services[service].size = 0;
>  }
> diff --git a/android/ipc.h b/android/ipc.h
> index cfa4018..601301c 100644
> --- a/android/ipc.h
> +++ b/android/ipc.h
> @@ -32,20 +32,24 @@ struct service_handler {
>  	uint8_t size;
>  };
>  
> -void ipc_init(void);
> -void ipc_cleanup(void);
> +struct ipc;
> +
> +struct ipc *ipc_init(const char *path, size_t size, int max_service_id);
> +void ipc_cleanup(struct ipc *ipc);
> +
>  GIOChannel *ipc_connect(const char *path, size_t size, GIOFunc connect_cb,
>  							void *user_data);
>  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,
> -							void *param, int fd);
> -void ipc_send_notif(uint8_t service_id, uint8_t opcode,  uint16_t len,
> -								void *param);
> +void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +								uint8_t status);
> +void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +					uint16_t len, void *param, int fd);
> +void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode,
> +						uint16_t len, void *param);
>  void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
>  							void *param, int fd);
> -void ipc_register(uint8_t service, const struct ipc_handler *handlers,
> -								uint8_t size);
> -void ipc_unregister(uint8_t service);
> +void ipc_register(struct ipc *ipc, uint8_t service,
> +			const struct ipc_handler *handlers, uint8_t size);
> +void ipc_unregister(struct ipc *ipc, uint8_t service);
> diff --git a/android/main.c b/android/main.c
> index aca6351..9f22486 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -48,11 +48,11 @@
>  
>  #include "lib/bluetooth.h"
>  
> +#include "ipc.h"
>  #include "bluetooth.h"
>  #include "socket.h"
>  #include "hidhost.h"
>  #include "hal-msg.h"
> -#include "ipc.h"
>  #include "a2dp.h"
>  #include "pan.h"
>  #include "avrcp.h"
> @@ -67,6 +67,8 @@ static bdaddr_t adapter_bdaddr;
>  
>  static GMainLoop *event_loop;
>  
> +static struct ipc *hal_ipc = NULL;
> +
>  static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
>  
>  static void service_register(const void *buf, uint16_t len)
> @@ -81,43 +83,43 @@ static void service_register(const void *buf, uint16_t len)
>  
>  	switch (m->service_id) {
>  	case HAL_SERVICE_ID_BLUETOOTH:
> -		bt_bluetooth_register();
> +		bt_bluetooth_register(hal_ipc);
>  
>  		break;
>  	case HAL_SERVICE_ID_SOCKET:
> -		bt_socket_register(&adapter_bdaddr);
> +		bt_socket_register(hal_ipc, &adapter_bdaddr);
>  
>  		break;
>  	case HAL_SERVICE_ID_HIDHOST:
> -		if (!bt_hid_register(&adapter_bdaddr)) {
> +		if (!bt_hid_register(hal_ipc, &adapter_bdaddr)) {
>  			status = HAL_STATUS_FAILED;
>  			goto failed;
>  		}
>  
>  		break;
>  	case HAL_SERVICE_ID_A2DP:
> -		if (!bt_a2dp_register(&adapter_bdaddr)) {
> +		if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr)) {
>  			status = HAL_STATUS_FAILED;
>  			goto failed;
>  		}
>  
>  		break;
>  	case HAL_SERVICE_ID_PAN:
> -		if (!bt_pan_register(&adapter_bdaddr)) {
> +		if (!bt_pan_register(hal_ipc, &adapter_bdaddr)) {
>  			status = HAL_STATUS_FAILED;
>  			goto failed;
>  		}
>  
>  		break;
>  	case HAL_SERVICE_ID_AVRCP:
> -		if (!bt_avrcp_register(&adapter_bdaddr)) {
> +		if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr)) {
>  			status = HAL_STATUS_FAILED;
>  			goto failed;
>  		}
>  
>  		break;
>  	case HAL_SERVICE_ID_HANDSFREE:
> -		if (!bt_handsfree_register(&adapter_bdaddr)) {
> +		if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr)) {
>  			status = HAL_STATUS_FAILED;
>  			goto failed;
>  		}
> @@ -136,7 +138,8 @@ static void service_register(const void *buf, uint16_t len)
>  	info("Service ID=%u registered", m->service_id);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
> +								status);
>  }
>  
>  static void service_unregister(const void *buf, uint16_t len)
> @@ -186,7 +189,8 @@ static void service_unregister(const void *buf, uint16_t len)
>  	info("Service ID=%u unregistered", m->service_id);
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
> +								status);
>  }
>  
>  static const struct ipc_handler cmd_handlers[] = {
> @@ -240,7 +244,15 @@ static void adapter_ready(int err, const bdaddr_t *addr)
>  
>  	info("Adapter initialized");
>  
> -	ipc_init();
> +	hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> +							HAL_SERVICE_ID_MAX);
> +	if (!hal_ipc) {
> +		error("Failed to initialize IPC");
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_CORE, cmd_handlers,
> +						G_N_ELEMENTS(cmd_handlers));
>  }
>  
>  static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
> @@ -464,9 +476,6 @@ int main(int argc, char *argv[])
>  	/* Use params: mtu = 0, flags = 0 */
>  	start_sdp_server(0, 0);
>  
> -	ipc_register(HAL_SERVICE_ID_CORE, cmd_handlers,
> -						G_N_ELEMENTS(cmd_handlers));
> -
>  	DBG("Entering main loop");
>  
>  	event_loop = g_main_loop_new(NULL, FALSE);
> @@ -480,12 +489,12 @@ int main(int argc, char *argv[])
>  
>  	cleanup_services();
>  
> -	ipc_cleanup();
>  	stop_sdp_server();
>  	bt_bluetooth_cleanup();
>  	g_main_loop_unref(event_loop);
>  
> -	ipc_unregister(HAL_SERVICE_ID_CORE);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
> +	ipc_cleanup(hal_ipc);
>  
>  	info("Exit");
>  
> diff --git a/android/pan.c b/android/pan.c
> index cfc03bc..b4a3494 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -49,11 +49,11 @@
>  #include "profiles/network/bnep.h"
>  #include "src/log.h"
>  
> -#include "pan.h"
>  #include "hal-msg.h"
>  #include "ipc.h"
>  #include "utils.h"
>  #include "bluetooth.h"
> +#include "pan.h"
>  
>  #define SVC_HINT_NETWORKING 0x02
>  
> @@ -64,6 +64,7 @@
>  static bdaddr_t adapter_addr;
>  GSList *devices = NULL;
>  uint8_t local_role = HAL_PAN_ROLE_NONE;
> +static struct ipc *hal_ipc = NULL;
>  
>  struct pan_device {
>  	char		iface[16];
> @@ -247,8 +248,8 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
>  	ev.remote_role = dev->role;
>  	ev.status = HAL_STATUS_SUCCESS;
>  
> -	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
> -									&ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE,
> +							sizeof(ev), &ev);
>  	if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
>  		pan_device_remove(dev);
>  }
> @@ -270,8 +271,8 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
>  	else
>  		memcpy(ev.name, dev->iface, sizeof(dev->iface));
>  
> -	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE, sizeof(ev),
> -									&ev);
> +	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE,
> +							sizeof(ev), &ev);
>  }
>  
>  static void bnep_disconn_cb(void *data)
> @@ -414,7 +415,7 @@ static void bt_pan_connect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
>  }
>  
>  static void bt_pan_disconnect(const void *buf, uint16_t len)
> @@ -444,7 +445,8 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT,
> +									status);
>  }
>  
>  static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond,
> @@ -676,7 +678,7 @@ static void bt_pan_enable(const void *buf, uint16_t len)
>  	status = HAL_STATUS_SUCCESS;
>  
>  reply:
> -	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
>  }
>  
>  static void bt_pan_get_role(const void *buf, uint16_t len)
> @@ -686,8 +688,8 @@ static void bt_pan_get_role(const void *buf, uint16_t len)
>  	DBG("");
>  
>  	rsp.local_role = local_role;
> -	ipc_send_rsp_full(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, sizeof(rsp),
> -								&rsp, -1);
> +	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE,
> +							sizeof(rsp), &rsp, -1);
>  }
>  
>  static const struct ipc_handler cmd_handlers[] = {
> @@ -776,7 +778,7 @@ static sdp_record_t *pan_record(void)
>  	return record;
>  }
>  
> -bool bt_pan_register(const bdaddr_t *addr)
> +bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	sdp_record_t *rec;
>  	int err;
> @@ -813,7 +815,9 @@ bool bt_pan_register(const bdaddr_t *addr)
>  	}
>  
>  	nap_dev.record_id = rec->handle;
> -	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
> +
> +	hal_ipc = ipc;
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_PAN, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
>  	return true;
> @@ -829,7 +833,9 @@ void bt_pan_unregister(void)
>  
>  	bnep_cleanup();
>  
> -	ipc_unregister(HAL_SERVICE_ID_PAN);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_PAN);
> +	hal_ipc = NULL;
> +
>  	bt_adapter_remove_record(nap_dev.record_id);
>  	nap_dev.record_id = 0;
>  	destroy_nap_device();
> diff --git a/android/pan.h b/android/pan.h
> index 72a7eab..2045ac5 100644
> --- a/android/pan.h
> +++ b/android/pan.h
> @@ -21,5 +21,5 @@
>   *
>   */
>  
> -bool bt_pan_register(const bdaddr_t *addr);
> +bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_pan_unregister(void);
> diff --git a/android/socket.c b/android/socket.c
> index 655ee40..d463255 100644
> --- a/android/socket.c
> +++ b/android/socket.c
> @@ -38,11 +38,11 @@
>  #include "src/sdpd.h"
>  #include "src/log.h"
>  
> -#include "bluetooth.h"
>  #include "hal-msg.h"
>  #include "hal-ipc.h"
>  #include "ipc.h"
>  #include "utils.h"
> +#include "bluetooth.h"
>  #include "socket.h"
>  
>  #define RFCOMM_CHANNEL_MAX 30
> @@ -60,6 +60,7 @@
>  #define MAP_MSG_TYPE_SMS_CDMA	0x04
>  #define DEFAULT_MAS_MSG_TYPE	(MAP_MSG_TYPE_SMS_GSM | MAP_MSG_TYPE_SMS_CDMA)
>  
> +static struct ipc *hal_ipc = NULL;
>  struct rfcomm_sock {
>  	int channel;	/* RFCOMM channel */
>  	BtIOSecLevel sec_level;
> @@ -862,13 +863,14 @@ static void handle_listen(const void *buf, uint16_t len)
>  	if (status != HAL_STATUS_SUCCESS)
>  		goto failed;
>  
> -	ipc_send_rsp_full(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, 0, NULL,
> -								hal_sock);
> +	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
> +							0, NULL, hal_sock);
>  	close(hal_sock);
>  	return ;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN,
> +									status);
>  }
>  
>  static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
> @@ -1106,13 +1108,14 @@ static void handle_connect(const void *buf, uint16_t len)
>  	if (status != HAL_STATUS_SUCCESS)
>  		goto failed;
>  
> -	ipc_send_rsp_full(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, 0,
> -							 NULL, hal_sock);
> +	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
> +							0, NULL, hal_sock);
>  	close(hal_sock);
>  	return;
>  
>  failed:
> -	ipc_send_rsp(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, status);
> +	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT,
> +									status);
>  
>  }
>  
> @@ -1123,7 +1126,7 @@ static const struct ipc_handler cmd_handlers[] = {
>  	{ handle_connect, false, sizeof(struct hal_cmd_socket_connect) },
>  };
>  
> -void bt_socket_register(const bdaddr_t *addr)
> +void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr)
>  {
>  	size_t i;
>  
> @@ -1137,7 +1140,9 @@ void bt_socket_register(const bdaddr_t *addr)
>  			servers[profiles[i].channel].reserved = true;
>  
>  	bacpy(&adapter_addr, addr);
> -	ipc_register(HAL_SERVICE_ID_SOCKET, cmd_handlers,
> +
> +	hal_ipc = ipc;
> +	ipc_register(hal_ipc, HAL_SERVICE_ID_SOCKET, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  }
>  
> @@ -1155,5 +1160,6 @@ void bt_socket_unregister(void)
>  
>  	memset(servers, 0, sizeof(servers));
>  
> -	ipc_unregister(HAL_SERVICE_ID_SOCKET);
> +	ipc_unregister(hal_ipc, HAL_SERVICE_ID_SOCKET);
> +	hal_ipc = NULL;
>  }
> diff --git a/android/socket.h b/android/socket.h
> index d41616f..d3ed9b4 100644
> --- a/android/socket.h
> +++ b/android/socket.h
> @@ -30,5 +30,5 @@ struct hal_sock_connect_signal {
>  
>  void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
>  
> -void bt_socket_register(const bdaddr_t *addr);
> +void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr);
>  void bt_socket_unregister(void);
> diff --git a/android/test-ipc.c b/android/test-ipc.c
> index 8dd53a1..054af84 100644
> --- a/android/test-ipc.c
> +++ b/android/test-ipc.c
> @@ -43,6 +43,8 @@
>  #include "android/hal-msg.h"
>  #include "android/ipc.h"
>  
> +static struct ipc *ipc = NULL;
> +
>  struct test_data {
>  	uint32_t expected_signal;
>  	const void *cmd;
> @@ -283,11 +285,15 @@ static void test_init(gconstpointer data)
>  {
>  	struct context *context = create_context(data);
>  
> -	ipc_init();
> +	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> +							HAL_SERVICE_ID_MAX);
> +
> +	g_assert(ipc);
>  
>  	execute_context(context);
>  
> -	ipc_cleanup();
> +	ipc_cleanup(ipc);
> +	ipc = NULL;
>  }
>  
>  static gboolean send_cmd(gpointer user_data)
> @@ -310,7 +316,7 @@ static gboolean register_service(gpointer user_data)
>  	struct context *context = user_data;
>  	const struct test_data *test_data = context->data;
>  
> -	ipc_register(test_data->service, test_data->handlers,
> +	ipc_register(ipc, test_data->service, test_data->handlers,
>  						test_data->handlers_size);
>  
>  	return FALSE;
> @@ -321,7 +327,7 @@ static gboolean unregister_service(gpointer user_data)
>  	struct context *context = user_data;
>  	const struct test_data *test_data = context->data;
>  
> -	ipc_unregister(test_data->service);
> +	ipc_unregister(ipc, test_data->service);
>  
>  	return FALSE;
>  }
> @@ -330,13 +336,17 @@ static void test_cmd(gconstpointer data)
>  {
>  	struct context *context = create_context(data);
>  
> -	ipc_init();
> +	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> +							HAL_SERVICE_ID_MAX);
> +
> +	g_assert(ipc);
>  
>  	g_idle_add(send_cmd, context);
>  
>  	execute_context(context);
>  
> -	ipc_cleanup();
> +	ipc_cleanup(ipc);
> +	ipc = NULL;
>  }
>  
>  static void test_cmd_reg(gconstpointer data)
> @@ -344,23 +354,30 @@ static void test_cmd_reg(gconstpointer data)
>  	struct context *context = create_context(data);
>  	const struct test_data *test_data = context->data;
>  
> -	ipc_init();
> +	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> +							HAL_SERVICE_ID_MAX);
> +
> +	g_assert(ipc);
>  
>  	g_idle_add(register_service, context);
>  	g_idle_add(send_cmd, context);
>  
>  	execute_context(context);
>  
> -	ipc_unregister(test_data->service);
> +	ipc_unregister(ipc, test_data->service);
>  
> -	ipc_cleanup();
> +	ipc_cleanup(ipc);
> +	ipc = NULL;
>  }
>  
>  static void test_cmd_reg_1(gconstpointer data)
>  {
>  	struct context *context = create_context(data);
>  
> -	ipc_init();
> +	ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
> +							HAL_SERVICE_ID_MAX);
> +
> +	g_assert(ipc);
>  
>  	g_idle_add(register_service, context);
>  	g_idle_add(unregister_service, context);
> @@ -368,17 +385,18 @@ static void test_cmd_reg_1(gconstpointer data)
>  
>  	execute_context(context);
>  
> -	ipc_cleanup();
> +	ipc_cleanup(ipc);
> +	ipc = NULL;
>  }
>  
>  static void test_cmd_handler_1(const void *buf, uint16_t len)
>  {
> -	ipc_send_rsp(0, 1, 0);
> +	ipc_send_rsp(ipc, 0, 1, 0);
>  }
>  
>  static void test_cmd_handler_2(const void *buf, uint16_t len)
>  {
> -	ipc_send_rsp(0, 2, 0);
> +	ipc_send_rsp(ipc, 0, 2, 0);
>  }
>  
>  static void test_cmd_handler_invalid(const void *buf, uint16_t len)
> 

All patches are now upstream.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-02-28 14:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-28 13:09 [PATCH 1/6] android: Refactor IPC init Szymon Janc
2014-02-28 13:09 ` [PATCH 2/6] android: Add support for registering disconnect callback in IPC Szymon Janc
2014-02-28 13:09 ` [PATCH 3/6] android/unit: Update test-ipc with disconnect handler support Szymon Janc
2014-02-28 13:09 ` [PATCH 4/6] android: Add support for disabling notifications in IPC Szymon Janc
2014-02-28 13:09 ` [PATCH 5/6] android/a2dp: Use common IPC for audio socket Szymon Janc
2014-02-28 13:09 ` [PATCH 6/6] android: Create comon header for IPC Szymon Janc
2014-02-28 14:34 ` [PATCH 1/6] android: Refactor IPC init Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.