Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv2 1/2] android: Add PTS PICS for GAP
From: Jakub Tyszkowski @ 2013-11-15 10:45 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384512332-21906-1-git-send-email-jakub.tyszkowski@tieto.com>

PTS PICS for GAP, targeting Android 4.4.

---
 android/pics-gap.txt | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)
 create mode 100644 android/pics-gap.txt

diff --git a/android/pics-gap.txt b/android/pics-gap.txt
new file mode 100644
index 0000000..1ef94a6
--- /dev/null
+++ b/android/pics-gap.txt
@@ -0,0 +1,223 @@
+GAP PICS for the PTS tool.
+
+* - different than PTS defaults
+
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_GAP_0_1	False		BR/EDR
+TSPC_GAP_0_2	False		LE
+TSPC_GAP_0_3	True (*)	BR/EDR/LE
+TSPC_GAP_0A_1	False		Core Specification Addendum 3 (CSA3),
+					GAP Connection Parameters Changes,
+					Authentication and Lost Bond Changes,
+					Private Addressing Changes,
+					Dual Mode Addressing Changes,
+					Adopted 24 July 2012
+TSPC_GAP_1_1	True (*)	Non-discoverable mode
+TSPC_GAP_1_2	False		Limited-discoverable mode
+TSPC_GAP_1_3	True (*)	General-discoverable mode
+TSPC_GAP_1_4	True (*)	Non-connectable mode
+TSPC_GAP_1_5	True		Connectable mode
+TSPC_GAP_1_6	False		Non-bondable mode
+TSPC_GAP_1_7	True (*)	Bondable mode
+TSPC_GAP_2_1	True (*)	Authentication procedure
+TSPC_GAP_2_2	True (*)	Support of LMP-Authentication
+TSPC_GAP_2_3	True (*)	Initiate LMP-Authentication
+TSPC_GAP_2_4	False		Security mode 1
+TSPC_GAP_2_5	True (*)	Security mode 2
+TSPC_GAP_2_6	False		Security mode 3
+TSPC_GAP_2_7	True (*)	Security mode 4
+TSPC_GAP_2_8	True (*)	Support of Authenticated link key
+TSPC_GAP_2_9	True (*)	Support of Unauthenticated link key
+TSPC_GAP_2_10	False		No security
+TSPC_GAP_3_1	True (*)	Initiation of general inquiry
+TSPC_GAP_3_2	False		Initiation of limited inquiry
+TSPC_GAP_3_3	True (*)	Initiation of name discover
+TSPC_GAP_3_4	True (*)	Initiation of device discovery
+TSPC_GAP_3_5	True (*)	Initiation of general bonding
+TSPC_GAP_3_6	True (*)	Initiation of dedicated bonding
+TSPC_GAP_4_1	True		Support link establishment as initiator
+TSPC_GAP_4_2	True		Support link establishment as acceptor
+TSPC_GAP_4_3	True (*)	Support channel establishment as initiator
+TSPC_GAP_4_4	True		Support channel establishment as acceptor
+TSPC_GAP_4_5	True (*)	Support connection establishment as initiator
+TSPC_GAP_4_6	True (*)	Support connection establishment as acceptor
+TSPC_GAP_5_1	False (*)	Broadcaster
+TSPC_GAP_5_2	False		Observer
+TSPC_GAP_5_3	False (*)	Peripheral
+TSPC_GAP_5_4	True (*)	Central
+TSPC_GAP_6_1	False (*)	Broadcaster: Transmitter
+TSPC_GAP_6_2	False		Broadcaster: Receiver
+TSPC_GAP_7_1	False (*)	Broadcaster: Standby
+TSPC_GAP_7_2	False (*)	Broadcaster: Advertising
+TSPC_GAP_8_1	False (*)	Broadcaster: Non-Connectable Undirected Event
+TSPC_GAP_8_2	False		Broadcaster: Scannable Undirected Event
+TSPC_GAP_8A_1	False		AD Type-Service UUID
+TSPC_GAP_8A_2	False		AD Type-Local Name
+TSPC_GAP_8A_3	False (*)	AD Type-Flags
+TSPC_GAP_8A_4	False		AD Type-Manufacturer Specific Data
+TSPC_GAP_8A_5	False		AD Type-TX Power Level
+TSPC_GAP_8A_6	False		AD Type-Security Manager Out of Band (OOB)
+TSPC_GAP_8A_7	False		AD Type-Security manager TK Value
+TSPC_GAP_8A_8	False		AD Type-Slave Connection Interval Range
+TSPC_GAP_8A_9	False		AD Type-Service Solicitation
+TSPC_GAP_8A_10	False		AD Type-Service Data
+TSPC_GAP_9_1	False (*)	Broadcaster: Non-Connectable Mode
+TSPC_GAP_10_1	False (*)	Broadcaster: Broadcast Mode
+TSPC_GAP_11_1	False		Broadcaster: Privacy Feature
+TSPC_GAP_11_2	False		Broadcaster: Resolvable Private Address
+					Generation Procedure
+TSPC_GAP_12_1	True		Observer: Receiver
+TSPC_GAP_12_2	False		Observer: Transmitter
+TSPC_GAP_13_1	True		Observer: Standby
+TSPC_GAP_13_2	True		Observer: Scanning
+TSPC_GAP_14_1	True		Observer: Passive Scanning
+TSPC_GAP_14_2	False		Observer: Active Scanning
+TSPC_GAP_15_1	True		Observer: Non-Connectable Mode
+TSPC_GAP_16_1	True		Observer: Observation Procedure
+TSPC_GAP_17_1	False		Observer: Privacy Feature
+TSPC_GAP_17_2	False		Observer: Non-Resolvable Private Address
+					Generation Procedure
+TSPC_GAP_17_3	False		Observer: Resolvable Private Address Resolution
+					Procedure
+TSPC_GAP_17_4	False		Observer: Resolvable Private Address Generation
+					Procedure
+TSPC_GAP_18_1	False		Peripheral: Transmitter
+TSPC_GAP_18_2	False		Peripheral: Receiver
+TSPC_GAP_19_1	False		Peripheral: Standby
+TSPC_GAP_19_2	False		Peripheral: Advertising
+TSPC_GAP_19_3	False		Peripheral: Connection, Slave Role
+TSPC_GAP_20_1	False		Peripheral: Connectable Undirected Event
+TSPC_GAP_20_2	False		Peripheral: Connectable Directed Event
+TSPC_GAP_20_3	False		Peripheral: Non-Connectable Undirected Event
+TSPC_GAP_20_4	False		Peripheral: Scannable Undirected Event
+TSPC_GAP_20A_1	False		AD Type-Service UUID
+TSPC_GAP_20A_2	False		AD Type-Local Name
+TSPC_GAP_20A_3	False		AD Type-Flags
+TSPC_GAP_20A_4	False		AD Type-Manufacturer Specific Data
+TSPC_GAP_20A_5	False		AD Type-TX Power Level
+TSPC_GAP_20A_6	False		AD Type-Security Manager Out of Band (OOB)
+TSPC_GAP_20A_7	False		AD Type-Security manager TK Value
+TSPC_GAP_20A_8	False		AD Type-Slave Connection Interval Range
+TSPC_GAP_20A_9	False		AD Type-Service Solicitation
+TSPC_GAP_20A_10	False		AD Type-Service Data
+TSPC_GAP_21_1	False (*)	Peripheral: Connection Update Procedure
+TSPC_GAP_21_2	False (*)	Peripheral: Channel Map Update Procedure
+TSPC_GAP_21_3	False		Peripheral: Encryption Procedure
+TSPC_GAP_21_4	False (*)	Peripheral: Feature Exchange Procedure
+TSPC_GAP_21_5	False (*)	Peripheral: Version Exchange Procedure
+TSPC_GAP_21_6	False (*)	Peripheral: Termination Procedure
+TSPC_GAP_22_1	False		Peripheral: Non-Discoverable Mode
+TSPC_GAP_22_2	False		Peripheral: Limited Discoverable Mode
+TSPC_GAP_22_3	False		Peripheral: General Discoverable Mode
+TSPC_GAP_22_4	False		Peripheral: Name Discovery Procedure
+TSPC_GAP_23_1	False		Peripheral: Non-Connectable Mode
+TSPC_GAP_23_2	False		Peripheral: Directed Connectable Mode
+TSPC_GAP_23_3	False		Peripheral: Undirected Connectable Mode
+TSPC_GAP_23_4	False		Peripheral: Connection Parameter Update
+					Procedure
+TSPC_GAP_23_5	False		Peripheral: Terminate Connection Procedure
+TSPC_GAP_24_1	False		Peripheral: Non-Bondable Mode
+TSPC_GAP_24_2	False		Peripheral: Bondable Mode
+TSPC_GAP_24_3	False		Peripheral: Bonding Procedure
+TSPC_GAP_24_4	False		Peripheral: Multiple Bonds
+TSPC_GAP_25_1	False		Peripheral: Security Mode 1
+TSPC_GAP_25_2	False		Peripheral: Security Mode 2
+TSPC_GAP_25_3	False		Peripheral: Authentication Procedure
+TSPC_GAP_25_4	False		Peripheral: Authorization Procedure
+TSPC_GAP_25_5	False		Peripheral: Connection Data Signing Procedure
+TSPC_GAP_25_6	False		Peripheral: Authenticate Signed Data Procedure
+TSPC_GAP_25_7	False		Peripheral: Authenticated Pairing
+					(LE security mode 1 level 3)
+TSPC_GAP_25_8	False		Peripheral: Unauthenticated Pairing
+					(LE security mode 1 level 2)
+TSPC_GAP_26_1	False		Peripheral: Privacy Feature
+TSPC_GAP_26_2	False		Peripheral: Non-Resolvable Private Address
+					Generation Procedure
+TSPC_GAP_26_3	False		Peripheral: Resolvable Private Address
+					Generation Procedure
+TSPC_GAP_27_1	False (*)	Peripheral: Device Name
+TSPC_GAP_27_2	False (*)	Peripheral: Appearance
+TSPC_GAP_27_3	False		Peripheral: Peripheral Privacy Flag
+TSPC_GAP_27_4	False		Peripheral: Reconnection Address
+TSPC_GAP_27_5	False		Peripheral: Peripheral Preferred Connection
+					Parameters
+TSPC_GAP_27_6	False		Peripheral: Writeable Device Name
+TSPC_GAP_27_7	False		Peripheral: Writeable Appearance
+TSPC_GAP_27_8	False		Peripheral: Writeable Peripheral Privacy Flag
+TSPC_GAP_28_1	True (*)	Central: Transmitter
+TSPC_GAP_28_2	True (*)	Central: Receiver
+TSPC_GAP_29_1	True (*)	Central: Standby
+TSPC_GAP_29_2	True (*)	Central: Scanning
+TSPC_GAP_29_3	True (*)	Central: Initiating
+TSPC_GAP_29_4	True (*)	Central: Connection, Master Role
+TSPC_GAP_30_1	True (*)	Central: Passive Scanning
+TSPC_GAP_30_2	True (*)	Central: Active Scanning
+TSPC_GAP_31_1	True (*)	Central: Connection Update Procedure
+TSPC_GAP_31_2	True (*)	Central: Channel Map Update Procedure
+TSPC_GAP_31_3	True (*)	Central: Encryption Procedure
+TSPC_GAP_31_4	True (*)	Central: Feature Exchange Procedure
+TSPC_GAP_31_5	True (*)	Central: Version Exchange Procedure
+TSPC_GAP_31_6	True (*)	Central: Termination Procedure
+TSPC_GAP_32_1	False		Central: Limited Discovery Procedure
+TSPC_GAP_32_2	True (*)	Central: General Discovery Procedure
+TSPC_GAP_32_3	True (*)	Central: Name Discovery Procedure
+TSPC_GAP_33_1	True (*)	Central: Auto Connection Establishment
+					Procedure
+TSPC_GAP_33_2	True (*)	Central: General Connection Establishment
+					Procedure
+TSPC_GAP_33_3	True (*)	Central: Selective Connection Establishment
+					Procedure
+TSPC_GAP_33_4	True (*)	Central: Direct Connectin Establishment
+					Procedure
+TSPC_GAP_33_5	True (*)	Central: Connection Parameter Update Procedure
+TSPC_GAP_33_6	True (*)	Central: Terminate Connection Procedure
+TSPC_GAP_34_1	False		Central: Non-Bondable Mode
+TSPC_GAP_34_2	True (*)	Central: Bondable Mode
+TSPC_GAP_34_3	True (*)	Central: Bonding Procedure
+TSPC_GAP_35_1	True (*)	Central: Security Mode 1
+TSPC_GAP_35_2	True (*)	Central: Security Mode 2
+TSPC_GAP_35_3	True (*)	Central: Authentication Procedure
+TSPC_GAP_35_4	True (*)	Central: Authorization Procedure
+TSPC_GAP_35_5	True (*)	Central: Connection Data Signing Procedure
+TSPC_GAP_35_6	True (*)	Central: Authenticate Signed Data Procedure
+TSPC_GAP_35_7	False		Central: Authenticated Pairing
+					(LE security mode 1 level 3)
+TSPC_GAP_35_8	False		Central: Unauthenticated Pairing
+					(LE security mode 1 level 2)
+TSPC_GAP_36_1	False		Central: Privacy Feature
+TSPC_GAP_36_2	False		Central: Non-Resolvable Private Address
+					Generation Procedure
+TSPC_GAP_36_3	False		Central: Resolvable Private Address Resolution
+					Procedure
+TSPC_GAP_36_4	False		Central: Write to Privacy Characteristic
+					(Enable/Disable Privacy)
+TSPC_GAP_37_1	True (*)	Central: Device Name
+TSPC_GAP_37_2	True (*)	Central: Appearance
+TSPC_GAP_38_1	False		BR/EDR/LE: Broadcaster
+TSPC_GAP_38_2	True (*)	BR/EDR/LE: Observer
+TSPC_GAP_38_3	False		BR/EDR/LE: Peripheral
+TSPC_GAP_38_4	True (*)	BR/EDR/LE: Central
+TSPC_GAP_39_1	True (*)	Central BR/EDR/LE: Non-Discoverable Mode
+TSPC_GAP_39_2	True (*)	Central BR/EDR/LE: Discoverable Mode
+TSPC_GAP_39_3	True (*)	Central BR/EDR/LE: Non-Connectable Mode
+TSPC_GAP_39_4	True		Central BR/EDR/LE: Connectable Mode
+TSPC_GAP_39_5	False		Central BR/EDR/LE: Non-Bondable Mode
+TSPC_GAP_39_6	True (*)	Central BR/EDR/LE: Bondable Mode
+TSPC_GAP_40_1	True (*)	Central BR/EDR/LE: General Discovery
+TSPC_GAP_40_2	False		Central BR/EDR/LE: Limited Discovery
+TSPC_GAP_40_3	True (*)	Central BR/EDR/LE: Device Type Discovery
+TSPC_GAP_40_4	True (*)	Central BR/EDR/LE: Name Discovery
+TSPC_GAP_40_5	True (*)	Central BR/EDR/LE: Link Establishment
+TSPC_GAP_41_1	True		Central BR/EDR/LE: Security Aspects
+TSPC_GAP_42_1	False		Peripheral BR/EDR/LE: Non-Discoverable Mode
+TSPC_GAP_42_2	False		Peripheral BR/EDR/LE: Discoverable Mode
+TSPC_GAP_42_3	False		Peripheral BR/EDR/LE: Non-Connectable Mode
+TSPC_GAP_42_4	False (*)	Peripheral BR/EDR/LE: Connectable Mode
+TSPC_GAP_42_5	False		Peripheral BR/EDR/LE: Non-Bondable Mode
+TSPC_GAP_42_6	False		Peripheral BR/EDR/LE: Bondable Mode
+TSPC_GAP_43_1	False (*)	Peripheral BR/EDR/LE: Security Aspects
+TSPC_SM_1_1	False		Master Role (Initiator)
+TSPC_SM_1_2	False		Slave Role (Responder)
+TSPC_SM_2_4	False		OOB supported
+TSPC_ALL	False		Turns on all
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 0/2] PICS for GAP and HID
From: Jakub Tyszkowski @ 2013-11-15 10:45 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384435587-12427-1-git-send-email-jakub.tyszkowski@tieto.com>

