BLE Application to open a Garage door

Dependencies:   BLE_API Crypto RNG mbed nRF51822

Fork of BLE_LED by Bluetooth Low Energy

main.cpp

Committer:
dgomes
Date:
2015-08-25
Revision:
10:80850cd6c29e
Parent:
9:329af8cdc923
Child:
11:3de9b542eeac

File content as of revision 10:80850cd6c29e:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * 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 "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 -in inputfile
// TTTTIIIISSSSSSSS
// T -> 4 bytes Timestamp uint32_t
// I -> 4 bytes ID (chars)
// S -> 8 bytes SHARED_SECRET   (chars)

#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 actuatedLED(P0_19);
Timeout offRelay;

#ifndef DEBUG
DigitalOut relay(P0_8);
#endif

static const uint16_t uuid16_list[] = {GaragemService::GARAGEM_SERVICE_UUID};

GaragemService *garagemServicePtr;

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.startAdvertising(); 
}
/**
 * This callback allows the LEDService to receive updates to the ledState Characteristic.
 *
 * @param[in] params
 *     Information about the characterisitc being updated.
 */
void onDataWrittenCallback(const GattWriteCallbackParams *params) {
    DBG("onDataWrittenCallback: handle = %d      len = %d\r\n", params->handle, params->len);
    garagemServicePtr->nextLastOpen(params->data, params->len);

    if ((params->handle == garagemServicePtr->getChallengeHandle()) && (params->len ==16)) {
        DBG("We have Challenge: data = %s\r\n", (char *) (params->data));
        
        AES myAES(AES_128, myKey, iv);
        uint8_t msg[16];
        myAES.decrypt(msg,(uint8_t *) (params->data),16);
        
        if(garagemServicePtr->checkMessage(msg) == GARAGEM_OK) {  
            DBG("ABRE-TE SESAMO!\r\n");

            #ifndef DEBUG
            relay = 1;
            #endif
            actuatedLED = !actuatedLED;
            //please cleanup afterwards
            offRelay.attach(&switchOffRelay, 1.0);
            
        } else {
            DBG("NO SUCH LUCK...\r\n");
        }
    } 
}

int main(void)
{
    DBG("Garagem v0\r\n");

    //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.onDisconnection(disconnectionCallback);
    ble.gattServer().onDataWritten(onDataWrittenCallback);

     /**
     * 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();

    while (true) {
        ble.waitForEvent();
    }
}