* [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
* [PATCH v2 3/3] android/hal: Register adapter and socket interface on HAL init
From: Szymon Janc @ 2013-10-21 12:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382360211-3565-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 | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 3d3023f..c1e0261 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -257,6 +257,9 @@ static void stop_daemon(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())
@@ -267,7 +270,27 @@ static int init(bt_callbacks_t *callbacks)
bt_hal_cbacks = callbacks;
+ cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
+
+ if (hal_send_msg(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+ sizeof(cmd), &cmd,
+ sizeof(rsp), &rsp, NULL) < 0)
+ goto fail;
+
+ cmd.service_id = HAL_SERVICE_ID_SOCK;
+
+ if (hal_send_msg(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+ sizeof(cmd), &cmd,
+ sizeof(rsp), &rsp, NULL) < 0)
+ goto fail;
+
return BT_STATUS_SUCCESS;
+
+fail:
+ stop_daemon();
+ bt_hal_cbacks = NULL;
+ return BT_STATUS_FAIL;
+
}
static int enable(void)
--
1.8.4
^ permalink raw reply related
* [PATCH v2 2/3] android/hal: Add initial code for sending commands
From: Szymon Janc @ 2013-10-21 12:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382360211-3565-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-bluetooth.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg.h | 3 ++
2 files changed, 111 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 589cb1b..3d3023f 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -23,6 +23,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <poll.h>
+#include <pthread.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
@@ -43,6 +44,113 @@ bt_callbacks_t *bt_hal_cbacks = NULL;
static int cmd_sk = -1;
static int notif_sk = -1;
+static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int hal_send_msg(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);
+ abort();
+ }
+
+ 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);
+ abort();
+ }
+
+ pthread_mutex_unlock(&cmd_sk_mutex);
+
+ if (ret < (ssize_t)sizeof(hal_msg)) {
+ error("Too small response received(%zd bytes), aborting", ret);
+ abort();
+ }
+
+ if (ret != (ssize_t)(sizeof(hal_msg) + hal_msg.len)) {
+ error("Malformed response received(%zd bytes), aborting", ret);
+ abort();
+ }
+
+ if (hal_msg.opcode != opcode && hal_msg.opcode != HAL_MSG_OP_ERROR) {
+ error("Invalid opcode received (%u vs %u), aborting",
+ hal_msg.opcode, opcode);
+ abort();
+ }
+
+ 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;
+}
+
static bool interface_ready(void)
{
return bt_hal_cbacks != NULL;
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4440fc8..a33df96 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -246,3 +246,6 @@ struct hal_msg_ev_bt_le_test_mode {
uint8_t status;
uint16_t num_packets;
} __attribute__((packed));
+
+int hal_send_msg(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 v2 1/3] android: Add missing error status description for Core Service
From: Szymon Janc @ 2013-10-21 12:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
We need at least one failed status description.
---
android/hal-ipc-api.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index 9a8b770..5d8e085 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -117,7 +117,9 @@ Core Service (ID 0)
Opcode 0x00 - Error response
- Response parameters: Error (1 octet)
+ Response parameters: Status (1 octet)
+
+ Valid status values: 0x01 = Fail
Opcode 0x01 - Register module command/response
--
1.8.4
^ permalink raw reply related
* [RFCv1 6/6] android: Add Android HAL callback task
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Android HAL callback task listens for messages from BlueZ GPL daemon.
---
android/Android.mk | 6 ++++
android/hal-cb-thread.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
create mode 100644 android/hal-cb-thread.c
diff --git a/android/Android.mk b/android/Android.mk
index 786c9fb..c5c6e7b 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -58,9 +58,15 @@ LOCAL_SRC_FILES := \
hal-pan.c \
hal-msg-client.c \
bt-sock.c \
+ hal-cb-thread.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
+ libglib \
+
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
LOCAL_MODULE := bluetooth.default
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
diff --git a/android/hal-cb-thread.c b/android/hal-cb-thread.c
new file mode 100644
index 0000000..1b1e228
--- /dev/null
+++ b/android/hal-cb-thread.c
@@ -0,0 +1,86 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <sys/epoll.h>
+#include <hardware/bluetooth.h>
+#include <fcntl.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+#include "hal-msg.h"
+
+#define HAL_CBACK(base, cb_function, ...) \
+ do { \
+ if (base && base->cb_function) { \
+ ALOGI("CB %s->%s", #base, #cb_function); \
+ base->cb_function(__VA_ARGS__); \
+ } else { \
+ ALOGE("%s: Callback is NULL", __func__); \
+ } \
+ } while (0)
+
+extern bt_callbacks_t *bt_hal_cbacks;
+
+static int epfd;
+
+static void bthal_thread_associate(void)
+{
+ ALOGI(__func__);
+
+ HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);
+}
+
+static void bthal_thread_disassociate(void)
+{
+ ALOGI(__func__);
+
+ HAL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM);
+
+ bt_hal_cbacks = NULL;
+}
+
+void process_msg(struct hal_msg_hdr *msg)
+{
+ ALOGI(__func__);
+
+ /* TODO: Process messages from daemon */
+}
+
+int mainloop(void)
+{
+ return EXIT_SUCCESS;
+}
+
+void *hal_cb_task(void *arg)
+{
+ int sock;
+
+ sock = open_hal_chan();
+
+ bthal_thread_associate();
+
+ bthal_thread_disassociate();
+
+ return NULL;
+}
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 5/6] android: Add helper to send fd using SCM_RIGHTS
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is used in accept message to Android framework.
---
android/Android.mk | 1 +
android/bt-sock.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
create mode 100644 android/bt-sock.c
diff --git a/android/Android.mk b/android/Android.mk
index 4bd4116..786c9fb 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -57,6 +57,7 @@ LOCAL_SRC_FILES := \
hal-hidhost.c \
hal-pan.c \
hal-msg-client.c \
+ bt-sock.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/bt-sock.c b/android/bt-sock.c
new file mode 100644
index 0000000..68dbe32
--- /dev/null
+++ b/android/bt-sock.c
@@ -0,0 +1,64 @@
+/*
+ * 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 <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+
+int bt_sock_send_acc_fd(int sock_fd, const unsigned char *buf, int len,
+ int send_fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iv;
+ char msgbuf[CMSG_SPACE(1)];
+
+ ALOGD("%s: len %d sock_fd %d send_fd %d", __func__, len, sock_fd,
+ send_fd);
+
+ if (sock_fd == -1 || send_fd == -1)
+ return -1;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = msgbuf;
+ msg.msg_controllen = sizeof(msgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+ memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+ iv.iov_base = (unsigned char *) buf;
+ iv.iov_len = len;
+
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+ if (ret < 0) {
+ ALOGE("%s: sock_fd %d send_fd %d sendmsg ret %d errno %d %s",
+ __func__, sock_fd, send_fd, (int)ret, errno,
+ strerror(errno));
+ return ret;
+ }
+
+ return ret;
+}
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 4/6] android: Add HAL message helpers
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add helper to ease opening channel and sending commands.
---
android/Android.mk | 1 +
android/hal-msg-client.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg-client.h | 25 ++++++++++
3 files changed, 149 insertions(+)
create mode 100644 android/hal-msg-client.c
create mode 100644 android/hal-msg-client.h
diff --git a/android/Android.mk b/android/Android.mk
index d5dfde7..4bd4116 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -56,6 +56,7 @@ LOCAL_SRC_FILES := \
hal-sock.c \
hal-hidhost.c \
hal-pan.c \
+ hal-msg-client.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal-msg-client.c b/android/hal-msg-client.c
new file mode 100644
index 0000000..43af9a1
--- /dev/null
+++ b/android/hal-msg-client.c
@@ -0,0 +1,123 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+#include "hal-msg.h"
+#include "hal-msg-client.h"
+
+#define BLUEZ_SOCKET "/tmp/bt_hal"
+
+int open_hal_chan(void)
+{
+ int tries = 10;
+ int sock;
+
+ while (tries-- > 0) {
+ sock = socket_local_client(BLUEZ_SOCKET,
+ ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
+ SOCK_SEQPACKET);
+ if (sock < 0)
+ ALOGE("%s: Cannot open chan: %s", __func__,
+ strerror(errno));
+ else
+ return sock;
+
+ usleep(100000);
+ }
+
+ return sock;
+}
+
+static int hal_send(int sock, struct hal_msg_hdr *msg)
+{
+ int len, size;
+ uint8_t buf[MAX_HAL_BUF_SIZE];
+ struct hal_msg_rsp {
+ struct hal_msg_hdr hdr;
+ uint8_t status;
+ } *rsp;
+
+ if (sock < 0) {
+ ALOGE("%s: socket not ready", __func__);
+ return BT_STATUS_NOT_READY;
+ }
+
+ size = sizeof(*msg) + msg->len;
+ len = send(sock, msg, size, 0);
+ if (len != size) {
+ ALOGE("%s: send(): %s", __func__, strerror(errno));
+ close(sock);
+ return BT_STATUS_FAIL;
+ }
+
+ ALOGD("%s: Sent %d bytes", __func__, len);
+
+ len = recv(sock, &buf, sizeof(buf), 0);
+ if (len <= 0) {
+ ALOGE("%s: recv(): %s", __func__, strerror(errno));
+ return BT_STATUS_FAIL;
+ }
+
+ if (len == sizeof(struct hal_msg_hdr))
+ return BT_STATUS_SUCCESS;
+
+ rsp = (struct hal_msg_rsp *) buf;
+
+ ALOGE("%s: error returned: %u", __func__, rsp->status);
+
+ return rsp->status;
+}
+
+int hal_register_module(int sock, uint8_t service_id)
+{
+ struct hal_msg_hdr *hdr;
+ struct hal_msg_cmd_register_module *msg;
+ int err;
+
+ hdr = malloc(sizeof(*hdr) + sizeof(*msg));
+ if (hdr == NULL)
+ return BT_STATUS_NOMEM;
+
+ hdr->service_id = 0;
+ hdr->opcode = HAL_MSG_OP_REGISTER_MODULE;
+ hdr->len = sizeof(*msg);
+
+ msg = (struct hal_msg_cmd_register_module *) hdr + sizeof(*hdr);
+ msg->service_id = service_id;
+
+ err = hal_send(sock, hdr);
+
+ free(hdr);
+ return err;
+}
diff --git a/android/hal-msg-client.h b/android/hal-msg-client.h
new file mode 100644
index 0000000..c620dea
--- /dev/null
+++ b/android/hal-msg-client.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int hal_register_module(int sock, uint8_t service_id);
+int open_hal_chan(void);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 3/6] android: Implement basic HAL server
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add basic HAL server on BlueZ daemon side. It will listen for messages
from Android HAL threads.
---
Makefile.android | 2 +-
android/Android.mk | 1 +
android/hal-msg.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg.h | 5 +
android/main.c | 11 +++
5 files changed, 285 insertions(+), 1 deletion(-)
create mode 100644 android/hal-msg.c
diff --git a/Makefile.android b/Makefile.android
index 8196583..96f3f22 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -3,7 +3,7 @@ noinst_PROGRAMS += android/bluetoothd
android_bluetoothd_SOURCES = android/main.c \
src/log.c \
- android/hal-msg.h \
+ android/hal-msg.h android/hal-msg.c \
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/Android.mk b/android/Android.mk
index 30b2169..d5dfde7 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -16,6 +16,7 @@ LOCAL_SRC_FILES := \
main.c \
log.c \
adapter.c \
+ hal-msg.c \
../src/shared/mgmt.c \
../src/shared/util.c \
../src/sdpd-database.c \
diff --git a/android/hal-msg.c b/android/hal-msg.c
new file mode 100644
index 0000000..aa02236
--- /dev/null
+++ b/android/hal-msg.c
@@ -0,0 +1,267 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+
+#include "log.h"
+#include "hal-msg.h"
+
+static guint watch_id = 0;
+
+static uint8_t hal_register_module(struct hal_msg_hdr *msg)
+{
+ DBG("");
+
+ return 0;
+}
+
+static uint8_t hal_unregister_module(struct hal_msg_hdr *msg)
+{
+ DBG("");
+
+ return 0;
+}
+
+static uint8_t process_hal_service_chan(struct hal_msg_hdr *msg)
+{
+ uint8_t status = -1;
+
+ DBG("");
+
+ switch (msg->opcode) {
+ case HAL_MSG_OP_REGISTER_MODULE:
+ status = hal_register_module(msg);
+ break;
+ case HAL_MSG_OP_UNREGISTER_MODULE:
+ status = hal_unregister_module(msg);
+ break;
+ default:
+ error("%s: unrecognized command on service channel", __func__);
+ break;
+ }
+
+ return status;
+}
+
+static uint8_t sanity_check(struct hal_msg_hdr *msg)
+{
+ /* TODO: Add sanity check here */
+
+ return 0;
+}
+
+static uint8_t process_hal_msg(uint8_t *buf, int len)
+{
+ struct hal_msg_hdr *msg = (struct hal_msg_hdr *) buf;
+ uint8_t status;
+
+ DBG("");
+
+ status = sanity_check(msg);
+ if (status != 0)
+ return status;
+
+ if (msg->service_id == 0)
+ status = process_hal_service_chan(msg);
+
+ return status;
+}
+
+static gboolean io_session_event(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct hal_msg_hdr *hdr;
+ uint8_t buf[MAX_HAL_BUF_SIZE];
+ int sock, len;
+ uint8_t status;
+
+ if (cond & G_IO_NVAL)
+ return FALSE;
+
+ sock = g_io_channel_unix_get_fd(chan);
+
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ error("%s: error condition %d", __func__, cond);
+ /* TODO: handle */
+ return FALSE;
+ }
+
+ len = recv(sock, buf, sizeof(buf), 0);
+ if (len <= 0) {
+ error("%s: recv(): %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+
+ if (len < (int) sizeof(struct hal_msg_hdr))
+ return FALSE;
+
+ status = process_hal_msg(buf, len);
+
+ hdr = (struct hal_msg_hdr *) buf;
+
+ if (status == 0) {
+ /* Success reply */
+ len = send(sock, hdr, sizeof(*hdr), 0);
+ if (len != sizeof(hdr)) {
+ error("%s: send() rsp: %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+ } else {
+ struct hal_msg_rsp {
+ struct hal_msg_hdr hdr;
+ uint8_t status;
+ } rsp;
+
+ rsp.hdr.service_id = hdr->service_id;
+ rsp.hdr.opcode = HAL_MSG_OP_ERROR;
+ rsp.hdr.len = sizeof(rsp.status);
+ rsp.status = status;
+
+ len = send(sock, &rsp, sizeof(rsp), 0);
+ if (len != sizeof(rsp)) {
+ error("%s: send() rsp: %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ GIOChannel *io;
+ int sock, nsk;
+ struct sockaddr_un addr;
+ socklen_t len = sizeof(addr);
+
+ DBG("");
+
+ if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
+ return FALSE;
+
+ sock = g_io_channel_unix_get_fd(chan);
+
+ nsk = accept(sock, (struct sockaddr *) &addr, &len);
+ if (nsk < 0) {
+ error("%s: accept(): %s", __func__, strerror(errno));
+ return TRUE;
+ }
+
+ io = g_io_channel_unix_new(nsk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ io_session_event, data);
+
+ g_io_channel_unref(io);
+
+ return TRUE;
+}
+
+static int init_hal_socket(const char *sock_path)
+{
+ struct sockaddr_un addr;
+ int sock;
+ size_t len;
+
+ DBG("");
+
+ sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (sock < 0) {
+ error("%s: socket(): %s", __func__, strerror(errno));
+ return sock;
+ }
+
+ len = strlen(sock_path);
+ if (len > sizeof(addr.sun_path) - 1) {
+ error("%s: too big socket name", __func__);
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, sock_path);
+
+ /* let fail for android */
+ if (unlink(addr.sun_path) < 0)
+ warn("%s: unlink() %s failed: %s", __func__, sock_path,
+ strerror(errno));
+
+ if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ error("%s: bind(): %s", __func__, strerror(errno));
+ return -1;
+ }
+
+ if (listen(sock, 5) < 0) {
+ error("%s: listen(): %s", __func__, strerror(errno));
+ return -1;
+ }
+
+ chmod(sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+ return sock;
+}
+
+void start_hal_srv(const char *sock_path)
+{
+ GIOChannel *io;
+ int sock;
+
+ DBG("");
+
+ sock = init_hal_socket(sock_path);
+ if (sock < 0)
+ return;
+
+ io = g_io_channel_unix_new(sock);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ watch_id = g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ io_accept_event, &sock);
+}
+
+void stop_hal_srv(void)
+{
+ DBG("");
+
+ if (watch_id > 0)
+ g_source_remove(watch_id);
+
+ watch_id = 0;
+}
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4440fc8..f27662a 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -23,6 +23,9 @@
static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
+void start_hal_srv(const char *sock_path);
+void stop_hal_srv(void);
+
struct hal_msg_hdr {
uint8_t service_id;
uint8_t opcode;
@@ -40,6 +43,8 @@ struct hal_msg_hdr {
#define HAL_SERVICE_ID_AVRCP 8
#define HAL_SERVICE_ID_GATT 9
+#define MAX_HAL_BUF_SIZE 1024
+
/* Core Service */
#define HAL_MSG_OP_ERROR 0x00
diff --git a/android/main.c b/android/main.c
index 4a716be..99db09b 100644
--- a/android/main.c
+++ b/android/main.c
@@ -56,6 +56,14 @@
#include "adapter.h"
#include "hal-msg.h"
+#if defined(ANDROID)
+#define BT_HAL_SOCKET "/tmp/bt_hal"
+#else
+#define BT_HAL_SOCKET "/var/run/bt_hal"
+#endif
+
+#define SHUTDOWN_GRACE_SECONDS 10
+
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;
@@ -505,6 +513,7 @@ int main(int argc, char *argv[])
/* Use params: mtu = 0, flags = 0 */
start_sdp_server(0, 0);
+ start_hal_srv(BT_HAL_SOCKET);
DBG("Entering main loop");
@@ -513,6 +522,8 @@ int main(int argc, char *argv[])
g_source_remove(signal);
cleanup_hal_connection();
+
+ stop_hal_srv();
stop_sdp_server();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 2/6] android: Handle mgmt changed events
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add code handling changing adapter settings.
---
android/adapter.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 4009f4d..cae3187 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -69,6 +69,134 @@ failed:
adapter->ready(NULL, err);
}
+static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cp_set_local_name *rp = param;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of local name changed parameters");
+ return;
+ }
+
+ if (!g_strcmp0(adapter->name, (const char *) rp->name))
+ return;
+
+ DBG("name: %s", rp->name);
+
+ g_free(adapter->name);
+ adapter->name = g_strdup((const char *) rp->name);
+
+ /* TODO Update services if needed */
+}
+
+static void settings_changed_connectable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed_discoverable(struct bt_adapter *adapter)
+{
+ /* TODO */
+}
+
+static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
+{
+ uint32_t changed_mask;
+
+ changed_mask = adapter->current_settings ^ settings;
+
+ adapter->current_settings = settings;
+
+ DBG("0x%08x", changed_mask);
+
+ if (changed_mask & MGMT_SETTING_POWERED) {
+ info("Powered");
+
+ /*
+ if (adapter->current_settings & MGMT_SETTING_POWERED)
+ start_adapter()
+ else
+ stop_adapter()
+ */
+ }
+
+ if (changed_mask & MGMT_SETTING_CONNECTABLE) {
+ DBG("Connectable");
+
+ settings_changed_connectable(adapter);
+ }
+
+ if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
+ DBG("Discoverable");
+
+ settings_changed_discoverable(adapter);
+ }
+}
+
+static void new_settings_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ uint32_t settings;
+
+ if (length < sizeof(settings)) {
+ error("Wrong size of new settings parameters");
+ return;
+ }
+
+ settings = bt_get_le32(param);
+
+ DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+ settings);
+
+ if (settings == adapter->current_settings)
+ return;
+
+ settings_changed(adapter, settings);
+}
+
+static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct bt_adapter *adapter = user_data;
+ const struct mgmt_cod *rp = param;
+ uint32_t dev_class;
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of class of device changed parameters");
+ return;
+ }
+
+ dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
+
+ if (dev_class == adapter->dev_class)
+ return;
+
+ DBG("Class: 0x%06x", dev_class);
+
+ adapter->dev_class = dev_class;
+
+ /* TODO: Inform prop change: Class */
+
+ /* TODO: Gatt attrib set*/
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+ mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, 0,
+ new_settings_callback, adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+ 0, mgmt_dev_class_changed_event,
+ adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+ 0, mgmt_local_name_changed_event,
+ adapter, NULL);
+}
+
static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
{
struct mgmt_cp_load_link_keys *cp;
@@ -128,6 +256,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
adapter->current_settings = btohs(rp->current_settings);
/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(adapter);
load_link_keys(adapter, NULL);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 1/6] android: Add capabilities and set userid
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The patch set UID as standard Bluetooth user for Android (AID_BLUETOOTH).
For SDP server we need to bind to lower port, acquire this capability.
Other capabilities are required to access management interface.
---
android/main.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 62 insertions(+)
diff --git a/android/main.c b/android/main.c
index fac1003..4a716be 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,54 @@ 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;
+ gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_NET_ADMIN};
+
+ 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_SETGID) |
+ 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 (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+ warn("%s: setgroups: %s", __func__, strerror(errno));
+
+ 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 +497,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.7.10.4
^ permalink raw reply related
* [RFCv1 0/6] Set of patches implementing missing IPC functionality
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is my set of patches rebased against very recent bluez.git
(most probably there might be some issues related to style used).
These patches add some missing capability to the process, add basic IPC server
and client. Daemon listens for incoming connections from HALs so it acts
as a server, while HALs connect and act as client. Please advise what
are better names for hal-msg and hal-msg-client, should some code be moved
to adapter.c?
Andrei Emeltchenko (6):
android: Add capabilities and set userid
android: Handle mgmt changed events
android: Implement basic HAL server
android: Add HAL message helpers
android: Add helper to send fd using SCM_RIGHTS
android: Add Android HAL callback task
Makefile.android | 2 +-
android/Android.mk | 9 ++
android/adapter.c | 129 ++++++++++++++++++++++
android/bt-sock.c | 64 +++++++++++
android/hal-cb-thread.c | 86 +++++++++++++++
android/hal-msg-client.c | 123 +++++++++++++++++++++
android/hal-msg-client.h | 25 +++++
android/hal-msg.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg.h | 5 +
android/main.c | 69 ++++++++++++
configure.ac | 4 +
11 files changed, 782 insertions(+), 1 deletion(-)
create mode 100644 android/bt-sock.c
create mode 100644 android/hal-cb-thread.c
create mode 100644 android/hal-msg-client.c
create mode 100644 android/hal-msg-client.h
create mode 100644 android/hal-msg.c
--
1.7.10.4
^ permalink raw reply
* Re: [PATCH BlueZ v2] android: Add A2DP skeleton
From: Johan Hedberg @ 2013-10-21 10:44 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1382351241-17513-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Mon, Oct 21, 2013, Luiz Augusto von Dentz wrote:
> This adds initial skeleton for A2DP Android HAL.
> ---
> v2: Adds hal-av.c to Android.mk
>
> Makefile.android | 2 ++
> android/Android.mk | 1 +
> android/hal-av.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> android/hal.h | 2 ++
> 4 files changed, 99 insertions(+)
> create mode 100644 android/hal-av.c
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ v2] android: Add A2DP skeleton
From: Luiz Augusto von Dentz @ 2013-10-21 10:27 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds initial skeleton for A2DP Android HAL.
---
v2: Adds hal-av.c to Android.mk
Makefile.android | 2 ++
android/Android.mk | 1 +
android/hal-av.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal.h | 2 ++
4 files changed, 99 insertions(+)
create mode 100644 android/hal-av.c
diff --git a/Makefile.android b/Makefile.android
index 8196583..f5a5834 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -18,6 +18,7 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
android/hal-sock.c \
android/hal-hidhost.c \
android/hal-pan.c \
+ android/hal-av.c \
android/hardware/bluetooth.h \
android/hardware/bt_av.h \
android/hardware/bt_gatt.h \
@@ -61,6 +62,7 @@ EXTRA_DIST += android/hal-bluetooth.c \
android/hal-sock.c \
android/hal-hidhost.c \
android/hal-pan.c \
+ android/hal-av.c \
android/hal-log.h
EXTRA_DIST += android/client/terminal.c \
diff --git a/android/Android.mk b/android/Android.mk
index 30b2169..87445ed 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -55,6 +55,7 @@ LOCAL_SRC_FILES := \
hal-sock.c \
hal-hidhost.c \
hal-pan.c \
+ hal-av.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal-av.c b/android/hal-av.c
new file mode 100644
index 0000000..ef45066
--- /dev/null
+++ b/android/hal-av.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <stdbool.h>
+#include <stddef.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+
+#include "hal-log.h"
+#include "hal.h"
+
+const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+ return cbs != NULL;
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (!bd_addr)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (!bd_addr)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+ DBG("");
+
+ cbs = callbacks;
+
+ /* TODO: enable service */
+
+ return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+ DBG("");
+
+ if (!interface_ready())
+ return;
+
+ /* TODO: disable service */
+
+ cbs = NULL;
+}
+
+static btav_interface_t iface = {
+ .size = sizeof(iface),
+ .init = av_init,
+ .connect = av_connect,
+ .disconnect = av_disconnect,
+ .cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+ return &iface;
+}
diff --git a/android/hal.h b/android/hal.h
index a548e48..d984336 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -18,7 +18,9 @@
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
#include <hardware/bt_pan.h>
+#include <hardware/bt_av.h>
btsock_interface_t *bt_get_sock_interface(void);
bthh_interface_t *bt_get_hidhost_interface(void);
btpan_interface_t *bt_get_pan_interface(void);
+btav_interface_t *bt_get_av_interface(void);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ] android: Add A2DP skeleton
From: Luiz Augusto von Dentz @ 2013-10-21 8:39 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds initial skeleton for A2DP Android HAL.
---
Makefile.android | 1 +
android/hal-av.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal.h | 2 ++
3 files changed, 97 insertions(+)
create mode 100644 android/hal-av.c
diff --git a/Makefile.android b/Makefile.android
index 8196583..ec9e4be 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -18,6 +18,7 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
android/hal-sock.c \
android/hal-hidhost.c \
android/hal-pan.c \
+ android/hal-av.c \
android/hardware/bluetooth.h \
android/hardware/bt_av.h \
android/hardware/bt_gatt.h \
diff --git a/android/hal-av.c b/android/hal-av.c
new file mode 100644
index 0000000..ef45066
--- /dev/null
+++ b/android/hal-av.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <stdbool.h>
+#include <stddef.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+
+#include "hal-log.h"
+#include "hal.h"
+
+const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+ return cbs != NULL;
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (!bd_addr)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (!bd_addr)
+ return BT_STATUS_PARM_INVALID;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+ DBG("");
+
+ cbs = callbacks;
+
+ /* TODO: enable service */
+
+ return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+ DBG("");
+
+ if (!interface_ready())
+ return;
+
+ /* TODO: disable service */
+
+ cbs = NULL;
+}
+
+static btav_interface_t iface = {
+ .size = sizeof(iface),
+ .init = av_init,
+ .connect = av_connect,
+ .disconnect = av_disconnect,
+ .cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+ return &iface;
+}
diff --git a/android/hal.h b/android/hal.h
index a548e48..d984336 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -18,7 +18,9 @@
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
#include <hardware/bt_pan.h>
+#include <hardware/bt_av.h>
btsock_interface_t *bt_get_sock_interface(void);
bthh_interface_t *bt_get_hidhost_interface(void);
btpan_interface_t *bt_get_pan_interface(void);
+btav_interface_t *bt_get_av_interface(void);
--
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