v1: initial documents with PICS targeting Android 4.4
v2: layout changed, each parameter description added

Jakub Tyszkowski (2):
  android: Add PTS PICS for GAP
  android: Add PTS PICS for HID

 android/pics-gap.txt | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++
 android/pics-hid.txt | 125 +++++++++++++++++++++++++++++
 2 files changed, 348 insertions(+)
 create mode 100644 android/pics-gap.txt
 create mode 100644 android/pics-hid.txt

-- 
1.8.4.1


^ permalink raw reply

* [PATCH 3/3] android/hal: Unregister Bluetooth on cleanup
From: Andrei Emeltchenko @ 2013-11-15 10:13 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384510435-17497-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 This is more like RFC. Shall we send this event or this will be cleaned up itself.

 android/hal-bluetooth.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 8cd4327..4bf1183 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -379,11 +379,18 @@ static int disable(void)
 
 static void cleanup(void)
 {
+	struct hal_cmd_register_module cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return;
 
+	cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
+
+	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+					sizeof(cmd), &cmd, NULL, NULL, NULL);
+
 	hal_ipc_cleanup();
 
 	bt_hal_cbacks = NULL;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/3] android/hal: Remove unneeded code
From: Andrei Emeltchenko @ 2013-11-15 10:13 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384510435-17497-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Socket HAL always registers with Bluetooth HAL and there is no sense
to send 2 commands over IPC.
---
 android/hal-bluetooth.c |    9 ---------
 1 file changed, 9 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 078d537..8cd4327 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -347,15 +347,6 @@ static int init(bt_callbacks_t *callbacks)
 		goto fail;
 	}
 
-	cmd.service_id = HAL_SERVICE_ID_SOCK;
-
-	status = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
-					sizeof(cmd), &cmd, NULL, NULL, NULL);
-	if (status != BT_STATUS_SUCCESS) {
-		error("Failed to register 'socket' service");
-		goto fail;
-	}
-
 	return status;
 
 fail:
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/3] android/hal: Merge bluetooth and sock register/unregister
From: Andrei Emeltchenko @ 2013-11-15 10:13 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Bluetooth and Socket HAL are registered and unregistered at the
same time.
---
 android/main.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/android/main.c b/android/main.c
index a4f5e84..f72004c 100644
--- a/android/main.c
+++ b/android/main.c
@@ -87,10 +87,11 @@ static void service_register(void *buf, uint16_t len)
 		if (!bt_bluetooth_register(sk))
 			goto failed;
 
-		break;
-	case HAL_SERVICE_ID_SOCK:
-		if (!bt_socket_register(sk, &adapter_bdaddr))
+		if (!bt_socket_register(sk, &adapter_bdaddr)) {
+			bt_bluetooth_unregister();
 			goto failed;
+		}
+		services[HAL_SERVICE_ID_SOCK] = true;
 
 		break;
 	case HAL_SERVICE_ID_HIDHOST:
@@ -135,8 +136,6 @@ static void service_unregister(void *buf, uint16_t len)
 	switch (m->service_id) {
 	case HAL_SERVICE_ID_BLUETOOTH:
 		bt_bluetooth_unregister();
-		break;
-	case HAL_SERVICE_ID_SOCK:
 		bt_socket_unregister();
 		break;
 	case HAL_SERVICE_ID_HIDHOST:
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH 1/2] android/pan: Fix wrong HAL service id
From: Johan Hedberg @ 2013-11-15 10:03 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1384509565-27465-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Fri, Nov 15, 2013, Ravi kumar Veeramally wrote:
> ---
>  android/pan.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] android/hal-ipc: Add pan notification call to hal-ipc dispatch handler
From: Ravi kumar Veeramally @ 2013-11-15  9:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384509565-27465-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-ipc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index e1c8dd7..026e245 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -55,6 +55,9 @@ static void notification_dispatch(struct hal_hdr *msg, int fd)
 	case HAL_SERVICE_ID_A2DP:
 		bt_notify_a2dp(msg->opcode, msg->payload, msg->len);
 		break;
+	case HAL_SERVICE_ID_PAN:
+		bt_notify_pan(msg->opcode, msg->payload, msg->len);
+		break;
 	default:
 		DBG("Unhandled notification service=%d opcode=0x%x",
 						msg->service_id, msg->opcode);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] android/pan: Fix wrong HAL service id
From: Ravi kumar Veeramally @ 2013-11-15  9:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

---
 android/pan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/pan.c b/android/pan.c
index 061e611..46b3700 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -87,7 +87,7 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 		break;
 	}
 
-	ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, status);
+	ipc_send_rsp(sk, HAL_SERVICE_ID_PAN, status);
 }
 
 bool bt_pan_register(int sk, const bdaddr_t *addr)
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH BlueZ] build: Fix out of tree builds
From: Andre Heider @ 2013-11-15  9:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384451935-4836-1-git-send-email-a.heider@gmail.com>

