BLE Application to open a Garage door

Dependencies:   BLE_API Crypto RNG mbed nRF51822

Fork of BLE_LED by Bluetooth Low Energy

Committer:
duststorm
Date:
Mon May 01 00:33:07 2017 +0000
Revision:
15:88ea59cb2b9e
Parent:
13:bc1be947b497
force address for Nano to F2:9B:4B:03:02:01 to match the prefix expected by the app

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