parent
2532d2f0b5
commit
6dca3ed8d4
@ -0,0 +1,176 @@
|
||||
#include "MicroBit.h"
|
||||
|
||||
#define MICROBIT_BLE_ENABLE_BONDING true
|
||||
#define MICROBIT_BLE_REQUIRE_MITM true
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) && CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
|
||||
const char* MICROBIT_BLE_MANUFACTURER = "The Cast of W1A";
|
||||
const char* MICROBIT_BLE_MODEL = "BBC micro:bit";
|
||||
const char* MICROBIT_BLE_HARDWARE_VERSION = "1.0";
|
||||
const char* MICROBIT_BLE_FIRMWARE_VERSION = MICROBIT_DAL_VERSION;
|
||||
const char* MICROBIT_BLE_SOFTWARE_VERSION = NULL;
|
||||
|
||||
/*
|
||||
* Many of the mbed interfaces we need to use only support callbacks to plain C functions, rather than C++ methods.
|
||||
* So, we maintain a pointer to the MicroBitBLEManager that's in use. Ths way, we can still access resources on the micro:bit
|
||||
* whilst keeping the code modular.
|
||||
*/
|
||||
static MicroBitBLEManager *manager = NULL;
|
||||
|
||||
/**
|
||||
* Callback when a BLE GATT disconnect occurs.
|
||||
*/
|
||||
static void bleDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
|
||||
{
|
||||
(void) handle; /* -Wunused-param */
|
||||
(void) reason; /* -Wunused-param */
|
||||
|
||||
if (manager)
|
||||
manager->bleDisconnectionCallback();
|
||||
|
||||
}
|
||||
|
||||
static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
|
||||
{
|
||||
(void) handle; /* -Wunused-param */
|
||||
|
||||
printf("Input passKey: ");
|
||||
for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
|
||||
printf("%c", passkey[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
|
||||
{
|
||||
(void) handle; /* -Wunused-param */
|
||||
|
||||
if (status == SecurityManager::SEC_STATUS_SUCCESS) {
|
||||
printf("Security success %d\r\n", status);
|
||||
} else {
|
||||
printf("Security failed %d\r\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
static void securitySetupInitiatedCallback(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
|
||||
{
|
||||
(void) handle; /* -Wunused-param */
|
||||
(void) allowBonding; /* -Wunused-param */
|
||||
(void) requireMITM; /* -Wunused-param */
|
||||
(void) iocaps; /* -Wunused-param */
|
||||
|
||||
printf("Security setup initiated\r\n");
|
||||
}
|
||||
|
||||
void initializeSecurity(BLE &ble)
|
||||
{
|
||||
bool enableBonding = true;
|
||||
bool requireMITM = HID_SECURITY_REQUIRE_MITM;
|
||||
|
||||
ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
|
||||
ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
|
||||
ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
|
||||
|
||||
ble.securityManager().init(enableBonding, requireMITM, HID_SECURITY_IOCAPS);
|
||||
}
|
||||
|
||||
|
||||
void MicroBitBLEManager::bleDisconnectionCallback()
|
||||
{
|
||||
ble.startAdvertising();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
|
||||
* Note that the BLE stack *cannot* be brought up in a static context.
|
||||
* (the software simply hangs or corrupts itself).
|
||||
* Hence, we bring it up in an explicit init() method, rather than in the constructor.
|
||||
*/
|
||||
MicroBitBLEManager::MicroBitBLEManager()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Post constructor initialisation method.
|
||||
* After *MUCH* pain, it's noted that the BLE stack can't be brought up in a
|
||||
* static context, so we bring it up here rather than in the constructor.
|
||||
* n.b. This method *must* be called in main() or later, not before.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.init();
|
||||
* @endcode
|
||||
*/
|
||||
void MicroBitBLEManager::init()
|
||||
{
|
||||
// Start the BLE stack.
|
||||
ble = new BLEDevice();
|
||||
ble->init();
|
||||
|
||||
// automatically restart advertising after a device disconnects.
|
||||
ble->onDisconnection(bleDisconnectionCallback);
|
||||
|
||||
// Setup our security requirements.
|
||||
ble->securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
|
||||
ble->securityManager().onPasskeyDisplay(passkeyDisplayCallback);
|
||||
ble->securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
|
||||
|
||||
ble.securityManager().init(MICROBIT_BLE_ENABLE_BONDING, MICROBIT_BLE_REQUIRE_MITM, HID_SECURITY_IOCAPS);
|
||||
|
||||
// Bring up any configured auxiliary services.
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_DFU_SERVICE)
|
||||
ble_firmware_update_service = new MicroBitDFUService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
|
||||
DeviceInformationService ble_device_information_service (*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, getSerial().toCharArray(), MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_EVENT_SERVICE)
|
||||
new MicroBitEventService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_LED_SERVICE)
|
||||
new MicroBitLEDService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_ACCELEROMETER_SERVICE)
|
||||
new MicroBitAccelerometerService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_MAGNETOMETER_SERVICE)
|
||||
new MicroBitMagnetometerService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_BUTTON_SERVICE)
|
||||
new MicroBitButtonService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_IO_PIN_SERVICE)
|
||||
new MicroBitIOPinService(*ble);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_BLE_TEMPERATURE_SERVICE)
|
||||
new MicroBitTemperatureService(*ble);
|
||||
#endif
|
||||
|
||||
// Configure for high speed mode where possible.
|
||||
Gap::ConnectionParams_t fast;
|
||||
ble->getPreferredConnectionParams(&fast);
|
||||
fast.minConnectionInterval = 8; // 10 ms
|
||||
fast.maxConnectionInterval = 16; // 20 ms
|
||||
fast.slaveLatency = 0;
|
||||
ble->setPreferredConnectionParams(&fast);
|
||||
|
||||
// Setup advertising.
|
||||
ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
|
||||
ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)MICROBIT_BLE_DEVICE_NAME, sizeof(MICROBIT_BLE_DEVICE_NAME));
|
||||
ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
|
||||
ble->setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(200));
|
||||
ble->startAdvertising();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
Loading…
Reference in new issue