On Thu, Nov 14, 2013 at 6:58 PM, Andre Heider <a.heider@gmail.com> wrote:
> Don't create bogus symlinks when passing an absolute path to --prefix.

No idea how that happened, but I meant:
Don't create bogus symlinks when calling the configure script via an
absolute path.

;)

Regards,
Andre

^ permalink raw reply

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
From: Marcel Holtmann @ 2013-11-15  9:32 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <20131115092317.GA7413@aemeltch-MOBL1>

Hi Andrei,

>>> Handle events from Android framework. Write everything to real RFCOMM
>>> socket.
>>> ---
>>> android/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 42 insertions(+)
>>> 
>>> diff --git a/android/socket.c b/android/socket.c
>>> index c9ee32f..07743f6 100644
>>> --- a/android/socket.c
>>> +++ b/android/socket.c
>>> @@ -118,6 +118,48 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
>>> static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
>>> 								gpointer data)
>>> {
>>> +	struct rfcomm_slot *rfslot = data;
>>> +	unsigned char buf[1024] = { 0 };
>> 
>> since why are we doing this { 0 } thing?
>> 
>>> +	int len, sent;
>>> +
>>> +	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
>>> +		rfslot->fd, rfslot->real_sock, rfslot->channel,
>>> +		g_io_channel_unix_get_fd(io));
>>> +
>>> +	if (!g_list_find(rfcomm_connected_list, rfslot)) {
>>> +		error("rfslot %p not found in the list", rfslot);
>>> +		return FALSE;
>>> +	}
>>> +
>>> +	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
>>> +		error("Socket error: sock %d cond %d",
>>> +					g_io_channel_unix_get_fd(io), cond);
>>> +		rfcomm_connected_list = g_list_remove(rfcomm_connected_list,
>>> +								rfslot);
>>> +		cleanup_rfslot(rfslot);
>>> +		return FALSE;
>>> +	}
>>> +
>>> +	/* FIXME check fd vs sock(io) */
>> 
>> I do not even understand this FIXME. Why not get it right in the fist place.
>> 
>>> +	len = recv(rfslot->fd, buf, sizeof(buf), 0);
>>> +	if (len <= 0) {
>>> +		error("recv(): %s", strerror(errno));
>>> +		return FALSE;
>>> +	}
>>> +
>>> +	DBG("read %d bytes write to %d", len, rfslot->real_sock);
>>> +
>>> +	sent = send(rfslot->real_sock, buf, len, 0);
>>> +	if (sent < 0) {
>>> +		error("send(): %s", strerror(errno));
>>> +		return FALSE;
>>> +	}
>>> +
>>> +	if (sent != len) {
>>> +		error("send(): sent %d bytes out of %d", sent, len);
>>> +		return FALSE;
>>> +	}
>> 
>> Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.
>> 
> 
> So shall we retry to send the several (say 3) times here?

you can have partial success here as well. You need to keep sending until you succeeded or get other errors then the ones mentioned above.

Regards

Marcel


^ permalink raw reply

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
From: Andrei Emeltchenko @ 2013-11-15  9:23 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <91DA1530-80F5-41BE-BDC6-6A03BA9B4C33@holtmann.org>

Hi Marcel,

On Fri, Nov 15, 2013 at 09:00:51AM +0900, Marcel Holtmann wrote:
> Hi Andrei,
> 
> > Handle events from Android framework. Write everything to real RFCOMM
> > socket.
> > ---
> > android/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 42 insertions(+)
> > 
> > diff --git a/android/socket.c b/android/socket.c
> > index c9ee32f..07743f6 100644
> > --- a/android/socket.c
> > +++ b/android/socket.c
> > @@ -118,6 +118,48 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
> > static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
> > 								gpointer data)
> > {
> > +	struct rfcomm_slot *rfslot = data;
> > +	unsigned char buf[1024] = { 0 };
> 
> since why are we doing this { 0 } thing?
> 
> > +	int len, sent;
> > +
> > +	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
> > +		rfslot->fd, rfslot->real_sock, rfslot->channel,
> > +		g_io_channel_unix_get_fd(io));
> > +
> > +	if (!g_list_find(rfcomm_connected_list, rfslot)) {
> > +		error("rfslot %p not found in the list", rfslot);
> > +		return FALSE;
> > +	}
> > +
> > +	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
> > +		error("Socket error: sock %d cond %d",
> > +					g_io_channel_unix_get_fd(io), cond);
> > +		rfcomm_connected_list = g_list_remove(rfcomm_connected_list,
> > +								rfslot);
> > +		cleanup_rfslot(rfslot);
> > +		return FALSE;
> > +	}
> > +
> > +	/* FIXME check fd vs sock(io) */
> 
> I do not even understand this FIXME. Why not get it right in the fist place.
> 
> > +	len = recv(rfslot->fd, buf, sizeof(buf), 0);
> > +	if (len <= 0) {
> > +		error("recv(): %s", strerror(errno));
> > +		return FALSE;
> > +	}
> > +
> > +	DBG("read %d bytes write to %d", len, rfslot->real_sock);
> > +
> > +	sent = send(rfslot->real_sock, buf, len, 0);
> > +	if (sent < 0) {
> > +		error("send(): %s", strerror(errno));
> > +		return FALSE;
> > +	}
> > +
> > +	if (sent != len) {
> > +		error("send(): sent %d bytes out of %d", sent, len);
> > +		return FALSE;
> > +	}
> 
> Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.
> 

So shall we retry to send the several (say 3) times here?

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* [RFC v2 5/5] android/hal-a2dp: Use generic IPC message handling for events
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384479617-15555-1-git-send-email-szymon.janc@tieto.com>

Register handlers on service init and unregister on cleanup.
---
 android/hal-a2dp.c | 41 +++++++++++++++++++++--------------------
 android/hal.h      |  1 -
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index e9fadb7..757a8ce 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -31,7 +31,7 @@ static bool interface_ready(void)
 	return cbs != NULL;
 }
 
-static void handle_conn_state(void *buf)
+static void handle_conn_state(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_a2dp_conn_state *ev = buf;
 
@@ -40,7 +40,7 @@ static void handle_conn_state(void *buf)
 						(bt_bdaddr_t *) (ev->bdaddr));
 }
 
-static void handle_audio_state(void *buf)
+static void handle_audio_state(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_a2dp_audio_state *ev = buf;
 
@@ -48,24 +48,19 @@ static void handle_audio_state(void *buf)
 		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
 }
 
-/* will be called from notification thread context */
-void bt_notify_a2dp(uint8_t opcode, void *buf, uint16_t len)
-{
-	if (!interface_ready())
-		return;
-
-	switch (opcode) {
-	case HAL_EV_A2DP_CONN_STATE:
-		handle_conn_state(buf);
-		break;
-	case HAL_EV_A2DP_AUDIO_STATE:
-		handle_audio_state(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
-}
+/* handlers will be called from notification thread context */
+static const struct hal_msg_handler ev_handlers[] = {
+	{
+		.handler = handle_conn_state,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_pan_conn_state),
+	},
+	{
+		.handler = handle_audio_state,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_pan_ctrl_state),
+	},
+};
 
 static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr)
 {
@@ -105,6 +100,10 @@ static bt_status_t init(btav_callbacks_t *callbacks)
 
 	cbs = callbacks;
 
+	hal_msg_register(HAL_SERVICE_ID_A2DP, ev_handlers,
+				sizeof(ev_handlers)/sizeof(ev_handlers[0]),
+				HAL_MINIMUM_EVENT);
+
 	cmd.service_id = HAL_SERVICE_ID_A2DP;
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
@@ -126,6 +125,8 @@ static void cleanup()
 
 	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
+
+	hal_msg_unregister(HAL_SERVICE_ID_A2DP);
 }
 
 static btav_interface_t iface = {
diff --git a/android/hal.h b/android/hal.h
index 6bd4c5a..b475411 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -28,4 +28,3 @@ btav_interface_t *bt_get_a2dp_interface(void);
 
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
-void bt_notify_a2dp(uint8_t opcode, void *buf, uint16_t len);
-- 
1.8.4.3


^ permalink raw reply related

* [RFC v2 4/5] android/hal-pan: Use generic IPC message handling for events
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384479617-15555-1-git-send-email-szymon.janc@tieto.com>

Register handlers on service init and unregister on cleanup.
---
 android/hal-pan.c | 40 +++++++++++++++++++++-------------------
 android/hal.h     |  1 -
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index 2bc560e..4190d0b 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -31,7 +31,7 @@ static bool interface_ready(void)
 	return cbs != NULL;
 }
 
-static void handle_conn_state(void *buf)
+static void handle_conn_state(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_pan_conn_state *ev = buf;
 
@@ -41,7 +41,7 @@ static void handle_conn_state(void *buf)
 					ev->local_role, ev->remote_role);
 }
 
-static void handle_ctrl_state(void *buf)
+static void handle_ctrl_state(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_pan_ctrl_state *ev = buf;
 
@@ -50,23 +50,19 @@ static void handle_ctrl_state(void *buf)
 					ev->local_role, (char *)ev->name);
 }
 
-void bt_notify_pan(uint8_t opcode, void *buf, uint16_t len)
-{
-	if (!interface_ready())
-		return;
-
-	switch (opcode) {
-	case HAL_EV_PAN_CONN_STATE:
-		handle_conn_state(buf);
-		break;
-	case HAL_EV_PAN_CTRL_STATE:
-		handle_ctrl_state(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
-}
+/* handlers will be called from notification thread context */
+static const struct hal_msg_handler ev_handlers[] = {
+	{
+		.handler = handle_conn_state,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_pan_conn_state),
+	},
+	{
+		.handler = handle_ctrl_state,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_pan_ctrl_state),
+	},
+};
 
 static bt_status_t pan_enable(int local_role)
 {
@@ -143,6 +139,10 @@ static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
 
 	cbs = callbacks;
 
+	hal_msg_register(HAL_SERVICE_ID_PAN, ev_handlers,
+				sizeof(ev_handlers)/sizeof(ev_handlers[0]),
+				HAL_MINIMUM_EVENT);
+
 	cmd.service_id = HAL_SERVICE_ID_PAN;
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
@@ -164,6 +164,8 @@ static void pan_cleanup()
 
 	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
+
+	hal_msg_unregister(HAL_SERVICE_ID_PAN);
 }
 
 static btpan_interface_t pan_if = {
diff --git a/android/hal.h b/android/hal.h
index 58426a9..6bd4c5a 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -29,4 +29,3 @@ btav_interface_t *bt_get_a2dp_interface(void);
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
 void bt_notify_a2dp(uint8_t opcode, void *buf, uint16_t len);
-void bt_notify_pan(uint8_t opcode, void *buf, uint16_t len);
-- 
1.8.4.3


^ permalink raw reply related

* [RFC v2 3/5] android/hal-hidhost: Use generic IPC message handling for events
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384479617-15555-1-git-send-email-szymon.janc@tieto.com>

Register handlers on service init and unregister on cleanup.
---
 android/hal-hidhost.c | 76 +++++++++++++++++++++++++++++----------------------
 android/hal.h         |  1 -
 2 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 2ce17a3..a1726d8 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -32,7 +32,7 @@ static bool interface_ready(void)
 	return cbacks != NULL;
 }
 
