Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
Diff: ble/services/EddystoneConfigService.h
- Revision:
- 832:5dac246f8f02
- Parent:
- 831:47413688398a
- Child:
- 841:468a5863cacb
--- a/ble/services/EddystoneConfigService.h Tue Sep 29 09:54:19 2015 +0100 +++ b/ble/services/EddystoneConfigService.h Tue Sep 29 09:54:19 2015 +0100 @@ -14,17 +14,13 @@ * limitations under the License. */ -#ifndef SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_ -#define SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_ +#ifndef SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_ +#define SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_ #include "mbed.h" #include "ble/BLE.h" #include "ble/services/EddystoneService.h" -#define EDDYSTONE_NUM_UID_FRAMES 10 -#define EDDYSTONE_NUM_URL_FRAMES 50 - - #define UUID_URI_BEACON(FIRST, SECOND) { \ 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \ 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ @@ -40,7 +36,7 @@ static const uint8_t UUID_TX_POWER_MODE_CHAR[] = UUID_URI_BEACON(0x20, 0x87); static const uint8_t UUID_BEACON_PERIOD_CHAR[] = UUID_URI_BEACON(0x20, 0x88); static const uint8_t UUID_RESET_CHAR[] = UUID_URI_BEACON(0x20, 0x89); -extern const uint8_t BEACON_EDDYSTONE[2]; +extern const uint8_t BEACON_EDDYSTONE[2]; /** * @class EddystoneConfigService @@ -50,34 +46,34 @@ */ class EddystoneConfigService { -public: +public: /** * @brief Transmission Power Modes for UriBeacon */ - static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */ - static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */ - static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */ - static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */ - static const unsigned NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */ + enum { + TX_POWER_MODE_LOWEST, + TX_POWER_MODE_LOW, + TX_POWER_MODE_MEDIUM, + TX_POWER_MODE_HIGH, + NUM_POWER_MODES + }; - static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. - static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets + static const unsigned ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. + static const unsigned SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets - typedef uint8_t Lock_t[16]; /* 128 bits */ + typedef uint8_t Lock_t[16]; /* 128 bits */ typedef int8_t PowerLevels_t[NUM_POWER_MODES]; // There are currently 3 subframes defined, URI, UID, and TLM #define EDDYSTONE_MAX_FRAMETYPE 3 - void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t); - uint8_t frameIndex; - static const int URI_DATA_MAX = 18; - typedef uint8_t UriData_t[URI_DATA_MAX]; + static const unsigned URI_DATA_MAX = 18; + typedef uint8_t UriData_t[URI_DATA_MAX]; // UID Frame Type subfields - static const int UID_NAMESPACEID_SIZE = 10; - typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE]; - static const int UID_INSTANCEID_SIZE = 6; - typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE]; + static const size_t UID_NAMESPACEID_SIZE = 10; + typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE]; + static const size_t UID_INSTANCEID_SIZE = 6; + typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE]; // Eddystone Frame Type ID static const uint8_t FRAME_TYPE_UID = 0x00; @@ -89,27 +85,28 @@ struct Params_t { // Config Data - bool isConfigured; // Flag for configuration being complete, True = configured, false = not configured. Reset at instantiation, used for external callbacks. - uint8_t lockedState; - Lock_t lock; - uint8_t flags; - PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels - uint8_t txPowerMode; // Firmware power levels used with setTxPower() - uint16_t beaconPeriod; + bool isConfigured; // Flag for configuration being complete, + // True = configured, false = not configured. Reset at instantiation, used for external callbacks. + uint8_t lockedState; + Lock_t lock; + uint8_t flags; + PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels + uint8_t txPowerMode; // Firmware power levels used with setTxPower() + uint16_t beaconPeriod; // TLM Frame Data - uint8_t tlmVersion; // version of TLM packet - bool tlmEnabled; - float tlmBeaconPeriod; // how often to broadcat TLM frame, in S + uint8_t tlmVersion; // version of TLM packet + bool tlmEnabled; + float tlmBeaconPeriod; // how often to broadcat TLM frame, in seconds. // URI Frame Data - uint8_t uriDataLength; - UriData_t uriData; - bool uriEnabled; - float uriBeaconPeriod; // how often to broadcast URIFrame, in S + uint8_t uriDataLength; + UriData_t uriData; + bool uriEnabled; + float uriBeaconPeriod; // how often to broadcast URIFrame, in seconds. // UID Frame Data - UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B - UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B - bool uidEnabled; - float uidBeaconPeriod; // how often to broadcast UID Frame, in S + UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B + UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B + bool uidEnabled; + float uidBeaconPeriod; // how often to broadcast UID Frame, in seconds. }; /** @@ -149,27 +146,9 @@ advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, ¶ms.advPowerLevels), txPowerModeChar(UUID_TX_POWER_MODE_CHAR, ¶ms.txPowerMode), beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, ¶ms.beaconPeriod), - resetChar(UUID_RESET_CHAR, &resetFlag) - { + resetChar(UUID_RESET_CHAR, &resetFlag) { // set eddystone as not configured yet. Used to exit config before timeout if GATT services are written to. params.isConfigured = false; - } - - /* - * @breif Start EddystoneConfig advertising. This function should be called after the EddystoneConfig constructor and after all the frames have been added. - * @paramsP[in] resetToDefaultsFlag - * Applies to the state of the 'paramsIn' parameter. - * If true, it indicates that paramsIn is potentially - * un-initialized, and default values should be used - * instead. Otherwise, paramsIn overrides the defaults. - * - */ - void start(bool resetToDefaultsFlag){ - INFO("reset to defaults flag = %d", resetToDefaultsFlag); - if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { - INFO("Reset to Defaults triggered"); - resetToDefaultsFlag = true; - } lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback); unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback); @@ -188,16 +167,33 @@ GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(configService); + ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback); + } + + /** + * @brief Start EddystoneConfig advertising. This function should be called + * after the EddystoneConfig constructor and after all the frames have been added. + * + * @paramsP[in] resetToDefaultsFlag + * Applies to the state of the 'paramsIn' parameter. + * If true, it indicates that paramsIn is potentially + * un-initialized, and default values should be used + * instead. Otherwise, paramsIn overrides the defaults. + */ + void start(bool resetToDefaultsFlag){ + INFO("reset to defaults flag = %d", resetToDefaultsFlag); + if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { + INFO("Reset to Defaults triggered"); + resetToDefaultsFlag = true; + } + if (resetToDefaultsFlag) { resetToDefaults(); } else { updateCharacteristicValues(); } - - ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback); setupEddystoneConfigAdvertisements(); /* Setup advertising for the configService. */ - initSucceeded = true; } @@ -207,48 +203,47 @@ bool initSuccessfully(void) const { return initSucceeded; } - + /* - * @breif Function to update the default values for the TLM frame. Only applied if Reset Defaults is applied. + * @brief Function to update the default values for the TLM frame. Only applied if Reset Defaults is applied. * * @param[in] tlmVersionIn Version of the TLM frame being used * @param[in] advPeriodInMin how long between TLM frames being advertised, this is measured in minutes. * */ void setDefaultTLMFrameData(uint8_t tlmVersionIn = 0, float advPeriodInSec = 60){ - DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f",tlmVersionIn,advPeriodInSec); - defaultTlmVersion = tlmVersionIn; - TlmBatteryVoltage = 0; - TlmBeaconTemp = 0; - TlmPduCount = 0; - TlmTimeSinceBoot = 0; + DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f", tlmVersionIn, advPeriodInSec); + defaultTlmVersion = tlmVersionIn; + TlmBatteryVoltage = 0; + TlmBeaconTemp = 0; + TlmPduCount = 0; + TlmTimeSinceBoot = 0; defaultTlmAdvPeriod = advPeriodInSec; - tlmIsSet = true; // flag to add this to eddystone service when config is done - + tlmIsSet = true; // flag to add this to eddystone service when config is done } - + /* - * @breif Function to update the default values for the URI frame. Only applied if Reset Defaults is applied. + * @brief Function to update the default values for the URI frame. Only applied if Reset Defaults is applied. * * @param[in] uriIn url to advertise * @param[in] advPeriod how long to advertise the url for, measured in number of ADV frames. * */ - void setDefaultURIFrameData(const char * uriIn, float advPeriod = 1){ + void setDefaultURIFrameData(const char *uriIn, float advPeriod = 1){ DBG("Setting Default URI Data"); // Set URL Frame - EddystoneService::encodeURL(uriIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting + EddystoneService::encodeURL(uriIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting if (defaultUriDataLength > URI_DATA_MAX) { return; } INFO("\t URI input = %s : %d", uriIn, defaultUriDataLength); - INFO("\t default URI = %s : %d ",defaultUriData,defaultUriDataLength ); + INFO("\t default URI = %s : %d ", defaultUriData, defaultUriDataLength ); defaultUriAdvPeriod = advPeriod; - urlIsSet = true; // flag to add this to eddystone service when config is done + urlIsSet = true; // flag to add this to eddystone service when config is done } - + /* - * @breif Function to update the default values for the UID frame. Only applied if Reset Defaults is applied. + * @brief Function to update the default values for the UID frame. Only applied if Reset Defaults is applied. * * @param[in] namespaceID 10Byte Namespace ID * @param[in] instanceID 6Byte Instance ID @@ -261,7 +256,7 @@ memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE); memcpy(defaultUidInstanceID, instanceID, UID_INSTANCEID_SIZE); defaultUidAdvPeriod = advPeriod; - uidIsSet = true; // flag to add this to eddystone service when config is done + uidIsSet = true; // flag to add this to eddystone service when config is done } /* Start out by advertising the configService for a limited time after @@ -304,24 +299,26 @@ extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */ saveURIBeaconConfigParams(¶ms); INFO("Saved Params to Memory.") - // Setup Eddystone Service - static EddystoneService eddyServ(ble,params.beaconPeriod,radioPowerLevels[params.txPowerMode]); + // Setup Eddystone Service + static EddystoneService eddyServ(ble, params.beaconPeriod, radioPowerLevels[params.txPowerMode]); // Set configured frames (TLM,UID,URI...etc) - if(params.tlmEnabled){ - eddyServ.setTLMFrameData(params.tlmVersion,params.tlmBeaconPeriod); + if (params.tlmEnabled) { + eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod); } - if(params.uriEnabled){ + if (params.uriEnabled) { eddyServ.setURLFrameData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriBeaconPeriod); } - if(params.uidEnabled){ - eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode], (uint8_t *) params.uidNamespaceID, (uint8_t *) params.uidInstanceID, params.uidBeaconPeriod); - } - // Start Advertising the eddystone service. - eddyServ.start(); + if (params.uidEnabled) { + eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode], + (uint8_t *)params.uidNamespaceID, + (uint8_t *)params.uidInstanceID, + params.uidBeaconPeriod); + } + // Start Advertising the eddystone service. + eddyServ.start(); } private: - /* * This callback is invoked when a GATT client attempts to modify any of the * characteristics of this service. Attempts to do so are also applied to @@ -342,32 +339,32 @@ INFO("Device Unlocked"); } else if (handle == uriDataChar.getValueHandle()) { params.uriDataLength = writeParams->len; - memset(params.uriData,0x00,URI_DATA_MAX); // clear URI string + memset(params.uriData, 0x00, URI_DATA_MAX); // clear URI string memcpy(params.uriData, writeParams->data, params.uriDataLength); // set URI string params.uriEnabled = true; INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len); } else if (handle == flagsChar.getValueHandle()) { params.flags = *(writeParams->data); - INFO("flagsChar = 0x%x",params.flags); + INFO("flagsChar = 0x%x", params.flags); } else if (handle == advPowerLevelsChar.getValueHandle()) { memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); - INFO("PowerLevelsChar = %4x",params.advPowerLevels); + INFO("PowerLevelsChar = %4x", params.advPowerLevels); } else if (handle == txPowerModeChar.getValueHandle()) { params.txPowerMode = *(writeParams->data); - INFO("TxPowerModeChar = %d",params.txPowerMode); + INFO("TxPowerModeChar = %d", params.txPowerMode); } else if (handle == beaconPeriodChar.getValueHandle()) { params.beaconPeriod = *((uint16_t *)(writeParams->data)); - INFO("BeaconPeriod = %d",params.beaconPeriod); + INFO("BeaconPeriod = %d", params.beaconPeriod); /* Re-map beaconPeriod to within permissible bounds if necessary. */ if (params.beaconPeriod != 0) { bool paramsUpdated = false; if (params.beaconPeriod < ble.getMinAdvertisingInterval()) { params.beaconPeriod = ble.getMinAdvertisingInterval(); - paramsUpdated = true; + paramsUpdated = true; } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) { params.beaconPeriod = ble.getMaxAdvertisingInterval(); - paramsUpdated = true; + paramsUpdated = true; } if (paramsUpdated) { ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); @@ -387,30 +384,30 @@ void resetToDefaults(void) { INFO("Resetting to defaults"); // General - params.lockedState = false; + params.lockedState = false; memset(params.lock, 0, sizeof(Lock_t)); - params.flags = 0x10; + params.flags = 0x10; memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); - params.txPowerMode = TX_POWER_MODE_LOW; - params.beaconPeriod = 1000; - + params.txPowerMode = TX_POWER_MODE_LOW; + params.beaconPeriod = 1000; + // TLM Frame - params.tlmVersion = defaultTlmVersion; + params.tlmVersion = defaultTlmVersion; params.tlmBeaconPeriod = defaultTlmAdvPeriod; - params.tlmEnabled = tlmIsSet; - + params.tlmEnabled = tlmIsSet; + // URL Frame memcpy(params.uriData, defaultUriData, URI_DATA_MAX); - params.uriDataLength = defaultUriDataLength; - params.uriBeaconPeriod = defaultUriAdvPeriod; - params.uriEnabled = urlIsSet; - + params.uriDataLength = defaultUriDataLength; + params.uriBeaconPeriod = defaultUriAdvPeriod; + params.uriEnabled = urlIsSet; + // UID Frame memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE); memcpy(params.uidInstanceID, defaultUidInstanceID, UID_INSTANCEID_SIZE); params.uidBeaconPeriod = defaultUidAdvPeriod; - params.uidEnabled = uidIsSet; - + params.uidEnabled = uidIsSet; + updateCharacteristicValues(); } @@ -420,8 +417,7 @@ */ void updateCharacteristicValues(void) { ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), ¶ms.lockedState, 1); - ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); // TODO: this isnt updating the initial URI in config mode, need to figure out why. - INFO("updateCharacteristicValues - URI, %s : %d",params.uriData, params.uriDataLength); + ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); ble.updateCharacteristicValue(flagsChar.getValueHandle(), ¶ms.flags, 1); ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); @@ -443,7 +439,6 @@ } } - void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; @@ -495,41 +490,41 @@ } } - BLEDevice &ble; - Params_t ¶ms; - Ticker timeSinceBootTick; - Timeout switchFrame; -// Default value that is restored on reset - PowerLevels_t &defaultAdvPowerLevels; // this goes into the advertising frames (radio power measured at 1m from device) - PowerLevels_t &radioPowerLevels; // this configures the power levels of the radio - uint8_t lockedState; - bool initSucceeded; - uint8_t resetFlag; - bool switchFlag; + BLEDevice &ble; + Params_t ¶ms; + Ticker timeSinceBootTick; + Timeout switchFrame; + // Default value that is restored on reset + PowerLevels_t &defaultAdvPowerLevels; // this goes into the advertising frames (radio power measured at 1m from device) + PowerLevels_t &radioPowerLevels; // this configures the power levels of the radio + uint8_t lockedState; + bool initSucceeded; + uint8_t resetFlag; + bool switchFlag; -//UID Default value that is restored on reset - UIDNamespaceID_t defaultUidNamespaceID; - UIDInstanceID_t defaultUidInstanceID; - float defaultUidAdvPeriod; - int8_t defaultUidPower; - uint16_t uidRFU; - bool uidIsSet; + //UID Default value that is restored on reset + UIDNamespaceID_t defaultUidNamespaceID; + UIDInstanceID_t defaultUidInstanceID; + float defaultUidAdvPeriod; + int8_t defaultUidPower; + uint16_t uidRFU; + bool uidIsSet; -//URI Default value that is restored on reset - uint8_t defaultUriDataLength; - UriData_t defaultUriData; - int8_t defaultUrlPower; - float defaultUriAdvPeriod; - bool urlIsSet; + //URI Default value that is restored on reset + uint8_t defaultUriDataLength; + UriData_t defaultUriData; + int8_t defaultUrlPower; + float defaultUriAdvPeriod; + bool urlIsSet; -//TLM Default value that is restored on reset - uint8_t defaultTlmVersion; - float defaultTlmAdvPeriod; - volatile uint16_t TlmBatteryVoltage; - volatile uint16_t TlmBeaconTemp; - volatile uint32_t TlmPduCount; - volatile uint32_t TlmTimeSinceBoot; - bool tlmIsSet; + //TLM Default value that is restored on reset + uint8_t defaultTlmVersion; + float defaultTlmAdvPeriod; + volatile uint16_t TlmBatteryVoltage; + volatile uint16_t TlmBeaconTemp; + volatile uint32_t TlmPduCount; + volatile uint32_t TlmTimeSinceBoot; + bool tlmIsSet; ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; WriteOnlyGattCharacteristic<Lock_t> lockChar; @@ -540,7 +535,6 @@ ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; WriteOnlyGattCharacteristic<uint8_t> resetChar; - }; -#endif // SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_ \ No newline at end of file +#endif // SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_ \ No newline at end of file