summaryrefslogtreecommitdiffstats
path: root/tools/hciconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/hciconfig.c')
-rw-r--r--tools/hciconfig.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/tools/hciconfig.c b/tools/hciconfig.c
index df9b211e..5f72ce66 100644
--- a/tools/hciconfig.c
+++ b/tools/hciconfig.c
@@ -45,6 +45,7 @@
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
+#include "textfile.h"
#include "csr.h"
static struct hci_dev_info di;
@@ -689,6 +690,101 @@ static void cmd_voice(int ctl, int hdev, char *opt)
}
}
+static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key)
+{
+ char filename[PATH_MAX + 1], addr[18], tmp[3], *str;
+ int i;
+
+ ba2str(local, addr);
+ snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);
+
+ ba2str(peer, addr);
+ str = textfile_get(filename, addr);
+ if (!str)
+ return -EIO;
+
+ memset(tmp, 0, sizeof(tmp));
+ for (i = 0; i < 16; i++) {
+ memcpy(tmp, str + (i * 2), 2);
+ key[i] = (uint8_t) strtol(tmp, NULL, 16);
+ }
+
+ free(str);
+
+ return 0;
+}
+
+static void cmd_putkey(int ctl, int hdev, char *opt)
+{
+ struct hci_dev_info di;
+ bdaddr_t bdaddr;
+ uint8_t key[16];
+ int dd;
+
+ if (!opt)
+ return;
+
+ dd = hci_open_dev(hdev);
+ if (dd < 0) {
+ fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
+ hdev, strerror(errno), errno);
+ exit(1);
+ }
+
+ if (hci_devinfo(hdev, &di) < 0) {
+ fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n",
+ hdev, strerror(errno), errno);
+ exit(1);
+ }
+
+ str2ba(opt, &bdaddr);
+ if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) {
+ fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev);
+ exit(1);
+ }
+
+ if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) {
+ fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n",
+ hdev, strerror(errno), errno);
+ exit(1);
+ }
+
+ hci_close_dev(dd);
+}
+
+static void cmd_delkey(int ctl, int hdev, char *opt)
+{
+ bdaddr_t bdaddr;
+ uint8_t all;
+ int dd;
+
+ if (!opt)
+ return;
+
+ dd = hci_open_dev(hdev);
+ if (dd < 0) {
+ fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
+ hdev, strerror(errno), errno);
+ exit(1);
+ }
+
+ if (!strcasecmp(opt, "all")) {
+ bacpy(&bdaddr, BDADDR_ANY);
+ all = 1;
+ } else {
+ str2ba(opt, &bdaddr);
+ all = 0;
+ }
+
+ if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) {
+ fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n",
+ hdev, strerror(errno), errno);
+ exit(1);
+ }
+
+ hci_close_dev(dd);
+}
+
static void cmd_commands(int ctl, int hdev, char *opt)
{
uint8_t cmds[64];
@@ -702,7 +798,7 @@ static void cmd_commands(int ctl, int hdev, char *opt)
}
if (hci_read_local_commands(dd, cmds, 1000) < 0) {
- fprintf(stderr, "Can't read support commands hci%d: %s (%d)\n",
+ fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n",
hdev, strerror(errno), errno);
exit(1);
}
@@ -1235,6 +1331,8 @@ static struct {
{ "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" },
{ "aclmtu", cmd_aclmtu, "<mtu:pkt>", "Set ACL MTU and number of packets" },
{ "scomtu", cmd_scomtu, "<mtu:pkt>", "Set SCO MTU and number of packets" },
+ { "putkey", cmd_putkey, "<bdaddr>", "Store link key on the device" },
+ { "delkey", cmd_delkey, "<bdaddr>", "Delete link key from the device" },
{ "commands", cmd_commands, 0, "Display supported commands" },
{ "features", cmd_features, 0, "Display device features" },
{ "version", cmd_version, 0, "Display version information" },