Skip to content

Commit 60ccea7

Browse files
committed
Merge pull request ARMmbed#58 from ARMmbed/powerOff
Fixes to the stopCurrentService to sleep in a low power way
2 parents 8675c2f + 4413874 commit 60ccea7

File tree

8 files changed

+150
-40
lines changed

8 files changed

+150
-40
lines changed

BLE_EddystoneService/config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,13 @@
44
},
55
"mbed": {
66
"max-filehandles": 4
7+
},
8+
"eddystone": {
9+
"default-device-name": "\"EDDYSTONE CONFIG\"",
10+
"default-url": "\"https://www.mbed.com/\"",
11+
"default-url-frame-interval": 700,
12+
"default-uid-frame-interval": 300,
13+
"default-tlm-frame-interval": 2000,
14+
"default-eddystone-url-config-adv-interval": 1000
715
}
816
}

BLE_EddystoneService/source/EddystoneService.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ EddystoneService::EddystoneError_t EddystoneService::startConfigService(void)
126126
if (operationMode == EDDYSTONE_MODE_BEACON) {
127127
ble.shutdown();
128128
stopBeaconService();
129+
}
130+
131+
if (!ble.hasInitialized()) {
129132
operationMode = EDDYSTONE_MODE_CONFIG;
130133
ble.init(this, &EddystoneService::bleInitComplete);
131134
/* Set the device name once more */
@@ -152,6 +155,9 @@ EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
152155
ble.shutdown();
153156
/* Free unused memory */
154157
freeConfigCharacteristics();
158+
}
159+
160+
if (!ble.hasInitialized()) {
155161
operationMode = EDDYSTONE_MODE_BEACON;
156162
ble.init(this, &EddystoneService::bleInitComplete);
157163
/* Set the device name once more */
@@ -165,6 +171,34 @@ EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
165171
return EDDYSTONE_ERROR_NONE;
166172
}
167173