-static void handle_conn_state(void *buf)
+static void handle_conn_state(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_hidhost_conn_state *ev = buf;
 
@@ -41,7 +41,7 @@ static void handle_conn_state(void *buf)
 								ev->state);
 }
 
-static void handle_info(void *buf)
+static void handle_info(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_hidhost_info *ev = buf;
 	bthh_hid_info_t info;
@@ -60,7 +60,7 @@ static void handle_info(void *buf)
 		cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
 }
 
-static void handle_proto_mode(void *buf)
+static void handle_proto_mode(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_hidhost_proto_mode *ev = buf;
 
@@ -69,16 +69,21 @@ static void handle_proto_mode(void *buf)
 							ev->status, ev->mode);
 }
 
-static void handle_get_report(void *buf)
+static void handle_get_report(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_hidhost_get_report *ev = buf;
 
+	if (len != sizeof(*ev) + ev->len) {
+		error("invalid get report event, aborting");
+		exit(EXIT_FAILURE);
+	}
+
 	if (cbacks->get_report_cb)
 		cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
 							ev->data, ev->len);
 }
 
-static void handle_virtual_unplug(void *buf)
+static void handle_virtual_unplug(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_hidhost_virtual_unplug *ev = buf;
 
@@ -87,33 +92,34 @@ static void handle_virtual_unplug(void *buf)
 								ev->status);
 }
 
-/* will be called from notification thread context */
-void bt_notify_hidhost(uint8_t opcode, void *buf, uint16_t len)
-{
-	if (!interface_ready())
-		return;
-
-	switch (opcode) {
-	case HAL_EV_HIDHOST_CONN_STATE:
-		handle_conn_state(buf);
-		break;
-	case HAL_EV_HIDHOST_INFO:
-		handle_info(buf);
-		break;
-	case HAL_EV_HIDHOST_PROTO_MODE:
-		handle_proto_mode(buf);
-		break;
-	case HAL_EV_HIDHOST_GET_REPORT:
-		handle_get_report(buf);
-		break;
-	case HAL_EV_HIDHOST_VIRTUAL_UNPLUG:
-		handle_virtual_unplug(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
-}
+/* handlers will be called from notification thread context */
+static const struct hal_msg_handler ev_handlers[] = {
+	{
+		.handler = handle_conn_state,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_hidhost_conn_state)
+	},
+	{
+		.handler = handle_info,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_hidhost_info),
+	},
+	{
+		.handler = handle_proto_mode,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_hidhost_proto_mode),
+	},
+	{
+		.handler = handle_get_report,
+		.var_len = true,
+		.data_len = sizeof(struct hal_ev_hidhost_get_report),
+	},
+	{
+		.handler = handle_virtual_unplug,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_hidhost_virtual_unplug),
+	},
+};
 
 static bt_status_t hidhost_connect(bt_bdaddr_t *bd_addr)
 {
@@ -362,6 +368,10 @@ static bt_status_t init(bthh_callbacks_t *callbacks)
 	/* store reference to user callbacks */
 	cbacks = callbacks;
 
+	hal_msg_register(HAL_SERVICE_ID_HIDHOST, ev_handlers,
+				sizeof(ev_handlers)/sizeof(ev_handlers[0]),
+				HAL_MINIMUM_EVENT);
+
 	cmd.service_id = HAL_SERVICE_ID_HIDHOST;
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
@@ -383,6 +393,8 @@ static void cleanup(void)
 
 	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
+
+	hal_msg_unregister(HAL_SERVICE_ID_HIDHOST);
 }
 
 static bthh_interface_t hidhost_if = {
diff --git a/android/hal.h b/android/hal.h
index 67dad5d..58426a9 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -28,6 +28,5 @@ btav_interface_t *bt_get_a2dp_interface(void);
 
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
-void bt_notify_hidhost(uint8_t opcode, void *buf, uint16_t len);
 void bt_notify_a2dp(uint8_t opcode, void *buf, uint16_t len);
 void bt_notify_pan(uint8_t opcode, void *buf, uint16_t len);
-- 
1.8.4.3


^ permalink raw reply related

* [RFC v2 2/5] android/hal-bluetooth: Use generic IPC message handling for events
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384479617-15555-1-git-send-email-szymon.janc@tieto.com>

Register handlers on service init. Since this requires all handlers to
be registered (unknown opcode is considered IPC error) missing handlers
stubs are provided.
---
 android/hal-bluetooth.c | 221 ++++++++++++++++++++++++++++++------------------
 android/hal-ipc.c       |  45 ++--------
 android/hal.h           |   1 -
 3 files changed, 145 insertions(+), 122 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 078d537..4176563 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -35,7 +35,7 @@ static const bt_callbacks_t *bt_hal_cbacks = NULL;
 	*pe = *((uint8_t *) (hal_prop->val)); \
 } while (0)
 
-static void handle_adapter_state_changed(void *buf)
+static void handle_adapter_state_changed(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_adapter_state_changed *ev = buf;
 
@@ -45,38 +45,35 @@ static void handle_adapter_state_changed(void *buf)
 		bt_hal_cbacks->adapter_state_changed_cb(ev->state);
 }
 
-static void adapter_props_to_hal(bt_property_t *send_props,
-					struct hal_property *hal_prop,
-					uint8_t num_props, void *buff_end)
+static void adapter_props_to_hal(bt_property_t *send_props, void *buf,
+							uint8_t num_props)
 {
-	void *p = hal_prop;
+	struct hal_property *prop = buf;
 	uint8_t i;
 
 	for (i = 0; i < num_props; i++) {
-		if (p + sizeof(*hal_prop) + hal_prop->len > buff_end) {
-			error("invalid adapter properties event, aborting");
-			exit(EXIT_FAILURE);
-		}
-
-		send_props[i].type = hal_prop->type;
+		send_props[i].type = prop->type;
 
-		switch (hal_prop->type) {
+		switch (prop->type) {
 		case HAL_PROP_ADAPTER_TYPE:
-			create_enum_prop(send_props[i], hal_prop,
+			create_enum_prop(send_props[i], prop,
 							bt_device_type_t);
 			break;
 		case HAL_PROP_ADAPTER_SCAN_MODE:
-			create_enum_prop(send_props[i], hal_prop,
+			create_enum_prop(send_props[i], prop,
 							bt_scan_mode_t);
 			break;
 		case HAL_PROP_ADAPTER_SERVICE_REC:
 		default:
-			send_props[i].len = hal_prop->len;
-			send_props[i].val = hal_prop->val;
+			send_props[i].len = prop->len;
+			send_props[i].val = prop->val;
 			break;
 		}
 
 		DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
+
+		buf += sizeof(*prop) + prop->len;
+		prop = buf;
 	}
 }
 
@@ -96,36 +93,30 @@ static void adapter_hal_props_cleanup(bt_property_t *props, uint8_t num)
 	}
 }
 
-static void device_props_to_hal(bt_property_t *send_props,
-					struct hal_property *hal_prop,
-					uint8_t num_props, void *buff_end)
+static void device_props_to_hal(bt_property_t *send_props, void *buf,
+							uint8_t num_props)
 {
-	void *p = hal_prop;
+	struct hal_property *prop = buf;
 	uint8_t i;
 
 	for (i = 0; i < num_props; i++) {
-		if (p + sizeof(*hal_prop) + hal_prop->len > buff_end) {
-			error("invalid adapter properties event, aborting");
-			exit(EXIT_FAILURE);
-		}
-
-		send_props[i].type = hal_prop->type;
+		send_props[i].type = prop->type;
 
-		switch (hal_prop->type) {
+		switch (prop->type) {
 		case HAL_PROP_DEVICE_TYPE:
-			create_enum_prop(send_props[i], hal_prop,
+			create_enum_prop(send_props[i], prop,
 							bt_device_type_t);
 			break;
 		case HAL_PROP_DEVICE_SERVICE_REC:
 		case HAL_PROP_DEVICE_VERSION_INFO:
 		default:
-			send_props[i].len = hal_prop->len;
-			send_props[i].val = hal_prop->val;
+			send_props[i].len = prop->len;
+			send_props[i].val = prop->val;
 			break;
 		}
 
-		p += sizeof(*hal_prop) + hal_prop->len;
-		hal_prop = p;
+		buf += sizeof(*prop) + prop->len;
+		prop = buf;
 
 		DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
 	}
@@ -147,24 +138,45 @@ static void device_hal_props_cleanup(bt_property_t *props, uint8_t num)
 	}
 }
 
-static void handle_adapter_props_changed(void *buf, uint16_t len)
+static void check_props(int num, const struct hal_property *prop, uint16_t len)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		if (sizeof(*prop) + prop->len < len)
+			goto fail;
+
+		len -= sizeof(*prop) + prop->len;
+	}
+
+	if (!len)
+		return;
+
+fail:
+	error("invalid properties event, aborting");
+	exit(EXIT_FAILURE);
+}
+
+static void handle_adapter_props_changed(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_adapter_props_changed *ev = buf;
 	bt_property_t props[ev->num_props];
 
 	DBG("");
 
+	check_props(ev->num_props, ev->props, len - sizeof(*ev));
+
 	if (!bt_hal_cbacks->adapter_properties_cb)
 		return;
 
-	adapter_props_to_hal(props, ev->props, ev->num_props, buf + len);
+	adapter_props_to_hal(props, ev->props, ev->num_props);
 
 	bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
 
 	adapter_hal_props_cleanup(props, ev->num_props);
 }
 
-static void handle_bond_state_change(void *buf)
+static void handle_bond_state_change(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_bond_state_changed *ev = buf;
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
@@ -176,7 +188,7 @@ static void handle_bond_state_change(void *buf)
 								ev->state);
 }
 
-static void handle_pin_request(void *buf)
+static void handle_pin_request(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_pin_request *ev = buf;
 	/* Those are declared as packed, so it's safe to assign pointers */
@@ -189,7 +201,7 @@ static void handle_pin_request(void *buf)
 		bt_hal_cbacks->pin_request_cb(addr, name, ev->class_of_dev);
 }
 
