Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] android/client: Add clear screen on Cltr-L
From: Jerzy Kasenberg @ 2013-10-28 12:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg

This patch allows to clear screen on Ctrl-L.
---
 android/client/terminal.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/android/client/terminal.c b/android/client/terminal.c
index 88c963b..e721160 100644
--- a/android/client/terminal.c
+++ b/android/client/terminal.c
@@ -94,6 +94,7 @@ static const struct ansii_sequence ansii_sequnces[] = {
 #define KEY_SEQUNCE_NOT_FINISHED -1
 #define KEY_C_C 3
 #define KEY_C_D 4
+#define KEY_C_L 12
 
 #define isseqence(c) ((c) == 0x1B)
 
@@ -237,6 +238,15 @@ static void terminal_clear_line(void)
 	terminal_line_replaced();
 }
 
+static void terminal_clear_sceen(void)
+{
+	line_buf[0] = '\0';
+	line_buf_ix = 0;
+	line_len = 0;
+
+	printf("\x1b[2J\x1b[1;1H%s", prompt);
+}
+
 static void terminal_delete_char(void)
 {
 	/* delete character under cursor if not at the very end */
@@ -525,6 +535,9 @@ void terminal_process_char(int c, void (*process_line)(char *line))
 			exit(0);
 		}
 		break;
+	case KEY_C_L:
+		terminal_clear_sceen();
+		break;
 	default:
 		if (!isprint(c)) {
 			/*
-- 
1.7.9.5


^ permalink raw reply related

* [BUG] Crash during disconnecting and removing bond from remote device
From: Seung-Woo Kim @ 2013-10-28 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Seung-Woo Kim, s.syam

Dear list,

I used 3.10.14 with RFCOMM tty patches in 3.12-rc, and I tested
disconnecting and removing a bond from remote device. and I got
following crash.

[   42.706670] Unable to handle kernel NULL pointer dereference at
virtual address 00000010
[   42.709197] pgd = c0004000
[   42.714500] [00000010] *pgd=00000000
[   42.715484] Internal error: Oops: 17 [#1] PREEMPT SMP ARM
[   42.720820] Modules linked in:
[   42.723879] CPU: 1 PID: 828 Comm: krfcommd Not tainted
3.10.14-gdca4b73 #340
[   42.730892] task: df03ac00 ti: df178000 task.ti: df178000
[   42.736328] PC is at l2cap_create_basic_pdu+0x30/0x1ac
[   42.741406] LR is at l2cap_chan_send+0x100/0x1d8
[   42.745997] pc : [<c05163b8>]    lr : [<c051addc>]    psr: 400f0013
[   42.745997] sp : df179d40  ip : c082daa0  fp : 00000008
[   42.757443] r10: 00000004  r9 : 0000065a  r8 : 000003f5
[   42.762652] r7 : 00000000  r6 : 00000000  r5 : df179e84  r4 : d782bc00
[   42.769162] r3 : 00000000  r2 : 00000004  r1 : df179e84  r0 : 00000000
[   42.775680] Flags: nZcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[   42.782964] Control: 10c53c7d  Table: 5f3f804a  DAC: 00000015
[   42.788693] Process krfcommd (pid: 828, stack limit = 0xdf178238)
[   42.794770] Stack: (0xdf179d40 to 0xdf17a000)
[   42.799127] 9d40: 00000000 d782bc00 00000004 df179e84 00000004
000003f5 0000065a c082f6a8
[   42.807285] 9d60: 00000008 c051addc df179e84 d782bc00 00000004
d782bdfc de6c9600 df179e84
[   42.815440] 9d80: d782bc00 00000004 d782bdfc c051fb30 00000004
dd728c00 df179e84 00000004
[   42.823600] 9da0: df179db0 df03ac00 c082f6a8 c044fffc 00000001
00000000 00000000 00000000
[   42.831735] 9dc0: 00000000 df03ac00 00000000 00000000 00000000
00000000 df179e10 00000000
[   42.839895] 9de0: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[   42.848053] 9e00: 00000000 00000000 00000000 00000000 002e4d55
00000000 00000000 00000004
[   42.856213] 9e20: dd728c00 df18ee00 00000000 df179e84 df178000
df03ac00 df18f0e4 00000000
[   42.864372] 9e40: df178000 c0012030 c07e7ff8 c005c7b0 df178000
00000000 df179e84 db45b010
[   42.872533] 9e60: 00000043 c04505cc 00000001 00000004 dfb53200
c0528f6c 00000004 dfb5320c
[   42.880690] 9e80: ffff388b 00000000 00000000 df179ea0 00000001
00000000 00000000 00000000
[   42.888850] 9ea0: df179ebc 00000004 dfb53200 c05d6854 00000000
c05291e4 c07c58c0 d7017303
[   42.897010] 9ec0: f0e3fe36 00000000 dfb53200 c052a4d8 c07e7fe0
c07e8018 db779000 dfb53200
[   42.905169] 9ee0: 00000000 c052beb0 dfb53200 dfb53500 dfb53200
de6c9600 db779000 00000000
[   42.913328] 9f00: de6c964c c052c044 dfb16880 dfb53200 dfb53200
dfb16880 dfb53200 c081eca8
[   42.921488] 9f20: c052c22c c052c124 a0000113 df178000 00000001
c082f6a8 00000000 c052c22c
[   42.929646] 9f40: 00000000 00000000 00000000 c052c294 00000000
df9d0000 df9d5ee4 df179f6c
[   42.937805] 9f60: df178000 c0049d54 00000000 00000000 c07e7ff8
00000000 00000000 00000000
[   42.945964] 9f80: df179f80 df179f80 00000000 00000000 df179f90
df179f90 df9d5ee4 c0049c9c
[   42.954123] 9fa0: 00000000 00000000 00000000 c000f168 00000000
00000000 00000000 00000000
[   42.962283] 9fc0: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[   42.970442] 9fe0: 00000000 00000000 00000000 00000000 00000013
00000000 00000000 00000000
[   42.978647] [<c05163b8>] (l2cap_create_basic_pdu+0x30/0x1ac) from
[<c051addc>] (l2cap_chan_send+0x100/0x1d8)
[   42.988428] [<c051addc>] (l2cap_chan_send+0x100/0x1d8) from
[<c051fb30>] (l2cap_sock_sendmsg+0x7c/0xd8)
[   42.997807] [<c051fb30>] (l2cap_sock_sendmsg+0x7c/0xd8) from
[<c044fffc>] (sock_sendmsg+0xac/0xcc)
[   43.006736] [<c044fffc>] (sock_sendmsg+0xac/0xcc) from [<c04505cc>]
(kernel_sendmsg+0x2c/0x34)
[   43.015345] [<c04505cc>] (kernel_sendmsg+0x2c/0x34) from [<c0528f6c>]
(rfcomm_send_frame+0x58/0x7c)
[   43.024352] [<c0528f6c>] (rfcomm_send_frame+0x58/0x7c) from
[<c05291e4>] (rfcomm_send_ua+0x98/0xbc)
[   43.033382] [<c05291e4>] (rfcomm_send_ua+0x98/0xbc) from [<c052a4d8>]
(rfcomm_recv_disc+0xac/0x100)
[   43.042405] [<c052a4d8>] (rfcomm_recv_disc+0xac/0x100) from
[<c052beb0>] (rfcomm_recv_frame+0x144/0x264)
[   43.051866] [<c052beb0>] (rfcomm_recv_frame+0x144/0x264) from
[<c052c044>] (rfcomm_process_rx+0x74/0xfc)
[   43.061327] [<c052c044>] (rfcomm_process_rx+0x74/0xfc) from
[<c052c124>] (rfcomm_process_sessions+0x58/0x160)
[   43.071221] [<c052c124>] (rfcomm_process_sessions+0x58/0x160) from
[<c052c294>] (rfcomm_run+0x68/0x110)
[   43.080614] [<c052c294>] (rfcomm_run+0x68/0x110) from [<c0049d54>]
(kthread+0xb8/0xbc)
[   43.088528] [<c0049d54>] (kthread+0xb8/0xbc) from [<c000f168>]
(ret_from_fork+0x14/0x2c)
[   43.096574] Code: e3100004 e1a07003 e5946004 1a000057 (e5969010)
[   43.110479] ---[ end trace b2b00f82e7216259 ]---

This happens because l2cap_chan_send() is called after l2cap_chan_del()
and I can easily fix this with following patch.

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 63fa111..11b5d09 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2452,6 +2452,9 @@ int l2cap_chan_send(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
 	int err;
 	struct sk_buff_head seg_queue;

+	if (!chan->conn)
+		return -ENOTCONN;
+
 	/* Connectionless channel */
 	if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
 		skb = l2cap_create_connless_pdu(chan, msg, len, priority);


Here is also hcidump log for operation for this issue.

$ hcidump -X
HCI sniffer - Bluetooth packet analyzer ver 2.4
device: hci0 snap_len: 1500 filter: 0xffffffff
> ACL data: handle 12 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 0]
      0000: 3b 53 01 e7                                       ;S..
< ACL data: handle 12 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 0]
      0000: 3b 73 01 cd                                       ;s..
> ACL data: handle 12 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 0]
      0000: 03 53 01 fd                                       .S..
< ACL data: handle 12 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 0]
      0000: 03 73 01 d7                                       .s..
