Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions inc/MicroBitBLEService.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class MicroBitBLEService

~MicroBitBLEService();

ble_uuid_t getServiceUUID();

protected:

Expand Down Expand Up @@ -137,6 +138,7 @@ class MicroBitBLEService

uint8_t bs_uuid_type;
microbit_servicehandle_t bs_service_handle;
ble_uuid_t bs_service_uuid;

static const uint8_t bs_base_uuid[16];
};
Expand Down
6 changes: 5 additions & 1 deletion inc/MicroBitConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
#endif

// Enable/Disable Nordic Firmware style BLE based UART implimentation.
// The default codal implimentation reverses the TX/RX ids
// The default codal implementation reverses the TX/RX ids
// Set to '1' to enable
#ifndef MICROBIT_BLE_NORDIC_STYLE_UART
#define MICROBIT_BLE_NORDIC_STYLE_UART 0
Expand All @@ -272,4 +272,8 @@
#define MICROBIT_USB_SERIAL_WAKE 0
#endif

#ifndef MICROBIT_SW_VERSION
#define MICROBIT_SW_VERSION "unknown"
#endif

#endif
13 changes: 13 additions & 0 deletions inc/bluetooth/MicroBitBLEManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ class MicroBitBLEManager : public CodalComponent
*/
void advertise();

/**
* When called, the micro:bit will begin advertising the supplied service's complete UUID.
*
* @param serviceUUIDs Pointer to an array of service UUID structures to insert into the advertising data.
* @param service_count Count of service UUID structures to insert into the advertising data.
* @param service_list_complete Flag to indicate whether the service UUID array contains all available services.
* @param manufacturer_id Manufacturer ID to insert into Manfacturer Data value in the advertising data.
* @param manufacturer_data Array of Manfacturer Data bytes to insert into the advertising data.
* @param manufacturer_data_size Size of Manfacturer Data array.
*/
void advertise(ble_uuid_t *serviceUUIDs, uint16_t service_count = 1, bool service_list_complete = true,
uint16_t manufacturer_id = 0, uint8_t *manufacturer_data = nullptr, uint16_t manufacturer_data_size = 0);

/**
* Determines the number of devices currently bonded with this micro:bit.
* @return The number of active bonds.
Expand Down
95 changes: 92 additions & 3 deletions source/bluetooth/MicroBitBLEManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@ DEALINGS IN THE SOFTWARE.

const char *MICROBIT_BLE_MANUFACTURER = NULL;
const char *MICROBIT_BLE_MODEL = "BBC micro:bit";
const char *MICROBIT_BLE_VERSION[2] = { "2.0", "2.X" };
const char *MICROBIT_BLE_HARDWARE_VERSION = NULL;
const char *MICROBIT_BLE_FIRMWARE_VERSION = MICROBIT_DAL_VERSION;
const char *MICROBIT_BLE_SOFTWARE_VERSION = NULL;
const char *MICROBIT_BLE_SOFTWARE_VERSION = MICROBIT_SW_VERSION;

const int8_t MICROBIT_BLE_POWER_LEVEL[] = { -40, -20, -16, -12, -8, -4, 0, 4};

Expand All @@ -131,6 +132,7 @@ MicroBitBLEManager *MicroBitBLEManager::manager = NULL; // Singleton reference t
static int m_power = MICROBIT_BLE_DEFAULT_TX_POWER;
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
static uint8_t m_enc_advdata[ BLE_GAP_ADV_SET_DATA_SIZE_MAX];
static uint8_t m_enc_scan_rsp_data[ BLE_GAP_ADV_SET_DATA_SIZE_MAX];

static volatile int m_pending;

Expand All @@ -149,10 +151,21 @@ static void microbit_ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_conte
static void microbit_ble_pm_evt_handler(pm_evt_t const * p_evt);
static void microbit_ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);

#if CONFIG_ENABLED(MICROBIT_BLE_DFU_SERVICE)
static void microbit_dfu_init(void);
#endif

static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist,
uint16_t interval_ms, int timeout_seconds,
ble_advdata_t *p_advdata, ble_advdata_t *p_scndata = nullptr);

static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist, uint16_t interval_ms, int timeout_seconds);

static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist,
uint16_t interval_ms, int timeout_seconds,
ble_advdata_uuid_list_t *services, bool service_list_complete = true,
ble_advdata_manuf_data_t *manufacturer_data = nullptr);

#if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL) || CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_UID)
static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist, uint16_t interval_ms, int timeout_seconds,
uint8_t *frameData, uint16_t frameSize);
Expand Down Expand Up @@ -446,7 +459,7 @@ void MicroBitBLEManager::init( ManagedString deviceName, ManagedString serialNum
const_ascii_to_utf8( &disi.manufact_name_str, MICROBIT_BLE_MANUFACTURER);
const_ascii_to_utf8( &disi.model_num_str, disName.toCharArray());
const_ascii_to_utf8( &disi.serial_num_str, serialNumber.toCharArray());
const_ascii_to_utf8( &disi.hw_rev_str, MICROBIT_BLE_HARDWARE_VERSION);
const_ascii_to_utf8( &disi.hw_rev_str, modelVersion.toCharArray());
const_ascii_to_utf8( &disi.fw_rev_str, MICROBIT_BLE_FIRMWARE_VERSION);
const_ascii_to_utf8( &disi.sw_rev_str, MICROBIT_BLE_SOFTWARE_VERSION);
//ble_dis_sys_id_t * p_sys_id; /**< System ID. */
Expand Down Expand Up @@ -657,6 +670,40 @@ void MicroBitBLEManager::advertise()
}


