Cleanup for GAP publication (iBeacon working)
parent
66da5fce1b
commit
87ea616662
|
@ -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;
|
||||
}
|
||||
|
|
81
main.cpp
81
main.cpp
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue