From owner-svn-src-head@freebsd.org Wed Jun 10 05:01:01 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C4D26328830; Wed, 10 Jun 2020 05:01:01 +0000 (UTC) (envelope-from takawata@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49hZZP4vgGz4gC8; Wed, 10 Jun 2020 05:01:01 +0000 (UTC) (envelope-from takawata@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A3A7D2155C; Wed, 10 Jun 2020 05:01:01 +0000 (UTC) (envelope-from takawata@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05A511fE064725; Wed, 10 Jun 2020 05:01:01 GMT (envelope-from takawata@FreeBSD.org) Received: (from takawata@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05A510HH064116; Wed, 10 Jun 2020 05:01:00 GMT (envelope-from takawata@FreeBSD.org) Message-Id: <202006100501.05A510HH064116@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: takawata set sender to takawata@FreeBSD.org using -f From: Takanori Watanabe Date: Wed, 10 Jun 2020 05:01:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362005 - head/usr.sbin/bluetooth/hccontrol X-SVN-Group: head X-SVN-Commit-Author: takawata X-SVN-Commit-Paths: head/usr.sbin/bluetooth/hccontrol X-SVN-Commit-Revision: 362005 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2020 05:01:01 -0000 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 \n" + "Read the channel map for a connection", + &le_read_channel_map + }, + { + "le_read_remote_features", + "le_read_remote_features \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); +}