/**
* When called, the micro:bit will begin advertising for a predefined period,
* MICROBIT_BLE_ADVERTISING_TIMEOUT seconds to bonded devices.
*
* @param serviceUUID The service UUID to insert into advertising data.
*/
void MicroBitBLEManager::advertise(ble_uuid_t *serviceUUIDs, uint16_t service_count, bool service_list_complete, uint16_t manufacturer_id, uint8_t *manufacturer_data, uint16_t manufacturer_data_size)
{
MICROBIT_DEBUG_DMESG( "advertise service");

ble_advdata_uuid_list_t services;
services.p_uuids = serviceUUIDs;
services.uuid_cnt = service_count;

if(manufacturer_data != nullptr)
{
ble_advdata_manuf_data_t manuf_data;
manuf_data.company_identifier = manufacturer_id;
manuf_data.data.p_data = manufacturer_data;
manuf_data.data.size = manufacturer_data_size;

microbit_ble_configureAdvertising(true, true, false, MICROBIT_BLE_ADVERTISING_INTERVAL,
MICROBIT_BLE_ADVERTISING_TIMEOUT, &services, service_list_complete, &manuf_data);
}
else
{
microbit_ble_configureAdvertising(true, true, false, MICROBIT_BLE_ADVERTISING_INTERVAL,
MICROBIT_BLE_ADVERTISING_TIMEOUT, &services, service_list_complete);
}

advertise();
}


