Button initiated config service

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Committer:
mbedAustin
Date:
Thu Sep 10 17:06:18 2015 +0000
Revision:
39:2c73bc1ff4f5
Parent:
38:8fdb16f67e7c
Child:
40:6f39aee31205
Added parameter types to check for frame types being enabled and for eddystone config data being configured.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 23:05e9bb3b13af 1 /* mbed Microcontroller Library
mbedAustin 23:05e9bb3b13af 2 * Copyright (c) 2006-2013 ARM Limited
mbedAustin 23:05e9bb3b13af 3 *
mbedAustin 23:05e9bb3b13af 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbedAustin 23:05e9bb3b13af 5 * you may not use this file except in compliance with the License.
mbedAustin 23:05e9bb3b13af 6 * You may obtain a copy of the License at
mbedAustin 23:05e9bb3b13af 7 *
mbedAustin 23:05e9bb3b13af 8 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 23:05e9bb3b13af 9 *
mbedAustin 23:05e9bb3b13af 10 * Unless required by applicable law or agreed to in writing, software
mbedAustin 23:05e9bb3b13af 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbedAustin 23:05e9bb3b13af 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 23:05e9bb3b13af 13 * See the License for the specific language governing permissions and
mbedAustin 23:05e9bb3b13af 14 * limitations under the License.
mbedAustin 23:05e9bb3b13af 15 */
mbedAustin 23:05e9bb3b13af 16
mbedAustin 33:8c65879e7d52 17 #ifndef SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_
mbedAustin 33:8c65879e7d52 18 #define SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_
mbedAustin 23:05e9bb3b13af 19
mbedAustin 23:05e9bb3b13af 20 #include "mbed.h"
mbedAustin 23:05e9bb3b13af 21 #include "ble/BLE.h"
mbedAustin 34:5876fbb1aa62 22 #include "ble/services/EddystoneService.h"
mbedAustin 23:05e9bb3b13af 23
mbedAustin 33:8c65879e7d52 24 #define EDDYSTONE_NUM_UID_FRAMES 10
mbedAustin 33:8c65879e7d52 25 #define EDDYSTONE_NUM_URL_FRAMES 50
mbedAustin 33:8c65879e7d52 26
mbedAustin 23:05e9bb3b13af 27
mbedAustin 23:05e9bb3b13af 28 #define UUID_URI_BEACON(FIRST, SECOND) { \
mbedAustin 23:05e9bb3b13af 29 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \
mbedAustin 23:05e9bb3b13af 30 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \
mbedAustin 23:05e9bb3b13af 31 }
mbedAustin 23:05e9bb3b13af 32
mbedAustin 23:05e9bb3b13af 33 static const uint8_t UUID_URI_BEACON_SERVICE[] = UUID_URI_BEACON(0x20, 0x80);
mbedAustin 23:05e9bb3b13af 34 static const uint8_t UUID_LOCK_STATE_CHAR[] = UUID_URI_BEACON(0x20, 0x81);
mbedAustin 23:05e9bb3b13af 35 static const uint8_t UUID_LOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x82);
mbedAustin 23:05e9bb3b13af 36 static const uint8_t UUID_UNLOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x83);
mbedAustin 23:05e9bb3b13af 37 static const uint8_t UUID_URI_DATA_CHAR[] = UUID_URI_BEACON(0x20, 0x84);
mbedAustin 23:05e9bb3b13af 38 static const uint8_t UUID_FLAGS_CHAR[] = UUID_URI_BEACON(0x20, 0x85);
mbedAustin 23:05e9bb3b13af 39 static const uint8_t UUID_ADV_POWER_LEVELS_CHAR[] = UUID_URI_BEACON(0x20, 0x86);
mbedAustin 23:05e9bb3b13af 40 static const uint8_t UUID_TX_POWER_MODE_CHAR[] = UUID_URI_BEACON(0x20, 0x87);
mbedAustin 23:05e9bb3b13af 41 static const uint8_t UUID_BEACON_PERIOD_CHAR[] = UUID_URI_BEACON(0x20, 0x88);
mbedAustin 23:05e9bb3b13af 42 static const uint8_t UUID_RESET_CHAR[] = UUID_URI_BEACON(0x20, 0x89);
mbedAustin 34:5876fbb1aa62 43 extern const uint8_t BEACON_EDDYSTONE[2];
mbedAustin 23:05e9bb3b13af 44
mbedAustin 23:05e9bb3b13af 45 /**
mbedAustin 23:05e9bb3b13af 46 * @class EddystoneConfigService
mbedAustin 23:05e9bb3b13af 47 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
mbedAustin 25:e20bed9e466f 48 * See https://github.com/google/eddystone
mbedAustin 23:05e9bb3b13af 49 *
mbedAustin 23:05e9bb3b13af 50 */
mbedAustin 23:05e9bb3b13af 51 class EddystoneConfigService
mbedAustin 23:05e9bb3b13af 52 {
mbedAustin 39:2c73bc1ff4f5 53 public:
mbedAustin 23:05e9bb3b13af 54 /**
mbedAustin 23:05e9bb3b13af 55 * @brief Transmission Power Modes for UriBeacon
mbedAustin 23:05e9bb3b13af 56 */
mbedAustin 23:05e9bb3b13af 57 static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */
mbedAustin 23:05e9bb3b13af 58 static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */
mbedAustin 23:05e9bb3b13af 59 static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */
mbedAustin 23:05e9bb3b13af 60 static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */
mbedAustin 34:5876fbb1aa62 61 static const unsigned NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */
mbedAustin 23:05e9bb3b13af 62
mbedAustin 23:05e9bb3b13af 63 static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service.
mbedAustin 23:05e9bb3b13af 64 static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets
mbedAustin 23:05e9bb3b13af 65
mbedAustin 23:05e9bb3b13af 66 typedef uint8_t Lock_t[16]; /* 128 bits */
mbedAustin 23:05e9bb3b13af 67 typedef int8_t PowerLevels_t[NUM_POWER_MODES];
mbedAustin 23:05e9bb3b13af 68
mbedAustin 23:05e9bb3b13af 69 // There are currently 3 subframes defined, URI, UID, and TLM
mbedAustin 23:05e9bb3b13af 70 #define EDDYSTONE_MAX_FRAMETYPE 3
mbedAustin 23:05e9bb3b13af 71 void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t);
mbedAustin 23:05e9bb3b13af 72 uint8_t frameIndex;
mbedAustin 23:05e9bb3b13af 73 static const int URI_DATA_MAX = 18;
mbedAustin 23:05e9bb3b13af 74 typedef uint8_t UriData_t[URI_DATA_MAX];
mbedAustin 23:05e9bb3b13af 75
mbedAustin 23:05e9bb3b13af 76 // UID Frame Type subfields
mbedAustin 23:05e9bb3b13af 77 static const int UID_NAMESPACEID_SIZE = 10;
mbedAustin 37:22175faa76be 78 typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
mbedAustin 23:05e9bb3b13af 79 static const int UID_INSTANCEID_SIZE = 6;
mbedAustin 37:22175faa76be 80 typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE];
mbedAustin 23:05e9bb3b13af 81
mbedAustin 23:05e9bb3b13af 82 // Eddystone Frame Type ID
mbedAustin 23:05e9bb3b13af 83 static const uint8_t FRAME_TYPE_UID = 0x00;
mbedAustin 23:05e9bb3b13af 84 static const uint8_t FRAME_TYPE_URL = 0x10;
mbedAustin 23:05e9bb3b13af 85 static const uint8_t FRAME_TYPE_TLM = 0x20;
mbedAustin 23:05e9bb3b13af 86
mbedAustin 23:05e9bb3b13af 87 static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
mbedAustin 23:05e9bb3b13af 88 static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
mbedAustin 23:05e9bb3b13af 89
mbedAustin 23:05e9bb3b13af 90 struct Params_t {
mbedAustin 39:2c73bc1ff4f5 91 // Config Data
mbedAustin 39:2c73bc1ff4f5 92 bool isConfigured; // Flag for configuration being complete, True = configured, false = not configured. Reset at instantiation, used for external callbacks.
mbedAustin 34:5876fbb1aa62 93 uint8_t lockedState;
mbedAustin 23:05e9bb3b13af 94 Lock_t lock;
mbedAustin 23:05e9bb3b13af 95 uint8_t flags;
mbedAustin 23:05e9bb3b13af 96 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels
mbedAustin 23:05e9bb3b13af 97 uint8_t txPowerMode; // Firmware power levels used with setTxPower()
mbedAustin 23:05e9bb3b13af 98 uint16_t beaconPeriod;
mbedAustin 39:2c73bc1ff4f5 99 // TLM Frame Data
mbedAustin 34:5876fbb1aa62 100 uint8_t tlmVersion; // version of TLM packet
mbedAustin 39:2c73bc1ff4f5 101 bool tlmEnabled;
mbedAustin 39:2c73bc1ff4f5 102 uint8_t tlmBeaconPeriod; // how often to broadcat TLM frame, in minutes.
mbedAustin 39:2c73bc1ff4f5 103 // URI Frame Data
mbedAustin 39:2c73bc1ff4f5 104 uint8_t uriDataLength;
mbedAustin 39:2c73bc1ff4f5 105 UriData_t uriData;
mbedAustin 39:2c73bc1ff4f5 106 bool uriEnabled;
mbedAustin 39:2c73bc1ff4f5 107 uint8_t uriBeaconPeriod; // how often to broadcast URIFrame, in # of adv frames
mbedAustin 39:2c73bc1ff4f5 108 // UID Frame Data
mbedAustin 34:5876fbb1aa62 109 UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
mbedAustin 34:5876fbb1aa62 110 UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B
mbedAustin 39:2c73bc1ff4f5 111 bool uidEnabled;
mbedAustin 39:2c73bc1ff4f5 112 uint8_t uidBeaconPeriod; // how often to broadcast UID Frame, in # of adv frames
mbedAustin 23:05e9bb3b13af 113 };
mbedAustin 23:05e9bb3b13af 114
mbedAustin 23:05e9bb3b13af 115 /**
mbedAustin 23:05e9bb3b13af 116 * @param[ref] ble
mbedAustin 23:05e9bb3b13af 117 * BLEDevice object for the underlying controller.
mbedAustin 23:05e9bb3b13af 118 * @param[in/out] paramsIn
mbedAustin 23:05e9bb3b13af 119 * Reference to application-visible beacon state, loaded
mbedAustin 23:05e9bb3b13af 120 * from persistent storage at startup.
mbedAustin 23:05e9bb3b13af 121 * @paramsP[in] resetToDefaultsFlag
mbedAustin 23:05e9bb3b13af 122 * Applies to the state of the 'paramsIn' parameter.
mbedAustin 23:05e9bb3b13af 123 * If true, it indicates that paramsIn is potentially
mbedAustin 23:05e9bb3b13af 124 * un-initialized, and default values should be used
mbedAustin 23:05e9bb3b13af 125 * instead. Otherwise, paramsIn overrides the defaults.
mbedAustin 23:05e9bb3b13af 126 * @param[in] defaultAdvPowerLevelsIn
mbedAustin 23:05e9bb3b13af 127 * Default power-levels array; applies only if the resetToDefaultsFlag is true.
mbedAustin 34:5876fbb1aa62 128 * @param[in] defaultUriDataIn
mbedAustin 34:5876fbb1aa62 129 * Default un-encoded URI; optional parameter, applies only if the resetToDefaultsFlag is true
mbedAustin 34:5876fbb1aa62 130 * @param[in] defaultUIDNamespaceIDIn
mbedAustin 34:5876fbb1aa62 131 * Default 10Byte UID Namespace ID; optional parameter, applies only if the resetToDefaultsFlag is true
mbedAustin 34:5876fbb1aa62 132 * @param[in] defaultUIDInstanceIDIn
mbedAustin 34:5876fbb1aa62 133 * Default 6byte UID Instance ID; optional parameter, applies only if the resetToDefaultsFlag is true
mbedAustin 34:5876fbb1aa62 134 * @param[in] defaultTLMVersionIn
mbedAustin 34:5876fbb1aa62 135 * Default TLM version; defaults to 0, applies only if the resetToDefaultsFlag is true
mbedAustin 23:05e9bb3b13af 136 */
mbedAustin 23:05e9bb3b13af 137 EddystoneConfigService(BLEDevice &bleIn,
mbedAustin 23:05e9bb3b13af 138 Params_t &paramsIn,
mbedAustin 23:05e9bb3b13af 139 bool resetToDefaultsFlag,
mbedAustin 34:5876fbb1aa62 140 PowerLevels_t &defaultAdvPowerLevelsIn,
mbedAustin 34:5876fbb1aa62 141 const char *defaultURIDataIn = NULL,
mbedAustin 34:5876fbb1aa62 142 UIDNamespaceID_t *defaultUIDNamespaceIDIn = NULL,
mbedAustin 34:5876fbb1aa62 143 UIDInstanceID_t *defaultUIDInstanceIDIn = NULL,
mbedAustin 34:5876fbb1aa62 144 uint8_t defaultTLMVersionIn = 0) :
mbedAustin 23:05e9bb3b13af 145 ble(bleIn),
mbedAustin 31:11e7a505a4be 146 params(paramsIn), // Initialize URL Data
mbedAustin 23:05e9bb3b13af 147 defaultUriDataLength(),
mbedAustin 23:05e9bb3b13af 148 defaultUriData(),
mbedAustin 34:5876fbb1aa62 149 defaultUidNamespaceID(), // Initialize UID Data
mbedAustin 34:5876fbb1aa62 150 defaultUidInstanceID(),
mbedAustin 31:11e7a505a4be 151 defaultUrlPower(params.advPowerLevels[params.txPowerMode]),
mbedAustin 31:11e7a505a4be 152 defaultUidPower(params.advPowerLevels[params.txPowerMode]),
mbedAustin 31:11e7a505a4be 153 uidIsSet(true),
mbedAustin 31:11e7a505a4be 154 urlIsSet(true),
mbedAustin 23:05e9bb3b13af 155 defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
mbedAustin 23:05e9bb3b13af 156 initSucceeded(false),
mbedAustin 23:05e9bb3b13af 157 resetFlag(),
mbedAustin 34:5876fbb1aa62 158 lockedStateChar(UUID_LOCK_STATE_CHAR, &params.lockedState),
mbedAustin 34:5876fbb1aa62 159 TlmVersion(defaultTLMVersionIn), // Initialize TLM Data
mbedAustin 31:11e7a505a4be 160 TlmBatteryVoltage(0),
mbedAustin 31:11e7a505a4be 161 TlmBeaconTemp(0),
mbedAustin 31:11e7a505a4be 162 TlmPduCount(0),
mbedAustin 31:11e7a505a4be 163 TlmTimeSinceBoot(0),
mbedAustin 23:05e9bb3b13af 164 lockChar(UUID_LOCK_CHAR, &params.lock),
mbedAustin 23:05e9bb3b13af 165 uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
mbedAustin 23:05e9bb3b13af 166 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
mbedAustin 23:05e9bb3b13af 167 unlockChar(UUID_UNLOCK_CHAR, &params.lock),
mbedAustin 23:05e9bb3b13af 168 flagsChar(UUID_FLAGS_CHAR, &params.flags),
mbedAustin 23:05e9bb3b13af 169 advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, &params.advPowerLevels),
mbedAustin 23:05e9bb3b13af 170 txPowerModeChar(UUID_TX_POWER_MODE_CHAR, &params.txPowerMode),
mbedAustin 23:05e9bb3b13af 171 beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, &params.beaconPeriod),
mbedAustin 31:11e7a505a4be 172 resetChar(UUID_RESET_CHAR, &resetFlag)
mbedAustin 31:11e7a505a4be 173 {
mbedAustin 31:11e7a505a4be 174 //Set UID frame
mbedAustin 34:5876fbb1aa62 175 memcpy(defaultUidNamespaceID,defaultUIDNamespaceIDIn,UID_NAMESPACEID_SIZE);
mbedAustin 34:5876fbb1aa62 176 memcpy(defaultUidInstanceID,defaultUIDInstanceIDIn,UID_INSTANCEID_SIZE);
mbedAustin 31:11e7a505a4be 177
mbedAustin 31:11e7a505a4be 178 // Set URL Frame
mbedAustin 23:05e9bb3b13af 179 encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
mbedAustin 23:05e9bb3b13af 180 if (defaultUriDataLength > URI_DATA_MAX) {
mbedAustin 23:05e9bb3b13af 181 return;
mbedAustin 23:05e9bb3b13af 182 }
mbedAustin 23:05e9bb3b13af 183
mbedAustin 23:05e9bb3b13af 184 if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) {
mbedAustin 23:05e9bb3b13af 185 resetToDefaultsFlag = true;
mbedAustin 23:05e9bb3b13af 186 }
mbedAustin 23:05e9bb3b13af 187 if (resetToDefaultsFlag) {
mbedAustin 23:05e9bb3b13af 188 resetToDefaults();
mbedAustin 23:05e9bb3b13af 189 } else {
mbedAustin 23:05e9bb3b13af 190 updateCharacteristicValues();
mbedAustin 23:05e9bb3b13af 191 }
mbedAustin 23:05e9bb3b13af 192
mbedAustin 23:05e9bb3b13af 193 lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 194 unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 195 uriDataChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::uriDataWriteAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 196 flagsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
mbedAustin 23:05e9bb3b13af 197 advPowerLevelsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<PowerLevels_t>);
mbedAustin 23:05e9bb3b13af 198 txPowerModeChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::powerModeAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 199 beaconPeriodChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint16_t>);
mbedAustin 23:05e9bb3b13af 200 resetChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
mbedAustin 23:05e9bb3b13af 201
mbedAustin 23:05e9bb3b13af 202 static GattCharacteristic *charTable[] = {
mbedAustin 23:05e9bb3b13af 203 &lockedStateChar, &lockChar, &unlockChar, &uriDataChar,
mbedAustin 23:05e9bb3b13af 204 &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar
mbedAustin 23:05e9bb3b13af 205 };
mbedAustin 23:05e9bb3b13af 206
mbedAustin 23:05e9bb3b13af 207 GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
mbedAustin 23:05e9bb3b13af 208
mbedAustin 23:05e9bb3b13af 209 ble.addService(configService);
mbedAustin 23:05e9bb3b13af 210 ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback);
mbedAustin 23:05e9bb3b13af 211
mbedAustin 23:05e9bb3b13af 212 setupEddystoneConfigAdvertisements(); /* Setup advertising for the configService. */
mbedAustin 23:05e9bb3b13af 213
mbedAustin 23:05e9bb3b13af 214 initSucceeded = true;
mbedAustin 23:05e9bb3b13af 215 }
mbedAustin 23:05e9bb3b13af 216
mbedAustin 39:2c73bc1ff4f5 217 /*
mbedAustin 39:2c73bc1ff4f5 218 * Check if eddystone initialized successfully
mbedAustin 39:2c73bc1ff4f5 219 */
mbedAustin 39:2c73bc1ff4f5 220 bool initSuccessfully(void) const {
mbedAustin 23:05e9bb3b13af 221 return initSucceeded;
mbedAustin 23:05e9bb3b13af 222 }
mbedAustin 23:05e9bb3b13af 223
mbedAustin 23:05e9bb3b13af 224 /* Start out by advertising the configService for a limited time after
mbedAustin 23:05e9bb3b13af 225 * startup; and switch to the normal non-connectible beacon functionality
mbedAustin 23:05e9bb3b13af 226 * afterwards. */
mbedAustin 23:05e9bb3b13af 227 void setupEddystoneConfigAdvertisements() {
mbedAustin 23:05e9bb3b13af 228 const char DEVICE_NAME[] = "eddystone Config";
mbedAustin 23:05e9bb3b13af 229
mbedAustin 23:05e9bb3b13af 230 ble.clearAdvertisingPayload();
mbedAustin 23:05e9bb3b13af 231
mbedAustin 23:05e9bb3b13af 232 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbedAustin 23:05e9bb3b13af 233
mbedAustin 23:05e9bb3b13af 234 // UUID is in different order in the ADV frame (!)
mbedAustin 23:05e9bb3b13af 235 uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
mbedAustin 23:05e9bb3b13af 236 for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
mbedAustin 23:05e9bb3b13af 237 reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
mbedAustin 23:05e9bb3b13af 238 }
mbedAustin 23:05e9bb3b13af 239 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID));
mbedAustin 23:05e9bb3b13af 240 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
mbedAustin 23:05e9bb3b13af 241 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME));
mbedAustin 23:05e9bb3b13af 242 ble.accumulateScanResponse(
mbedAustin 23:05e9bb3b13af 243 GapAdvertisingData::TX_POWER_LEVEL,
mbedAustin 23:05e9bb3b13af 244 reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[EddystoneConfigService::TX_POWER_MODE_LOW]),
mbedAustin 23:05e9bb3b13af 245 sizeof(uint8_t));
mbedAustin 23:05e9bb3b13af 246
mbedAustin 23:05e9bb3b13af 247 ble.setTxPower(params.advPowerLevels[params.txPowerMode]);
mbedAustin 23:05e9bb3b13af 248 ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
mbedAustin 23:05e9bb3b13af 249 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbedAustin 34:5876fbb1aa62 250 ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
mbedAustin 23:05e9bb3b13af 251 }
mbedAustin 23:05e9bb3b13af 252
mbedAustin 23:05e9bb3b13af 253 /*
mbedAustin 25:e20bed9e466f 254 * This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function
mbedAustin 25:e20bed9e466f 255 * to load saved config params, or it can be called explicitly to reset the eddystone beacon to hardcoded values on each reset.
mbedAustin 25:e20bed9e466f 256 *
mbedAustin 25:e20bed9e466f 257 */
mbedAustin 23:05e9bb3b13af 258 void setupEddystoneAdvertisements() {
mbedAustin 23:05e9bb3b13af 259 DBG("Switching Config -> adv");
mbedAustin 36:ccb188bcfef1 260 //uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 36:ccb188bcfef1 261 //unsigned serviceDataLen = 0;
mbedAustin 36:ccb188bcfef1 262 //unsigned beaconPeriod = params.beaconPeriod;
mbedAustin 32:985642364cf5 263
mbedAustin 36:ccb188bcfef1 264 //setUIDFrameData(params.txPowerMode,defaultUidNamespaceID, defaultUidInstanceID);
mbedAustin 32:985642364cf5 265 //setURLFrameData(params.txPowerMode,(char *)params.uriData);
mbedAustin 23:05e9bb3b13af 266
mbedAustin 23:05e9bb3b13af 267 // Initialize Frame transition
mbedAustin 36:ccb188bcfef1 268 //frameIndex = 0;
mbedAustin 36:ccb188bcfef1 269 //uidRFU = 0;
mbedAustin 36:ccb188bcfef1 270 //switchFlag = true;
mbedAustin 23:05e9bb3b13af 271
mbedAustin 23:05e9bb3b13af 272
mbedAustin 23:05e9bb3b13af 273 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
mbedAustin 35:314f2152506f 274 // ble.shutdown();
mbedAustin 35:314f2152506f 275 // ble.init();
mbedAustin 35:314f2152506f 276 // ble.setTxPower(params.txPowerMode);
mbedAustin 35:314f2152506f 277 // ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbedAustin 35:314f2152506f 278 // ble.setAdvertisingInterval(beaconPeriod);
mbedAustin 23:05e9bb3b13af 279 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */
mbedAustin 23:05e9bb3b13af 280 saveURIBeaconConfigParams(&params);
mbedAustin 23:05e9bb3b13af 281
mbedAustin 36:ccb188bcfef1 282 static EddystoneService eddyServ(ble,params.beaconPeriod,params.txPowerMode, (uint8_t *) params.uidNamespaceID, (uint8_t *) params.uidInstanceID, (const char *) params.uriData, params.uriDataLength, params.tlmVersion );
mbedAustin 35:314f2152506f 283 // updateTlmPduCount(0);
mbedAustin 35:314f2152506f 284 // updateTlmTimeSinceBoot(0);
mbedAustin 23:05e9bb3b13af 285
mbedAustin 23:05e9bb3b13af 286 // Construct TLM Frame in initial advertising.
mbedAustin 35:314f2152506f 287 // serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 35:314f2152506f 288 // serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 35:314f2152506f 289 // serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,SERVICE_DATA_MAX);
mbedAustin 23:05e9bb3b13af 290
mbedAustin 35:314f2152506f 291 // updateAdvPacket(serviceData, serviceDataLen);
mbedAustin 35:314f2152506f 292 // ble.gap().startAdvertising();
mbedAustin 35:314f2152506f 293 // ble.gap().onRadioNotification(this,&EddystoneConfigService::radioNotificationCallback);
mbedAustin 35:314f2152506f 294 // timeSinceBootTick.attach(this,&EddystoneConfigService::tsbCallback,0.1); // incriment the TimeSinceBoot ticker every 0.1s
mbedAustin 23:05e9bb3b13af 295 }
mbedAustin 23:05e9bb3b13af 296
mbedAustin 23:05e9bb3b13af 297 private:
mbedAustin 23:05e9bb3b13af 298
mbedAustin 23:05e9bb3b13af 299 /*
mbedAustin 23:05e9bb3b13af 300 * This callback is invoked when a GATT client attempts to modify any of the
mbedAustin 23:05e9bb3b13af 301 * characteristics of this service. Attempts to do so are also applied to
mbedAustin 23:05e9bb3b13af 302 * the internal state of this service object.
mbedAustin 23:05e9bb3b13af 303 */
mbedAustin 23:05e9bb3b13af 304 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) {
mbedAustin 23:05e9bb3b13af 305 uint16_t handle = writeParams->handle;
mbedAustin 23:05e9bb3b13af 306
mbedAustin 23:05e9bb3b13af 307 if (handle == lockChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 308 // Validated earlier
mbedAustin 23:05e9bb3b13af 309 memcpy(params.lock, writeParams->data, sizeof(Lock_t));
roywant 38:8fdb16f67e7c 310 // Set the state to be locked by the lock code (note: zeros are a valid lock)
mbedAustin 34:5876fbb1aa62 311 params.lockedState = true;
mbedAustin 23:05e9bb3b13af 312 } else if (handle == unlockChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 313 // Validated earlier
mbedAustin 34:5876fbb1aa62 314 params.lockedState = false;
mbedAustin 23:05e9bb3b13af 315 } else if (handle == uriDataChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 316 params.uriDataLength = writeParams->len;
mbedAustin 23:05e9bb3b13af 317 memcpy(params.uriData, writeParams->data, params.uriDataLength);
mbedAustin 34:5876fbb1aa62 318 memcpy(defaultUriData, writeParams->data, params.uriDataLength);
mbedAustin 34:5876fbb1aa62 319 defaultUriDataLength = params.uriDataLength;
mbedAustin 34:5876fbb1aa62 320 INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len);
mbedAustin 23:05e9bb3b13af 321 } else if (handle == flagsChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 322 params.flags = *(writeParams->data);
mbedAustin 34:5876fbb1aa62 323 INFO("flagsChar = 0x%x",params.flags);
mbedAustin 23:05e9bb3b13af 324 } else if (handle == advPowerLevelsChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 325 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
mbedAustin 34:5876fbb1aa62 326 INFO("PowerLevelsChar = %4x",writeParams->data);
mbedAustin 23:05e9bb3b13af 327 } else if (handle == txPowerModeChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 328 params.txPowerMode = *(writeParams->data);
mbedAustin 34:5876fbb1aa62 329 INFO("TxPowerModeChar = %d",params.txPowerMode);
mbedAustin 23:05e9bb3b13af 330 } else if (handle == beaconPeriodChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 331 params.beaconPeriod = *((uint16_t *)(writeParams->data));
mbedAustin 23:05e9bb3b13af 332
mbedAustin 23:05e9bb3b13af 333 /* Re-map beaconPeriod to within permissible bounds if necessary. */
mbedAustin 23:05e9bb3b13af 334 if (params.beaconPeriod != 0) {
mbedAustin 23:05e9bb3b13af 335 bool paramsUpdated = false;
mbedAustin 23:05e9bb3b13af 336 if (params.beaconPeriod < ble.getMinAdvertisingInterval()) {
mbedAustin 23:05e9bb3b13af 337 params.beaconPeriod = ble.getMinAdvertisingInterval();
mbedAustin 23:05e9bb3b13af 338 paramsUpdated = true;
mbedAustin 23:05e9bb3b13af 339 } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) {
mbedAustin 23:05e9bb3b13af 340 params.beaconPeriod = ble.getMaxAdvertisingInterval();
mbedAustin 23:05e9bb3b13af 341 paramsUpdated = true;
mbedAustin 23:05e9bb3b13af 342 }
mbedAustin 23:05e9bb3b13af 343 if (paramsUpdated) {
mbedAustin 23:05e9bb3b13af 344 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
mbedAustin 23:05e9bb3b13af 345 }
mbedAustin 23:05e9bb3b13af 346 }
mbedAustin 23:05e9bb3b13af 347 } else if (handle == resetChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 348 resetToDefaults();
mbedAustin 23:05e9bb3b13af 349 }
roywant 38:8fdb16f67e7c 350 updateCharacteristicValues();
mbedAustin 23:05e9bb3b13af 351 }
mbedAustin 23:05e9bb3b13af 352
mbedAustin 23:05e9bb3b13af 353 /*
mbedAustin 23:05e9bb3b13af 354 * Reset the default values.
mbedAustin 23:05e9bb3b13af 355 */
mbedAustin 23:05e9bb3b13af 356 void resetToDefaults(void) {
mbedAustin 34:5876fbb1aa62 357 params.lockedState = false;
mbedAustin 23:05e9bb3b13af 358 memset(params.lock, 0, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 359 memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
mbedAustin 23:05e9bb3b13af 360 params.uriDataLength = defaultUriDataLength;
mbedAustin 34:5876fbb1aa62 361 params.flags = 0x10;
mbedAustin 23:05e9bb3b13af 362 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
mbedAustin 23:05e9bb3b13af 363 params.txPowerMode = TX_POWER_MODE_LOW;
mbedAustin 23:05e9bb3b13af 364 params.beaconPeriod = 1000;
mbedAustin 34:5876fbb1aa62 365 memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
mbedAustin 34:5876fbb1aa62 366 memcpy(params.uidInstanceID, defaultUidInstanceID, UID_INSTANCEID_SIZE);
mbedAustin 34:5876fbb1aa62 367 params.tlmVersion = TlmVersion;
mbedAustin 23:05e9bb3b13af 368 updateCharacteristicValues();
mbedAustin 23:05e9bb3b13af 369 }
mbedAustin 23:05e9bb3b13af 370
mbedAustin 23:05e9bb3b13af 371 /*
mbedAustin 23:05e9bb3b13af 372 * Internal helper function used to update the GATT database following any
mbedAustin 23:05e9bb3b13af 373 * change to the internal state of the service object.
mbedAustin 23:05e9bb3b13af 374 */
mbedAustin 23:05e9bb3b13af 375 void updateCharacteristicValues(void) {
mbedAustin 34:5876fbb1aa62 376 ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &params.lockedState, 1);
mbedAustin 23:05e9bb3b13af 377 ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
mbedAustin 23:05e9bb3b13af 378 ble.updateCharacteristicValue(flagsChar.getValueHandle(), &params.flags, 1);
mbedAustin 23:05e9bb3b13af 379 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(),
mbedAustin 23:05e9bb3b13af 380 reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
mbedAustin 23:05e9bb3b13af 381 ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), &params.txPowerMode, 1);
mbedAustin 23:05e9bb3b13af 382 ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(),
mbedAustin 23:05e9bb3b13af 383 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
mbedAustin 23:05e9bb3b13af 384 }
mbedAustin 23:05e9bb3b13af 385
mbedAustin 23:05e9bb3b13af 386 private:
mbedAustin 23:05e9bb3b13af 387 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 34:5876fbb1aa62 388 if (params.lockedState) {
mbedAustin 23:05e9bb3b13af 389 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 390 } else if (authParams->len != sizeof(Lock_t)) {
mbedAustin 23:05e9bb3b13af 391 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 392 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 393 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 394 } else {
mbedAustin 23:05e9bb3b13af 395 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 396 }
mbedAustin 23:05e9bb3b13af 397 }
mbedAustin 23:05e9bb3b13af 398
mbedAustin 23:05e9bb3b13af 399
mbedAustin 23:05e9bb3b13af 400 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 34:5876fbb1aa62 401 if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) {
mbedAustin 23:05e9bb3b13af 402 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 403 } else if (authParams->len != sizeof(Lock_t)) {
mbedAustin 23:05e9bb3b13af 404 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 405 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 406 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 407 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) {
mbedAustin 23:05e9bb3b13af 408 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 409 } else {
mbedAustin 23:05e9bb3b13af 410 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 411 }
mbedAustin 23:05e9bb3b13af 412 }
mbedAustin 23:05e9bb3b13af 413
mbedAustin 23:05e9bb3b13af 414 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 34:5876fbb1aa62 415 if (params.lockedState) {
mbedAustin 23:05e9bb3b13af 416 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 417 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 418 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 419 } else {
mbedAustin 23:05e9bb3b13af 420 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 421 }
mbedAustin 23:05e9bb3b13af 422 }
mbedAustin 23:05e9bb3b13af 423
mbedAustin 23:05e9bb3b13af 424 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 34:5876fbb1aa62 425 if (params.lockedState) {
mbedAustin 23:05e9bb3b13af 426 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 427 } else if (authParams->len != sizeof(uint8_t)) {
mbedAustin 23:05e9bb3b13af 428 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 429 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 430 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 431 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) {
mbedAustin 23:05e9bb3b13af 432 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
mbedAustin 23:05e9bb3b13af 433 } else {
mbedAustin 23:05e9bb3b13af 434 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 435 }
mbedAustin 23:05e9bb3b13af 436 }
mbedAustin 23:05e9bb3b13af 437
mbedAustin 23:05e9bb3b13af 438 template <typename T>
mbedAustin 23:05e9bb3b13af 439 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 34:5876fbb1aa62 440 if (params.lockedState) {
mbedAustin 23:05e9bb3b13af 441 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 442 } else if (authParams->len != sizeof(T)) {
mbedAustin 23:05e9bb3b13af 443 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 444 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 445 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 446 } else {
mbedAustin 23:05e9bb3b13af 447 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 448 }
mbedAustin 23:05e9bb3b13af 449 }
mbedAustin 23:05e9bb3b13af 450
mbedAustin 23:05e9bb3b13af 451 BLEDevice &ble;
mbedAustin 23:05e9bb3b13af 452 Params_t &params;
mbedAustin 23:05e9bb3b13af 453 Ticker timeSinceBootTick;
mbedAustin 23:05e9bb3b13af 454 Timeout switchFrame;
mbedAustin 23:05e9bb3b13af 455 // Default value that is restored on reset
mbedAustin 34:5876fbb1aa62 456 uint8_t defaultUriDataLength;
mbedAustin 23:05e9bb3b13af 457 UriData_t defaultUriData;
mbedAustin 23:05e9bb3b13af 458 UIDNamespaceID_t defaultUidNamespaceID;
mbedAustin 23:05e9bb3b13af 459 UIDInstanceID_t defaultUidInstanceID;
mbedAustin 23:05e9bb3b13af 460 int8_t defaultUidPower;
mbedAustin 23:05e9bb3b13af 461 int8_t defaultUrlPower;
mbedAustin 23:05e9bb3b13af 462 uint16_t uidRFU;
mbedAustin 25:e20bed9e466f 463 bool uidIsSet;
mbedAustin 25:e20bed9e466f 464 bool urlIsSet;
mbedAustin 23:05e9bb3b13af 465 // Default value that is restored on reset
mbedAustin 23:05e9bb3b13af 466 PowerLevels_t &defaultAdvPowerLevels;
mbedAustin 23:05e9bb3b13af 467 uint8_t lockedState;
mbedAustin 23:05e9bb3b13af 468 bool initSucceeded;
mbedAustin 23:05e9bb3b13af 469 uint8_t resetFlag;
mbedAustin 31:11e7a505a4be 470 bool switchFlag;
mbedAustin 23:05e9bb3b13af 471
mbedAustin 23:05e9bb3b13af 472 // Private Variables for Telemetry Data
mbedAustin 23:05e9bb3b13af 473 uint8_t TlmVersion;
mbedAustin 23:05e9bb3b13af 474 volatile uint16_t TlmBatteryVoltage;
mbedAustin 23:05e9bb3b13af 475 volatile uint16_t TlmBeaconTemp;
mbedAustin 23:05e9bb3b13af 476 volatile uint32_t TlmPduCount;
mbedAustin 23:05e9bb3b13af 477 volatile uint32_t TlmTimeSinceBoot;
mbedAustin 23:05e9bb3b13af 478
mbedAustin 23:05e9bb3b13af 479 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar;
mbedAustin 23:05e9bb3b13af 480 WriteOnlyGattCharacteristic<Lock_t> lockChar;
mbedAustin 23:05e9bb3b13af 481 GattCharacteristic uriDataChar;
mbedAustin 23:05e9bb3b13af 482 WriteOnlyGattCharacteristic<Lock_t> unlockChar;
mbedAustin 23:05e9bb3b13af 483 ReadWriteGattCharacteristic<uint8_t> flagsChar;
mbedAustin 23:05e9bb3b13af 484 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar;
mbedAustin 23:05e9bb3b13af 485 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar;
mbedAustin 23:05e9bb3b13af 486 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar;
mbedAustin 23:05e9bb3b13af 487 WriteOnlyGattCharacteristic<uint8_t> resetChar;
mbedAustin 23:05e9bb3b13af 488
mbedAustin 23:05e9bb3b13af 489 public:
mbedAustin 23:05e9bb3b13af 490 /*
mbedAustin 23:05e9bb3b13af 491 * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
mbedAustin 23:05e9bb3b13af 492 */
mbedAustin 34:5876fbb1aa62 493 static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, uint8_t &sizeofURIDataOut) {
mbedAustin 23:05e9bb3b13af 494 const char *prefixes[] = {
mbedAustin 23:05e9bb3b13af 495 "http://www.",
mbedAustin 23:05e9bb3b13af 496 "https://www.",
mbedAustin 23:05e9bb3b13af 497 "http://",
mbedAustin 23:05e9bb3b13af 498 "https://",
mbedAustin 23:05e9bb3b13af 499 };
mbedAustin 34:5876fbb1aa62 500 const uint8_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
mbedAustin 23:05e9bb3b13af 501 const char *suffixes[] = {
mbedAustin 23:05e9bb3b13af 502 ".com/",
mbedAustin 23:05e9bb3b13af 503 ".org/",
mbedAustin 23:05e9bb3b13af 504 ".edu/",
mbedAustin 23:05e9bb3b13af 505 ".net/",
mbedAustin 23:05e9bb3b13af 506 ".info/",
mbedAustin 23:05e9bb3b13af 507 ".biz/",
mbedAustin 23:05e9bb3b13af 508 ".gov/",
mbedAustin 23:05e9bb3b13af 509 ".com",
mbedAustin 23:05e9bb3b13af 510 ".org",
mbedAustin 23:05e9bb3b13af 511 ".edu",
mbedAustin 23:05e9bb3b13af 512 ".net",
mbedAustin 23:05e9bb3b13af 513 ".info",
mbedAustin 23:05e9bb3b13af 514 ".biz",
mbedAustin 23:05e9bb3b13af 515 ".gov"
mbedAustin 23:05e9bb3b13af 516 };
mbedAustin 34:5876fbb1aa62 517 const uint8_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
mbedAustin 23:05e9bb3b13af 518
mbedAustin 23:05e9bb3b13af 519 sizeofURIDataOut = 0;
mbedAustin 23:05e9bb3b13af 520 memset(uriDataOut, 0, sizeof(UriData_t));
mbedAustin 23:05e9bb3b13af 521
mbedAustin 23:05e9bb3b13af 522 if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) {
mbedAustin 23:05e9bb3b13af 523 return;
mbedAustin 23:05e9bb3b13af 524 }
mbedAustin 23:05e9bb3b13af 525
mbedAustin 23:05e9bb3b13af 526 /*
mbedAustin 23:05e9bb3b13af 527 * handle prefix
mbedAustin 23:05e9bb3b13af 528 */
mbedAustin 23:05e9bb3b13af 529 for (unsigned i = 0; i < NUM_PREFIXES; i++) {
mbedAustin 34:5876fbb1aa62 530 uint8_t prefixLen = strlen(prefixes[i]);
mbedAustin 23:05e9bb3b13af 531 if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
mbedAustin 23:05e9bb3b13af 532 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 23:05e9bb3b13af 533 uriDataIn += prefixLen;
mbedAustin 23:05e9bb3b13af 534 break;
mbedAustin 23:05e9bb3b13af 535 }
mbedAustin 23:05e9bb3b13af 536 }
mbedAustin 23:05e9bb3b13af 537
mbedAustin 23:05e9bb3b13af 538 /*
mbedAustin 23:05e9bb3b13af 539 * handle suffixes
mbedAustin 23:05e9bb3b13af 540 */
mbedAustin 23:05e9bb3b13af 541 while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) {
mbedAustin 23:05e9bb3b13af 542 /* check for suffix match */
mbedAustin 23:05e9bb3b13af 543 unsigned i;
mbedAustin 23:05e9bb3b13af 544 for (i = 0; i < NUM_SUFFIXES; i++) {
mbedAustin 34:5876fbb1aa62 545 uint8_t suffixLen = strlen(suffixes[i]);
mbedAustin 23:05e9bb3b13af 546 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
mbedAustin 23:05e9bb3b13af 547 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 23:05e9bb3b13af 548 uriDataIn += suffixLen;
mbedAustin 23:05e9bb3b13af 549 break; /* from the for loop for checking against suffixes */
mbedAustin 23:05e9bb3b13af 550 }
mbedAustin 23:05e9bb3b13af 551 }
mbedAustin 23:05e9bb3b13af 552 /* This is the default case where we've got an ordinary character which doesn't match a suffix. */
mbedAustin 23:05e9bb3b13af 553 if (i == NUM_SUFFIXES) {
mbedAustin 23:05e9bb3b13af 554 uriDataOut[sizeofURIDataOut++] = *uriDataIn;
mbedAustin 23:05e9bb3b13af 555 ++uriDataIn;
mbedAustin 23:05e9bb3b13af 556 }
mbedAustin 23:05e9bb3b13af 557 }
mbedAustin 23:05e9bb3b13af 558 }
mbedAustin 23:05e9bb3b13af 559 };
mbedAustin 23:05e9bb3b13af 560
mbedAustin 33:8c65879e7d52 561 #endif // SERVICES_EDDYSTONEBEACONCONFIGSERVICE_H_