Changed to work with St Board

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_URIBeacon by Bluetooth Low Energy

Revision:
16:1daa78939a3b
Parent:
14:868a1207022d
Child:
17:e2c0a1696e39
--- a/main.cpp	Fri Mar 06 09:23:50 2015 +0000
+++ b/main.cpp	Mon Mar 09 16:35:03 2015 +0000
@@ -14,244 +14,49 @@
  * limitations under the License.
  */
 
-#include <stdint.h>
-#include <stddef.h>
-#include <nrf_error.h>
 #include "mbed.h"
 #include "BLEDevice.h"
 #include "URIBeaconConfigService.h"
 #include "DFUService.h"
-#include "pstorage.h"
 #include "DeviceInformationService.h"
-
-// Struct to hold persistent data across power cycles
-struct PersistentData_t {
-    uint32_t magic;
-    URIBeaconConfigService::Params_t params;
-    uint8_t pad[4];
-} __attribute__ ((aligned (4)));
-
-static const int PERSISTENT_DATA_ALIGNED_SIZE = sizeof(PersistentData_t);
-// Seconds after power-on that config service is available.
-static const int ADVERTISING_TIMEOUT_SECONDS = 60;
-// Advertising interval for config service.
-static const int ADVERTISING_INTERVAL_MSEC = 1000;
-// Maximum size of service data in ADV packets
-static const int SERVICE_DATA_MAX = 31;
-// Magic that identifies persistent storage
-static const uint32_t MAGIC = 0x1BEAC000;
-// Values for ADV packets related to firmware levels
-static URIBeaconConfigService::PowerLevels_t  defaultAdvPowerLevels = {-20, -4, 0, 10};
-// Values for setTxPower() indexed by power mode.
-static const int8_t firmwarePowerLevels[] = {-20, -4, 0, 10};
+#include "ConfigParamsPersistence.h"
 
 BLEDevice ble;
 URIBeaconConfigService *uriBeaconConfig;
-pstorage_handle_t pstorageHandle;
-PersistentData_t  persistentData;
 