/**
* Stops any currently running BLE advertisements
*/
Expand Down Expand Up @@ -1177,7 +1224,7 @@ void MicroBitBLEManager::servicesChanged()
*/
static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist,
uint16_t interval_ms, int timeout_seconds,
ble_advdata_t *p_advdata)
ble_advdata_t *p_advdata, ble_advdata_t *p_scandata)
{
MICROBIT_DEBUG_DMESG( "configureAdvertising connectable %d, discoverable %d", (int) connectable, (int) discoverable);
MICROBIT_DEBUG_DMESG( "whitelist %d, interval_ms %d, timeout_seconds %d", (int) whitelist, (int) interval_ms, (int) timeout_seconds);
Expand All @@ -1198,10 +1245,22 @@ static void microbit_ble_configureAdvertising( bool connectable, bool discoverab

ble_gap_adv_data_t gap_adv_data;
memset( &gap_adv_data, 0, sizeof( gap_adv_data));

// encode advertising data
gap_adv_data.adv_data.p_data = m_enc_advdata;
gap_adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
MICROBIT_BLE_ECHK( ble_advdata_encode( p_advdata, gap_adv_data.adv_data.p_data, &gap_adv_data.adv_data.len));
NRF_LOG_HEXDUMP_INFO( gap_adv_data.adv_data.p_data, gap_adv_data.adv_data.len);

// encode scan response data if supplied
if(p_scandata != nullptr)
{
gap_adv_data.scan_rsp_data.p_data = m_enc_scan_rsp_data;
gap_adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
MICROBIT_BLE_ECHK( ble_advdata_encode( p_scandata, gap_adv_data.scan_rsp_data.p_data, &gap_adv_data.scan_rsp_data.len));
NRF_LOG_HEXDUMP_INFO( gap_adv_data.scan_rsp_data.p_data, gap_adv_data.scan_rsp_data.len);
}

MICROBIT_BLE_ECHK( sd_ble_gap_adv_set_configure( &m_adv_handle, &gap_adv_data, &gap_adv_params));
}

Expand All @@ -1220,6 +1279,36 @@ static void microbit_ble_configureAdvertising( bool connectable, bool discoverab
}


static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist,
uint16_t interval_ms, int timeout_seconds,
ble_advdata_uuid_list_t *services, bool service_list_complete,
ble_advdata_manuf_data_t *manufacturer_data)
{
ble_advdata_t advdata;
memset( &advdata, 0, sizeof( advdata));
advdata.name_type = BLE_ADVDATA_FULL_NAME;
advdata.flags = !whitelist && discoverable
? BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED | BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE
: BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;

ble_advdata_t scandata;
memset( &scandata, 0, sizeof( scandata));
if(service_list_complete)
{
scandata.uuids_complete = *services;
}
else
{
scandata.uuids_more_available = *services;
}
if(manufacturer_data != nullptr) {
scandata.p_manuf_specific_data = manufacturer_data;
}

microbit_ble_configureAdvertising( connectable, discoverable, whitelist, interval_ms, timeout_seconds, &advdata, &scandata);
}


#if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL) || CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_UID)

static void microbit_ble_configureAdvertising( bool connectable, bool discoverable, bool whitelist,
Expand Down
19 changes: 12 additions & 7 deletions source/bluetooth/MicroBitBLEService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ MicroBitBLEService::MicroBitBLEService() :
bs_uuid_type(0),
bs_service_handle(0)
{
bs_service_uuid.type = 0;
bs_service_uuid.uuid = 0;
MicroBitBLEServices::getShared()->AddService( this);
}

Expand All @@ -66,9 +68,10 @@ MicroBitBLEService::~MicroBitBLEService()
void MicroBitBLEService::RegisterBaseUUID( const uint8_t *bytes16UUID)
{
ble_uuid128_t uuid128;
for ( int i = 0; i < 16; i++)
for ( int i = 0; i < 16; i++) {
uuid128.uuid128[i] = bytes16UUID[ 15 - i];

}

MICROBIT_BLE_ECHK( sd_ble_uuid_vs_add( &uuid128, &bs_uuid_type));

MICROBIT_DEBUG_DMESG( "MicroBitBLEService::RegisterBaseUUID bs_uuid_type = %d", (int) bs_uuid_type);
Expand All @@ -77,12 +80,10 @@ void MicroBitBLEService::RegisterBaseUUID( const uint8_t *bytes16UUID)

void MicroBitBLEService::CreateService( uint16_t uuid)
{
ble_uuid_t serviceUUID;
bs_service_uuid.uuid = uuid;
bs_service_uuid.type = bs_uuid_type;

serviceUUID.uuid = uuid;
serviceUUID.type = bs_uuid_type;

MICROBIT_BLE_ECHK( sd_ble_gatts_service_add( BLE_GATTS_SRVC_TYPE_PRIMARY, &serviceUUID, &bs_service_handle));
MICROBIT_BLE_ECHK( sd_ble_gatts_service_add( BLE_GATTS_SRVC_TYPE_PRIMARY, &bs_service_uuid, &bs_service_handle));

MICROBIT_DEBUG_DMESG( "MicroBitBLEService::CreateService( %x) = %d", (unsigned int) uuid, (int) bs_service_handle);
}
Expand Down Expand Up @@ -140,6 +141,10 @@ void MicroBitBLEService::CreateCharacteristic(
(int) charHandles( idx)->sccd);
}

ble_uuid_t MicroBitBLEService::getServiceUUID()
{
return bs_service_uuid;
}

microbit_gaphandle_t MicroBitBLEService::getConnectionHandle()
{
Expand Down