Cleanup for GAP publication (iBeacon working)

master
ktownsend 2013-12-18 12:07:38 +00:00
parent 66da5fce1b
commit 87ea616662
2 changed files with 31 additions and 148 deletions

View File

@ -1,9 +1,6 @@
#include "nrf51822.h"
#include "mbed.h"
/* Enables debug output over USB CDC at 9600 bps */
#define NRF51822_DEBUG_MODE (1)
/**************************************************************************/
/*!
@brief UART callback function
@ -14,11 +11,7 @@ void nRF51822::uartCallback(void)
/* ToDo: Check responses and set a flag for success/error/etc. */
/* Read serial to clear the RX interrupt */
#if NRF51822_DEBUG_MODE
printf("%c", uart.getc());
#else
uart.getc();
#endif
}
/**************************************************************************/
@ -92,39 +85,35 @@ ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisi
uint8_t len = 0;
uint8_t *buffer;
#if NRF51822_DEBUG_MODE
printf("%-40s", "Configuring Advertising");
#endif
/* Make sure we support the advertising type */
if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED)
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_NOT_IMPLEMENTED);
printf("--> ADV_CONNECTABLE_DIRECTED not supported\r\n");
#endif
return BLE_ERROR_NOT_IMPLEMENTED;
}
/* Check interval range */
if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
(params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED)
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
printf("--> Advertising interval out of range\r\n");
#endif
return BLE_ERROR_PARAM_OUT_OF_RANGE;
/* Min delay is slightly longer for unconnectable devices */
if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
(params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
{
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
}
else
{
if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
(params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
{
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
}
/* Check timeout is zero for Connectable Directed */
if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
(params.getTimeout() != 0))
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
printf("--> Timeout must be 0 with ADV_CONNECTABLE_DIRECTED\r\n");
#endif
/* Timeout must be 0 with this type, although we'll never get here */
/* since this isn't implemented yet anyway */
return BLE_ERROR_PARAM_OUT_OF_RANGE;
@ -134,20 +123,12 @@ ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisi
if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
(params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX))
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
printf("--> Timeout out of range\r\n");
#endif
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
/* Make sure we don't exceed the advertising payload length */
if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW);
printf("--> Advertising payload > 31 bytes\r\n");
#endif
return BLE_ERROR_BUFFER_OVERFLOW;
}
@ -156,10 +137,6 @@ ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisi
{
if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
{
#if NRF51822_DEBUG_MODE
printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW);
printf("--> Scan response payload > 31 bytes\r\n");
#endif
return BLE_ERROR_BUFFER_OVERFLOW;
}
}
@ -227,9 +204,6 @@ ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisi
wait(0.1);
}
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -251,10 +225,6 @@ ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisi
/**************************************************************************/
ble_error_t nRF51822::addService(GattService & service)
{
#if NRF51822_DEBUG_MODE
printf("%-40s", "Adding a service");
#endif
/* ToDo: Make sure we don't overflow the array, etc. */
/* ToDo: Make sure this service UUID doesn't already exist (?) */
/* ToDo: Basic validation */
@ -313,9 +283,6 @@ ble_error_t nRF51822::addService(GattService & service)
service.handle = serviceCount;
serviceCount++;
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -348,15 +315,8 @@ ble_error_t nRF51822::addService(GattService & service)
/**************************************************************************/
ble_error_t nRF51822::readCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
{
#if NRF51822_DEBUG_MODE
printf("Reading characteristic (handle = %d) ", characteristic.handle);
#endif
/* ToDo */
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -389,10 +349,6 @@ ble_error_t nRF51822::readCharacteristic(GattService &service, GattCharacteristi
/**************************************************************************/
ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
{
#if NRF51822_DEBUG_MODE
printf("Writing characteristic (handle = %d) ", characteristic.handle);
#endif
/* Command ID = 0x0006, Payload = Service ID, Characteristic ID, Value */
uart.printf("10 06 00 %02X %02X %02X", len + 2, characteristic.handle, service.handle);
for (uint16_t i = 0; i<len; i++)
@ -404,9 +360,6 @@ ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacterist
/* ToDo: Check response */
wait(0.1);
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -431,19 +384,12 @@ ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacterist
/**************************************************************************/
ble_error_t nRF51822::start(void)
{
#if NRF51822_DEBUG_MODE
printf("%-40s", "Starting the radio");
#endif
/* Command ID = 0x0003, No payload */
uart.printf("10 03 00 00\r\n");
/* ToDo: Check response */
wait(0.5);
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -465,19 +411,12 @@ ble_error_t nRF51822::start(void)
/**************************************************************************/
ble_error_t nRF51822::stop(void)
{
#if NRF51822_DEBUG_MODE
printf("%-40s", "Stopping the radio");
#endif
/* Command ID = 0x0004, No payload */
uart.printf("10 04 00 00\r\n");
/* ToDo: Check response */
wait(0.1);
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}
@ -500,10 +439,6 @@ ble_error_t nRF51822::stop(void)
/**************************************************************************/
ble_error_t nRF51822::reset(void)
{
#if NRF51822_DEBUG_MODE
printf("%-40s", "Resetting the radio");
#endif
/* Command ID = 0x0005, No payload */
uart.printf("10 05 00 00\r\n");
@ -513,8 +448,5 @@ ble_error_t nRF51822::reset(void)
/* Wait for the radio to come back up */
wait(1);
#if NRF51822_DEBUG_MODE
printf("[OK]\r\n");
#endif
return BLE_ERROR_NONE;
}

View File

@ -10,27 +10,12 @@ DigitalOut myled ( LED1 );
/* Radio HW abstraction layer */
nRF51822 radio;
/* Battery Level Service */
/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml */
GattService battService ( 0x180F );
GattCharacteristic battLevel ( 0x2A19, 1, 1, BLE_GATT_CHAR_PROPERTIES_NOTIFY | BLE_GATT_CHAR_PROPERTIES_READ );
/* Heart Rate Monitor Service */
/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */
GattService hrmService ( 0x180D );
GattCharacteristic hrmRate ( 0x2A37, 2, 3, BLE_GATT_CHAR_PROPERTIES_NOTIFY );
GattCharacteristic hrmLocation ( 0x2A39, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ );
/* Health Thermometer Service */
/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml */
GattService thermService ( 0x1809 );
GattCharacteristic thermTemp ( 0x2A1C, 5, 13, BLE_GATT_CHAR_PROPERTIES_INDICATE );
GattCharacteristic thermType ( 0x2A1D, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ );
GattCharacteristic thermInterval ( 0x2A21, 2, 2, BLE_GATT_CHAR_PROPERTIES_READ );
/* Notify = device (server) sends data when it changes */
/* Indicate = device (server) sends data when it changes and client confirms reception */
/* GAP Advertising Example (iBeacon) */
GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED );
GapAdvertisingData advData;
@ -51,60 +36,29 @@ void startBeacon(void)
error = radio.start();
}
int main()
void startHRM(void)
{
wait(2);
startBeacon();
while(1);
/* Add the battery level characteristic to the battery service */
/* Note: This will also update the characteristic's .index field */
/* so that we know where it's stored in the BLEService.characteristics */
/* array. */
battService.addCharacteristic(battLevel);
uint8_t hrmCounter = 100;
/* Add the heart rate and sensor location chars to the HRM service */
hrmService.addCharacteristic(hrmRate);
hrmService.addCharacteristic(hrmLocation);
/* Add the Health Thermometer server characteristics */
thermService.addCharacteristic(thermTemp);
thermService.addCharacteristic(thermType);
thermService.addCharacteristic(thermInterval);
/* Reset the BLE hardware to make sure we get a clean start */
wait(2);
radio.reset();
/* Add the services to the radio HAL */
radio.addService(battService);
radio.addService(hrmService);
radio.addService(thermService);
/* Start the services so that we can start pushing data out */
radio.start();
/* Set the heart rate monitor location (one time only) */
/* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */
uint8_t location = 0x01; /* Chest */
radio.writeCharacteristic(hrmService, hrmLocation, (uint8_t*)&location, sizeof(location));
/* Update the battery level */
/* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */
uint8_t batt = 72; /* Percentage (0..100) */
radio.writeCharacteristic(battService, battLevel, (uint8_t*)&batt, sizeof(batt));
/* Update the fixed health thermometer characteristics */
/* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */
uint8_t thermLocation = 6; /* Location = mouth */
radio.writeCharacteristic(thermService, thermType, (uint8_t*)&thermLocation, sizeof(thermLocation));
/* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.measurement_interval.xml */
uint16_t thermDelay = 5;
radio.writeCharacteristic(thermService, thermInterval, (uint8_t*)&thermDelay, sizeof(thermDelay));
/* Blinky + value updates */
uint8_t hrmCounter = 100;
while(1)
{
myled = 1;
@ -119,20 +73,17 @@ int main()
if (hrmCounter == 175) hrmCounter = 100;
uint8_t bpm[2] = { 0x00, hrmCounter };
radio.writeCharacteristic(hrmService, hrmRate, bpm, 2);
/* Update the Health Thermometer measurement */
// NOTE: This is an IEEE-11073 32-bit float NOT a IEEE-754 float (standard single precision float type) !!!
// See: Section 2.2 of https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961
// Example:
// Consider a temperature measurement of 36.4 degrees Celsius with precision of 0.1 degrees Celsius.
// The FLOAT-Type representation is a 32-bit value consisting of an exponent of an 8-bit signed integer
// followed by a mantissa of a 24-bit signed integer; here, the exponent is -1 (0xFF) and the mantissa
// is 364 (0x00016C). Therefore, the FLOAT-Type representation of 36.4 is 0xFF00016C.
uint8_t temperature[5] = { 0x00, 0x00, 0x00, 0x00, 0xFF };
// Use the hrm counter to provide a shifting temperature value (175 = 17.5C, etc.)
memcpy (temperature+1, &hrmCounter, 1);
radio.writeCharacteristic(thermService, thermTemp, temperature, 5);
}
}
int main()
{
/* Give the radio some time to boot up and settle */
wait(2);
/* Only use one of these two options! */
startBeacon();
// startHRM();
while(1);
}