BLE Application to open a Garage door

Dependencies:   BLE_API Crypto RNG mbed nRF51822

Fork of BLE_LED by Bluetooth Low Energy

Revision:
9:329af8cdc923
Parent:
7:c9271599ec5f
Child:
10:80850cd6c29e
--- a/main.cpp	Thu Jul 02 08:44:06 2015 +0000
+++ b/main.cpp	Tue Aug 25 22:18:21 2015 +0000
@@ -13,30 +13,57 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG
+
+#ifndef DEBUG
+    #define DEVICE_SERIAL   0   //disable SERIAL so me can use P0_8 (shared with serial)
+    #define DBG(...)
+#else
+    #define DBG printf
+#endif
 
 #include "mbed.h"
 #include "BLE.h"
-#include "LEDService.h"
+#include "GaragemService.h"
+#include "ble/services/iBeacon.h"
+#include "DeviceInformationService.h"
+
+#include "Crypto.h"
+
+//how-to test:
+//create a string to write to the characteristic
+//openssl enc -aes-128-cbc -K 9734062BA852A049CF5D40593B769014 -iv A2685636521871D02306E2EB8F7027B3 -out /dev/stdout
+#define SHARED_KEY  "figueiredo"
+#define DEVICE_NAME    "Garagem"
+//openssl enc -aes-128-cbc -pass pass:********** -nosalt -P
+uint8_t myKey[16];
+uint8_t iv[16] = { 0xA2, 0x68, 0x56, 0x36, 0x52, 0x18, 0x71, 0xD0, 0x23, 0x06, 0xE2, 0xEB, 0x8F, 0x70, 0x27, 0xB3 };
 
 BLE        ble;
-DigitalOut alivenessLED(LED1);
-DigitalOut actuatedLED(LED2);
+DigitalOut actuatedLED(P0_19);
+Timeout offRelay;
+
+#ifndef DEBUG
+DigitalOut relay(P0_8);
+#endif
+
+static const uint16_t uuid16_list[] = {GaragemService::GARAGEM_SERVICE_UUID};
 
-const static char     DEVICE_NAME[] = "LED";
-static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
+GaragemService *garagemServicePtr;
 
-LEDService *ledServicePtr;
-
+void switchOffRelay()
+{
+    actuatedLED = !actuatedLED;
+    DBG("JA CHEGA...\r\n");
+    #ifndef DEBUG
+    relay = 0;
+    #endif
+}
+    
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
-{
-    ble.gap().startAdvertising();
+{   
+    ble.startAdvertising(); 
 }
-
-void periodicCallback(void)
-{
-    //alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
-}
-
 /**
  * This callback allows the LEDService to receive updates to the ledState Characteristic.
  *
@@ -44,32 +71,74 @@
  *     Information about the characterisitc being updated.
  */
 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
-    if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
-        actuatedLED = *(params->data);
+    DBG("onDataWrittenCallback: handle = %d      len = %d\r\n", params->handle, params->len);
+    
+    if ((params->handle == garagemServicePtr->getChallengeHandle()) && (params->len ==16)) {
+        DBG("onDataWrittenCallback: data = %s\r\n", (char *) (params->data));
+        actuatedLED = !actuatedLED;
+        
+        AES myAES(AES_128, myKey, iv);
+        uint8_t msg[16];
+        myAES.decrypt(msg,(uint8_t *) (params->data),16);
+        
+        if(garagemServicePtr->checkMessage(msg) == GARAGEM_OK) {  
+            #ifndef DEBUG
+            relay = 1;
+            #endif
+            DBG("ABRE-TE SESAMO!\r\n");
+
+            //please cleanup afterwards
+            offRelay.attach(&switchOffRelay, 1.0);
+            
+        } else {
+            DBG("NO SUCH LUCK...\r\n");
+        }
     }
 }
 
 int main(void)
 {
-    alivenessLED = 0;
-    actuatedLED  = 0;
+    DBG("Garagem v0\r\n");
 
-    Ticker ticker;
-    ticker.attach(periodicCallback, 1);
+    //Compute myKey from SHARED_KEY
+    MD5::computeHash(myKey, (uint8_t*) SHARED_KEY, strlen(SHARED_KEY));
+    
+    actuatedLED  = true;
+    #ifndef DEBUG
+    relay = 0;
+    #endif
 
     ble.init();
-    ble.gap().onDisconnection(disconnectionCallback);
+    ble.onDisconnection(disconnectionCallback);
     ble.gattServer().onDataWritten(onDataWrittenCallback);
 
-    bool initialValueForLEDCharacteristic = false;
-    LEDService ledService(ble, initialValueForLEDCharacteristic);
-    ledServicePtr = &ledService;
+     /**
+     * The Beacon payload has the following composition:
+     * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
+     * Major/Minor  = 0x1122 / 0x3344
+     * Tx Power     = 0xC8 = 200, 2's compliment is 256-200 = (-56dB)
+     *
+     * Note: please remember to calibrate your beacons TX Power for more accurate results.
+     */
+    const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,
+                            0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61};
+    uint16_t majorNumber = 3800;
+    uint16_t minorNumber = 1423;
+    uint16_t txPower     = 0xBE;
+    iBeacon ibeacon(ble, uuid, majorNumber, minorNumber, txPower);
+    
+    GaragemService garagemService(ble);
+    garagemServicePtr = &garagemService;
+
+    DeviceInformationService deviceInfo(ble, "diogogomes.com", DEVICE_NAME, "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
 
     /* setup advertising */
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    
+    
     ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
     ble.gap().startAdvertising();