URI-Beacons are handy when there is a need to advertise a small amount of information (usually a URL) to any nearby device. They’re really easy to set up: the code is fully available on the mbed website, so all you’ll need to do is tell the beacon what to broadcast. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_URIBeacon

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 #include "mbed.h"
00019 #include "ble/BLE.h"
00020 #include "ble/services/URIBeaconConfigService.h"
00021 #include "ble/services/DFUService.h"
00022 #include "ble/services/DeviceInformationService.h"
00023 #include "ConfigParamsPersistence.h"
00024 
00025 /**
00026  * URIBeaconConfig service can operate in two modes: a configuration mode which
00027  * allows a user to update settings over a connection; and normal URIBeacon mode
00028  * which involves advertising a URI. Constructing an object from URIBeaconConfig
00029  * service sets up advertisements for the configuration mode. It is then up to
00030  * the application to switch to URIBeacon mode based on some timeout.
00031  *
00032  * The following help with this switch.
00033  */
00034 static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 60;  // Duration after power-on that config service is available.
00035 
00036 static EventQueue eventQueue(
00037     /* event count */ 16 * /* event size */ 32
00038 );
00039 
00040 /* global static objects */
00041 BLE ble;
00042 URIBeaconConfigService *uriBeaconConfig;
00043 URIBeaconConfigService::Params_t params;
00044 
00045 /**
00046  * Stop advertising the UriBeaconConfig Service after a delay; and switch to normal URIBeacon.
00047  */
00048 void timeout(void)
00049 {
00050     Gap::GapState_t state;
00051     state = ble.getGapState();
00052     if (!state.connected) { /* don't switch if we're in a connected state. */
00053         uriBeaconConfig->setupURIBeaconAdvertisements();
00054         ble.startAdvertising();
00055     } else {
00056         eventQueue.call_in(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000, timeout);
00057     }
00058 }
00059 
00060 /**
00061  * Callback triggered upon a disconnection event. Needs to re-enable advertisements.
00062  */
00063 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *)
00064 {
00065     ble.startAdvertising();
00066 }
00067 
00068 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00069     BLE &ble = BLE::Instance();
00070     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00071 }
00072 
00073 int main()
00074 {
00075     ble.onEventsToProcess(scheduleBleEventsProcessing);
00076     ble.init();
00077     ble.onDisconnection(disconnectionCallback);
00078 
00079     /*
00080      * Load parameters from (platform specific) persistent storage. Parameters
00081      * can be set to non-default values while the URIBeacon is in configuration
00082      * mode (within the first 60 seconds of power-up). Thereafter, parameters
00083      * get copied out to persistent storage before switching to normal URIBeacon
00084      * operation.
00085      */
00086     bool fetchedFromPersistentStorage = loadURIBeaconConfigParams(&params);
00087 
00088     /* Initialize a URIBeaconConfig service providing config params, default URI, and power levels. */
00089     static URIBeaconConfigService::PowerLevels_t defaultAdvPowerLevels = {-20, -4, 0, 10}; // Values for ADV packets related to firmware levels
00090     uriBeaconConfig = new URIBeaconConfigService(ble, params, !fetchedFromPersistentStorage, "http://uribeacon.org", defaultAdvPowerLevels);
00091     if (!uriBeaconConfig->configuredSuccessfully()) {
00092         error("failed to accommodate URI");
00093     }
00094 
00095     // Setup auxiliary services to allow over-the-air firmware updates, etc
00096     DFUService *dfu = new DFUService(ble);
00097     DeviceInformationService *deviceInfo = new DeviceInformationService(ble, "ARM", "UriBeacon", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00098 
00099     ble.startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the URIBeaconConfig
00100                              * service. This can then be switched to the normal URIBeacon functionality after a timeout. */
00101 
00102     eventQueue.call_in(CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS * 1000, timeout);
00103 
00104     eventQueue.dispatch_forever();
00105 
00106     return 0;
00107 }