-static void handle_ssp_request(void *buf)
+static void handle_ssp_request(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_ssp_request *ev = buf;
 	/* Those are declared as packed, so it's safe to assign pointers */
@@ -221,7 +233,7 @@ static bool interface_ready(void)
 	return bt_hal_cbacks != NULL;
 }
 
-static void handle_discovery_state_changed(void *buf)
+static void handle_discovery_state_changed(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_discovery_state_changed *ev = buf;
 
@@ -231,34 +243,38 @@ static void handle_discovery_state_changed(void *buf)
 		bt_hal_cbacks->discovery_state_changed_cb(ev->state);
 }
 
-static void handle_device_found(void *buf, uint16_t len)
+static void handle_device_found(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_device_found *ev = buf;
 	bt_property_t props[ev->num_props];
 
 	DBG("");
 
+	check_props(ev->num_props, ev->props, len - sizeof(*ev));
+
 	if (!bt_hal_cbacks->device_found_cb)
 		return;
 
-	device_props_to_hal(props, ev->props, ev->num_props, buf + len);
+	device_props_to_hal(props, ev->props, ev->num_props);
 
 	bt_hal_cbacks->device_found_cb(ev->num_props, props);
 
 	device_hal_props_cleanup(props, ev->num_props);
 }
 
-static void handle_device_state_changed(void *buf, uint16_t len)
+static void handle_device_state_changed(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_remote_device_props *ev = buf;
 	bt_property_t props[ev->num_props];
 
 	DBG("");
 
+	check_props(ev->num_props, ev->props, len - sizeof(*ev));
+
 	if (!bt_hal_cbacks->remote_device_properties_cb)
 		return;
 
-	device_props_to_hal(props, ev->props, ev->num_props, buf + len);
+	device_props_to_hal(props, ev->props, ev->num_props);
 
 	bt_hal_cbacks->remote_device_properties_cb(ev->status,
 						(bt_bdaddr_t *)ev->bdaddr,
@@ -267,7 +283,7 @@ static void handle_device_state_changed(void *buf, uint16_t len)
 	device_hal_props_cleanup(props, ev->num_props);
 }
 
-static void handle_acl_state_changed(void *buf)
+static void handle_acl_state_changed(void *buf, uint16_t len, int fd)
 {
 	struct hal_ev_acl_state_changed *ev = buf;
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
@@ -279,48 +295,82 @@ static void handle_acl_state_changed(void *buf)
 								ev->state);
 }
 
-/* will be called from notification thread context */
-void bt_notify_adapter(uint8_t opcode, void *buf, uint16_t len)
+static void handle_dut_mode_receive(void *buf, uint16_t len, int fd)
 {
-	if (!interface_ready())
-		return;
-
-	DBG("opcode 0x%x", opcode);
+	DBG("");
 
-	switch (opcode) {
-	case HAL_EV_ADAPTER_STATE_CHANGED:
-		handle_adapter_state_changed(buf);
-		break;
-	case HAL_EV_ADAPTER_PROPS_CHANGED:
-		handle_adapter_props_changed(buf, len);
-		break;
-	case HAL_EV_DISCOVERY_STATE_CHANGED:
-		handle_discovery_state_changed(buf);
-		break;
-	case HAL_EV_DEVICE_FOUND:
-		handle_device_found(buf, len);
-		break;
-	case HAL_EV_REMOTE_DEVICE_PROPS:
-		handle_device_state_changed(buf, len);
-		break;
-	case HAL_EV_BOND_STATE_CHANGED:
-		handle_bond_state_change(buf);
-		break;
-	case HAL_EV_PIN_REQUEST:
-		handle_pin_request(buf);
-		break;
-	case HAL_EV_SSP_REQUEST:
-		handle_ssp_request(buf);
-		break;
-	case HAL_EV_ACL_STATE_CHANGED:
-		handle_acl_state_changed(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
+	/* TODO */
 }
 
+static void handle_le_test_mode(void *buf, uint16_t len, int fd)
+{
+	DBG("");
+
+	/* TODO */
+}
+
+/* handlers will be called from notification thread context */
+static const struct hal_msg_handler ev_handlers[] = {
+	{
+		.handler = handle_adapter_state_changed,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_adapter_state_changed)
+	},
+	{
+		.handler = handle_adapter_props_changed,
+		.var_len = true,
+		.data_len = sizeof(struct hal_ev_adapter_props_changed) +
+						sizeof(struct hal_property),
+	},
+	{
+		.handler = handle_device_state_changed,
+		.var_len = true,
+		.data_len = sizeof(struct hal_ev_remote_device_props) +
+						sizeof(struct hal_property),
+	},
+	{
+		.handler = handle_device_found,
+		.var_len = true,
+		.data_len = sizeof(struct hal_ev_device_found) +
+						sizeof(struct hal_property),
+	},
+	{
+		.handler = handle_discovery_state_changed,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_discovery_state_changed),
+	},
+	{
+		.handler = handle_pin_request,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_pin_request),
+	},
+	{
+		.handler = handle_ssp_request,
+		.var_len = false,
+		.data_len = sizeof(handle_ssp_request),
+	},
+	{
+		.handler = handle_bond_state_change,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_bond_state_changed),
+	},
+	{
+		.handler = handle_acl_state_changed,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_acl_state_changed),
+	},
+	{
+		.handler = handle_dut_mode_receive,
+		.var_len = true,
+		.data_len = sizeof(struct hal_ev_dut_mode_receive),
+	},
+	{
+		.handler = handle_le_test_mode,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_le_test_mode),
+	},
+};
+
 static int init(bt_callbacks_t *callbacks)
 {
 	struct hal_cmd_register_module cmd;
@@ -333,6 +383,10 @@ static int init(bt_callbacks_t *callbacks)
 
 	bt_hal_cbacks = callbacks;
 
+	hal_msg_register(HAL_SERVICE_ID_BLUETOOTH, ev_handlers,
+				sizeof(ev_handlers)/sizeof(ev_handlers[0]),
+				HAL_MINIMUM_EVENT);
+
 	if (!hal_ipc_init()) {
 		bt_hal_cbacks = NULL;
 		return BT_STATUS_FAIL;
@@ -361,6 +415,9 @@ static int init(bt_callbacks_t *callbacks)
 fail:
 	hal_ipc_cleanup();
 	bt_hal_cbacks = NULL;
+
+	hal_msg_unregister(HAL_SERVICE_ID_BLUETOOTH);
+
 	return status;
 }
 
@@ -396,6 +453,8 @@ static void cleanup(void)
 	hal_ipc_cleanup();
 
 	bt_hal_cbacks = NULL;
+
+	hal_msg_unregister(HAL_SERVICE_ID_BLUETOOTH);
 }
 
 static int get_adapter_properties(void)
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index e1c8dd7..0ab77bc 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -43,25 +43,6 @@ static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static pthread_t notif_th = 0;
 
-static void notification_dispatch(struct hal_hdr *msg, int fd)
-{
-	switch (msg->service_id) {
-	case HAL_SERVICE_ID_BLUETOOTH:
-		bt_notify_adapter(msg->opcode, msg->payload, msg->len);
-		break;
-	case HAL_SERVICE_ID_HIDHOST:
-		bt_notify_hidhost(msg->opcode, msg->payload, msg->len);
-		break;
-	case HAL_SERVICE_ID_A2DP:
-		bt_notify_a2dp(msg->opcode, msg->payload, msg->len);
-		break;
-	default:
-		DBG("Unhandled notification service=%d opcode=0x%x",
-						msg->service_id, msg->opcode);
-		break;
-	}
-}
-
 static void *notification_handler(void *data)
 {
 	struct msghdr msg;
@@ -69,7 +50,6 @@ static void *notification_handler(void *data)
 	struct cmsghdr *cmsg;
 	char cmsgbuf[CMSG_SPACE(sizeof(int))];
 	char buf[BLUEZ_HAL_MTU];
-	struct hal_hdr *ev = (void *) buf;
 	ssize_t ret;
 	int fd;
 
@@ -80,7 +60,7 @@ static void *notification_handler(void *data)
 		memset(buf, 0, sizeof(buf));
 		memset(cmsgbuf, 0, sizeof(cmsgbuf));
 
-		iv.iov_base = ev;
+		iv.iov_base = buf;
 		iv.iov_len = sizeof(buf);
 
 		msg.msg_iov = &iv;
@@ -105,24 +85,6 @@ static void *notification_handler(void *data)
 			exit(EXIT_FAILURE);
 		}
 
-		if (ret < (ssize_t) sizeof(*ev)) {
-			error("Too small notification (%zd bytes), aborting",
-									ret);
-			exit(EXIT_FAILURE);
-		}
-
-		if (ev->opcode < HAL_MINIMUM_EVENT) {
-			error("Invalid notification (0x%x), aborting",
-							ev->opcode);
-			exit(EXIT_FAILURE);
-		}
-
-		if (ret != (ssize_t) (sizeof(*ev) + ev->len)) {
-			error("Malformed notification(%zd bytes), aborting",
-									ret);
-			exit(EXIT_FAILURE);
-		}
-
 		fd = -1;
 
 		/* Receive auxiliary data in msg */
@@ -135,7 +97,10 @@ static void *notification_handler(void *data)
 			}
 		}
 
-		notification_dispatch(ev, fd);
+		if (!hal_msg_handler(buf, ret, fd)) {
+			error("Notification handler failed, aborting");
+			exit(EXIT_FAILURE);
+		}
 	}
 
 	close(notif_sk);
diff --git a/android/hal.h b/android/hal.h
index 72090fe..67dad5d 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -26,7 +26,6 @@ bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 btav_interface_t *bt_get_a2dp_interface(void);
 
-void bt_notify_adapter(uint8_t opcode, void *buf, uint16_t len);
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
 void bt_notify_hidhost(uint8_t opcode, void *buf, uint16_t len);
-- 
1.8.4.3


^ permalink raw reply related

* [RFC v2 1/5] android: Add initial code for generic IPC msg handling
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384479617-15555-1-git-send-email-szymon.janc@tieto.com>

This will allow to register and unregister handlers for IPC messages.
Basic sanity check will be done in common code. Commands with variable
length will be verified against minimum size only.
---
 android/Android.mk  |  2 ++
 android/Makefile.am |  5 +--
 android/hal-msg.c   | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-msg.h   | 14 ++++++++
 android/ipc.c       |  1 +
 5 files changed, 114 insertions(+), 2 deletions(-)
 create mode 100644 android/hal-msg.c

diff --git a/android/Android.mk b/android/Android.mk
index 616a338..23a530f 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -27,6 +27,7 @@ LOCAL_SRC_FILES := \
 	ipc.c ipc.h \
 	a2dp.c \
 	pan.c \
