Initial work on BLE advertisement gateway for BLE-WiFI packet forwarding

Dependencies:   BLE_API mbed nRF51822

Files at this revision

API Documentation at this revision

Comitter:
petekmet
Date:
Wed Mar 30 07:17:33 2016 +0000
Commit message:
initial commit

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 4f2e461b0995 BLE_API.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Wed Mar 30 07:17:33 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#ff83f0020480
diff -r 000000000000 -r 4f2e461b0995 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Mar 30 07:17:33 2016 +0000
@@ -0,0 +1,204 @@
+#include "mbed.h"
+#include "BLE.h"
+#include "Gap.h"
+#include "stdio.h"
+
+typedef struct{
+    BLEProtocol::AddressBytes_t address;
+    uint8_t frameId;
+    uint16_t age;
+} DeviceEntry;
+
+typedef struct{
+    BLEProtocol::AddressBytes_t address;
+    uint8_t data[31];
+    uint8_t dataLen;
+} TransmitData;
+
+BLE  ble;
+Serial pc(USBTX, USBRX);
+DeviceEntry *deviceArray;
+TransmitData txData;
+bool txEnabled = false;
+uint8_t devicesCount = 0;
+char tmp[18];
+
+void dumpBytes(const uint8_t *data, uint8_t len){
+    for(uint8_t i=0;i<len; i++){
+        pc.printf("%02X ", data[i]);
+    }
+}
+
+bool isAddressEqual(const uint8_t *addr1, const uint8_t *addr2){
+    uint8_t n;
+    for(n=0;n<6;n++){
+        if(addr1[n] != addr2[n]){
+            return false;
+        }
+    }
+    return true;
+}
+
+void getAddressString(char* addressString, const uint8_t *address){
+    sprintf(addressString, "%02X%02X%02X%02X%02X%02X", address[5], address[4], address[3], address[2], address[1], address[0]);
+}
+
+void sendToWifi(BLEProtocol::AddressBytes_t *address, const uint8_t *data, uint8_t dataLen){
+    if(txEnabled==false){
+        txEnabled = true;
+        getAddressString(tmp, (uint8_t*)address);
+        memcpy(txData.address, address, sizeof(BLEProtocol::AddressBytes_t));
+        memcpy(txData.data, data, dataLen);
+        txData.dataLen = dataLen;
+    }
+}
+
+void sendToWifi(){
+    if(txData.data[3] == 0xFB){
+        //beescale
+    }else
+    if(txData.data[3] == 0xFA){
+        //weatherbeacon
+        float temp = (float)(txData.data[11]|txData.data[12]<<8)/100;
+        int16_t pressure = txData.data[14]|txData.data[15]<<8;
+        uint16_t battery = txData.data[16]|txData.data[17]<<8;
+        
+        pc.printf("\r\ntemperature is %.1f C\r\n", temp);
+        pc.printf("humidity %d%%\r\n", txData.data[13]);
+        if(pressure>0){
+            pc.printf("pressure %d hPa\r\n", pressure);
+        }
+        pc.printf("battery %dmV\r\n", battery);
+    }else
+    if(txData.data[3] == 0xFC){
+        //weatherbeacon
+        float temp = (float)(txData.data[11]|txData.data[12]<<8)/10;
+        int16_t pressure = txData.data[14]|txData.data[15]<<8;
+        uint16_t battery = txData.data[16]|txData.data[17]<<8;
+        /*
+        pc.printf("\r\ntemperature is %.1f C\r\n", temp);
+        pc.printf("humidity %d%%\r\n", txData.data[13]);
+        if(pressure>0){
+            pc.printf("pressure %d hPa\r\n", pressure);
+        }
+        */
+        pc.printf("START\r\n");
+        pc.printf("api.thingspeak.com\r\n");
+        pc.printf("/update.json\r\n");
+        pc.printf("key=WL5U725HQ30KWELM&field1=%.1f&field2=%d&field3=%d&field4=%d\r\n", temp, txData.data[13], pressure, battery);
+        pc.printf("END\r\n");
+        //START
+        //HOST
+        //QUERY
+        //POST DATA
+        //END
+    }
+    
+    getAddressString(tmp, (uint8_t*)txData.address);
+    dumpBytes(txData.data, txData.dataLen);
+    pc.printf("\r\nuploading %d bytes, frame type %02X from %s to the cloud...", txData.dataLen, txData.data[3], tmp);
+    wait(2);
+    pc.printf(" OK\r\n");
+} 
+
+void updateDevice(const uint8_t *address, uint8_t frameId, const uint8_t *data, uint8_t dataLen){
+    
+        //search if there are some devices, find if this already exists
+        DeviceEntry *_devArr = deviceArray;
+        for(uint8_t n=0;n<devicesCount;n++){
+            if(isAddressEqual(_devArr->address, address)){
+                if(_devArr->frameId == frameId){
+                    //check if frameId is equal
+                    //pc.printf("frameId is equal, skipping\r\n");
+                }else{
+                    _devArr->frameId = frameId;
+                    getAddressString(tmp, address);
+                    pc.printf("\r\nnew frameId %d on %s\r\n", frameId, tmp);
+                    sendToWifi((BLEProtocol::AddressBytes_t*)address, data, dataLen);
+                }
+                return;
+            } 
+            _devArr+=sizeof(DeviceEntry);
+        }
+        
+        //create new device (existing device not found or no devices yet)
+        DeviceEntry *_newDevArr = (DeviceEntry *)malloc(sizeof(DeviceEntry)*(devicesCount+1));
+        if(_newDevArr!=NULL){
+            if(deviceArray!=NULL){ //resizing
+                pc.printf("\r\nextending devices array, now size %d, old %d, new %d\r\n", devicesCount+1, deviceArray, _newDevArr);
+                memcpy(_newDevArr, deviceArray, sizeof(DeviceEntry)*devicesCount);
+                free(deviceArray); //release old array
+                
+            }else{
+                //initializing
+                pc.printf("\r\ninitializing dev array\r\n");
+            }
+            
+            devicesCount++;
+            deviceArray = _newDevArr; //remember new resized array
+            
+            //put to array
+            DeviceEntry *newDevEntry = deviceArray + ((devicesCount-1)*sizeof(DeviceEntry)); 
+            memcpy(newDevEntry->address, address, sizeof(BLEProtocol::AddressBytes_t));
+            newDevEntry->frameId = frameId;
+            getAddressString(tmp, address);
+            pc.printf("address %s and frameId %d registered\r\n", tmp, frameId);
+            sendToWifi((BLEProtocol::AddressBytes_t*)address, data, dataLen);
+            
+        }else{
+            pc.printf("\r\nmalloc failed\r\n");
+        }
+}
+
+void onScanResult(const Gap::AdvertisementCallbackParams_t *params){
+    uint8_t n;
+    const uint8_t *data = params->advertisingData;
+    for(n=0;n<params->advertisingDataLen-1;n++){
+        const uint8_t len = data[n];
+        const uint8_t tpe = data[n+1];
+        //printf("Type %02X, l=%d\r\n", tpe, len);
+        if(tpe==0xFF){//search for manufacturer-data
+            if(data[n+2] == 0xFF && data[n+3] == 0xFF && (data[n+4] == 0xFA || data[n+4] == 0xFC || data[n+4] == 0xFC)){
+                updateDevice(params->peerAddr, data[n+5], data+n+1, len);
+            }
+        }
+        n+=len;
+    }
+}
+
+int main(void)
+{
+    pc.baud(9600);
+    ble.init();
+    while (ble.hasInitialized()  == false) { /* spin loop */ }
+    ble.gap().setScanParams(1000 /* scan interval */, 1000 /* scan window */);
+    ble.gap().startScan(onScanResult);
+    
+    pc.printf("Scan Start \r\n");
+    while(1){
+        ble.waitForEvent();
+        
+        if(txEnabled){
+            ble.gap().stopScan();
+            sendToWifi();
+            txEnabled = false;
+            ble.gap().startScan(onScanResult);
+        } 
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 4f2e461b0995 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Mar 30 07:17:33 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/87f2f5183dfb
\ No newline at end of file
diff -r 000000000000 -r 4f2e461b0995 nRF51822.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Wed Mar 30 07:17:33 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#1751e2e2637a