BLE Application to open a Garage door
Dependencies: BLE_API Crypto RNG mbed nRF51822
Fork of BLE_LED by
Revision 9:329af8cdc923, committed 2015-08-25
- Comitter:
- dgomes
- Date:
- Tue Aug 25 22:18:21 2015 +0000
- Parent:
- 8:0f145b25ab0b
- Child:
- 10:80850cd6c29e
- Commit message:
- Mostly Works :)
Changed in this revision
--- a/BLE_API.lib Thu Jul 02 08:44:06 2015 +0000 +++ b/BLE_API.lib Tue Aug 25 22:18:21 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#6884e374e2eb +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#8d316a3271a8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Crypto.lib Tue Aug 25 22:18:21 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/feb11/code/Crypto/#f04410cef037
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GaragemService.h Tue Aug 25 22:18:21 2015 +0000 @@ -0,0 +1,86 @@ +/* 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. + */ + +#ifndef __BLE_GARAGEM_SERVICE_H__ +#define __BLE_GARAGEM_SERVICE_H__ +#include "History.h" + +#define SHARED_SECRET "ABRE-TE" + +#define GARAGEM_OK 0 +#define GARAGEM_ERROR_REPETITION_ATTACK 1 +#define GARAGEM_ERROR_WRONG_SHARED_SECRET 2 + + +class GaragemService { +public: + const static uint16_t GARAGEM_SERVICE_UUID = 0x2000; + const static uint16_t GARAGEM_CHALLENGE_CHARACTERISTIC_UUID = 0x2001; + const static uint16_t GARAGEM_LAST_OPEN_TS_UUID = 0x2002; + const static uint16_t GARAGEM_LAST_OPEN_ID_UUID = 0x2003; + + GaragemService(BLE &_ble) : + ble(_ble), + GaragemChallenge(GARAGEM_CHALLENGE_CHARACTERISTIC_UUID, (uint8_t *)"INIT"), + GaragemLastOpenTS(GARAGEM_LAST_OPEN_TS_UUID, 0), + GaragemLastOpenID(GARAGEM_LAST_OPEN_ID_UUID, (uint8_t *)"INIT") + { + GattCharacteristic *charTable[] = {&GaragemChallenge, &GaragemLastOpenTS, &GaragemLastOpenID}; + GattService GaragemService(GARAGEM_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(GaragemService); + } + + GattAttribute::Handle_t getChallengeHandle() const { + return GaragemChallenge.getValueHandle(); + } + + int checkMessage(uint8_t *msg) { + DBG("WHAT ? %s\r\n", (char *) msg); + + uint64_t token; + char syskey[8]; + memcpy(&token, msg, 8); + memcpy(&syskey, &msg[8], 8); + DBG("TS=%lu\tID=%c%c%c%c\tSYSKEY=%s\r\n", *((uint32_t *) msg), msg[4], msg[5], msg[6], msg[7], &msg[8]); + + //check we are not a victim of a repetion attack + if(history.last_ts() >= (uint32_t) msg[0]) { + DBG("HA HA repetion here...\r\n"); + return GARAGEM_ERROR_REPETITION_ATTACK; + } + + if (strncmp(syskey,SHARED_SECRET,7)==0) {//TODO MOVE TO 8 CHARS + //Save our success + history.save(token); + ble.gattServer().write(GaragemLastOpenTS.getValueHandle(), (const uint8_t *)&msg[0], 4*sizeof(uint8_t)); + ble.gattServer().write(GaragemLastOpenID.getValueHandle(), (const uint8_t *)&msg[4], 4*sizeof(uint8_t)); + + return GARAGEM_OK; + } else { + return GARAGEM_ERROR_WRONG_SHARED_SECRET; + } + } + +private: + BLE &ble; + WriteOnlyArrayGattCharacteristic<uint8_t, 16> GaragemChallenge; + ReadOnlyGattCharacteristic<uint32_t> GaragemLastOpenTS; + ReadOnlyArrayGattCharacteristic<uint8_t, 4> GaragemLastOpenID; + + History<16> history; +}; + +#endif /* #ifndef __BLE_GARAGEM_SERVICE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/History.h Tue Aug 25 22:18:21 2015 +0000 @@ -0,0 +1,50 @@ +#ifndef HISTORY_H +#define HISTORY_H + +template<uint32_t BufferSize> +class History { +public: + History() : _head(0) { + } + + ~History() { + } + + void save(const uint64_t& data) { + _pool[_head++] = data; + _head %= BufferSize; + } + + bool exist(const uint64_t& data) { + for(uint32_t i=0; i<BufferSize; i++) { + DBG("%llu == %llu\r\n", _pool[i], data); + if(_pool[i]==data) { + return true; + } + } + return false; + } + + uint64_t last() { + uint32_t prev = (_head-1+BufferSize)%BufferSize; + return _pool[prev]; + } + + uint32_t last_ts() { + return (uint32_t) last(); + } + + /** Reset the buffer + * + */ + void reset() { + _head = 0; + } + +private: + uint64_t _pool[BufferSize]; + volatile uint32_t _head; +}; + + +#endif \ No newline at end of file
--- a/LEDService.h Thu Jul 02 08:44:06 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* 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. - */ - -#ifndef __BLE_LED_SERVICE_H__ -#define __BLE_LED_SERVICE_H__ - -class LEDService { -public: - const static uint16_t LED_SERVICE_UUID = 0xA000; - const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001; - - LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) : - ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) - { - GattCharacteristic *charTable[] = {&ledState}; - GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.addService(ledService); - } - - GattAttribute::Handle_t getValueHandle() const { - return ledState.getValueHandle(); - } - -private: - BLEDevice &ble; - ReadWriteGattCharacteristic<bool> ledState; -}; - -#endif /* #ifndef __BLE_LED_SERVICE_H__ */
--- 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();
--- a/mbed.bld Thu Jul 02 08:44:06 2015 +0000 +++ b/mbed.bld Tue Aug 25 22:18:21 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/8ed44a420e5c \ No newline at end of file
--- a/nRF51822.lib Thu Jul 02 08:44:06 2015 +0000 +++ b/nRF51822.lib Tue Aug 25 22:18:21 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#7455428e5ddb +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#ca9c9c2cfc6a