-/* LEDs for indication */
-DigitalOut  connectionStateLed(LED1);
-DigitalOut  advertisingStateLed(LED2);
-
-/* Dummy callback handler needed by Nordic's pstorage module. */
-void pstorageNotificationCallback(pstorage_handle_t *p_handle,
-                                  uint8_t            op_code,
-                                  uint32_t           result,
-                                  uint8_t *          p_data,
-                                  uint32_t           data_len) {
-    /* APP_ERROR_CHECK(result); */
-}
-
-void pstorageLoad() {
-    pstorage_init();
-    pstorage_module_param_t pstorageParams = {
-        .cb          = pstorageNotificationCallback,
-        .block_size  = PERSISTENT_DATA_ALIGNED_SIZE,
-        .block_count = 1
-    };
-    pstorage_register(&pstorageParams, &pstorageHandle);
-    if (pstorage_load(reinterpret_cast<uint8_t *>(&persistentData),
-                      &pstorageHandle, PERSISTENT_DATA_ALIGNED_SIZE, 0) != NRF_SUCCESS) {
-        // On failure zero out and let the service reset to defaults
-        memset(&persistentData, 0, sizeof(PersistentData_t));
-    }
-}
-
-
-void pstorageSave() {
-    if (persistentData.magic != MAGIC) {
-        persistentData.magic = MAGIC;
-        pstorage_store(&pstorageHandle,
-                       reinterpret_cast<uint8_t *>(&persistentData),
-                       sizeof(PersistentData_t),
-                       0 /* offset */);
-    } else {
-        pstorage_update(&pstorageHandle,
-                        reinterpret_cast<uint8_t *>(&persistentData),
-                        sizeof(PersistentData_t),
-                        0 /* offset */);
-    }
-}
-
-void startAdvertisingUriBeaconConfig() {
-    char  DEVICE_NAME[] = "mUriBeacon Config";
-
-    ble.clearAdvertisingPayload();
-
-    // Stops advertising the UriBeacon Config Service after a delay
-    ble.setAdvertisingTimeout(ADVERTISING_TIMEOUT_SECONDS);
-
-    ble.accumulateAdvertisingPayload(
-        GapAdvertisingData::BREDR_NOT_SUPPORTED |
-        GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-
-    // UUID is in different order in the ADV frame (!)
-    uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
-    for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
-        reversedServiceUUID[i] =
-            UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
-    }
-    ble.accumulateAdvertisingPayload(
-        GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
-        reversedServiceUUID,
-        sizeof(reversedServiceUUID));
-
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
-    ble.accumulateScanResponse(
-        GapAdvertisingData::COMPLETE_LOCAL_NAME,
-        reinterpret_cast<uint8_t *>(&DEVICE_NAME),
-        sizeof(DEVICE_NAME));
-    ble.accumulateScanResponse(
-        GapAdvertisingData::TX_POWER_LEVEL,
-        reinterpret_cast<uint8_t *>(
-            &defaultAdvPowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]),
-        sizeof(uint8_t));
-
-    ble.setTxPower(
-        firmwarePowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]);
-
-    ble.setDeviceName(reinterpret_cast<uint8_t *>(&DEVICE_NAME));
-    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    ble.setAdvertisingInterval(
-        Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
+{
     ble.startAdvertising();
 }
 
-void startAdvertisingUriBeacon() {
-    uint8_t serviceData[SERVICE_DATA_MAX];
-    int serviceDataLen = 0;
-
-    advertisingStateLed = 1;
-    connectionStateLed = 1;
-
-    ble.shutdown();
-    ble.init();
-
-    // Fields from the Service
-    int beaconPeriod  = persistentData.params.beaconPeriod;
-    int txPowerMode   = persistentData.params.txPowerMode;
-    int uriDataLength = persistentData.params.uriDataLength;
-    URIBeaconConfigService::UriData_t &uriData = persistentData.params.uriData;
-    URIBeaconConfigService::PowerLevels_t &advPowerLevels = persistentData.params.advPowerLevels;
-    uint8_t flags = persistentData.params.flags;
-
-    pstorageSave();
-
-    delete uriBeaconConfig;
-    uriBeaconConfig = NULL;
-
-    ble.clearAdvertisingPayload();
-    ble.setTxPower(firmwarePowerLevels[txPowerMode]);
-
-    ble.setAdvertisingType(
-        GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
-
-    ble.setAdvertisingInterval(
-        Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(beaconPeriod));
-
-    ble.accumulateAdvertisingPayload(
-        GapAdvertisingData::BREDR_NOT_SUPPORTED |
-        GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-
-    ble.accumulateAdvertisingPayload(
-        GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID,
-        sizeof(BEACON_UUID));
-
-    serviceData[serviceDataLen++] = BEACON_UUID[0];
-    serviceData[serviceDataLen++] = BEACON_UUID[1];
-    serviceData[serviceDataLen++] = flags;
-    serviceData[serviceDataLen++] = advPowerLevels[txPowerMode];
-    for (int j=0; j < uriDataLength; j++) {
-        serviceData[serviceDataLen++] = uriData[j];
-    }
-
-    ble.accumulateAdvertisingPayload(
-        GapAdvertisingData::SERVICE_DATA,
-        serviceData, serviceDataLen);
-
-    ble.startAdvertising();
-}
-
-// After advertising timeout, stop config and switch to UriBeacon
-void timeout(void) {
-    Gap::GapState_t state;
-    state = ble.getGapState();
-    if (!state.connected) {
-        startAdvertisingUriBeacon();
-    }
-}
-
-// When connected to config service, change the LEDs
-void connectionCallback(Gap::Handle_t handle,
-                        Gap::addr_type_t peerAddrType,
-                        const Gap::address_t peerAddr,
-                        const Gap::ConnectionParams_t *params) {
-    advertisingStateLed = 1;
-    connectionStateLed = 0;
-}
-
-// When disconnected from config service, start advertising UriBeacon
-void disconnectionCallback(Gap::Handle_t handle,
-                           Gap::DisconnectionReason_t reason) {
-    advertisingStateLed = 0;    // on
-    connectionStateLed = 1;     // off
-    startAdvertisingUriBeacon();
-}
-
 int main(void)
 {
-    advertisingStateLed = 0; // on
-    connectionStateLed  = 1; // off
-
     ble.init();
     ble.onDisconnection(disconnectionCallback);
-    ble.onConnection(connectionCallback);
-    // Advertising timeout
-    ble.onTimeout(timeout);
-
-    pstorageLoad();
-    bool resetToDefaults = persistentData.magic != MAGIC;
 
-    URIBeaconConfigService::UriData_t defaultUriData;
-    size_t                            defaultUriDataLength;
-    URIBeaconConfigService::encodeURI("http://uribeacon.org", defaultUriData, defaultUriDataLength);
+    /*
+     * Load parameters from (platform specific) persistent storage. Parameters
+     * can be set to non-default values while the URIBeacon is in configuration
+     * mode (within the first 60 seconds of power-up). Thereafter, parameters
+     * get copied out to persistent storage before switching to normal URIBeacon
+     * operation.
+     */
+    URIBeaconConfigService::Params_t params;
+    loadURIBeaconConfigParams(&params);
 
-    uriBeaconConfig = new URIBeaconConfigService(ble, persistentData.params, resetToDefaults,
-                                                 defaultUriData, defaultUriDataLength, defaultAdvPowerLevels);
+    /* Initialize a URIBeaconConfig service providing config params, default URI, and power levels. */
+    static URIBeaconConfigService::PowerLevels_t defaultAdvPowerLevels = {-20, -4, 0, 10}; // Values for ADV packets related to firmware levels
+    uriBeaconConfig = new URIBeaconConfigService(ble, params, "http://uribeacon.org", defaultAdvPowerLevels);
     if (!uriBeaconConfig->configuredSuccessfully()) {
         error("failed to accommodate URI");
     }
 
     // Setup auxiliary services to allow over-the-air firmware updates, etc
     DFUService dfu(ble);
-    DeviceInformationService deviceInfo(
-        ble, "ARM", "UriBeacon", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+    DeviceInformationService deviceInfo(ble, "ARM", "UriBeacon", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
 
-    /* Start out by advertising the configService for a limited time after
-     * startup; and switch to the normal non-connectible beacon functionality
-     * afterwards. */
-    startAdvertisingUriBeaconConfig();
+    ble.startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the URIBeaconConfig
+                             * service, which then automatically switches to the URIBeacon after a timeout. */
 
     while (true) {
         ble.waitForEvent();