Eddystone test using modified DAL

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit-eddystone

Fork of microbit-dal by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitEventService.cpp Source File

MicroBitEventService.cpp

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 /**
00027   * Class definition for a MicroBit BLE Event Service.
00028   * Provides a BLE gateway onto an Event Model.
00029   */
00030 
00031 #include "MicroBitConfig.h"
00032 #include "MicroBitEventService.h"
00033 #include "ble/UUID.h"
00034 #include "ExternalEvents.h"
00035 #include "MicroBitFiber.h"
00036 
00037 /**
00038   * Constructor.
00039   * Create a representation of the EventService
00040   * @param _ble The instance of a BLE device that we're running on.
00041   * @param _messageBus An instance of an EventModel which events will be mirrored from.
00042   */
00043 MicroBitEventService::MicroBitEventService(BLEDevice &_ble, EventModel &_messageBus) :
00044         ble(_ble),messageBus(_messageBus)
00045 {
00046     GattCharacteristic  microBitEventCharacteristic(MicroBitEventServiceMicroBitEventCharacteristicUUID, (uint8_t *)&microBitEventBuffer, 0, sizeof(EventServiceEvent),
00047     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00048 
00049     GattCharacteristic  clientEventCharacteristic(MicroBitEventServiceClientEventCharacteristicUUID, (uint8_t *)&clientEventBuffer, 0, sizeof(EventServiceEvent),
00050     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
00051 
00052     GattCharacteristic  clientRequirementsCharacteristic(MicroBitEventServiceClientRequirementsCharacteristicUUID, (uint8_t *)&clientRequirementsBuffer, 0, sizeof(EventServiceEvent), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
00053 
00054     microBitRequirementsCharacteristic = new GattCharacteristic(MicroBitEventServiceMicroBitRequirementsCharacteristicUUID, (uint8_t *)&microBitRequirementsBuffer, 0, sizeof(EventServiceEvent), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00055 
00056     microBitRequirementsCharacteristic->setReadAuthorizationCallback(this, &MicroBitEventService::onRequirementsRead);
00057 
00058     clientEventBuffer.type = 0x00;
00059     clientEventBuffer.reason = 0x00;
00060 
00061     microBitEventBuffer = microBitRequirementsBuffer = clientRequirementsBuffer = clientEventBuffer;
00062 
00063     messageBusListenerOffset = 0;
00064 
00065     // Set default security requirements
00066     microBitEventCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00067     clientEventCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00068     clientRequirementsCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00069     microBitRequirementsCharacteristic->requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00070 
00071     GattCharacteristic *characteristics[] = {&microBitEventCharacteristic, &clientEventCharacteristic, &clientRequirementsCharacteristic, microBitRequirementsCharacteristic};
00072     GattService         service(MicroBitEventServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
00073 
00074     ble.addService(service);
00075 
00076     microBitEventCharacteristicHandle = microBitEventCharacteristic.getValueHandle();
00077     clientEventCharacteristicHandle = clientEventCharacteristic.getValueHandle();
00078     clientRequirementsCharacteristicHandle = clientRequirementsCharacteristic.getValueHandle();
00079 
00080     ble.onDataWritten(this, &MicroBitEventService::onDataWritten);
00081 
00082     fiber_add_idle_component(this);
00083 }
00084 
00085 
00086 /**
00087   * Callback. Invoked when any of our attributes are written via BLE.
00088   */
00089 void MicroBitEventService::onDataWritten(const GattWriteCallbackParams *params)
00090 {
00091     int len = params->len;
00092     EventServiceEvent *e = (EventServiceEvent *)params->data;
00093 
00094     if (params->handle == clientEventCharacteristicHandle) {
00095 
00096         // Read and fire all events...
00097         while (len >= 4)
00098         {
00099             MicroBitEvent evt(e->type, e->reason);
00100             len-=4;
00101             e++;
00102         }
00103         return;
00104     }
00105 
00106     if (params->handle == clientRequirementsCharacteristicHandle) {
00107         // Read and register for all the events given...
00108         while (len >= 4)
00109         {
00110             messageBus.listen(e->type, e->reason, this, &MicroBitEventService::onMicroBitEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
00111 
00112             len-=4;
00113             e++;
00114         }
00115         return;
00116     }
00117 }
00118 
00119 /**
00120   * Callback. Invoked when any events are sent on the microBit message bus.
00121   */
00122 void MicroBitEventService::onMicroBitEvent(MicroBitEvent evt)
00123 {
00124     EventServiceEvent *e = &microBitEventBuffer;
00125 
00126     if (ble.getGapState().connected) {
00127         e->type = evt.source;
00128         e->reason = evt.value;
00129 
00130         ble.gattServer().notify(microBitEventCharacteristicHandle, (const uint8_t *)e, sizeof(EventServiceEvent));
00131     }
00132 }
00133 
00134 /**
00135   * Periodic callback from MicroBit scheduler.
00136   * If we're no longer connected, remove any registered Message Bus listeners.
00137   */
00138 void MicroBitEventService::idleTick()
00139 {
00140     if (!ble.getGapState().connected && messageBusListenerOffset >0) {
00141         messageBusListenerOffset = 0;
00142         messageBus.ignore(MICROBIT_ID_ANY, MICROBIT_EVT_ANY, this, &MicroBitEventService::onMicroBitEvent);
00143     }
00144 }
00145 
00146 /**
00147   * Read callback on microBitRequirements characteristic.
00148   *
00149   * Used to iterate through the events that the code on this micro:bit is interested in.
00150   */
00151 void MicroBitEventService::onRequirementsRead(GattReadAuthCallbackParams *params)
00152 {
00153     if (params->handle == microBitRequirementsCharacteristic->getValueHandle())
00154     {
00155         // Walk through the lsit of message bus listeners.
00156         // We send one at a time, and our client can keep reading from this characterisitic until we return an emtpy value.
00157         MicroBitListener *l = messageBus.elementAt(messageBusListenerOffset++);
00158 
00159         if (l != NULL)
00160         {
00161             microBitRequirementsBuffer.type = l->id;
00162             microBitRequirementsBuffer.reason = l->value;
00163             ble.gattServer().write(microBitRequirementsCharacteristic->getValueHandle(), (uint8_t *)&microBitRequirementsBuffer, sizeof(EventServiceEvent));
00164         } else {
00165             ble.gattServer().write(microBitRequirementsCharacteristic->getValueHandle(), (uint8_t *)&microBitRequirementsBuffer, 0);
00166         }
00167     }
00168 }
00169 
00170 const uint8_t  MicroBitEventServiceUUID[] = {
00171     0xe9,0x5d,0x93,0xaf,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00172 };
00173 
00174 const uint8_t  MicroBitEventServiceMicroBitEventCharacteristicUUID[] = {
00175     0xe9,0x5d,0x97,0x75,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00176 };
00177 
00178 const uint8_t  MicroBitEventServiceClientEventCharacteristicUUID[] = {
00179     0xe9,0x5d,0x54,0x04,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00180 };
00181 
00182 const uint8_t  MicroBitEventServiceMicroBitRequirementsCharacteristicUUID[] = {
00183     0xe9,0x5d,0xb8,0x4c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00184 };
00185 
00186 const uint8_t  MicroBitEventServiceClientRequirementsCharacteristicUUID[] = {
00187     0xe9,0x5d,0x23,0xc4,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00188 };