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
--- /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
--- /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);
+        } 
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /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
--- /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