Initial work on BLE advertisement gateway for BLE-WiFI packet forwarding
Dependencies: BLE_API mbed nRF51822
main.cpp
- Committer:
- petekmet
- Date:
- 2016-03-30
- Revision:
- 0:4f2e461b0995
File content as of revision 0:4f2e461b0995:
#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); } } }