first compiling build.

master
Joe Finney 7 years ago
parent 6dca3ed8d4
commit 79c739674c
  1. 40
      inc/MicroBit.h
  2. 88
      inc/MicroBitBLEManager.h
  3. 1
      source/CMakeLists.txt
  4. 78
      source/MicroBit.cpp
  5. 25
      source/MicroBitSuperMain.cpp
  6. 62
      source/ble-services/MicroBitBLEManager.cpp

@ -32,35 +32,7 @@
#include "MicroBitFiber.h"
#include "MicroBitMessageBus.h"
/*
* The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
* If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
* The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
* as a compatability option, but does not support the options used...
*/
#if !defined (__arm)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
#include "ble/BLE.h"
/*
* Return to our predefined compiler settings.
*/
#if !defined (__arm)
#pragma GCC diagnostic pop
#endif
#include "ble/services/DeviceInformationService.h"
#include "MicroBitDFUService.h"
#include "MicroBitEventService.h"
#include "MicroBitLEDService.h"
#include "MicroBitAccelerometerService.h"
#include "MicroBitMagnetometerService.h"
#include "MicroBitButtonService.h"
#include "MicroBitIOPinService.h"
#include "MicroBitTemperatureService.h"
#include "ExternalEvents.h"
#include "MicroBitBLEManager.h"
// MicroBit::flags values
#define MICROBIT_FLAG_SCHEDULER_RUNNING 0x00000001
@ -128,8 +100,8 @@ class MicroBit
MicroBitIO io;
// Bluetooth related member variables.
BLEDevice *ble;
MicroBitDFUService *ble_firmware_update_service;
MicroBitBLEManager bleManager;
BLEDevice *ble;
/**
* Constructor.
@ -298,12 +270,6 @@ class MicroBit
// code integration a little bit easier for third parties.
extern MicroBit uBit;
//
// BLE callback when an active GATT session with another device is terminated.
// Used to reset state and restart advertising ourselves.
//
void bleDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason);
// Entry point for application programs. Called after the super-main function
// has initialized the device and runtime environment.
extern "C" void app_main();

@ -0,0 +1,88 @@
#ifndef MICROBIT_BLE_MANAGER_H
#define MICROBIT_BLE_MANAGER_H
#include "mbed.h"
/*
* The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
* If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
* The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
* as a compatability option, but does not support the options used...
*/
#if !defined (__arm)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
#include "ble/BLE.h"
/*
* Return to our predefined compiler settings.
*/
#if !defined (__arm)
#pragma GCC diagnostic pop
#endif
#include "ble/services/DeviceInformationService.h"
#include "MicroBitDFUService.h"
#include "MicroBitEventService.h"
#include "MicroBitLEDService.h"
#include "MicroBitAccelerometerService.h"
#include "MicroBitMagnetometerService.h"
#include "MicroBitButtonService.h"
#include "MicroBitIOPinService.h"
#include "MicroBitTemperatureService.h"
#include "ExternalEvents.h"
/**
* Class definition for the MicroBitBLEManager.
*
*/
class MicroBitBLEManager
{
public:
// The mbed abstraction of the BlueTooth Low Energy (BLE) hardware
BLEDevice *ble;
/**
* 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();
/**
* 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 init(ManagedString deviceName, ManagedString serialNumber);
/**
* Enter BLUEZOE mode. This is mode is called to initiate pairing, and to enable FOTA programming
* of the micro:bit in cases where BLE is disabled during normal operation.
*
* @param display a MicroBitDisplay to use when displaying pairing information.
*/
void bluezone(MicroBitDisplay &display);
/**
* Method that is called whenever a BLE device disconnects from us.
* The nordic stack stops dvertising whenever a device connects, so we use
* this callback to restart advertising.
*/
void onDisconnectionCallback();
};
#endif

@ -29,6 +29,7 @@ set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES
"MicroBitHeapAllocator.cpp"
"MicroBitListener.cpp"
"MemberFunctionCallback.cpp"
"ble-services/MicroBitBLEManager.cpp"
"ble-services/MicroBitDFUService.cpp"
"ble-services/MicroBitEventService.cpp"
"ble-services/MicroBitLEDService.cpp"