< ACL data: handle 12 flags 0x00 dlen 12
    L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
> ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
< ACL data: handle 12 flags 0x00 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 12 packets 2
> ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 12 packets 2
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 12 reason 0x13
    Reason: Remote User Terminated Connection

Best Regards,
- Seung-Woo Kim <sw0312.kim@samsung.com>

-- 
Seung-Woo Kim
Samsung Software R&D Center
--


^ permalink raw reply related

* [PATCH 4/4] android: Remove bogus hal_rsp_register_module structure
From: Szymon Janc @ 2013-10-28 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382964375-7589-1-git-send-email-szymon.janc@tieto.com>

Core service Register ID command doesn't return any parameter.
---
 android/hal-msg.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 99238ff..03daa51 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -70,9 +70,6 @@ struct hal_status {
 struct hal_cmd_register_module {
 	uint8_t service_id;
 } __attribute__((packed));
-struct hal_rsp_register_module {
-	uint8_t service_id;
-} __attribute__((packed));
 
 #define HAL_OP_UNREGISTER_MODULE	0x02
 struct hal_cmd_unregister_module {
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 3/4] android: Fix HAL_OP_REMOVE_BOND value
From: Szymon Janc @ 2013-10-28 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382964375-7589-1-git-send-email-szymon.janc@tieto.com>

This is a copy-and-paste mistake.
---
 android/hal-msg.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index a0a8390..99238ff 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -163,7 +163,7 @@ struct hal_cmd_create_bond {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_REMOVE_BOND		0x0d
+#define HAL_OP_REMOVE_BOND		0x0e
 struct hal_cmd_remove_bond {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 2/4] android: Add helper functions for converting bdaddr transmitted over IPC
From: Szymon Janc @ 2013-10-28 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382964375-7589-1-git-send-email-szymon.janc@tieto.com>

Android holds Bluetooth address in reverse order comparing to
bluetoothd. Add convenient functions for converting to and from that
format.

Convertion is done on daemon side to keep HAL library simple.
---
 Makefile.android  |  1 +
 android/adapter.c |  3 ++-
 android/utils.h   | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 android/utils.h

diff --git a/Makefile.android b/Makefile.android
index 01b3cea..6cd26e1 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -4,6 +4,7 @@ noinst_PROGRAMS += android/bluetoothd
 android_bluetoothd_SOURCES =	android/main.c \
 				src/log.c \
 				android/hal-msg.h \
+				android/utils.h \
 				src/sdpd-database.c src/sdpd-server.c \
 				src/sdpd-service.c src/sdpd-request.c \
 				src/shared/util.h src/shared/util.c \
diff --git a/android/adapter.c b/android/adapter.c
index f393c49..15b65e5 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -31,6 +31,7 @@
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "utils.h"
 #include "adapter.h"
 
 static GIOChannel *notification_io = NULL;
@@ -384,7 +385,7 @@ static void send_adapter_address(void)
 
 	ev->props[0].type = HAL_PROP_ADAPTER_ADDR;
 	ev->props[0].len = sizeof(bdaddr_t);
-	baswap((bdaddr_t *) ev->props[0].val, &adapter->bdaddr);
+	bdaddr2android(&adapter->bdaddr, ev->props[0].val);
 
 	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
 				HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
diff --git a/android/utils.h b/android/utils.h
new file mode 100644
index 0000000..5b009bc
--- /dev/null
+++ b/android/utils.h
@@ -0,0 +1,33 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+static inline void android2bdaddr(const void *buf, bdaddr_t *dst)
+{
+	baswap(dst, buf);
+}
+
+static inline void bdaddr2android(const bdaddr_t *src, void *buf)
+{
+	baswap(buf, src);
+}
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 1/4] android: Rename send_adapter_name to send_adapter_address
From: Szymon Janc @ 2013-10-28 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Make function name match what it acctually does.
---
 android/adapter.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 80a9e6d..f393c49 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -370,7 +370,7 @@ static bool set_discoverable(uint8_t mode, uint16_t timeout)
 	return false;
 }
 
-static void send_adapter_name(void)
+static void send_adapter_address(void)
 {
 	struct hal_ev_adapter_props_changed *ev;
 	int len;
@@ -398,7 +398,7 @@ static bool get_property(void *buf, uint16_t len)
 
 	switch (cmd->type) {
 	case HAL_PROP_ADAPTER_ADDR:
-		send_adapter_name();
+		send_adapter_address();
 		return true;
 	case HAL_PROP_ADAPTER_NAME:
 	case HAL_PROP_ADAPTER_UUIDS:
-- 
1.8.4.1


^ permalink raw reply related

* Re: [PATCH BlueZ 1/5] android/hal-pan: Add implementation of .init
From: Johan Hedberg @ 2013-10-28 12:43 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1382962146-19587-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Mon, Oct 28, 2013, Luiz Augusto von Dentz wrote:
> ---
>  android/hal-pan.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)

All five patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 0/4] Add handsfree interface methods to haltest
From: Johan Hedberg @ 2013-10-28 12:42 UTC (permalink / raw)
  To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1382960343-10765-1-git-send-email-jerzy.kasenberg@tieto.com>

Hi Jerzy,

On Mon, Oct 28, 2013, Jerzy Kasenberg wrote:
> With this patchset handsfree interface is available in haltest.
> 
> Jerzy Kasenberg (4):
>   android/client: Add skeleton for handsfree calls
>   android/client: Add code for handsfree callbacks
>   android/client: Add code for handsfree methods
>   android/client: Add completion for hf methods
> 
>  Makefile.android         |    2 +
>  android/Android.mk       |    1 +
>  android/client/haltest.c |    1 +
>  android/client/if-bt.c   |    2 +-
>  android/client/if-hf.c   |  784 ++++++++++++++++++++++++++++++++++++++++++++++
>  android/client/if-main.h |    2 +
>  6 files changed, 791 insertions(+), 1 deletion(-)
>  create mode 100644 android/client/if-hf.c

All patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 5/5] android: Add and remove uuids in mgmt interface
From: Marcin Kraglak @ 2013-10-28 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1382963409-1012-1-git-send-email-marcin.kraglak@tieto.com>

Use mgmt interface for adding and removing uuids to adapter.
This is needed for proper changing adapter's class of device.
---
 android/adapter.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index b1cb5f8..bed0423 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -532,10 +532,105 @@ error:
 	ipc_send_rsp(io, HAL_SERVICE_ID_BLUETOOTH, status);
 }
 
+static int uuid_cmp(const void *a, const void *b)
+{
+	const sdp_record_t *rec = a;
+	const uuid_t *uuid = b;
+
+	return sdp_uuid_cmp(&rec->svclass, uuid);
+}
+
+static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
+{
+	if (uuid->type == SDP_UUID16)
+		sdp_uuid16_to_uuid128(uuid128, uuid);
+	else if (uuid->type == SDP_UUID32)
+		sdp_uuid32_to_uuid128(uuid128, uuid);
+	else
+		memcpy(uuid128, uuid, sizeof(*uuid));
+}
+
+static uint8_t get_uuid_mask(const uuid_t *uuid)
+{
+	if (uuid->type != SDP_UUID16)
+		return 0;
+
+	switch (uuid->value.uuid16) {
+	case DIALUP_NET_SVCLASS_ID:
+	case CIP_SVCLASS_ID:
+		return 0x42;    /* Telephony & Networking */
+	case IRMC_SYNC_SVCLASS_ID:
+	case OBEX_OBJPUSH_SVCLASS_ID:
+	case OBEX_FILETRANS_SVCLASS_ID:
+	case IRMC_SYNC_CMD_SVCLASS_ID:
+	case PBAP_PSE_SVCLASS_ID:
+		return 0x10;    /* Object Transfer */
+	case HEADSET_SVCLASS_ID:
+	case HANDSFREE_SVCLASS_ID:
+		return 0x20;    /* Audio */
+	case CORDLESS_TELEPHONY_SVCLASS_ID:
+	case INTERCOM_SVCLASS_ID:
+	case FAX_SVCLASS_ID:
+	case SAP_SVCLASS_ID:
+	/*
+	* Setting the telephony bit for the handsfree audio gateway
+	* role is not required by the HFP specification, but the
+	* Nokia 616 carkit is just plain broken! It will refuse
+	* pairing without this bit set.
+	*/
+	case HANDSFREE_AGW_SVCLASS_ID:
+		return 0x40;    /* Telephony */
+	case AUDIO_SOURCE_SVCLASS_ID:
+	case VIDEO_SOURCE_SVCLASS_ID:
+		return 0x08;    /* Capturing */
+	case AUDIO_SINK_SVCLASS_ID:
+	case VIDEO_SINK_SVCLASS_ID:
+		return 0x04;    /* Rendering */
+	case PANU_SVCLASS_ID:
+	case NAP_SVCLASS_ID:
+	case GN_SVCLASS_ID:
+		return 0x02;    /* Networking */
+	default:
+		return 0;
+	}
+}
+
+static void add_uuid_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to add UUID: %s (0x%02x)",
+						mgmt_errstr(status), status);
+		return;
+	}
+	/*TODO inform that adapter uuids has been changed*/
+}
+
+static int add_uuid(uuid_t *uuid, uint8_t svc_hint)
+{
+	struct mgmt_cp_add_uuid cp;
+	uuid_t uuid128;
+	uint128_t uint128;
+
+	uuid_to_uuid128(&uuid128, uuid);
+
+	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
+	htob128(&uint128, (uint128_t *) cp.uuid);
+	cp.svc_hint = svc_hint;
+
+	if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
+			0, sizeof(cp), &cp,
+			add_uuid_complete, adapter, NULL) > 0)
+		return 0;
+
+	return -EIO;
+}
+
 static void adapter_service_insert(sdp_record_t *rec)
 {
 	sdp_list_t *browse_list = NULL;
 	uuid_t browse_uuid;
+	bool new_uuid;
 
 	/* skip record without a browse group */
 	if (sdp_get_browse_groups(rec, &browse_list) < 0) {
@@ -552,6 +647,19 @@ static void adapter_service_insert(sdp_record_t *rec)
 	adapter->services = sdp_list_insert_sorted(
 				adapter->services, rec, record_sort);
 
+	if (!sdp_list_find(adapter->services, &rec->svclass, uuid_cmp))
+		new_uuid = true;
+	else
+		new_uuid = false;
+
+	adapter->services = sdp_list_insert_sorted(adapter->services, rec,
+							record_sort);
+
+	if (new_uuid) {
+		uint8_t svc_hint = get_uuid_mask(&rec->svclass);
+		add_uuid(&rec->svclass, svc_hint);
+	}
+
 done:
 	sdp_list_free(browse_list, free);
 }
@@ -569,6 +677,36 @@ int bt_adapter_service_add(sdp_record_t *rec)
 	return ret;
 }
 
