Fork of ble-x-nucleo-idb0xa1 with changes required by BleStarMbed

Dependents:   ble-star-mbed

Committer:
lorevee
Date:
Tue Feb 20 11:07:16 2018 +0000
Revision:
0:ac0b0725c6fa
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lorevee 0:ac0b0725c6fa 1 /* mbed Microcontroller Library
lorevee 0:ac0b0725c6fa 2 * Copyright (c) 2006-2013 ARM Limited
lorevee 0:ac0b0725c6fa 3 *
lorevee 0:ac0b0725c6fa 4 * Licensed under the Apache License, Version 2.0 (the "License");
lorevee 0:ac0b0725c6fa 5 * you may not use this file except in compliance with the License.
lorevee 0:ac0b0725c6fa 6 * You may obtain a copy of the License at
lorevee 0:ac0b0725c6fa 7 *
lorevee 0:ac0b0725c6fa 8 * http://www.apache.org/licenses/LICENSE-2.0
lorevee 0:ac0b0725c6fa 9 *
lorevee 0:ac0b0725c6fa 10 * Unless required by applicable law or agreed to in writing, software
lorevee 0:ac0b0725c6fa 11 * distributed under the License is distributed on an "AS IS" BASIS,
lorevee 0:ac0b0725c6fa 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lorevee 0:ac0b0725c6fa 13 * See the License for the specific language governing permissions and
lorevee 0:ac0b0725c6fa 14 * limitations under the License.
lorevee 0:ac0b0725c6fa 15 */
lorevee 0:ac0b0725c6fa 16
lorevee 0:ac0b0725c6fa 17
lorevee 0:ac0b0725c6fa 18 /**
lorevee 0:ac0b0725c6fa 19 ******************************************************************************
lorevee 0:ac0b0725c6fa 20 * @file BlueNRGGap.cpp
lorevee 0:ac0b0725c6fa 21 * @author STMicroelectronics
lorevee 0:ac0b0725c6fa 22 * @brief Implementation of BLE_API Gap Class
lorevee 0:ac0b0725c6fa 23 ******************************************************************************
lorevee 0:ac0b0725c6fa 24 * @copy
lorevee 0:ac0b0725c6fa 25 *
lorevee 0:ac0b0725c6fa 26 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
lorevee 0:ac0b0725c6fa 27 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
lorevee 0:ac0b0725c6fa 28 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
lorevee 0:ac0b0725c6fa 29 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
lorevee 0:ac0b0725c6fa 30 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
lorevee 0:ac0b0725c6fa 31 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
lorevee 0:ac0b0725c6fa 32 *
lorevee 0:ac0b0725c6fa 33 * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
lorevee 0:ac0b0725c6fa 34 */
lorevee 0:ac0b0725c6fa 35
lorevee 0:ac0b0725c6fa 36 /** @defgroup BlueNRGGap
lorevee 0:ac0b0725c6fa 37 * @brief BlueNRG BLE_API GAP Adaptation
lorevee 0:ac0b0725c6fa 38 * @{
lorevee 0:ac0b0725c6fa 39 */
lorevee 0:ac0b0725c6fa 40
lorevee 0:ac0b0725c6fa 41 #include "BlueNRGDevice.h"
lorevee 0:ac0b0725c6fa 42 #ifdef YOTTA_CFG_MBED_OS
lorevee 0:ac0b0725c6fa 43 #include "mbed-drivers/mbed.h"
lorevee 0:ac0b0725c6fa 44 #else
lorevee 0:ac0b0725c6fa 45 #include "mbed.h"
lorevee 0:ac0b0725c6fa 46 #endif
lorevee 0:ac0b0725c6fa 47 #include "ble_payload.h"
lorevee 0:ac0b0725c6fa 48 #include "ble_utils.h"
lorevee 0:ac0b0725c6fa 49 #include "ble_debug.h"
lorevee 0:ac0b0725c6fa 50
lorevee 0:ac0b0725c6fa 51 /*
lorevee 0:ac0b0725c6fa 52 * Utility to process GAP specific events (e.g., Advertising timeout)
lorevee 0:ac0b0725c6fa 53 */
lorevee 0:ac0b0725c6fa 54 void BlueNRGGap::Process(void)
lorevee 0:ac0b0725c6fa 55 {
lorevee 0:ac0b0725c6fa 56 if(AdvToFlag) {
lorevee 0:ac0b0725c6fa 57 AdvToFlag = false;
lorevee 0:ac0b0725c6fa 58 stopAdvertising();
lorevee 0:ac0b0725c6fa 59 }
lorevee 0:ac0b0725c6fa 60
lorevee 0:ac0b0725c6fa 61 if(ScanToFlag) {
lorevee 0:ac0b0725c6fa 62 ScanToFlag = false;
lorevee 0:ac0b0725c6fa 63 stopScan();
lorevee 0:ac0b0725c6fa 64 //processTimeoutEvent(TIMEOUT_SRC_SCAN);
lorevee 0:ac0b0725c6fa 65 }
lorevee 0:ac0b0725c6fa 66 }
lorevee 0:ac0b0725c6fa 67
lorevee 0:ac0b0725c6fa 68 /**************************************************************************/
lorevee 0:ac0b0725c6fa 69 /*!
lorevee 0:ac0b0725c6fa 70 @brief Sets the advertising parameters and payload for the device.
lorevee 0:ac0b0725c6fa 71 Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
lorevee 0:ac0b0725c6fa 72
lorevee 0:ac0b0725c6fa 73 @params[in] advData
lorevee 0:ac0b0725c6fa 74 The primary advertising data payload
lorevee 0:ac0b0725c6fa 75 @params[in] scanResponse
lorevee 0:ac0b0725c6fa 76 The optional Scan Response payload if the advertising
lorevee 0:ac0b0725c6fa 77 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
lorevee 0:ac0b0725c6fa 78 in \ref GapAdveritinngParams
lorevee 0:ac0b0725c6fa 79
lorevee 0:ac0b0725c6fa 80 @returns \ref ble_error_t
lorevee 0:ac0b0725c6fa 81
lorevee 0:ac0b0725c6fa 82 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 83 Everything executed properly
lorevee 0:ac0b0725c6fa 84
lorevee 0:ac0b0725c6fa 85 @retval BLE_ERROR_BUFFER_OVERFLOW
lorevee 0:ac0b0725c6fa 86 The proposed action would cause a buffer overflow. All
lorevee 0:ac0b0725c6fa 87 advertising payloads must be <= 31 bytes, for example.
lorevee 0:ac0b0725c6fa 88
lorevee 0:ac0b0725c6fa 89 @retval BLE_ERROR_NOT_IMPLEMENTED
lorevee 0:ac0b0725c6fa 90 A feature was requested that is not yet supported in the
lorevee 0:ac0b0725c6fa 91 nRF51 firmware or hardware.
lorevee 0:ac0b0725c6fa 92
lorevee 0:ac0b0725c6fa 93 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
lorevee 0:ac0b0725c6fa 94 One of the proposed values is outside the valid range.
lorevee 0:ac0b0725c6fa 95
lorevee 0:ac0b0725c6fa 96 @section EXAMPLE
lorevee 0:ac0b0725c6fa 97
lorevee 0:ac0b0725c6fa 98 @code
lorevee 0:ac0b0725c6fa 99
lorevee 0:ac0b0725c6fa 100 @endcode
lorevee 0:ac0b0725c6fa 101 */
lorevee 0:ac0b0725c6fa 102 /**************************************************************************/
lorevee 0:ac0b0725c6fa 103 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
lorevee 0:ac0b0725c6fa 104 {
lorevee 0:ac0b0725c6fa 105 PRINTF("BlueNRGGap::setAdvertisingData\n\r");
lorevee 0:ac0b0725c6fa 106 /* Make sure we don't exceed the advertising payload length */
lorevee 0:ac0b0725c6fa 107 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
lorevee 0:ac0b0725c6fa 108 PRINTF("Exceeded the advertising payload length\n\r");
lorevee 0:ac0b0725c6fa 109 return BLE_ERROR_BUFFER_OVERFLOW;
lorevee 0:ac0b0725c6fa 110 }
lorevee 0:ac0b0725c6fa 111
lorevee 0:ac0b0725c6fa 112 /* Make sure we have a payload! */
lorevee 0:ac0b0725c6fa 113 if (advData.getPayloadLen() != 0) {
lorevee 0:ac0b0725c6fa 114 PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
lorevee 0:ac0b0725c6fa 115
lorevee 0:ac0b0725c6fa 116 /* Align the GAP Service Appearance Char value coherently
lorevee 0:ac0b0725c6fa 117 This setting is duplicate (see below GapAdvertisingData::APPEARANCE)
lorevee 0:ac0b0725c6fa 118 since BLE API has an overloaded function for appearance
lorevee 0:ac0b0725c6fa 119 */
lorevee 0:ac0b0725c6fa 120 STORE_LE_16(deviceAppearance, advData.getAppearance());
lorevee 0:ac0b0725c6fa 121 setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]));
lorevee 0:ac0b0725c6fa 122
lorevee 0:ac0b0725c6fa 123
lorevee 0:ac0b0725c6fa 124 for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
lorevee 0:ac0b0725c6fa 125 loadPtr.getUnitAtIndex(index);
lorevee 0:ac0b0725c6fa 126
lorevee 0:ac0b0725c6fa 127 PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
lorevee 0:ac0b0725c6fa 128 PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));
lorevee 0:ac0b0725c6fa 129
lorevee 0:ac0b0725c6fa 130 switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
lorevee 0:ac0b0725c6fa 131 /**< TX Power Level (in dBm) */
lorevee 0:ac0b0725c6fa 132 case GapAdvertisingData::TX_POWER_LEVEL:
lorevee 0:ac0b0725c6fa 133 {
lorevee 0:ac0b0725c6fa 134 PRINTF("Advertising type: TX_POWER_LEVEL\n\r");
lorevee 0:ac0b0725c6fa 135 int8_t enHighPower = 0;
lorevee 0:ac0b0725c6fa 136 int8_t paLevel = 0;
lorevee 0:ac0b0725c6fa 137
lorevee 0:ac0b0725c6fa 138 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
lorevee 0:ac0b0725c6fa 139 tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 140 #ifdef DEBUG
lorevee 0:ac0b0725c6fa 141 PRINTF("dbm=%d, ret=%d\n\r", dbm, ret);
lorevee 0:ac0b0725c6fa 142 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 143 #endif
lorevee 0:ac0b0725c6fa 144 if(ret == BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 145 aci_hal_set_tx_power_level(enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 146 }
lorevee 0:ac0b0725c6fa 147 break;
lorevee 0:ac0b0725c6fa 148 }
lorevee 0:ac0b0725c6fa 149 /**< Appearance */
lorevee 0:ac0b0725c6fa 150 case GapAdvertisingData::APPEARANCE:
lorevee 0:ac0b0725c6fa 151 {
lorevee 0:ac0b0725c6fa 152 PRINTF("Advertising type: APPEARANCE\n\r");
lorevee 0:ac0b0725c6fa 153
lorevee 0:ac0b0725c6fa 154 GapAdvertisingData::Appearance appearanceP;
lorevee 0:ac0b0725c6fa 155 memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2);
lorevee 0:ac0b0725c6fa 156
lorevee 0:ac0b0725c6fa 157 PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
lorevee 0:ac0b0725c6fa 158
lorevee 0:ac0b0725c6fa 159 appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]);
lorevee 0:ac0b0725c6fa 160 /* Align the GAP Service Appearance Char value coherently */
lorevee 0:ac0b0725c6fa 161 setAppearance(appearanceP);
lorevee 0:ac0b0725c6fa 162 break;
lorevee 0:ac0b0725c6fa 163 }
lorevee 0:ac0b0725c6fa 164
lorevee 0:ac0b0725c6fa 165 } // end switch
lorevee 0:ac0b0725c6fa 166
lorevee 0:ac0b0725c6fa 167 } //end for
lorevee 0:ac0b0725c6fa 168
lorevee 0:ac0b0725c6fa 169 }
lorevee 0:ac0b0725c6fa 170
lorevee 0:ac0b0725c6fa 171 // update the advertising data in the shield if advertising is running
lorevee 0:ac0b0725c6fa 172 if (state.advertising == 1) {
lorevee 0:ac0b0725c6fa 173 tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload());
lorevee 0:ac0b0725c6fa 174
lorevee 0:ac0b0725c6fa 175 if(BLE_STATUS_SUCCESS != ret) {
lorevee 0:ac0b0725c6fa 176 PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
lorevee 0:ac0b0725c6fa 177 switch (ret) {
lorevee 0:ac0b0725c6fa 178 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 179 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 180 default:
lorevee 0:ac0b0725c6fa 181 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 182 }
lorevee 0:ac0b0725c6fa 183 }
lorevee 0:ac0b0725c6fa 184
lorevee 0:ac0b0725c6fa 185 ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload());
lorevee 0:ac0b0725c6fa 186 if (ret) {
lorevee 0:ac0b0725c6fa 187 PRINTF("error while setting the payload\r\n");
lorevee 0:ac0b0725c6fa 188 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 189 }
lorevee 0:ac0b0725c6fa 190 }
lorevee 0:ac0b0725c6fa 191
lorevee 0:ac0b0725c6fa 192 _advData = advData;
lorevee 0:ac0b0725c6fa 193 _scanResponse = scanResponse;
lorevee 0:ac0b0725c6fa 194
lorevee 0:ac0b0725c6fa 195 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 196 }
lorevee 0:ac0b0725c6fa 197
lorevee 0:ac0b0725c6fa 198 /*
lorevee 0:ac0b0725c6fa 199 * Utility to set ADV timeout flag
lorevee 0:ac0b0725c6fa 200 */
lorevee 0:ac0b0725c6fa 201 void BlueNRGGap::setAdvToFlag(void) {
lorevee 0:ac0b0725c6fa 202 AdvToFlag = true;
lorevee 0:ac0b0725c6fa 203 signalEventsToProcess();
lorevee 0:ac0b0725c6fa 204 }
lorevee 0:ac0b0725c6fa 205
lorevee 0:ac0b0725c6fa 206 /*
lorevee 0:ac0b0725c6fa 207 * ADV timeout callback
lorevee 0:ac0b0725c6fa 208 */
lorevee 0:ac0b0725c6fa 209 #ifdef AST_FOR_MBED_OS
lorevee 0:ac0b0725c6fa 210 static void advTimeoutCB(void)
lorevee 0:ac0b0725c6fa 211 {
lorevee 0:ac0b0725c6fa 212 BlueNRGGap::getInstance().stopAdvertising();
lorevee 0:ac0b0725c6fa 213 }
lorevee 0:ac0b0725c6fa 214 #else
lorevee 0:ac0b0725c6fa 215 static void advTimeoutCB(void)
lorevee 0:ac0b0725c6fa 216 {
lorevee 0:ac0b0725c6fa 217 BlueNRGGap::getInstance().setAdvToFlag();
lorevee 0:ac0b0725c6fa 218
lorevee 0:ac0b0725c6fa 219 Timeout& t = BlueNRGGap::getInstance().getAdvTimeout();
lorevee 0:ac0b0725c6fa 220 t.detach(); /* disable the callback from the timeout */
lorevee 0:ac0b0725c6fa 221 }
lorevee 0:ac0b0725c6fa 222 #endif /* AST_FOR_MBED_OS */
lorevee 0:ac0b0725c6fa 223
lorevee 0:ac0b0725c6fa 224 /*
lorevee 0:ac0b0725c6fa 225 * Utility to set SCAN timeout flag
lorevee 0:ac0b0725c6fa 226 */
lorevee 0:ac0b0725c6fa 227 void BlueNRGGap::setScanToFlag(void) {
lorevee 0:ac0b0725c6fa 228 ScanToFlag = true;
lorevee 0:ac0b0725c6fa 229 signalEventsToProcess();
lorevee 0:ac0b0725c6fa 230 }
lorevee 0:ac0b0725c6fa 231
lorevee 0:ac0b0725c6fa 232 static void scanTimeoutCB(void)
lorevee 0:ac0b0725c6fa 233 {
lorevee 0:ac0b0725c6fa 234 BlueNRGGap::getInstance().setScanToFlag();
lorevee 0:ac0b0725c6fa 235
lorevee 0:ac0b0725c6fa 236 Timeout& t = BlueNRGGap::getInstance().getScanTimeout();
lorevee 0:ac0b0725c6fa 237 t.detach(); /* disable the callback from the timeout */
lorevee 0:ac0b0725c6fa 238 }
lorevee 0:ac0b0725c6fa 239
lorevee 0:ac0b0725c6fa 240 /**************************************************************************/
lorevee 0:ac0b0725c6fa 241 /*!
lorevee 0:ac0b0725c6fa 242 @brief Starts the BLE HW, initialising any services that were
lorevee 0:ac0b0725c6fa 243 added before this function was called.
lorevee 0:ac0b0725c6fa 244
lorevee 0:ac0b0725c6fa 245 @param[in] params
lorevee 0:ac0b0725c6fa 246 Basic advertising details, including the advertising
lorevee 0:ac0b0725c6fa 247 delay, timeout and how the device should be advertised
lorevee 0:ac0b0725c6fa 248
lorevee 0:ac0b0725c6fa 249 @note All services must be added before calling this function!
lorevee 0:ac0b0725c6fa 250
lorevee 0:ac0b0725c6fa 251 @returns ble_error_t
lorevee 0:ac0b0725c6fa 252
lorevee 0:ac0b0725c6fa 253 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 254 Everything executed properly
lorevee 0:ac0b0725c6fa 255
lorevee 0:ac0b0725c6fa 256 @section EXAMPLE
lorevee 0:ac0b0725c6fa 257
lorevee 0:ac0b0725c6fa 258 @code
lorevee 0:ac0b0725c6fa 259
lorevee 0:ac0b0725c6fa 260 @endcode
lorevee 0:ac0b0725c6fa 261 */
lorevee 0:ac0b0725c6fa 262 /**************************************************************************/
lorevee 0:ac0b0725c6fa 263
lorevee 0:ac0b0725c6fa 264 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
lorevee 0:ac0b0725c6fa 265 {
lorevee 0:ac0b0725c6fa 266 tBleStatus ret;
lorevee 0:ac0b0725c6fa 267 int err;
lorevee 0:ac0b0725c6fa 268
lorevee 0:ac0b0725c6fa 269 /* Make sure we support the advertising type */
lorevee 0:ac0b0725c6fa 270 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
lorevee 0:ac0b0725c6fa 271 /* ToDo: This requires a proper security implementation, etc. */
lorevee 0:ac0b0725c6fa 272 return BLE_ERROR_NOT_IMPLEMENTED;
lorevee 0:ac0b0725c6fa 273 }
lorevee 0:ac0b0725c6fa 274
lorevee 0:ac0b0725c6fa 275 /* Check interval range */
lorevee 0:ac0b0725c6fa 276 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
lorevee 0:ac0b0725c6fa 277 /* Min delay is slightly longer for unconnectable devices */
lorevee 0:ac0b0725c6fa 278 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
lorevee 0:ac0b0725c6fa 279 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
lorevee 0:ac0b0725c6fa 280 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 281 }
lorevee 0:ac0b0725c6fa 282 } else {
lorevee 0:ac0b0725c6fa 283 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
lorevee 0:ac0b0725c6fa 284 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
lorevee 0:ac0b0725c6fa 285 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 286 }
lorevee 0:ac0b0725c6fa 287 }
lorevee 0:ac0b0725c6fa 288
lorevee 0:ac0b0725c6fa 289 /* Check timeout is zero for Connectable Directed */
lorevee 0:ac0b0725c6fa 290 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
lorevee 0:ac0b0725c6fa 291 /* Timeout must be 0 with this type, although we'll never get here */
lorevee 0:ac0b0725c6fa 292 /* since this isn't implemented yet anyway */
lorevee 0:ac0b0725c6fa 293 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 294 }
lorevee 0:ac0b0725c6fa 295
lorevee 0:ac0b0725c6fa 296 /* Check timeout for other advertising types */
lorevee 0:ac0b0725c6fa 297 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
lorevee 0:ac0b0725c6fa 298 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
lorevee 0:ac0b0725c6fa 299 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 300 }
lorevee 0:ac0b0725c6fa 301
lorevee 0:ac0b0725c6fa 302 /*
lorevee 0:ac0b0725c6fa 303 * Advertising filter policy setting
lorevee 0:ac0b0725c6fa 304 * FIXME: the Security Manager should be implemented
lorevee 0:ac0b0725c6fa 305 */
lorevee 0:ac0b0725c6fa 306 AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode();
lorevee 0:ac0b0725c6fa 307 if(mode != ADV_POLICY_IGNORE_WHITELIST) {
lorevee 0:ac0b0725c6fa 308 ret = aci_gap_configure_whitelist();
lorevee 0:ac0b0725c6fa 309 if(ret != BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 310 PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret);
lorevee 0:ac0b0725c6fa 311 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 312 }
lorevee 0:ac0b0725c6fa 313 }
lorevee 0:ac0b0725c6fa 314
lorevee 0:ac0b0725c6fa 315 uint8_t advFilterPolicy = NO_WHITE_LIST_USE;
lorevee 0:ac0b0725c6fa 316 switch(mode) {
lorevee 0:ac0b0725c6fa 317 case ADV_POLICY_FILTER_SCAN_REQS:
lorevee 0:ac0b0725c6fa 318 advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN;
lorevee 0:ac0b0725c6fa 319 break;
lorevee 0:ac0b0725c6fa 320 case ADV_POLICY_FILTER_CONN_REQS:
lorevee 0:ac0b0725c6fa 321 advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN;
lorevee 0:ac0b0725c6fa 322 break;
lorevee 0:ac0b0725c6fa 323 case ADV_POLICY_FILTER_ALL_REQS:
lorevee 0:ac0b0725c6fa 324 advFilterPolicy = WHITE_LIST_FOR_ALL;
lorevee 0:ac0b0725c6fa 325 break;
lorevee 0:ac0b0725c6fa 326 default:
lorevee 0:ac0b0725c6fa 327 advFilterPolicy = NO_WHITE_LIST_USE;
lorevee 0:ac0b0725c6fa 328 break;
lorevee 0:ac0b0725c6fa 329 }
lorevee 0:ac0b0725c6fa 330
lorevee 0:ac0b0725c6fa 331 /* Check the ADV type before setting scan response data */
lorevee 0:ac0b0725c6fa 332 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ||
lorevee 0:ac0b0725c6fa 333 params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) {
lorevee 0:ac0b0725c6fa 334
lorevee 0:ac0b0725c6fa 335 /* set scan response data */
lorevee 0:ac0b0725c6fa 336 PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen());
lorevee 0:ac0b0725c6fa 337 ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload());
lorevee 0:ac0b0725c6fa 338
lorevee 0:ac0b0725c6fa 339 if(BLE_STATUS_SUCCESS!=ret) {
lorevee 0:ac0b0725c6fa 340 PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
lorevee 0:ac0b0725c6fa 341 switch (ret) {
lorevee 0:ac0b0725c6fa 342 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 343 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 344 default:
lorevee 0:ac0b0725c6fa 345 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 346 }
lorevee 0:ac0b0725c6fa 347 }
lorevee 0:ac0b0725c6fa 348 } else {
lorevee 0:ac0b0725c6fa 349 hci_le_set_scan_resp_data(0, NULL);
lorevee 0:ac0b0725c6fa 350 }
lorevee 0:ac0b0725c6fa 351
lorevee 0:ac0b0725c6fa 352 setAdvParameters();
lorevee 0:ac0b0725c6fa 353 PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType());
lorevee 0:ac0b0725c6fa 354
lorevee 0:ac0b0725c6fa 355 err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload());
lorevee 0:ac0b0725c6fa 356
lorevee 0:ac0b0725c6fa 357 if (err) {
lorevee 0:ac0b0725c6fa 358 PRINTF("error while setting the payload\r\n");
lorevee 0:ac0b0725c6fa 359 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 360 }
lorevee 0:ac0b0725c6fa 361
lorevee 0:ac0b0725c6fa 362 tBDAddr dummy_addr = { 0 };
lorevee 0:ac0b0725c6fa 363 uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval;
lorevee 0:ac0b0725c6fa 364 uint16_t advIntervalMax = advIntervalMin + 1;
lorevee 0:ac0b0725c6fa 365
lorevee 0:ac0b0725c6fa 366 err = hci_le_set_advertising_parameters(
lorevee 0:ac0b0725c6fa 367 advIntervalMin,
lorevee 0:ac0b0725c6fa 368 advIntervalMax,
lorevee 0:ac0b0725c6fa 369 params.getAdvertisingType(),
lorevee 0:ac0b0725c6fa 370 addr_type,
lorevee 0:ac0b0725c6fa 371 0x00,
lorevee 0:ac0b0725c6fa 372 dummy_addr,
lorevee 0:ac0b0725c6fa 373 /* all channels */ 7,
lorevee 0:ac0b0725c6fa 374 advFilterPolicy
lorevee 0:ac0b0725c6fa 375 );
lorevee 0:ac0b0725c6fa 376
lorevee 0:ac0b0725c6fa 377 if (err) {
lorevee 0:ac0b0725c6fa 378 PRINTF("impossible to set advertising parameters\n\r");
lorevee 0:ac0b0725c6fa 379 PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
lorevee 0:ac0b0725c6fa 380 PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
lorevee 0:ac0b0725c6fa 381 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 382 }
lorevee 0:ac0b0725c6fa 383
lorevee 0:ac0b0725c6fa 384 err = hci_le_set_advertise_enable(0x01);
lorevee 0:ac0b0725c6fa 385 if (err) {
lorevee 0:ac0b0725c6fa 386 PRINTF("impossible to start advertising\n\r");
lorevee 0:ac0b0725c6fa 387 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 388 }
lorevee 0:ac0b0725c6fa 389
lorevee 0:ac0b0725c6fa 390 if(params.getTimeout() != 0) {
lorevee 0:ac0b0725c6fa 391 PRINTF("!!! attaching adv to!!!\n");
lorevee 0:ac0b0725c6fa 392 #ifdef AST_FOR_MBED_OS
lorevee 0:ac0b0725c6fa 393 minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
lorevee 0:ac0b0725c6fa 394 #else
lorevee 0:ac0b0725c6fa 395 advTimeout.attach(advTimeoutCB, params.getTimeout());
lorevee 0:ac0b0725c6fa 396 #endif
lorevee 0:ac0b0725c6fa 397 }
lorevee 0:ac0b0725c6fa 398
lorevee 0:ac0b0725c6fa 399 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 400
lorevee 0:ac0b0725c6fa 401 }
lorevee 0:ac0b0725c6fa 402
lorevee 0:ac0b0725c6fa 403
lorevee 0:ac0b0725c6fa 404 /**************************************************************************/
lorevee 0:ac0b0725c6fa 405 /*!
lorevee 0:ac0b0725c6fa 406 @brief Stops the BLE HW and disconnects from any devices
lorevee 0:ac0b0725c6fa 407
lorevee 0:ac0b0725c6fa 408 @returns ble_error_t
lorevee 0:ac0b0725c6fa 409
lorevee 0:ac0b0725c6fa 410 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 411 Everything executed properly
lorevee 0:ac0b0725c6fa 412
lorevee 0:ac0b0725c6fa 413 @section EXAMPLE
lorevee 0:ac0b0725c6fa 414
lorevee 0:ac0b0725c6fa 415 @code
lorevee 0:ac0b0725c6fa 416
lorevee 0:ac0b0725c6fa 417 @endcode
lorevee 0:ac0b0725c6fa 418 */
lorevee 0:ac0b0725c6fa 419 /**************************************************************************/
lorevee 0:ac0b0725c6fa 420 ble_error_t BlueNRGGap::stopAdvertising(void)
lorevee 0:ac0b0725c6fa 421 {
lorevee 0:ac0b0725c6fa 422 if(state.advertising == 1) {
lorevee 0:ac0b0725c6fa 423
lorevee 0:ac0b0725c6fa 424 int err = hci_le_set_advertise_enable(0);
lorevee 0:ac0b0725c6fa 425 if (err) {
lorevee 0:ac0b0725c6fa 426 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 427 }
lorevee 0:ac0b0725c6fa 428
lorevee 0:ac0b0725c6fa 429 PRINTF("Advertisement stopped!!\n\r") ;
lorevee 0:ac0b0725c6fa 430 //Set GapState_t::advertising state
lorevee 0:ac0b0725c6fa 431 state.advertising = 0;
lorevee 0:ac0b0725c6fa 432 }
lorevee 0:ac0b0725c6fa 433
lorevee 0:ac0b0725c6fa 434 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 435 }
lorevee 0:ac0b0725c6fa 436
lorevee 0:ac0b0725c6fa 437 /**************************************************************************/
lorevee 0:ac0b0725c6fa 438 /*!
lorevee 0:ac0b0725c6fa 439 @brief Disconnects if we are connected to a central device
lorevee 0:ac0b0725c6fa 440
lorevee 0:ac0b0725c6fa 441 @param[in] reason
lorevee 0:ac0b0725c6fa 442 Disconnection Reason
lorevee 0:ac0b0725c6fa 443
lorevee 0:ac0b0725c6fa 444 @returns ble_error_t
lorevee 0:ac0b0725c6fa 445
lorevee 0:ac0b0725c6fa 446 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 447 Everything executed properly
lorevee 0:ac0b0725c6fa 448
lorevee 0:ac0b0725c6fa 449 @section EXAMPLE
lorevee 0:ac0b0725c6fa 450
lorevee 0:ac0b0725c6fa 451 @code
lorevee 0:ac0b0725c6fa 452
lorevee 0:ac0b0725c6fa 453 @endcode
lorevee 0:ac0b0725c6fa 454 */
lorevee 0:ac0b0725c6fa 455 /**************************************************************************/
lorevee 0:ac0b0725c6fa 456 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
lorevee 0:ac0b0725c6fa 457 {
lorevee 0:ac0b0725c6fa 458 tBleStatus ret;
lorevee 0:ac0b0725c6fa 459
lorevee 0:ac0b0725c6fa 460 ret = aci_gap_terminate(connectionHandle, reason);
lorevee 0:ac0b0725c6fa 461
lorevee 0:ac0b0725c6fa 462 if (BLE_STATUS_SUCCESS != ret){
lorevee 0:ac0b0725c6fa 463 PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
lorevee 0:ac0b0725c6fa 464 switch (ret) {
lorevee 0:ac0b0725c6fa 465 case ERR_COMMAND_DISALLOWED:
lorevee 0:ac0b0725c6fa 466 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 467 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 468 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 469 default:
lorevee 0:ac0b0725c6fa 470 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 471 }
lorevee 0:ac0b0725c6fa 472 }
lorevee 0:ac0b0725c6fa 473
lorevee 0:ac0b0725c6fa 474 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 475 }
lorevee 0:ac0b0725c6fa 476
lorevee 0:ac0b0725c6fa 477 /**************************************************************************/
lorevee 0:ac0b0725c6fa 478 /*!
lorevee 0:ac0b0725c6fa 479 @brief Disconnects if we are connected to a central device
lorevee 0:ac0b0725c6fa 480
lorevee 0:ac0b0725c6fa 481 @param[in] reason
lorevee 0:ac0b0725c6fa 482 Disconnection Reason
lorevee 0:ac0b0725c6fa 483
lorevee 0:ac0b0725c6fa 484 @returns ble_error_t
lorevee 0:ac0b0725c6fa 485
lorevee 0:ac0b0725c6fa 486 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 487 Everything executed properly
lorevee 0:ac0b0725c6fa 488
lorevee 0:ac0b0725c6fa 489 @section EXAMPLE
lorevee 0:ac0b0725c6fa 490
lorevee 0:ac0b0725c6fa 491 @code
lorevee 0:ac0b0725c6fa 492
lorevee 0:ac0b0725c6fa 493 @endcode
lorevee 0:ac0b0725c6fa 494 */
lorevee 0:ac0b0725c6fa 495 /**************************************************************************/
lorevee 0:ac0b0725c6fa 496 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
lorevee 0:ac0b0725c6fa 497 {
lorevee 0:ac0b0725c6fa 498 return disconnect(m_connectionHandle, reason);
lorevee 0:ac0b0725c6fa 499 }
lorevee 0:ac0b0725c6fa 500
lorevee 0:ac0b0725c6fa 501 /**************************************************************************/
lorevee 0:ac0b0725c6fa 502 /*!
lorevee 0:ac0b0725c6fa 503 @brief Sets the 16-bit connection handle
lorevee 0:ac0b0725c6fa 504
lorevee 0:ac0b0725c6fa 505 @param[in] conn_handle
lorevee 0:ac0b0725c6fa 506 Connection Handle which is set in the Gap Instance
lorevee 0:ac0b0725c6fa 507
lorevee 0:ac0b0725c6fa 508 @returns void
lorevee 0:ac0b0725c6fa 509 */
lorevee 0:ac0b0725c6fa 510 /**************************************************************************/
lorevee 0:ac0b0725c6fa 511 void BlueNRGGap::setConnectionHandle(uint16_t conn_handle)
lorevee 0:ac0b0725c6fa 512 {
lorevee 0:ac0b0725c6fa 513 m_connectionHandle = conn_handle;
lorevee 0:ac0b0725c6fa 514 }
lorevee 0:ac0b0725c6fa 515
lorevee 0:ac0b0725c6fa 516 /**************************************************************************/
lorevee 0:ac0b0725c6fa 517 /*!
lorevee 0:ac0b0725c6fa 518 @brief Gets the 16-bit connection handle
lorevee 0:ac0b0725c6fa 519
lorevee 0:ac0b0725c6fa 520 @param[in] void
lorevee 0:ac0b0725c6fa 521
lorevee 0:ac0b0725c6fa 522 @returns uint16_t
lorevee 0:ac0b0725c6fa 523 Connection Handle of the Gap Instance
lorevee 0:ac0b0725c6fa 524 */
lorevee 0:ac0b0725c6fa 525 /**************************************************************************/
lorevee 0:ac0b0725c6fa 526 uint16_t BlueNRGGap::getConnectionHandle(void)
lorevee 0:ac0b0725c6fa 527 {
lorevee 0:ac0b0725c6fa 528 return m_connectionHandle;
lorevee 0:ac0b0725c6fa 529 }
lorevee 0:ac0b0725c6fa 530
lorevee 0:ac0b0725c6fa 531 /**************************************************************************/
lorevee 0:ac0b0725c6fa 532 /*!
lorevee 0:ac0b0725c6fa 533 @brief Sets the BLE device address. SetAddress will reset the BLE
lorevee 0:ac0b0725c6fa 534 device and re-initialize BTLE. Will not start advertising.
lorevee 0:ac0b0725c6fa 535
lorevee 0:ac0b0725c6fa 536 @param[in] type
lorevee 0:ac0b0725c6fa 537 Type of Address
lorevee 0:ac0b0725c6fa 538
lorevee 0:ac0b0725c6fa 539 @param[in] address[6]
lorevee 0:ac0b0725c6fa 540 Value of the Address to be set
lorevee 0:ac0b0725c6fa 541
lorevee 0:ac0b0725c6fa 542 @returns ble_error_t
lorevee 0:ac0b0725c6fa 543
lorevee 0:ac0b0725c6fa 544 @section EXAMPLE
lorevee 0:ac0b0725c6fa 545
lorevee 0:ac0b0725c6fa 546 @code
lorevee 0:ac0b0725c6fa 547
lorevee 0:ac0b0725c6fa 548 @endcode
lorevee 0:ac0b0725c6fa 549 */
lorevee 0:ac0b0725c6fa 550 /**************************************************************************/
lorevee 0:ac0b0725c6fa 551 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address)
lorevee 0:ac0b0725c6fa 552 {
lorevee 0:ac0b0725c6fa 553 if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
lorevee 0:ac0b0725c6fa 554 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 555 }
lorevee 0:ac0b0725c6fa 556
lorevee 0:ac0b0725c6fa 557 if(type == BLEProtocol::AddressType::PUBLIC){
lorevee 0:ac0b0725c6fa 558 tBleStatus ret = aci_hal_write_config_data(
lorevee 0:ac0b0725c6fa 559 CONFIG_DATA_PUBADDR_OFFSET,
lorevee 0:ac0b0725c6fa 560 CONFIG_DATA_PUBADDR_LEN,
lorevee 0:ac0b0725c6fa 561 address
lorevee 0:ac0b0725c6fa 562 );
lorevee 0:ac0b0725c6fa 563 if(ret != BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 564 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 565 }
lorevee 0:ac0b0725c6fa 566 } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) {
lorevee 0:ac0b0725c6fa 567 // ensure that the random static address is well formed
lorevee 0:ac0b0725c6fa 568 if ((address[5] & 0xC0) != 0xC0) {
lorevee 0:ac0b0725c6fa 569 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 570 }
lorevee 0:ac0b0725c6fa 571
lorevee 0:ac0b0725c6fa 572 // thanks to const correctness of the API ...
lorevee 0:ac0b0725c6fa 573 tBDAddr random_address = { 0 };
lorevee 0:ac0b0725c6fa 574 memcpy(random_address, address, sizeof(random_address));
lorevee 0:ac0b0725c6fa 575 int err = hci_le_set_random_address(random_address);
lorevee 0:ac0b0725c6fa 576 if (err) {
lorevee 0:ac0b0725c6fa 577 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 578 }
lorevee 0:ac0b0725c6fa 579
lorevee 0:ac0b0725c6fa 580 // It is not possible to get the bluetooth address when it is set
lorevee 0:ac0b0725c6fa 581 // store it locally in class data member
lorevee 0:ac0b0725c6fa 582 memcpy(bdaddr, address, sizeof(bdaddr));
lorevee 0:ac0b0725c6fa 583 } else {
lorevee 0:ac0b0725c6fa 584 // FIXME random addresses are not supported yet
lorevee 0:ac0b0725c6fa 585 // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
lorevee 0:ac0b0725c6fa 586 // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
lorevee 0:ac0b0725c6fa 587 return BLE_ERROR_NOT_IMPLEMENTED;
lorevee 0:ac0b0725c6fa 588 }
lorevee 0:ac0b0725c6fa 589
lorevee 0:ac0b0725c6fa 590 // if we're here then the address was correctly set
lorevee 0:ac0b0725c6fa 591 // commit it inside the addr_type
lorevee 0:ac0b0725c6fa 592 addr_type = type;
lorevee 0:ac0b0725c6fa 593 isSetAddress = true;
lorevee 0:ac0b0725c6fa 594 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 595 }
lorevee 0:ac0b0725c6fa 596
lorevee 0:ac0b0725c6fa 597 /**************************************************************************/
lorevee 0:ac0b0725c6fa 598 /*!
lorevee 0:ac0b0725c6fa 599 @brief Returns boolean if the address of the device has been set
lorevee 0:ac0b0725c6fa 600 or not
lorevee 0:ac0b0725c6fa 601
lorevee 0:ac0b0725c6fa 602 @returns bool
lorevee 0:ac0b0725c6fa 603
lorevee 0:ac0b0725c6fa 604 @section EXAMPLE
lorevee 0:ac0b0725c6fa 605
lorevee 0:ac0b0725c6fa 606 @code
lorevee 0:ac0b0725c6fa 607
lorevee 0:ac0b0725c6fa 608 @endcode
lorevee 0:ac0b0725c6fa 609 */
lorevee 0:ac0b0725c6fa 610 /**************************************************************************/
lorevee 0:ac0b0725c6fa 611 bool BlueNRGGap::getIsSetAddress()
lorevee 0:ac0b0725c6fa 612 {
lorevee 0:ac0b0725c6fa 613 return isSetAddress;
lorevee 0:ac0b0725c6fa 614 }
lorevee 0:ac0b0725c6fa 615
lorevee 0:ac0b0725c6fa 616 /**************************************************************************/
lorevee 0:ac0b0725c6fa 617 /*!
lorevee 0:ac0b0725c6fa 618 @brief Returns the address of the device if set
lorevee 0:ac0b0725c6fa 619
lorevee 0:ac0b0725c6fa 620 @returns Pointer to the address if Address is set else NULL
lorevee 0:ac0b0725c6fa 621
lorevee 0:ac0b0725c6fa 622 @section EXAMPLE
lorevee 0:ac0b0725c6fa 623
lorevee 0:ac0b0725c6fa 624 @code
lorevee 0:ac0b0725c6fa 625
lorevee 0:ac0b0725c6fa 626 @endcode
lorevee 0:ac0b0725c6fa 627 */
lorevee 0:ac0b0725c6fa 628 /**************************************************************************/
lorevee 0:ac0b0725c6fa 629 ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address)
lorevee 0:ac0b0725c6fa 630 {
lorevee 0:ac0b0725c6fa 631 uint8_t bdaddr[BDADDR_SIZE];
lorevee 0:ac0b0725c6fa 632 uint8_t data_len_out;
lorevee 0:ac0b0725c6fa 633
lorevee 0:ac0b0725c6fa 634 // precondition, check that pointers in input are valid
lorevee 0:ac0b0725c6fa 635 if (typeP == NULL || address == NULL) {
lorevee 0:ac0b0725c6fa 636 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 637 }
lorevee 0:ac0b0725c6fa 638
lorevee 0:ac0b0725c6fa 639 if (addr_type == BLEProtocol::AddressType::PUBLIC) {
lorevee 0:ac0b0725c6fa 640 tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr);
lorevee 0:ac0b0725c6fa 641 if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) {
lorevee 0:ac0b0725c6fa 642 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 643 }
lorevee 0:ac0b0725c6fa 644 } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) {
lorevee 0:ac0b0725c6fa 645 // FIXME hci_read_bd_addr and
lorevee 0:ac0b0725c6fa 646 // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1
lorevee 0:ac0b0725c6fa 647 // does not work, use the address stored in class data member
lorevee 0:ac0b0725c6fa 648 memcpy(bdaddr, this->bdaddr, sizeof(bdaddr));
lorevee 0:ac0b0725c6fa 649 } else {
lorevee 0:ac0b0725c6fa 650 // FIXME: should be implemented with privacy features
lorevee 0:ac0b0725c6fa 651 // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
lorevee 0:ac0b0725c6fa 652 // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
lorevee 0:ac0b0725c6fa 653 return BLE_ERROR_NOT_IMPLEMENTED;
lorevee 0:ac0b0725c6fa 654 }
lorevee 0:ac0b0725c6fa 655
lorevee 0:ac0b0725c6fa 656 *typeP = addr_type;
lorevee 0:ac0b0725c6fa 657 memcpy(address, bdaddr, BDADDR_SIZE);
lorevee 0:ac0b0725c6fa 658
lorevee 0:ac0b0725c6fa 659 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 660 }
lorevee 0:ac0b0725c6fa 661
lorevee 0:ac0b0725c6fa 662 /**************************************************************************/
lorevee 0:ac0b0725c6fa 663 /*!
lorevee 0:ac0b0725c6fa 664 @brief obtains preferred connection params
lorevee 0:ac0b0725c6fa 665
lorevee 0:ac0b0725c6fa 666 @returns ble_error_t
lorevee 0:ac0b0725c6fa 667
lorevee 0:ac0b0725c6fa 668 @section EXAMPLE
lorevee 0:ac0b0725c6fa 669
lorevee 0:ac0b0725c6fa 670 @code
lorevee 0:ac0b0725c6fa 671
lorevee 0:ac0b0725c6fa 672 @endcode
lorevee 0:ac0b0725c6fa 673 */
lorevee 0:ac0b0725c6fa 674 /**************************************************************************/
lorevee 0:ac0b0725c6fa 675 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params)
lorevee 0:ac0b0725c6fa 676 {
lorevee 0:ac0b0725c6fa 677 static const size_t parameter_size = 2;
lorevee 0:ac0b0725c6fa 678
lorevee 0:ac0b0725c6fa 679 if (!g_preferred_connection_parameters_char_handle) {
lorevee 0:ac0b0725c6fa 680 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 681 }
lorevee 0:ac0b0725c6fa 682
lorevee 0:ac0b0725c6fa 683 // Peripheral preferred connection parameters are an array of 4 uint16_t
lorevee 0:ac0b0725c6fa 684 uint8_t parameters_packed[parameter_size * 4];
lorevee 0:ac0b0725c6fa 685 uint16_t bytes_read = 0;
lorevee 0:ac0b0725c6fa 686
lorevee 0:ac0b0725c6fa 687 tBleStatus err = aci_gatt_read_handle_value(
lorevee 0:ac0b0725c6fa 688 g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE,
lorevee 0:ac0b0725c6fa 689 sizeof(parameters_packed),
lorevee 0:ac0b0725c6fa 690 &bytes_read,
lorevee 0:ac0b0725c6fa 691 parameters_packed
lorevee 0:ac0b0725c6fa 692 );
lorevee 0:ac0b0725c6fa 693
lorevee 0:ac0b0725c6fa 694 PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read);
lorevee 0:ac0b0725c6fa 695
lorevee 0:ac0b0725c6fa 696 // check that the read succeed and the result have the expected length
lorevee 0:ac0b0725c6fa 697 if (err || bytes_read != sizeof(parameters_packed)) {
lorevee 0:ac0b0725c6fa 698 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 699 }
lorevee 0:ac0b0725c6fa 700
lorevee 0:ac0b0725c6fa 701 // memcpy field by field
lorevee 0:ac0b0725c6fa 702 memcpy(&params->minConnectionInterval, parameters_packed, parameter_size);
lorevee 0:ac0b0725c6fa 703 memcpy(&params->maxConnectionInterval, &parameters_packed[parameter_size], parameter_size);
lorevee 0:ac0b0725c6fa 704 memcpy(&params->slaveLatency, &parameters_packed[2 * parameter_size], parameter_size);
lorevee 0:ac0b0725c6fa 705 memcpy(&params->connectionSupervisionTimeout, &parameters_packed[3 * parameter_size], parameter_size);
lorevee 0:ac0b0725c6fa 706
lorevee 0:ac0b0725c6fa 707 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 708 }
lorevee 0:ac0b0725c6fa 709
lorevee 0:ac0b0725c6fa 710
lorevee 0:ac0b0725c6fa 711 /**************************************************************************/
lorevee 0:ac0b0725c6fa 712 /*!
lorevee 0:ac0b0725c6fa 713 @brief sets preferred connection params
lorevee 0:ac0b0725c6fa 714
lorevee 0:ac0b0725c6fa 715 @returns ble_error_t
lorevee 0:ac0b0725c6fa 716
lorevee 0:ac0b0725c6fa 717 @section EXAMPLE
lorevee 0:ac0b0725c6fa 718
lorevee 0:ac0b0725c6fa 719 @code
lorevee 0:ac0b0725c6fa 720
lorevee 0:ac0b0725c6fa 721 @endcode
lorevee 0:ac0b0725c6fa 722 */
lorevee 0:ac0b0725c6fa 723 /**************************************************************************/
lorevee 0:ac0b0725c6fa 724 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params)
lorevee 0:ac0b0725c6fa 725 {
lorevee 0:ac0b0725c6fa 726 static const size_t parameter_size = 2;
lorevee 0:ac0b0725c6fa 727 uint8_t parameters_packed[parameter_size * 4];
lorevee 0:ac0b0725c6fa 728
lorevee 0:ac0b0725c6fa 729 // ensure that parameters are correct
lorevee 0:ac0b0725c6fa 730 // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C]
lorevee 0:ac0b0725c6fa 731 // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC
lorevee 0:ac0b0725c6fa 732 if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) &&
lorevee 0:ac0b0725c6fa 733 params->minConnectionInterval != 0xFFFF) {
lorevee 0:ac0b0725c6fa 734 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 735 }
lorevee 0:ac0b0725c6fa 736
lorevee 0:ac0b0725c6fa 737 if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) &&
lorevee 0:ac0b0725c6fa 738 params->maxConnectionInterval != 0xFFFF) {
lorevee 0:ac0b0725c6fa 739 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 740 }
lorevee 0:ac0b0725c6fa 741
lorevee 0:ac0b0725c6fa 742 if (params->slaveLatency > 0x01F3) {
lorevee 0:ac0b0725c6fa 743 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 744 }
lorevee 0:ac0b0725c6fa 745
lorevee 0:ac0b0725c6fa 746 if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) &&
lorevee 0:ac0b0725c6fa 747 params->connectionSupervisionTimeout != 0xFFFF) {
lorevee 0:ac0b0725c6fa 748 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 749 }
lorevee 0:ac0b0725c6fa 750
lorevee 0:ac0b0725c6fa 751 // copy the parameters inside the byte array
lorevee 0:ac0b0725c6fa 752 memcpy(parameters_packed, &params->minConnectionInterval, parameter_size);
lorevee 0:ac0b0725c6fa 753 memcpy(&parameters_packed[parameter_size], &params->maxConnectionInterval, parameter_size);
lorevee 0:ac0b0725c6fa 754 memcpy(&parameters_packed[2 * parameter_size], &params->slaveLatency, parameter_size);
lorevee 0:ac0b0725c6fa 755 memcpy(&parameters_packed[3 * parameter_size], &params->connectionSupervisionTimeout, parameter_size);
lorevee 0:ac0b0725c6fa 756
lorevee 0:ac0b0725c6fa 757 tBleStatus err = aci_gatt_update_char_value(
lorevee 0:ac0b0725c6fa 758 g_gap_service_handle,
lorevee 0:ac0b0725c6fa 759 g_preferred_connection_parameters_char_handle,
lorevee 0:ac0b0725c6fa 760 /* offset */ 0,
lorevee 0:ac0b0725c6fa 761 sizeof(parameters_packed),
lorevee 0:ac0b0725c6fa 762 parameters_packed
lorevee 0:ac0b0725c6fa 763 );
lorevee 0:ac0b0725c6fa 764
lorevee 0:ac0b0725c6fa 765 if (err) {
lorevee 0:ac0b0725c6fa 766 PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ;
lorevee 0:ac0b0725c6fa 767 switch (err) {
lorevee 0:ac0b0725c6fa 768 case BLE_STATUS_INVALID_HANDLE:
lorevee 0:ac0b0725c6fa 769 case BLE_STATUS_INVALID_PARAMETER:
lorevee 0:ac0b0725c6fa 770 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 771 case BLE_STATUS_INSUFFICIENT_RESOURCES:
lorevee 0:ac0b0725c6fa 772 return BLE_ERROR_NO_MEM;
lorevee 0:ac0b0725c6fa 773 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 774 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 775 default:
lorevee 0:ac0b0725c6fa 776 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 777 }
lorevee 0:ac0b0725c6fa 778 }
lorevee 0:ac0b0725c6fa 779
lorevee 0:ac0b0725c6fa 780 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 781 }
lorevee 0:ac0b0725c6fa 782
lorevee 0:ac0b0725c6fa 783 /**************************************************************************/
lorevee 0:ac0b0725c6fa 784 /*!
lorevee 0:ac0b0725c6fa 785 @brief updates preferred connection params
lorevee 0:ac0b0725c6fa 786
lorevee 0:ac0b0725c6fa 787 @returns ble_error_t
lorevee 0:ac0b0725c6fa 788
lorevee 0:ac0b0725c6fa 789 @section EXAMPLE
lorevee 0:ac0b0725c6fa 790
lorevee 0:ac0b0725c6fa 791 @code
lorevee 0:ac0b0725c6fa 792
lorevee 0:ac0b0725c6fa 793 @endcode
lorevee 0:ac0b0725c6fa 794 */
lorevee 0:ac0b0725c6fa 795 /**************************************************************************/
lorevee 0:ac0b0725c6fa 796 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
lorevee 0:ac0b0725c6fa 797 {
lorevee 0:ac0b0725c6fa 798 tBleStatus ret = BLE_STATUS_SUCCESS;
lorevee 0:ac0b0725c6fa 799
lorevee 0:ac0b0725c6fa 800 if(gapRole == Gap::CENTRAL) {
lorevee 0:ac0b0725c6fa 801 ret = aci_gap_start_connection_update(handle,
lorevee 0:ac0b0725c6fa 802 params->minConnectionInterval,
lorevee 0:ac0b0725c6fa 803 params->maxConnectionInterval,
lorevee 0:ac0b0725c6fa 804 params->slaveLatency,
lorevee 0:ac0b0725c6fa 805 params->connectionSupervisionTimeout,
lorevee 0:ac0b0725c6fa 806 CONN_L1, CONN_L2);
lorevee 0:ac0b0725c6fa 807 } else {
lorevee 0:ac0b0725c6fa 808 ret = aci_l2cap_connection_parameter_update_request(handle,
lorevee 0:ac0b0725c6fa 809 params->minConnectionInterval,
lorevee 0:ac0b0725c6fa 810 params->maxConnectionInterval,
lorevee 0:ac0b0725c6fa 811 params->slaveLatency,
lorevee 0:ac0b0725c6fa 812 params->connectionSupervisionTimeout);
lorevee 0:ac0b0725c6fa 813 }
lorevee 0:ac0b0725c6fa 814
lorevee 0:ac0b0725c6fa 815 if (BLE_STATUS_SUCCESS != ret){
lorevee 0:ac0b0725c6fa 816 PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ;
lorevee 0:ac0b0725c6fa 817 switch (ret) {
lorevee 0:ac0b0725c6fa 818 case ERR_INVALID_HCI_CMD_PARAMS:
lorevee 0:ac0b0725c6fa 819 case BLE_STATUS_INVALID_PARAMETER:
lorevee 0:ac0b0725c6fa 820 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 821 case ERR_COMMAND_DISALLOWED:
lorevee 0:ac0b0725c6fa 822 case BLE_STATUS_NOT_ALLOWED:
lorevee 0:ac0b0725c6fa 823 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 824 default:
lorevee 0:ac0b0725c6fa 825 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 826 }
lorevee 0:ac0b0725c6fa 827 }
lorevee 0:ac0b0725c6fa 828
lorevee 0:ac0b0725c6fa 829 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 830 }
lorevee 0:ac0b0725c6fa 831
lorevee 0:ac0b0725c6fa 832 /**************************************************************************/
lorevee 0:ac0b0725c6fa 833 /*!
lorevee 0:ac0b0725c6fa 834 @brief Sets the Device Name Characteristic
lorevee 0:ac0b0725c6fa 835
lorevee 0:ac0b0725c6fa 836 @param[in] deviceName
lorevee 0:ac0b0725c6fa 837 pointer to device name to be set
lorevee 0:ac0b0725c6fa 838
lorevee 0:ac0b0725c6fa 839 @returns ble_error_t
lorevee 0:ac0b0725c6fa 840
lorevee 0:ac0b0725c6fa 841 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 842 Everything executed properly
lorevee 0:ac0b0725c6fa 843
lorevee 0:ac0b0725c6fa 844 @section EXAMPLE
lorevee 0:ac0b0725c6fa 845
lorevee 0:ac0b0725c6fa 846 @code
lorevee 0:ac0b0725c6fa 847
lorevee 0:ac0b0725c6fa 848 @endcode
lorevee 0:ac0b0725c6fa 849 */
lorevee 0:ac0b0725c6fa 850 /**************************************************************************/
lorevee 0:ac0b0725c6fa 851 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName)
lorevee 0:ac0b0725c6fa 852 {
lorevee 0:ac0b0725c6fa 853 tBleStatus ret;
lorevee 0:ac0b0725c6fa 854 uint8_t nameLen = 0;
lorevee 0:ac0b0725c6fa 855
lorevee 0:ac0b0725c6fa 856 nameLen = strlen((const char*)deviceName);
lorevee 0:ac0b0725c6fa 857 PRINTF("DeviceName Size=%d\n\r", nameLen);
lorevee 0:ac0b0725c6fa 858
lorevee 0:ac0b0725c6fa 859 ret = aci_gatt_update_char_value(g_gap_service_handle,
lorevee 0:ac0b0725c6fa 860 g_device_name_char_handle,
lorevee 0:ac0b0725c6fa 861 0,
lorevee 0:ac0b0725c6fa 862 nameLen,
lorevee 0:ac0b0725c6fa 863 deviceName);
lorevee 0:ac0b0725c6fa 864
lorevee 0:ac0b0725c6fa 865 if (BLE_STATUS_SUCCESS != ret){
lorevee 0:ac0b0725c6fa 866 PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
lorevee 0:ac0b0725c6fa 867 switch (ret) {
lorevee 0:ac0b0725c6fa 868 case BLE_STATUS_INVALID_HANDLE:
lorevee 0:ac0b0725c6fa 869 case BLE_STATUS_INVALID_PARAMETER:
lorevee 0:ac0b0725c6fa 870 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 871 case BLE_STATUS_INSUFFICIENT_RESOURCES:
lorevee 0:ac0b0725c6fa 872 return BLE_ERROR_NO_MEM;
lorevee 0:ac0b0725c6fa 873 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 874 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 875 default:
lorevee 0:ac0b0725c6fa 876 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 877 }
lorevee 0:ac0b0725c6fa 878 }
lorevee 0:ac0b0725c6fa 879
lorevee 0:ac0b0725c6fa 880 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 881 }
lorevee 0:ac0b0725c6fa 882
lorevee 0:ac0b0725c6fa 883 /**************************************************************************/
lorevee 0:ac0b0725c6fa 884 /*!
lorevee 0:ac0b0725c6fa 885 @brief Gets the Device Name Characteristic
lorevee 0:ac0b0725c6fa 886
lorevee 0:ac0b0725c6fa 887 @param[in] deviceName
lorevee 0:ac0b0725c6fa 888 pointer to device name
lorevee 0:ac0b0725c6fa 889
lorevee 0:ac0b0725c6fa 890 @param[in] lengthP
lorevee 0:ac0b0725c6fa 891 pointer to device name length
lorevee 0:ac0b0725c6fa 892
lorevee 0:ac0b0725c6fa 893 @returns ble_error_t
lorevee 0:ac0b0725c6fa 894
lorevee 0:ac0b0725c6fa 895 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 896 Everything executed properly
lorevee 0:ac0b0725c6fa 897
lorevee 0:ac0b0725c6fa 898 @section EXAMPLE
lorevee 0:ac0b0725c6fa 899
lorevee 0:ac0b0725c6fa 900 @code
lorevee 0:ac0b0725c6fa 901
lorevee 0:ac0b0725c6fa 902 @endcode
lorevee 0:ac0b0725c6fa 903 */
lorevee 0:ac0b0725c6fa 904 /**************************************************************************/
lorevee 0:ac0b0725c6fa 905 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
lorevee 0:ac0b0725c6fa 906 {
lorevee 0:ac0b0725c6fa 907 tBleStatus ret;
lorevee 0:ac0b0725c6fa 908
lorevee 0:ac0b0725c6fa 909 ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
lorevee 0:ac0b0725c6fa 910 *lengthP,
lorevee 0:ac0b0725c6fa 911 (uint16_t *)lengthP,
lorevee 0:ac0b0725c6fa 912 deviceName);
lorevee 0:ac0b0725c6fa 913 PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP);
lorevee 0:ac0b0725c6fa 914 if (ret == BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 915 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 916 } else {
lorevee 0:ac0b0725c6fa 917 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 918 }
lorevee 0:ac0b0725c6fa 919 }
lorevee 0:ac0b0725c6fa 920
lorevee 0:ac0b0725c6fa 921 /**************************************************************************/
lorevee 0:ac0b0725c6fa 922 /*!
lorevee 0:ac0b0725c6fa 923 @brief Sets the Device Appearance Characteristic
lorevee 0:ac0b0725c6fa 924
lorevee 0:ac0b0725c6fa 925 @param[in] appearance
lorevee 0:ac0b0725c6fa 926 device appearance
lorevee 0:ac0b0725c6fa 927
lorevee 0:ac0b0725c6fa 928 @returns ble_error_t
lorevee 0:ac0b0725c6fa 929
lorevee 0:ac0b0725c6fa 930 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 931 Everything executed properly
lorevee 0:ac0b0725c6fa 932
lorevee 0:ac0b0725c6fa 933 @section EXAMPLE
lorevee 0:ac0b0725c6fa 934
lorevee 0:ac0b0725c6fa 935 @code
lorevee 0:ac0b0725c6fa 936
lorevee 0:ac0b0725c6fa 937 @endcode
lorevee 0:ac0b0725c6fa 938 */
lorevee 0:ac0b0725c6fa 939 /**************************************************************************/
lorevee 0:ac0b0725c6fa 940 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
lorevee 0:ac0b0725c6fa 941 {
lorevee 0:ac0b0725c6fa 942 tBleStatus ret;
lorevee 0:ac0b0725c6fa 943 uint8_t deviceAppearance[2];
lorevee 0:ac0b0725c6fa 944
lorevee 0:ac0b0725c6fa 945 STORE_LE_16(deviceAppearance, appearance);
lorevee 0:ac0b0725c6fa 946 PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
lorevee 0:ac0b0725c6fa 947
lorevee 0:ac0b0725c6fa 948 ret = aci_gatt_update_char_value(g_gap_service_handle,
lorevee 0:ac0b0725c6fa 949 g_appearance_char_handle,
lorevee 0:ac0b0725c6fa 950 0, 2, (uint8_t *)deviceAppearance);
lorevee 0:ac0b0725c6fa 951 if (BLE_STATUS_SUCCESS == ret){
lorevee 0:ac0b0725c6fa 952 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 953 }
lorevee 0:ac0b0725c6fa 954
lorevee 0:ac0b0725c6fa 955 PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret);
lorevee 0:ac0b0725c6fa 956 switch (ret) {
lorevee 0:ac0b0725c6fa 957 case BLE_STATUS_INVALID_HANDLE:
lorevee 0:ac0b0725c6fa 958 case BLE_STATUS_INVALID_PARAMETER:
lorevee 0:ac0b0725c6fa 959 return BLE_ERROR_INVALID_PARAM;
lorevee 0:ac0b0725c6fa 960 case BLE_STATUS_INSUFFICIENT_RESOURCES:
lorevee 0:ac0b0725c6fa 961 return BLE_ERROR_NO_MEM;
lorevee 0:ac0b0725c6fa 962 case BLE_STATUS_TIMEOUT:
lorevee 0:ac0b0725c6fa 963 return BLE_STACK_BUSY;
lorevee 0:ac0b0725c6fa 964 default:
lorevee 0:ac0b0725c6fa 965 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 966 }
lorevee 0:ac0b0725c6fa 967 }
lorevee 0:ac0b0725c6fa 968
lorevee 0:ac0b0725c6fa 969 /**************************************************************************/
lorevee 0:ac0b0725c6fa 970 /*!
lorevee 0:ac0b0725c6fa 971 @brief Gets the Device Appearance Characteristic
lorevee 0:ac0b0725c6fa 972
lorevee 0:ac0b0725c6fa 973 @param[in] appearance
lorevee 0:ac0b0725c6fa 974 pointer to device appearance value
lorevee 0:ac0b0725c6fa 975
lorevee 0:ac0b0725c6fa 976 @returns ble_error_t
lorevee 0:ac0b0725c6fa 977
lorevee 0:ac0b0725c6fa 978 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 979 Everything executed properly
lorevee 0:ac0b0725c6fa 980
lorevee 0:ac0b0725c6fa 981 @section EXAMPLE
lorevee 0:ac0b0725c6fa 982
lorevee 0:ac0b0725c6fa 983 @code
lorevee 0:ac0b0725c6fa 984
lorevee 0:ac0b0725c6fa 985 @endcode
lorevee 0:ac0b0725c6fa 986 */
lorevee 0:ac0b0725c6fa 987 /**************************************************************************/
lorevee 0:ac0b0725c6fa 988 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
lorevee 0:ac0b0725c6fa 989 {
lorevee 0:ac0b0725c6fa 990 tBleStatus ret;
lorevee 0:ac0b0725c6fa 991 uint16_t lengthP = 2;
lorevee 0:ac0b0725c6fa 992
lorevee 0:ac0b0725c6fa 993 ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
lorevee 0:ac0b0725c6fa 994 lengthP,
lorevee 0:ac0b0725c6fa 995 &lengthP,
lorevee 0:ac0b0725c6fa 996 (uint8_t*)appearanceP);
lorevee 0:ac0b0725c6fa 997 PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP);
lorevee 0:ac0b0725c6fa 998 if (ret == BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 999 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1000 } else {
lorevee 0:ac0b0725c6fa 1001 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 1002 }
lorevee 0:ac0b0725c6fa 1003
lorevee 0:ac0b0725c6fa 1004 }
lorevee 0:ac0b0725c6fa 1005
lorevee 0:ac0b0725c6fa 1006 GapScanningParams* BlueNRGGap::getScanningParams(void)
lorevee 0:ac0b0725c6fa 1007 {
lorevee 0:ac0b0725c6fa 1008 return &_scanningParams;
lorevee 0:ac0b0725c6fa 1009 }
lorevee 0:ac0b0725c6fa 1010
lorevee 0:ac0b0725c6fa 1011 static void makeConnection(void)
lorevee 0:ac0b0725c6fa 1012 {
lorevee 0:ac0b0725c6fa 1013 BlueNRGGap::getInstance().createConnection();
lorevee 0:ac0b0725c6fa 1014 }
lorevee 0:ac0b0725c6fa 1015
lorevee 0:ac0b0725c6fa 1016 void BlueNRGGap::Discovery_CB(Reason_t reason,
lorevee 0:ac0b0725c6fa 1017 uint8_t adv_type,
lorevee 0:ac0b0725c6fa 1018 uint8_t addr_type,
lorevee 0:ac0b0725c6fa 1019 uint8_t *addr,
lorevee 0:ac0b0725c6fa 1020 uint8_t *data_length,
lorevee 0:ac0b0725c6fa 1021 uint8_t *data,
lorevee 0:ac0b0725c6fa 1022 uint8_t *RSSI)
lorevee 0:ac0b0725c6fa 1023 {
lorevee 0:ac0b0725c6fa 1024 switch (reason) {
lorevee 0:ac0b0725c6fa 1025 case DEVICE_FOUND:
lorevee 0:ac0b0725c6fa 1026 {
lorevee 0:ac0b0725c6fa 1027 GapAdvertisingParams::AdvertisingType_t type;
lorevee 0:ac0b0725c6fa 1028 bool isScanResponse = false;
lorevee 0:ac0b0725c6fa 1029
lorevee 0:ac0b0725c6fa 1030 /*
lorevee 0:ac0b0725c6fa 1031 * Whitelisting (scan policy):
lorevee 0:ac0b0725c6fa 1032 * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
lorevee 0:ac0b0725c6fa 1033 * Private Random Address
lorevee 0:ac0b0725c6fa 1034 * => scan_results = FALSE
lorevee 0:ac0b0725c6fa 1035 * FIXME: the Security Manager should be implemented
lorevee 0:ac0b0725c6fa 1036 */
lorevee 0:ac0b0725c6fa 1037 ScanningPolicyMode_t mode = getScanningPolicyMode();
lorevee 0:ac0b0725c6fa 1038 PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type);
lorevee 0:ac0b0725c6fa 1039 if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV ||
lorevee 0:ac0b0725c6fa 1040 (addr_type == RESOLVABLE_PRIVATE_ADDR ||
lorevee 0:ac0b0725c6fa 1041 addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) {
lorevee 0:ac0b0725c6fa 1042 return;
lorevee 0:ac0b0725c6fa 1043 }
lorevee 0:ac0b0725c6fa 1044
lorevee 0:ac0b0725c6fa 1045 switch(adv_type) {
lorevee 0:ac0b0725c6fa 1046 case ADV_IND:
lorevee 0:ac0b0725c6fa 1047 type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
lorevee 0:ac0b0725c6fa 1048 break;
lorevee 0:ac0b0725c6fa 1049 case ADV_DIRECT_IND:
lorevee 0:ac0b0725c6fa 1050 type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
lorevee 0:ac0b0725c6fa 1051 break;
lorevee 0:ac0b0725c6fa 1052 case ADV_SCAN_IND:
lorevee 0:ac0b0725c6fa 1053 case SCAN_RSP:
lorevee 0:ac0b0725c6fa 1054 type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
lorevee 0:ac0b0725c6fa 1055 isScanResponse = true;
lorevee 0:ac0b0725c6fa 1056 break;
lorevee 0:ac0b0725c6fa 1057 case ADV_NONCONN_IND:
lorevee 0:ac0b0725c6fa 1058 type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
lorevee 0:ac0b0725c6fa 1059 break;
lorevee 0:ac0b0725c6fa 1060 default:
lorevee 0:ac0b0725c6fa 1061 type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
lorevee 0:ac0b0725c6fa 1062 }
lorevee 0:ac0b0725c6fa 1063
lorevee 0:ac0b0725c6fa 1064 PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
lorevee 0:ac0b0725c6fa 1065 *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
lorevee 0:ac0b0725c6fa 1066 if(!_connecting) {
lorevee 0:ac0b0725c6fa 1067 processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
lorevee 0:ac0b0725c6fa 1068 }
lorevee 0:ac0b0725c6fa 1069 PRINTF("!!!After processAdvertisementReport\n\r");
lorevee 0:ac0b0725c6fa 1070 }
lorevee 0:ac0b0725c6fa 1071 break;
lorevee 0:ac0b0725c6fa 1072
lorevee 0:ac0b0725c6fa 1073 case DISCOVERY_COMPLETE:
lorevee 0:ac0b0725c6fa 1074 // The discovery is complete. If this is due to a stop scanning (i.e., the device
lorevee 0:ac0b0725c6fa 1075 // we are interested in has been found) and a connection has been requested
lorevee 0:ac0b0725c6fa 1076 // then we start the device connection.
lorevee 0:ac0b0725c6fa 1077 PRINTF("DISCOVERY_COMPLETE\n\r");
lorevee 0:ac0b0725c6fa 1078 _scanning = false;
lorevee 0:ac0b0725c6fa 1079
lorevee 0:ac0b0725c6fa 1080 //----------------------------------------------------------------------
lorevee 0:ac0b0725c6fa 1081 //Added
lorevee 0:ac0b0725c6fa 1082 processTimeoutEvent(TIMEOUT_SRC_SCAN);
lorevee 0:ac0b0725c6fa 1083 //----------------------------------------------------------------------
lorevee 0:ac0b0725c6fa 1084
lorevee 0:ac0b0725c6fa 1085 // Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
lorevee 0:ac0b0725c6fa 1086 // we need to delay the starting of connection
lorevee 0:ac0b0725c6fa 1087 uint16_t delay = (_scanningParams.getInterval()*0.625);
lorevee 0:ac0b0725c6fa 1088
lorevee 0:ac0b0725c6fa 1089 #ifdef AST_FOR_MBED_OS
lorevee 0:ac0b0725c6fa 1090 if(_connecting) {
lorevee 0:ac0b0725c6fa 1091 minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
lorevee 0:ac0b0725c6fa 1092 }
lorevee 0:ac0b0725c6fa 1093 #else
lorevee 0:ac0b0725c6fa 1094 Clock_Wait(delay);
lorevee 0:ac0b0725c6fa 1095 if(_connecting) {
lorevee 0:ac0b0725c6fa 1096 makeConnection();
lorevee 0:ac0b0725c6fa 1097 }
lorevee 0:ac0b0725c6fa 1098 #endif /* AST_FOR_MBED_OS */
lorevee 0:ac0b0725c6fa 1099
lorevee 0:ac0b0725c6fa 1100 break;
lorevee 0:ac0b0725c6fa 1101 }
lorevee 0:ac0b0725c6fa 1102 }
lorevee 0:ac0b0725c6fa 1103
lorevee 0:ac0b0725c6fa 1104 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
lorevee 0:ac0b0725c6fa 1105 {
lorevee 0:ac0b0725c6fa 1106
lorevee 0:ac0b0725c6fa 1107 tBleStatus ret = BLE_STATUS_SUCCESS;
lorevee 0:ac0b0725c6fa 1108
lorevee 0:ac0b0725c6fa 1109 // Stop ADV before scanning
lorevee 0:ac0b0725c6fa 1110 /*
lorevee 0:ac0b0725c6fa 1111 if (state.advertising == 1) {
lorevee 0:ac0b0725c6fa 1112 stopAdvertising();
lorevee 0:ac0b0725c6fa 1113 }
lorevee 0:ac0b0725c6fa 1114 */
lorevee 0:ac0b0725c6fa 1115
lorevee 0:ac0b0725c6fa 1116 /*
lorevee 0:ac0b0725c6fa 1117 * Whitelisting (scan policy):
lorevee 0:ac0b0725c6fa 1118 * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
lorevee 0:ac0b0725c6fa 1119 * White List is empty
lorevee 0:ac0b0725c6fa 1120 * => scan operation = FAILURE
lorevee 0:ac0b0725c6fa 1121 * FIXME: the Security Manager should be implemented
lorevee 0:ac0b0725c6fa 1122 */
lorevee 0:ac0b0725c6fa 1123 ScanningPolicyMode_t mode = getScanningPolicyMode();
lorevee 0:ac0b0725c6fa 1124 uint8_t whiteListSize = whitelistAddresses.size;
lorevee 0:ac0b0725c6fa 1125 if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) {
lorevee 0:ac0b0725c6fa 1126 return BLE_ERROR_OPERATION_NOT_PERMITTED;
lorevee 0:ac0b0725c6fa 1127 }
lorevee 0:ac0b0725c6fa 1128
lorevee 0:ac0b0725c6fa 1129 ret = btleStartRadioScan(scanningParams.getActiveScanning(),
lorevee 0:ac0b0725c6fa 1130 scanningParams.getInterval(),
lorevee 0:ac0b0725c6fa 1131 scanningParams.getWindow(),
lorevee 0:ac0b0725c6fa 1132 addr_type);
lorevee 0:ac0b0725c6fa 1133
lorevee 0:ac0b0725c6fa 1134 PRINTF("Scanning...\n\r");
lorevee 0:ac0b0725c6fa 1135 PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000);
lorevee 0:ac0b0725c6fa 1136 PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000);
lorevee 0:ac0b0725c6fa 1137 //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval());
lorevee 0:ac0b0725c6fa 1138 //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1);
lorevee 0:ac0b0725c6fa 1139 //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2);
lorevee 0:ac0b0725c6fa 1140 if (BLE_STATUS_SUCCESS == ret){
lorevee 0:ac0b0725c6fa 1141 PRINTF("Observation Procedure Started\n");
lorevee 0:ac0b0725c6fa 1142 _scanning = true;
lorevee 0:ac0b0725c6fa 1143
lorevee 0:ac0b0725c6fa 1144 if(scanningParams.getTimeout() != 0) {
lorevee 0:ac0b0725c6fa 1145 PRINTF("!!! attaching scan to!!!\n");
lorevee 0:ac0b0725c6fa 1146 scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout());
lorevee 0:ac0b0725c6fa 1147 }
lorevee 0:ac0b0725c6fa 1148
lorevee 0:ac0b0725c6fa 1149 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1150 }
lorevee 0:ac0b0725c6fa 1151
lorevee 0:ac0b0725c6fa 1152 // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
lorevee 0:ac0b0725c6fa 1153 switch (ret) {
lorevee 0:ac0b0725c6fa 1154 case BLE_STATUS_INVALID_CID:
lorevee 0:ac0b0725c6fa 1155 PRINTF("Observation Procedure not implemented!!!\n\r");
lorevee 0:ac0b0725c6fa 1156 return BLE_ERROR_NOT_IMPLEMENTED;
lorevee 0:ac0b0725c6fa 1157 default:
lorevee 0:ac0b0725c6fa 1158 PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
lorevee 0:ac0b0725c6fa 1159 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 1160 }
lorevee 0:ac0b0725c6fa 1161
lorevee 0:ac0b0725c6fa 1162 }
lorevee 0:ac0b0725c6fa 1163
lorevee 0:ac0b0725c6fa 1164 ble_error_t BlueNRGGap::stopScan() {
lorevee 0:ac0b0725c6fa 1165 tBleStatus ret = BLE_STATUS_SUCCESS;
lorevee 0:ac0b0725c6fa 1166
lorevee 0:ac0b0725c6fa 1167 if(_scanning) {
lorevee 0:ac0b0725c6fa 1168 ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
lorevee 0:ac0b0725c6fa 1169
lorevee 0:ac0b0725c6fa 1170 if (ret != BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 1171 PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret);
lorevee 0:ac0b0725c6fa 1172 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 1173 } else {
lorevee 0:ac0b0725c6fa 1174 PRINTF("Discovery Procedure Terminated\n");
lorevee 0:ac0b0725c6fa 1175 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1176 }
lorevee 0:ac0b0725c6fa 1177 }
lorevee 0:ac0b0725c6fa 1178
lorevee 0:ac0b0725c6fa 1179 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1180 }
lorevee 0:ac0b0725c6fa 1181
lorevee 0:ac0b0725c6fa 1182 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1183 /*!
lorevee 0:ac0b0725c6fa 1184 @brief set Tx power level
lorevee 0:ac0b0725c6fa 1185 @param[in] txPower Transmission Power level
lorevee 0:ac0b0725c6fa 1186 @returns ble_error_t
lorevee 0:ac0b0725c6fa 1187 */
lorevee 0:ac0b0725c6fa 1188 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1189 ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
lorevee 0:ac0b0725c6fa 1190 {
lorevee 0:ac0b0725c6fa 1191 tBleStatus ret;
lorevee 0:ac0b0725c6fa 1192
lorevee 0:ac0b0725c6fa 1193 int8_t enHighPower = 0;
lorevee 0:ac0b0725c6fa 1194 int8_t paLevel = 0;
lorevee 0:ac0b0725c6fa 1195
lorevee 0:ac0b0725c6fa 1196 ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 1197 if(ret!=BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 1198 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 1199 }
lorevee 0:ac0b0725c6fa 1200
lorevee 0:ac0b0725c6fa 1201 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 1202 ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
lorevee 0:ac0b0725c6fa 1203 if(ret!=BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 1204 return BLE_ERROR_PARAM_OUT_OF_RANGE;
lorevee 0:ac0b0725c6fa 1205 }
lorevee 0:ac0b0725c6fa 1206
lorevee 0:ac0b0725c6fa 1207 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1208 }
lorevee 0:ac0b0725c6fa 1209
lorevee 0:ac0b0725c6fa 1210 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1211 /*!
lorevee 0:ac0b0725c6fa 1212 @brief get permitted Tx power values
lorevee 0:ac0b0725c6fa 1213 @param[in] values pointer to pointer to permitted power values
lorevee 0:ac0b0725c6fa 1214 @param[in] num number of values
lorevee 0:ac0b0725c6fa 1215 */
lorevee 0:ac0b0725c6fa 1216 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1217 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
lorevee 0:ac0b0725c6fa 1218 static const int8_t permittedTxValues[] = {
lorevee 0:ac0b0725c6fa 1219 -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8
lorevee 0:ac0b0725c6fa 1220 };
lorevee 0:ac0b0725c6fa 1221
lorevee 0:ac0b0725c6fa 1222 *valueArrayPP = permittedTxValues;
lorevee 0:ac0b0725c6fa 1223 *countP = sizeof(permittedTxValues) / sizeof(int8_t);
lorevee 0:ac0b0725c6fa 1224 }
lorevee 0:ac0b0725c6fa 1225
lorevee 0:ac0b0725c6fa 1226 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1227 /*!
lorevee 0:ac0b0725c6fa 1228 @brief Set advertising parameters according to the current state
lorevee 0:ac0b0725c6fa 1229 Parameters value is set taking into account guidelines of the BlueNRG
lorevee 0:ac0b0725c6fa 1230 time slots allocation
lorevee 0:ac0b0725c6fa 1231 */
lorevee 0:ac0b0725c6fa 1232 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1233 void BlueNRGGap::setAdvParameters(void)
lorevee 0:ac0b0725c6fa 1234 {
lorevee 0:ac0b0725c6fa 1235 uint32_t advIntMS;
lorevee 0:ac0b0725c6fa 1236
lorevee 0:ac0b0725c6fa 1237 if(state.connected == 1) {
lorevee 0:ac0b0725c6fa 1238 advIntMS = (conn_min_interval*1.25)-GUARD_INT;
lorevee 0:ac0b0725c6fa 1239 advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
lorevee 0:ac0b0725c6fa 1240
lorevee 0:ac0b0725c6fa 1241 PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval);
lorevee 0:ac0b0725c6fa 1242 } else {
lorevee 0:ac0b0725c6fa 1243 advInterval = _advParams.getIntervalInADVUnits();
lorevee 0:ac0b0725c6fa 1244 }
lorevee 0:ac0b0725c6fa 1245 }
lorevee 0:ac0b0725c6fa 1246
lorevee 0:ac0b0725c6fa 1247 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1248 /*!
lorevee 0:ac0b0725c6fa 1249 @brief Set connection parameters according to the current state (ADV and/or SCAN)
lorevee 0:ac0b0725c6fa 1250 Parameters value is set taking into account guidelines of the BlueNRG
lorevee 0:ac0b0725c6fa 1251 time slots allocation
lorevee 0:ac0b0725c6fa 1252 */
lorevee 0:ac0b0725c6fa 1253 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1254 void BlueNRGGap::setConnectionParameters(void)
lorevee 0:ac0b0725c6fa 1255 {
lorevee 0:ac0b0725c6fa 1256 if (state.connected == 1) {
lorevee 0:ac0b0725c6fa 1257
lorevee 0:ac0b0725c6fa 1258 PRINTF("state.connected=1\r\n");
lorevee 0:ac0b0725c6fa 1259 scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25);
lorevee 0:ac0b0725c6fa 1260 scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt)
lorevee 0:ac0b0725c6fa 1261
lorevee 0:ac0b0725c6fa 1262 } else if (state.advertising == 1) {
lorevee 0:ac0b0725c6fa 1263
lorevee 0:ac0b0725c6fa 1264 if (_scanningParams.getInterval() < advInterval) {
lorevee 0:ac0b0725c6fa 1265 PRINTF("state.adv=1 scanInterval<advInterval\r\n");
lorevee 0:ac0b0725c6fa 1266 scanInterval = advInterval;
lorevee 0:ac0b0725c6fa 1267 scanWindow = advInterval;
lorevee 0:ac0b0725c6fa 1268 } else {
lorevee 0:ac0b0725c6fa 1269 PRINTF("state.adv=1 scanInterval>=advInterval\r\n");
lorevee 0:ac0b0725c6fa 1270 scanInterval = _scanningParams.getInterval();
lorevee 0:ac0b0725c6fa 1271 scanWindow = _scanningParams.getWindow();
lorevee 0:ac0b0725c6fa 1272 }
lorevee 0:ac0b0725c6fa 1273
lorevee 0:ac0b0725c6fa 1274 if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms
lorevee 0:ac0b0725c6fa 1275 conn_min_interval = MAX_INT_CONN;
lorevee 0:ac0b0725c6fa 1276 conn_max_interval = MAX_INT_CONN;
lorevee 0:ac0b0725c6fa 1277 } else {
lorevee 0:ac0b0725c6fa 1278 conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
lorevee 0:ac0b0725c6fa 1279 conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
lorevee 0:ac0b0725c6fa 1280 }
lorevee 0:ac0b0725c6fa 1281
lorevee 0:ac0b0725c6fa 1282 } else {
lorevee 0:ac0b0725c6fa 1283
lorevee 0:ac0b0725c6fa 1284 PRINTF("state.adv = 0\r\n");
lorevee 0:ac0b0725c6fa 1285
lorevee 0:ac0b0725c6fa 1286 scanInterval = _scanningParams.getInterval();
lorevee 0:ac0b0725c6fa 1287 scanWindow = _scanningParams.getWindow();
lorevee 0:ac0b0725c6fa 1288 if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) ||
lorevee 0:ac0b0725c6fa 1289 SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms
lorevee 0:ac0b0725c6fa 1290 conn_min_interval = DEF_INT_CONN;
lorevee 0:ac0b0725c6fa 1291 conn_max_interval = DEF_INT_CONN;
lorevee 0:ac0b0725c6fa 1292 } else {
lorevee 0:ac0b0725c6fa 1293 conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
lorevee 0:ac0b0725c6fa 1294 conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
lorevee 0:ac0b0725c6fa 1295 }
lorevee 0:ac0b0725c6fa 1296 }
lorevee 0:ac0b0725c6fa 1297 PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval));
lorevee 0:ac0b0725c6fa 1298 PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow));
lorevee 0:ac0b0725c6fa 1299 PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25));
lorevee 0:ac0b0725c6fa 1300 PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25));
lorevee 0:ac0b0725c6fa 1301
lorevee 0:ac0b0725c6fa 1302 }
lorevee 0:ac0b0725c6fa 1303
lorevee 0:ac0b0725c6fa 1304 ble_error_t BlueNRGGap::createConnection ()
lorevee 0:ac0b0725c6fa 1305 {
lorevee 0:ac0b0725c6fa 1306 tBleStatus ret;
lorevee 0:ac0b0725c6fa 1307
lorevee 0:ac0b0725c6fa 1308 /*
lorevee 0:ac0b0725c6fa 1309 Before creating connection, set parameters according
lorevee 0:ac0b0725c6fa 1310 to previous or current procedure (ADV and/or SCAN)
lorevee 0:ac0b0725c6fa 1311 */
lorevee 0:ac0b0725c6fa 1312 setConnectionParameters();
lorevee 0:ac0b0725c6fa 1313
lorevee 0:ac0b0725c6fa 1314 /*
lorevee 0:ac0b0725c6fa 1315 Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min,
lorevee 0:ac0b0725c6fa 1316 Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max
lorevee 0:ac0b0725c6fa 1317 */
lorevee 0:ac0b0725c6fa 1318 ret = aci_gap_create_connection(scanInterval,
lorevee 0:ac0b0725c6fa 1319 scanWindow,
lorevee 0:ac0b0725c6fa 1320 _peerAddrType,
lorevee 0:ac0b0725c6fa 1321 (unsigned char*)_peerAddr,
lorevee 0:ac0b0725c6fa 1322 addr_type,
lorevee 0:ac0b0725c6fa 1323 conn_min_interval, conn_max_interval, 0,
lorevee 0:ac0b0725c6fa 1324 SUPERV_TIMEOUT, CONN_L1, CONN_L1);
lorevee 0:ac0b0725c6fa 1325
lorevee 0:ac0b0725c6fa 1326 //_connecting = false;
lorevee 0:ac0b0725c6fa 1327
lorevee 0:ac0b0725c6fa 1328 if (ret != BLE_STATUS_SUCCESS) {
lorevee 0:ac0b0725c6fa 1329 PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
lorevee 0:ac0b0725c6fa 1330 return BLE_ERROR_UNSPECIFIED;
lorevee 0:ac0b0725c6fa 1331 } else {
lorevee 0:ac0b0725c6fa 1332 PRINTF("Connection started.\n");
lorevee 0:ac0b0725c6fa 1333 _connecting = false;
lorevee 0:ac0b0725c6fa 1334 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1335 }
lorevee 0:ac0b0725c6fa 1336 }
lorevee 0:ac0b0725c6fa 1337
lorevee 0:ac0b0725c6fa 1338 ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
lorevee 0:ac0b0725c6fa 1339 Gap::AddressType_t peerAddrType,
lorevee 0:ac0b0725c6fa 1340 const ConnectionParams_t *connectionParams,
lorevee 0:ac0b0725c6fa 1341 const GapScanningParams *scanParams)
lorevee 0:ac0b0725c6fa 1342 {
lorevee 0:ac0b0725c6fa 1343 /* avoid compiler warnings about unused variables */
lorevee 0:ac0b0725c6fa 1344 (void)connectionParams;
lorevee 0:ac0b0725c6fa 1345
lorevee 0:ac0b0725c6fa 1346 setScanParams(scanParams->getInterval(),
lorevee 0:ac0b0725c6fa 1347 scanParams->getWindow(),
lorevee 0:ac0b0725c6fa 1348 scanParams->getTimeout(),
lorevee 0:ac0b0725c6fa 1349 scanParams->getActiveScanning()
lorevee 0:ac0b0725c6fa 1350 );
lorevee 0:ac0b0725c6fa 1351
lorevee 0:ac0b0725c6fa 1352 // Save the peer address
lorevee 0:ac0b0725c6fa 1353 for(int i=0; i<BDADDR_SIZE; i++) {
lorevee 0:ac0b0725c6fa 1354 _peerAddr[i] = peerAddr[i];
lorevee 0:ac0b0725c6fa 1355 }
lorevee 0:ac0b0725c6fa 1356 _peerAddrType = peerAddrType;
lorevee 0:ac0b0725c6fa 1357
lorevee 0:ac0b0725c6fa 1358 _connecting = true;
lorevee 0:ac0b0725c6fa 1359
lorevee 0:ac0b0725c6fa 1360 if(_scanning) {
lorevee 0:ac0b0725c6fa 1361 stopScan();
lorevee 0:ac0b0725c6fa 1362 } else {
lorevee 0:ac0b0725c6fa 1363 PRINTF("Calling createConnection from connect()\n\r");
lorevee 0:ac0b0725c6fa 1364 return createConnection();
lorevee 0:ac0b0725c6fa 1365 }
lorevee 0:ac0b0725c6fa 1366
lorevee 0:ac0b0725c6fa 1367 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1368 }
lorevee 0:ac0b0725c6fa 1369
lorevee 0:ac0b0725c6fa 1370 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1371 /*!
lorevee 0:ac0b0725c6fa 1372 @brief Set the advertising policy filter mode that will be used in
lorevee 0:ac0b0725c6fa 1373 the next call to startAdvertising().
lorevee 0:ac0b0725c6fa 1374
lorevee 0:ac0b0725c6fa 1375 @returns \ref ble_errror_t
lorevee 0:ac0b0725c6fa 1376
lorevee 0:ac0b0725c6fa 1377 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 1378 Everything executed properly.
lorevee 0:ac0b0725c6fa 1379
lorevee 0:ac0b0725c6fa 1380 BLE_ERROR_NOT_IMPLEMENTED
lorevee 0:ac0b0725c6fa 1381 This feature is currently note implemented.
lorevee 0:ac0b0725c6fa 1382 */
lorevee 0:ac0b0725c6fa 1383 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1384 ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
lorevee 0:ac0b0725c6fa 1385 {
lorevee 0:ac0b0725c6fa 1386 advertisingPolicyMode = mode;
lorevee 0:ac0b0725c6fa 1387
lorevee 0:ac0b0725c6fa 1388 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1389 }
lorevee 0:ac0b0725c6fa 1390
lorevee 0:ac0b0725c6fa 1391 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1392 /*!
lorevee 0:ac0b0725c6fa 1393 @brief Set the scanning policy filter mode that will be used in
lorevee 0:ac0b0725c6fa 1394 the next call to startAdvertising().
lorevee 0:ac0b0725c6fa 1395
lorevee 0:ac0b0725c6fa 1396 @returns \ref ble_errror_t
lorevee 0:ac0b0725c6fa 1397
lorevee 0:ac0b0725c6fa 1398 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 1399 Everything executed properly.
lorevee 0:ac0b0725c6fa 1400
lorevee 0:ac0b0725c6fa 1401 BLE_ERROR_NOT_IMPLEMENTED
lorevee 0:ac0b0725c6fa 1402 This feature is currently note implemented.
lorevee 0:ac0b0725c6fa 1403 */
lorevee 0:ac0b0725c6fa 1404 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1405 ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
lorevee 0:ac0b0725c6fa 1406 {
lorevee 0:ac0b0725c6fa 1407 scanningPolicyMode = mode;
lorevee 0:ac0b0725c6fa 1408
lorevee 0:ac0b0725c6fa 1409 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1410 }
lorevee 0:ac0b0725c6fa 1411
lorevee 0:ac0b0725c6fa 1412 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1413 /*!
lorevee 0:ac0b0725c6fa 1414 @brief Get the current advertising policy filter mode.
lorevee 0:ac0b0725c6fa 1415
lorevee 0:ac0b0725c6fa 1416 @returns The advertising policy filter mode.
lorevee 0:ac0b0725c6fa 1417 */
lorevee 0:ac0b0725c6fa 1418 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1419 Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const
lorevee 0:ac0b0725c6fa 1420 {
lorevee 0:ac0b0725c6fa 1421 return advertisingPolicyMode;
lorevee 0:ac0b0725c6fa 1422 }
lorevee 0:ac0b0725c6fa 1423
lorevee 0:ac0b0725c6fa 1424 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1425 /*!
lorevee 0:ac0b0725c6fa 1426 @brief Get the current scanning policy filter mode.
lorevee 0:ac0b0725c6fa 1427
lorevee 0:ac0b0725c6fa 1428 @returns The scanning policy filter mode.
lorevee 0:ac0b0725c6fa 1429
lorevee 0:ac0b0725c6fa 1430 */
lorevee 0:ac0b0725c6fa 1431 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1432 Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const
lorevee 0:ac0b0725c6fa 1433 {
lorevee 0:ac0b0725c6fa 1434 return scanningPolicyMode;
lorevee 0:ac0b0725c6fa 1435 }
lorevee 0:ac0b0725c6fa 1436
lorevee 0:ac0b0725c6fa 1437 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1438 /*!
lorevee 0:ac0b0725c6fa 1439 @brief Clear BlueNRGGap's state.
lorevee 0:ac0b0725c6fa 1440
lorevee 0:ac0b0725c6fa 1441 @returns ble_error_t
lorevee 0:ac0b0725c6fa 1442
lorevee 0:ac0b0725c6fa 1443 @retval BLE_ERROR_NONE
lorevee 0:ac0b0725c6fa 1444 Everything executed properly
lorevee 0:ac0b0725c6fa 1445 */
lorevee 0:ac0b0725c6fa 1446 /**************************************************************************/
lorevee 0:ac0b0725c6fa 1447 ble_error_t BlueNRGGap::reset(void)
lorevee 0:ac0b0725c6fa 1448 {
lorevee 0:ac0b0725c6fa 1449 PRINTF("BlueNRGGap::reset\n");
lorevee 0:ac0b0725c6fa 1450
lorevee 0:ac0b0725c6fa 1451 /* Clear all state that is from the parent, including private members */
lorevee 0:ac0b0725c6fa 1452 if (Gap::reset() != BLE_ERROR_NONE) {
lorevee 0:ac0b0725c6fa 1453 return BLE_ERROR_INVALID_STATE;
lorevee 0:ac0b0725c6fa 1454 }
lorevee 0:ac0b0725c6fa 1455
lorevee 0:ac0b0725c6fa 1456 AdvToFlag = false;
lorevee 0:ac0b0725c6fa 1457 ScanToFlag = false;
lorevee 0:ac0b0725c6fa 1458
lorevee 0:ac0b0725c6fa 1459 /* Clear derived class members */
lorevee 0:ac0b0725c6fa 1460 m_connectionHandle = BLE_CONN_HANDLE_INVALID;
lorevee 0:ac0b0725c6fa 1461
lorevee 0:ac0b0725c6fa 1462 /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
lorevee 0:ac0b0725c6fa 1463 advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
lorevee 0:ac0b0725c6fa 1464 scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST;
lorevee 0:ac0b0725c6fa 1465
lorevee 0:ac0b0725c6fa 1466 return BLE_ERROR_NONE;
lorevee 0:ac0b0725c6fa 1467 }
lorevee 0:ac0b0725c6fa 1468
lorevee 0:ac0b0725c6fa 1469 void BlueNRGGap::setConnectionInterval(uint16_t interval) {
lorevee 0:ac0b0725c6fa 1470 conn_min_interval = interval;
lorevee 0:ac0b0725c6fa 1471 conn_max_interval = interval;
lorevee 0:ac0b0725c6fa 1472 }
lorevee 0:ac0b0725c6fa 1473
lorevee 0:ac0b0725c6fa 1474 Gap::Role_t BlueNRGGap::getGapRole(void)
lorevee 0:ac0b0725c6fa 1475 {
lorevee 0:ac0b0725c6fa 1476 return (gapRole);
lorevee 0:ac0b0725c6fa 1477 }
lorevee 0:ac0b0725c6fa 1478
lorevee 0:ac0b0725c6fa 1479 void BlueNRGGap::setGapRole(Gap::Role_t role)
lorevee 0:ac0b0725c6fa 1480 {
lorevee 0:ac0b0725c6fa 1481 gapRole = role;
lorevee 0:ac0b0725c6fa 1482 }
lorevee 0:ac0b0725c6fa 1483