+	hal-msg.c \
 	../src/log.c \
 	../src/shared/mgmt.c \
 	../src/shared/util.c \
@@ -88,6 +89,7 @@ LOCAL_SRC_FILES := \
 	hal-pan.c \
 	hal-a2dp.c \
 	hal-utils.c \
+	hal-msg.c \
 
 LOCAL_C_INCLUDES += \
 	$(call include-path-for, system-core) \
diff --git a/android/Makefile.am b/android/Makefile.am
index 4e0c9ed..831a3cb 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -8,7 +8,7 @@ noinst_PROGRAMS += android/bluetoothd
 
 android_bluetoothd_SOURCES = android/main.c \
 				src/log.c \
-				android/hal-msg.h \
+				android/hal-msg.h android/hal-msg.c \
 				android/utils.h \
 				src/sdpd-database.c src/sdpd-server.c \
 				src/sdpd-service.c src/sdpd-request.c \
@@ -49,7 +49,8 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hardware/hardware.h \
 					android/cutils/properties.h \
 					android/hal-log.h \
-					android/hal-ipc.h android/hal-ipc.c
+					android/hal-ipc.h android/hal-ipc.c \
+					android/hal-msg.h android/hal-msg.c
 
 android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android
 
diff --git a/android/hal-msg.c b/android/hal-msg.c
new file mode 100644
index 0000000..2b5178b
--- /dev/null
+++ b/android/hal-msg.c
@@ -0,0 +1,94 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  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
+ *
+ */
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "hal-msg.h"
+
+struct service_handler {
+	const struct hal_msg_handler *handler;
+	uint8_t size;
+	uint8_t offset;
+};
+
+static struct service_handler services[HAL_SERVICE_ID_MAX + 1];
+
+void hal_msg_register(uint8_t service, const struct hal_msg_handler *handlers,
+						uint8_t size, uint8_t offset)
+{
+	services[service].handler = handlers;
+	services[service].size = size;
+	services[service].offset = offset;
+}
+
+void hal_msg_unregister(uint8_t service)
+{
+	services[service].handler = NULL;
+	services[service].size = 0;
+	services[service].offset = 0;
+}
+
+bool hal_msg_handler(void *buf, ssize_t len, int fd)
+{
+	struct hal_hdr *msg = buf;
+	const struct hal_msg_handler *handler;
+	uint8_t opcode;
+
+	if (len < (ssize_t) sizeof(*msg))
+		return false;
+
+	if (len != (ssize_t) (sizeof(*msg) + msg->len))
+		return false;
+
+	/* if service is valid */
+	if (msg->service_id > HAL_SERVICE_ID_MAX)
+		return false;
+
+	/* if service is registered */
+	if (!services[msg->service_id].handler)
+		return false;
+
+	/* if opcode fit offset (eg. events) */
+	if (msg->opcode < services[msg->service_id].offset)
+		return false;
+
+	opcode = msg->opcode - services[msg->service_id].offset;
+
+	/* if opcode is valid */
+	if (opcode >= services[msg->service_id].size)
+		return false;
+
+	handler = &services[msg->service_id].handler[opcode];
+
+	/* if payload size is valid */
+	if ((handler->var_len && handler->data_len > msg->len) ||
+			(!handler->var_len && handler->data_len != msg->len))
+		return false;
+
+	handler->handler(msg->payload, msg->len, fd);
+
+	return true;
+}
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 44fd5c8..17c0ac4 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -546,3 +546,17 @@ struct hal_ev_a2dp_audio_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
+
+
+/* HAL message handler helpers */
+
+struct hal_msg_handler {
+	void (*handler) (void *buf, uint16_t len, int fd);
+	bool var_len;
+	size_t data_len;
+};
+
+void hal_msg_register(uint8_t service, const struct hal_msg_handler *handlers,
+						uint8_t size, uint8_t offset);
+void hal_msg_unregister(uint8_t service);
+bool hal_msg_handler(void *buf, ssize_t len, int fd);
diff --git a/android/ipc.c b/android/ipc.c
index 729f157..7526d25 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -28,6 +28,7 @@
 #include <stddef.h>
 #include <errno.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <string.h>
 #include <signal.h>
 #include <sys/socket.h>
-- 
1.8.4.3


^ permalink raw reply related

* [RFC v2 0/5] android: IPC improvements
From: Szymon Janc @ 2013-11-15  1:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi,

This version uses table approach suggested by Johan.

Handlers are registered on service init and unregistered on cleanup.
Service id and opcode are used to select proper handler from tables.

Handlers are declared with expected (or minimum) payload size and this is
verified before calling proper handler.

This only implement HAL library side to demonstrate use. If this approach is
agreed on daemon patches will follow.

Comments are welcome.

-- 
BR
Szymon Janc

Szymon Janc (5):
  android: Add initial code for generic IPC msg handling
  android/hal-bluetooth: Use generic IPC message handling for events
  android/hal-hidhost: Use generic IPC message handling for events
  android/hal-pan: Use generic IPC message handling for events
  android/hal-a2dp: Use generic IPC message handling for events

 android/Android.mk      |   2 +
 android/Makefile.am     |   5 +-
 android/hal-a2dp.c      |  41 ++++-----
 android/hal-bluetooth.c | 221 ++++++++++++++++++++++++++++++------------------
 android/hal-hidhost.c   |  76 ++++++++++-------
 android/hal-ipc.c       |  45 ++--------
 android/hal-msg.c       |  94 ++++++++++++++++++++
 android/hal-msg.h       |  14 +++
 android/hal-pan.c       |  40 ++++-----
 android/hal.h           |   4 -
 android/ipc.c           |   1 +
 11 files changed, 345 insertions(+), 198 deletions(-)
 create mode 100644 android/hal-msg.c

-- 
1.8.4.3


^ permalink raw reply

* Re: [PATCH 1/2] android: Add PTS PICS for GAP
From: Marcel Holtmann @ 2013-11-15  0:51 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384435587-12427-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

> PTS PICS for GAP, targeting Android 4.4.
> 
> ---
> android/pics-gap.txt | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 201 insertions(+)
> create mode 100644 android/pics-gap.txt
> 
> diff --git a/android/pics-gap.txt b/android/pics-gap.txt
> new file mode 100644
> index 0000000..bcb64cb
> --- /dev/null
> +++ b/android/pics-gap.txt
> @@ -0,0 +1,201 @@
> +GAP PICS for the PTS tool.
> +
> +* - different than PTS defaults
> +
> ++------------------+------------+
> +|  Parameter Name  |  Selected  |
> ++------------------+------------+
> +| TSPC_GAP_0_1     |   False    |
> +| TSPC_GAP_0_2     |   False    |
> +| TSPC_GAP_0_3     |   True*    |

I would go easy on the ASCII Art here. A simple table with tabs should be just fine.

Parameter name		Selected	Description
-------------------------------------------------------------
TSPC_GAP_0_1		True (*)	Short description of what it is

Regards

Marcel


^ permalink raw reply

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
From: Marcel Holtmann @ 2013-11-15  0:00 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384441915-23966-8-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

> Handle events from Android framework. Write everything to real RFCOMM
> socket.
> ---
> android/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
> 
> diff --git a/android/socket.c b/android/socket.c
> index c9ee32f..07743f6 100644
> --- a/android/socket.c
> +++ b/android/socket.c
> @@ -118,6 +118,48 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
> static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
> 								gpointer data)
> {
> +	struct rfcomm_slot *rfslot = data;
> +	unsigned char buf[1024] = { 0 };

since why are we doing this { 0 } thing?

> +	int len, sent;
> +
> +	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
> +		rfslot->fd, rfslot->real_sock, rfslot->channel,
> +		g_io_channel_unix_get_fd(io));
> +
> +	if (!g_list_find(rfcomm_connected_list, rfslot)) {
> +		error("rfslot %p not found in the list", rfslot);
> +		return FALSE;
> +	}
> +
> +	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
> +		error("Socket error: sock %d cond %d",
> +					g_io_channel_unix_get_fd(io), cond);
> +		rfcomm_connected_list = g_list_remove(rfcomm_connected_list,
> +								rfslot);
> +		cleanup_rfslot(rfslot);
> +		return FALSE;
> +	}
> +
> +	/* FIXME check fd vs sock(io) */

I do not even understand this FIXME. Why not get it right in the fist place.

> +	len = recv(rfslot->fd, buf, sizeof(buf), 0);
> +	if (len <= 0) {
> +		error("recv(): %s", strerror(errno));
> +		return FALSE;
> +	}
> +
> +	DBG("read %d bytes write to %d", len, rfslot->real_sock);
> +
> +	sent = send(rfslot->real_sock, buf, len, 0);
> +	if (sent < 0) {
> +		error("send(): %s", strerror(errno));
> +		return FALSE;
> +	}
> +
> +	if (sent != len) {
> +		error("send(): sent %d bytes out of %d", sent, len);
> +		return FALSE;
> +	}

Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.

Regards

Marcel


^ permalink raw reply

* (no subject)
From: Bruno Bruzzano @ 2013-11-14 21:47 UTC (permalink / raw)
  To: linux-bluetooth

Hi everyone!
As suggested by vcgomes, I subscribed to this mailing list to report a
possible bug. I hope I'll receive a feedback from you.
I'm using Neard and BlueZ5 and my goal is to try the bluetooth
handover. The steps I followed are: I run the Bluetooth daemon with
experimental arg (-E), run the neard daemon, powered the NFC adapter
and set it up in Polling mode; furthermore, I wrote the MiFare Classic
1k tag with a record to do the pair. In particular, I used a Samsung
S3 to write the tag, using the NXP WriteTag application. So, the last
step (I think!) is to put the tag on the adapter to start the pairing.
Unfortunally, something happens, that is, in my smartphone I receive a
pairing request and I give the 'Ok', but watching the debug of
Bluetooth daemon, I read always:
"bluetoothd[22063]: src/agent.c:agent_unref() 0x89470c8: ref=-87222"
"bluetoothd[22063]: src/adapter.c:btd_adapter_confirm_reply() hci0
addr B0:C4:E7:BC:B9:4A success 0".
This two lines are repeated continuisly, with the 'ref' that increases
up to a certain point. After that the Bluetooth daemon crashes.
Here you can find two pastebin, respectively for BlueZ daemon and Neard daemon.
BlueZ: http://pastebin.com/Z4W0V5NZ
Neard: http://pastebin.com/cNfQ7qi0


Best Regards
br1_21

^ permalink raw reply

