diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2008-11-24 23:34:43 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2008-11-24 23:34:43 +0000 |
commit | b76ea0f34f6d26d8711d402b22cc4aa21d8bac6c (patch) | |
tree | b8b93e3d3e731a3dd6da39f8b778856970f8b23f /usr.sbin/btd/db.c | |
parent | b6679679f13b731ba42b47d62e0c1c9c441021fe (diff) |
Bluetooth daemon and contrl utility, one for all, work in progress
Diffstat (limited to 'usr.sbin/btd/db.c')
-rw-r--r-- | usr.sbin/btd/db.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/usr.sbin/btd/db.c b/usr.sbin/btd/db.c new file mode 100644 index 00000000000..e147b072b8d --- /dev/null +++ b/usr.sbin/btd/db.c @@ -0,0 +1,203 @@ +#include <sys/stat.h> + +#include <netbt/hci.h> + +#include <assert.h> +#include <bluetooth.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> + +#include "btd.h" + +typedef enum { + DB_DEVINFO, + DB_LINK_KEY +} db_type; + +typedef struct { + bdaddr_t addr; + db_type type; +} db_key; + +int db_put(struct btd_db *, db_key *, const void *, size_t); +int db_get_raw(struct btd_db *, db_key *, void **, size_t *); +int db_get_exact(struct btd_db *, db_key *, void *, size_t); + +void +db_open(const char *file, struct btd_db *db) +{ + assert(db->dbh == NULL); + + db->dbh = dbopen(file, O_CREAT | O_EXLOCK | O_RDWR, + S_IRUSR | S_IWUSR, DB_HASH, NULL); + if (db->dbh == NULL) + fatal(file); +} + +int +db_put(struct btd_db *db, db_key *key, const void *data, size_t size) +{ + DB *dbh = db->dbh; + DBT dbk, dbd; + + memset(&dbk, 0, sizeof(dbk)); + dbk.size = sizeof(db_key); + dbk.data = (void *)key; + memset(&dbd, 0, sizeof(dbd)); + dbd.size = size; + dbd.data = (void*)data; + + if (dbh->put(dbh, &dbk, &dbd, 0)) { + log_warn("db_put"); + return -1; + } + + if (dbh->sync(dbh, 0)) { + log_warn("db_sync"); + return -1; + } + + return 0; +} + +int +db_get_raw(struct btd_db *db, db_key *key, void **data, size_t *size) +{ + DB *dbh = db->dbh; + DBT dbk, dbd; + int res; + + memset(&dbk, 0, sizeof(dbk)); + dbk.size = sizeof(db_key); + dbk.data = (void *)key; + memset(&dbd, 0, sizeof(dbd)); + + if ((res = dbh->get(dbh, &dbk, &dbd, 0)) != 0) { + if (res == -1) + log_warn("db_get"); + return res; + } + + *data = dbd.data; + *size = dbd.size; + return 0; +} + +int +db_get_exact(struct btd_db *db, db_key *key, void *data, size_t size) +{ + void *d; + size_t dlen; + int res; + + if ((res = db_get_raw(db, key, &d, &dlen)) == 0) { + if (dlen != size) { + log_warnx("data size mismatch for key type %#x" + " (%u != %u)", key->type, dlen, size); + return -1; + } + memcpy(data, d, size); + } + + return res; +} + +int +db_put_link_key(struct btd_db *db, const bdaddr_t *addr, + const uint8_t *link_key) +{ + db_key key; + + memset(&key, 0, sizeof(key)); + bdaddr_copy(&key.addr, addr); + key.type = DB_LINK_KEY; + + return db_put(db, &key, link_key, HCI_KEY_SIZE); +} + +int +db_get_link_key(struct btd_db *db, const bdaddr_t *addr, uint8_t *link_key) +{ + db_key key; + + memset(&key, 0, sizeof(key)); + bdaddr_copy(&key.addr, addr); + key.type = DB_LINK_KEY; + + return db_get_exact(db, &key, link_key, HCI_KEY_SIZE); +} + +int +db_put_devinfo(struct btd_db *db, const bdaddr_t *addr, + const struct bt_devinfo *info) +{ + db_key key; + void *data; + size_t size; + int res; + + memset(&key, 0, sizeof(key)); + bdaddr_copy(&key.addr, addr); + key.type = DB_DEVINFO; + + if (devinfo_store(info, &data, &size)) + return -1; + + res = db_put(db, &key, data, size); + free(data); + return res; +} + +int +db_get_devinfo(struct btd_db *db, const bdaddr_t *addr, + struct bt_devinfo *info) +{ + db_key key; + void *data; + size_t size; + int res; + + memset(&key, 0, sizeof(key)); + bdaddr_copy(&key.addr, addr); + key.type = DB_DEVINFO; + + if ((res = db_get_raw(db, &key, &data, &size)) == 0 && + devinfo_load(info, data, size)) + res = -1; + + return res; +} + +void +db_dump(struct btd_db *db) +{ + struct bt_devinfo info; + DB *dbh = db->dbh; + DBT dbk, dbd; + + if (dbh->seq(dbh, &dbk, &dbd, R_FIRST) != 0) + return; + do { + db_key *key = dbk.data; + + if (dbk.size != sizeof(db_key)) + fatalx("invalid db key"); + + switch (key->type) { + case DB_LINK_KEY: + log_info("%s link_key", bt_ntoa(&key->addr, NULL)); + break; + case DB_DEVINFO: + log_info("%s devinfo", bt_ntoa(&key->addr, NULL)); + if (db_get_devinfo(db, &key->addr, &info) == 0) { + devinfo_dump(&info); + devinfo_unload(&info); + } + break; + default: + fatalx("invalid db key type"); + } + } + while (dbh->seq(dbh, &dbk, &dbd, R_NEXT) == 0); +} |