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
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(¶ms); 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 }
Generated on Sat Jul 16 2022 01:41:25 by 1.7.2