+static void remove_uuid_complete(uint8_t status, uint16_t length,
+				const void *param, void *user_data)
+{
+	if (status != MGMT_STATUS_SUCCESS) {
+			error("Failed to remove UUID: %s (0x%02x)",
+		mgmt_errstr(status), status);
+		return;
+	}
+	/*TODO inform that adapter uuids has been changed*/
+}
+
+static int remove_uuid(uuid_t *uuid)
+{
+	struct mgmt_cp_remove_uuid cp;
+	uuid_t uuid128;
+	uint128_t uint128;
+
+	uuid_to_uuid128(&uuid128, uuid);
+
+	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
+	htob128(&uint128, (uint128_t *) cp.uuid);
+
+	if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID,
+			0, sizeof(cp), &cp,
+			remove_uuid_complete, adapter, NULL) > 0)
+		return 0;
+
+	return -EIO;
+}
+
 void bt_adapter_service_remove(uint32_t handle)
 {
 	sdp_record_t *rec = sdp_record_find(handle);
@@ -578,6 +716,9 @@ void bt_adapter_service_remove(uint32_t handle)
 
 	adapter->services = sdp_list_remove(adapter->services, rec);
 
+	if (!sdp_list_find(adapter->services, &rec->svclass, uuid_cmp))
+		remove_uuid(&rec->svclass);
+
 	remove_record_from_server(rec->handle);
 }
 
-- 
1.8.2.2


^ permalink raw reply related

* [PATCH 4/5] android: Cache adapter services in bt_adapter struct
From: Marcin Kraglak @ 2013-10-28 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1382963409-1012-1-git-send-email-marcin.kraglak@tieto.com>

We need to cache list of sdp records to add/remove uuids
in mgmt interface properly.
---
 android/adapter.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index a14c2a4..b1cb5f8 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -30,6 +30,7 @@
 #include "src/shared/mgmt.h"
 #include "lib/mgmt.h"
 #include "lib/sdp.h"
+#include "lib/sdp_lib.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
@@ -50,6 +51,8 @@ struct bt_adapter {
 
 	uint32_t supported_settings;
 	uint32_t current_settings;
+
+	sdp_list_t *services;
 };
 
 static struct bt_adapter *adapter;
@@ -529,14 +532,53 @@ error:
 	ipc_send_rsp(io, HAL_SERVICE_ID_BLUETOOTH, status);
 }
 
+static void adapter_service_insert(sdp_record_t *rec)
+{
+	sdp_list_t *browse_list = NULL;
+	uuid_t browse_uuid;
+
+	/* skip record without a browse group */
+	if (sdp_get_browse_groups(rec, &browse_list) < 0) {
+		DBG("skipping record without browse group");
+		return;
+	}
+
+	sdp_uuid16_create(&browse_uuid, PUBLIC_BROWSE_GROUP);
+
+	/* skip record without public browse group */
+	if (!sdp_list_find(browse_list, &browse_uuid, sdp_uuid_cmp))
+		goto done;
+
+	adapter->services = sdp_list_insert_sorted(
+				adapter->services, rec, record_sort);
+
+done:
+	sdp_list_free(browse_list, free);
+}
+
 int bt_adapter_service_add(sdp_record_t *rec)
 {
-	return add_record_to_server(&adapter->bdaddr, rec);
+	int ret;
+
+	ret = add_record_to_server(&adapter->bdaddr, rec);
+	if (ret < 0)
+		return ret;
+
+	adapter_service_insert(rec);
+
+	return ret;
 }
 
 void bt_adapter_service_remove(uint32_t handle)
 {
-	remove_record_from_server(handle);
+	sdp_record_t *rec = sdp_record_find(handle);
+
+	if (!rec)
+		return;
+
+	adapter->services = sdp_list_remove(adapter->services, rec);
+
+	remove_record_from_server(rec->handle);
 }
 
 const bdaddr_t *bt_adapter_get_address(void)
-- 
1.8.2.2


^ permalink raw reply related

* [PATCH 3/5] android: Add initial sdp implementation
From: Marcin Kraglak @ 2013-10-28 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1382963409-1012-1-git-send-email-marcin.kraglak@tieto.com>

Add and remove records to sdp server. This api will
be used in android's profiles implementations.
---
 android/adapter.c | 12 ++++++++++++
 android/adapter.h |  3 +++
 2 files changed, 15 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 80a9e6d..a14c2a4 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -26,8 +26,10 @@
 #include <glib.h>
 
 #include "lib/bluetooth.h"
+#include "src/sdpd.h"
 #include "src/shared/mgmt.h"
 #include "lib/mgmt.h"
+#include "lib/sdp.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
@@ -527,6 +529,16 @@ error:
 	ipc_send_rsp(io, HAL_SERVICE_ID_BLUETOOTH, status);
 }
 
+int bt_adapter_service_add(sdp_record_t *rec)
+{
+	return add_record_to_server(&adapter->bdaddr, rec);
+}
+
+void bt_adapter_service_remove(uint32_t handle)
+{
+	remove_record_from_server(handle);
+}
+
 const bdaddr_t *bt_adapter_get_address(void)
 {
 	return &adapter->bdaddr;
diff --git a/android/adapter.h b/android/adapter.h
index 2afc67a..1726f18 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -38,5 +38,8 @@ void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 
 const bdaddr_t *bt_adapter_get_address(void);
 
+int bt_adapter_service_add(sdp_record_t *rec);
+void bt_adapter_service_remove(uint32_t handle);
+
 bool bt_adapter_register(GIOChannel *io);
 void bt_adapter_unregister(void);
-- 
1.8.2.2


^ permalink raw reply related

* [PATCH 2/5] android: Initial implementation of socket interface
From: Marcin Kraglak @ 2013-10-28 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1382963409-1012-1-git-send-email-marcin.kraglak@tieto.com>

Add stub implementation of socket interace on daemon side.
---
 android/main.c   |  4 ++++
 android/socket.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 android/socket.h |  3 +++
 3 files changed, 49 insertions(+)

diff --git a/android/main.c b/android/main.c
index 6ff30a9..2b40621 100644
--- a/android/main.c
+++ b/android/main.c
@@ -213,6 +213,10 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
 		bt_hid_handle_cmd(hal_cmd_io, msg->opcode, msg->payload,
 								msg->len);
 		break;
+	case HAL_SERVICE_ID_SOCK:
+		bt_sock_handle_cmd(hal_cmd_io, msg->opcode, msg->payload,
+								msg->len);
+		break;
 	default:
 		ipc_send_rsp(hal_cmd_io, msg->service_id, HAL_STATUS_FAILED);
 		break;
diff --git a/android/socket.c b/android/socket.c
index 22d2acb..39709cd 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -26,8 +26,50 @@
 
 #include "lib/bluetooth.h"
 #include "log.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
+#include "ipc.h"
 #include "socket.h"
 
+
+static int handle_listen(void *buf)
+{
+	return -1;
+}
+
+static int handle_connect(void *buf)
+{
+	return -1;
+}
+
+void bt_sock_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
+							uint16_t len)
+{
+	int fd;
+
+	switch (opcode) {
+	case HAL_OP_SOCK_LISTEN:
+		fd = handle_listen(buf);
+		if (fd < 0)
+			break;
+
+		ipc_send(io, HAL_SERVICE_ID_SOCK, opcode, 0, NULL, fd);
+		return;
+	case HAL_OP_SOCK_CONNECT:
+		fd = handle_connect(buf);
+		if (fd < 0)
+			break;
+
+		ipc_send(io, HAL_SERVICE_ID_SOCK, opcode, 0, NULL, fd);
+		return;
+	default:
+		DBG("Unhandled command, opcode 0x%x", opcode);
+		break;
+	}
+
+	ipc_send_rsp(io, HAL_SERVICE_ID_SOCK, HAL_STATUS_FAILED);
+}
+
 bool bt_socket_register(GIOChannel *io, const bdaddr_t *addr)
 {
 	DBG("");
diff --git a/android/socket.h b/android/socket.h
index b13e84c..2b3b940 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -21,5 +21,8 @@
  *
  */
 
+void bt_sock_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
+						uint16_t len);
+
 bool bt_socket_register(GIOChannel *io, const bdaddr_t *addr);
 void bt_socket_unregister(void);
