Button initiated config service

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Committer:
mbedAustin
Date:
Fri Jul 24 02:06:57 2015 +0000
Revision:
25:e20bed9e466f
Parent:
23:05e9bb3b13af
Child:
31:11e7a505a4be
[[Debug]] added function to take all parameters for eddystone beacon, thus bypassing the need for config. Will get this working then go back to get config working.

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 23:05e9bb3b13af 17 #ifndef SERVICES_ZIPBEACONCONFIGSERVICE_H_
mbedAustin 23:05e9bb3b13af 18 #define SERVICES_ZIPBEACONCONFIGSERVICE_H_
mbedAustin 23:05e9bb3b13af 19
mbedAustin 23:05e9bb3b13af 20 #include "mbed.h"
mbedAustin 23:05e9bb3b13af 21 #include "ble/BLE.h"
mbedAustin 23:05e9bb3b13af 22
mbedAustin 23:05e9bb3b13af 23
mbedAustin 23:05e9bb3b13af 24 #define UUID_URI_BEACON(FIRST, SECOND) { \
mbedAustin 23:05e9bb3b13af 25 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \
mbedAustin 23:05e9bb3b13af 26 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \
mbedAustin 23:05e9bb3b13af 27 }
mbedAustin 23:05e9bb3b13af 28
mbedAustin 23:05e9bb3b13af 29 static const uint8_t UUID_URI_BEACON_SERVICE[] = UUID_URI_BEACON(0x20, 0x80);
mbedAustin 23:05e9bb3b13af 30 static const uint8_t UUID_LOCK_STATE_CHAR[] = UUID_URI_BEACON(0x20, 0x81);
mbedAustin 23:05e9bb3b13af 31 static const uint8_t UUID_LOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x82);
mbedAustin 23:05e9bb3b13af 32 static const uint8_t UUID_UNLOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x83);
mbedAustin 23:05e9bb3b13af 33 static const uint8_t UUID_URI_DATA_CHAR[] = UUID_URI_BEACON(0x20, 0x84);
mbedAustin 23:05e9bb3b13af 34 static const uint8_t UUID_FLAGS_CHAR[] = UUID_URI_BEACON(0x20, 0x85);
mbedAustin 23:05e9bb3b13af 35 static const uint8_t UUID_ADV_POWER_LEVELS_CHAR[] = UUID_URI_BEACON(0x20, 0x86);
mbedAustin 23:05e9bb3b13af 36 static const uint8_t UUID_TX_POWER_MODE_CHAR[] = UUID_URI_BEACON(0x20, 0x87);
mbedAustin 23:05e9bb3b13af 37 static const uint8_t UUID_BEACON_PERIOD_CHAR[] = UUID_URI_BEACON(0x20, 0x88);
mbedAustin 23:05e9bb3b13af 38 static const uint8_t UUID_RESET_CHAR[] = UUID_URI_BEACON(0x20, 0x89);
mbedAustin 23:05e9bb3b13af 39 static const uint8_t BEACON_EDDYSTONE[] = {0xAA, 0xFE};
mbedAustin 23:05e9bb3b13af 40
mbedAustin 23:05e9bb3b13af 41 //Debug is disabled by default
mbedAustin 23:05e9bb3b13af 42 #if 0
mbedAustin 23:05e9bb3b13af 43 #define DBG(x, ...) printf("[EddyStone: DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 23:05e9bb3b13af 44 #define WARN(x, ...) printf("[EddyStone: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 23:05e9bb3b13af 45 #define ERR(x, ...) printf("[EddyStone: ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 23:05e9bb3b13af 46 #else
mbedAustin 23:05e9bb3b13af 47 #define DBG(x, ...) //wait_us(10);
mbedAustin 23:05e9bb3b13af 48 #define WARN(x, ...) //wait_us(10);
mbedAustin 23:05e9bb3b13af 49 #define ERR(x, ...)
mbedAustin 23:05e9bb3b13af 50 #endif
mbedAustin 23:05e9bb3b13af 51
mbedAustin 23:05e9bb3b13af 52 /**
mbedAustin 23:05e9bb3b13af 53 * @class EddystoneConfigService
mbedAustin 23:05e9bb3b13af 54 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
mbedAustin 25:e20bed9e466f 55 * See https://github.com/google/eddystone
mbedAustin 23:05e9bb3b13af 56 *
mbedAustin 23:05e9bb3b13af 57 */
mbedAustin 23:05e9bb3b13af 58 class EddystoneConfigService
mbedAustin 23:05e9bb3b13af 59 {
mbedAustin 23:05e9bb3b13af 60 public:
mbedAustin 23:05e9bb3b13af 61 /**
mbedAustin 23:05e9bb3b13af 62 * @brief Transmission Power Modes for UriBeacon
mbedAustin 23:05e9bb3b13af 63 */
mbedAustin 23:05e9bb3b13af 64 static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */
mbedAustin 23:05e9bb3b13af 65 static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */
mbedAustin 23:05e9bb3b13af 66 static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */
mbedAustin 23:05e9bb3b13af 67 static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */
mbedAustin 23:05e9bb3b13af 68 static const unsigned int NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */
mbedAustin 23:05e9bb3b13af 69
mbedAustin 23:05e9bb3b13af 70 static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service.
mbedAustin 23:05e9bb3b13af 71 static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets
mbedAustin 23:05e9bb3b13af 72
mbedAustin 23:05e9bb3b13af 73 typedef uint8_t Lock_t[16]; /* 128 bits */
mbedAustin 23:05e9bb3b13af 74 typedef int8_t PowerLevels_t[NUM_POWER_MODES];
mbedAustin 23:05e9bb3b13af 75
mbedAustin 23:05e9bb3b13af 76 // There are currently 3 subframes defined, URI, UID, and TLM
mbedAustin 23:05e9bb3b13af 77 #define EDDYSTONE_MAX_FRAMETYPE 3
mbedAustin 23:05e9bb3b13af 78 void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t);
mbedAustin 23:05e9bb3b13af 79 uint8_t frameIndex;
mbedAustin 23:05e9bb3b13af 80 static const int URI_DATA_MAX = 18;
mbedAustin 23:05e9bb3b13af 81 typedef uint8_t UriData_t[URI_DATA_MAX];
mbedAustin 23:05e9bb3b13af 82
mbedAustin 23:05e9bb3b13af 83 // UID Frame Type subfields
mbedAustin 23:05e9bb3b13af 84 static const int UID_NAMESPACEID_SIZE = 10;
mbedAustin 23:05e9bb3b13af 85 typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
mbedAustin 23:05e9bb3b13af 86 static const int UID_INSTANCEID_SIZE = 6;
mbedAustin 23:05e9bb3b13af 87 typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE];
mbedAustin 23:05e9bb3b13af 88
mbedAustin 23:05e9bb3b13af 89 // Eddystone Frame Type ID
mbedAustin 23:05e9bb3b13af 90 static const uint8_t FRAME_TYPE_UID = 0x00;
mbedAustin 23:05e9bb3b13af 91 static const uint8_t FRAME_TYPE_URL = 0x10;
mbedAustin 23:05e9bb3b13af 92 static const uint8_t FRAME_TYPE_TLM = 0x20;
mbedAustin 23:05e9bb3b13af 93
mbedAustin 23:05e9bb3b13af 94 static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
mbedAustin 23:05e9bb3b13af 95 static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
mbedAustin 23:05e9bb3b13af 96
mbedAustin 23:05e9bb3b13af 97 struct Params_t {
mbedAustin 23:05e9bb3b13af 98 Lock_t lock;
mbedAustin 23:05e9bb3b13af 99 uint8_t uriDataLength;
mbedAustin 23:05e9bb3b13af 100 UriData_t uriData;
mbedAustin 23:05e9bb3b13af 101 uint8_t flags;
mbedAustin 23:05e9bb3b13af 102 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels
mbedAustin 23:05e9bb3b13af 103 uint8_t txPowerMode; // Firmware power levels used with setTxPower()
mbedAustin 23:05e9bb3b13af 104 uint16_t beaconPeriod;
mbedAustin 23:05e9bb3b13af 105 uint8_t tlmVersion; // version of TLM packet
mbedAustin 23:05e9bb3b13af 106 UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
mbedAustin 23:05e9bb3b13af 107 UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B
mbedAustin 25:e20bed9e466f 108 int(*tlmGetBatt(void)); // Function Pointers for user provided functions that return the Temp and Battery Voltage data for the TLM field.
mbedAustin 25:e20bed9e466f 109 int(*tlmGetTemp(void)); // ^^
mbedAustin 25:e20bed9e466f 110
mbedAustin 23:05e9bb3b13af 111 };
mbedAustin 23:05e9bb3b13af 112
mbedAustin 23:05e9bb3b13af 113 /**
mbedAustin 23:05e9bb3b13af 114 * @param[ref] ble
mbedAustin 23:05e9bb3b13af 115 * BLEDevice object for the underlying controller.
mbedAustin 23:05e9bb3b13af 116 * @param[in/out] paramsIn
mbedAustin 23:05e9bb3b13af 117 * Reference to application-visible beacon state, loaded
mbedAustin 23:05e9bb3b13af 118 * from persistent storage at startup.
mbedAustin 23:05e9bb3b13af 119 * @paramsP[in] resetToDefaultsFlag
mbedAustin 23:05e9bb3b13af 120 * Applies to the state of the 'paramsIn' parameter.
mbedAustin 23:05e9bb3b13af 121 * If true, it indicates that paramsIn is potentially
mbedAustin 23:05e9bb3b13af 122 * un-initialized, and default values should be used
mbedAustin 23:05e9bb3b13af 123 * instead. Otherwise, paramsIn overrides the defaults.
mbedAustin 23:05e9bb3b13af 124 * @param[in] defaultUriDataIn
mbedAustin 23:05e9bb3b13af 125 * Default un-encoded URI; applies only if the resetToDefaultsFlag is true.
mbedAustin 23:05e9bb3b13af 126 * @param[in] defaultAdvPowerLevelsIn
mbedAustin 23:05e9bb3b13af 127 * Default power-levels array; applies only if the resetToDefaultsFlag is true.
mbedAustin 23:05e9bb3b13af 128 */
mbedAustin 23:05e9bb3b13af 129 EddystoneConfigService(BLEDevice &bleIn,
mbedAustin 23:05e9bb3b13af 130 Params_t &paramsIn,
mbedAustin 23:05e9bb3b13af 131 bool resetToDefaultsFlag,
mbedAustin 23:05e9bb3b13af 132 const char *defaultURIDataIn,
mbedAustin 23:05e9bb3b13af 133 PowerLevels_t &defaultAdvPowerLevelsIn) :
mbedAustin 23:05e9bb3b13af 134 ble(bleIn),
mbedAustin 23:05e9bb3b13af 135 params(paramsIn),
mbedAustin 23:05e9bb3b13af 136 defaultUriDataLength(),
mbedAustin 23:05e9bb3b13af 137 defaultUriData(),
mbedAustin 23:05e9bb3b13af 138 defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
mbedAustin 23:05e9bb3b13af 139 initSucceeded(false),
mbedAustin 23:05e9bb3b13af 140 resetFlag(),
mbedAustin 23:05e9bb3b13af 141 lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState),
mbedAustin 23:05e9bb3b13af 142 lockChar(UUID_LOCK_CHAR, &params.lock),
mbedAustin 23:05e9bb3b13af 143 uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
mbedAustin 23:05e9bb3b13af 144 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
mbedAustin 23:05e9bb3b13af 145 unlockChar(UUID_UNLOCK_CHAR, &params.lock),
mbedAustin 23:05e9bb3b13af 146 flagsChar(UUID_FLAGS_CHAR, &params.flags),
mbedAustin 23:05e9bb3b13af 147 advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, &params.advPowerLevels),
mbedAustin 23:05e9bb3b13af 148 txPowerModeChar(UUID_TX_POWER_MODE_CHAR, &params.txPowerMode),
mbedAustin 23:05e9bb3b13af 149 beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, &params.beaconPeriod),
mbedAustin 23:05e9bb3b13af 150 resetChar(UUID_RESET_CHAR, &resetFlag) {
mbedAustin 23:05e9bb3b13af 151
mbedAustin 23:05e9bb3b13af 152 encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
mbedAustin 23:05e9bb3b13af 153 if (defaultUriDataLength > URI_DATA_MAX) {
mbedAustin 23:05e9bb3b13af 154 return;
mbedAustin 23:05e9bb3b13af 155 }
mbedAustin 23:05e9bb3b13af 156
mbedAustin 23:05e9bb3b13af 157 if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) {
mbedAustin 23:05e9bb3b13af 158 resetToDefaultsFlag = true;
mbedAustin 23:05e9bb3b13af 159 }
mbedAustin 23:05e9bb3b13af 160 if (resetToDefaultsFlag) {
mbedAustin 23:05e9bb3b13af 161 resetToDefaults();
mbedAustin 23:05e9bb3b13af 162 } else {
mbedAustin 23:05e9bb3b13af 163 updateCharacteristicValues();
mbedAustin 23:05e9bb3b13af 164 }
mbedAustin 23:05e9bb3b13af 165
mbedAustin 23:05e9bb3b13af 166 lockedState = isLocked();
mbedAustin 23:05e9bb3b13af 167
mbedAustin 23:05e9bb3b13af 168 lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 169 unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 170 uriDataChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::uriDataWriteAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 171 flagsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
mbedAustin 23:05e9bb3b13af 172 advPowerLevelsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<PowerLevels_t>);
mbedAustin 23:05e9bb3b13af 173 txPowerModeChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::powerModeAuthorizationCallback);
mbedAustin 23:05e9bb3b13af 174 beaconPeriodChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint16_t>);
mbedAustin 23:05e9bb3b13af 175 resetChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
mbedAustin 23:05e9bb3b13af 176
mbedAustin 23:05e9bb3b13af 177 static GattCharacteristic *charTable[] = {
mbedAustin 23:05e9bb3b13af 178 &lockedStateChar, &lockChar, &unlockChar, &uriDataChar,
mbedAustin 23:05e9bb3b13af 179 &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar
mbedAustin 23:05e9bb3b13af 180 };
mbedAustin 23:05e9bb3b13af 181
mbedAustin 23:05e9bb3b13af 182 GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
mbedAustin 23:05e9bb3b13af 183
mbedAustin 23:05e9bb3b13af 184 ble.addService(configService);
mbedAustin 23:05e9bb3b13af 185 ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback);
mbedAustin 23:05e9bb3b13af 186
mbedAustin 23:05e9bb3b13af 187 setupEddystoneConfigAdvertisements(); /* Setup advertising for the configService. */
mbedAustin 23:05e9bb3b13af 188
mbedAustin 23:05e9bb3b13af 189 initSucceeded = true;
mbedAustin 23:05e9bb3b13af 190 }
mbedAustin 23:05e9bb3b13af 191
mbedAustin 23:05e9bb3b13af 192 bool configuredSuccessfully(void) const {
mbedAustin 23:05e9bb3b13af 193 return initSucceeded;
mbedAustin 23:05e9bb3b13af 194 }
mbedAustin 23:05e9bb3b13af 195
mbedAustin 23:05e9bb3b13af 196 /* Start out by advertising the configService for a limited time after
mbedAustin 23:05e9bb3b13af 197 * startup; and switch to the normal non-connectible beacon functionality
mbedAustin 23:05e9bb3b13af 198 * afterwards. */
mbedAustin 23:05e9bb3b13af 199 void setupEddystoneConfigAdvertisements() {
mbedAustin 23:05e9bb3b13af 200 const char DEVICE_NAME[] = "eddystone Config";
mbedAustin 23:05e9bb3b13af 201
mbedAustin 23:05e9bb3b13af 202 ble.clearAdvertisingPayload();
mbedAustin 23:05e9bb3b13af 203
mbedAustin 23:05e9bb3b13af 204 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbedAustin 23:05e9bb3b13af 205
mbedAustin 23:05e9bb3b13af 206 // UUID is in different order in the ADV frame (!)
mbedAustin 23:05e9bb3b13af 207 uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
mbedAustin 23:05e9bb3b13af 208 for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
mbedAustin 23:05e9bb3b13af 209 reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
mbedAustin 23:05e9bb3b13af 210 }
mbedAustin 23:05e9bb3b13af 211 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID));
mbedAustin 23:05e9bb3b13af 212 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
mbedAustin 23:05e9bb3b13af 213 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME));
mbedAustin 23:05e9bb3b13af 214 ble.accumulateScanResponse(
mbedAustin 23:05e9bb3b13af 215 GapAdvertisingData::TX_POWER_LEVEL,
mbedAustin 23:05e9bb3b13af 216 reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[EddystoneConfigService::TX_POWER_MODE_LOW]),
mbedAustin 23:05e9bb3b13af 217 sizeof(uint8_t));
mbedAustin 23:05e9bb3b13af 218
mbedAustin 23:05e9bb3b13af 219 ble.setTxPower(params.advPowerLevels[params.txPowerMode]);
mbedAustin 23:05e9bb3b13af 220 ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
mbedAustin 23:05e9bb3b13af 221 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbedAustin 23:05e9bb3b13af 222 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
mbedAustin 23:05e9bb3b13af 223 }
mbedAustin 23:05e9bb3b13af 224
mbedAustin 23:05e9bb3b13af 225 /*
mbedAustin 23:05e9bb3b13af 226 * Set Eddystone UID Frame information.
mbedAustin 23:05e9bb3b13af 227 * @param[in] power TX Power in dB measured at 0 meters from the device. Range of -100 to +20 dB.
mbedAustin 23:05e9bb3b13af 228 * @param namespaceID 10B namespace ID
mbedAustin 23:05e9bb3b13af 229 * @param instanceID 6B instance ID
mbedAustin 23:05e9bb3b13af 230 * @param RFU 2B of RFU, initialized to 0x0000 and not broadcast, included for future reference.
mbedAustin 23:05e9bb3b13af 231 *
mbedAustin 23:05e9bb3b13af 232 */
mbedAustin 23:05e9bb3b13af 233 void setUIDFrameData(int8_t power, UIDNamespaceID_t namespaceID, UIDInstanceID_t instanceID, uint16_t RFU = 0x0000) {
mbedAustin 23:05e9bb3b13af 234 if(power > 20) {
mbedAustin 23:05e9bb3b13af 235 power = 20;
mbedAustin 23:05e9bb3b13af 236 }
mbedAustin 23:05e9bb3b13af 237 if(power < -100) {
mbedAustin 23:05e9bb3b13af 238 power = -100;
mbedAustin 23:05e9bb3b13af 239 }
mbedAustin 23:05e9bb3b13af 240 defaultUidPower = power;
mbedAustin 23:05e9bb3b13af 241 memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
mbedAustin 23:05e9bb3b13af 242 memcpy(defaultUidInstanceID, instanceID, UID_INSTANCEID_SIZE);
mbedAustin 23:05e9bb3b13af 243 uidRFU = (uint16_t)RFU; // this is probably bad form, but it doesnt really matter yet.
mbedAustin 23:05e9bb3b13af 244 return;
mbedAustin 23:05e9bb3b13af 245 }
mbedAustin 23:05e9bb3b13af 246
mbedAustin 23:05e9bb3b13af 247 /*
mbedAustin 23:05e9bb3b13af 248 * Construct UID frame from private variables
mbedAustin 23:05e9bb3b13af 249 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 23:05e9bb3b13af 250 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 23:05e9bb3b13af 251 * @return number of bytes used. negative number indicates error message.
mbedAustin 23:05e9bb3b13af 252 */
mbedAustin 23:05e9bb3b13af 253 int constructUIDFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 23:05e9bb3b13af 254
mbedAustin 23:05e9bb3b13af 255 int index = 0;
mbedAustin 23:05e9bb3b13af 256 Data[index++] = FRAME_TYPE_UID; // 1B Type
mbedAustin 23:05e9bb3b13af 257 if(defaultUidPower > 20) {
mbedAustin 23:05e9bb3b13af 258 defaultUidPower = 20; // enforce range of vaild values.
mbedAustin 23:05e9bb3b13af 259 }
mbedAustin 23:05e9bb3b13af 260 if(defaultUidPower < -100) {
mbedAustin 23:05e9bb3b13af 261 defaultUidPower = -100;
mbedAustin 23:05e9bb3b13af 262 }
mbedAustin 23:05e9bb3b13af 263 Data[index++] = defaultUidPower; // 1B Power @ 0meter
mbedAustin 23:05e9bb3b13af 264 for(int x = 0; x < UID_NAMESPACEID_SIZE; x++) { // 10B Namespce ID
mbedAustin 23:05e9bb3b13af 265 Data[index++] = defaultUidNamespaceID[x];
mbedAustin 23:05e9bb3b13af 266 }
mbedAustin 23:05e9bb3b13af 267 for(int x = 0; x< UID_INSTANCEID_SIZE; x++) { // 6B Instance ID
mbedAustin 23:05e9bb3b13af 268 Data[index++] = defaultUidInstanceID[x];
mbedAustin 23:05e9bb3b13af 269 }
mbedAustin 23:05e9bb3b13af 270 if(0 != uidRFU) { // 2B RFU, include if non-zero, otherwise ignore
mbedAustin 23:05e9bb3b13af 271 Data[index++] = (uint8_t)(uidRFU >> 0);
mbedAustin 23:05e9bb3b13af 272 Data[index++] = (uint8_t)(uidRFU >> 8);
mbedAustin 23:05e9bb3b13af 273 }
mbedAustin 23:05e9bb3b13af 274 DBG("construcUIDFrame %d, %d",maxSize,index);
mbedAustin 23:05e9bb3b13af 275 return index;
mbedAustin 23:05e9bb3b13af 276 }
mbedAustin 23:05e9bb3b13af 277
mbedAustin 23:05e9bb3b13af 278 /*
mbedAustin 23:05e9bb3b13af 279 * Set Eddystone URL Frame information.
mbedAustin 23:05e9bb3b13af 280 * @param[in] power TX Power in dB measured at 0 meters from the device.
mbedAustin 23:05e9bb3b13af 281 * @param url URL to encode
mbedAustin 23:05e9bb3b13af 282 * @return false on success, true on failure.
mbedAustin 23:05e9bb3b13af 283 */
mbedAustin 23:05e9bb3b13af 284 bool setURLFrameData(int8_t power, const char * url) {
mbedAustin 23:05e9bb3b13af 285 defaultUrlPower = power;
mbedAustin 23:05e9bb3b13af 286 encodeURI(url, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
mbedAustin 23:05e9bb3b13af 287 if (defaultUriDataLength > URI_DATA_MAX) {
mbedAustin 23:05e9bb3b13af 288 return true; // error, URL is too big
mbedAustin 23:05e9bb3b13af 289 }
mbedAustin 23:05e9bb3b13af 290 return false;
mbedAustin 23:05e9bb3b13af 291 }
mbedAustin 23:05e9bb3b13af 292
mbedAustin 23:05e9bb3b13af 293 /*
mbedAustin 23:05e9bb3b13af 294 * Construct URL frame from private variables
mbedAustin 23:05e9bb3b13af 295 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 23:05e9bb3b13af 296 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 23:05e9bb3b13af 297 * @return number of bytes used. negative number indicates error message.
mbedAustin 23:05e9bb3b13af 298 */
mbedAustin 23:05e9bb3b13af 299 int constructURLFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 23:05e9bb3b13af 300 int index = 0;
mbedAustin 23:05e9bb3b13af 301 Data[index++] = FRAME_TYPE_URL; // 1B Type
mbedAustin 25:e20bed9e466f 302 Data[index++] = defaultUrlPower; // 1B TX Power
mbedAustin 23:05e9bb3b13af 303 for(int x = 0; x < defaultUriDataLength; x++) { // 18B of URL Prefix + encoded URL
mbedAustin 23:05e9bb3b13af 304 Data[index++] = defaultUriData[x];
mbedAustin 23:05e9bb3b13af 305 }
mbedAustin 23:05e9bb3b13af 306 DBG("constructURLFrame: %d, %d",maxSize,index);
mbedAustin 23:05e9bb3b13af 307 return index;
mbedAustin 23:05e9bb3b13af 308 }
mbedAustin 23:05e9bb3b13af 309
mbedAustin 23:05e9bb3b13af 310 /*
mbedAustin 23:05e9bb3b13af 311 * Set Eddystone TLM Frame information.
mbedAustin 23:05e9bb3b13af 312 * @param[in] Version of the TLM beacon data format
mbedAustin 23:05e9bb3b13af 313 * @param batteryVoltage in milivolts
mbedAustin 23:05e9bb3b13af 314 * @param beaconTemp in 8.8 floating point notation
mbedAustin 23:05e9bb3b13af 315 *
mbedAustin 23:05e9bb3b13af 316 */
mbedAustin 23:05e9bb3b13af 317 void setTLMFrameData(uint8_t version, uint16_t batteryVoltage, uint16_t beaconTemp, uint32_t pduCount = 0, uint32_t timeSinceBoot = 0) {
mbedAustin 23:05e9bb3b13af 318 TlmVersion = version;
mbedAustin 23:05e9bb3b13af 319 TlmBatteryVoltage = batteryVoltage;
mbedAustin 23:05e9bb3b13af 320 TlmBeaconTemp = beaconTemp;
mbedAustin 23:05e9bb3b13af 321 TlmPduCount = pduCount; // reset
mbedAustin 23:05e9bb3b13af 322 TlmTimeSinceBoot = timeSinceBoot; // reset
mbedAustin 23:05e9bb3b13af 323 return;
mbedAustin 23:05e9bb3b13af 324 }
mbedAustin 23:05e9bb3b13af 325
mbedAustin 23:05e9bb3b13af 326 /*
mbedAustin 23:05e9bb3b13af 327 * Construct TLM frame from private variables
mbedAustin 23:05e9bb3b13af 328 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 23:05e9bb3b13af 329 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 23:05e9bb3b13af 330 * @return number of bytes used. negative number indicates error message.
mbedAustin 23:05e9bb3b13af 331 */
mbedAustin 23:05e9bb3b13af 332 int constructTLMFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 23:05e9bb3b13af 333 int index = 0;
mbedAustin 23:05e9bb3b13af 334 Data[index++] = FRAME_TYPE_TLM; // Eddystone frame type = Telemetry
mbedAustin 23:05e9bb3b13af 335 Data[index++] = TlmVersion; // TLM Version Number
mbedAustin 23:05e9bb3b13af 336 Data[index++] = (uint8_t)(TlmBatteryVoltage>>8); // Battery Voltage[0]
mbedAustin 23:05e9bb3b13af 337 Data[index++] = (uint8_t)(TlmBatteryVoltage>>0); // Battery Voltage[1]
mbedAustin 23:05e9bb3b13af 338 Data[index++] = (uint8_t)(TlmBeaconTemp>>8); // Beacon Temp[0]
mbedAustin 23:05e9bb3b13af 339 Data[index++] = (uint8_t)(TlmBeaconTemp>>0); // Beacon Temp[1]
mbedAustin 23:05e9bb3b13af 340 Data[index++] = (uint8_t)(TlmPduCount>>24); // PDU Count [0]
mbedAustin 23:05e9bb3b13af 341 Data[index++] = (uint8_t)(TlmPduCount>>16); // PDU Count [1]
mbedAustin 23:05e9bb3b13af 342 Data[index++] = (uint8_t)(TlmPduCount>>8); // PDU Count [2]
mbedAustin 23:05e9bb3b13af 343 Data[index++] = (uint8_t)(TlmPduCount>>0); // PDU Count [3]
mbedAustin 23:05e9bb3b13af 344 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>24); // Time Since Boot [0]
mbedAustin 23:05e9bb3b13af 345 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>16); // Time Since Boot [1]
mbedAustin 23:05e9bb3b13af 346 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>8); // Time Since Boot [2]
mbedAustin 23:05e9bb3b13af 347 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>0); // Time Since Boot [3]
mbedAustin 23:05e9bb3b13af 348 DBG("constructURLFrame: %d, %d",maxSize,index);
mbedAustin 23:05e9bb3b13af 349 return index;
mbedAustin 23:05e9bb3b13af 350 }
mbedAustin 23:05e9bb3b13af 351
mbedAustin 23:05e9bb3b13af 352 /*
mbedAustin 23:05e9bb3b13af 353 * Update the TLM frame battery voltage value
mbedAustin 23:05e9bb3b13af 354 * @param[in] voltagemv Voltage to update the TLM field battery voltage with (in mV)
mbedAustin 23:05e9bb3b13af 355 * @return nothing
mbedAustin 23:05e9bb3b13af 356 */
mbedAustin 23:05e9bb3b13af 357 void updateTlmBatteryVoltage(uint16_t voltagemv) {
mbedAustin 23:05e9bb3b13af 358 TlmBatteryVoltage = voltagemv;
mbedAustin 23:05e9bb3b13af 359 return;
mbedAustin 23:05e9bb3b13af 360 }
mbedAustin 23:05e9bb3b13af 361
mbedAustin 23:05e9bb3b13af 362 /*
mbedAustin 23:05e9bb3b13af 363 * Update the TLM frame beacon temperature
mbedAustin 23:05e9bb3b13af 364 * @param[in] temp Temperature of beacon (in 8.8fpn)
mbedAustin 23:05e9bb3b13af 365 * @return nothing
mbedAustin 23:05e9bb3b13af 366 */
mbedAustin 23:05e9bb3b13af 367 void updateTlmBeaconTemp(uint16_t temp) {
mbedAustin 23:05e9bb3b13af 368 TlmBeaconTemp = temp;
mbedAustin 23:05e9bb3b13af 369 return;
mbedAustin 23:05e9bb3b13af 370 }
mbedAustin 23:05e9bb3b13af 371
mbedAustin 23:05e9bb3b13af 372 /*
mbedAustin 23:05e9bb3b13af 373 * Update the TLM frame PDU Count field
mbedAustin 23:05e9bb3b13af 374 * @param[in] pduCount Number of Advertisiting frames sent since powerup
mbedAustin 23:05e9bb3b13af 375 * @return nothing
mbedAustin 23:05e9bb3b13af 376 */
mbedAustin 23:05e9bb3b13af 377 void updateTlmPduCount(uint32_t pduCount) {
mbedAustin 23:05e9bb3b13af 378 TlmPduCount = pduCount;
mbedAustin 23:05e9bb3b13af 379 return;
mbedAustin 23:05e9bb3b13af 380 }
mbedAustin 23:05e9bb3b13af 381
mbedAustin 23:05e9bb3b13af 382 /*
mbedAustin 23:05e9bb3b13af 383 * Update the TLM frame Time since boot in 0.1s incriments
mbedAustin 23:05e9bb3b13af 384 * @param[in] timeSinceBoot Time since boot in 0.1s incriments
mbedAustin 23:05e9bb3b13af 385 * @return nothing
mbedAustin 23:05e9bb3b13af 386 */
mbedAustin 23:05e9bb3b13af 387 void updateTlmTimeSinceBoot(uint32_t timeSinceBoot) {
mbedAustin 23:05e9bb3b13af 388 TlmTimeSinceBoot = timeSinceBoot;
mbedAustin 23:05e9bb3b13af 389 return;
mbedAustin 23:05e9bb3b13af 390 }
mbedAustin 23:05e9bb3b13af 391
mbedAustin 23:05e9bb3b13af 392 /*
mbedAustin 23:05e9bb3b13af 393 * callback function, called every 0.1s, incriments the TimeSinceBoot field in the TLM frame
mbedAustin 23:05e9bb3b13af 394 * @return nothing
mbedAustin 23:05e9bb3b13af 395 */
mbedAustin 23:05e9bb3b13af 396 void tsbCallback(void) {
mbedAustin 23:05e9bb3b13af 397 TlmTimeSinceBoot++;
mbedAustin 23:05e9bb3b13af 398 }
mbedAustin 23:05e9bb3b13af 399
mbedAustin 23:05e9bb3b13af 400 /*
mbedAustin 23:05e9bb3b13af 401 * Update advertising data
mbedAustin 23:05e9bb3b13af 402 * @return true on success, false on failure
mbedAustin 23:05e9bb3b13af 403 */
mbedAustin 23:05e9bb3b13af 404 bool updateAdvPacket(uint8_t serviceData[], unsigned serviceDataLen) {
mbedAustin 23:05e9bb3b13af 405 // Fields from the Service
mbedAustin 23:05e9bb3b13af 406 DBG("Updating AdvFrame: %d", serviceDataLen);
mbedAustin 23:05e9bb3b13af 407 // printf("\r\n");
mbedAustin 23:05e9bb3b13af 408 // for(int x = 0; x<serviceDataLen; x++) {
mbedAustin 23:05e9bb3b13af 409 // printf("%2.2x:",serviceData[x]);
mbedAustin 23:05e9bb3b13af 410 // }
mbedAustin 23:05e9bb3b13af 411 // printf("\r\n");
mbedAustin 23:05e9bb3b13af 412 ble.clearAdvertisingPayload();
mbedAustin 23:05e9bb3b13af 413 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbedAustin 23:05e9bb3b13af 414 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_EDDYSTONE, sizeof(BEACON_EDDYSTONE));
mbedAustin 23:05e9bb3b13af 415 ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
mbedAustin 23:05e9bb3b13af 416
mbedAustin 23:05e9bb3b13af 417 return true;
mbedAustin 23:05e9bb3b13af 418 }
mbedAustin 23:05e9bb3b13af 419
mbedAustin 23:05e9bb3b13af 420 /*
mbedAustin 23:05e9bb3b13af 421 * State machine for switching out frames.
mbedAustin 23:05e9bb3b13af 422 * This function is called by the radioNotificationCallback when a frame needs to get swapped out.
mbedAustin 23:05e9bb3b13af 423 * This function exists because of time constraints in the radioNotificationCallback, so it is effectively
mbedAustin 23:05e9bb3b13af 424 * broken up into two functions.
mbedAustin 23:05e9bb3b13af 425 */
mbedAustin 23:05e9bb3b13af 426 void swapOutFrames(void) {
mbedAustin 23:05e9bb3b13af 427 uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 23:05e9bb3b13af 428 unsigned serviceDataLen = 0;
mbedAustin 23:05e9bb3b13af 429 //hard code in the eddystone UUID
mbedAustin 23:05e9bb3b13af 430 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 23:05e9bb3b13af 431 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 23:05e9bb3b13af 432
mbedAustin 25:e20bed9e466f 433 // if certain frames are not enabled, then skip them. Worst case TLM is always enabled
mbedAustin 23:05e9bb3b13af 434 switch(frameIndex) {
mbedAustin 25:e20bed9e466f 435 case 1:
mbedAustin 25:e20bed9e466f 436 // URL Frame
mbedAustin 25:e20bed9e466f 437 if(urlIsSet) {
mbedAustin 25:e20bed9e466f 438 serviceDataLen += constructURLFrame(serviceData+serviceDataLen,20);
mbedAustin 25:e20bed9e466f 439 DBG("\t Swapping in URL Frame: len=%d ",serviceDataLen);
mbedAustin 25:e20bed9e466f 440 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 25:e20bed9e466f 441 switchFlag = false;
mbedAustin 25:e20bed9e466f 442 frameIndex++;
mbedAustin 25:e20bed9e466f 443 break;
mbedAustin 25:e20bed9e466f 444 }
mbedAustin 25:e20bed9e466f 445 case 2:
mbedAustin 25:e20bed9e466f 446 // UID Frame
mbedAustin 25:e20bed9e466f 447 if(uidIsSet) {
mbedAustin 25:e20bed9e466f 448 serviceDataLen += constructUIDFrame(serviceData+serviceDataLen,20);
mbedAustin 25:e20bed9e466f 449 DBG("\t Swapping in UID Frame: len=%d",serviceDataLen);
mbedAustin 25:e20bed9e466f 450 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 25:e20bed9e466f 451 switchFlag = false;
mbedAustin 25:e20bed9e466f 452 frameIndex++;
mbedAustin 25:e20bed9e466f 453 break;
mbedAustin 25:e20bed9e466f 454 }
mbedAustin 25:e20bed9e466f 455 default:
mbedAustin 25:e20bed9e466f 456 // TLM frame
mbedAustin 23:05e9bb3b13af 457 serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,20);
mbedAustin 23:05e9bb3b13af 458 DBG("\t Swapping in TLM Frame: len=%d",serviceDataLen);
mbedAustin 23:05e9bb3b13af 459 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 23:05e9bb3b13af 460 frameIndex++;
mbedAustin 23:05e9bb3b13af 461 break;
mbedAustin 23:05e9bb3b13af 462 }
mbedAustin 23:05e9bb3b13af 463 }
mbedAustin 23:05e9bb3b13af 464
mbedAustin 23:05e9bb3b13af 465 /*
mbedAustin 23:05e9bb3b13af 466 * Callback from onRadioNotification(), used to update the PDUCounter and process next state.
mbedAustin 23:05e9bb3b13af 467 */
mbedAustin 25:e20bed9e466f 468 #define EDDYSTONE_SWAPFRAME_DELAYMS 1
mbedAustin 23:05e9bb3b13af 469 void radioNotificationCallback(bool radioActive) {
mbedAustin 23:05e9bb3b13af 470 //DBG("RadioNotificationCallback : %d, %d, %d, %d",radioActive,frameIndex,TlmPduCount,TlmTimeSinceBoot);
mbedAustin 23:05e9bb3b13af 471 // Update PDUCount
mbedAustin 23:05e9bb3b13af 472 TlmPduCount++;
mbedAustin 23:05e9bb3b13af 473 frameIndex = frameIndex % EDDYSTONE_MAX_FRAMETYPE;
mbedAustin 23:05e9bb3b13af 474
mbedAustin 23:05e9bb3b13af 475
mbedAustin 23:05e9bb3b13af 476 // True just before an frame is sent, fale just after a frame is sent
mbedAustin 23:05e9bb3b13af 477 if(radioActive) {
mbedAustin 23:05e9bb3b13af 478 // Do Nothing
mbedAustin 23:05e9bb3b13af 479 } else {
mbedAustin 23:05e9bb3b13af 480 // state machine to control which packet is being sent
mbedAustin 23:05e9bb3b13af 481 switch(frameIndex) {
mbedAustin 25:e20bed9e466f 482 case 0: // TLM Frame
mbedAustin 23:05e9bb3b13af 483 switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 23:05e9bb3b13af 484 switchFlag = true;
mbedAustin 23:05e9bb3b13af 485 break;
mbedAustin 25:e20bed9e466f 486 case 1: // URL Frame
mbedAustin 23:05e9bb3b13af 487 // switch out packets
mbedAustin 23:05e9bb3b13af 488 if(switchFlag) {
mbedAustin 23:05e9bb3b13af 489 switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 23:05e9bb3b13af 490 switchFlag = false;
mbedAustin 23:05e9bb3b13af 491 } else {
mbedAustin 23:05e9bb3b13af 492 if((TlmPduCount % 10) == 0) { // every 10 adv packets switch the frame
mbedAustin 23:05e9bb3b13af 493 switchFlag = true;
mbedAustin 23:05e9bb3b13af 494 }
mbedAustin 23:05e9bb3b13af 495 }
mbedAustin 23:05e9bb3b13af 496 break;
mbedAustin 25:e20bed9e466f 497 case 2: // UIDFrame
mbedAustin 23:05e9bb3b13af 498 // switch out packets
mbedAustin 25:e20bed9e466f 499 if(switchFlag ) {
mbedAustin 23:05e9bb3b13af 500 switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 23:05e9bb3b13af 501 switchFlag = false;
mbedAustin 23:05e9bb3b13af 502 } else {
mbedAustin 23:05e9bb3b13af 503 if((TlmPduCount % 10) == 0) { // every 10 adv packets switch the frame
mbedAustin 23:05e9bb3b13af 504 switchFlag = true;
mbedAustin 23:05e9bb3b13af 505 }
mbedAustin 23:05e9bb3b13af 506 }
mbedAustin 23:05e9bb3b13af 507 break;
mbedAustin 23:05e9bb3b13af 508 }
mbedAustin 23:05e9bb3b13af 509 }
mbedAustin 23:05e9bb3b13af 510
mbedAustin 23:05e9bb3b13af 511 return;
mbedAustin 23:05e9bb3b13af 512 }
mbedAustin 23:05e9bb3b13af 513
mbedAustin 25:e20bed9e466f 514 /*
mbedAustin 25:e20bed9e466f 515 * This function explicityly sets the parameters used by the Eddystone beacon.
mbedAustin 25:e20bed9e466f 516 * this function should be used in leu of the config service.
mbedAustin 25:e20bed9e466f 517 *
mbedAustin 25:e20bed9e466f 518 * @param bleIn ble object used to broadcast eddystone information
mbedAustin 25:e20bed9e466f 519 * @oaram beaconPeriodus is how often ble broadcasts are mde, in mili seconds
mbedAustin 25:e20bed9e466f 520 * @param txPowerLevel sets the broadcasting power level.
mbedAustin 25:e20bed9e466f 521 * @param uidNamespaceID 10Byte Namespace UUID
mbedAustin 25:e20bed9e466f 522 * @param uidInstanceID 6Byte Instance UUID
mbedAustin 25:e20bed9e466f 523 * @param url shortened URL to broadcast (pass in as a string)
mbedAustin 25:e20bed9e466f 524 * @param urlLen length of shortened url
mbedAustin 25:e20bed9e466f 525 * @param tlmVersion version of telemetry data field to use (default to 0x00)
mbedAustin 25:e20bed9e466f 526 *
mbedAustin 25:e20bed9e466f 527 */
mbedAustin 25:e20bed9e466f 528 void setupEddystoneAdvertisements( BLEDevice &bleIn,
mbedAustin 25:e20bed9e466f 529 uint16_t beaconPeriodus,
mbedAustin 25:e20bed9e466f 530 uint8_t txPowerLevel,
mbedAustin 25:e20bed9e466f 531 uint8_t * uidNamespaceID = NULL,
mbedAustin 25:e20bed9e466f 532 uint8_t * uidInstanceID = NULL,
mbedAustin 25:e20bed9e466f 533 const char * url = NULL,
mbedAustin 25:e20bed9e466f 534 uint8_t urlLen = 0,
mbedAustin 25:e20bed9e466f 535 uint8_t tlmVersion = 0x00) :
mbedAustin 25:e20bed9e466f 536 ble(bleIn)
mbedAustin 25:e20bed9e466f 537 {
mbedAustin 25:e20bed9e466f 538 uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 25:e20bed9e466f 539 unsigned serviceDataLen = 0;
mbedAustin 25:e20bed9e466f 540 ERR("This function is not fully implemented yet, dont use it!!");
mbedAustin 25:e20bed9e466f 541 // Check optional frames, set their 'isSet' flags appropriately
mbedAustin 25:e20bed9e466f 542 if((uidNamespaceID != NULL) & (uidInstanceID != NULL)) {
mbedAustin 25:e20bed9e466f 543 uidIsSet = true;
mbedAustin 25:e20bed9e466f 544 setUIDFrameData(txPowerLevel,uidNamespaceID, uidInstanceID);
mbedAustin 25:e20bed9e466f 545 } else {
mbedAustin 25:e20bed9e466f 546 uidIsSet = false;
mbedAustin 25:e20bed9e466f 547 }
mbedAustin 25:e20bed9e466f 548 if(url != NULL) {
mbedAustin 25:e20bed9e466f 549 urlIsSet = true;
mbedAustin 25:e20bed9e466f 550 setURLFrameData(txPowerLevel,url);
mbedAustin 25:e20bed9e466f 551 } else {
mbedAustin 25:e20bed9e466f 552 uidIsSet = false;
mbedAustin 25:e20bed9e466f 553 }
mbedAustin 25:e20bed9e466f 554 // Default TLM frame to version 0x00, start all values at zero to be spec compliant.
mbedAustin 25:e20bed9e466f 555 setTLMFrameData(tlmVersion, 0x00,0x00);
mbedAustin 25:e20bed9e466f 556
mbedAustin 25:e20bed9e466f 557 // Initialize Frame transition
mbedAustin 25:e20bed9e466f 558 frameIndex = 0;
mbedAustin 25:e20bed9e466f 559 uidRFU = 0;
mbedAustin 25:e20bed9e466f 560 switchFlag = true;
mbedAustin 25:e20bed9e466f 561
mbedAustin 25:e20bed9e466f 562 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
mbedAustin 25:e20bed9e466f 563 ble.shutdown();
mbedAustin 25:e20bed9e466f 564 ble.init();
mbedAustin 25:e20bed9e466f 565 ble.setTxPower(txPowerLevel);
mbedAustin 25:e20bed9e466f 566 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbedAustin 25:e20bed9e466f 567 ble.setAdvertisingInterval(beaconPeriodus);
mbedAustin 25:e20bed9e466f 568
mbedAustin 25:e20bed9e466f 569 // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset
mbedAustin 25:e20bed9e466f 570 updateTlmPduCount(0);
mbedAustin 25:e20bed9e466f 571 updateTlmTimeSinceBoot(0);
mbedAustin 25:e20bed9e466f 572
mbedAustin 25:e20bed9e466f 573 // Construct TLM Frame in initial advertising.
mbedAustin 25:e20bed9e466f 574 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 25:e20bed9e466f 575 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 25:e20bed9e466f 576 serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,SERVICE_DATA_MAX);
mbedAustin 25:e20bed9e466f 577
mbedAustin 25:e20bed9e466f 578 updateAdvPacket(serviceData, serviceDataLen);
mbedAustin 25:e20bed9e466f 579 ble.gap().startAdvertising();
mbedAustin 25:e20bed9e466f 580 ble.gap().onRadioNotification(this,&EddystoneConfigService::radioNotificationCallback);
mbedAustin 25:e20bed9e466f 581 timeSinceBootTick.attach(this,&EddystoneConfigService::tsbCallback,0.1); // incriment the TimeSinceBoot ticker every 0.1s
mbedAustin 25:e20bed9e466f 582
mbedAustin 25:e20bed9e466f 583 }
mbedAustin 25:e20bed9e466f 584
mbedAustin 25:e20bed9e466f 585 /*
mbedAustin 25:e20bed9e466f 586 * This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function
mbedAustin 25:e20bed9e466f 587 * 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 588 *
mbedAustin 25:e20bed9e466f 589 */
mbedAustin 23:05e9bb3b13af 590 void setupEddystoneAdvertisements() {
mbedAustin 23:05e9bb3b13af 591 DBG("Switching Config -> adv");
mbedAustin 23:05e9bb3b13af 592 uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 23:05e9bb3b13af 593 unsigned serviceDataLen = 0;
mbedAustin 23:05e9bb3b13af 594 unsigned beaconPeriod = params.beaconPeriod;
mbedAustin 23:05e9bb3b13af 595
mbedAustin 23:05e9bb3b13af 596 // Initialize Frame transition
mbedAustin 25:e20bed9e466f 597 frameIndex = 0;
mbedAustin 23:05e9bb3b13af 598 uidRFU = 0;
mbedAustin 23:05e9bb3b13af 599 switchFlag = true;
mbedAustin 23:05e9bb3b13af 600
mbedAustin 23:05e9bb3b13af 601
mbedAustin 23:05e9bb3b13af 602 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
mbedAustin 23:05e9bb3b13af 603 ble.shutdown();
mbedAustin 23:05e9bb3b13af 604 ble.init();
mbedAustin 23:05e9bb3b13af 605 ble.setTxPower(params.advPowerLevels[params.txPowerMode]);
mbedAustin 23:05e9bb3b13af 606 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbedAustin 23:05e9bb3b13af 607 ble.setAdvertisingInterval(beaconPeriod);
mbedAustin 23:05e9bb3b13af 608 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */
mbedAustin 23:05e9bb3b13af 609 saveURIBeaconConfigParams(&params);
mbedAustin 23:05e9bb3b13af 610
mbedAustin 23:05e9bb3b13af 611 setTLMFrameData(0x00,0x2222,0x3333,0x01,0x02); // Initialize TLM Data, for testing, remove for release
mbedAustin 23:05e9bb3b13af 612 updateTlmPduCount(0);
mbedAustin 23:05e9bb3b13af 613 updateTlmTimeSinceBoot(0);
mbedAustin 23:05e9bb3b13af 614
mbedAustin 23:05e9bb3b13af 615 // Construct TLM Frame in initial advertising.
mbedAustin 23:05e9bb3b13af 616 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 23:05e9bb3b13af 617 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 23:05e9bb3b13af 618 serviceDataLen += constructURLFrame(serviceData+serviceDataLen,SERVICE_DATA_MAX);
mbedAustin 23:05e9bb3b13af 619
mbedAustin 23:05e9bb3b13af 620 updateAdvPacket(serviceData, serviceDataLen);
mbedAustin 23:05e9bb3b13af 621 ble.gap().startAdvertising();
mbedAustin 23:05e9bb3b13af 622 ble.gap().onRadioNotification(this,&EddystoneConfigService::radioNotificationCallback);
mbedAustin 23:05e9bb3b13af 623 timeSinceBootTick.attach(this,&EddystoneConfigService::tsbCallback,0.1); // incriment the TimeSinceBoot ticker every 0.1s
mbedAustin 23:05e9bb3b13af 624 }
mbedAustin 23:05e9bb3b13af 625
mbedAustin 23:05e9bb3b13af 626 private:
mbedAustin 23:05e9bb3b13af 627 // True if the lock bits are non-zero
mbedAustin 23:05e9bb3b13af 628 bool isLocked() {
mbedAustin 23:05e9bb3b13af 629 Lock_t testLock;
mbedAustin 23:05e9bb3b13af 630 memset(testLock, 0, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 631 return memcmp(params.lock, testLock, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 632 }
mbedAustin 23:05e9bb3b13af 633
mbedAustin 23:05e9bb3b13af 634 /*
mbedAustin 23:05e9bb3b13af 635 * This callback is invoked when a GATT client attempts to modify any of the
mbedAustin 23:05e9bb3b13af 636 * characteristics of this service. Attempts to do so are also applied to
mbedAustin 23:05e9bb3b13af 637 * the internal state of this service object.
mbedAustin 23:05e9bb3b13af 638 */
mbedAustin 23:05e9bb3b13af 639 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) {
mbedAustin 23:05e9bb3b13af 640 uint16_t handle = writeParams->handle;
mbedAustin 23:05e9bb3b13af 641
mbedAustin 23:05e9bb3b13af 642 if (handle == lockChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 643 // Validated earlier
mbedAustin 23:05e9bb3b13af 644 memcpy(params.lock, writeParams->data, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 645 // use isLocked() in case bits are being set to all 0's
mbedAustin 23:05e9bb3b13af 646 lockedState = isLocked();
mbedAustin 23:05e9bb3b13af 647 } else if (handle == unlockChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 648 // Validated earlier
mbedAustin 23:05e9bb3b13af 649 memset(params.lock, 0, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 650 lockedState = false;
mbedAustin 23:05e9bb3b13af 651 } else if (handle == uriDataChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 652 params.uriDataLength = writeParams->len;
mbedAustin 23:05e9bb3b13af 653 memcpy(params.uriData, writeParams->data, params.uriDataLength);
mbedAustin 23:05e9bb3b13af 654 } else if (handle == flagsChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 655 params.flags = *(writeParams->data);
mbedAustin 23:05e9bb3b13af 656 } else if (handle == advPowerLevelsChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 657 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
mbedAustin 23:05e9bb3b13af 658 } else if (handle == txPowerModeChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 659 params.txPowerMode = *(writeParams->data);
mbedAustin 23:05e9bb3b13af 660 } else if (handle == beaconPeriodChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 661 params.beaconPeriod = *((uint16_t *)(writeParams->data));
mbedAustin 23:05e9bb3b13af 662
mbedAustin 23:05e9bb3b13af 663 /* Re-map beaconPeriod to within permissible bounds if necessary. */
mbedAustin 23:05e9bb3b13af 664 if (params.beaconPeriod != 0) {
mbedAustin 23:05e9bb3b13af 665 bool paramsUpdated = false;
mbedAustin 23:05e9bb3b13af 666 if (params.beaconPeriod < ble.getMinAdvertisingInterval()) {
mbedAustin 23:05e9bb3b13af 667 params.beaconPeriod = ble.getMinAdvertisingInterval();
mbedAustin 23:05e9bb3b13af 668 paramsUpdated = true;
mbedAustin 23:05e9bb3b13af 669 } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) {
mbedAustin 23:05e9bb3b13af 670 params.beaconPeriod = ble.getMaxAdvertisingInterval();
mbedAustin 23:05e9bb3b13af 671 paramsUpdated = true;
mbedAustin 23:05e9bb3b13af 672 }
mbedAustin 23:05e9bb3b13af 673 if (paramsUpdated) {
mbedAustin 23:05e9bb3b13af 674 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
mbedAustin 23:05e9bb3b13af 675 }
mbedAustin 23:05e9bb3b13af 676 }
mbedAustin 23:05e9bb3b13af 677 } else if (handle == resetChar.getValueHandle()) {
mbedAustin 23:05e9bb3b13af 678 resetToDefaults();
mbedAustin 23:05e9bb3b13af 679 }
mbedAustin 23:05e9bb3b13af 680 }
mbedAustin 23:05e9bb3b13af 681
mbedAustin 23:05e9bb3b13af 682 /*
mbedAustin 23:05e9bb3b13af 683 * Reset the default values.
mbedAustin 23:05e9bb3b13af 684 */
mbedAustin 23:05e9bb3b13af 685 void resetToDefaults(void) {
mbedAustin 23:05e9bb3b13af 686 lockedState = false;
mbedAustin 23:05e9bb3b13af 687 memset(params.lock, 0, sizeof(Lock_t));
mbedAustin 23:05e9bb3b13af 688 memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
mbedAustin 23:05e9bb3b13af 689 params.uriDataLength = defaultUriDataLength;
mbedAustin 23:05e9bb3b13af 690 params.flags = 0;
mbedAustin 23:05e9bb3b13af 691 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
mbedAustin 23:05e9bb3b13af 692 params.txPowerMode = TX_POWER_MODE_LOW;
mbedAustin 23:05e9bb3b13af 693 params.beaconPeriod = 1000;
mbedAustin 23:05e9bb3b13af 694 memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
mbedAustin 23:05e9bb3b13af 695 memcpy(params.uidInstanceID, defaultUidInstanceID, UID_INSTANCEID_SIZE);
mbedAustin 23:05e9bb3b13af 696 params.tlmVersion = 0;
mbedAustin 23:05e9bb3b13af 697 updateCharacteristicValues();
mbedAustin 23:05e9bb3b13af 698 }
mbedAustin 23:05e9bb3b13af 699
mbedAustin 23:05e9bb3b13af 700 /*
mbedAustin 23:05e9bb3b13af 701 * Internal helper function used to update the GATT database following any
mbedAustin 23:05e9bb3b13af 702 * change to the internal state of the service object.
mbedAustin 23:05e9bb3b13af 703 */
mbedAustin 23:05e9bb3b13af 704 void updateCharacteristicValues(void) {
mbedAustin 23:05e9bb3b13af 705 ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &lockedState, 1);
mbedAustin 23:05e9bb3b13af 706 ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
mbedAustin 23:05e9bb3b13af 707 ble.updateCharacteristicValue(flagsChar.getValueHandle(), &params.flags, 1);
mbedAustin 23:05e9bb3b13af 708 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(),
mbedAustin 23:05e9bb3b13af 709 reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
mbedAustin 23:05e9bb3b13af 710 ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), &params.txPowerMode, 1);
mbedAustin 23:05e9bb3b13af 711 ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(),
mbedAustin 23:05e9bb3b13af 712 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
mbedAustin 23:05e9bb3b13af 713 }
mbedAustin 23:05e9bb3b13af 714
mbedAustin 23:05e9bb3b13af 715 private:
mbedAustin 23:05e9bb3b13af 716 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 23:05e9bb3b13af 717 if (lockedState) {
mbedAustin 23:05e9bb3b13af 718 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 719 } else if (authParams->len != sizeof(Lock_t)) {
mbedAustin 23:05e9bb3b13af 720 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 721 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 722 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 723 } else {
mbedAustin 23:05e9bb3b13af 724 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 725 }
mbedAustin 23:05e9bb3b13af 726 }
mbedAustin 23:05e9bb3b13af 727
mbedAustin 23:05e9bb3b13af 728
mbedAustin 23:05e9bb3b13af 729 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 23:05e9bb3b13af 730 if (!lockedState) {
mbedAustin 23:05e9bb3b13af 731 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 732 } else if (authParams->len != sizeof(Lock_t)) {
mbedAustin 23:05e9bb3b13af 733 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 734 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 735 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 736 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) {
mbedAustin 23:05e9bb3b13af 737 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 738 } else {
mbedAustin 23:05e9bb3b13af 739 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 740 }
mbedAustin 23:05e9bb3b13af 741 }
mbedAustin 23:05e9bb3b13af 742
mbedAustin 23:05e9bb3b13af 743 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 23:05e9bb3b13af 744 if (lockedState) {
mbedAustin 23:05e9bb3b13af 745 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 746 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 747 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 748 } else {
mbedAustin 23:05e9bb3b13af 749 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 750 }
mbedAustin 23:05e9bb3b13af 751 }
mbedAustin 23:05e9bb3b13af 752
mbedAustin 23:05e9bb3b13af 753 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 23:05e9bb3b13af 754 if (lockedState) {
mbedAustin 23:05e9bb3b13af 755 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 756 } else if (authParams->len != sizeof(uint8_t)) {
mbedAustin 23:05e9bb3b13af 757 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 758 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 759 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 760 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) {
mbedAustin 23:05e9bb3b13af 761 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
mbedAustin 23:05e9bb3b13af 762 } else {
mbedAustin 23:05e9bb3b13af 763 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 764 }
mbedAustin 23:05e9bb3b13af 765 }
mbedAustin 23:05e9bb3b13af 766
mbedAustin 23:05e9bb3b13af 767 template <typename T>
mbedAustin 23:05e9bb3b13af 768 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
mbedAustin 23:05e9bb3b13af 769 if (lockedState) {
mbedAustin 23:05e9bb3b13af 770 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
mbedAustin 23:05e9bb3b13af 771 } else if (authParams->len != sizeof(T)) {
mbedAustin 23:05e9bb3b13af 772 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbedAustin 23:05e9bb3b13af 773 } else if (authParams->offset != 0) {
mbedAustin 23:05e9bb3b13af 774 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbedAustin 23:05e9bb3b13af 775 } else {
mbedAustin 23:05e9bb3b13af 776 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbedAustin 23:05e9bb3b13af 777 }
mbedAustin 23:05e9bb3b13af 778 }
mbedAustin 23:05e9bb3b13af 779
mbedAustin 23:05e9bb3b13af 780 BLEDevice &ble;
mbedAustin 23:05e9bb3b13af 781 Params_t &params;
mbedAustin 23:05e9bb3b13af 782 Ticker timeSinceBootTick;
mbedAustin 23:05e9bb3b13af 783 Timeout switchFrame;
mbedAustin 23:05e9bb3b13af 784 // Default value that is restored on reset
mbedAustin 23:05e9bb3b13af 785 size_t defaultUriDataLength;
mbedAustin 23:05e9bb3b13af 786 UriData_t defaultUriData;
mbedAustin 23:05e9bb3b13af 787 UIDNamespaceID_t defaultUidNamespaceID;
mbedAustin 23:05e9bb3b13af 788 UIDInstanceID_t defaultUidInstanceID;
mbedAustin 23:05e9bb3b13af 789 int8_t defaultUidPower;
mbedAustin 23:05e9bb3b13af 790 int8_t defaultUrlPower;
mbedAustin 23:05e9bb3b13af 791 uint16_t uidRFU;
mbedAustin 25:e20bed9e466f 792 bool uidIsSet;
mbedAustin 25:e20bed9e466f 793 bool urlIsSet;
mbedAustin 23:05e9bb3b13af 794 // Default value that is restored on reset
mbedAustin 23:05e9bb3b13af 795 PowerLevels_t &defaultAdvPowerLevels;
mbedAustin 23:05e9bb3b13af 796 uint8_t lockedState;
mbedAustin 23:05e9bb3b13af 797 bool initSucceeded;
mbedAustin 23:05e9bb3b13af 798 uint8_t resetFlag;
mbedAustin 23:05e9bb3b13af 799 bool switchFlag;
mbedAustin 23:05e9bb3b13af 800
mbedAustin 23:05e9bb3b13af 801 // Private Variables for Telemetry Data
mbedAustin 23:05e9bb3b13af 802 uint8_t TlmVersion;
mbedAustin 23:05e9bb3b13af 803 volatile uint16_t TlmBatteryVoltage;
mbedAustin 23:05e9bb3b13af 804 volatile uint16_t TlmBeaconTemp;
mbedAustin 23:05e9bb3b13af 805 volatile uint32_t TlmPduCount;
mbedAustin 23:05e9bb3b13af 806 volatile uint32_t TlmTimeSinceBoot;
mbedAustin 23:05e9bb3b13af 807
mbedAustin 23:05e9bb3b13af 808 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar;
mbedAustin 23:05e9bb3b13af 809 WriteOnlyGattCharacteristic<Lock_t> lockChar;
mbedAustin 23:05e9bb3b13af 810 GattCharacteristic uriDataChar;
mbedAustin 23:05e9bb3b13af 811 WriteOnlyGattCharacteristic<Lock_t> unlockChar;
mbedAustin 23:05e9bb3b13af 812 ReadWriteGattCharacteristic<uint8_t> flagsChar;
mbedAustin 23:05e9bb3b13af 813 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar;
mbedAustin 23:05e9bb3b13af 814 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar;
mbedAustin 23:05e9bb3b13af 815 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar;
mbedAustin 23:05e9bb3b13af 816 WriteOnlyGattCharacteristic<uint8_t> resetChar;
mbedAustin 23:05e9bb3b13af 817
mbedAustin 23:05e9bb3b13af 818 public:
mbedAustin 23:05e9bb3b13af 819 /*
mbedAustin 23:05e9bb3b13af 820 * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
mbedAustin 23:05e9bb3b13af 821 */
mbedAustin 23:05e9bb3b13af 822 static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) {
mbedAustin 23:05e9bb3b13af 823 const char *prefixes[] = {
mbedAustin 23:05e9bb3b13af 824 "http://www.",
mbedAustin 23:05e9bb3b13af 825 "https://www.",
mbedAustin 23:05e9bb3b13af 826 "http://",
mbedAustin 23:05e9bb3b13af 827 "https://",
mbedAustin 23:05e9bb3b13af 828 };
mbedAustin 23:05e9bb3b13af 829 const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
mbedAustin 23:05e9bb3b13af 830 const char *suffixes[] = {
mbedAustin 23:05e9bb3b13af 831 ".com/",
mbedAustin 23:05e9bb3b13af 832 ".org/",
mbedAustin 23:05e9bb3b13af 833 ".edu/",
mbedAustin 23:05e9bb3b13af 834 ".net/",
mbedAustin 23:05e9bb3b13af 835 ".info/",
mbedAustin 23:05e9bb3b13af 836 ".biz/",
mbedAustin 23:05e9bb3b13af 837 ".gov/",
mbedAustin 23:05e9bb3b13af 838 ".com",
mbedAustin 23:05e9bb3b13af 839 ".org",
mbedAustin 23:05e9bb3b13af 840 ".edu",
mbedAustin 23:05e9bb3b13af 841 ".net",
mbedAustin 23:05e9bb3b13af 842 ".info",
mbedAustin 23:05e9bb3b13af 843 ".biz",
mbedAustin 23:05e9bb3b13af 844 ".gov"
mbedAustin 23:05e9bb3b13af 845 };
mbedAustin 23:05e9bb3b13af 846 const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
mbedAustin 23:05e9bb3b13af 847
mbedAustin 23:05e9bb3b13af 848 sizeofURIDataOut = 0;
mbedAustin 23:05e9bb3b13af 849 memset(uriDataOut, 0, sizeof(UriData_t));
mbedAustin 23:05e9bb3b13af 850
mbedAustin 23:05e9bb3b13af 851 if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) {
mbedAustin 23:05e9bb3b13af 852 return;
mbedAustin 23:05e9bb3b13af 853 }
mbedAustin 23:05e9bb3b13af 854
mbedAustin 23:05e9bb3b13af 855 /*
mbedAustin 23:05e9bb3b13af 856 * handle prefix
mbedAustin 23:05e9bb3b13af 857 */
mbedAustin 23:05e9bb3b13af 858 for (unsigned i = 0; i < NUM_PREFIXES; i++) {
mbedAustin 23:05e9bb3b13af 859 size_t prefixLen = strlen(prefixes[i]);
mbedAustin 23:05e9bb3b13af 860 if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
mbedAustin 23:05e9bb3b13af 861 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 23:05e9bb3b13af 862 uriDataIn += prefixLen;
mbedAustin 23:05e9bb3b13af 863 break;
mbedAustin 23:05e9bb3b13af 864 }
mbedAustin 23:05e9bb3b13af 865 }
mbedAustin 23:05e9bb3b13af 866
mbedAustin 23:05e9bb3b13af 867 /*
mbedAustin 23:05e9bb3b13af 868 * handle suffixes
mbedAustin 23:05e9bb3b13af 869 */
mbedAustin 23:05e9bb3b13af 870 while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) {
mbedAustin 23:05e9bb3b13af 871 /* check for suffix match */
mbedAustin 23:05e9bb3b13af 872 unsigned i;
mbedAustin 23:05e9bb3b13af 873 for (i = 0; i < NUM_SUFFIXES; i++) {
mbedAustin 23:05e9bb3b13af 874 size_t suffixLen = strlen(suffixes[i]);
mbedAustin 23:05e9bb3b13af 875 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
mbedAustin 23:05e9bb3b13af 876 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 23:05e9bb3b13af 877 uriDataIn += suffixLen;
mbedAustin 23:05e9bb3b13af 878 break; /* from the for loop for checking against suffixes */
mbedAustin 23:05e9bb3b13af 879 }
mbedAustin 23:05e9bb3b13af 880 }
mbedAustin 23:05e9bb3b13af 881 /* This is the default case where we've got an ordinary character which doesn't match a suffix. */
mbedAustin 23:05e9bb3b13af 882 if (i == NUM_SUFFIXES) {
mbedAustin 23:05e9bb3b13af 883 uriDataOut[sizeofURIDataOut++] = *uriDataIn;
mbedAustin 23:05e9bb3b13af 884 ++uriDataIn;
mbedAustin 23:05e9bb3b13af 885 }
mbedAustin 23:05e9bb3b13af 886 }
mbedAustin 23:05e9bb3b13af 887 }
mbedAustin 23:05e9bb3b13af 888 };
mbedAustin 23:05e9bb3b13af 889
mbedAustin 23:05e9bb3b13af 890 #endif // SERVICES_ZIPBEACONCONFIGSERVICE_H_