BLE Application to open a Garage door

Dependencies:   BLE_API Crypto RNG mbed nRF51822

Fork of BLE_LED by Bluetooth Low Energy

Committer:
dgomes
Date:
Sun Aug 30 01:10:16 2015 +0000
Revision:
14:1c187c90992c
Parent:
13:bc1be947b497
Child:
15:88ea59cb2b9e
BLE application to control a relay connected to your garage door

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgomes 13:bc1be947b497 1 //#define DEBUG
dgomes 9:329af8cdc923 2
dgomes 9:329af8cdc923 3 #ifndef DEBUG
dgomes 9:329af8cdc923 4 #define DEVICE_SERIAL 0 //disable SERIAL so me can use P0_8 (shared with serial)
dgomes 9:329af8cdc923 5 #define DBG(...)
dgomes 9:329af8cdc923 6 #else
dgomes 9:329af8cdc923 7 #define DBG printf
dgomes 9:329af8cdc923 8 #endif
rgrover1 0:ed5c53845de7 9
rgrover1 0:ed5c53845de7 10 #include "mbed.h"
rgrover1 6:fca54d71d10e 11 #include "BLE.h"
dgomes 9:329af8cdc923 12 #include "GaragemService.h"
dgomes 11:3de9b542eeac 13 #include "SecurityService.h"
dgomes 9:329af8cdc923 14 #include "ble/services/iBeacon.h"
dgomes 9:329af8cdc923 15 #include "DeviceInformationService.h"
dgomes 9:329af8cdc923 16
dgomes 9:329af8cdc923 17
dgomes 11:3de9b542eeac 18 // HOW-TO TEST:
dgomes 11:3de9b542eeac 19 //create a string to write to the characteristic 2000:2001
dgomes 10:80850cd6c29e 20 //openssl enc -aes-128-cbc -K 9734062BA852A049CF5D40593B769014 -iv A2685636521871D02306E2EB8F7027B3 -out /dev/stdout -in inputfile
dgomes 10:80850cd6c29e 21 // TTTTIIIISSSSSSSS
dgomes 10:80850cd6c29e 22 // T -> 4 bytes Timestamp uint32_t
dgomes 10:80850cd6c29e 23 // I -> 4 bytes ID (chars)
dgomes 10:80850cd6c29e 24 // S -> 8 bytes SHARED_SECRET (chars)
dgomes 10:80850cd6c29e 25
dgomes 12:eaee29bfa1c7 26 // Generating K and iv:
dgomes 12:eaee29bfa1c7 27 //openssl enc -aes-128-cbc -pass pass:********** -nosalt -P
dgomes 12:eaee29bfa1c7 28
dgomes 9:329af8cdc923 29 #define SHARED_KEY "figueiredo"
dgomes 9:329af8cdc923 30 #define DEVICE_NAME "Garagem"
rgrover1 0:ed5c53845de7 31
rgrover1 7:c9271599ec5f 32 BLE ble;
dgomes 9:329af8cdc923 33 DigitalOut actuatedLED(P0_19);
dgomes 9:329af8cdc923 34 Timeout offRelay;
dgomes 12:eaee29bfa1c7 35 bool boot;
dgomes 9:329af8cdc923 36 #ifndef DEBUG
dgomes 9:329af8cdc923 37 DigitalOut relay(P0_8);
dgomes 9:329af8cdc923 38 #endif
dgomes 9:329af8cdc923 39
dgomes 11:3de9b542eeac 40 static const uint16_t uuid16_list[] = {GaragemService::GARAGEM_SERVICE_UUID, SecurityService::SECURITY_SERVICE_UUID};
rgrover1 0:ed5c53845de7 41
dgomes 9:329af8cdc923 42 GaragemService *garagemServicePtr;
dgomes 11:3de9b542eeac 43 SecurityService *securityServicePtr;
rgrover1 0:ed5c53845de7 44
dgomes 9:329af8cdc923 45 void switchOffRelay()
dgomes 9:329af8cdc923 46 {
dgomes 9:329af8cdc923 47 actuatedLED = !actuatedLED;
dgomes 9:329af8cdc923 48 DBG("JA CHEGA...\r\n");
dgomes 9:329af8cdc923 49 #ifndef DEBUG
dgomes 9:329af8cdc923 50 relay = 0;
dgomes 9:329af8cdc923 51 #endif
dgomes 9:329af8cdc923 52 }
dgomes 9:329af8cdc923 53
rgrover1 0:ed5c53845de7 54 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
dgomes 9:329af8cdc923 55 {
dgomes 9:329af8cdc923 56 ble.startAdvertising();
rgrover1 0:ed5c53845de7 57 }
dgomes 11:3de9b542eeac 58
rgrover1 7:c9271599ec5f 59 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
dgomes 9:329af8cdc923 60 DBG("onDataWrittenCallback: handle = %d len = %d\r\n", params->handle, params->len);
dgomes 10:80850cd6c29e 61 garagemServicePtr->nextLastOpen(params->data, params->len);
dgomes 10:80850cd6c29e 62
dgomes 9:329af8cdc923 63 if ((params->handle == garagemServicePtr->getChallengeHandle()) && (params->len ==16)) {
dgomes 10:80850cd6c29e 64 DBG("We have Challenge: data = %s\r\n", (char *) (params->data));
dgomes 9:329af8cdc923 65
dgomes 9:329af8cdc923 66 uint8_t msg[16];
dgomes 11:3de9b542eeac 67 securityServicePtr->decode(msg, (uint8_t *) params->data, 16);
dgomes 9:329af8cdc923 68
dgomes 9:329af8cdc923 69 if(garagemServicePtr->checkMessage(msg) == GARAGEM_OK) {
dgomes 10:80850cd6c29e 70 DBG("ABRE-TE SESAMO!\r\n");
dgomes 10:80850cd6c29e 71
dgomes 9:329af8cdc923 72 #ifndef DEBUG
dgomes 9:329af8cdc923 73 relay = 1;
dgomes 9:329af8cdc923 74 #endif
dgomes 10:80850cd6c29e 75 actuatedLED = !actuatedLED;
dgomes 9:329af8cdc923 76 //please cleanup afterwards
dgomes 9:329af8cdc923 77 offRelay.attach(&switchOffRelay, 1.0);
dgomes 9:329af8cdc923 78
dgomes 9:329af8cdc923 79 } else {
dgomes 9:329af8cdc923 80 DBG("NO SUCH LUCK...\r\n");
dgomes 9:329af8cdc923 81 }
dgomes 12:eaee29bfa1c7 82 } if(boot && (params->handle == securityServicePtr->getKeyHandle()) && (params->len > 0)) {
dgomes 11:3de9b542eeac 83 securityServicePtr->setKey((char *) params->data);
dgomes 11:3de9b542eeac 84 }
dgomes 12:eaee29bfa1c7 85 boot = false;
rgrover1 0:ed5c53845de7 86 }
rgrover1 0:ed5c53845de7 87
rgrover1 0:ed5c53845de7 88 int main(void)
rgrover1 0:ed5c53845de7 89 {
dgomes 9:329af8cdc923 90 DBG("Garagem v0\r\n");
rgrover1 0:ed5c53845de7 91
dgomes 12:eaee29bfa1c7 92 boot = true;
dgomes 9:329af8cdc923 93 actuatedLED = true;
dgomes 9:329af8cdc923 94 #ifndef DEBUG
dgomes 9:329af8cdc923 95 relay = 0;
dgomes 9:329af8cdc923 96 #endif
rgrover1 0:ed5c53845de7 97
rgrover1 0:ed5c53845de7 98 ble.init();
dgomes 9:329af8cdc923 99 ble.onDisconnection(disconnectionCallback);
rgrover1 7:c9271599ec5f 100 ble.gattServer().onDataWritten(onDataWrittenCallback);
rgrover1 0:ed5c53845de7 101
dgomes 9:329af8cdc923 102 /**
dgomes 9:329af8cdc923 103 * The Beacon payload has the following composition:
dgomes 9:329af8cdc923 104 * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
dgomes 9:329af8cdc923 105 * Major/Minor = 0x1122 / 0x3344
dgomes 9:329af8cdc923 106 * Tx Power = 0xC8 = 200, 2's compliment is 256-200 = (-56dB)
dgomes 9:329af8cdc923 107 *
dgomes 9:329af8cdc923 108 * Note: please remember to calibrate your beacons TX Power for more accurate results.
dgomes 9:329af8cdc923 109 */
dgomes 9:329af8cdc923 110 const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,
dgomes 9:329af8cdc923 111 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61};
dgomes 9:329af8cdc923 112 uint16_t majorNumber = 3800;
dgomes 9:329af8cdc923 113 uint16_t minorNumber = 1423;
dgomes 9:329af8cdc923 114 uint16_t txPower = 0xBE;
dgomes 9:329af8cdc923 115 iBeacon ibeacon(ble, uuid, majorNumber, minorNumber, txPower);
dgomes 12:eaee29bfa1c7 116
dgomes 12:eaee29bfa1c7 117 DeviceInformationService deviceInfo(ble, "diogogomes.com", DEVICE_NAME, "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
dgomes 9:329af8cdc923 118
dgomes 9:329af8cdc923 119 GaragemService garagemService(ble);
dgomes 9:329af8cdc923 120 garagemServicePtr = &garagemService;
dgomes 11:3de9b542eeac 121
dgomes 12:eaee29bfa1c7 122 SecurityService securityService(ble);
dgomes 12:eaee29bfa1c7 123 securityService.init(SHARED_KEY);
dgomes 11:3de9b542eeac 124 securityServicePtr = &securityService;
dgomes 9:329af8cdc923 125
rgrover1 0:ed5c53845de7 126 /* setup advertising */
rgrover1 7:c9271599ec5f 127 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
rgrover1 7:c9271599ec5f 128 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
rgrover1 7:c9271599ec5f 129 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
rgrover1 7:c9271599ec5f 130 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
dgomes 9:329af8cdc923 131
dgomes 9:329af8cdc923 132
rgrover1 7:c9271599ec5f 133 ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
rgrover1 7:c9271599ec5f 134 ble.gap().startAdvertising();
rgrover1 0:ed5c53845de7 135
rgrover1 0:ed5c53845de7 136 while (true) {
rgrover1 0:ed5c53845de7 137 ble.waitForEvent();
rgrover1 0:ed5c53845de7 138 }
rgrover1 0:ed5c53845de7 139 }