-- 
1.8.2.2


^ permalink raw reply related

* [PATCH 1/5] android/hal: Add initial socket implementation
From: Marcin Kraglak @ 2013-10-28 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak

Added socket api opcodes and structures and its implementation
in hal-sock.c.
---
 android/hal-msg.h  | 20 ++++++++++++++++++++
 android/hal-sock.c | 28 ++++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 677b00b..ec7d181 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -213,6 +213,26 @@ struct hal_cmd_le_test_mode {
 	uint8_t  data[0];
 } __attribute__((packed));
 
+/* Bluetooth Socket HAL api */
+
+#define HAL_OP_SOCK_LISTEN		0x01
+struct hal_op_sock_listen {
+	uint8_t type;
+	uint8_t name[256];
+	uint8_t uuid[16];
+	uint16_t channel;
+	uint8_t flags;
+} __attribute__((packed));
+
+#define HAL_OP_SOCK_CONNECT		0x02
+struct hal_op_sock_connect {
+	uint8_t bdaddr[6];
+	uint8_t type;
+	uint8_t uuid[16];
+	uint16_t channel;
+	uint8_t flags;
+} __attribute__((packed));
+
 #define HAL_OP_HID_CONNECT		0x01
 struct hal_cmd_hid_connect {
 	uint8_t bdaddr[6];
diff --git a/android/hal-sock.c b/android/hal-sock.c
index 7642ee3..131877a 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -15,18 +15,33 @@
  *
  */
 
+#include <stdbool.h>
+#include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 
+#include "hal-ipc.h"
 #include "hal-log.h"
+#include "hal-msg.h"
 #include "hal.h"
 
 static bt_status_t sock_listen_rfcomm(const char *service_name,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
+	struct hal_op_sock_listen cmd;
+
 	DBG("");
 
-	return BT_STATUS_UNSUPPORTED;
+	cmd.flags = flags;
+	cmd.type = BTSOCK_RFCOMM;
+	cmd.channel = chan;
+	memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
+	memset(cmd.name, 0, sizeof(cmd.name));
+	memcpy(cmd.name, service_name, strlen(service_name));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN,
+				sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
 static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
@@ -58,6 +73,8 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
+	struct hal_op_sock_connect cmd;
+
 	if ((!uuid && chan <= 0) || !bdaddr || !sock) {
 		error("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
 					bdaddr, uuid, chan, sock);
@@ -66,7 +83,14 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 
 	DBG("uuid %p chan %d sock %p type %d", uuid, chan, sock, type);
 
-	return BT_STATUS_UNSUPPORTED;
+	cmd.flags = flags;
+	cmd.type = type;
+	cmd.channel = chan;
+	memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
+	memcpy(cmd.bdaddr, bdaddr, sizeof(cmd.bdaddr));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
+					sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
 static btsock_interface_t sock_if = {
-- 
1.8.2.2


^ permalink raw reply related

* [PATCH BlueZ 5/5] android/hal-pan: Add implementation of .disconnect
From: Luiz Augusto von Dentz @ 2013-10-28 12:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382962146-19587-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-msg.h | 5 +++++
 android/hal-pan.c | 8 +++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 65f60dc..bba031c 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -309,6 +309,11 @@ struct hal_cmd_pan_connect {
 	uint8_t remote_role;
 } __attribute__((packed));
 
+#define HAL_OP_PAN_DISCONNECT	0x04
+struct hal_cmd_pan_disconnect {
+	uint8_t bdaddr[6];
+} __attribute__((packed));
+
 /* Notifications and confirmations */
 
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 3e23eb5..cacc6c0 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -85,15 +85,17 @@ static bt_status_t pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
 
 static bt_status_t pan_disconnect(const bt_bdaddr_t *bd_addr)
 {
+	struct hal_cmd_pan_disconnect cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
 
-	if (!bd_addr)
-		return BT_STATUS_PARM_INVALID;
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return BT_STATUS_UNSUPPORTED;
+	return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 4/5] android/hal-pan: Add implementation of .connect
From: Luiz Augusto von Dentz @ 2013-10-28 12:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382962146-19587-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-msg.h |  7 +++++++
 android/hal-pan.c | 11 ++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 350cec1..65f60dc 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -302,6 +302,13 @@ struct hal_rsp_pan_get_role {
 	uint8_t local_role;
 } __attribute__((packed));
 
+#define HAL_OP_PAN_CONNECT	0x03
+struct hal_cmd_pan_connect {
+	uint8_t bdaddr[6];
+	uint8_t local_role;
+	uint8_t remote_role;
+} __attribute__((packed));
+
 /* Notifications and confirmations */
 
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index c8dcdec..3e23eb5 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -17,6 +17,7 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <string.h>
 
 #include "hal-log.h"
 #include "hal.h"
@@ -67,15 +68,19 @@ static int pan_get_local_role(void)
 static bt_status_t pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
 					int remote_role)
 {
+	struct hal_cmd_pan_connect cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
 
-	if (!bd_addr)
-		return BT_STATUS_PARM_INVALID;
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+	cmd.local_role = local_role;
+	cmd.remote_role = remote_role;
 
-	return BT_STATUS_UNSUPPORTED;
+	return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t pan_disconnect(const bt_bdaddr_t *bd_addr)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 3/5] android/hal-pan: Add implementation of .get_local_role
From: Luiz Augusto von Dentz @ 2013-10-28 12:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382962146-19587-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-msg.h |  5 +++++
 android/hal-pan.c | 11 ++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 0987eec..350cec1 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -297,6 +297,11 @@ struct hal_cmd_pan_enable {
 	uint8_t local_role;
 } __attribute__((packed));
 
+#define HAL_OP_PAN_GET_ROLE	0x02
+struct hal_rsp_pan_get_role {
+	uint8_t local_role;
+} __attribute__((packed));
+
 /* Notifications and confirmations */
 
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 8fb2563..c8dcdec 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -47,12 +47,21 @@ static bt_status_t pan_enable(int local_role)
 
 static int pan_get_local_role(void)
 {
+	struct hal_rsp_pan_get_role rsp;
+	size_t len = sizeof(rsp);
+	bt_status_t status;
+
 	DBG("");
 
 	if (!interface_ready())
 		return BTPAN_ROLE_NONE;
 
-	return BTPAN_ROLE_NONE;
+	status = hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, 0, NULL,
+							&len, &rsp, NULL);
+	if (status != BT_STATUS_SUCCESS)
+		return BTPAN_ROLE_NONE;
+
+	return rsp.local_role;
 }
 
 static bt_status_t pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 2/5] android/hal-pan: Add implementation of .enable
From: Luiz Augusto von Dentz @ 2013-10-28 12:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382962146-19587-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-msg.h | 7 +++++++
 android/hal-pan.c | 7 ++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index a0a8390..0987eec 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -290,6 +290,13 @@ struct hal_cmd_av_disconnect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
+/* PAN HAL API */
+
+#define HAL_OP_PAN_ENABLE	0x01
+struct hal_cmd_pan_enable {
+	uint8_t local_role;
+} __attribute__((packed));
+
 /* Notifications and confirmations */
 
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 62fec00..8fb2563 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -32,12 +32,17 @@ static bool interface_ready(void)
 
 static bt_status_t pan_enable(int local_role)
 {
+	struct hal_cmd_pan_enable cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
 
-	return BT_STATUS_UNSUPPORTED;
+	cmd.local_role = local_role;
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static int pan_get_local_role(void)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 1/5] android/hal-pan: Add implementation of .init
From: Luiz Augusto von Dentz @ 2013-10-28 12:09 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-pan.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index 609bc1c..62fec00 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -20,6 +20,8 @@
 
 #include "hal-log.h"
 #include "hal.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
 
 static const btpan_callbacks_t *cbs = NULL;
 
@@ -77,15 +79,16 @@ static bt_status_t pan_disconnect(const bt_bdaddr_t *bd_addr)
 
 static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
 {
+	struct hal_cmd_register_module cmd;
+
 	DBG("");
 
 	cbs = callbacks;
 
-	/* TODO: start HID Host thread */
-
-	/* TODO: enable service */
+	cmd.service_id = HAL_SERVICE_ID_PAN;
 
-	return BT_STATUS_SUCCESS;
+	return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static void pan_cleanup()
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/4] android/client: Add completion for hf methods
From: Jerzy Kasenberg @ 2013-10-28 11:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382960343-10765-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds completion functions to handsfree methods.
---
 android/client/if-hf.c |  124 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 114 insertions(+), 10 deletions(-)

diff --git a/android/client/if-hf.c b/android/client/if-hf.c
index 585a569..c23fb13 100644
--- a/android/client/if-hf.c
+++ b/android/client/if-hf.c
@@ -269,6 +269,14 @@ static void init_p(int argc, const char **argv)
 
 /* connect */
 
+static void connect_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 3) {
+		*user = NULL;
+		*enum_func = enum_devices;
+	}
+}
 
 static void connect_p(int argc, const char **argv)
 {
@@ -282,6 +290,22 @@ static void connect_p(int argc, const char **argv)
 
 /* disconnect */
 
+/*
+ * This completion function will be used for several methods
+ * returning recently connected address
+ */
+static void connected_addr_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 3) {
+		*user = last_addr;
+		*enum_func = enum_one_string;
+	}
+}
+
+/* Map completion to connected_addr_c */
+#define disconnect_c connected_addr_c
+
 static void disconnect_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -294,6 +318,9 @@ static void disconnect_p(int argc, const char **argv)
 
 /* create an audio connection */
 
