svn commit: r362005 - head/usr.sbin/bluetooth/hccontrol
Takanori Watanabe
takawata at FreeBSD.org
Wed Jun 10 05:01:01 UTC 2020
Author: takawata
Date: Wed Jun 10 05:01:00 2020
New Revision: 362005
URL: https://svnweb.freebsd.org/changeset/base/362005
Log:
Add le_read_channel_map and le_read_remote_features command
PR: 247051
Submitted by: Marc Veldman marc at bumblingdork.com
Modified:
head/usr.sbin/bluetooth/hccontrol/hccontrol.8
head/usr.sbin/bluetooth/hccontrol/hccontrol.h
head/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
head/usr.sbin/bluetooth/hccontrol/le.c
head/usr.sbin/bluetooth/hccontrol/util.c
Modified: head/usr.sbin/bluetooth/hccontrol/hccontrol.8
==============================================================================
--- head/usr.sbin/bluetooth/hccontrol/hccontrol.8 Wed Jun 10 04:54:02 2020 (r362004)
+++ head/usr.sbin/bluetooth/hccontrol/hccontrol.8 Wed Jun 10 05:01:00 2020 (r362005)
@@ -162,6 +162,8 @@ are:
.It Cm LE_Add_Device_To_White_List
.It Cm LE_Remove_Device_From_White_List
.It Cm LE_Connect
+.It Cm LE_Read_Channel_Map
+.It Cm LE_Read_Remote_Features
.El
.Pp
The currently supported node commands in
Modified: head/usr.sbin/bluetooth/hccontrol/hccontrol.h
==============================================================================
--- head/usr.sbin/bluetooth/hccontrol/hccontrol.h Wed Jun 10 04:54:02 2020 (r362004)
+++ head/usr.sbin/bluetooth/hccontrol/hccontrol.h Wed Jun 10 05:01:00 2020 (r362005)
@@ -82,6 +82,7 @@ char const * hci_bdaddr2str (bdaddr_t const *);
char const * hci_addrtype2str (int type);
char const * hci_role2str (int role);
char const * hci_mc_accuracy2str (int accuracy);
+char const * hci_le_chanmap2str (uint8_t *, char *, int);
void dump_adv_data(int len, uint8_t* advdata);
void print_adv_data(int len, uint8_t* advdata);
Modified: head/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
==============================================================================
--- head/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c Wed Jun 10 04:54:02 2020 (r362004)
+++ head/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c Wed Jun 10 05:01:00 2020 (r362005)
@@ -1526,14 +1526,14 @@ hci_write_le_host_support(int s, int argc, char **argv
switch (argc) {
case 2:
if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
- printf("ARGC2: %d\n", n);
+ printf("-ARGC2: %d\n", n);
return (USAGE);
}
cp.simultaneous_le_host = (n &1);
case 1:
if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
- printf("ARGC1: %d\n", n);
+ printf("+ARGC1: %d\n", n);
return (USAGE);
}
Modified: head/usr.sbin/bluetooth/hccontrol/le.c
==============================================================================
--- head/usr.sbin/bluetooth/hccontrol/le.c Wed Jun 10 04:54:02 2020 (r362004)
+++ head/usr.sbin/bluetooth/hccontrol/le.c Wed Jun 10 05:01:00 2020 (r362005)
@@ -69,6 +69,8 @@ static int le_add_device_to_white_list(int s, int argc
static int le_remove_device_from_white_list(int s, int argc, char *argv[]);
static int le_connect(int s, int argc, char *argv[]);
static void handle_le_connection_event(ng_hci_event_pkt_t* e, bool verbose);
+static int le_read_channel_map(int s, int argc, char *argv[]);
+static void handle_le_remote_features_event(ng_hci_event_pkt_t* e);
static int
le_set_scan_param(int s, int argc, char *argv[])
@@ -1086,6 +1088,131 @@ static void handle_le_connection_event(ng_hci_event_pk
return;
}
+static int
+le_read_channel_map(int s, int argc, char *argv[])
+{
+ ng_hci_le_read_channel_map_cp cp;
+ ng_hci_le_read_channel_map_rp rp;
+ int n;
+ char buffer[2048];
+
+ /* parse command parameters */
+ switch (argc) {
+ case 1:
+ /* connection handle */
+ if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
+ return (USAGE);
+
+ cp.connection_handle = (uint16_t) (n & 0x0fff);
+ cp.connection_handle = htole16(cp.connection_handle);
+ break;
+
+ default:
+ return (USAGE);
+ }
+
+ n = sizeof(rp);
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_READ_CHANNEL_MAP),
+ (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout,
+ "Read channel map failed. Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ fprintf(stdout, "Connection handle: %d\n",
+ le16toh(rp.connection_handle));
+ fprintf(stdout, "Used channels:\n");
+ fprintf(stdout, "\n%s\n", hci_le_chanmap2str(rp.le_channel_map,
+ buffer, sizeof(buffer)));
+
+ return (OK);
+} /* le_read_channel_map */
+
+static int
+le_read_remote_features(int s, int argc, char *argv[])
+{
+ ng_hci_le_read_remote_used_features_cp cp;
+ ng_hci_status_rp rp;
+ int n, bufsize;
+ char b[512];
+
+ ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b;
+
+ /* parse command parameters */
+ switch (argc) {
+ case 1:
+ /* connection handle */
+ if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
+ return (USAGE);
+
+ cp.connection_handle = (uint16_t) (n & 0x0fff);
+ cp.connection_handle = htole16(cp.connection_handle);
+ break;
+
+ default:
+ return (USAGE);
+ }
+
+ n = sizeof(rp);
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
+ NG_HCI_OCF_LE_READ_REMOTE_USED_FEATURES),
+ (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout,
+ "Read remote features failed. Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ /* wait for connection events */
+ bufsize = sizeof(b);
+ if (hci_recv(s, b, &bufsize) == ERROR) {
+ return (ERROR);
+ }
+
+ if (bufsize < sizeof(*e)) {
+ errno = EIO;
+ return (ERROR);
+ }
+ if (e->event == NG_HCI_EVENT_LE) {
+ handle_le_remote_features_event(e);
+ }
+
+ return (OK);
+} /* le_read_remote_features */
+
+static void handle_le_remote_features_event(ng_hci_event_pkt_t* e)
+{
+ ng_hci_le_ep *ev_pkt;
+ ng_hci_le_read_remote_features_ep *feat_event;
+ char buffer[2048];
+
+ ev_pkt = (ng_hci_le_ep *)(e + 1);
+
+ if (ev_pkt->subevent_code == NG_HCI_LEEV_READ_REMOTE_FEATURES_COMPL) {
+ feat_event =(ng_hci_le_read_remote_features_ep *)(ev_pkt + 1);
+ fprintf(stdout, "Handle: %d\n",
+ le16toh(feat_event->connection_handle));
+ fprintf(stdout,
+ "Status: %s\n",
+ hci_status2str(feat_event->status));
+ fprintf(stdout, "Features:\n%s\n",
+ hci_le_features2str(feat_event->features,
+ buffer, sizeof(buffer)));
+ }
+
+ return;
+} /* handle_le_remote_features_event */
+
+
+
struct hci_command le_commands[] = {
{
"le_enable",
@@ -1195,5 +1322,18 @@ struct hci_command le_commands[] = {
"le_connect -a address [-t public|random] [-v]\n"
"Connect to an LE device",
&le_connect
+ },
+ {
+ "le_read_channel_map",
+ "le_read_channel_map <connection_handle>\n"
+ "Read the channel map for a connection",
+ &le_read_channel_map
+ },
+ {
+ "le_read_remote_features",
+ "le_read_remote_features <connection_handle>\n"
+ "Read supported features for the device\n"
+ "identified by the connection handle",
+ &le_read_remote_features
},
};
Modified: head/usr.sbin/bluetooth/hccontrol/util.c
==============================================================================
--- head/usr.sbin/bluetooth/hccontrol/util.c Wed Jun 10 04:54:02 2020 (r362004)
+++ head/usr.sbin/bluetooth/hccontrol/util.c Wed Jun 10 05:01:00 2020 (r362005)
@@ -3322,3 +3322,46 @@ hci_mc_accuracy2str(int accuracy)
return (accuracy >= SIZE(acc)? "Unknown accuracy" : acc[accuracy]);
} /* hci_mc_accuracy2str */
+
+char const *
+hci_le_chanmap2str(uint8_t *map, char *buffer, int size)
+{
+ char chantxt[4];
+ if (buffer != NULL && size > 0) {
+ int n, i, len0, len1;
+
+ memset(buffer, 0, size);
+ len1 = 0;
+ size--;
+
+ for (n = 0; n < 5; n++) {
+ fprintf(stdout, "%02x ", map[n]);
+ for (i = 0; i < 8; i++) {
+ len0 = strlen(buffer);
+ if (len0 >= size)
+ goto done;
+
+ if (map[n] & (1 << i)) {
+ if (len1 + 3 > 60) {
+ len1 = 0;
+ buffer[len0 - 1] = '\n';
+ }
+
+ len1 += 3;
+ snprintf(
+ chantxt,
+ sizeof(chantxt),
+ "%02d ",
+ (n * 8 + i));
+ strncat(
+ buffer,
+ chantxt,
+ size - len0);
+ }
+ }
+ }
+ fprintf(stdout, "\n");
+ }
+done:
+ return (buffer);
+}
More information about the svn-src-all
mailing list