Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
Gap.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __GAP_H__ 00018 #define __GAP_H__ 00019 00020 #include "GapAdvertisingData.h" 00021 #include "GapAdvertisingParams.h" 00022 #include "GapScanningParams.h" 00023 #include "GapEvents.h" 00024 #include "CallChainOfFunctionPointersWithContext.h" 00025 #include "FunctionPointerWithContext.h" 00026 00027 /* Forward declarations for classes which will only be used for pointers or references in the following. */ 00028 class GapAdvertisingParams; 00029 class GapScanningParams; 00030 class GapAdvertisingData; 00031 00032 class Gap { 00033 public: 00034 enum AddressType_t { 00035 ADDR_TYPE_PUBLIC = 0, 00036 ADDR_TYPE_RANDOM_STATIC, 00037 ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, 00038 ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 00039 }; 00040 typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */ 00041 00042 static const unsigned ADDR_LEN = 6; 00043 typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ 00044 typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */ 00045 00046 enum TimeoutSource_t { 00047 TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */ 00048 TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */ 00049 TIMEOUT_SRC_SCAN = 0x02, /**< Scanning timeout. */ 00050 TIMEOUT_SRC_CONN = 0x03, /**< Connection timeout. */ 00051 }; 00052 00053 /** 00054 * Enumeration for disconnection reasons. The values for these reasons are 00055 * derived from Nordic's implementation; but the reasons are meant to be 00056 * independent of the transport. If you are returned a reason which is not 00057 * covered by this enumeration, then please refer to the underlying 00058 * transport library. 00059 */ 00060 enum DisconnectionReason_t { 00061 CONNECTION_TIMEOUT = 0x08, 00062 REMOTE_USER_TERMINATED_CONNECTION = 0x13, 00063 REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to low resources.*/ 00064 REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to power off. */ 00065 LOCAL_HOST_TERMINATED_CONNECTION = 0x16, 00066 CONN_INTERVAL_UNACCEPTABLE = 0x3B, 00067 }; 00068 00069 /* Describes the current state of the device (more than one bit can be set) */ 00070 struct GapState_t { 00071 unsigned advertising : 1; /**< peripheral is currently advertising */ 00072 unsigned connected : 1; /**< peripheral is connected to a central */ 00073 }; 00074 00075 typedef uint16_t Handle_t; /* Type for connection handle. */ 00076 00077 typedef struct { 00078 uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ 00079 uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ 00080 uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ 00081 uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ 00082 } ConnectionParams_t; 00083 00084 enum Role_t { 00085 PERIPHERAL = 0x1, /**< Peripheral Role. */ 00086 CENTRAL = 0x2, /**< Central Role. */ 00087 }; 00088 00089 struct AdvertisementCallbackParams_t { 00090 Address_t peerAddr; 00091 int8_t rssi; 00092 bool isScanResponse; 00093 GapAdvertisingParams::AdvertisingType_t type; 00094 uint8_t advertisingDataLen; 00095 const uint8_t *advertisingData; 00096 }; 00097 typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; 00098 00099 struct ConnectionCallbackParams_t { 00100 Handle_t handle; 00101 Role_t role; 00102 AddressType_t peerAddrType; 00103 Address_t peerAddr; 00104 AddressType_t ownAddrType; 00105 Address_t ownAddr; 00106 const ConnectionParams_t *connectionParams; 00107 00108 ConnectionCallbackParams_t(Handle_t handleIn, 00109 Role_t roleIn, 00110 AddressType_t peerAddrTypeIn, 00111 const uint8_t *peerAddrIn, 00112 AddressType_t ownAddrTypeIn, 00113 const uint8_t *ownAddrIn, 00114 const ConnectionParams_t *connectionParamsIn) : 00115 handle(handleIn), 00116 role(roleIn), 00117 peerAddrType(peerAddrTypeIn), 00118 peerAddr(), 00119 ownAddrType(ownAddrTypeIn), 00120 ownAddr(), 00121 connectionParams(connectionParamsIn) { 00122 memcpy(peerAddr, peerAddrIn, ADDR_LEN); 00123 memcpy(ownAddr, ownAddrIn, ADDR_LEN); 00124 } 00125 }; 00126 00127 struct DisconnectionCallbackParams_t { 00128 Handle_t handle; 00129 DisconnectionReason_t reason; 00130 00131 DisconnectionCallbackParams_t(Handle_t handleIn, 00132 DisconnectionReason_t reasonIn) : 00133 handle(handleIn), 00134 reason(reasonIn) 00135 {} 00136 }; 00137 00138 static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ 00139 static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { 00140 return (durationInMillis * 1000) / UNIT_1_25_MS; 00141 } 00142 00143 00144 typedef void (*TimeoutEventCallback_t)(TimeoutSource_t source); 00145 typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params); 00146 typedef void (*DisconnectionEventCallback_t)(const DisconnectionCallbackParams_t *params); 00147 typedef FunctionPointerWithContext<bool> RadioNotificationEventCallback_t; 00148 00149 /* 00150 * The following functions are meant to be overridden in the platform-specific sub-class. 00151 */ 00152 public: 00153 /** 00154 * Set the BTLE MAC address and type. Please note that the address format is 00155 * LSB (least significant byte first). Please refer to Address_t. 00156 * 00157 * @return BLE_ERROR_NONE on success. 00158 */ 00159 virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { 00160 /* avoid compiler warnings about unused variables */ 00161 (void)type; 00162 (void)address; 00163 00164 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00165 } 00166 00167 /** 00168 * Fetch the BTLE MAC address and type. 00169 * 00170 * @return BLE_ERROR_NONE on success. 00171 */ 00172 virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { 00173 /* avoid compiler warnings about unused variables */ 00174 (void)typeP; 00175 (void)address; 00176 00177 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00178 } 00179 00180 /** 00181 * @return Minimum Advertising interval in milliseconds. 00182 */ 00183 virtual uint16_t getMinAdvertisingInterval(void) const { 00184 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00185 } 00186 00187 /** 00188 * @return Minimum Advertising interval in milliseconds for non-connectible mode. 00189 */ 00190 virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const { 00191 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00192 } 00193 00194 /** 00195 * @return Maximum Advertising interval in milliseconds. 00196 */ 00197 virtual uint16_t getMaxAdvertisingInterval(void) const { 00198 return 0xFFFF; /* Requesting action from porter(s): override this API if this capability is supported. */ 00199 } 00200 00201 virtual ble_error_t stopAdvertising(void) { 00202 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00203 } 00204 00205 /** 00206 * Stop scanning. The current scanning parameters remain in effect. 00207 * 00208 * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. 00209 */ 00210 virtual ble_error_t stopScan() { 00211 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00212 } 00213 00214 /** 00215 * Create a connection (GAP Link Establishment). 00216 * 00217 * @param peerAddr 00218 * 48-bit address, LSB format. 00219 * @param peerAddrType 00220 * Address type of the peer. 00221 * @param connectionParams 00222 * Connection parameters. 00223 * @param scanParams 00224 * Paramters to be used while scanning for the peer. 00225 * @return BLE_ERROR_NONE if connection establishment procedure is started 00226 * successfully. The connectionCallChain (if set) will be invoked upon 00227 * a connection event. 00228 */ 00229 virtual ble_error_t connect(const Address_t peerAddr, 00230 Gap::AddressType_t peerAddrType, 00231 const ConnectionParams_t *connectionParams, 00232 const GapScanningParams *scanParams) { 00233 /* avoid compiler warnings about unused variables */ 00234 (void)peerAddr; 00235 (void)peerAddrType; 00236 (void)connectionParams; 00237 (void)scanParams; 00238 00239 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00240 } 00241 00242 /** 00243 * This call initiates the disconnection procedure, and its completion will 00244 * be communicated to the application with an invocation of the 00245 * disconnectionCallback. 00246 * 00247 * @param reason 00248 * The reason for disconnection to be sent back to the peer. 00249 */ 00250 virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) { 00251 /* avoid compiler warnings about unused variables */ 00252 (void)connectionHandle; 00253 (void)reason; 00254 00255 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00256 } 00257 00258 /** 00259 * This call initiates the disconnection procedure, and its completion will 00260 * be communicated to the application with an invocation of the 00261 * disconnectionCallback. 00262 * 00263 * @param reason 00264 * The reason for disconnection to be sent back to the peer. 00265 * 00266 * @note: this version of disconnect() doesn't take a connection handle. It 00267 * will work reliably only for stacks which are limited to a single 00268 * connection. This API should be considered *deprecated* in favour of the 00269 * altertive which takes a connection handle. It will be dropped in the future. 00270 */ 00271 virtual ble_error_t disconnect(DisconnectionReason_t reason) { 00272 /* avoid compiler warnings about unused variables */ 00273 (void)reason; 00274 00275 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00276 } 00277 00278 /** 00279 * Get the GAP peripheral preferred connection parameters. These are the 00280 * defaults that the peripheral would like to have in a connection. The 00281 * choice of the connection parameters is eventually up to the central. 00282 * 00283 * @param[out] params 00284 * The structure where the parameters will be stored. Memory 00285 * for this is owned by the caller. 00286 * 00287 * @return BLE_ERROR_NONE if the parameters were successfully filled into 00288 * the given structure pointed to by params. 00289 */ 00290 virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) { 00291 /* avoid compiler warnings about unused variables */ 00292 (void)params; 00293 00294 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00295 } 00296 00297 /** 00298 * Set the GAP peripheral preferred connection parameters. These are the 00299 * defaults that the peripheral would like to have in a connection. The 00300 * choice of the connection parameters is eventually up to the central. 00301 * 00302 * @param[in] params 00303 * The structure containing the desired parameters. 00304 */ 00305 virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) { 00306 /* avoid compiler warnings about unused variables */ 00307 (void)params; 00308 00309 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00310 } 00311 00312 /** 00313 * Update connection parameters. 00314 * In the central role this will initiate a Link Layer connection parameter update procedure, 00315 * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for 00316 * the central to perform the procedure. 00317 * 00318 * @param[in] handle 00319 * Connection Handle 00320 * @param[in] params 00321 * Pointer to desired connection parameters. If NULL is provided on a peripheral role, 00322 * the parameters in the PPCP characteristic of the GAP service will be used instead. 00323 */ 00324 virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) { 00325 /* avoid compiler warnings about unused variables */ 00326 (void)handle; 00327 (void)params; 00328 00329 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00330 } 00331 00332 /** 00333 * Set the device name characteristic in the GAP service. 00334 * @param[in] deviceName 00335 * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. 00336 */ 00337 virtual ble_error_t setDeviceName(const uint8_t *deviceName) { 00338 /* avoid compiler warnings about unused variables */ 00339 (void)deviceName; 00340 00341 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00342 } 00343 00344 /** 00345 * Get the value of the device name characteristic in the GAP service. 00346 * @param[out] deviceName 00347 * Pointer to an empty buffer where the UTF-8 *non NULL- 00348 * terminated* string will be placed. Set this 00349 * value to NULL in order to obtain the deviceName-length 00350 * from the 'length' parameter. 00351 * 00352 * @param[in/out] lengthP 00353 * (on input) Length of the buffer pointed to by deviceName; 00354 * (on output) the complete device name length (without the 00355 * null terminator). 00356 * 00357 * @note If the device name is longer than the size of the supplied buffer, 00358 * length will return the complete device name length, and not the 00359 * number of bytes actually returned in deviceName. The application may 00360 * use this information to retry with a suitable buffer size. 00361 */ 00362 virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { 00363 /* avoid compiler warnings about unused variables */ 00364 (void)deviceName; 00365 (void)lengthP; 00366 00367 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00368 } 00369 00370 /** 00371 * Set the appearance characteristic in the GAP service. 00372 * @param[in] appearance 00373 * The new value for the device-appearance. 00374 */ 00375 virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { 00376 /* avoid compiler warnings about unused variables */ 00377 (void)appearance; 00378 00379 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00380 } 00381 00382 /** 00383 * Get the appearance characteristic in the GAP service. 00384 * @param[out] appearance 00385 * The new value for the device-appearance. 00386 */ 00387 virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { 00388 /* avoid compiler warnings about unused variables */ 00389 (void)appearanceP; 00390 00391 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00392 } 00393 00394 /** 00395 * Set the radio's transmit power. 00396 * @param[in] txPower Radio transmit power in dBm. 00397 */ 00398 virtual ble_error_t setTxPower(int8_t txPower) { 00399 /* avoid compiler warnings about unused variables */ 00400 (void)txPower; 00401 00402 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00403 } 00404 00405 /** 00406 * Query the underlying stack for permitted arguments for setTxPower(). 00407 * 00408 * @param[out] valueArrayPP 00409 * Out parameter to receive the immutable array of Tx values. 00410 * @param[out] countP 00411 * Out parameter to receive the array's size. 00412 */ 00413 virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { 00414 /* avoid compiler warnings about unused variables */ 00415 (void)valueArrayPP; 00416 (void)countP; 00417 00418 *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00419 } 00420 00421 protected: 00422 /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */ 00423 virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { 00424 (void)scanningParams; 00425 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00426 } 00427 00428 /* 00429 * APIs with non-virtual implementations. 00430 */ 00431 public: 00432 /** 00433 * Returns the current GAP state of the device using a bitmask which 00434 * describes whether the device is advertising and/or connected. 00435 */ 00436 GapState_t getState(void) const { 00437 return state; 00438 } 00439 00440 /** 00441 * Set the GAP advertising mode to use for this device. 00442 */ 00443 void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { 00444 _advParams.setAdvertisingType(advType); 00445 } 00446 00447 /** 00448 * @param[in] interval 00449 * Advertising interval in units of milliseconds. Advertising 00450 * is disabled if interval is 0. If interval is smaller than 00451 * the minimum supported value, then the minimum supported 00452 * value is used instead. This minimum value can be discovered 00453 * using getMinAdvertisingInterval(). 00454 * 00455 * This field must be set to 0 if connectionMode is equal 00456 * to ADV_CONNECTABLE_DIRECTED. 00457 * 00458 * @note: Decreasing this value will allow central devices to detect a 00459 * peripheral faster at the expense of more power being used by the radio 00460 * due to the higher data transmit rate. 00461 * 00462 * @note: This API is now *deprecated* and will be dropped in the future. 00463 * You should use the parallel API from Gap directly. A former call to 00464 * ble.setAdvertisingInterval(...) should now be achieved using 00465 * ble.gap().setAdvertisingInterval(...). 00466 * 00467 * @Note: [WARNING] This API previously used 0.625ms as the unit for its 00468 * 'interval' argument. That required an explicit conversion from 00469 * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is 00470 * no longer required as the new units are milliseconds. Any application 00471 * code depending on the old semantics would need to be updated accordingly. 00472 */ 00473 void setAdvertisingInterval(uint16_t interval) { 00474 if (interval == 0) { 00475 stopAdvertising(); 00476 } else if (interval < getMinAdvertisingInterval()) { 00477 interval = getMinAdvertisingInterval(); 00478 } 00479 _advParams.setInterval(interval); 00480 } 00481 00482 /** 00483 * @param[in] timeout 00484 * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 00485 * and 16383). Use 0 to disable the advertising timeout. 00486 */ 00487 void setAdvertisingTimeout(uint16_t timeout) { 00488 _advParams.setTimeout(timeout); 00489 } 00490 00491 /** 00492 * Start advertising. 00493 */ 00494 ble_error_t startAdvertising(void) { 00495 setAdvertisingData(); /* update the underlying stack */ 00496 return startAdvertising(_advParams); 00497 } 00498 00499 /** 00500 * Reset any advertising payload prepared from prior calls to 00501 * accumulateAdvertisingPayload(). This automatically propagates the re- 00502 * initialized adv payload to the underlying stack. 00503 * 00504 * Note: This should be followed by a call to setAdvertisingPayload() or 00505 * startAdvertising() before the update takes effect. 00506 */ 00507 void clearAdvertisingPayload(void) { 00508 _advPayload.clear(); 00509 setAdvertisingData(); 00510 } 00511 00512 /** 00513 * Accumulate an AD structure in the advertising payload. Please note that 00514 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00515 * as an additional 31 bytes if the advertising payload proves to be too 00516 * small. 00517 * 00518 * @param[in] flags 00519 * The flags to be added. Please refer to 00520 * GapAdvertisingData::Flags for valid flags. Multiple 00521 * flags may be specified in combination. 00522 */ 00523 ble_error_t accumulateAdvertisingPayload(uint8_t flags) { 00524 ble_error_t rc; 00525 if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) { 00526 return rc; 00527 } 00528 00529 return setAdvertisingData(); 00530 } 00531 00532 /** 00533 * Accumulate an AD structure in the advertising payload. Please note that 00534 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00535 * as an additional 31 bytes if the advertising payload proves to be too 00536 * small. 00537 * 00538 * @param app 00539 * The appearance of the peripheral. 00540 */ 00541 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { 00542 setAppearance(app); 00543 00544 ble_error_t rc; 00545 if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) { 00546 return rc; 00547 } 00548 00549 return setAdvertisingData(); 00550 } 00551 00552 /** 00553 * Accumulate an AD structure in the advertising payload. Please note that 00554 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00555 * as an additional 31 bytes if the advertising payload proves to be too 00556 * small. 00557 * 00558 * @param app 00559 * The max transmit power to be used by the controller (in dBm). 00560 * This is only a hint. 00561 */ 00562 ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { 00563 ble_error_t rc; 00564 if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) { 00565 return rc; 00566 } 00567 00568 return setAdvertisingData(); 00569 } 00570 00571 /** 00572 * Accumulate a variable length byte-stream as an AD structure in the 00573 * advertising payload. Please note that the payload is limited to 31 bytes. 00574 * The SCAN_RESPONSE message may be used as an additional 31 bytes if the 00575 * advertising payload proves to be too small. 00576 * 00577 * @param type The type which describes the variable length data. 00578 * @param data data bytes. 00579 * @param len length of data. 00580 */ 00581 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00582 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00583 setDeviceName(data); 00584 } 00585 00586 ble_error_t rc; 00587 if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) { 00588 return rc; 00589 } 00590 00591 return setAdvertisingData(); 00592 } 00593 00594 /** 00595 * Update a particular ADV field in the advertising payload (based on 00596 * matching type and length). Note: the length of the new data must be the 00597 * same as the old one. 00598 * 00599 * @param[in] type The ADV type field which describes the variable length data. 00600 * @param[in] data data bytes. 00601 * @param[in] len length of data. 00602 * 00603 * @note: If advertisements are enabled, then the update will take effect immediately. 00604 * 00605 * @return BLE_ERROR_NONE if the advertisement payload was updated based on 00606 * a <type, len> match; else an appropriate error. 00607 */ 00608 ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00609 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00610 setDeviceName(data); 00611 } 00612 00613 ble_error_t rc; 00614 if ((rc = _advPayload.updateData(type, data, len)) != BLE_ERROR_NONE) { 00615 return rc; 00616 } 00617 00618 return setAdvertisingData(); 00619 } 00620 00621 /** 00622 * Setup a particular, user-constructed advertisement payload for the 00623 * underlying stack. It would be uncommon for this API to be used directly; 00624 * there are other APIs to build an advertisement payload (see above). 00625 */ 00626 ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) { 00627 _advPayload = payload; 00628 return setAdvertisingData(); 00629 } 00630 00631 /** 00632 * @return Read back advertising data. Useful for storing and 00633 * restoring payload. 00634 */ 00635 const GapAdvertisingData &getAdvertisingPayload(void) const { 00636 return _advPayload; 00637 } 00638 00639 /** 00640 * Accumulate a variable length byte-stream as an AD structure in the 00641 * scanResponse payload. 00642 * 00643 * @param[in] type The type which describes the variable length data. 00644 * @param[in] data data bytes. 00645 * @param[in] len length of data. 00646 */ 00647 ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00648 ble_error_t rc; 00649 if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) { 00650 return rc; 00651 } 00652 00653 return setAdvertisingData(); 00654 } 00655 00656 /** 00657 * Reset any scan response prepared from prior calls to 00658 * accumulateScanResponse(). 00659 * 00660 * Note: This should be followed by a call to setAdvertisingPayload() or 00661 * startAdvertising() before the update takes effect. 00662 */ 00663 void clearScanResponse(void) { 00664 _scanResponse.clear(); 00665 setAdvertisingData(); 00666 } 00667 00668 /** 00669 * Setup parameters for GAP scanning--i.e. observer mode. 00670 * @param[in] interval 00671 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00672 * @param[in] window 00673 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00674 * @param[in] timeout 00675 * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. 00676 * @param[in] activeScanning 00677 * Set to True if active-scanning is required. This is used to fetch the 00678 * scan response from a peer if possible. 00679 * 00680 * The scanning window divided by the interval determines the duty cycle for 00681 * scanning. For example, if the interval is 100ms and the window is 10ms, 00682 * then the controller will scan for 10 percent of the time. It is possible 00683 * to have the interval and window set to the same value. In this case, 00684 * scanning is continuous, with a change of scanning frequency once every 00685 * interval. 00686 * 00687 * Once the scanning parameters have been configured, scanning can be 00688 * enabled by using startScan(). 00689 * 00690 * @Note: The scan interval and window are recommendations to the BLE stack. 00691 */ 00692 ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, 00693 uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, 00694 uint16_t timeout = 0, 00695 bool activeScanning = false) { 00696 ble_error_t rc; 00697 if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && 00698 ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && 00699 ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { 00700 _scanningParams.setActiveScanning(activeScanning); 00701 return BLE_ERROR_NONE; 00702 } 00703 00704 return rc; 00705 } 00706 00707 /** 00708 * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. 00709 * @param[in] interval 00710 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00711 * 00712 * The scanning window divided by the interval determines the duty cycle for 00713 * scanning. For example, if the interval is 100ms and the window is 10ms, 00714 * then the controller will scan for 10 percent of the time. It is possible 00715 * to have the interval and window set to the same value. In this case, 00716 * scanning is continuous, with a change of scanning frequency once every 00717 * interval. 00718 * 00719 * Once the scanning parameters have been configured, scanning can be 00720 * enabled by using startScan(). 00721 */ 00722 ble_error_t setScanInterval(uint16_t interval) { 00723 return _scanningParams.setInterval(interval); 00724 } 00725 00726 /** 00727 * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. 00728 * @param[in] window 00729 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00730 * 00731 * The scanning window divided by the interval determines the duty cycle for 00732 * scanning. For example, if the interval is 100ms and the window is 10ms, 00733 * then the controller will scan for 10 percent of the time. It is possible 00734 * to have the interval and window set to the same value. In this case, 00735 * scanning is continuous, with a change of scanning frequency once every 00736 * interval. 00737 * 00738 * Once the scanning parameters have been configured, scanning can be 00739 * enabled by using startScan(). 00740 * 00741 * If scanning is already active, the updated value of scanWindow will be 00742 * propagated to the underlying BLE stack. 00743 */ 00744 ble_error_t setScanWindow(uint16_t window) { 00745 ble_error_t rc; 00746 if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) { 00747 return rc; 00748 } 00749 00750 /* If scanning is already active, propagate the new setting to the stack. */ 00751 if (scanningActive) { 00752 return startRadioScan(_scanningParams); 00753 } 00754 00755 return BLE_ERROR_NONE; 00756 } 00757 00758 /** 00759 * Setup parameters for GAP scanning--i.e. observer mode. 00760 * @param[in] timeout 00761 * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. 00762 * 00763 * Once the scanning parameters have been configured, scanning can be 00764 * enabled by using startScan(). 00765 * 00766 * If scanning is already active, the updated value of scanTimeout will be 00767 * propagated to the underlying BLE stack. 00768 */ 00769 ble_error_t setScanTimeout(uint16_t timeout) { 00770 ble_error_t rc; 00771 if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) { 00772 return rc; 00773 } 00774 00775 /* If scanning is already active, propagate the new settings to the stack. */ 00776 if (scanningActive) { 00777 return startRadioScan(_scanningParams); 00778 } 00779 00780 return BLE_ERROR_NONE; 00781 } 00782 00783 /** 00784 * Setup parameters for GAP scanning--i.e. observer mode. 00785 * @param[in] activeScanning 00786 * Set to True if active-scanning is required. This is used to fetch the 00787 * scan response from a peer if possible. 00788 * 00789 * Once the scanning parameters have been configured, scanning can be 00790 * enabled by using startScan(). 00791 * 00792 * If scanning is already in progress, then active-scanning will be enabled 00793 * for the underlying BLE stack. 00794 */ 00795 ble_error_t setActiveScanning(bool activeScanning) { 00796 _scanningParams.setActiveScanning(activeScanning); 00797 00798 /* If scanning is already active, propagate the new settings to the stack. */ 00799 if (scanningActive) { 00800 return startRadioScan(_scanningParams); 00801 } 00802 00803 return BLE_ERROR_NONE; 00804 } 00805 00806 /** 00807 * Start scanning (Observer Procedure) based on the parameters currently in 00808 * effect. 00809 * 00810 * @param[in] callback 00811 * The application specific callback to be invoked upon 00812 * receiving every advertisement report. This can be passed in 00813 * as NULL, in which case scanning may not be enabled at all. 00814 */ 00815 ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) { 00816 ble_error_t err = BLE_ERROR_NONE; 00817 if (callback) { 00818 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { 00819 scanningActive = true; 00820 onAdvertisementReport.attach(callback); 00821 } 00822 } 00823 00824 return err; 00825 } 00826 00827 /** 00828 * Same as above, but this takes an (object, method) pair for a callback. 00829 */ 00830 template<typename T> 00831 ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { 00832 ble_error_t err = BLE_ERROR_NONE; 00833 if (object && callbackMember) { 00834 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { 00835 scanningActive = true; 00836 onAdvertisementReport.attach(object, callbackMember); 00837 } 00838 } 00839 00840 return err; 00841 } 00842 00843 /** 00844 * Initialize radio-notification events to be generated from the stack. 00845 * This API doesn't need to be called directly; 00846 * 00847 * Radio Notification is a feature that enables ACTIVE and INACTIVE 00848 * (nACTIVE) signals from the stack that notify the application when the 00849 * radio is in use. 00850 * 00851 * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE 00852 * signal is sent at the end of the Radio Event. These signals can be used 00853 * by the application programmer to synchronize application logic with radio 00854 * activity. For example, the ACTIVE signal can be used to shut off external 00855 * devices to manage peak current drawn during periods when the radio is on, 00856 * or to trigger sensor data collection for transmission in the Radio Event. 00857 * 00858 * @return BLE_ERROR_NONE on successful initialization, otherwise an error code. 00859 */ 00860 virtual ble_error_t initRadioNotification(void) { 00861 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00862 } 00863 00864 private: 00865 ble_error_t setAdvertisingData(void) { 00866 return setAdvertisingData(_advPayload, _scanResponse); 00867 } 00868 00869 private: 00870 virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; 00871 virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; 00872 00873 public: 00874 /** 00875 * Accessors to read back currently active advertising params. 00876 */ 00877 GapAdvertisingParams &getAdvertisingParams(void) { 00878 return _advParams; 00879 } 00880 const GapAdvertisingParams &getAdvertisingParams(void) const { 00881 return _advParams; 00882 } 00883 00884 /** 00885 * Setup a particular, user-constructed set of advertisement parameters for 00886 * the underlying stack. It would be uncommon for this API to be used 00887 * directly; there are other APIs to tweak advertisement parameters 00888 * individually. 00889 */ 00890 void setAdvertisingParams(const GapAdvertisingParams &newParams) { 00891 _advParams = newParams; 00892 } 00893 00894 /* Event callback handlers. */ 00895 public: 00896 /** 00897 * Setup a callback for timeout events. Refer to TimeoutSource_t for 00898 * possible event types. 00899 */ 00900 void onTimeout(TimeoutEventCallback_t callback) {timeoutCallback = callback;} 00901 00902 /** 00903 * Append to a chain of callbacks to be invoked upon GAP connection. 00904 */ 00905 void onConnection(ConnectionEventCallback_t callback) {connectionCallChain.add(callback);} 00906 00907 template<typename T> 00908 void onConnection(T *tptr, void (T::*mptr)(const ConnectionCallbackParams_t*)) {connectionCallChain.add(tptr, mptr);} 00909 00910 /** 00911 * Append to a chain of callbacks to be invoked upon GAP disconnection. 00912 */ 00913 void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallChain.add(callback);} 00914 00915 template<typename T> 00916 void onDisconnection(T *tptr, void (T::*mptr)(const DisconnectionCallbackParams_t*)) {disconnectionCallChain.add(tptr, mptr);} 00917 00918 /** 00919 * Set the application callback for radio-notification events. 00920 * 00921 * Radio Notification is a feature that enables ACTIVE and INACTIVE 00922 * (nACTIVE) signals from the stack that notify the application when the 00923 * radio is in use. 00924 * 00925 * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE 00926 * signal is sent at the end of the Radio Event. These signals can be used 00927 * by the application programmer to synchronize application logic with radio 00928 * activity. For example, the ACTIVE signal can be used to shut off external 00929 * devices to manage peak current drawn during periods when the radio is on, 00930 * or to trigger sensor data collection for transmission in the Radio Event. 00931 * 00932 * @param callback 00933 * The application handler to be invoked in response to a radio 00934 * ACTIVE/INACTIVE event. 00935 * 00936 * or in the other version: 00937 * 00938 * @param tptr 00939 * Pointer to the object of a class defining the member callback 00940 * function (mptr). 00941 * @param mptr 00942 * The member callback (within the context of an object) to be 00943 * invoked in response to a radio ACTIVE/INACTIVE event. 00944 */ 00945 void onRadioNotification(void (*callback)(bool param)) { 00946 radioNotificationCallback.attach(callback); 00947 initRadioNotification(); 00948 } 00949 template <typename T> 00950 void onRadioNotification(T *tptr, void (T::*mptr)(bool)) { 00951 radioNotificationCallback.attach(tptr, mptr); 00952 initRadioNotification(); 00953 } 00954 00955 protected: 00956 Gap() : 00957 _advParams(), 00958 _advPayload(), 00959 _scanningParams(), 00960 _scanResponse(), 00961 state(), 00962 scanningActive(false), 00963 timeoutCallback(NULL), 00964 radioNotificationCallback(), 00965 onAdvertisementReport(), 00966 connectionCallChain(), 00967 disconnectionCallChain() { 00968 _advPayload.clear(); 00969 _scanResponse.clear(); 00970 } 00971 00972 /* Entry points for the underlying stack to report events back to the user. */ 00973 public: 00974 void processConnectionEvent(Handle_t handle, 00975 Role_t role, 00976 AddressType_t peerAddrType, 00977 const Address_t peerAddr, 00978 AddressType_t ownAddrType, 00979 const Address_t ownAddr, 00980 const ConnectionParams_t *connectionParams) { 00981 state.connected = 1; 00982 ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); 00983 connectionCallChain.call(&callbackParams); 00984 } 00985 00986 void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { 00987 state.connected = 0; 00988 DisconnectionCallbackParams_t callbackParams(handle, reason); 00989 disconnectionCallChain.call(&callbackParams); 00990 } 00991 00992 void processAdvertisementReport(const Address_t peerAddr, 00993 int8_t rssi, 00994 bool isScanResponse, 00995 GapAdvertisingParams::AdvertisingType_t type, 00996 uint8_t advertisingDataLen, 00997 const uint8_t *advertisingData) { 00998 AdvertisementCallbackParams_t params; 00999 memcpy(params.peerAddr, peerAddr, ADDR_LEN); 01000 params.rssi = rssi; 01001 params.isScanResponse = isScanResponse; 01002 params.type = type; 01003 params.advertisingDataLen = advertisingDataLen; 01004 params.advertisingData = advertisingData; 01005 onAdvertisementReport.call(¶ms); 01006 } 01007 01008 void processTimeoutEvent(TimeoutSource_t source) { 01009 if (timeoutCallback) { 01010 timeoutCallback(source); 01011 } 01012 } 01013 01014 protected: 01015 GapAdvertisingParams _advParams; 01016 GapAdvertisingData _advPayload; 01017 GapScanningParams _scanningParams; 01018 GapAdvertisingData _scanResponse; 01019 01020 GapState_t state; 01021 bool scanningActive; 01022 01023 protected: 01024 TimeoutEventCallback_t timeoutCallback; 01025 RadioNotificationEventCallback_t radioNotificationCallback; 01026 AdvertisementReportCallback_t onAdvertisementReport; 01027 CallChainOfFunctionPointersWithContext<const ConnectionCallbackParams_t*> connectionCallChain; 01028 CallChainOfFunctionPointersWithContext<const DisconnectionCallbackParams_t*> disconnectionCallChain; 01029 01030 private: 01031 /* disallow copy and assignment */ 01032 Gap(const Gap &); 01033 Gap& operator=(const Gap &); 01034 }; 01035 01036 #endif // ifndef __GAP_H__
Generated on Mon Jul 18 2022 01:10:56 by
1.7.2
