Skip to content

Commit

Permalink
Merge pull request ARMmbed#58 from ARMmbed/powerOff
Browse files Browse the repository at this point in the history
Fixes to the stopCurrentService to sleep in a low power way
  • Loading branch information
pan- committed Feb 23, 2016
2 parents 8675c2f + 4413874 commit 60ccea7
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 40 deletions.
8 changes: 8 additions & 0 deletions BLE_EddystoneService/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,13 @@
},
"mbed": {
"max-filehandles": 4
},
"eddystone": {
"default-device-name": "\"EDDYSTONE CONFIG\"",
"default-url": "\"https://www.mbed.com/\"",
"default-url-frame-interval": 700,
"default-uid-frame-interval": 300,
"default-tlm-frame-interval": 2000,
"default-eddystone-url-config-adv-interval": 1000
}
}
37 changes: 37 additions & 0 deletions BLE_EddystoneService/source/EddystoneService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ EddystoneService::EddystoneError_t EddystoneService::startConfigService(void)
if (operationMode == EDDYSTONE_MODE_BEACON) {
ble.shutdown();
stopBeaconService();
}

if (!ble.hasInitialized()) {
operationMode = EDDYSTONE_MODE_CONFIG;
ble.init(this, &EddystoneService::bleInitComplete);
/* Set the device name once more */
Expand All @@ -152,6 +155,9 @@ EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
ble.shutdown();
/* Free unused memory */
freeConfigCharacteristics();
}

if (!ble.hasInitialized()) {
operationMode = EDDYSTONE_MODE_BEACON;
ble.init(this, &EddystoneService::bleInitComplete);
/* Set the device name once more */
Expand All @@ -165,6 +171,34 @@ EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
return EDDYSTONE_ERROR_NONE;
}

EddystoneService::EddystoneError_t EddystoneService::stopCurrentService(void)
{
switch (operationMode) {
case EDDYSTONE_MODE_NONE:
return EDDYSTONE_ERROR_INVALID_STATE;
case EDDYSTONE_MODE_BEACON:
ble.shutdown();
stopBeaconService();
break;
case EDDYSTONE_MODE_CONFIG:
ble.shutdown();
freeConfigCharacteristics();
break;
default:
/* Some error occurred */
error("Invalid EddystonService mode");
break;
}
operationMode = EDDYSTONE_MODE_NONE;
/* Currently on some platforms, the BLE stack handles power management,
* so we should bring it up again, but not configure it.
* Once the system sleep without BLE initialised is fixed, remove this
*/
ble.init(this, &EddystoneService::bleInitComplete);

return EDDYSTONE_ERROR_NONE;
}