* RE: [RFC BlueZ v1] doc: Add GATT API
From: Caleb Reinhold @ 2013-11-14 20:13 UTC (permalink / raw)
  To: 'Claudio Takahasi', 'Scott James Remnant'; +Cc: linux-bluetooth
In-Reply-To: <CAKT1EBc2d3VkiUF705aNY79YDmL5ZRX75fg=a4a_ZfTPt4zoDA@mail.gmail.com>

Hi Claudio and Scott,

While having minimal familiarity with the workings of BlueZ, I have a fair degree of familiarity with the various health related BTLE specifications.
Because of this, and because of a desire to make use of a more complete GATT API for BlueZ, I thought I might be able to offer some worthwhile insight on useful ways for the API to behave. 

I think that while discussing the reading of characteristics, considering the information available to the client side at the time of connection due to advertisements would be useful. Since UUIDs for a given service being included in an advertisement are only at the level of a "should" it may be useful for an application to be able to decide to abort a connection after discovering only the service declarations. 

As far as the behavior of enabling Notifications or Indications, while in most circumstances it would be possible to draw appropriate information from the corresponding characteristic declaration's properties, if a situation occurred in which both options were for some reason viable selections it could be quite frustrating for the developer making use of the API. Manual control of the state of the client characteristic configuration descriptors also allows a developer to ensure that data will not be lost due to arriving before the client program is ready to handle it. 

Regarding the caching of attributes we were wondering if there is a method for removing the stored data, at least for the purposes of testing.

Regards,

Caleb Reinhold

-----Original Message-----
From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Claudio Takahasi
Sent: Tuesday, November 12, 2013 1:49 PM
To: Scott James Remnant
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

Hi Scott,

On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <keybuk@google.com> wrote:
> On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi 
> <claudio.takahasi@openbossa.org> wrote:
>
>> +GATT local and remote services share the same high-level D-Bus API. 
>> +Local refers to local GATT based service exported by a BlueZ plugin 
>> +or an external application. Remote refers to GATT services exported by the peer.
>
> If this object format also be used to describe the services and 
> characteristics of a remote device, how will those be handled? I 
> assume that we don't want to get the value of every single 
> characteristic on connection - that seems wasteful, and would quite 
> rapidly drain the batteries of smaller devices.

Declarations are stored/cached. All attributes are discovered only once in the first connection or after bonding.
When re-connecting, value is read on demand when the user calls Properties Get (if value is not cached).
Another point is: Notification or Indication are automatically enabled after the discovery procedure.

>
>
> How will service changed be handled? How will BlueZ track the set of 
> applications, and the set of services etc. defined by those 
> applications in a manner that keeps handles consistent? How will it 
> handle generating the Services Changed notification in the cases where 
> the set of applications and/or services change, or the handles change?

We implemented a hash of declarations. Using the "Id"  provided in the options dictionary (see RegisterAgent) we are able to identity if the external service changed its attributes.
However, I don' t think we will upstream this approach soon, Marcel wants a simpler approach: always send ServiceChanged.

If you want to understand more details of the implementation see:
https://db.tt/FkWob6jw

>
>
>> +Characteristic hierarchy
>> +========================
>   :
>> +Service                org.bluez
>> +Interface      org.bluez.Characteristic1 [Experimental]
>> +Object path    [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>
> This would also need a "Permissions" property akin to the one you have 
> for Descriptors - characteristics can be "not accessible", read-only, 
> write-only, read/write - and can also require authorization, 
> authentication, encryption and minimum encryption key sizes - as with 
> descriptors.

It is implemented already, there is an optional "Flags" property :
"array{string} Flags [read-only, optional]"

But this is not enough, there are some cases that the permissions are defined by the external application.

>
>> +               array{byte} Value [read-write]
>> +
>> +                       Cached Value of the characteristic. If present, the
>> +                       value will be cached by bluetoothd and updated when the
>> +                       PropertiesChanged signal is emitted.
>> +
>> +                       External services must emit this signal when the
>> +                       characteristic supports notification/indication, so
>> +                       that clients can be notified of the new value.
>
> The PropertiesChanged signal explains how Notification will be handled
> - but how will Indication? How will a service receive the Indication 
> Confirmation from the remote devices?

The bluetoothd core manages the Confirmation. In my opinion clients listening for PropertiesChanged don' t need to know the difference between notification and indication.
Allow an external client to manage the Confirmation will insert additional complexity without giving real benefits.

>
>
>> +Application Manager hierarchy
>> +=============================
>   :
>> +Service                org.bluez
>> +Interface      org.bluez.ApplicationManager1 [Experimental]
>> +Object path    /org/bluez
>> +
>> +Methods                RegisterAgent(object application, dict options)
>
> Shouldn't this be "RegisterApplication" ?
>
> I assume that the object path is the one to which D-Bus Object Manager 
> queries are sent, allowing a single process to implement multiple 
> "applications"?

The name is still open, but remember that this method might be used to register client and servers.

At the moment "object path" together with DBus BUS id are used for identification only. Multiple GATT services can be registered independently of the application object path.
Application object path can be used to manage *groups* of services exposed by the single process.

>
>> +               UnregisterAgent(object application)
>
> Likewise, "UnregisterApplication" ?
>
>> +Application Agent hierarchy
>> +===========================
>> +
>> +Service                unique name
>> +Interface      org.bluez.ApplicationAgent1 [Experimental]
>> +Object path    freely definable
>> +
>
> "Agent" seems unnnecessary here - if the object is an Application, 
> then org.bluez.Application1 would be a decent enough name. Thus an 
> "Application" consists of multiple Services, each of which consists of 
> multiple Characteristics, each of which has multiple Descriptors

IMO "Agent" gives a better association with its functionality, it reminds me org.bluez.Agent1.
Let's wait the opinion of the others developers...

Regards,
Claudio
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@vger.kernel.org More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* [PATCH v4 4/4] android: Change TODO with explaining comment
From: Lukasz Rymanowski @ 2013-11-14 18:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384453825-19241-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index e75baef..2e94e1f 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -654,7 +654,10 @@ static void send_ssp_request(const bdaddr_t *addr, uint8_t variant,
 {
 	struct hal_ev_ssp_request ev;
 
-	/* TODO name and CoD of remote devices should probably be cached */
+	/* It is ok to have empty name and CoD of remote devices here since
+	* those information has been already provided on device_connected event
+	* or during device scaning. Android will use that instead.
+	*/
 	memset(&ev, 0, sizeof(ev));
 	bdaddr2android(addr, ev.bdaddr);
 	ev.pairing_variant = variant;
-- 
1.8.4


^ permalink raw reply related

* [PATCH v4 3/4] android: Update bond state on auth and connect failed
From: Lukasz Rymanowski @ 2013-11-14 18:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384453825-19241-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 57 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index ce153c2..e75baef 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -996,16 +996,51 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
 			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
 }
 
+static uint8_t status_mgmt2hal(uint8_t mgmt)
+{
+	switch (mgmt) {
+	case MGMT_STATUS_SUCCESS:
+		return HAL_STATUS_SUCCESS;
+	case MGMT_STATUS_NO_RESOURCES:
+		return HAL_STATUS_NOMEM;
+	case MGMT_STATUS_BUSY:
+		return HAL_STATUS_BUSY;
+	case MGMT_STATUS_NOT_SUPPORTED:
+		return HAL_STATUS_UNSUPPORTED;
+	case MGMT_STATUS_INVALID_PARAMS:
+		return HAL_STATUS_INVALID;
+	case MGMT_STATUS_AUTH_FAILED:
+		return HAL_STATUS_AUTH_FAILURE;
+	case MGMT_STATUS_NOT_CONNECTED:
+		return HAL_STATUS_REMOTE_DEVICE_DOWN;
+	default:
+		return HAL_STATUS_FAILED;
+	}
+}
+
 static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
+	const struct mgmt_ev_connect_failed *ev = param;
+
 	DBG("");
+
+	/* In case security mode 3 pairing we will get connect failed event
+	* in case e.g wrong PIN code entered. Let's check if device is
+	* bonding, if so update bond state */
+	set_device_bond_state(&ev->addr.bdaddr, status_mgmt2hal(ev->status),
+							HAL_BOND_STATE_NONE);
 }
 
 static void mgmt_auth_failed_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
+	const struct mgmt_ev_auth_failed *ev = param;
+
 	DBG("");
+
+	set_device_bond_state(&ev->addr.bdaddr, status_mgmt2hal(ev->status),
+							HAL_BOND_STATE_NONE);
 }
 
 static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
@@ -1931,28 +1966,6 @@ static uint8_t set_property(void *buf, uint16_t len)
 	}
 }
 
-static uint8_t status_mgmt2hal(uint8_t mgmt)
-{
-	switch (mgmt) {
-	case MGMT_STATUS_SUCCESS:
-		return HAL_STATUS_SUCCESS;
-	case MGMT_STATUS_NO_RESOURCES:
-		return HAL_STATUS_NOMEM;
-	case MGMT_STATUS_BUSY:
-		return HAL_STATUS_BUSY;
-	case MGMT_STATUS_NOT_SUPPORTED:
-		return HAL_STATUS_UNSUPPORTED;
-	case MGMT_STATUS_INVALID_PARAMS:
-		return HAL_STATUS_INVALID;
-	case MGMT_STATUS_AUTH_FAILED:
-		return HAL_STATUS_AUTH_FAILURE;
-	case MGMT_STATUS_NOT_CONNECTED:
-		return HAL_STATUS_REMOTE_DEVICE_DOWN;
-	default:
-		return HAL_STATUS_FAILED;
-	}
-}
-
 static void pair_device_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
-- 
1.8.4


^ permalink raw reply related

* [PATCH v4 2/4] android: Cache device name on device list.
From: Lukasz Rymanowski @ 2013-11-14 18:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384453825-19241-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 65 insertions(+), 6 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index f70db5b..ce153c2 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -96,6 +96,7 @@ static struct {
 struct device {
 	bdaddr_t bdaddr;
 	int bond_state;
+	char *name;
 };
 
 struct browse_req {
@@ -330,6 +331,34 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 			HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
 }
 
+static void cache_device_name(const bdaddr_t *addr, char *name)
+{
+	struct device *dev = NULL;
+	GSList *l;
+
+	l = g_slist_find_custom(devices, addr, bdaddr_cmp);
+	if (l)
+		dev = l->data;
+
+	if (!dev) {
+		dev = g_new0(struct device, 1);
+		bacpy(&dev->bdaddr, addr);
+		dev->bond_state = HAL_BOND_STATE_NONE;
+		dev->name = g_malloc0(strlen(name) + 1);
+		memcpy(dev->name, name, strlen(name));
+
+		devices = g_slist_prepend(devices, dev);
+		return;
+	}
+
+	if (!g_strcmp0(dev->name, name))
+			return;
+
+	g_free(dev->name);
+	dev->name = g_strdup(name);
+	/*TODO: Do some real caching here */
+}
+
 static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
 								int state) {
 
@@ -542,10 +571,35 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
 	browse_remote_sdp(&addr->bdaddr);
 }
 