174+
EddystoneService::EddystoneError_t EddystoneService::stopCurrentService(void)
175+
{
176+
switch (operationMode) {
177+
case EDDYSTONE_MODE_NONE:
178+
return EDDYSTONE_ERROR_INVALID_STATE;
179+
case EDDYSTONE_MODE_BEACON:
180+
ble.shutdown();
181+
stopBeaconService();
182+
break;
183+
case EDDYSTONE_MODE_CONFIG:
184+
ble.shutdown();
185+
freeConfigCharacteristics();
186+
break;
187+
default:
188+
/* Some error occurred */
189+
error("Invalid EddystonService mode");
190+
break;
191+
}
192+
operationMode = EDDYSTONE_MODE_NONE;
193+
/* Currently on some platforms, the BLE stack handles power management,
194+
* so we should bring it up again, but not configure it.
195+
* Once the system sleep without BLE initialised is fixed, remove this
196+
*/
197+
ble.init(this, &EddystoneService::bleInitComplete);
198+
199+
return EDDYSTONE_ERROR_NONE;
200+
}
201+
168202
ble_error_t EddystoneService::setCompleteDeviceName(const char *deviceNameIn)
169203
{
170204
/* Make sure the device name is safe */
@@ -257,6 +291,9 @@ void EddystoneService::bleInitComplete(BLE::InitializationCompleteCallbackContex
257291
case EDDYSTONE_MODE_BEACON:
258292
setupBeaconService();
259293
break;
294+
case EDDYSTONE_MODE_NONE:
295+
/* We don't need to do anything here, but it isn't an error */
296+
break;
260297
default:
261298
/* Some error occurred */
262299
error("Invalid EddystonService mode");

BLE_EddystoneService/source/EddystoneService.h

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@
3131
#include "CircularBuffer.h"
3232
#endif
3333

34+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL
35+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL 700
36+
#endif
37+
38+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL
39+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL 300
40+
#endif
41+
42+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL
43+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL 2000
44+
#endif
45+
46+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL
47+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL 1000
48+
#endif
49+
3450
/**
3551
* This class implements the Eddystone-URL Config Service and the Eddystone
3652
* Protocol Specification as defined in the publicly available specification at
@@ -49,22 +65,22 @@ class EddystoneService
4965
* Default interval for advertising packets for the Eddystone-URL
5066
* Configuration Service.
5167
*/
52-
static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = 1000;
68+
static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_EDDYSTONE_URL_CONFIG_ADV_INTERVAL;
5369
/**
5470
* Recommended interval for advertising packets containing Eddystone URL
5571
* frames.
5672
*/
57-
static const uint16_t DEFAULT_URL_FRAME_PERIOD_MSEC = 700;
73+
static const uint16_t DEFAULT_URL_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_URL_FRAME_INTERVAL;
5874
/**
5975
* Recommended interval for advertising packets containing Eddystone UID
6076
* frames.
6177
*/
62-
static const uint16_t DEFAULT_UID_FRAME_PERIOD_MSEC = 300;
78+
static const uint16_t DEFAULT_UID_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_UID_FRAME_INTERVAL;
6379
/**
6480
* Recommended interval for advertising packets containing Eddystone TLM
6581
* frames.
6682
*/
67-
static const uint16_t DEFAULT_TLM_FRAME_PERIOD_MSEC = 2000;
83+
static const uint16_t DEFAULT_TLM_FRAME_PERIOD_MSEC = YOTTA_CFG_EDDYSTONE_DEFAULT_TLM_FRAME_INTERVAL;
6884

6985
/**
7086
* Enumeration that defines the various operation modes of the
@@ -215,7 +231,12 @@ class EddystoneService
215231
* - Gap::getMinAdvertisingInterval()
216232
* - Gap::getMaxAdvertisingInterval()
217233
*/
218-
EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL
234+
EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL,
235+
/**
236+
* The result of executing a call when the the EddystoneService is in
237+
* the incorrect operation mode.
238+
*/
239+
EDDYSTONE_ERROR_INVALID_STATE
219240
};
220241

221242
/**
@@ -405,6 +426,20 @@ class EddystoneService
405426
*/
406427
EddystoneError_t startBeaconService(void);
407428

429+
/**
430+
* Change the EddystoneService OperationMode to EDDYSTONE_MODE_NONE.
431+
*
432+
* @retval EDDYSTONE_ERROR_NONE if the operation succeeded.
433+
* @retval EDDYSTONE_ERROR_INVALID_STATE if the state of the
434+
* EddystoneService already is EDDYSTONE_MODE_NONE.
435+
*
436+
* @note If EddystoneService was previously in EDDYSTONE_MODE_CONFIG or
437+
* EDDYSTONE_MODE_BEACON, then the resources allocated to that mode
438+
* of operation such as memory are freed and the BLE instance
439+
* shutdown before the new operation mode is configured.
440+
*/
441+
EddystoneError_t stopCurrentService(void);
442+
408443
/**
409444
* Set the Comple Local Name for the BLE device. This not only updates
410445
* the value of the Device Name Characteristic, it also updates the scan
@@ -553,6 +588,10 @@ class EddystoneService
553588
/**
554589
* Free the resources acquired by a call to setupBeaconService() and
555590
* cancel all pending callbacks that operate the radio and frame queue.
591+
*
592+
* @note This call will not modify the current state of the BLE device.
593+
* EddystoneService::stopBeaconService should only be called after
594+
* a call to BLE::shutdown().
556595
*/
557596
void stopBeaconService(void);
558597

BLE_EddystoneService/source/EddystoneTypes.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
#include <stdint.h>
2121
#include <stddef.h>
2222

23+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME
24+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME "EDDYSTONE CONFIG"
25+
#endif
26+
27+
#ifndef YOTTA_CFG_EDDYSTONE_DEFAULT_URL
28+
#define YOTTA_CFG_EDDYSTONE_DEFAULT_URL "https://www.mbed.com/"
29+
#endif
30+
2331
/**
2432
* Macro to expand a 16-bit Eddystone UUID to 128-bit UUID.
2533
*/
@@ -86,12 +94,12 @@ const uint8_t UUID_RESET_CHAR[] = UUID_URL_BEACON(0x20, 0x89);
8694
/**
8795
* Default name for the BLE Device Name characteristic.
8896
*/
89-
const char DEFAULT_DEVICE_NAME[] = "EDDYSTONE CONFIG";
97+
const char DEFAULT_DEVICE_NAME[] = YOTTA_CFG_EDDYSTONE_DEFAULT_DEVICE_NAME;
9098

9199
/**
92100
* Default URL used by EddystoneService.
93101
*/
94-
const char DEFAULT_URL[] = "http://www.mbed.com/";
102+
const char DEFAULT_URL[] = YOTTA_CFG_EDDYSTONE_DEFAULT_URL;
95103

96104
/**
97105
* Enumeration that defines the Eddystone power levels for the Eddystone-URL
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2015 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "ConfigParamsPersistence.h"
18+
19+
#ifndef TARGET_NRF51822 /* Persistent storage supported on nrf51 platforms */
20+
/**
21+
* When not using an nRF51-based target then persistent storage is not available.
22+
*/
23+
#warning "EddystoneService is not configured to store configuration data in non-volatile memory"
24+
25+
bool loadEddystoneServiceConfigParams(EddystoneService::EddystoneParams_t *paramsP)
26+
{
27+
/* Avoid compiler warnings */
28+
(void) paramsP;
29+
30+
/*
31+
* Do nothing and let the main program set Eddystone params to
32+
* defaults
33+
*/
34+
return false;
35+
}
36+
37+
void saveEddystoneServiceConfigParams(const EddystoneService::EddystoneParams_t *paramsP)
38+
{
39+
/* Avoid compiler warnings */
40+
(void) paramsP;
41+
42+
/* Do nothing... */
43+
return;
44+
}
45+
#endif /* #ifdef TARGET_NRF51822 */

BLE_EddystoneService/source/nrfPersistentStorageHelper/ConfigParamsPersistence.h renamed to BLE_EddystoneService/source/PersistentStorageHelper/ConfigParamsPersistence.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
#ifdef TARGET_NRF51822 /* Persistent storage supported on nrf51 platforms */
18-
1917
#ifndef __BLE_CONFIG_PARAMS_PERSISTENCE_H__
2018
#define __BLE_CONFIG_PARAMS_PERSISTENCE_H__
2119

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

5553
#endif /* #ifndef __BLE_CONFIG_PARAMS_PERSISTENCE_H__*/
56-
57-
#endif /* #ifdef TARGET_NRF51822 */

BLE_EddystoneService/source/nrfPersistentStorageHelper/nrfConfigParamsPersistence.cpp renamed to BLE_EddystoneService/source/PersistentStorageHelper/nrfPersistentStorageHelper/nrfConfigParamsPersistence.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extern "C" {
2121
}
2222

2323
#include "nrf_error.h"
24-
#include "ConfigParamsPersistence.h"
24+
#include "../../EddystoneService.h"
2525

2626
/**
2727
* Nordic specific structure used to store params persistently.

BLE_EddystoneService/source/main.cpp

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
#include "ble/BLE.h"
1919
#include "EddystoneService.h"
2020

21-
#ifdef TARGET_NRF51822
22-
#include "nrfPersistentStorageHelper/ConfigParamsPersistence.h"
23-
#endif
21+
#include "PersistentStorageHelper/ConfigParamsPersistence.h"
2422

2523
EddystoneService *eddyServicePtr;
2624

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

37-
/* Default configuration advertising interval */
38-
static const uint32_t advConfigInterval = 500;
39-
40-
/* Default URL */
41-
static const char defaultUrl[] = "http://mbed.org";
42-
4335
/* Values for ADV packets related to firmware levels, calibrated based on measured values at 1m */
4436
static const PowerLevels_t defaultAdvPowerLevels = {-47, -33, -21, -13};
4537
/* Values for radio power levels, provided by manufacturer. */
4638
static const PowerLevels_t radioPowerLevels = {-30, -16, -4, 4};
4739

48-
/* Custom device name for this application */
49-
static const char deviceName[] = "mbed Eddystone";
50-
5140
DigitalOut led(LED1, 1);
5241

5342
/**
@@ -68,11 +57,9 @@ static void timeout(void)
6857
state = BLE::Instance().gap().getState();
6958
if (!state.connected) { /* don't switch if we're in a connected state. */
7059
eddyServicePtr->startBeaconService();
71-
#ifdef TARGET_NRF51822
7260
EddystoneService::EddystoneParams_t params;
7361
eddyServicePtr->getEddystoneParams(params);
7462
saveEddystoneServiceConfigParams(&params);
75-
#endif
7663
} else {
7764
minar::Scheduler::postCallback(timeout).delay(minar::milliseconds(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000));
7865
}
@@ -92,10 +79,11 @@ static void onBleInitError(BLE::InitializationCompleteCallbackContext* initConte
9279
static void initializeEddystoneToDefaults(BLE &ble)
9380
{
9481
/* Set everything to defaults */
95-
eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels, advConfigInterval);
82+
eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels);
9683

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

113101
ble.gap().onDisconnection(disconnectionCallback);
114102

115-
#ifdef TARGET_NRF51822
116103
EddystoneService::EddystoneParams_t params;
117104
if (loadEddystoneServiceConfigParams(&params)) {
118-
eddyServicePtr = new EddystoneService(ble, params, radioPowerLevels, advConfigInterval);
105+
eddyServicePtr = new EddystoneService(ble, params, radioPowerLevels);
119106
} else {
120107
initializeEddystoneToDefaults(ble);
121108
}
122-
#else
123-
#warning "EddystoneService is not configured to store configuration data in non-volatile memory"
124-
initializeEddystoneToDefaults(ble);
125-
#endif
126-
127-
/*
128-
* Set the custom device name. The device name is not stored in persistent
129-
* storage, so we need to set it manually every time the device is reset
130-
*/
131-
eddyServicePtr->setCompleteDeviceName(deviceName);
132109

133110
/* Start Eddystone in config mode */
134111
eddyServicePtr->startConfigService();

0 commit comments

Comments
 (0)