Skip to content

Commit a610e0e

Browse files
dssengfabiobaltieri
authored andcommitted
bluetooth: hci: userchan: support connecting over UNIX socket
Can be used with Bluez btvirt Signed-off-by: Dmitrii Sharshakov <[email protected]>
1 parent 2b42a1d commit a610e0e

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

drivers/bluetooth/hci/userchan.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,16 @@ static struct k_thread rx_thread_data;
4646
static unsigned short bt_dev_index;
4747

4848
#define TCP_ADDR_BUFF_SIZE 16
49-
static bool hci_socket;
49+
#define UNIX_ADDR_BUFF_SIZE 4096
50+
enum hci_connection_type {
51+
HCI_USERCHAN,
52+
HCI_TCP,
53+
HCI_UNIX,
54+
};
55+
static enum hci_connection_type conn_type;
5056
static char ip_addr[TCP_ADDR_BUFF_SIZE];
5157
static unsigned int port;
58+
static char socket_path[UNIX_ADDR_BUFF_SIZE];
5259
static bool arg_found;
5360

5461
static struct net_buf *get_rx(const uint8_t *buf)
@@ -286,16 +293,19 @@ static int uc_open(const struct device *dev, bt_hci_recv_t recv)
286293
{
287294
struct uc_data *uc = dev->data;
288295

289-
if (hci_socket) {
296+
switch (conn_type) {
297+
case HCI_USERCHAN:
290298
LOG_DBG("hci%d", bt_dev_index);
291-
} else {
292-
LOG_DBG("hci %s:%d", ip_addr, port);
293-
}
294-
295-
if (hci_socket) {
296299
uc->fd = user_chan_socket_open(bt_dev_index);
297-
} else {
300+
break;
301+
case HCI_TCP:
302+
LOG_DBG("hci %s:%d", ip_addr, port);
298303
uc->fd = user_chan_net_connect(ip_addr, port);
304+
break;
305+
case HCI_UNIX:
306+
LOG_DBG("hci socket %s", socket_path);
307+
uc->fd = user_chan_unix_connect(socket_path);
308+
break;
299309
}
300310
if (uc->fd < 0) {
301311
return -nsi_errno_from_mid(-uc->fd);
@@ -325,7 +335,8 @@ static int uc_init(const struct device *dev)
325335
{
326336
if (!arg_found) {
327337
posix_print_warning("Warning: Bluetooth device missing.\n"
328-
"Specify either a local hci interface --bt-dev=hciN\n"
338+
"Specify either a local hci interface --bt-dev=hciN,\n"
339+
"a UNIX socket --bt-dev=/tmp/bt-server-bredrle\n"
329340
"or a valid hci tcp server --bt-dev=ip_address:port\n");
330341
return -ENODEV;
331342
}
@@ -350,7 +361,7 @@ static void cmd_bt_dev_found(char *argv, int offset)
350361

351362
if (arg_hci_idx >= 0 && arg_hci_idx <= USHRT_MAX) {
352363
bt_dev_index = arg_hci_idx;
353-
hci_socket = true;
364+
conn_type = HCI_USERCHAN;
354365
} else {
355366
posix_print_error_and_exit("Invalid argument value for --bt-dev. "
356367
"hci idx must be within range 0 to 65536.\n");
@@ -365,9 +376,14 @@ static void cmd_bt_dev_found(char *argv, int offset)
365376
posix_print_error_and_exit("Error: IP address for bluetooth "
366377
"hci tcp server is incorrect.\n");
367378
}
379+
380+
conn_type = HCI_TCP;
381+
} else if (strlen(&argv[offset]) > 0 && argv[offset] == '/') {
382+
strncpy(socket_path, &argv[offset], UNIX_ADDR_BUFF_SIZE - 1);
383+
conn_type = HCI_UNIX;
368384
} else {
369385
posix_print_error_and_exit("Invalid option %s for --bt-dev. "
370-
"An hci interface or hci tcp server is expected.\n",
386+
"An hci interface, absolute UNIX socket path or hci tcp server is expected.\n",
371387
&argv[offset]);
372388
}
373389
}
@@ -385,7 +401,8 @@ static void add_btuserchan_arg(void)
385401
{ false, true, false,
386402
"bt-dev", "hciX", 's',
387403
NULL, cmd_bt_dev_found,
388-
"A local HCI device to be used for Bluetooth (e.g. hci0) "
404+
"A local HCI device to be used for Bluetooth (e.g. hci0), "
405+
"UNIX socket (absolute path, like /tmp/bt-server-bredrle) "
389406
"or an HCI TCP Server (e.g. 127.0.0.1:9000)"},
390407
ARG_TABLE_ENDMARKER
391408
};

drivers/bluetooth/hci/userchan_bottom.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <poll.h>
1616
#include <unistd.h>
1717
#include <sys/socket.h>
18+
#include <sys/un.h>
1819
#include <limits.h>
1920
#include <netinet/in.h>
2021
#include <arpa/inet.h>
@@ -97,3 +98,26 @@ int user_chan_net_connect(char ip_addr[], unsigned int port)
9798

9899
return fd;
99100
}
101+
102+
int user_chan_unix_connect(char socket_path[])
103+
{
104+
int fd;
105+
struct sockaddr_un addr;
106+
107+
fd = socket(AF_UNIX, SOCK_STREAM, 0);
108+
if (fd < 0) {
109+
return -nsi_errno_to_mid(errno);
110+
}
111+
112+
addr.sun_family = AF_UNIX;
113+
strcpy(addr.sun_path, socket_path);
114+
115+
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
116+
int err = -nsi_errno_to_mid(errno);
117+
118+
close(fd);
119+
return err;
120+
}
121+
122+
return fd;
123+
}

drivers/bluetooth/hci/userchan_bottom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ bool user_chan_rx_ready(int fd);
1717
int user_chan_is_ipaddr_ok(char ip_addr[]);
1818
int user_chan_socket_open(unsigned short bt_dev_index);
1919
int user_chan_net_connect(char ip_addr[], unsigned int port);
20+
int user_chan_unix_connect(char socket_path[]);
2021

2122
#ifdef __cplusplus
2223
}

0 commit comments

Comments
 (0)