ble_error_t EddystoneService::setCompleteDeviceName(const char *deviceNameIn)
{
/* Make sure the device name is safe */
Expand Down Expand Up @@ -257,6 +291,9 @@ void EddystoneService::bleInitComplete(BLE::InitializationCompleteCallbackContex
case EDDYSTONE_MODE_BEACON:
setupBeaconService();
break;
case EDDYSTONE_MODE_NONE:
/* We don't need to do anything here, but it isn't an error */
break;
default:
/* Some error occurred */
error("Invalid EddystonService mode");
Expand Down
49 changes: 44 additions & 5 deletions BLE_EddystoneService/source/EddystoneService.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@
#include "CircularBuffer.h"
#endif

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL
#define YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL 700
#endif

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL
#define YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL 300
#endif

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL
#define YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL 2000
#endif

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL
#define YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL 1000
#endif

/**
* This class implements the Eddystone-URL Config Service and the Eddystone
* Protocol Specification as defined in the publicly available specification at
Expand All @@ -49,22 +65,22 @@ class EddystoneService
* Default interval for advertising packets for the Eddystone-URL
* Configuration Service.
*/
static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = 1000;
static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL;
/**
* Recommended interval for advertising packets containing Eddystone URL
* frames.
*/
static const uint16_t DEFAULT_URL_FRAME_PERIOD_MSEC = 700;
static const uint16_t DEFAULT_URL_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL;
/**
* Recommended interval for advertising packets containing Eddystone UID
* frames.
*/
static const uint16_t DEFAULT_UID_FRAME_PERIOD_MSEC = 300;
static const uint16_t DEFAULT_UID_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL;
/**
* Recommended interval for advertising packets containing Eddystone TLM
* frames.
*/
static const uint16_t DEFAULT_TLM_FRAME_PERIOD_MSEC = 2000;
static const uint16_t DEFAULT_TLM_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL;

/**
* Enumeration that defines the various operation modes of the
Expand Down Expand Up @@ -215,7 +231,12 @@ class EddystoneService
* - Gap::getMinAdvertisingInterval()
* - Gap::getMaxAdvertisingInterval()
*/
EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL
EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL,
/**
* The result of executing a call when the the EddystoneService is in
* the incorrect operation mode.
*/
EDDYSTONE_ERROR_INVALID_STATE
};

/**
Expand Down Expand Up @@ -405,6 +426,20 @@ class EddystoneService
*/
EddystoneError_t startBeaconService(void);

/**
* Change the EddystoneService OperationMode to EDDYSTONE_MODE_NONE.
*
* @retval EDDYSTONE_ERROR_NONE if the operation succeeded.
* @retval EDDYSTONE_ERROR_INVALID_STATE if the state of the
* EddystoneService already is EDDYSTONE_MODE_NONE.
*
* @note If EddystoneService was previously in EDDYSTONE_MODE_CONFIG or
* EDDYSTONE_MODE_BEACON, then the resources allocated to that mode
* of operation such as memory are freed and the BLE instance
* shutdown before the new operation mode is configured.
*/
EddystoneError_t stopCurrentService(void);

/**
* Set the Comple Local Name for the BLE device. This not only updates
* the value of the Device Name Characteristic, it also updates the scan
Expand Down Expand Up @@ -553,6 +588,10 @@ class EddystoneService
/**
* Free the resources acquired by a call to setupBeaconService() and
* cancel all pending callbacks that operate the radio and frame queue.
*
* @note This call will not modify the current state of the BLE device.
* EddystoneService::stopBeaconService should only be called after
* a call to BLE::shutdown().
*/
void stopBeaconService(void);

Expand Down
12 changes: 10 additions & 2 deletions BLE_EddystoneService/source/EddystoneTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
#include <stdint.h>
#include <stddef.h>

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME
#define YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME "EDDYSTONE CONFIG"
#endif

#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_URL
#define YOTTA_CFG_EDDYSTONE_DEFAULT_URL "https://www.mbed.com/"
#endif

/**
* Macro to expand a 16-bit Eddystone UUID to 128-bit UUID.
*/
Expand Down Expand Up @@ -86,12 +94,12 @@ const uint8_t UUID_RESET_CHAR[] = UUID_URL_BEACON(0x20, 0x89);
/**
* Default name for the BLE Device Name characteristic.
*/
const char DEFAULT_DEVICE_NAME[] = "EDDYSTONE CONFIG";
const char DEFAULT_DEVICE_NAME[] = YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME;

/**
* Default URL used by EddystoneService.
*/
const char DEFAULT_URL[] = "http://www.mbed.com/";
const char DEFAULT_URL[] = YOTTA_CFG_EDDYSTONE_DEFAULT_URL;

/**
* Enumeration that defines the Eddystone power levels for the Eddystone-URL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2015 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "ConfigParamsPersistence.h"

#ifndef TARGET_NRF51822 /* Persistent storage supported on nrf51 platforms */
/**
* When not using an nRF51-based target then persistent storage is not available.
*/
#warning "EddystoneService is not configured to store configuration data in non-volatile memory"

bool loadEddystoneServiceConfigParams(EddystoneService::EddystoneParams_t *paramsP)
{
/* Avoid compiler warnings */
(void) paramsP;

/*
* Do nothing and let the main program set Eddystone params to
* defaults
*/
return false;
}

void saveEddystoneServiceConfigParams(const EddystoneService::EddystoneParams_t *paramsP)
{
/* Avoid compiler warnings */
(void) paramsP;

/* Do nothing... */
return;
}
#endif /* #ifdef TARGET_NRF51822 */
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*/

#ifdef TARGET_NRF51822 /* Persistent storage supported on nrf51 platforms */

#ifndef __BLE_CONFIG_PARAMS_PERSISTENCE_H__
#define __BLE_CONFIG_PARAMS_PERSISTENCE_H__

Expand Down Expand Up @@ -53,5 +51,3 @@ bool loadEddystoneServiceConfigParams(EddystoneService::EddystoneParams_t *param
void saveEddystoneServiceConfigParams(const EddystoneService::EddystoneParams_t *paramsP);

#endif /* #ifndef __BLE_CONFIG_PARAMS_PERSISTENCE_H__*/

#endif /* #ifdef TARGET_NRF51822 */
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern "C" {
}

#include "nrf_error.h"
#include "ConfigParamsPersistence.h"
#include "../../EddystoneService.h"

/**
* Nordic specific structure used to store params persistently.
Expand Down
33 changes: 5 additions & 28 deletions BLE_EddystoneService/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
#include "ble/BLE.h"
#include "EddystoneService.h"

#ifdef TARGET_NRF51822
#include "nrfPersistentStorageHelper/ConfigParamsPersistence.h"
#endif
#include "PersistentStorageHelper/ConfigParamsPersistence.h"

EddystoneService *eddyServicePtr;

Expand All @@ -34,20 +32,11 @@ static const UIDInstanceID_t uidInstanceID = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x
/* Default version in TLM frame */
static const uint8_t tlmVersion = 0x00;

/* Default configuration advertising interval */
static const uint32_t advConfigInterval = 500;

/* Default URL */
static const char defaultUrl[] = "http://mbed.org";

/* Values for ADV packets related to firmware levels, calibrated based on measured values at 1m */
static const PowerLevels_t defaultAdvPowerLevels = {-47, -33, -21, -13};
/* Values for radio power levels, provided by manufacturer. */
static const PowerLevels_t radioPowerLevels = {-30, -16, -4, 4};

/* Custom device name for this application */
static const char deviceName[] = "mbed Eddystone";

DigitalOut led(LED1, 1);

/**
Expand All @@ -68,11 +57,9 @@ static void timeout(void)
state = BLE::Instance().gap().getState();
if (!state.connected) { /* don't switch if we're in a connected state. */
eddyServicePtr->startBeaconService();
#ifdef TARGET_NRF51822
EddystoneService::EddystoneParams_t params;
eddyServicePtr->getEddystoneParams(params);
saveEddystoneServiceConfigParams(&params);
#endif
} else {
minar::Scheduler::postCallback(timeout).delay(minar::milliseconds(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000));
}
Expand All @@ -92,10 +79,11 @@ static void onBleInitError(BLE::InitializationCompleteCallbackContext* initConte
static void initializeEddystoneToDefaults(BLE &ble)
{
/* Set everything to defaults */
eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels, advConfigInterval);
eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels);

/* Set default URL, UID and TLM frame data if not initialized through the config service */
eddyServicePtr->setURLData(defaultUrl);
const char* url = YOTTA_CFG_EDDYSTONE_DEFAULT_URL;
eddyServicePtr->setURLData(url);
eddyServicePtr->setUIDData(uidNamespaceID, uidInstanceID);
eddyServicePtr->setTLMData(tlmVersion);
}
Expand All @@ -112,23 +100,12 @@ static void bleInitComplete(BLE::InitializationCompleteCallbackContext* initCont

ble.gap().onDisconnection(disconnectionCallback);

#ifdef TARGET_NRF51822
EddystoneService::EddystoneParams_t params;
if (loadEddystoneServiceConfigParams(&params)) {
eddyServicePtr = new EddystoneService(ble, params, radioPowerLevels, advConfigInterval);
eddyServicePtr = new EddystoneService(ble, params, radioPowerLevels);
} else {
initializeEddystoneToDefaults(ble);
}
#else
#warning "EddystoneService is not configured to store configuration data in non-volatile memory"
initializeEddystoneToDefaults(ble);
#endif

/*
* Set the custom device name. The device name is not stored in persistent
* storage, so we need to set it manually every time the device is reset
*/
eddyServicePtr->setCompleteDeviceName(deviceName);

/* Start Eddystone in config mode */
eddyServicePtr->startConfigService();
Expand Down

0 comments on commit 60ccea7

Please sign in to comment.