BLE Application to open a Garage door

Dependencies:   BLE_API Crypto RNG mbed nRF51822

Fork of BLE_LED by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //#define DEBUG
00002 
00003 #ifndef DEBUG
00004     #define DEVICE_SERIAL   0   //disable SERIAL so me can use P0_8 (shared with serial)
00005     #define DBG(...)
00006 #else
00007     #define DBG printf
00008 #endif
00009 
00010 #include "mbed.h"
00011 #include "BLE.h"
00012 #include "GaragemService.h"
00013 #include "SecurityService.h"
00014 #include "ble/services/iBeacon.h"
00015 #include "DeviceInformationService.h"
00016 
00017 // HOW-TO TEST:
00018 //create a string to write to the characteristic 2000:2001
00019 //openssl enc -aes-128-cbc -K 9734062BA852A049CF5D40593B769014 -iv A2685636521871D02306E2EB8F7027B3 -out /dev/stdout -in inputfile
00020 // TTTTIIIISSSSSSSS
00021 // T -> 4 bytes Timestamp uint32_t
00022 // I -> 4 bytes ID (chars)
00023 // S -> 8 bytes SHARED_SECRET   (chars)
00024 
00025 // Generating K and iv:
00026 //openssl enc -aes-128-cbc -pass pass:********** -nosalt -P
00027 
00028 #define SHARED_KEY  "figueiredo"
00029 #define DEVICE_NAME    "Garagem"
00030 
00031 BLE        ble;
00032 DigitalOut actuatedLED(P0_19);
00033 Timeout offRelay;
00034 bool boot;
00035 #ifndef DEBUG
00036 DigitalOut relay(P0_8);
00037 #endif
00038 
00039 static const uint16_t uuid16_list[] = {GaragemService::GARAGEM_SERVICE_UUID, SecurityService::SECURITY_SERVICE_UUID};
00040 
00041 GaragemService *garagemServicePtr;
00042 SecurityService *securityServicePtr;
00043 
00044 void switchOffRelay()
00045 {
00046     actuatedLED = !actuatedLED;
00047     DBG("JA CHEGA...\r\n");
00048     #ifndef DEBUG
00049     relay = 0;
00050     #endif
00051 }
00052     
00053 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00054 {   
00055     ble.startAdvertising(); 
00056 }
00057 
00058 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
00059     DBG("onDataWrittenCallback: handle = %d      len = %d\r\n", params->handle, params->len);
00060     garagemServicePtr->nextLastOpen(params->data, params->len);
00061 
00062     if ((params->handle == garagemServicePtr->getChallengeHandle()) && (params->len ==16)) {
00063         DBG("We have Challenge: data = %s\r\n", (char *) (params->data));
00064         
00065         uint8_t msg[16];
00066         securityServicePtr->decode(msg, (uint8_t *) params->data, 16);
00067         
00068         if(garagemServicePtr->checkMessage(msg) == GARAGEM_OK) {  
00069             DBG("ABRE-TE SESAMO!\r\n");
00070 
00071             #ifndef DEBUG
00072             relay = 1;
00073             #endif
00074             actuatedLED = !actuatedLED;
00075             //please cleanup afterwards
00076             offRelay.attach(&switchOffRelay, 1.0);
00077             
00078         } else {
00079             DBG("NO SUCH LUCK...\r\n");
00080         }
00081     } if(boot && (params->handle == securityServicePtr->getKeyHandle()) && (params->len > 0)) {
00082         securityServicePtr->setKey((char *) params->data);    
00083     }
00084     boot = false;
00085 }
00086 
00087 int main(void)
00088 {
00089     DBG("Garagem v0\r\n");
00090 
00091     boot = true;
00092     actuatedLED  = true;
00093     #ifndef DEBUG
00094     relay = 0;
00095     #endif
00096 
00097     ble.init();
00098     
00099     // Note that the Garagem app that is in the Google Play store has the prefix for the BLE Nano hardcoded as F2:9B:4B, but newer Nanos do not have this prefix
00100     // The following line changes the address on your Nano to ensure it will work with the app as is.
00101     const uint8_t address1[] = {0x01,0x02,0x03,0x4B,0x9B,0xF2}; ble.setAddress(Gap::ADDR_TYPE_PUBLIC, address1);
00102 
00103     ble.onDisconnection(disconnectionCallback);
00104     ble.gattServer().onDataWritten(onDataWrittenCallback);
00105 
00106      /**
00107      * The Beacon payload has the following composition:
00108      * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
00109      * Major/Minor  = 0x1122 / 0x3344
00110      * Tx Power     = 0xC8 = 200, 2's compliment is 256-200 = (-56dB)
00111      *
00112      * Note: please remember to calibrate your beacons TX Power for more accurate results.
00113      */
00114     const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,
00115                             0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61};
00116     uint16_t majorNumber = 3800;
00117     uint16_t minorNumber = 1423;
00118     uint16_t txPower     = 0xBE;
00119     iBeacon ibeacon(ble, uuid, majorNumber, minorNumber, txPower);
00120 
00121     DeviceInformationService deviceInfo(ble, "diogogomes.com", DEVICE_NAME, "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00122     
00123     GaragemService garagemService(ble);
00124     garagemServicePtr = &garagemService;
00125     
00126     SecurityService securityService(ble);
00127     securityService.init(SHARED_KEY);
00128     securityServicePtr = &securityService;
00129 
00130     /* setup advertising */
00131     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00132     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00133     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00134     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00135     
00136     
00137     ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
00138     ble.gap().startAdvertising();
00139 
00140     while (true) {
00141         ble.waitForEvent();
00142     }
00143 }