@ -2,13 +2,6 @@
char MICROBIT_BLE_DEVICE_NAME[] = "BBC micro:bit [xxxxx]";
#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;
#endif
/**
* custom function for panic for malloc & new due to scoping issue.
@ -28,17 +21,6 @@ microbit_reset()
}
/**
* Callback when a BLE GATT disconnect occurs.
*/
void bleDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
(void) handle; /* -Wunused-param */
(void) reason; /* -Wunused-param */
uBit.ble->startAdvertising();
}
/**
* Constructor.
* Create a representation of a MicroBit device as a global singleton.
@ -76,7 +58,8 @@ MicroBit::MicroBit() :
MICROBIT_ID_IO_P9,MICROBIT_ID_IO_P10,MICROBIT_ID_IO_P11,
MICROBIT_ID_IO_P12,MICROBIT_ID_IO_P13,MICROBIT_ID_IO_P14,
MICROBIT_ID_IO_P15,MICROBIT_ID_IO_P16,MICROBIT_ID_IO_P19,
MICROBIT_ID_IO_P20)
MICROBIT_ID_IO_P20),
bleManager()
{
}
@ -112,63 +95,10 @@ void MicroBit::init()
#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED)
// Start the BLE stack.
ble = new BLEDevice();
ble->init();
ble->onDisconnection(bleDisconnectionCallback);
// 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);
bleManager.init(this->getName(), this->getSerial());
ble = bleManager.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
// Start refreshing the Matrix Display
systemTicker.attach(this, &MicroBit::systemTick, MICROBIT_DISPLAY_REFRESH_PERIOD);
}

@ -47,28 +47,13 @@ int main()
if (i == 10)
{
// OK - we need to enter BLUE ZONE mode.
// Test to see if BLE and the necessary services have been brought up already.
// If not, start them.
if (!uBit.ble)
{
uBit.ble = new BLEDevice();
uBit.ble->init();
uBit.ble->onDisconnection(bleDisconnectionCallback);
// Bring up the BLE stack if it isn't alredy done.
if (!uBit.ble)
uBit.bleManager.init(uBit.getName(), uBit.getSerial());
// Ensure we're advertising.
uBit.ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
uBit.ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)MICROBIT_BLE_DEVICE_NAME, sizeof(MICROBIT_BLE_DEVICE_NAME));
uBit.ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
uBit.ble->setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(200));
uBit.ble->startAdvertising();
}
// Enter BLUE ZONE mode, using the LED matrix for any necessary paiing operations
uBit.bleManager.bluezone(uBit.display);
if (!uBit.ble_firmware_update_service)
uBit.ble_firmware_update_service = new MicroBitDFUService(*uBit.ble);
// enter BLUE ZONE mode.
uBit.ble_firmware_update_service->pair();
}
}
#endif

@ -1,9 +1,8 @@
#include "MicroBit.h"
#define MICROBIT_BLE_ENABLE_BONDING true
#define MICROBIT_BLE_REQUIRE_MITM 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";
@ -13,7 +12,7 @@ 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.
* whilst keeping the code modular.
*/
static MicroBitBLEManager *manager = NULL;
@ -26,7 +25,7 @@ static void bleDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionRea
(void) reason; /* -Wunused-param */
if (manager)
manager->bleDisconnectionCallback();
manager->onDisconnectionCallback();
}
@ -54,31 +53,14 @@ static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager
static void securitySetupInitiatedCallback(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
{
(void) handle; /* -Wunused-param */
(void) handle; /* -Wunused-param */
(void) allowBonding; /* -Wunused-param */
(void) requireMITM; /* -Wunused-param */
(void) iocaps; /* -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.
@ -90,6 +72,18 @@ void MicroBitBLEManager::bleDisconnectionCallback()
*/
MicroBitBLEManager::MicroBitBLEManager()
{
this->ble = NULL;
}
/**
* Method that is called whenever a BLE device disconnects from us.
* The nordic stack stops dvertising whenever a device connects, so we use
* this callback to restart advertising.
*/
void MicroBitBLEManager::onDisconnectionCallback()
{
if(ble)
ble->startAdvertising();
}
/**
@ -103,7 +97,7 @@ MicroBitBLEManager::MicroBitBLEManager()
* uBit.init();
* @endcode
*/
void MicroBitBLEManager::init()
void MicroBitBLEManager::init(ManagedString deviceName, ManagedString serialNumber)
{
// Start the BLE stack.
ble = new BLEDevice();
@ -116,16 +110,15 @@ void MicroBitBLEManager::init()
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);
ble->securityManager().init(MICROBIT_BLE_ENABLE_BONDING, MICROBIT_BLE_REQUIRE_MITM, SecurityManager::IO_CAPS_DISPLAY_ONLY);
// Bring up any configured auxiliary services.
#if CONFIG_ENABLED(MICROBIT_BLE_DFU_SERVICE)
ble_firmware_update_service = new MicroBitDFUService(*ble);
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);
DeviceInformationService ble_device_information_service (*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, serialNumber.toCharArray(), MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
#endif
#if CONFIG_ENABLED(MICROBIT_BLE_EVENT_SERVICE)
@ -166,11 +159,20 @@ void MicroBitBLEManager::init()
// 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->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)deviceName.toCharArray(), deviceName.length());
ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble->setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(200));
ble->startAdvertising();
#endif
}
/**
* Enter BLUEZONE mode. This is mode is called to initiate pairing, and to enable FOTA programming
* of the micro:bit in cases where BLE is disabled during normal operation.
*/
void MicroBitBLEManager::bluezone(MicroBitDisplay &display)
{
// TODO:
while(1);
}
Loading…
Cancel
Save