BLE EddystoneService example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include <events/mbed_events.h>
00018 
00019 #include <mbed.h>
00020 #include "ble/BLE.h"
00021 #include "EddystoneService.h"
00022 
00023 #include "PersistentStorageHelper/ConfigParamsPersistence.h"
00024 
00025 EddystoneService *eddyServicePtr;
00026 
00027 /* Duration after power-on that config service is available. */
00028 static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 30;
00029 
00030 /* Default UID frame data */
00031 static const UIDNamespaceID_t uidNamespaceID = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
00032 static const UIDInstanceID_t  uidInstanceID  = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
00033 
00034 /* Default version in TLM frame */
00035 static const uint8_t tlmVersion = 0x00;
00036 
00037 /* Values for ADV packets related to firmware levels, calibrated based on measured values at 1m */
00038 static const PowerLevels_t defaultAdvPowerLevels = {-47, -33, -21, -13};
00039 /* Values for radio power levels, provided by manufacturer. */
00040 static const PowerLevels_t radioPowerLevels      = {-30, -16, -4, 4};
00041 
00042 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
00043 
00044 DigitalOut led(LED1, 1);
00045 
00046 /**
00047  * Callback triggered upon a disconnection event.
00048  */
00049 static void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams)
00050 {
00051     (void) cbParams;
00052     BLE::Instance().gap().startAdvertising();
00053 }
00054 
00055 /**
00056  * Callback triggered some time after application started to switch to beacon mode.
00057  */
00058 static void timeout(void)
00059 {
00060     Gap::GapState_t state;
00061     state = BLE::Instance().gap().getState();
00062     if (!state.connected) { /* don't switch if we're in a connected state. */
00063         eddyServicePtr->startBeaconService();
00064         EddystoneService::EddystoneParams_t params;
00065         eddyServicePtr->getEddystoneParams(params);
00066         saveEddystoneServiceConfigParams(&params);
00067     } else {
00068         eventQueue.call_in(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000, timeout);
00069     }
00070 }
00071 
00072 static void blinky(void)
00073 {
00074     led = !led;
00075 }
00076 
00077 static void onBleInitError(BLE::InitializationCompleteCallbackContext* initContext)
00078 {
00079     /* Initialization error handling goes here... */
00080     (void) initContext;
00081 }
00082 
00083 static void initializeEddystoneToDefaults(BLE &ble)
00084 {
00085     /* Set everything to defaults */
00086     eddyServicePtr = new EddystoneService(ble, defaultAdvPowerLevels, radioPowerLevels, eventQueue);
00087 
00088     /* Set default URL, UID and TLM frame data if not initialized through the config service */
00089     const char* url = YOTTA_CFG_EDDYSTONE_DEFAULT_URL;
00090     eddyServicePtr->setURLData(url);
00091     eddyServicePtr->setUIDData(uidNamespaceID, uidInstanceID);
00092     eddyServicePtr->setTLMData(tlmVersion);
00093 }
00094 
00095 static void bleInitComplete(BLE::InitializationCompleteCallbackContext* initContext)
00096 {
00097     BLE         &ble  = initContext->ble;
00098     ble_error_t error = initContext->error;
00099 
00100     if (error != BLE_ERROR_NONE) {
00101         onBleInitError(initContext);
00102         return;
00103     }
00104 
00105     ble.gap().onDisconnection(disconnectionCallback);
00106 
00107     EddystoneService::EddystoneParams_t params;
00108     if (loadEddystoneServiceConfigParams(&params)) {
00109         eddyServicePtr = new EddystoneService(ble, params, radioPowerLevels, eventQueue);
00110     } else {
00111         initializeEddystoneToDefaults(ble);
00112     }
00113 
00114     /* Start Eddystone in config mode */
00115    eddyServicePtr->startConfigService();
00116 
00117    eventQueue.call_in(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000, timeout);
00118 }
00119 
00120 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00121     BLE &ble = BLE::Instance();
00122     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00123 }
00124 
00125 
00126 int main()
00127 {
00128     /* Tell standard C library to not allocate large buffers for these streams */
00129     setbuf(stdout, NULL);
00130     setbuf(stderr, NULL);
00131     setbuf(stdin, NULL);
00132 
00133     eventQueue.call_every(500, blinky);
00134 
00135     BLE &ble = BLE::Instance();
00136     ble.onEventsToProcess(scheduleBleEventsProcessing);
00137     ble.init(bleInitComplete);
00138 
00139     eventQueue.dispatch_forever();
00140     return 0;
00141 }