Maxim Integrated Bluetooth LE Library

Dependents:   BLE_Thermometer MAXWSNENV_demo

Committer:
enginerd
Date:
Thu Oct 06 22:02:31 2016 +0000
Revision:
5:5b87f64ce81e
Parent:
4:07f30e7452c0
Added new required method.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
enginerd 0:b562096246b3 1 /*******************************************************************************
enginerd 0:b562096246b3 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
enginerd 0:b562096246b3 3 *
enginerd 0:b562096246b3 4 * Permission is hereby granted, free of charge, to any person obtaining a
enginerd 0:b562096246b3 5 * copy of this software and associated documentation files (the "Software"),
enginerd 0:b562096246b3 6 * to deal in the Software without restriction, including without limitation
enginerd 0:b562096246b3 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
enginerd 0:b562096246b3 8 * and/or sell copies of the Software, and to permit persons to whom the
enginerd 0:b562096246b3 9 * Software is furnished to do so, subject to the following conditions:
enginerd 0:b562096246b3 10 *
enginerd 0:b562096246b3 11 * The above copyright notice and this permission notice shall be included
enginerd 0:b562096246b3 12 * in all copies or substantial portions of the Software.
enginerd 0:b562096246b3 13 *
enginerd 0:b562096246b3 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
enginerd 0:b562096246b3 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
enginerd 0:b562096246b3 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
enginerd 0:b562096246b3 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
enginerd 0:b562096246b3 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
enginerd 0:b562096246b3 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
enginerd 0:b562096246b3 20 * OTHER DEALINGS IN THE SOFTWARE.
enginerd 0:b562096246b3 21 *
enginerd 0:b562096246b3 22 * Except as contained in this notice, the name of Maxim Integrated
enginerd 0:b562096246b3 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
enginerd 0:b562096246b3 24 * Products, Inc. Branding Policy.
enginerd 0:b562096246b3 25 *
enginerd 0:b562096246b3 26 * The mere transfer of this software does not imply any licenses
enginerd 0:b562096246b3 27 * of trade secrets, proprietary technology, copyrights, patents,
enginerd 0:b562096246b3 28 * trademarks, maskwork rights, or any other form of intellectual
enginerd 0:b562096246b3 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
enginerd 0:b562096246b3 30 * ownership rights.
enginerd 0:b562096246b3 31 *******************************************************************************
enginerd 0:b562096246b3 32 */
enginerd 0:b562096246b3 33
enginerd 0:b562096246b3 34 #include "MaximGap.h"
enginerd 0:b562096246b3 35 #include "mbed.h"
enginerd 0:b562096246b3 36 #include "hci_vs.h"
enginerd 0:b562096246b3 37
enginerd 0:b562096246b3 38 MaximGap &MaximGap::getInstance() {
enginerd 0:b562096246b3 39 static MaximGap m_instance;
enginerd 0:b562096246b3 40 return m_instance;
enginerd 0:b562096246b3 41 }
enginerd 0:b562096246b3 42
enginerd 0:b562096246b3 43 ble_error_t MaximGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
enginerd 0:b562096246b3 44 {
enginerd 0:b562096246b3 45 /* Make sure we don't exceed the advertising payload length */
enginerd 0:b562096246b3 46 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
enginerd 0:b562096246b3 47 return BLE_ERROR_BUFFER_OVERFLOW;
enginerd 0:b562096246b3 48 }
enginerd 0:b562096246b3 49
enginerd 0:b562096246b3 50 /* Make sure we have a payload! */
enginerd 0:b562096246b3 51 if (advData.getPayloadLen() == 0) {
enginerd 0:b562096246b3 52 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 53 }
enginerd 0:b562096246b3 54
kgills 3:4e764337d5c5 55 /* save advertising and scan response data */
kgills 3:4e764337d5c5 56 advDataLen = advData.getPayloadLen();
kgills 3:4e764337d5c5 57 scanResponseLen = scanResponse.getPayloadLen();
kgills 3:4e764337d5c5 58 memcpy((void*)advDataCache, (void*)advData.getPayload(), advDataLen);
kgills 3:4e764337d5c5 59 memcpy((void*)advDataCache, (void*)advData.getPayload(), scanResponseLen);
enginerd 0:b562096246b3 60
enginerd 0:b562096246b3 61 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 62 }
enginerd 0:b562096246b3 63
enginerd 0:b562096246b3 64 ble_error_t MaximGap::startAdvertising(const GapAdvertisingParams &params)
enginerd 0:b562096246b3 65 {
enginerd 0:b562096246b3 66 /* Make sure we support the advertising type */
enginerd 0:b562096246b3 67 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
enginerd 0:b562096246b3 68 /* ToDo: This requires a proper security implementation, etc. */
enginerd 0:b562096246b3 69 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 70 }
enginerd 0:b562096246b3 71
enginerd 0:b562096246b3 72 /* Check interval range */
enginerd 0:b562096246b3 73 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
enginerd 0:b562096246b3 74 /* Min delay is slightly longer for unconnectable devices */
enginerd 0:b562096246b3 75 if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
enginerd 0:b562096246b3 76 (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
enginerd 0:b562096246b3 77 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 78 }
enginerd 0:b562096246b3 79 } else {
enginerd 0:b562096246b3 80 if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
enginerd 0:b562096246b3 81 (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
enginerd 0:b562096246b3 82 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 83 }
enginerd 0:b562096246b3 84 }
enginerd 0:b562096246b3 85
enginerd 0:b562096246b3 86 /* Check timeout is zero for Connectable Directed */
enginerd 0:b562096246b3 87 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
enginerd 0:b562096246b3 88 /* Timeout must be 0 with this type, although we'll never get here */
enginerd 0:b562096246b3 89 /* since this isn't implemented yet anyway */
enginerd 0:b562096246b3 90 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 91 }
enginerd 0:b562096246b3 92
enginerd 0:b562096246b3 93 /* Check timeout for other advertising types */
enginerd 0:b562096246b3 94 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
enginerd 0:b562096246b3 95 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
enginerd 0:b562096246b3 96 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 97 }
enginerd 0:b562096246b3 98
kgills 3:4e764337d5c5 99 /* set advertising and scan response data for discoverable mode */
kgills 3:4e764337d5c5 100 DmAdvSetData(DM_DATA_LOC_ADV, advDataLen, advDataCache);
kgills 3:4e764337d5c5 101 DmAdvSetData(DM_DATA_LOC_SCAN, scanResponseLen, scanResponseCache);
kgills 3:4e764337d5c5 102
enginerd 0:b562096246b3 103 DmAdvSetInterval(params.getInterval(), params.getInterval());
enginerd 0:b562096246b3 104 DmAdvStart(params.getAdvertisingType(), params.getTimeout());
enginerd 0:b562096246b3 105
enginerd 0:b562096246b3 106 state.advertising = 1;
enginerd 0:b562096246b3 107
enginerd 0:b562096246b3 108 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 109 }
enginerd 0:b562096246b3 110
enginerd 0:b562096246b3 111 ble_error_t MaximGap::stopAdvertising(void)
enginerd 0:b562096246b3 112 {
enginerd 0:b562096246b3 113 DmAdvStop();
enginerd 0:b562096246b3 114
enginerd 0:b562096246b3 115 state.advertising = 0;
enginerd 0:b562096246b3 116
enginerd 0:b562096246b3 117 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 118 }
enginerd 0:b562096246b3 119
enginerd 0:b562096246b3 120 void MaximGap::advertisingStopped(void)
enginerd 0:b562096246b3 121 {
enginerd 0:b562096246b3 122 /* If advertising stopped due to a call to stopAdvertising(), state.advertising will
enginerd 0:b562096246b3 123 * be '0.' Otherwise, advertising must have stopped due to a timeout
enginerd 0:b562096246b3 124 */
enginerd 0:b562096246b3 125 if (state.advertising) {
enginerd 0:b562096246b3 126 processTimeoutEvent(Gap::TIMEOUT_SRC_ADVERTISING);
enginerd 0:b562096246b3 127 }
enginerd 0:b562096246b3 128 }
enginerd 0:b562096246b3 129
enginerd 0:b562096246b3 130 ble_error_t MaximGap::disconnect(DisconnectionReason_t reason)
enginerd 0:b562096246b3 131 {
enginerd 0:b562096246b3 132 DmConnClose(DM_CLIENT_ID_APP, m_connectionHandle, reason);
enginerd 0:b562096246b3 133
enginerd 0:b562096246b3 134 state.advertising = 0;
enginerd 0:b562096246b3 135 state.connected = 0;
enginerd 0:b562096246b3 136
enginerd 0:b562096246b3 137 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 138 }
enginerd 0:b562096246b3 139
enginerd 0:b562096246b3 140 ble_error_t MaximGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
enginerd 0:b562096246b3 141 {
enginerd 0:b562096246b3 142 DmConnClose(DM_CLIENT_ID_APP, connectionHandle, reason);
enginerd 0:b562096246b3 143
enginerd 0:b562096246b3 144 state.advertising = 0;
enginerd 0:b562096246b3 145 state.connected = 0;
enginerd 0:b562096246b3 146
enginerd 0:b562096246b3 147 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 148 }
enginerd 0:b562096246b3 149
enginerd 0:b562096246b3 150 ble_error_t MaximGap::getPreferredConnectionParams(ConnectionParams_t *params)
enginerd 0:b562096246b3 151 {
enginerd 0:b562096246b3 152 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 153 }
enginerd 0:b562096246b3 154
enginerd 0:b562096246b3 155 ble_error_t MaximGap::setPreferredConnectionParams(const ConnectionParams_t *params)
enginerd 0:b562096246b3 156 {
enginerd 0:b562096246b3 157 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 158 }
enginerd 0:b562096246b3 159
enginerd 0:b562096246b3 160 ble_error_t MaximGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
enginerd 0:b562096246b3 161 {
enginerd 0:b562096246b3 162 if (DmConnCheckIdle(handle) != 0) {
enginerd 0:b562096246b3 163 return BLE_STACK_BUSY;
enginerd 0:b562096246b3 164 }
enginerd 0:b562096246b3 165
enginerd 0:b562096246b3 166 hciConnSpec_t connSpec;
enginerd 0:b562096246b3 167 connSpec.connIntervalMin = newParams->minConnectionInterval;
enginerd 0:b562096246b3 168 connSpec.connIntervalMax = newParams->maxConnectionInterval;
enginerd 0:b562096246b3 169 connSpec.connLatency = newParams->slaveLatency;
enginerd 0:b562096246b3 170 connSpec.supTimeout = newParams->connectionSupervisionTimeout;
enginerd 0:b562096246b3 171 DmConnUpdate(handle, &connSpec);
enginerd 0:b562096246b3 172
enginerd 0:b562096246b3 173 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 174 }
enginerd 0:b562096246b3 175
enginerd 0:b562096246b3 176 ble_error_t MaximGap::startRadioScan(const GapScanningParams &scanningParams)
enginerd 0:b562096246b3 177 {
enginerd 0:b562096246b3 178 DmScanSetInterval(scanningParams.getInterval(), scanningParams.getWindow());
enginerd 0:b562096246b3 179
enginerd 0:b562096246b3 180 uint8_t scanType = scanningParams.getActiveScanning() ? DM_SCAN_TYPE_ACTIVE : DM_SCAN_TYPE_PASSIVE;
enginerd 0:b562096246b3 181 uint32_t duration = (uint32_t)scanningParams.getTimeout() * 1000;
enginerd 0:b562096246b3 182 if (duration > 0xFFFF) {
enginerd 0:b562096246b3 183 // saturate to 16-bits
enginerd 0:b562096246b3 184 duration = 0xFFFF;
enginerd 0:b562096246b3 185 }
enginerd 0:b562096246b3 186
enginerd 0:b562096246b3 187 DmScanStart(DM_DISC_MODE_NONE, scanType, TRUE, duration);
enginerd 0:b562096246b3 188
enginerd 0:b562096246b3 189 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 190 }
enginerd 0:b562096246b3 191
enginerd 0:b562096246b3 192 ble_error_t MaximGap::stopScan(void)
enginerd 0:b562096246b3 193 {
enginerd 0:b562096246b3 194 DmScanStop();
enginerd 0:b562096246b3 195 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 196 }
enginerd 0:b562096246b3 197
enginerd 0:b562096246b3 198 void MaximGap::setConnectionHandle(uint16_t connectionHandle)
enginerd 0:b562096246b3 199 {
enginerd 0:b562096246b3 200 m_connectionHandle = connectionHandle;
enginerd 0:b562096246b3 201 }
enginerd 0:b562096246b3 202
enginerd 0:b562096246b3 203 uint16_t MaximGap::getConnectionHandle(void)
enginerd 0:b562096246b3 204 {
enginerd 0:b562096246b3 205 return m_connectionHandle;
enginerd 0:b562096246b3 206 }
enginerd 0:b562096246b3 207
enginerd 0:b562096246b3 208 ble_error_t MaximGap::setAddress(AddressType_t type, const Address_t address)
enginerd 0:b562096246b3 209 {
Jeremy Brodt 1:89048b73bc93 210 if ((type != BLEProtocol::AddressType::PUBLIC) && (type != BLEProtocol::AddressType::RANDOM_STATIC)) {
enginerd 0:b562096246b3 211 return BLE_ERROR_PARAM_OUT_OF_RANGE;
enginerd 0:b562096246b3 212 }
enginerd 0:b562096246b3 213
enginerd 0:b562096246b3 214 m_type = type;
enginerd 0:b562096246b3 215 HciVsSetPublicAddr((uint8_t*)address);
enginerd 0:b562096246b3 216
enginerd 0:b562096246b3 217 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 218 }
enginerd 0:b562096246b3 219
enginerd 0:b562096246b3 220 ble_error_t MaximGap::getAddress(AddressType_t *typeP, Address_t address)
enginerd 0:b562096246b3 221 {
enginerd 0:b562096246b3 222 *typeP = m_type;
enginerd 0:b562096246b3 223 BdaCpy(address, HciGetBdAddr());
enginerd 0:b562096246b3 224 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 225 }
enginerd 0:b562096246b3 226
enginerd 0:b562096246b3 227 ble_error_t MaximGap::setDeviceName(const uint8_t *deviceName)
enginerd 0:b562096246b3 228 {
enginerd 0:b562096246b3 229 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 230 }
enginerd 0:b562096246b3 231
enginerd 0:b562096246b3 232 ble_error_t MaximGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
enginerd 0:b562096246b3 233 {
enginerd 0:b562096246b3 234 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 235 }
enginerd 0:b562096246b3 236
enginerd 0:b562096246b3 237 ble_error_t MaximGap::setAppearance(GapAdvertisingData::Appearance appearance)
enginerd 0:b562096246b3 238 {
enginerd 0:b562096246b3 239 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 240 }
enginerd 0:b562096246b3 241
enginerd 0:b562096246b3 242 ble_error_t MaximGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
enginerd 0:b562096246b3 243 {
enginerd 0:b562096246b3 244 return BLE_ERROR_NOT_IMPLEMENTED;
enginerd 0:b562096246b3 245 }
enginerd 0:b562096246b3 246
enginerd 0:b562096246b3 247 ble_error_t MaximGap::setTxPower(int8_t txPower)
enginerd 0:b562096246b3 248 {
enginerd 0:b562096246b3 249 HciVsSetTxPower(txPower);
enginerd 0:b562096246b3 250 return BLE_ERROR_NONE;
enginerd 0:b562096246b3 251 }
enginerd 0:b562096246b3 252
enginerd 0:b562096246b3 253 void MaximGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
enginerd 0:b562096246b3 254 {
enginerd 0:b562096246b3 255 static const int8_t permittedTxValues[] = {
enginerd 0:b562096246b3 256 -18, -15, -12, -9, -6, -3, 0, 3
enginerd 0:b562096246b3 257 };
enginerd 0:b562096246b3 258
enginerd 0:b562096246b3 259 *valueArrayPP = permittedTxValues;
enginerd 0:b562096246b3 260 *countP = sizeof(permittedTxValues) / sizeof(int8_t);
enginerd 0:b562096246b3 261 }