-static void send_remote_device_name_prop(const bdaddr_t *bdaddr, char *name)
+static char* get_device_name(const bdaddr_t *addr)
+{
+	GSList *l;
+	struct device *dev;
+
+	l = g_slist_find_custom(devices, addr, bdaddr_cmp);
+	if (l) {
+		dev = l->data;
+		return dev->name;
+	}
+
+	return NULL;
+}
+
+static void send_remote_device_name_prop(const bdaddr_t *bdaddr)
 {
 	struct hal_ev_remote_device_props *ev;
-	uint8_t buf[BASELEN_REMOTE_DEV_PROP + strlen(name)];
+	uint8_t *buf;
+	char dst[18];
+	char *name;
+
+	ba2str(bdaddr, dst);
+
+	/* Use cached name or bdaddr string */
+	name = get_device_name(bdaddr);
+	if (!name)
+		name = dst;
+
+	buf = g_malloc0(BASELEN_REMOTE_DEV_PROP + strlen(name));
 
 	ev =  (void *) buf;
 	memset(buf, 0, sizeof(buf));
@@ -559,6 +613,8 @@ static void send_remote_device_name_prop(const bdaddr_t *bdaddr, char *name)
 
 	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
 			HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), ev, -1);
+
+	g_free(buf);
 }
 
 static void pin_code_request_callback(uint16_t index, uint16_t length,
@@ -576,15 +632,16 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 	ba2str(&ev->addr.bdaddr, dst);
 
 	/* Workaround for Android Bluetooth.apk issue: send remote
-	 * device property. Lets use address as a name for now */
-	send_remote_device_name_prop(&ev->addr.bdaddr, dst);
+	 * device property */
+	send_remote_device_name_prop(&ev->addr.bdaddr);
 
 	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
 						HAL_BOND_STATE_BONDING);
 
 	DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure);
 
-	/* TODO name and CoD of remote devices should probably be cached */
+	/* TODO CoD of remote devices should probably be cached
+	 * Name we already send in remote device prop */
 	memset(&hal_ev, 0, sizeof(hal_ev));
 	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
 
@@ -799,8 +856,10 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 	props_size += sizeof(struct hal_property) + sizeof(eir.class);
 	props_size += sizeof(struct hal_property) + sizeof(rssi);
 
-	if (eir.name)
+	if (eir.name) {
 		props_size += sizeof(struct hal_property) + strlen(eir.name);
+		cache_device_name(remote, eir.name);
+	}
 
 	if (is_new_dev) {
 		struct hal_ev_device_found *ev = NULL;
-- 
1.8.4


^ permalink raw reply related

* [PATCH v4 1/4] android: Update bond state on incoming bonding
From: Lukasz Rymanowski @ 2013-11-14 18:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384453825-19241-1-git-send-email-lukasz.rymanowski@tieto.com>

Before sending any ssp request or pin code request up to HAL library we
need to send bond state change with bonding state. Otherwise incoming
bonding is not correctly handled by Bluetooth.apk.
In this patch also device list has been added in order to e.g track
bonding state.

Note: For incoming paring (security mode 3) there is a  need to send
HAL_EVE_REMOTE_DEVICE_PROPS before HAL_EV_PIN_REQUEST.
It is because Android will crash due to bug in pinRequestCallback
function in java. Android checks if device is already in HashMap and if
not then creates  device, but forget to use that one, but instead do
operations on NULL. By sending HAL_BOND_STATE_BONDING event it works
better but we have race issue. It is because new device is added to
HashMap not in callback context but later after BONDING msg will be
received  by BondStateMachine. If it happens before pin_request_cb hits
java then we are fine, otherwise not. So for that reason we send
HAL_EV_REMOTE_DEVICE_PROPS so in the java handler class new device will
be added to HashMap in the  callback context.

In ssp case we don't have this problem as we send device found once acl
is created.
---
 android/bluetooth.c | 104 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 89 insertions(+), 15 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 39589fa..f70db5b 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -62,6 +62,8 @@ static uint16_t option_index = MGMT_INDEX_NONE;
 
 static int notification_sk = -1;
 
+#define BASELEN_REMOTE_DEV_PROP (sizeof(struct hal_ev_remote_device_props) \
+					+ sizeof(struct hal_property))
 /* This list contains addresses which are asked for records */
 static GSList *browse_reqs;
 
@@ -91,6 +93,11 @@ static struct {
 	.uuids = NULL,
 };
 
+struct device {
+	bdaddr_t bdaddr;
+	int bond_state;
+};
+
 struct browse_req {
 	bdaddr_t bdaddr;
 	GSList *uuids;
@@ -106,6 +113,7 @@ static const uint16_t uuid_list[] = {
 };
 
 static GSList *found_devices = NULL;
+static GSList *devices = NULL;
 
 static void adapter_name_changed(const uint8_t *name)
 {
@@ -301,6 +309,14 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 
 }
 
+static int bdaddr_cmp(gconstpointer a, gconstpointer b)
+{
+	const bdaddr_t *bda = a;
+	const bdaddr_t *bdb = b;
+
+	return bacmp(bdb, bda);
+}
+
 static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 								uint8_t state)
 {
@@ -314,6 +330,29 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 			HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
 }
 
+static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
+								int state) {
+
+	struct device *dev = NULL;
+	GSList *l;
+
+	l = g_slist_find_custom(devices, addr, bdaddr_cmp);
+	if (l)
+		dev = l->data;
+
+	if (!dev) {
+		dev = g_new0(struct device, 1);
+		bacpy(&dev->bdaddr, addr);
+		dev->bond_state = HAL_BOND_STATE_NONE;
+		devices = g_slist_prepend(devices, dev);
+	}
+
+	if (dev->bond_state != state) {
+		dev->bond_state = state;
+		send_bond_state_change(&dev->bdaddr, status, state);
+	}
+}
+
 static void browse_req_free(struct browse_req *req)
 {
 	g_slist_free_full(req->uuids, g_free);
@@ -497,12 +536,31 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
 								key->pin_len);
 	}
 
-	send_bond_state_change(&addr->bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&addr->bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_BONDED);
 
 	browse_remote_sdp(&addr->bdaddr);
 }
 
+static void send_remote_device_name_prop(const bdaddr_t *bdaddr, char *name)
+{
+	struct hal_ev_remote_device_props *ev;
+	uint8_t buf[BASELEN_REMOTE_DEV_PROP + strlen(name)];
+
+	ev =  (void *) buf;
+	memset(buf, 0, sizeof(buf));
+
+	ev->status = HAL_STATUS_SUCCESS;
+	bdaddr2android(bdaddr, ev->bdaddr);
+	ev->num_props = 1;
+	ev->props[0].type = HAL_PROP_DEVICE_NAME;
+	ev->props[0].len = strlen(name);
+	memcpy(&ev->props[0].val, name, strlen(name));
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), ev, -1);
+}
+
 static void pin_code_request_callback(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -517,6 +575,13 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 
 	ba2str(&ev->addr.bdaddr, dst);
 
+	/* Workaround for Android Bluetooth.apk issue: send remote
+	 * device property. Lets use address as a name for now */
+	send_remote_device_name_prop(&ev->addr.bdaddr, dst);
+
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure);
 
 	/* TODO name and CoD of remote devices should probably be cached */
@@ -556,6 +621,9 @@ static void user_confirm_request_callback(uint16_t index, uint16_t length,
 	ba2str(&ev->addr.bdaddr, dst);
 	DBG("%s confirm_hint %u", dst, ev->confirm_hint);
 
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	if (ev->confirm_hint)
 		send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_CONSENT, 0);
 	else
@@ -577,6 +645,9 @@ static void user_passkey_request_callback(uint16_t index, uint16_t length,
 	ba2str(&ev->addr.bdaddr, dst);
 	DBG("%s", dst);
 
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_ENTRY, 0);
 }
 
@@ -595,8 +666,13 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length,
 	DBG("%s entered %u", dst, ev->entered);
 
 	/* HAL seems to not support entered characters */
-	if (!ev->entered)
-		send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF,
+	if (ev->entered)
+		return;
+
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
+	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF,
 								ev->passkey);
 }
 
@@ -647,14 +723,6 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
 		error("Failed to send confirm name request");
 }
 
-static int bdaddr_cmp(gconstpointer a, gconstpointer b)
-{
-	const bdaddr_t *bda = a;
-	const bdaddr_t *bdb = b;
-
-	return bacmp(bdb, bda);
-}
-
 static int fill_device_props(struct hal_property *prop, bdaddr_t *addr,
 					uint32_t cod, int8_t rssi, char *name)
 {
@@ -1838,7 +1906,7 @@ static void pair_device_complete(uint8_t status, uint16_t length,
 	if (status == MGMT_STATUS_SUCCESS)
 		return;
 
-	send_bond_state_change(&rp->addr.bdaddr, status_mgmt2hal(status),
+	set_device_bond_state(&rp->addr.bdaddr, status_mgmt2hal(status),
 							HAL_BOND_STATE_NONE);
 }
 
@@ -1855,7 +1923,7 @@ static bool create_bond(void *buf, uint16_t len)
 				&cp, pair_device_complete, NULL, NULL) == 0)
 		return false;
 
-	send_bond_state_change(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
 						HAL_BOND_STATE_BONDING);
 
 	return true;
@@ -1865,12 +1933,18 @@ static bool cancel_bond(void *buf, uint16_t len)
 {
 	struct hal_cmd_cancel_bond *cmd = buf;
 	struct mgmt_addr_info cp;
+	bool result;
 
 	cp.type = BDADDR_BREDR;
 	android2bdaddr(cmd->bdaddr, &cp.bdaddr);
 
-	return mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
+	result = mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
 					sizeof(cp), &cp, NULL, NULL, NULL) > 0;
+	if (result)
+		set_device_bond_state(&cp.bdaddr, HAL_STATUS_SUCCESS,
+							HAL_BOND_STATE_NONE);
+
+	return result;
 }
 
 static void unpair_device_complete(uint8_t status, uint16_t length,
@@ -1883,7 +1957,7 @@ static void unpair_device_complete(uint8_t status, uint16_t length,
 	if (status != MGMT_STATUS_SUCCESS)
 		return;
 
-	send_bond_state_change(&rp->addr.bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&rp->addr.bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_NONE);
 }
 
-- 
1.8.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox