attempt to save recently used BT devices with their link keys in the BT dongle link key storage

Dependents:   ftusbClass

Files at this revision

API Documentation at this revision

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 = &param[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