* [PATCH v3 07/11] android: Add main_quit function
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
This will allow to stop mainloop from outside of main.c.
---
android/main.c | 6 ++++++
android/main.h | 24 ++++++++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 android/main.h
diff --git a/android/main.c b/android/main.c
index b24451e..04e8a48 100644
--- a/android/main.c
+++ b/android/main.c
@@ -48,6 +48,7 @@
#include "adapter.h"
#include "hal-msg.h"
+#include "main.h"
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;
@@ -418,6 +419,11 @@ static void cleanup_hal_connection(void)
}
}
+void main_quit(void)
+{
+ g_main_loop_quit(event_loop);
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
diff --git a/android/main.h b/android/main.h
new file mode 100644
index 0000000..4aa2557
--- /dev/null
+++ b/android/main.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * 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
+ *
+ */
+
+void main_quit(void);
--
1.8.4
^ permalink raw reply related
* [PATCH v3 06/11] android: Add HAL_SERVICE_ID_MAX define
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
---
android/hal-msg.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 58fff4d..f19d0d0 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -42,6 +42,8 @@ struct hal_msg_hdr {
#define HAL_SERVICE_ID_AVRCP 8
#define HAL_SERVICE_ID_GATT 9
+#define HAL_SERVICE_ID_MAX HAL_SERVICE_ID_GATT
+
/* Core Service */
#define HAL_MSG_OP_ERROR 0x00
--
1.8.4
^ permalink raw reply related
* [PATCH v3 05/11] android: Define IPC MTU size
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
This defines buffer size big enough to hold the largest possible IPC
message.
---
android/hal-msg.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4440fc8..58fff4d 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -21,6 +21,8 @@
*
*/
+#define BLUEZ_HAL_MTU 1024
+
static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
struct hal_msg_hdr {
--
1.8.4
^ permalink raw reply related
* [PATCH v3 04/11] android: Split command and notification socket watch
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
---
android/main.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/android/main.c b/android/main.c
index fac1003..b24451e 100644
--- a/android/main.c
+++ b/android/main.c
@@ -62,10 +62,19 @@ static GIOChannel *hal_notif_io = NULL;
static volatile sig_atomic_t __terminated = 0;
-static gboolean watch_cb(GIOChannel *io, GIOCondition cond,
+static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
- info("HAL socket closed, terminating");
+ info("HAL command socket closed, terminating");
+ g_main_loop_quit(event_loop);
+
+ return FALSE;
+}
+
+static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ info("HAL notification socket closed, terminating");
g_main_loop_quit(event_loop);
return FALSE;
@@ -123,7 +132,7 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
- g_io_add_watch(io, cond, watch_cb, NULL);
+ g_io_add_watch(io, cond, notif_watch_cb, NULL);
info("Successfully connected to HAL");
@@ -144,7 +153,7 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
- g_io_add_watch(io, cond, watch_cb, NULL);
+ g_io_add_watch(io, cond, cmd_watch_cb, NULL);
hal_notif_io = connect_hal(notif_connect_cb);
if (!hal_notif_io) {
--
1.8.4
^ permalink raw reply related
* [PATCH v3 03/11] android/hal: Register adapter and socket interface on HAL init
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
After daemon is started HAL needs to register those two interfaces
to performe initialization procedure as described in IPC documentation.
---
android/hal-bluetooth.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index b9a78b6..f408a7d 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -39,6 +39,9 @@ static bool interface_ready(void)
static int init(bt_callbacks_t *callbacks)
{
+ struct hal_msg_cmd_register_module cmd;
+ struct hal_msg_rsp_error rsp;
+
DBG("");
if (interface_ready())
@@ -49,7 +52,32 @@ static int init(bt_callbacks_t *callbacks)
bt_hal_cbacks = callbacks;
+ cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
+
+ if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+ sizeof(cmd), &cmd,
+ sizeof(rsp), &rsp, NULL) < 0) {
+ error("Failed to register 'bluetooth' service");
+ goto fail;
+ }
+
+ cmd.service_id = HAL_SERVICE_ID_SOCK;
+
+ if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+ sizeof(cmd), &cmd,
+ sizeof(rsp), &rsp, NULL) < 0) {
+ error("Failed to register 'socket' service");
+ goto fail;
+ }
+
return BT_STATUS_SUCCESS;
+
+fail:
+
+ hal_ipc_cleanup();
+ bt_hal_cbacks = NULL;
+ return BT_STATUS_FAIL;
+
}
static int enable(void)
--
1.8.4
^ permalink raw reply related
* [PATCH v3 02/11] android/hal: Add initial code for sending commands
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382381811-28123-1-git-send-email-szymon.janc@tieto.com>
This will be used by all HAL modules to send commands and get response
from daemon. In case of any protocol error abort.
If non-null fd pointer is passed auxiliary data with passed FD will be
received as part of response.
---
android/hal-ipc.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal-ipc.h | 3 ++
2 files changed, 110 insertions(+)
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 6db67f2..5b77adf 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -37,6 +37,8 @@
static int cmd_sk = -1;
static int notif_sk = -1;
+static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
+
static int accept_connection(int sk)
{
int err;
@@ -135,3 +137,108 @@ void hal_ipc_cleanup(void)
close(notif_sk);
notif_sk = -1;
}
+
+int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
+ size_t rsp_len, void *rsp, int *fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct iovec iv[2];
+ struct hal_msg_hdr hal_msg;
+ char cmsgbuf[CMSG_SPACE(sizeof(int))];
+
+ if (cmd_sk < 0)
+ return -EBADF;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&hal_msg, 0, sizeof(hal_msg));
+
+ hal_msg.service_id = service_id;
+ hal_msg.opcode = opcode;
+ hal_msg.len = len;
+
+ iv[0].iov_base = &hal_msg;
+ iv[0].iov_len = sizeof(hal_msg);
+
+ iv[1].iov_base = param;
+ iv[1].iov_len = len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ pthread_mutex_lock(&cmd_sk_mutex);
+
+ ret = sendmsg(cmd_sk, &msg, 0);
+ if (ret < 0) {
+ error("Sending command failed, aborting :%s", strerror(errno));
+ pthread_mutex_unlock(&cmd_sk_mutex);
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&hal_msg, 0, sizeof(hal_msg));
+
+ iv[0].iov_base = &hal_msg;
+ iv[0].iov_len = sizeof(hal_msg);
+
+ iv[1].iov_base = rsp;
+ iv[1].iov_len = rsp_len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ if (fd) {
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ }
+
+ ret = recvmsg(cmd_sk, &msg, 0);
+ if (ret < 0) {
+ error("Receiving command response failed, aborting :%s",
+ strerror(errno));
+ pthread_mutex_unlock(&cmd_sk_mutex);
+ exit(EXIT_FAILURE);
+ }
+
+ pthread_mutex_unlock(&cmd_sk_mutex);
+
+ if (ret < (ssize_t) sizeof(hal_msg)) {
+ error("Too small response received(%zd bytes), aborting", ret);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ret != (ssize_t) (sizeof(hal_msg) + hal_msg.len)) {
+ error("Malformed response received(%zd bytes), aborting", ret);
+ exit(EXIT_FAILURE);
+ }
+
+ if (hal_msg.opcode != opcode && hal_msg.opcode != HAL_MSG_OP_ERROR) {
+ error("Invalid opcode received (%u vs %u), aborting",
+ hal_msg.opcode, opcode);
+ exit(EXIT_FAILURE);
+ }
+
+ if (hal_msg.opcode == HAL_MSG_OP_ERROR) {
+ struct hal_msg_rsp_error *err = rsp;
+ return -err->status;
+ }
+
+ /* Receive auxiliary data in msg */
+ if (fd) {
+ struct cmsghdr *cmsg;
+
+ *fd = -1;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); !cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_RIGHTS) {
+ memcpy(fd, CMSG_DATA(cmsg), sizeof(int));
+ break;
+ }
+ }
+ }
+
+ return hal_msg.len;
+}
diff --git a/android/hal-ipc.h b/android/hal-ipc.h
index 2f71668..3834e7d 100644
--- a/android/hal-ipc.h
+++ b/android/hal-ipc.h
@@ -17,3 +17,6 @@
bool hal_ipc_init(void);
void hal_ipc_cleanup(void);
+
+int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
+ size_t rsp_len, void *rsp, int *fd);
--
1.8.4
^ permalink raw reply related
* [PATCH v3 01/11] android/hal: Move IPC and sockets related code to separate file
From: Szymon Janc @ 2013-10-21 18:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
hal-ipc will provide functionality related to IPC initialization and
sockets handling (including upcoming callbacks thread).
This allow to remove code from bluetooth HAL not related to adapter.
---
Makefile.android | 3 +-
android/Android.mk | 1 +
android/hal-bluetooth.c | 118 ++---------------------------------------
android/hal-ipc.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++
android/hal-ipc.h | 19 +++++++
5 files changed, 163 insertions(+), 115 deletions(-)
create mode 100644 android/hal-ipc.c
create mode 100644 android/hal-ipc.h
diff --git a/Makefile.android b/Makefile.android
index f5a5834..c2010b3 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -33,7 +33,8 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
android/hardware/bt_sock.h \
android/hardware/hardware.h \
android/cutils/properties.h \
- android/hal-log.h
+ android/hal-log.h \
+ android/hal-ipc.h android/hal-ipc.c
android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android
diff --git a/android/Android.mk b/android/Android.mk
index 87445ed..bd3d48a 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -51,6 +51,7 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
+ hal-ipc.c \
hal-bluetooth.c \
hal-sock.c \
hal-hidhost.c \
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 589cb1b..b9a78b6 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -17,136 +17,26 @@
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <stdbool.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <poll.h>
+#include <string.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
#include <hardware/bt_pan.h>
-#include <cutils/properties.h>
-
#include "hal-log.h"
#include "hal.h"
#include "hal-msg.h"
-
-#define SERVICE_NAME "bluetoothd"
-#define CONNECT_TIMEOUT (5 * 1000)
+#include "hal-ipc.h"
bt_callbacks_t *bt_hal_cbacks = NULL;
-static int cmd_sk = -1;
-static int notif_sk = -1;
-
static bool interface_ready(void)
{
return bt_hal_cbacks != NULL;
}
-static int accept_connection(int sk)
-{
- int err;
- struct pollfd pfd;
- int new_sk;
-
- memset(&pfd, 0 , sizeof(pfd));
- pfd.fd = sk;
- pfd.events = POLLIN;
-
- err = poll(&pfd, 1, CONNECT_TIMEOUT);
- if (err < 0) {
- err = errno;
- error("Failed to poll: %d (%s)", err, strerror(err));
- return -1;
- }
-
- if (err == 0) {
- error("bluetoothd connect timeout");
- return -1;
- }
-
- new_sk = accept(sk, NULL, NULL);
- if (new_sk < 0) {
- err = errno;
- error("Failed to accept socket: %d (%s)", err, strerror(err));
- return -1;
- }
-
- return new_sk;
-}
-
-static bool start_daemon(void)
-{
- struct sockaddr_un addr;
- int sk;
- int err;
-
- sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
- if (sk < 0) {
- err = errno;
- error("Failed to create socket: %d (%s)", err,
- strerror(err));
- return false;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
-
- memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
-
- if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- err = errno;
- error("Failed to bind socket: %d (%s)", err, strerror(err));
- close(sk);
- return false;
- }
-
- if (listen(sk, 2) < 0) {
- err = errno;
- error("Failed to listen on socket: %d (%s)", err,
- strerror(err));
- close(sk);
- return false;
- }
-
- /* Start Android Bluetooth daemon service */
- property_set("ctl.start", SERVICE_NAME);
-
- cmd_sk = accept_connection(sk);
- if (cmd_sk < 0) {
- close(sk);
- return false;
- }
-
- notif_sk = accept_connection(sk);
- if (notif_sk < 0) {
- close(sk);
- close(cmd_sk);
- cmd_sk = -1;
- return false;
- }
-
- info("bluetoothd connected");
-
- close(sk);
-
- return true;
-}
-
-static void stop_daemon(void)
-{
- close(cmd_sk);
- cmd_sk = -1;
-
- close(notif_sk);
- notif_sk = -1;
-}
-
static int init(bt_callbacks_t *callbacks)
{
DBG("");
@@ -154,7 +44,7 @@ static int init(bt_callbacks_t *callbacks)
if (interface_ready())
return BT_STATUS_SUCCESS;
- if (!start_daemon())
+ if (!hal_ipc_init())
return BT_STATUS_FAIL;
bt_hal_cbacks = callbacks;
@@ -186,7 +76,7 @@ static void cleanup(void)
if (!interface_ready())
return;
- stop_daemon();
+ hal_ipc_cleanup();
bt_hal_cbacks = NULL;
}
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
new file mode 100644
index 0000000..6db67f2
--- /dev/null
+++ b/android/hal-ipc.c
@@ -0,0 +1,137 @@
+/*
+ * 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 <pthread.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include <cutils/properties.h>
+
+#include "hal-msg.h"
+#include "hal-log.h"
+#include "hal-ipc.h"
+
+#define CONNECT_TIMEOUT (5 * 1000)
+#define SERVICE_NAME "bluetoothd"
+
+static int cmd_sk = -1;
+static int notif_sk = -1;
+
+static int accept_connection(int sk)
+{
+ int err;
+ struct pollfd pfd;
+ int new_sk;
+
+ memset(&pfd, 0 , sizeof(pfd));
+ pfd.fd = sk;
+ pfd.events = POLLIN;
+
+ err = poll(&pfd, 1, CONNECT_TIMEOUT);
+ if (err < 0) {
+ err = errno;
+ error("Failed to poll: %d (%s)", err, strerror(err));
+ return -1;
+ }
+
+ if (err == 0) {
+ error("bluetoothd connect timeout");
+ return -1;
+ }
+
+ new_sk = accept(sk, NULL, NULL);
+ if (new_sk < 0) {
+ err = errno;
+ error("Failed to accept socket: %d (%s)", err, strerror(err));
+ return -1;
+ }
+
+ return new_sk;
+}
+
+bool hal_ipc_init(void)
+{
+ struct sockaddr_un addr;
+ int sk;
+ int err;
+
+ sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
+ if (sk < 0) {
+ err = errno;
+ error("Failed to create socket: %d (%s)", err,
+ strerror(err));
+ return false;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+
+ if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ err = errno;
+ error("Failed to bind socket: %d (%s)", err, strerror(err));
+ close(sk);
+ return false;
+ }
+
+ if (listen(sk, 2) < 0) {
+ err = errno;
+ error("Failed to listen on socket: %d (%s)", err,
+ strerror(err));
+ close(sk);
+ return false;
+ }
+
+ /* Start Android Bluetooth daemon service */
+ property_set("ctl.start", SERVICE_NAME);
+
+ cmd_sk = accept_connection(sk);
+ if (cmd_sk < 0) {
+ close(sk);
+ return false;
+ }
+
+ notif_sk = accept_connection(sk);
+ if (notif_sk < 0) {
+ close(sk);
+ close(cmd_sk);
+ cmd_sk = -1;
+ return false;
+ }
+
+ info("bluetoothd connected");
+
+ close(sk);
+
+ return true;
+}
+
+void hal_ipc_cleanup(void)
+{
+ close(cmd_sk);
+ cmd_sk = -1;
+
+ close(notif_sk);
+ notif_sk = -1;
+}
diff --git a/android/hal-ipc.h b/android/hal-ipc.h
new file mode 100644
index 0000000..2f71668
--- /dev/null
+++ b/android/hal-ipc.h
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ *
+ */
+
+bool hal_ipc_init(void);
+void hal_ipc_cleanup(void);
--
1.8.4
^ permalink raw reply related
* Re: Issue with the kernel bluetooth HCI_Delete_Stored_Link_Key command patch
From: Pavel Machek @ 2013-10-21 18:48 UTC (permalink / raw)
To: alexandre@maloteaux.net, marcel, gustavo, johan.hedberg,
linux-bluetooth
Cc: johan.hedberg
In-Reply-To: <413864804.130358.1382295198929.open-xchange@oxwebmail.registrar-servers.com>
Hi!
Bouncing to right people.
And yes, my thinkpad was hit by something similar, but this one was
subsequently fixed.
Pavel
On Sun 2013-10-20 14:53:18, alexandre@maloteaux.net wrote:
> Hi
> I bought recently an old blutooth dongle in Gabon/Africa. I guess it is a pretty
> old 2.0 as it was written "Vista Compatible" on the box : Bus 004 Device 004: ID
> 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
>
> When trying to use it on ubuntu 13.10 - 3.11.0-12-generic, i got the same issue
> with hcitool :
> Can't init device hci0: Operation not supported (95)
>
> The main issue is that the bit7 of octet 6 is set in the supported command
> response (see attached hcidump).
>
> i tried to recompile the kernel by commenting this code :
>
> + if (hdev->commands[6] & 0x80) {
> + struct hci_cp_delete_stored_link_key cp;
> +
> + bacpy(&cp.bdaddr, BDADDR_ANY);
> + cp.delete_all = 0x01;
> + hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
> + sizeof(cp), &cp);
> + }
>
> and it worked.
>
> Are you sure about the flag position in the supported command ?
> If so , is not possible on fail just to continue the init process as this
> command seems obsolete.
>
> Best Regards
> hcidump -X
> HCI sniffer - Bluetooth packet analyzer ver 2.5
> device: hci0 snap_len: 1500 filter: 0xffffffff
> < HCI Command: Read Local Supported Features (0x04|0x0003) plen 0
> > HCI Event: Command Complete (0x0e) plen 12
> Read Local Supported Features (0x04|0x0003) ncmd 1
> status 0x00
> Features: 0xff 0xff 0x8d 0xfe 0x9b 0xf9 0x00 0x80
> < HCI Command: Read Local Version Information (0x04|0x0001) plen 0
> > HCI Event: Command Complete (0x0e) plen 12
> Read Local Version Information (0x04|0x0001) ncmd 1
> status 0x00
> HCI Version: 2.0 (0x3) HCI Revision: 0x3000
> LMP Version: 2.0 (0x3) LMP Subversion: 0x420b
> Manufacturer: Broadcom Corporation (15)
> < HCI Command: Read BD ADDR (0x04|0x0009) plen 0
> > HCI Event: Command Complete (0x0e) plen 10
> Read BD ADDR (0x04|0x0009) ncmd 1
> status 0x00 bdaddr 00:19:86:00:19:C2
> < HCI Command: Read Buffer Size (0x04|0x0005) plen 0
> > HCI Event: Command Complete (0x0e) plen 11
> Read Buffer Size (0x04|0x0005) ncmd 1
> status 0x00
> ACL MTU 1017:8 SCO MTU 64:0
> < HCI Command: Read Class of Device (0x03|0x0023) plen 0
> > HCI Event: Command Complete (0x0e) plen 7
> Read Class of Device (0x03|0x0023) ncmd 1
> status 0x00 class 0x000000
> < HCI Command: Read Local Name (0x03|0x0014) plen 0
> > HCI Event: Command Complete (0x0e) plen 252
> Read Local Name (0x03|0x0014) ncmd 1
> status 0x00 name 'BCM2045B'
> < HCI Command: Read Voice Setting (0x03|0x0025) plen 0
> > HCI Event: Command Complete (0x0e) plen 6
> Read Voice Setting (0x03|0x0025) ncmd 1
> status 0x00 voice setting 0x0060
> < HCI Command: Set Event Filter (0x03|0x0005) plen 1
> type 0 condition 0
> Clear all filters
> > HCI Event: Command Complete (0x0e) plen 4
> Set Event Filter (0x03|0x0005) ncmd 1
> status 0x00
> < HCI Command: Write Connection Accept Timeout (0x03|0x0016) plen 2
> timeout 32000
> > HCI Event: Command Complete (0x0e) plen 4
> Write Connection Accept Timeout (0x03|0x0016) ncmd 1
> status 0x00
> < HCI Command: Read Page Scan Activity (0x03|0x001b) plen 0
> > HCI Event: Command Complete (0x0e) plen 8
> Read Page Scan Activity (0x03|0x001b) ncmd 1
> status 0x00 interval 2048 window 18
> < HCI Command: Read Page Scan Type (0x03|0x0046) plen 0
> > HCI Event: Command Complete (0x0e) plen 5
> Read Page Scan Type (0x03|0x0046) ncmd 1
> 0000: 00 00 ..
> < HCI Command: Set Event Mask (0x03|0x0001) plen 8
> Mask: 0xfffffbff07180000
> > HCI Event: Command Complete (0x0e) plen 4
> Set Event Mask (0x03|0x0001) ncmd 1
> status 0x00
> < HCI Command: Read Local Supported Commands (0x04|0x0002) plen 0
> > HCI Event: Command Complete (0x0e) plen 68
> Read Local Supported Commands (0x04|0x0002) ncmd 1
> status 0x00
> Commands: ffffffffffffcfffffffffff0300ffff07
> < HCI Command: Write Inquiry Mode (0x03|0x0045) plen 1
> mode 1
> > HCI Event: Command Complete (0x0e) plen 4
> Write Inquiry Mode (0x03|0x0045) ncmd 1
> status 0x00
> < HCI Command: Read Local Extended Features (0x04|0x0004) plen 1
> page 1
> > HCI Event: Command Complete (0x0e) plen 14
> Read Local Extended Features (0x04|0x0004) ncmd 1
> status 0x00 page 1 max 0
> Features: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> < HCI Command: Delete Stored Link Key (0x03|0x0012) plen 7
> bdaddr 00:00:00:00:00:00 all 1
> > HCI Event: Command Complete (0x0e) plen 4
> Delete Stored Link Key (0x03|0x0012) ncmd 1
> status 0x11 deleted 0
> Error: Unsupported Feature or Parameter Value
>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Review about Linux Kernel Bluetooth subsystem in a new Linux Kernel Networking book.
From: Rami Rosen @ 2013-10-21 16:47 UTC (permalink / raw)
To: linux-bluetooth
Hello, all,
I am looking for reviewers for a section about the Linux Kernel
Bluetooth subsystem. It is only 9 pages.
Please reply privately off list.
--
regards,
Rami Rosen
^ permalink raw reply
* [PATCH -v2 5/5] Bluetooth: Remove parent socket usage from l2cap_core.c
From: Gustavo Padovan @ 2013-10-21 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1382372501-28562-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
The parent socket is not used inside the L2CAP core anymore. We only lock
it to indirect access through the new_connection() callback. The hold of
the socket lock was moved to the new_connection() callback.
Inside L2CAP core the channel lock is now used in l2cap_le_conn_ready()
and l2cap_conn_ready() to protect the execution of these two functions
during the handling of new incoming connections.
This change remove the socket lock usage from L2CAP core while keeping
the code safe against race conditions.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 14 ++++----------
net/bluetooth/l2cap_sock.c | 4 ++++
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c65ddc8..bb6d35e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1362,7 +1362,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
struct hci_conn *hcon = conn->hcon;
- struct sock *parent;
struct l2cap_chan *chan, *pchan;
u8 dst_type;
@@ -1384,9 +1383,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
return;
- parent = pchan->sk;
-
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
if (!chan)
@@ -1402,7 +1399,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
__l2cap_chan_add(conn, chan);
clean:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
}
static void l2cap_conn_ready(struct l2cap_conn *conn)
@@ -3705,7 +3702,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3721,10 +3717,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
goto sendresp;
}
- parent = pchan->sk;
-
mutex_lock(&conn->chan_lock);
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
/* Check if the ACL is secure enough (if not SDP) */
if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
@@ -3800,7 +3794,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
}
response:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
sendresp:
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index e559992..a159b0e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1042,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{
struct sock *sk, *parent = chan->data;
+ lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -1059,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
bt_accept_enqueue(parent, sk);
+ release_sock(parent);
+
return l2cap_pi(sk)->chan;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH -v2 4/5] Bluetooth: Remove socket lock from l2cap_state_change()
From: Gustavo Padovan @ 2013-10-21 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1382372501-28562-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This simplify and make safer the state change handling inside l2cap_core.c.
we got rid of __l2cap_state_change(). And l2cap_state_change() doesn't lock
the socket anymore, instead the socket is locked inside the ops callback for
state change in l2cap_sock.c.
It makes the code safer because in some we were using a unlocked version,
and now we are calls to l2cap_state_change(), when dealing with sockets, use
the locked version.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 31 +++++++------------------------
1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 049e1c8..c65ddc8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -223,7 +223,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
-static void __l2cap_state_change(struct l2cap_chan *chan, int state)
+static void l2cap_state_change(struct l2cap_chan *chan, int state)
{
BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
state_to_string(state));
@@ -232,33 +232,16 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
chan->ops->state_change(chan, state, 0);
}
-static void l2cap_state_change(struct l2cap_chan *chan, int state)
-{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
- __l2cap_state_change(chan, state);
- release_sock(sk);
-}
-
static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
int state, int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->state = state;
chan->ops->state_change(chan, chan->state, err);
- release_sock(sk);
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->ops->state_change(chan, chan->state, err);
- release_sock(sk);
}
static void __set_retrans_timer(struct l2cap_chan *chan)
@@ -3787,7 +3770,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_chan_check_security(chan)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
@@ -3797,21 +3780,21 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
* physical link is up.
*/
if (amp_id == AMP_ID_BREDR) {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
result = L2CAP_CR_SUCCESS;
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
}
status = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHEN_PEND;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_NO_INFO;
}
@@ -4738,7 +4721,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
sizeof(rsp), &rsp);
if (result == L2CAP_CR_SUCCESS) {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
L2CAP_CONF_REQ,
--
1.8.3.1
^ permalink raw reply related
* [PATCH -v2 3/5] Bluetooth: Hold socket in defer callback in L2CAP socket
From: Gustavo Padovan @ 2013-10-21 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1382372501-28562-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
In both places that we use the defer callback the socket lock is held for
a indirect sk access inside __l2cap_change_state() and chan->ops->defer(),
all the rest of the code between lock_sock() and release_sock() is
already protected by the channel lock and won't be affected by this
change.
We now use l2cap_change_state(), the locked version of the change state
function, and the defer callback does the locking itself now. This does
not affect other uses of the defer callback.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 15 +++------------
net/bluetooth/l2cap_sock.c | 8 ++++++--
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4141545..049e1c8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1299,20 +1299,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_chan_check_security(chan)) {
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
}
- release_sock(sk);
} else {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
@@ -6643,31 +6639,26 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
}
} else if (chan->state == BT_CONNECT2) {
- struct sock *sk = chan->sk;
struct l2cap_conn_rsp rsp;
__u16 res, stat;
- lock_sock(sk);
-
if (!status) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
res = L2CAP_CR_PEND;
stat = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
res = L2CAP_CR_SUCCESS;
stat = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_DISCONN);
+ l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
- release_sock(sk);
-
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(res);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a0b31db..e559992 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1195,11 +1195,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
{
- struct sock *sk = chan->data;
- struct sock *parent = bt_sk(sk)->parent;
+ struct sock *parent, *sk = chan->data;
+
+ lock_sock(sk);
+ parent = bt_sk(sk)->parent;
if (parent)
parent->sk_data_ready(parent, 0);
+
+ release_sock(sk);
}
static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
--
1.8.3.1
^ permalink raw reply related
* [PATCH -v2 2/5] Bluetooth: Do not access chan->sk directly
From: Gustavo Padovan @ 2013-10-21 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1382372501-28562-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
In the process of removing socket usage from L2CAP we now access the L2CAP
socket from the data member of struct l2cap_chan. For the L2CAP socket
user the data member points to the L2CAP socket.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_sock.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 1f326d9..a0b31db 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1159,11 +1159,12 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb)
{
+ struct sock *sk = chan->data;
struct sk_buff *skb;
int err;
l2cap_chan_unlock(chan);
- skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
+ skb = bt_skb_send_alloc(sk, len, nb, &err);
l2cap_chan_lock(chan);
if (!skb)
--
1.8.3.1
^ permalink raw reply related
* [PATCH -v2 1/5] Bluetooth: Remove not used struct sock
From: Gustavo Padovan @ 2013-10-21 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
It is a leftover from the recent effort of remove sk usage from L2CAP
core.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d52bd0d..4141545 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3726,7 +3726,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent, *sk = NULL;
+ struct sock *parent;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3765,8 +3765,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (!chan)
goto response;
- sk = chan->sk;
-
/* For certain devices (ex: HID mouse), support for authentication,
* pairing and bonding is optional. For such devices, inorder to avoid
* the ACL alive for too long after L2CAP disconnection, reset the ACL
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 0/3] Add basic commands to haltest
From: Johan Hedberg @ 2013-10-21 16:18 UTC (permalink / raw)
To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1382364136-13665-1-git-send-email-jerzy.kasenberg@tieto.com>
Hi Jerzy,
On Mon, Oct 21, 2013, Jerzy Kasenberg wrote:
> - Adds handling of Ctrl-c Ctrl-d as requested
> - Prompted changed to includ space
> - Added commands: quit exit help
> - Added completion for help
> - Terminal settings restored on exit
>
> Jerzy Kasenberg (3):
> android: Add space in prompt in haltest
> android: Add handling of Ctrl-c to haltest
> android: Add help and quit to haltest
>
> android/client/haltest.c | 151 ++++++++++++++++++++++++++++++++++------
> android/client/if-main.h | 6 ++
> android/client/tabcompletion.c | 151 ++++++++++++++++++++++++++++------------
> android/client/terminal.c | 100 ++++++++++++++++++--------
> 4 files changed, 312 insertions(+), 96 deletions(-)
Patches 1 and 3 have been applied. It seems we had a bit of a
misunderstanding about 2 though. I was looking for ctrl-d (i.e. EOF)
support. Sorry for not being more precise here. Right now when I try
it the following just happens:
jh@x220:bluez{master}$ android/haltest
> char-0x04
I wouldn't have expected this to be an issue if stdin is processed
properly, but it seems even something like the following doesn't result
in the expected behavior right now (to run all commands in the file and
then exit the tool):
$ tools/haltest < my-script.txt
Another thing I'd like to see fixed is getting the terminal back to a
sane state when exiting. Right now even after a clean exit I seem to
have to do a hard terminal reset to get normal behavior back. As an
example, the following is what I get after cleanly exiting using "exit"
and then pressing enter a couple of times:
jh@x220:bluez{master}$ android/haltest
> exit
jh@x220:bluez{master}$ jh@x220:bluez{master}$ jh@x220:bluez{master}$
Johan
^ permalink raw reply
* [PATCH] android: Add capabilities and set userid
From: Andrei Emeltchenko @ 2013-10-21 15:09 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The patch set UID as standard Bluetooth user for Android (AID_BLUETOOTH).
It also sets the same capability needed for systemd service (found
in src/bluetooth.service.
---
android/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 57 insertions(+)
diff --git a/android/main.c b/android/main.c
index fac1003..e7f842e 100644
--- a/android/main.c
+++ b/android/main.c
@@ -33,10 +33,17 @@
#include <stdbool.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
+
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/un.h>
+#if defined(ANDROID)
+#include <sys/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif
+
#include <glib.h>
#include "log.h"
@@ -409,6 +416,49 @@ static void cleanup_hal_connection(void)
}
}
+static bool set_capabilities(void)
+{
+#if defined(ANDROID)
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+#endif
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -442,6 +492,9 @@ int main(int argc, char *argv[])
__btd_log_init("*", 0);
+ if (!set_capabilities())
+ return EXIT_FAILURE;
+
if (!init_mgmt_interface())
return EXIT_FAILURE;
diff --git a/configure.ac b/configure.ac
index b4d3998..e3b5220 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
+if (test "${enable_android}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Fix enabling fast connectable on LE-only controllers
From: Marcel Holtmann @ 2013-10-21 14:19 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <1382363513-4083-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> The current "fast connectable" feature is BR/EDR-only, so add a proper
> check for BR/EDR support before proceeding with the associated HCI
> commands.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/mgmt.c | 3 +++
> 1 file changed, 3 insertions(+)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* [PATCH 3/3] android: Add help and quit to haltest
From: Jerzy Kasenberg @ 2013-10-21 14:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382364136-13665-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch adds help and quit commands.
It also adds tab completion for commands (it used to work
for interfaces).
---
android/client/haltest.c | 151 ++++++++++++++++++++++++++++++++++------
android/client/if-main.h | 6 ++
android/client/tabcompletion.c | 151 ++++++++++++++++++++++++++++------------
3 files changed, 240 insertions(+), 68 deletions(-)
diff --git a/android/client/haltest.c b/android/client/haltest.c
index 6b37f33..4864de1 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
@@ -34,6 +34,31 @@ const struct interface *interfaces[] = {
NULL
};
+static struct method commands[];
+
+struct method *get_method(struct method *methods, const char *name)
+{
+ while (strcmp(methods->name, "") != 0) {
+ if (strcmp(methods->name, name) == 0)
+ return methods;
+ methods++;
+ }
+ return NULL;
+}
+
+/* function returns interface of given name or NULL if not found */
+const struct interface *get_interface(const char *name)
+{
+ int i;
+
+ for (i = 0; interfaces[i] != NULL; ++i) {
+ if (strcmp(interfaces[i]->name, name) == 0)
+ break;
+ }
+
+ return interfaces[i];
+}
+
int haltest_error(const char *format, ...)
{
va_list args;
@@ -64,6 +89,95 @@ int haltest_warn(const char *format, ...)
return ret;
}
+static void help_print_interface(const struct interface *i)
+{
+ struct method *m;
+
+ for (m = i->methods; strcmp(m->name, "") != 0; m++)
+ haltest_info("%s %s %s\n", i->name, m->name,
+ (m->help ? m->help : ""));
+}
+
+/* Help completion */
+static void help_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ if (argc == 2)
+ *penum_func = interface_name;
+}
+
+/* Help execution */
+static void help_p(int argc, const char **argv)
+{
+ const struct method *m = commands;
+ const struct interface **ip = interfaces;
+ const struct interface *i;
+
+ if (argc == 1) {
+ terminal_print("haltest allows to call Android HAL methods.\n");
+ terminal_print("\nAvailable commands:\n");
+ while (0 != strcmp(m->name, "")) {
+ terminal_print("\t%s %s\n", m->name,
+ (m->help ? m->help : ""));
+ m++;
+ }
+ terminal_print("\nAvailable interfaces to use:\n");
+ while (NULL != *ip) {
+ terminal_print("\t%s\n", (*ip)->name);
+ ip++;
+ }
+ terminal_print("\nTo get help on methods for each interface type:\n");
+ terminal_print("\n\thelp <inerface>\n");
+ terminal_print("\nBasic scenario:\n\tadapter init\n");
+ terminal_print("\tadapter enable\n\tadapter start_discovery\n");
+ terminal_print("\tadapter get_profile_interface handsfree\n");
+ terminal_print("\thandsfree init\n\n");
+ return;
+ }
+ i = get_interface(argv[1]);
+ if (i == NULL) {
+ haltest_error("No such interface\n");
+ return;
+ }
+ help_print_interface(i);
+}
+
+/* quit/exit execution */
+static void quit_p(int argc, const char **argv)
+{
+ exit(0);
+}
+
+/* Commands available without interface */
+static struct method commands[] = {
+ STD_METHODCH(help, "[<interface>]"),
+ STD_METHOD(quit),
+ METHOD("exit", quit_p, NULL, NULL),
+ END_METHOD
+};
+
+/* Gets comman by name */
+struct method *get_command(const char *name)
+{
+ return get_method(commands, name);
+}
+
+/* Function to enumerate interface names */
+const char *interface_name(void *v, int i)
+{
+ return interfaces[i] ? interfaces[i]->name : NULL;
+}
+
+/* Function to enumerate command and interface names */
+const char *command_name(void *v, int i)
+{
+ int cmd_cnt = (int) (sizeof(commands)/sizeof(commands[0]) - 1);
+ if (i >= cmd_cnt)
+ return interface_name(v, i - cmd_cnt);
+ else
+ return commands[i].name;
+}
+
/*
* This function changes input parameter line_buffer so it has
* null termination after each token (due to strtok)
@@ -91,7 +205,7 @@ static void process_line(char *line_buffer)
char *argv[10];
int argc;
int i = 0;
- int j;
+ struct method *m;
argc = command_line_to_argv(line_buffer, argv, 10);
if (argc < 1)
@@ -103,32 +217,23 @@ static void process_line(char *line_buffer)
continue;
}
if (argc < 2 || strcmp(argv[1], "?") == 0) {
- struct method *m = &interfaces[i]->methods[0];
- while (strcmp(m->name, "")) {
- haltest_info("%s %s %s\n", argv[0],
- m->name,
- (m->help ? m->help : ""));
- m++;
- }
+ help_print_interface(interfaces[i]);
return;
}
- j = 0;
- while (strcmp(interfaces[i]->methods[j].name, "")) {
- if (strcmp(interfaces[i]->methods[j].name, argv[1])) {
- j++;
- continue;
- }
- interfaces[i]->methods[j].func(argc,
- (const char **)argv);
- break;
+ m = get_method(interfaces[i]->methods, argv[1]);
+ if (m != NULL) {
+ m->func(argc, (const char **) argv);
+ return;
}
- if (strcmp(interfaces[i]->methods[j].name, "") == 0)
- printf("No function %s found\n", argv[1]);
- break;
+ haltest_error("No function %s found\n", argv[1]);
+ return;
}
-
- if (interfaces[i] == NULL)
- printf("No such interface %s\n", argv[0]);
+ /* No interface, try commands */
+ m = get_command(argv[0]);
+ if (m == NULL)
+ haltest_error("No such command %s\n", argv[0]);
+ else
+ m->func(argc, (const char **) argv);
}
/* called when there is something on stdin */
diff --git a/android/client/if-main.h b/android/client/if-main.h
index b6bbf05..6d2b0cb 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -107,8 +107,14 @@ int haltest_warn(const char *format, ...);
* Enumerator for discovered devices, to be used as tab completion enum_func
*/
const char *enum_devices(void *v, int i);
+const char *interface_name(void *v, int i);
+const char *command_name(void *v, int i);
void add_remote_device(const bt_bdaddr_t *addr);
+const struct interface *get_interface(const char *name);
+struct method *get_method(struct method *methods, const char *name);
+struct method *get_command(const char *name);
+
/* Helper macro for executing function on interface and printing BT_STATUS */
#define EXEC(f, ...) \
{ \
diff --git a/android/client/tabcompletion.c b/android/client/tabcompletion.c
index e9c9921..2b95591 100644
--- a/android/client/tabcompletion.c
+++ b/android/client/tabcompletion.c
@@ -29,33 +29,16 @@ typedef struct split_arg {
char ntcopy[1]; /* null terminated copy of argument */
} split_arg_t;
-/* function returns interface of given name or NULL if not found */
-static const struct interface *get_interface(const char *name)
-{
- int i;
-
- for (i = 0; interfaces[i] != NULL; ++i) {
- if (strcmp(interfaces[i]->name, name) == 0)
- break;
- }
-
- return interfaces[i];
-}
-
/* function returns method of given name or NULL if not found */
-static const struct method *get_method(const char *iname, const char *mname)
+static const struct method *get_interface_method(const char *iname,
+ const char *mname)
{
- int i;
const struct interface *iface = get_interface(iname);
if (iface == NULL)
return NULL;
- for (i = 0; iface->methods[i].name[0]; ++i) {
- if (0 == strcmp(iface->methods[i].name, mname))
- return &iface->methods[i];
- }
- return NULL;
+ return get_method(iface->methods, mname);
}
/* prints matching elements */
@@ -113,12 +96,6 @@ static int split_command(const char *line_buffer, int size,
return argc;
}
-/* Function to enumerate interface names */
-static const char *interface_name(void *v, int i)
-{
- return interfaces[i] ? interfaces[i]->name : NULL;
-}
-
/* Function to enumerate method names */
static const char *methods_name(void *v, int i)
{
@@ -142,7 +119,7 @@ struct command_completion_args {
/*
* complete command line
*/
-static void command_completion(struct command_completion_args *args)
+static void tab_completion(struct command_completion_args *args)
{
const char *name = args->typed;
const int len = strlen(name);
@@ -211,15 +188,15 @@ static void command_completion(struct command_completion_args *args)
}
/* interface completion */
-static void interface_completion(split_arg_t *arg)
+static void command_completion(split_arg_t *arg)
{
struct command_completion_args args = {
.arg = arg,
.typed = arg->ntcopy,
- .func = interface_name
+ .func = command_name
};
- command_completion(&args);
+ tab_completion(&args);
}
/* method completion */
@@ -235,17 +212,86 @@ static void method_completion(const struct interface *iface, split_arg_t *arg)
if (iface == NULL)
return;
- command_completion(&args);
+ tab_completion(&args);
+}
+
+static const char *bold = "\x1b[1m";
+static const char *normal = "\x1b[0m";
+
+static bool find_nth_argument(const char *str, int n,
+ const char **s, const char **e)
+{
+ const char *p = str;
+ int argc = 0;
+ *e = NULL;
+
+ while (p != NULL && *p != 0) {
+
+ while (isspace(*p))
+ ++p;
+
+ if (n == argc)
+ *s = p;
+
+ if (*p == '[') {
+ p = strchr(p, ']');
+ if (p != NULL)
+ *e = ++p;
+ } else if (*p == '<') {
+ p = strchr(p, '>');
+ if (p != NULL)
+ *e = ++p;
+ } else {
+ *e = strchr(p, ' ');
+ if (*e == NULL)
+ *e = p + strlen(p);
+ p = *e;
+ }
+
+ if (n == argc)
+ break;
+
+ argc++;
+ *e = NULL;
+ }
+ return *e != NULL;
}
/* prints short help on method for interface */
static void method_help(struct command_completion_args *args)
{
+ int argc;
+ const split_arg_t *arg = args->arg;
+ const char *sb = NULL;
+ const char *eb = NULL;
+ const char *arg1 = "";
+ int arg1_size = 0; /* size of method field (for methods > 0) */
+
if (args->user_help == NULL)
return;
- haltest_info("%s %s %s\n", args->arg->ntcopy,
- args->arg->next->ntcopy, args->user_help);
+ for (argc = 0; arg != NULL; argc++)
+ arg = arg->next;
+
+ /* Check if this is method from interface */
+ if (get_command(args->arg->ntcopy) == NULL) {
+ /* if so help is missing interface and method name */
+ arg1 = args->arg->next->ntcopy;
+ arg1_size = strlen(arg1) + 1;
+ }
+
+ find_nth_argument(args->user_help, argc - (arg1_size ? 3 : 2),
+ &sb, &eb);
+
+ if (eb != NULL)
+ haltest_info("%s %-*s%.*s%s%.*s%s%s\n", args->arg->ntcopy,
+ arg1_size, arg1,
+ sb - (const char *) args->user_help,
+ args->user_help,
+ bold, eb - sb, sb, normal, eb);
+ else
+ haltest_info("%s %-*s%s\n", args->arg->ntcopy,
+ arg1_size, arg1, args->user_help);
}
/* So we have empty enumeration */
@@ -254,10 +300,15 @@ static const char *return_null(void *user, int i)
return NULL;
}
-/* parameter completion function */
-static void param_completion(int argc, const split_arg_t *arg)
+/*
+ * parameter completion function
+ * argc - number of elements in arg list
+ * arg - list of arguments
+ * megthod - method to get completion from (can be NULL)
+ */
+static void param_completion(int argc, const split_arg_t *arg,
+ const struct method *method, int hlpix)
{
- const struct method *method;
int i;
const char *argv[argc];
const split_arg_t *tmp = arg;
@@ -272,9 +323,6 @@ static void param_completion(int argc, const split_arg_t *arg)
tmp = tmp->next;
}
- /* Find method for <interface, name> pair */
- method = get_method(argv[0], argv[1]);
-
if (method != NULL && method->complete != NULL) {
/* ask method for completion function */
method->complete(argc, argv, &args.func, &args.user);
@@ -286,7 +334,7 @@ static void param_completion(int argc, const split_arg_t *arg)
args.help = method_help;
args.user_help = (void *) method->help;
- command_completion(&args);
+ tab_completion(&args);
}
}
@@ -300,14 +348,27 @@ void process_tab(const char *line, int len)
{
int argc;
static split_arg_t buf[(LINE_BUF_MAX * 2) / sizeof(split_arg_t)];
+ const struct method *method;
argc = split_command(line, len, buf, sizeof(buf));
tab_hit_count++;
- if (argc == 1)
- interface_completion(buf);
- else if (argc == 2)
+ if (argc == 0)
+ return;
+
+ if (argc == 1) {
+ command_completion(buf);
+ return;
+ }
+ method = get_command(buf[0].ntcopy);
+ if (method != NULL) {
+ param_completion(argc, buf, method, 1);
+ } else if (argc == 2) {
method_completion(get_interface(buf[0].ntcopy), buf);
- else if (argc > 2)
- param_completion(argc, buf);
+ } else {
+ /* Find method for <interface, name> pair */
+ method = get_interface_method(buf[0].ntcopy,
+ buf[0].next->ntcopy);
+ param_completion(argc, buf, method, 2);
+ }
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/3] android: Add handling of Ctrl-c to haltest
From: Jerzy Kasenberg @ 2013-10-21 14:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382364136-13665-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch adds handling of Ctrl-C so it does not break tool.
To exit tool Ctrl-D is used on empty command line.
Ctrl-D on not empty command line works like Delete key.
---
android/client/terminal.c | 83 +++++++++++++++++++++++++++++++++------------
1 file changed, 62 insertions(+), 21 deletions(-)
diff --git a/android/client/terminal.c b/android/client/terminal.c
index fb4d5d8..a57068a 100644
--- a/android/client/terminal.c
+++ b/android/client/terminal.c
@@ -20,6 +20,7 @@
#include <ctype.h>
#include <stdbool.h>
#include <termios.h>
+#include <stdlib.h>
#include "terminal.h"
#include "history.h"
@@ -90,6 +91,10 @@ static const struct ansii_sequence ansii_sequnces[] = {
{ 0, NULL }
};
+#define KEY_SEQUNCE_NOT_FINISHED -1
+#define KEY_C_C 3
+#define KEY_C_D 4
+
#define isseqence(c) ((c) == 0x1B)
/*
@@ -224,6 +229,30 @@ static void terminal_line_replaced(void)
line_buf_ix = line_len;
}
+static void terminal_clear_line(void)
+{
+ line_buf[0] = '\0';
+ terminal_line_replaced();
+}
+
+static void terminal_delete_char(void)
+{
+ /* delete character under cursor if not at the very end */
+ if (line_buf_ix >= line_len)
+ return;
+ /*
+ * Prepare buffer with one character missing
+ * trailing 0 is moved
+ */
+ line_len--;
+ memmove(line_buf + line_buf_ix, line_buf + line_buf_ix + 1,
+ line_len - line_buf_ix + 1);
+ /* print rest of line from current cursor position */
+ printf("%s \b", line_buf + line_buf_ix);
+ /* move back cursor */
+ terminal_move_cursor(line_buf_ix - line_len);
+}
+
/*
* Function tries to replace current line with specified line in history
* new_line_index - new line to show, -1 to show oldest
@@ -288,7 +317,7 @@ static int terminal_convert_sequence(int c)
/* Is ansii sequence detected by 0x1B ? */
if (isseqence(c)) {
current_sequence_len++;
- return 0;
+ return KEY_SEQUNCE_NOT_FINISHED;
}
return c;
}
@@ -307,7 +336,7 @@ static int terminal_convert_sequence(int c)
return ansii_sequnces[i].code;
}
/* partial match (not whole sequence yet) */
- return 0;
+ return KEY_SEQUNCE_NOT_FINISHED;
}
terminal_print("ansii char 0x%X %c\n", c);
/*
@@ -326,7 +355,7 @@ void terminal_process_char(int c, void (*process_line)(char *line))
c = terminal_convert_sequence(c);
switch (c) {
- case 0:
+ case KEY_SEQUNCE_NOT_FINISHED:
break;
case KEY_LEFT:
/* if not at the beginning move to previous character */
@@ -358,21 +387,7 @@ void terminal_process_char(int c, void (*process_line)(char *line))
}
break;
case KEY_DELETE:
- /* delete character under cursor if not at the very end */
- if (line_buf_ix >= line_len)
- break;
- /*
- * Prepare buffer with one character missing
- * trailing 0 is moved
- */
- line_len--;
- memmove(line_buf + line_buf_ix,
- line_buf + line_buf_ix + 1,
- line_len - line_buf_ix + 1);
- /* print rest of line from current cursor position */
- printf("%s \b", line_buf + line_buf_ix);
- /* move back cursor */
- terminal_move_cursor(line_buf_ix - line_len);
+ terminal_delete_char();
break;
case KEY_CLEFT:
/*
@@ -495,6 +510,17 @@ void terminal_process_char(int c, void (*process_line)(char *line))
/* Search history backward */
terminal_match_hitory(true);
break;
+ case KEY_C_C:
+ terminal_clear_line();
+ break;
+ case KEY_C_D:
+ if (line_len > 0) {
+ terminal_delete_char();
+ } else {
+ puts("");
+ exit(0);
+ }
+ break;
default:
if (!isprint(c)) {
/*
@@ -528,13 +554,28 @@ void terminal_process_char(int c, void (*process_line)(char *line))
}
}
+static struct termios origianl_tios;
+
+static void terminal_cleanup(void)
+{
+ tcsetattr(0, TCSANOW, &origianl_tios);
+}
+
void terminal_setup(void)
{
struct termios tios;
+ tcgetattr(0, &origianl_tios);
+ tios = origianl_tios;
- /* Turn off echo since all editing is done by hand */
- tcgetattr(0, &tios);
- tios.c_lflag &= ~(ICANON | ECHO);
+ /*
+ * Turn off echo since all editing is done by hand,
+ * Ctrl-c handled internaly
+ */
+ tios.c_lflag &= ~(ICANON | ECHO | BRKINT | IGNBRK);
tcsetattr(0, TCSANOW, &tios);
+
+ /* Restore terminal at exit */
+ atexit(terminal_cleanup);
+
printf("%s", prompt);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/3] android: Add space in prompt in haltest
From: Jerzy Kasenberg @ 2013-10-21 14:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382364136-13665-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch makes prompt more consistent with other bluez tools.
This also fixes small issue when prompt was printed twice.
---
android/client/terminal.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/android/client/terminal.c b/android/client/terminal.c
index 8dd3a25..fb4d5d8 100644
--- a/android/client/terminal.c
+++ b/android/client/terminal.c
@@ -111,6 +111,8 @@ static int line_len = 0;
/* line index used for fetching lines from history */
static int line_index = 0;
+static char prompt_buf[10] = "> ";
+static const char *prompt = prompt_buf;
/*
* Moves cursor to right or left
*
@@ -135,9 +137,9 @@ void terminal_draw_command_line(void)
* before parsing event though line_len and line_buf_ix are
*/
if (line_len > 0)
- printf(">%s", line_buf);
+ printf("%s%s", prompt, line_buf);
else
- putchar('>');
+ printf("%s", prompt);
/* move cursor to it's place */
terminal_move_cursor(line_buf_ix - line_len);
@@ -216,7 +218,7 @@ static void terminal_line_replaced(void)
putchar(' ');
}
/* draw new line */
- printf("\r>%s", line_buf);
+ printf("\r%s%s", prompt, line_buf);
/* set up indexes to new line */
line_len = strlen(line_buf);
line_buf_ix = line_len;
@@ -343,8 +345,7 @@ void terminal_process_char(int c, void (*process_line)(char *line))
break;
case KEY_HOME:
/* move to beginning of line and update position */
- putchar('\r');
- putchar('>');
+ printf("\r%s", prompt);
line_buf_ix = 0;
break;
case KEY_END:
@@ -446,10 +447,12 @@ void terminal_process_char(int c, void (*process_line)(char *line))
line_index = -1;
/* print new line */
putchar(c);
+ prompt = "";
process_line(line_buf);
/* clear current line */
line_buf[0] = '\0';
- putchar('>');
+ prompt = prompt_buf;
+ printf("%s", prompt);
break;
case '\t':
/* tab processing */
@@ -533,5 +536,5 @@ void terminal_setup(void)
tcgetattr(0, &tios);
tios.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &tios);
- putchar('>');
+ printf("%s", prompt);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/3] Add basic commands to haltest
From: Jerzy Kasenberg @ 2013-10-21 14:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
- Adds handling of Ctrl-c Ctrl-d as requested
- Prompted changed to includ space
- Added commands: quit exit help
- Added completion for help
- Terminal settings restored on exit
Jerzy Kasenberg (3):
android: Add space in prompt in haltest
android: Add handling of Ctrl-c to haltest
android: Add help and quit to haltest
android/client/haltest.c | 151 ++++++++++++++++++++++++++++++++++------
android/client/if-main.h | 6 ++
android/client/tabcompletion.c | 151 ++++++++++++++++++++++++++++------------
android/client/terminal.c | 100 ++++++++++++++++++--------
4 files changed, 312 insertions(+), 96 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH] Bluetooth: Fix enabling fast connectable on LE-only controllers
From: johan.hedberg @ 2013-10-21 13:51 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
The current "fast connectable" feature is BR/EDR-only, so add a proper
check for BR/EDR support before proceeding with the associated HCI
commands.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/mgmt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bd91ee5..074d836 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1307,6 +1307,9 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
struct hci_cp_write_page_scan_activity acp;
u8 type;
+ if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
+ return;
+
if (hdev->hci_ver < BLUETOOTH_VER_1_2)
return;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH BlueZ] core: Fix not forwarding errors caused by SDP search properly
From: Johan Hedberg @ 2013-10-21 13:26 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1382360648-5167-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Mon, Oct 21, 2013, Luiz Augusto von Dentz wrote:
> In case bt_search_service fails while processing (e.g. connection is
> dropped) the error forward is a positive value leading
> btd_service_connecting_complete to not change any state at all.
>
> Futhermore the error from sdp_process was completely ignored which may
> cause problems as well.
> ---
> src/sdp-client.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH v2 1/3] android: Add missing error status description for Core Service
From: Johan Hedberg @ 2013-10-21 13:25 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382360211-3565-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Mon, Oct 21, 2013, Szymon Janc wrote:
> We need at least one failed status description.
> ---
> android/hal-ipc-api.txt | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
This first patch has been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ] core: Fix not forwarding errors caused by SDP search properly
From: Luiz Augusto von Dentz @ 2013-10-21 13:04 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In case bt_search_service fails while processing (e.g. connection is
dropped) the error forward is a positive value leading
btd_service_connecting_complete to not change any state at all.
Futhermore the error from sdp_process was completely ignored which may
cause problems as well.
---
src/sdp-client.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/sdp-client.c b/src/sdp-client.c
index 2789db6..1221f5e 100644
--- a/src/sdp-client.c
+++ b/src/sdp-client.c
@@ -196,14 +196,15 @@ static gboolean search_process_cb(GIOChannel *chan, GIOCondition cond,
gpointer user_data)
{
struct search_context *ctxt = user_data;
- int err = 0;
+ int err;
if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
- err = EIO;
+ err = -EIO;
goto failed;
}
- if (sdp_process(ctxt->session) < 0)
+ err = sdp_process(ctxt->session);
+ if (err < 0)
goto failed;
return TRUE;
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox