attempt to save recently used BT devices with their link keys in the BT dongle link key storage
Revision 0:6707543df242, committed 2011-06-19
- Comitter:
- networker
- Date:
- Sun Jun 19 12:51:41 2011 +0000
- Commit message:
- initial (untested)
Changed in this revision
neighbourhood.cpp | Show annotated file Show diff for this revision Revisions of this file |
neighbourhood.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 6707543df242 neighbourhood.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neighbourhood.cpp Sun Jun 19 12:51:41 2011 +0000 @@ -0,0 +1,69 @@ +#include "Utils.h" +#include "neighbourhood.h" + +neighbourhood *neighbors = 0; + +int neighbourhood::get(BD_ADDR *a, unsigned char *key) { + for (list<item>::iterator i = keys.begin(); i != keys.end(); i++) + if (memcmp(a, &(*i).a, sizeof(BD_ADDR)) == 0) { + memcpy(key, (*i).lk, lksize); +#ifdef STRICT_MRU + if (i != keys.begin()) { + keys.push_front(*i); + keys.erase(i); + dirty = true; + } +#endif + return 1; + } + return 0; +} + +int neighbourhood::add(BD_ADDR *a, const unsigned char *key, bool init) { + for (list<item>::iterator i = keys.begin(); i != keys.end(); i++) + if (memcmp(a, &(*i).a, sizeof(BD_ADDR)) == 0) { + memcpy((*i).lk, key, lksize); //assume key has changed, update key + (*i).used = true; + return 1; + } + //new key + printf("Neighbourhood: "); printf(a); printf("\n"); + if (keys.size() < cap) { + keys.push_back(item(a, key, !init));//append as long as there is space + } else { + keys.push_front(item(a, key, true));//otherwise prepend + dirty = true; + } + return 0; +} + +void neighbourhood::write() { + int n = 0; + static const int maxkey = 11; + unsigned char param[maxkey*(lksize+sizeof(BD_ADDR))+1]; + int k = keys.size()-cap; + list<item>::iterator i = keys.begin(); + while (i != keys.end()) { + if (k>0) { + if (!(*i).used) { + delete_link_key(&(*i).a);//try to make some room + keys.erase(i); + k--; + } else + i++; + } else + break; + } + //hci->delete_link_keys(); + unsigned char *p = ¶m[1]; + for (list<item>::iterator i = keys.begin(); i != keys.end() && n<maxkey; i++, n++) { + memcpy(p, &(*i).a, sizeof(BD_ADDR)); + p += sizeof(BD_ADDR); + memcpy(p, (*i).lk, lksize); + p += lksize; + } + param[0] = n; + if (n > 0) + write_link_keys(param); +} +
diff -r 000000000000 -r 6707543df242 neighbourhood.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neighbourhood.h Sun Jun 19 12:51:41 2011 +0000 @@ -0,0 +1,77 @@ +#ifndef NEIGHBOURHOOD_H +#define NEIGHBOURHOOD_H + +#include <list> +#include "hci.h" + +//#define STRICT_MRU + +/****************************************************************************************** +call 'read' as part of the startup +on HCI_READ-STORED-LINK-KEY -COMPLETED event, call 'set_cap' +on RETURN_LINK_KEYS_EVENT call 'add' for each key with init=true +on LINK_KEY_NOTIFICATION_EVENT call 'add' with init=false (default) +on LINK_KEY_REQUEST_EVENT call 'get' and send the proper reply +call 'write' as part of shutdown + +a simpler approach could be to check for a link if it exists (single read) and try to add it. +when it fails just delete all. +********************************************************************************************/ + +#define HCI_DELETE_STORED_LINK_KEY 0x0C12 +#define HCI_WRITE_STORED_LINK_KEY 0x0C11 +#define HCI_READ_STORED_LINK_KEY 0x0C0D + +void printf(const BD_ADDR* addr); + +class neighbourhood { + static const int lksize = 16; + struct item { + BD_ADDR a; + unsigned char lk[lksize]; + bool used; + item (BD_ADDR *ad, const unsigned char *k, bool d) { + memcpy(&a, ad, sizeof(BD_ADDR)); + memcpy(lk, k, lksize); + used=d; + } + }; + int cap, initsize, used; + list<item> keys; + bool dirty; + HCI *hci; + void delete_link_key(BD_ADDR *a) { + unsigned char param[sizeof(BD_ADDR)+1]; + memcpy(param, a, sizeof(BD_ADDR)); + param[sizeof(BD_ADDR)] = 0; + hci->SendCmd(HCI_DELETE_STORED_LINK_KEY, param, sizeof(param)); + } + void write_link_keys(unsigned char param[]) { + hci->SendCmd(HCI_WRITE_STORED_LINK_KEY, param, param[0]*(sizeof(BD_ADDR)+lksize)+1); + } +public: + neighbourhood(HCI *h): hci(h) { + dirty = false; + used = 0; + cap=0; + initsize=0; + } + void read() { + unsigned char param[sizeof(BD_ADDR)+1]; + memset(param, 0, sizeof(BD_ADDR)); + param[sizeof(BD_ADDR)] = 1; + hci->SendCmd(HCI_READ_STORED_LINK_KEY, param, sizeof(param)); + } + void write(); + void set_cap(int c, int s) { + cap = c; + initsize = s; + printf("Neighbourhood: capacity=%d, used=%d\n", c, s); + } + int get(BD_ADDR *a, unsigned char *key); + int add(BD_ADDR *a, const unsigned char *key, bool init=false); +}; + +extern neighbourhood *neighbors; + +#endif \ No newline at end of file