erkin yucel / mbed-os

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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