Solution for Bluetooth SIG hands-on training course

Dependencies:   BLE_API mbed-dev-bin nRF51822-bluetooth-mdw

Dependents:   microbit

Fork of microbit-dal-bluetooth-mdw_starter by Martin Woolley

Committer:
LancasterUniversity
Date:
Wed Jul 13 12:17:54 2016 +0100
Revision:
22:23d7b9a4b082
Parent:
21:cab56b701601
Child:
23:6055f6c19fa6
Synchronized with git rev 7cf98c22
Author: James Devine
microbit-dal: patch for fiber_wake_on_event

fiber_wake_on_event used to crash after forking a FOB fiber.

It would attempt to obtain a new fiber context, and would place it on the wait queue.
Then when that fiber was paged in, the context of that fiber would not have been
initialised, as the function presumed schedule would be called immediately after
fiber initialisation.

This patch catches that edge case.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for the MicroBit BLE Magnetometer Service.
Jonathan Austin 1:8aa5cdb4ab67 28 * Provides access to live magnetometer data via BLE, and provides basic configuration options.
Jonathan Austin 1:8aa5cdb4ab67 29 */
Jonathan Austin 1:8aa5cdb4ab67 30 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 31 #include "ble/UUID.h"
Jonathan Austin 1:8aa5cdb4ab67 32
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitMagnetometerService.h"
Jonathan Austin 1:8aa5cdb4ab67 34
Jonathan Austin 1:8aa5cdb4ab67 35 /**
Jonathan Austin 1:8aa5cdb4ab67 36 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 37 * Create a representation of the MagnetometerService.
Jonathan Austin 1:8aa5cdb4ab67 38 * @param _ble The instance of a BLE device that we're running on.
Jonathan Austin 1:8aa5cdb4ab67 39 * @param _compass An instance of MicroBitCompass to use as our Magnetometer source.
Jonathan Austin 1:8aa5cdb4ab67 40 */
Jonathan Austin 1:8aa5cdb4ab67 41 MicroBitMagnetometerService::MicroBitMagnetometerService(BLEDevice &_ble, MicroBitCompass &_compass) :
Jonathan Austin 1:8aa5cdb4ab67 42 ble(_ble), compass(_compass)
Jonathan Austin 1:8aa5cdb4ab67 43 {
Jonathan Austin 1:8aa5cdb4ab67 44 // Create the data structures that represent each of our characteristics in Soft Device.
Jonathan Austin 1:8aa5cdb4ab67 45 GattCharacteristic magnetometerDataCharacteristic(MicroBitMagnetometerServiceDataUUID, (uint8_t *)magnetometerDataCharacteristicBuffer, 0,
Jonathan Austin 1:8aa5cdb4ab67 46 sizeof(magnetometerDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
Jonathan Austin 1:8aa5cdb4ab67 47
Jonathan Austin 1:8aa5cdb4ab67 48 GattCharacteristic magnetometerBearingCharacteristic(MicroBitMagnetometerServiceBearingUUID, (uint8_t *)&magnetometerBearingCharacteristicBuffer, 0,
Jonathan Austin 1:8aa5cdb4ab67 49 sizeof(magnetometerBearingCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
Jonathan Austin 1:8aa5cdb4ab67 50
Jonathan Austin 1:8aa5cdb4ab67 51 GattCharacteristic magnetometerPeriodCharacteristic(MicroBitMagnetometerServicePeriodUUID, (uint8_t *)&magnetometerPeriodCharacteristicBuffer, 0,
Jonathan Austin 1:8aa5cdb4ab67 52 sizeof(magnetometerPeriodCharacteristicBuffer),
Jonathan Austin 1:8aa5cdb4ab67 53 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
Jonathan Austin 1:8aa5cdb4ab67 54
Jonathan Austin 1:8aa5cdb4ab67 55 // Initialise our characteristic values.
Jonathan Austin 1:8aa5cdb4ab67 56 magnetometerDataCharacteristicBuffer[0] = 0;
Jonathan Austin 1:8aa5cdb4ab67 57 magnetometerDataCharacteristicBuffer[1] = 0;
Jonathan Austin 1:8aa5cdb4ab67 58 magnetometerDataCharacteristicBuffer[2] = 0;
Jonathan Austin 1:8aa5cdb4ab67 59 magnetometerBearingCharacteristicBuffer = 0;
Jonathan Austin 1:8aa5cdb4ab67 60 magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 61
Jonathan Austin 1:8aa5cdb4ab67 62 // Set default security requirements
Jonathan Austin 1:8aa5cdb4ab67 63 magnetometerDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
Jonathan Austin 1:8aa5cdb4ab67 64 magnetometerBearingCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
Jonathan Austin 1:8aa5cdb4ab67 65 magnetometerPeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
Jonathan Austin 1:8aa5cdb4ab67 66
Jonathan Austin 1:8aa5cdb4ab67 67 GattCharacteristic *characteristics[] = {&magnetometerDataCharacteristic, &magnetometerBearingCharacteristic, &magnetometerPeriodCharacteristic};
Jonathan Austin 1:8aa5cdb4ab67 68 GattService service(MicroBitMagnetometerServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 ble.addService(service);
Jonathan Austin 1:8aa5cdb4ab67 71
Jonathan Austin 1:8aa5cdb4ab67 72 magnetometerDataCharacteristicHandle = magnetometerDataCharacteristic.getValueHandle();
Jonathan Austin 1:8aa5cdb4ab67 73 magnetometerBearingCharacteristicHandle = magnetometerBearingCharacteristic.getValueHandle();
Jonathan Austin 1:8aa5cdb4ab67 74 magnetometerPeriodCharacteristicHandle = magnetometerPeriodCharacteristic.getValueHandle();
Jonathan Austin 1:8aa5cdb4ab67 75
Jonathan Austin 1:8aa5cdb4ab67 76 ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
LancasterUniversity 22:23d7b9a4b082 77 ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 78 ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 79
Jonathan Austin 1:8aa5cdb4ab67 80 ble.onDataWritten(this, &MicroBitMagnetometerService::onDataWritten);
Jonathan Austin 1:8aa5cdb4ab67 81 if (EventModel::defaultEventBus)
Jonathan Austin 1:8aa5cdb4ab67 82 {
Jonathan Austin 1:8aa5cdb4ab67 83 EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_DATA_UPDATE, this, &MicroBitMagnetometerService::magnetometerUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
Jonathan Austin 1:8aa5cdb4ab67 84 EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED, this, &MicroBitMagnetometerService::samplePeriodUpdateNeeded);
Jonathan Austin 1:8aa5cdb4ab67 85 }
Jonathan Austin 1:8aa5cdb4ab67 86 }
Jonathan Austin 1:8aa5cdb4ab67 87
Jonathan Austin 1:8aa5cdb4ab67 88 /**
Jonathan Austin 1:8aa5cdb4ab67 89 * Callback. Invoked when any of our attributes are written via BLE.
Jonathan Austin 1:8aa5cdb4ab67 90 */
Jonathan Austin 1:8aa5cdb4ab67 91 void MicroBitMagnetometerService::onDataWritten(const GattWriteCallbackParams *params)
Jonathan Austin 1:8aa5cdb4ab67 92 {
Jonathan Austin 1:8aa5cdb4ab67 93 if (params->handle == magnetometerPeriodCharacteristicHandle && params->len >= sizeof(magnetometerPeriodCharacteristicBuffer))
Jonathan Austin 1:8aa5cdb4ab67 94 {
Jonathan Austin 1:8aa5cdb4ab67 95 magnetometerPeriodCharacteristicBuffer = *((uint16_t *)params->data);
Jonathan Austin 1:8aa5cdb4ab67 96 MicroBitEvent evt(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED);
Jonathan Austin 1:8aa5cdb4ab67 97 }
Jonathan Austin 1:8aa5cdb4ab67 98 }
Jonathan Austin 1:8aa5cdb4ab67 99
Jonathan Austin 1:8aa5cdb4ab67 100 /**
Jonathan Austin 1:8aa5cdb4ab67 101 * Magnetometer update callback
Jonathan Austin 1:8aa5cdb4ab67 102 */
Jonathan Austin 1:8aa5cdb4ab67 103 void MicroBitMagnetometerService::magnetometerUpdate(MicroBitEvent)
Jonathan Austin 1:8aa5cdb4ab67 104 {
Jonathan Austin 1:8aa5cdb4ab67 105 if (ble.getGapState().connected)
Jonathan Austin 1:8aa5cdb4ab67 106 {
Jonathan Austin 1:8aa5cdb4ab67 107 magnetometerDataCharacteristicBuffer[0] = compass.getX();
Jonathan Austin 1:8aa5cdb4ab67 108 magnetometerDataCharacteristicBuffer[1] = compass.getY();
Jonathan Austin 1:8aa5cdb4ab67 109 magnetometerDataCharacteristicBuffer[2] = compass.getZ();
Jonathan Austin 1:8aa5cdb4ab67 110 magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 111
Jonathan Austin 1:8aa5cdb4ab67 112 ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 113 ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 114
Jonathan Austin 1:8aa5cdb4ab67 115 if (compass.isCalibrated())
Jonathan Austin 1:8aa5cdb4ab67 116 {
Jonathan Austin 1:8aa5cdb4ab67 117 magnetometerBearingCharacteristicBuffer = (uint16_t) compass.heading();
Jonathan Austin 1:8aa5cdb4ab67 118 ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 119 }
Jonathan Austin 1:8aa5cdb4ab67 120 }
Jonathan Austin 1:8aa5cdb4ab67 121 }
Jonathan Austin 1:8aa5cdb4ab67 122
Jonathan Austin 1:8aa5cdb4ab67 123 /**
Jonathan Austin 1:8aa5cdb4ab67 124 * Sample Period Change Needed callback.
Jonathan Austin 1:8aa5cdb4ab67 125 * Reconfiguring the magnetometer can to a REALLY long time (sometimes even seconds to complete)
Jonathan Austin 1:8aa5cdb4ab67 126 * So we do this in the background when necessary, through this event handler.
Jonathan Austin 1:8aa5cdb4ab67 127 */
Jonathan Austin 1:8aa5cdb4ab67 128 void MicroBitMagnetometerService::samplePeriodUpdateNeeded(MicroBitEvent)
Jonathan Austin 1:8aa5cdb4ab67 129 {
Jonathan Austin 1:8aa5cdb4ab67 130 // Reconfigure the compass. This might take a while...
Jonathan Austin 1:8aa5cdb4ab67 131 compass.setPeriod(magnetometerPeriodCharacteristicBuffer);
Jonathan Austin 1:8aa5cdb4ab67 132
Jonathan Austin 1:8aa5cdb4ab67 133 // The compass will choose the nearest sample period to that we've specified.
Jonathan Austin 1:8aa5cdb4ab67 134 // Read the ACTUAL sample period back.
Jonathan Austin 1:8aa5cdb4ab67 135 magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 136
Jonathan Austin 1:8aa5cdb4ab67 137 // Ensure this is reflected in our BLE connection.
Jonathan Austin 1:8aa5cdb4ab67 138 ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
Jonathan Austin 1:8aa5cdb4ab67 139
Jonathan Austin 1:8aa5cdb4ab67 140 }
Jonathan Austin 1:8aa5cdb4ab67 141
Jonathan Austin 1:8aa5cdb4ab67 142 const uint8_t MicroBitMagnetometerServiceUUID[] = {
Jonathan Austin 1:8aa5cdb4ab67 143 0xe9,0x5d,0xf2,0xd8,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
Jonathan Austin 1:8aa5cdb4ab67 144 };
Jonathan Austin 1:8aa5cdb4ab67 145
Jonathan Austin 1:8aa5cdb4ab67 146 const uint8_t MicroBitMagnetometerServiceDataUUID[] = {
Jonathan Austin 1:8aa5cdb4ab67 147 0xe9,0x5d,0xfb,0x11,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
Jonathan Austin 1:8aa5cdb4ab67 148 };
Jonathan Austin 1:8aa5cdb4ab67 149
Jonathan Austin 1:8aa5cdb4ab67 150 const uint8_t MicroBitMagnetometerServicePeriodUUID[] = {
Jonathan Austin 1:8aa5cdb4ab67 151 0xe9,0x5d,0x38,0x6c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
Jonathan Austin 1:8aa5cdb4ab67 152 };
Jonathan Austin 1:8aa5cdb4ab67 153
Jonathan Austin 1:8aa5cdb4ab67 154 const uint8_t MicroBitMagnetometerServiceBearingUUID[] = {
Jonathan Austin 1:8aa5cdb4ab67 155 0xe9,0x5d,0x97,0x15,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
LancasterUniversity 21:cab56b701601 156 };