Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51822
Source/BLE_Stuff.cpp
- Committer:
- sgetz7908
- Date:
- 2019-03-21
- Revision:
- 24:761c30334cf4
- Parent:
- 23:7ca590427f0e
- Child:
- 27:bb7247a1704e
File content as of revision 24:761c30334cf4:
/// @file BLE_Stuff.cpp
#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/services/UARTService.h"
#include "BLE_Stuff.h"
#include "infoService.h"
#include "hw.h"
#include "log.h"
#include "main.h"
#include "log.h"
#include "nrf_soc.h"
extern EventQueue eventQueue; //(/* event count */ 16 * EVENTS_EVENT_SIZE);
UARTService *uartServicePtr = NULL;
LowPowerTimeout bleInactivity_timeout;
int adv_timeout_ID = 0;
int adv_state = false;
char dev_name[15] = "";
volatile int batt_voltage = 0; // actual battery voltage * 100
bool m_isConnected = false;
void process_cmd(char * cmd);
/// Called by bleInactivity_timeout
void disconnect(void)
{
bleInactivity_timeout.detach();
#if UART_DEBUGGING==0
BLE &ble = BLE::Instance();
ble.gap().disconnect(Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF); // force disconnect
#endif
}
void reset_ble_activity_timer(void)
{
bleInactivity_timeout.detach();
bleInactivity_timeout.attach(&disconnect, BLE_INACTIVITY_TIMEOUT);
}
/// Called when the Bluetooth connection is disconnected.
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
m_isConnected = false;
bleInactivity_timeout.detach();
BLE &ble = BLE::Instance();
ble.gap().setAdvertisingInterval(ADV_INTERVAL);
if(adv_state) ble.gap().startAdvertising();
}
void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
m_isConnected = true;
BLE &ble = BLE::Instance();
ble.gap().setAdvertisingInterval(CONN_INTERVAL);
reset_ble_activity_timer();
}
bool isConnected(void)
{
return m_isConnected;
}
/// Called to write a string to the Bluetooth UART.
// used for writting to the BLE UART
void BLE_UART_xmit(const char * str)
{
if (uartServicePtr != NULL) {
uartServicePtr->writeString(str);
}
}
void BLE_UART_xmit(int i)
{
BLE_UART_xmit(uli2a(i));
}
char cmd_str[21];
/// Called when data is rcv'd from connected BLE device
void onDataWritten(const GattWriteCallbackParams *params)
{
if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
uint16_t bytesRead = params->len;
strncpy(cmd_str, (const char *)params->data, bytesRead);
cmd_str[bytesRead] = 0; // add end of string char
// Start process: process_cmd(cmd_str) as regular non-irq routine
eventQueue.call(process_cmd, cmd_str);
// the dispatch method executes events
//queue.dispatch();
//ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); // send back whatever is sent to us
reset_ble_activity_timer();
}
}
/// Turn on or off advertising
// When turned on, it will only advertise for a limited time, or until turned off.
void set_radio(int state)
{
BLE &ble = BLE::Instance();
adv_state = state;
if(state) {
//adv_state = true;
ble.gap().setAdvertisingInterval(ADV_INTERVAL);
ble.gap().startAdvertising();
} else {
//adv_state = false;
ble.gap().stopAdvertising();
disconnect();
}
}
#if 0
void stop_radio_and_wait(void)
{
set_radio(false);
// If radio is active, wait for it to become inactive.
//wait(0.5);
while (isConnected())// || isRadioActive())
{
// Do nothing (just wait for radio to become inactive).
sd_app_evt_wait();
}
}
#endif
ble_init_status_t ble_init_status = BLE_INIT_IN_PROGRESS;
/// Called to setup the Bluetooth link.
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
BLE& ble = params->ble;
ble_error_t error = params->error;
if (error != BLE_ERROR_NONE) {
ble_init_status = BLE_INIT_ERROR;
return;
}
/* Ensure that it is the default instance of BLE */
if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
return;
}
ble.gap().onDisconnection(disconnectionCallback);
ble.gap().onConnection(connectionCallback);
ble.gattServer().onDataWritten(onDataWritten);
//ble.gattServer().onDataRead( dataReadCallback ); //const DataReadCallback_t & callback)
//ble.onDataRead( dataReadCallback);
strcpy(dev_name, DEV_NAME);
strcat(dev_name, char2hex(NRF_FICR->DEVICEADDR[0] & 0xff));
int len = strlen(dev_name);
ble.gap().setDeviceName((std::uint8_t *)dev_name);
/* Setup primary service */
uartServicePtr = new UARTService(ble);
/* setup advertising */
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
(const uint8_t *)dev_name, len);
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
ble.gap().setAdvertisingInterval(ADV_INTERVAL);
ble.gap().setAdvertisingTimeout(BLE_ADVERTISING_DURATION);
ble.gap().setTxPower(-20); // -30, -20, -16, -12, -8, -4, 0, and 4 dBm
ble_init_status = BLE_INIT_OK;
set_radio(true);
}
/// Process BLE Events
void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
BLE &ble = BLE::Instance();
eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
}
/// Initialize the BLE Stack
// Returns 0 if OK
ble_init_status_t Init_BLE_Stuff(void)
{
ble_init_status = BLE_INIT_IN_PROGRESS;
BLE &ble = BLE::Instance();
ble.onEventsToProcess(scheduleBleEventsProcessing);
ble.init(bleInitComplete);
// Wait for initialization to complete. This is necessary because the
// BLE object is used after this.
while(ble_init_status == BLE_INIT_IN_PROGRESS) { wait(0.05);}
// set up BLE Information services in infoService.cpp
//ble.gattServer().addService(infoServicePtr);
return ble_init_status;
}