BLE Application to open a Garage door
Dependencies: BLE_API Crypto RNG mbed nRF51822
Fork of BLE_LED by
main.cpp@13:bc1be947b497, 2015-08-30 (annotated)
- Committer:
- dgomes
- Date:
- Sun Aug 30 01:06:17 2015 +0000
- Revision:
- 13:bc1be947b497
- Parent:
- 12:eaee29bfa1c7
- Child:
- 15:88ea59cb2b9e
Works :)
Who changed what in which revision?
User | Revision | Line number | New 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 | } |