+/* Map completion to connected_addr_c */
+#define connect_audio_c connected_addr_c
+
 static void connect_audio_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -306,6 +333,9 @@ static void connect_audio_p(int argc, const char **argv)
 
 /* close the audio connection */
 
+/* Map completion to connected_addr_c */
+#define disconnect_audio_c connected_addr_c
+
 static void disconnect_audio_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -336,6 +366,15 @@ static void stop_voice_recognition_p(int argc, const char **argv)
 
 /* volume control */
 
+static void volume_control_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 3) {
+		*user = TYPE_ENUM(bthf_volume_type_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void volume_control_p(int argc, const char **argv)
 {
 	bthf_volume_type_t type;
@@ -362,6 +401,19 @@ static void volume_control_p(int argc, const char **argv)
 
 /* Combined device status change notification */
 
+static void device_status_notification_c(int argc, const char **argv,
+							enum_func *enum_func,
+							void **user)
+{
+	if (argc == 3) {
+		*user = TYPE_ENUM(bthf_network_state_t);
+		*enum_func = enum_defines;
+	} else if (argc == 4) {
+		*user = TYPE_ENUM(bthf_service_type_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void device_status_notification_p(int argc, const char **argv)
 {
 	bthf_network_state_t ntk_state;
@@ -420,6 +472,15 @@ static void cops_response_p(int argc, const char **argv)
 
 /* Response for CIND command */
 
+static void cind_response_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 6) {
+		*user = TYPE_ENUM(bthf_call_state_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void cind_response_p(int argc, const char **argv)
 {
 	int svc;
@@ -502,6 +563,15 @@ static void formatted_at_response_p(int argc, const char **argv)
 
 /* at_response */
 
+static void at_response_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 3) {
+		*user = TYPE_ENUM(bthf_at_response_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void at_response_p(int argc, const char **argv)
 {
 	bthf_at_response_t response_code;
@@ -525,6 +595,27 @@ static void at_response_p(int argc, const char **argv)
 
 /* response for CLCC command */
 
+static void clcc_response_c(int argc, const char **argv, enum_func *enum_func,
+								void **user)
+{
+	if (argc == 4) {
+		*user = TYPE_ENUM(bthf_call_direction_t);
+		*enum_func = enum_defines;
+	} else if (argc == 5) {
+		*user = TYPE_ENUM(bthf_call_state_t);
+		*enum_func = enum_defines;
+	} else if (argc == 6) {
+		*user = TYPE_ENUM(bthf_call_mode_t);
+		*enum_func = enum_defines;
+	} else if (argc == 7) {
+		*user = TYPE_ENUM(bthf_call_mpty_type_t);
+		*enum_func = enum_defines;
+	} else if (argc == 9) {
+		*user = TYPE_ENUM(bthf_call_addrtype_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void clcc_response_p(int argc, const char **argv)
 {
 	int index;
@@ -591,6 +682,19 @@ static void clcc_response_p(int argc, const char **argv)
 }
 
 /* phone state change */
+
+static void phone_state_change_c(int argc, const char **argv,
+					enum_func *enum_func, void **user)
+{
+	if (argc == 5) {
+		*user = TYPE_ENUM(bthf_call_state_t);
+		*enum_func = enum_defines;
+	} else if (argc == 7) {
+		*user = TYPE_ENUM(bthf_call_addrtype_t);
+		*enum_func = enum_defines;
+	}
+}
+
 static void phone_state_change_p(int argc, const char **argv)
 {
 	int num_active;
@@ -652,23 +756,23 @@ static void cleanup_p(int argc, const char **argv)
 
 static struct method methods[] = {
 	STD_METHOD(init),
-	STD_METHODH(connect, "<addr>"),
-	STD_METHODH(disconnect, "<addr>"),
-	STD_METHODH(connect_audio, "<addr>"),
-	STD_METHODH(disconnect_audio, "<addr>"),
+	STD_METHODCH(connect, "<addr>"),
+	STD_METHODCH(disconnect, "<addr>"),
+	STD_METHODCH(connect_audio, "<addr>"),
+	STD_METHODCH(disconnect_audio, "<addr>"),
 	STD_METHOD(start_voice_recognition),
 	STD_METHOD(stop_voice_recognition),
-	STD_METHODH(volume_control, "<vol_type> <volume>"),
-	STD_METHODH(device_status_notification,
+	STD_METHODCH(volume_control, "<vol_type> <volume>"),
+	STD_METHODCH(device_status_notification,
 			"<ntk_state> <svt_type> <signal> <batt_chg>"),
 	STD_METHODH(cops_response, "<cops string>"),
-	STD_METHODH(cind_response,
+	STD_METHODCH(cind_response,
 			"<svc> <num_active> <num_held> <setup_state> <signal> <roam> <batt_chg>"),
 	STD_METHODH(formatted_at_response, "<at_response>"),
-	STD_METHODH(at_response, "<response_code> [<error_code>]"),
-	STD_METHODH(clcc_response,
+	STD_METHODCH(at_response, "<response_code> [<error_code>]"),
+	STD_METHODCH(clcc_response,
 			"<index> <direction> <state> <mode> <mpty> <number> <type>"),
-	STD_METHODH(phone_state_change,
+	STD_METHODCH(phone_state_change,
 			"<num_active> <num_held> <setup_state> <number> <type>"),
 	STD_METHOD(cleanup),
 	END_METHOD
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 3/4] android/client: Add code for handsfree methods
From: Jerzy Kasenberg @ 2013-10-28 11:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382960343-10765-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds implementation of handsfree methods to haltest.
---
 android/client/if-hf.c |  289 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 289 insertions(+)

diff --git a/android/client/if-hf.c b/android/client/if-hf.c
index 43c7f47..585a569 100644
--- a/android/client/if-hf.c
+++ b/android/client/if-hf.c
@@ -272,83 +272,372 @@ static void init_p(int argc, const char **argv)
 
 static void connect_p(int argc, const char **argv)
 {
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hf);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hf->connect, &addr);
 }
 
 /* disconnect */
 
 static void disconnect_p(int argc, const char **argv)
 {
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hf);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hf->disconnect, &addr);
 }
 
 /* create an audio connection */
 
 static void connect_audio_p(int argc, const char **argv)
 {
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hf);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hf->connect_audio, &addr);
 }
 
 /* close the audio connection */
 
 static void disconnect_audio_p(int argc, const char **argv)
 {
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hf);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hf->disconnect_audio, &addr);
 }
 
 /* start voice recognition */
 
 static void start_voice_recognition_p(int argc, const char **argv)
 {
+	RETURN_IF_NULL(if_hf);
+
+	EXEC(if_hf->start_voice_recognition);
 }
 
 /* stop voice recognition */
 
 static void stop_voice_recognition_p(int argc, const char **argv)
 {
+	RETURN_IF_NULL(if_hf);
+
+	EXEC(if_hf->stop_voice_recognition);
 }
 
 /* volume control */
 
 static void volume_control_p(int argc, const char **argv)
 {
+	bthf_volume_type_t type;
+	int volume;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* volume type */
+	if (argc <= 2) {
+		haltest_error("No volume type specified\n");
+		return;
+	}
+	type = str2bthf_volume_type_t(argv[2]);
+
+	/* volume */
+	if (argc <= 3) {
+		haltest_error("No volume specified\n");
+		return;
+	}
+	volume = atoi(argv[3]);
+
+	EXEC(if_hf->volume_control, type, volume);
 }
 
 /* Combined device status change notification */
 
 static void device_status_notification_p(int argc, const char **argv)
 {
+	bthf_network_state_t ntk_state;
+	bthf_service_type_t svc_type;
+	int signal;
+	int batt_chg;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* network state */
+	if (argc <= 2) {
+		haltest_error("No network state specified\n");
+		return;
+	}
+	ntk_state = str2bthf_network_state_t(argv[2]);
+
+	/* service type */
+	if (argc <= 3) {
+		haltest_error("No service type specified\n");
+		return;
+	}
+	svc_type = str2bthf_service_type_t(argv[3]);
+
+	/* signal */
+	if (argc <= 4) {
+		haltest_error("No signal specified\n");
+		return;
+	}
+	signal = atoi(argv[4]);
+
+	/* batt_chg */
+	if (argc <= 5) {
+		haltest_error("No batt_chg specified\n");
+		return;
+	}
+	batt_chg = atoi(argv[5]);
+
+	EXEC(if_hf->device_status_notification, ntk_state, svc_type, signal,
+								batt_chg);
 }
 
 /* Response for COPS command */
 
 static void cops_response_p(int argc, const char **argv)
 {
+	RETURN_IF_NULL(if_hf);
+
+	/* response */
+	if (argc <= 2) {
+		haltest_error("No cops specified\n");
+		return;
+	}
+
+	EXEC(if_hf->cops_response, argv[2]);
 }
 
 /* Response for CIND command */
 
 static void cind_response_p(int argc, const char **argv)
 {
+	int svc;
+	int num_active;
+	int num_held;
+	bthf_call_state_t call_setup_state;
+	int signal;
+	int roam;
+	int batt_chg;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* svc */
+	if (argc <= 2) {
+		haltest_error("No service specified\n");
+		return;
+	}
+	svc = atoi(argv[2]);
+
+	/* num active */
+	if (argc <= 3) {
+		haltest_error("No num active specified\n");
+		return;
+	}
+	num_active = atoi(argv[3]);
+
+	/* num held */
+	if (argc <= 4) {
+		haltest_error("No num held specified\n");
+		return;
+	}
+	num_held = atoi(argv[4]);
+
+	/* call setup state */
+	if (argc <= 5) {
+		haltest_error("No call setup state specified\n");
+		return;
+	}
+	call_setup_state = str2bthf_call_state_t(argv[5]);
+
+	/* signal */
+	if (argc <= 6) {
+		haltest_error("No signal specified\n");
+		return;
+	}
+	signal = atoi(argv[6]);
+
+	/* roam */
+	if (argc <= 7) {
+		haltest_error("No roam specified\n");
+		return;
+	}
+	roam = atoi(argv[7]);
+
+	/* batt_chg */
+	if (argc <= 8) {
+		haltest_error("No batt_chg specified\n");
+		return;
+	}
+	batt_chg = atoi(argv[8]);
+
+	EXEC(if_hf->cind_response, svc, num_active, num_held, call_setup_state,
+							signal, roam, batt_chg);
 }
 
 /* Pre-formatted AT response, typically in response to unknown AT cmd */
 
 static void formatted_at_response_p(int argc, const char **argv)
 {
+	RETURN_IF_NULL(if_hf);
+
+	/* response */
+	if (argc <= 2) {
+		haltest_error("No response specified\n");
+		return;
+	}
+
+	EXEC(if_hf->formatted_at_response, argv[2]);
 }
 
 /* at_response */
 
 static void at_response_p(int argc, const char **argv)
 {
+	bthf_at_response_t response_code;
+	int error_code = 0;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* response type */
+	if (argc <= 2) {
+		haltest_error("No response specified\n");
+		return;
+	}
+	response_code = str2bthf_at_response_t(argv[2]);
+
+	/* error code */
+	if (argc >= 3)
+		error_code = atoi(argv[3]);
+
+	EXEC(if_hf->at_response, response_code, error_code);
 }
 
 /* response for CLCC command */
 
 static void clcc_response_p(int argc, const char **argv)
 {
+	int index;
+	bthf_call_direction_t dir;
+	bthf_call_state_t state;
+	bthf_call_mode_t mode;
+	bthf_call_mpty_type_t mpty;
+	const char *number;
+	bthf_call_addrtype_t type;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* index */
+	if (argc <= 2) {
+		haltest_error("No index specified\n");
+		return;
+	}
+	index = atoi(argv[2]);
+
+	/* direction */
+	if (argc <= 3) {
+		haltest_error("No direction specified\n");
+		return;
+	}
+	dir = str2bthf_call_direction_t(argv[3]);
+
+	/* call state */
+	if (argc <= 4) {
+		haltest_error("No call state specified\n");
+		return;
+	}
+	state = str2bthf_call_state_t(argv[4]);
+
+	/* call mode */
+	if (argc <= 5) {
+		haltest_error("No mode specified\n");
+		return;
+	}
+	mode = str2bthf_call_mode_t(argv[5]);
+
+	/* call mpty type */
+	if (argc <= 6) {
+		haltest_error("No mpty type specified\n");
+		return;
+	}
+	mpty = str2bthf_call_mpty_type_t(argv[6]);
+
+	/* number */
+	if (argc <= 7) {
+		haltest_error("No number specified\n");
+		return;
+	}
+	number = argv[7];
+
+	/* call mpty type */
+	if (argc <= 8) {
+		haltest_error("No address type specified\n");
+		return;
+	}
+	type = str2bthf_call_addrtype_t(argv[8]);
+
+	EXEC(if_hf->clcc_response, index, dir, state, mode, mpty, number,
+									type);
 }
 
 /* phone state change */
 static void phone_state_change_p(int argc, const char **argv)
 {
+	int num_active;
+	int num_held;
+	bthf_call_state_t call_setup_state;
+	const char *number;
+	bthf_call_addrtype_t type;
+
+	RETURN_IF_NULL(if_hf);
+
+	/* num_active */
+	if (argc <= 2) {
+		haltest_error("No num_active specified\n");
+		return;
+	}
+	num_active = atoi(argv[2]);
+
+	/* num_held */
+	if (argc <= 3) {
+		haltest_error("No num_held specified\n");
+		return;
+	}
+	num_held = atoi(argv[3]);
+
+	/* setup state */
+	if (argc <= 4) {
+		haltest_error("No call setup state specified\n");
+		return;
+	}
+	call_setup_state = str2bthf_call_state_t(argv[4]);
+
+	/* number */
+	if (argc <= 5) {
+		haltest_error("No number specified\n");
+		return;
+	}
+	number = argv[5];
+
+	/* call mpty type */
+	if (argc <= 6) {
+		haltest_error("No address type specified\n");
+		return;
+	}
+	type = str2bthf_call_addrtype_t(argv[6]);
+
+	EXEC(if_hf->phone_state_change, num_active, num_held, call_setup_state,
+								number, type);
 }
 
 /* cleanup */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/4] android/client: Add code for handsfree callbacks
From: Jerzy Kasenberg @ 2013-10-28 11:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382960343-10765-1-git-send-email-jerzy.kasenberg@tieto.com>

This adds implementation for handsfree callbacks.
---
 android/client/if-hf.c |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/android/client/if-hf.c b/android/client/if-hf.c
index e4065df..43c7f47 100644
--- a/android/client/if-hf.c
+++ b/android/client/if-hf.c
@@ -106,6 +106,8 @@ ENDMAP
 
 /* Callbacks */
 
+static char last_addr[MAX_ADDR_STR_LEN];
+
 /*
  * Callback for connection state change.
  * state will have one of the values from BtHfConnectionState
@@ -113,6 +115,9 @@ ENDMAP
 static void connection_state_cb(bthf_connection_state_t state,
 							bt_bdaddr_t *bd_addr)
 {
+	haltest_info("%s: state=%s bd_addr=%s\n", __func__,
+					bthf_connection_state_t2str(state),
+					bt_bdaddr_t2str(bd_addr, last_addr));
 }
 
 /*
@@ -121,6 +126,9 @@ static void connection_state_cb(bthf_connection_state_t state,
  */
 static void audio_state_cb(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
 {
+	haltest_info("%s: state=%s bd_addr=%s\n", __func__,
+					bthf_audio_state_t2str(state),
+					bt_bdaddr_t2str(bd_addr, last_addr));
 }
 
 /*
@@ -129,16 +137,19 @@ static void audio_state_cb(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
  */
 static void vr_cmd_cb(bthf_vr_state_t state)
 {
+	haltest_info("%s: state=%s\n", __func__, bthf_vr_state_t2str(state));
 }
 
 /* Callback for answer incoming call (ATA) */
 static void answer_call_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /* Callback for disconnect call (AT+CHUP) */
 static void hangup_call_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /*
@@ -147,6 +158,8 @@ static void hangup_call_cmd_cb(void)
  */
 static void volume_cmd_cb(bthf_volume_type_t type, int volume)
 {
+	haltest_info("%s: type=%s volume=%d\n", __func__,
+					bthf_volume_type_t2str(type), volume);
 }
 
 /*
@@ -155,6 +168,7 @@ static void volume_cmd_cb(bthf_volume_type_t type, int volume)
  */
 static void dial_call_cmd_cb(char *number)
 {
+	haltest_info("%s: number=%s\n", __func__, number);
 }
 
 /*
@@ -163,6 +177,7 @@ static void dial_call_cmd_cb(char *number)
  */
 static void dtmf_cmd_cb(char tone)
 {
+	haltest_info("%s: tone=%d\n", __func__, tone);
 }
 
 /*
@@ -171,6 +186,7 @@ static void dtmf_cmd_cb(char tone)
  */
 static void nrec_cmd_cb(bthf_nrec_t nrec)
 {
+	haltest_info("%s: nrec=%s\n", __func__, bthf_nrec_t2str(nrec));
 }
 
 /*
@@ -179,26 +195,31 @@ static void nrec_cmd_cb(bthf_nrec_t nrec)
  */
 static void chld_cmd_cb(bthf_chld_type_t chld)
 {
+	haltest_info("%s: chld=%s\n", __func__, bthf_chld_type_t2str(chld));
 }
 
 /* Callback for CNUM (subscriber number) */
 static void cnum_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /* Callback for indicators (CIND) */
 static void cind_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /* Callback for operator selection (COPS) */
 static void cops_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /* Callback for call list (AT+CLCC) */
 static void clcc_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 /*
@@ -207,11 +228,13 @@ static void clcc_cmd_cb(void)
  */
 static void unknown_at_cmd_cb(char *at_string)
 {
+	haltest_info("%s: at_string=%s\n", __func__, at_string);
 }
 
 /* Callback for keypressed (HSP) event. */
 static void key_pressed_cmd_cb(void)
 {
+	haltest_info("%s\n", __func__);
 }
 
 static bthf_callbacks_t hf_cbacks = {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/4] android/client: Add skeleton for handsfree calls
From: Jerzy Kasenberg @ 2013-10-28 11:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382960343-10765-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds skeleton for all methods of handsfree along with
all callbacks.
---
 Makefile.android         |    2 +
 android/Android.mk       |    1 +
 android/client/haltest.c |    1 +
 android/client/if-bt.c   |    2 +-
 android/client/if-hf.c   |  368 ++++++++++++++++++++++++++++++++++++++++++++++
 android/client/if-main.h |    2 +
 6 files changed, 375 insertions(+), 1 deletion(-)
 create mode 100644 android/client/if-hf.c

diff --git a/Makefile.android b/Makefile.android
index 01b3cea..fd8043c 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -51,6 +51,7 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/tabcompletion.c \
 				android/client/if-av.c \
 				android/client/if-bt.c \
+				android/client/if-hf.c \
 				android/client/if-hh.c \
 				android/client/if-pan.c \
 				android/client/if-sock.c \
@@ -81,6 +82,7 @@ EXTRA_DIST += android/client/terminal.c \
 		android/client/history.c \
 		android/client/if-av.c \
 		android/client/if-bt.c \
+		android/client/if-hf.c \
 		android/client/if-hh.c \
 		android/client/if-pan.c \
 		android/client/if-sock.c \
diff --git a/android/Android.mk b/android/Android.mk
index 56c43cb..22208e0 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -104,6 +104,7 @@ LOCAL_SRC_FILES := \
 	client/tabcompletion.c \
 	client/if-av.c \
 	client/if-bt.c \
+	client/if-hf.c \
 	client/if-hh.c \
 	client/if-pan.c \
 	client/if-sock.c \
diff --git a/android/client/haltest.c b/android/client/haltest.c
index 6b4030b..7fe0436 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
@@ -32,6 +32,7 @@
 const struct interface *interfaces[] = {
 	&bluetooth_if,
 	&av_if,
+	&hf_if,
 	&hh_if,
 	&pan_if,
 	&sock_if,
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index dd5d12e..a20a7c6 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -811,7 +811,7 @@ static void get_profile_interface_p(int argc, const char **argv)
 	RETURN_IF_NULL(if_bluetooth);
 
 	if (strcmp(BT_PROFILE_HANDSFREE_ID, id) == 0)
-		pif = &dummy; /* TODO: change when if_hf is there */
+		pif = (const void **) &if_hf;
 	else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_ID, id) == 0)
 		pif = (const void **) &if_av;
 	else if (strcmp(BT_PROFILE_HEALTH_ID, id) == 0)
diff --git a/android/client/if-hf.c b/android/client/if-hf.c
new file mode 100644
index 0000000..e4065df
--- /dev/null
+++ b/android/client/if-hf.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "if-main.h"
+
+const bthf_interface_t *if_hf = NULL;
+
+SINTMAP(bthf_at_response_t, -1, "(unknown)")
+	DELEMENT(BTHF_AT_RESPONSE_ERROR),
+	DELEMENT(BTHF_AT_RESPONSE_OK),
+ENDMAP
+
+SINTMAP(bthf_connection_state_t, -1, "(unknown)")
+	DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTED),
+	DELEMENT(BTHF_CONNECTION_STATE_CONNECTING),
+	DELEMENT(BTHF_CONNECTION_STATE_CONNECTED),
+	DELEMENT(BTHF_CONNECTION_STATE_SLC_CONNECTED),
+	DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTING),
+ENDMAP
+
+SINTMAP(bthf_audio_state_t, -1, "(unknown)")
+	DELEMENT(BTHF_AUDIO_STATE_DISCONNECTED),
+	DELEMENT(BTHF_AUDIO_STATE_CONNECTING),
+	DELEMENT(BTHF_AUDIO_STATE_CONNECTED),
+	DELEMENT(BTHF_AUDIO_STATE_DISCONNECTING),
+ENDMAP
+
+SINTMAP(bthf_vr_state_t, -1, "(unknown)")
+	DELEMENT(BTHF_VR_STATE_STOPPED),
+	DELEMENT(BTHF_VR_STATE_STARTED),
+ENDMAP
+
+SINTMAP(bthf_volume_type_t, -1, "(unknown)")
+	DELEMENT(BTHF_VOLUME_TYPE_SPK),
+	DELEMENT(BTHF_VOLUME_TYPE_MIC),
+ENDMAP
+
+SINTMAP(bthf_nrec_t, -1, "(unknown)")
+	DELEMENT(BTHF_NREC_STOP),
+	DELEMENT(BTHF_NREC_START),
+ENDMAP
+
+SINTMAP(bthf_chld_type_t, -1, "(unknown)")
+	DELEMENT(BTHF_CHLD_TYPE_RELEASEHELD),
+	DELEMENT(BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD),
+	DELEMENT(BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD),
+	DELEMENT(BTHF_CHLD_TYPE_ADDHELDTOCONF),
+ENDMAP
+
+/* Network Status */
+SINTMAP(bthf_network_state_t, -1, "(unknown)")
+	DELEMENT(BTHF_NETWORK_STATE_NOT_AVAILABLE),
+	DELEMENT(BTHF_NETWORK_STATE_AVAILABLE),
+ENDMAP
+
+/* Service type */
+SINTMAP(bthf_service_type_t, -1, "(unknown)")
+	DELEMENT(BTHF_SERVICE_TYPE_HOME),
+	DELEMENT(BTHF_SERVICE_TYPE_ROAMING),
+ENDMAP
+
+SINTMAP(bthf_call_state_t, -1, "(unknown)")
+	DELEMENT(BTHF_CALL_STATE_ACTIVE),
+	DELEMENT(BTHF_CALL_STATE_HELD),
+	DELEMENT(BTHF_CALL_STATE_DIALING),
+	DELEMENT(BTHF_CALL_STATE_ALERTING),
+	DELEMENT(BTHF_CALL_STATE_INCOMING),
+	DELEMENT(BTHF_CALL_STATE_WAITING),
+	DELEMENT(BTHF_CALL_STATE_IDLE),
+ENDMAP
+
+SINTMAP(bthf_call_direction_t, -1, "(unknown)")
+	DELEMENT(BTHF_CALL_DIRECTION_OUTGOING),
+	DELEMENT(BTHF_CALL_DIRECTION_INCOMING),
+ENDMAP
+
+SINTMAP(bthf_call_mode_t, -1, "(unknown)")
+	DELEMENT(BTHF_CALL_TYPE_VOICE),
+	DELEMENT(BTHF_CALL_TYPE_DATA),
+	DELEMENT(BTHF_CALL_TYPE_FAX),
+ENDMAP
+
+SINTMAP(bthf_call_mpty_type_t, -1, "(unknown)")
+	DELEMENT(BTHF_CALL_MPTY_TYPE_SINGLE),
+	DELEMENT(BTHF_CALL_MPTY_TYPE_MULTI),
+ENDMAP
+
+SINTMAP(bthf_call_addrtype_t, -1, "(unknown)")
+	DELEMENT(BTHF_CALL_ADDRTYPE_UNKNOWN),
+	DELEMENT(BTHF_CALL_ADDRTYPE_INTERNATIONAL),
+ENDMAP
+
+/* Callbacks */
+
+/*
+ * Callback for connection state change.
+ * state will have one of the values from BtHfConnectionState
+ */
+static void connection_state_cb(bthf_connection_state_t state,
+							bt_bdaddr_t *bd_addr)
+{
+}
+
+/*
+ * Callback for audio connection state change.
+ * state will have one of the values from BtHfAudioState
+ */
+static void audio_state_cb(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
+{
+}
+
+/*
+ * Callback for VR connection state change.
+ * state will have one of the values from BtHfVRState
+ */
+static void vr_cmd_cb(bthf_vr_state_t state)
+{
+}
+
+/* Callback for answer incoming call (ATA) */
+static void answer_call_cmd_cb(void)
+{
+}
+
+/* Callback for disconnect call (AT+CHUP) */
+static void hangup_call_cmd_cb(void)
+{
+}
+
+/*
+ * Callback for disconnect call (AT+CHUP)
+ * type will denote Speaker/Mic gain (BtHfVolumeControl).
+ */
+static void volume_cmd_cb(bthf_volume_type_t type, int volume)
+{
+}
+
+/*
+ * Callback for dialing an outgoing call
+ * If number is NULL, redial
+ */
+static void dial_call_cmd_cb(char *number)
+{
+}
+
+/*
+ * Callback for sending DTMF tones
+ * tone contains the dtmf character to be sent
+ */
+static void dtmf_cmd_cb(char tone)
+{
+}
+
+/*
+ * Callback for enabling/disabling noise reduction/echo cancellation
+ * value will be 1 to enable, 0 to disable
+ */
+static void nrec_cmd_cb(bthf_nrec_t nrec)
+{
+}
+
+/*
+ * Callback for call hold handling (AT+CHLD)
+ * value will contain the call hold command (0, 1, 2, 3)
+ */
+static void chld_cmd_cb(bthf_chld_type_t chld)
+{
+}
+
+/* Callback for CNUM (subscriber number) */
+static void cnum_cmd_cb(void)
+{
+}
+
+/* Callback for indicators (CIND) */
+static void cind_cmd_cb(void)
+{
+}
+
+/* Callback for operator selection (COPS) */
+static void cops_cmd_cb(void)
+{
+}
+
+/* Callback for call list (AT+CLCC) */
+static void clcc_cmd_cb(void)
+{
+}
+
+/*
+ * Callback for unknown AT command recd from HF
+ * at_string will contain the unparsed AT string
+ */
+static void unknown_at_cmd_cb(char *at_string)
+{
+}
+
+/* Callback for keypressed (HSP) event. */
+static void key_pressed_cmd_cb(void)
+{
+}
+
+static bthf_callbacks_t hf_cbacks = {
+
+	.size = sizeof(hf_cbacks),
+	.connection_state_cb = connection_state_cb,
+	.audio_state_cb = audio_state_cb,
+	.vr_cmd_cb = vr_cmd_cb,
+	.answer_call_cmd_cb = answer_call_cmd_cb,
+	.hangup_call_cmd_cb = hangup_call_cmd_cb,
+	.volume_cmd_cb = volume_cmd_cb,
+	.dial_call_cmd_cb = dial_call_cmd_cb,
+	.dtmf_cmd_cb = dtmf_cmd_cb,
+	.nrec_cmd_cb = nrec_cmd_cb,
+	.chld_cmd_cb = chld_cmd_cb,
+	.cnum_cmd_cb = cnum_cmd_cb,
+	.cind_cmd_cb = cind_cmd_cb,
+	.cops_cmd_cb = cops_cmd_cb,
+	.clcc_cmd_cb = clcc_cmd_cb,
+	.unknown_at_cmd_cb = unknown_at_cmd_cb,
+	.key_pressed_cmd_cb = key_pressed_cmd_cb,
+};
+
+/* init */
+
+static void init_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_hf);
+
+	EXEC(if_hf->init, &hf_cbacks);
+}
+
+/* connect */
+
+
+static void connect_p(int argc, const char **argv)
+{
+}
+
+/* disconnect */
+
+static void disconnect_p(int argc, const char **argv)
+{
+}
+
+/* create an audio connection */
+
+static void connect_audio_p(int argc, const char **argv)
+{
+}
+
+/* close the audio connection */
+
+static void disconnect_audio_p(int argc, const char **argv)
+{
+}
+
+/* start voice recognition */
+
+static void start_voice_recognition_p(int argc, const char **argv)
+{
+}
+
+/* stop voice recognition */
+
+static void stop_voice_recognition_p(int argc, const char **argv)
+{
+}
+
+/* volume control */
+
+static void volume_control_p(int argc, const char **argv)
+{
+}
+
+/* Combined device status change notification */
+
+static void device_status_notification_p(int argc, const char **argv)
+{
+}
+
+/* Response for COPS command */
+
+static void cops_response_p(int argc, const char **argv)
+{
+}
+
+/* Response for CIND command */
+
+static void cind_response_p(int argc, const char **argv)
+{
+}
+
+/* Pre-formatted AT response, typically in response to unknown AT cmd */
+
+static void formatted_at_response_p(int argc, const char **argv)
+{
+}
+
+/* at_response */
+
+static void at_response_p(int argc, const char **argv)
+{
+}
+
+/* response for CLCC command */
+
+static void clcc_response_p(int argc, const char **argv)
+{
+}
+
+/* phone state change */
+static void phone_state_change_p(int argc, const char **argv)
+{
+}
+
+/* cleanup */
+
+static void cleanup_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_hf);
+
+	EXECV(if_hf->cleanup);
+	if_hf = NULL;
+}
+
+static struct method methods[] = {
+	STD_METHOD(init),
+	STD_METHODH(connect, "<addr>"),
+	STD_METHODH(disconnect, "<addr>"),
+	STD_METHODH(connect_audio, "<addr>"),
+	STD_METHODH(disconnect_audio, "<addr>"),
+	STD_METHOD(start_voice_recognition),
+	STD_METHOD(stop_voice_recognition),
+	STD_METHODH(volume_control, "<vol_type> <volume>"),
+	STD_METHODH(device_status_notification,
+			"<ntk_state> <svt_type> <signal> <batt_chg>"),
+	STD_METHODH(cops_response, "<cops string>"),
+	STD_METHODH(cind_response,
+			"<svc> <num_active> <num_held> <setup_state> <signal> <roam> <batt_chg>"),
+	STD_METHODH(formatted_at_response, "<at_response>"),
+	STD_METHODH(at_response, "<response_code> [<error_code>]"),
+	STD_METHODH(clcc_response,
+			"<index> <direction> <state> <mode> <mpty> <number> <type>"),
+	STD_METHODH(phone_state_change,
+			"<num_active> <num_held> <setup_state> <number> <type>"),
+	STD_METHOD(cleanup),
+	END_METHOD
+};
+
+const struct interface hf_if = {
+	.name = "handsfree",
+	.methods = methods
+};
diff --git a/android/client/if-main.h b/android/client/if-main.h
index eaee914..37086dd 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -45,6 +45,7 @@
 /* Interfaces from hal that can be populated during application lifetime */
 extern const bt_interface_t *if_bluetooth;
 extern const btav_interface_t *if_av;
+extern const bthf_interface_t *if_hf;
 extern const bthh_interface_t *if_hh;
 extern const btpan_interface_t *if_pan;
 extern const btsock_interface_t *if_sock;
@@ -62,6 +63,7 @@ extern const struct interface bluetooth_if;
 extern const struct interface av_if;
 extern const struct interface pan_if;
 extern const struct interface sock_if;
+extern const struct interface hf_if;
 extern const struct interface hh_if;
 
 /* Interfaces that will show up in tool (first part of command line) */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 0/4] Add handsfree interface methods to haltest
From: Jerzy Kasenberg @ 2013-10-28 11:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg

With this patchset handsfree interface is available in haltest.

Jerzy Kasenberg (4):
  android/client: Add skeleton for handsfree calls
  android/client: Add code for handsfree callbacks
  android/client: Add code for handsfree methods
  android/client: Add completion for hf methods

 Makefile.android         |    2 +
 android/Android.mk       |    1 +
 android/client/haltest.c |    1 +
 android/client/if-bt.c   |    2 +-
 android/client/if-hf.c   |  784 ++++++++++++++++++++++++++++++++++++++++++++++
 android/client/if-main.h |    2 +
 6 files changed, 791 insertions(+), 1 deletion(-)
 create mode 100644 android/client/if-hf.c

-- 
1.7.9.5


^ permalink raw reply

* [PATCHv1 4/4] android/hal: Add extra logs
From: Andrei Emeltchenko @ 2013-10-28 10:44 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382957047-31775-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add extra log prints for printing properties and bluetooth addresses.
---
 android/hal-bluetooth.c |   22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index da96202..81e23cb 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -251,7 +251,7 @@ static int set_adapter_property(const bt_property_t *property)
 
 static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
 {
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(remote_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -262,7 +262,8 @@ static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
 static int get_remote_device_property(bt_bdaddr_t *remote_addr,
 						bt_property_type_t type)
 {
-	DBG("");
+	DBG("bdaddr: %s prop: %s", bdaddr2str(remote_addr),
+						bt_property_type_t2str(type));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -273,7 +274,8 @@ 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)
 {
-	DBG("");
+	DBG("bdaddr: %s prop: %s", bdaddr2str(remote_addr),
+						btproperty2str(property));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -283,7 +285,7 @@ static int set_remote_device_property(bt_bdaddr_t *remote_addr,
 
 static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
 {
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(remote_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -293,7 +295,7 @@ static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
 
 static int get_remote_services(bt_bdaddr_t *remote_addr)
 {
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(remote_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -325,7 +327,7 @@ static int create_bond(const bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_create_bond cmd;
 
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(bd_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -340,7 +342,7 @@ static int cancel_bond(const bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_cancel_bond cmd;
 
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(bd_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -355,7 +357,7 @@ static int remove_bond(const bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_remove_bond cmd;
 
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(bd_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -371,7 +373,7 @@ static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
 {
 	struct hal_cmd_pin_reply cmd;
 
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(bd_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -390,7 +392,7 @@ static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
 {
 	struct hal_cmd_ssp_reply cmd;
 
-	DBG("");
+	DBG("bdaddr: %s", bdaddr2str(bd_addr));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 3/4] android/hal: Print full property in debug
From: Andrei Emeltchenko @ 2013-10-28 10:44 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382957047-31775-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Instead of printing property type print type and value. Use exported
function from hal test tool.
---
 android/hal-bluetooth.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5929fff..da96202 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -226,7 +226,7 @@ static int set_adapter_property(const bt_property_t *property)
 	char buf[sizeof(struct hal_cmd_set_adapter_prop) + property->len];
 	struct hal_cmd_set_adapter_prop *cmd = (void *) buf;
 
-	DBG("prop: %s", bt_property_type_t2str(property->type));
+	DBG("prop: %s", btproperty2str(property));
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
-- 
1.7.10.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