The eddystone config service allows you to configure the eddystone frame data over BLE for a set period of time and then starts an eddystone beacon. This example defaults to 30 seconds of config time.

Dependencies:   BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1

Fork of BLE_EddystoneBeaconConfigServiceRelease by Austin Blackstone

This is the eddystone config service. This code starts up and for a user configured time period (default 30 seconds) will advertise the configuration service.

The configuration service allows for modifying various frames of the eddystone specification.

For more details on the Configuration Service please see : https://github.com/google/eddystone/blob/master/eddystone-url/docs/config-service-spec.md

main.cpp

Committer:
mbedAustin
Date:
2015-10-01
Revision:
1:5b266d95731f
Parent:
0:f528fb53a9ef
Child:
2:378323d1b4d9

File content as of revision 1:5b266d95731f:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 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 "mbed.h"
#include "ble/BLE.h"
#include "ble/services/EddystoneConfigService.h"
#include "ConfigParamsPersistence.h"

BLE ble;
EddystoneConfigService *EddystoneBeaconConfig;
EddystoneConfigService::Params_t params;

/**
 * URIBeaconConfig service can operate in two modes: a configuration mode which
 * allows a user to update settings over a connection; and normal URIBeacon mode
 * which involves advertising a URI. Constructing an object from URIBeaconConfig
 * service sets up advertisements for the configuration mode. It is then up to
 * the application to switch to URIBeacon mode based on some timeout.
 *
 * The following help with this switch.
 */
static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 30;  // Duration after power-on that config service is available.

Ticker configAdvertisementTimeout;

/**
 * Stop advertising the Config Service after a delay; and switch to a non-connectable advertising mode only beacon.
 */
void timeout(void)
{
    Gap::GapState_t state;
    state = ble.getGapState();
    if (!state.connected) { /* don't switch if we're in a connected state. */
        configAdvertisementTimeout.detach(); /* disable the callback from the timeout Ticker. */
        EddystoneBeaconConfig->setupEddystoneAdvertisements();        
    }
}

/**
 * Callback triggered upon a disconnection event.
 */
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams)
{
    if (true == params.isConfigured){
        // end advertising, the beacon is configured
        timeout();
    }
    else{
        // eddystone is not configured, continue advertising    
        ble.gap().startAdvertising();
    }
}

int main(void)
{
    ble.init();
    ble.gap().onDisconnection(disconnectionCallback);

    /*
     * 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.
     */
    bool fetchedFromPersistentStorage = loadURIBeaconConfigParams(&params);
    
    // Set UID and TLM frame data
    EddystoneConfigService::UIDNamespaceID_t uidNamespaceID = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}; // 10Byte Namespace UUID
    EddystoneConfigService::UIDInstanceID_t  uidInstanceID = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // 6Byte Instance ID
    uint8_t tlmVersion = 0x00;
    
    /* Initialize a EddystoneBeaconConfig service providing config params, default URI, and power levels. */
    static EddystoneConfigService::PowerLevels_t defaultAdvPowerLevels = {-47, -33, -21, -13}; // Values for ADV packets related to firmware levels, calibrated based on measured values at 1m
    static EddystoneConfigService::PowerLevels_t radioPowerLevels =      {-30, -16, -4, 4};    // Values for radio power levels, provided by manufacturer.
    
    // Create Eddystone Config Service object
    EddystoneBeaconConfig = new EddystoneConfigService(ble, params, defaultAdvPowerLevels, radioPowerLevels);
    
    // Set default URI, UID and TLM frame data if not initialized through the config service
    EddystoneBeaconConfig->setDefaultURIFrameData("http://mbed.org",2);
    EddystoneBeaconConfig->setDefaultUIDFrameData(&uidNamespaceID, &uidInstanceID,5);
    EddystoneBeaconConfig->setDefaultTLMFrameData(tlmVersion,10);
    
    // start the config service
    EddystoneBeaconConfig->start(!fetchedFromPersistentStorage);
    
    if (!EddystoneBeaconConfig->initSuccessfully()) {
        error("failed to accommodate URI");
    }
    configAdvertisementTimeout.attach(timeout, CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS);

    ble.gap().startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the EddystoneBeaconConfig
                                   * service. This can then be switched to the normal URIBeacon functionality after a timeout. */
    while (true) {
        ble.waitForEvent();
    }
}