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 LinkNode-Test 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 that 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 that is not 00057 * covered by this enumeration, 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 typedef FunctionPointerWithContext<TimeoutSource_t> TimeoutEventCallback_t; 00144 typedef CallChainOfFunctionPointersWithContext<TimeoutSource_t> TimeoutEventCallbackChain_t; 00145 00146 typedef FunctionPointerWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallback_t; 00147 typedef CallChainOfFunctionPointersWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallbackChain_t; 00148 00149 typedef FunctionPointerWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallback_t; 00150 typedef CallChainOfFunctionPointersWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallbackChain_t; 00151 00152 typedef FunctionPointerWithContext<bool> RadioNotificationEventCallback_t; 00153 00154 /* 00155 * The following functions are meant to be overridden in the platform-specific sub-class. 00156 */ 00157 public: 00158 /** 00159 * Set the BTLE MAC address and type. Please note that the address format is 00160 * least significant byte first (LSB). Please refer to Address_t. 00161 * 00162 * @return BLE_ERROR_NONE on success. 00163 */ 00164 virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { 00165 /* avoid compiler warnings about unused variables */ 00166 (void)type; 00167 (void)address; 00168 00169 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00170 } 00171 00172 /** 00173 * Fetch the BTLE MAC address and type. 00174 * 00175 * @return BLE_ERROR_NONE on success. 00176 */ 00177 virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { 00178 /* Avoid compiler warnings about unused variables. */ 00179 (void)typeP; 00180 (void)address; 00181 00182 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00183 } 00184 00185 /** 00186 * @return Minimum Advertising interval in milliseconds for connectable 00187 * undirected and connectable directed event types. 00188 */ 00189 virtual uint16_t getMinAdvertisingInterval(void) const { 00190 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00191 } 00192 00193 /** 00194 * @return Minimum Advertising interval in milliseconds for scannable 00195 * undirected and non-connectable undirected event types. 00196 */ 00197 virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const { 00198 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00199 } 00200 00201 /** 00202 * @return Maximum Advertising interval in milliseconds. 00203 */ 00204 virtual uint16_t getMaxAdvertisingInterval(void) const { 00205 return 0xFFFF; /* Requesting action from porter(s): override this API if this capability is supported. */ 00206 } 00207 00208 virtual ble_error_t stopAdvertising(void) { 00209 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00210 } 00211 00212 /** 00213 * Stop scanning. The current scanning parameters remain in effect. 00214 * 00215 * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. 00216 */ 00217 virtual ble_error_t stopScan() { 00218 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00219 } 00220 00221 /** 00222 * Create a connection (GAP Link Establishment). 00223 * 00224 * @param peerAddr 00225 * 48-bit address, LSB format. 00226 * @param peerAddrType 00227 * Address type of the peer. 00228 * @param connectionParams 00229 * Connection parameters. 00230 * @param scanParams 00231 * Paramters to be used while scanning for the peer. 00232 * @return BLE_ERROR_NONE if connection establishment procedure is started 00233 * successfully. The connectionCallChain (if set) will be invoked upon 00234 * a connection event. 00235 */ 00236 virtual ble_error_t connect(const Address_t peerAddr, 00237 Gap::AddressType_t peerAddrType, 00238 const ConnectionParams_t *connectionParams, 00239 const GapScanningParams *scanParams) { 00240 /* Avoid compiler warnings about unused variables. */ 00241 (void)peerAddr; 00242 (void)peerAddrType; 00243 (void)connectionParams; 00244 (void)scanParams; 00245 00246 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00247 } 00248 00249 /** 00250 * This call initiates the disconnection procedure, and its completion will 00251 * be communicated to the application with an invocation of the 00252 * disconnectionCallback. 00253 * 00254 * @param reason 00255 * The reason for disconnection; to be sent back to the peer. 00256 */ 00257 virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) { 00258 /* avoid compiler warnings about unused variables */ 00259 (void)connectionHandle; 00260 (void)reason; 00261 00262 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00263 } 00264 00265 /** 00266 * This call initiates the disconnection procedure, and its completion will 00267 * be communicated to the application with an invocation of the 00268 * disconnectionCallback. 00269 * 00270 * @param reason 00271 * The reason for disconnection; to be sent back to the peer. 00272 * 00273 * @note: This version of disconnect() doesn't take a connection handle. It 00274 * works reliably only for stacks that are limited to a single 00275 * connection. This API should be considered *deprecated* in favour of the 00276 * alternative, which takes a connection handle. It will be dropped in the future. 00277 */ 00278 virtual ble_error_t disconnect(DisconnectionReason_t reason) { 00279 /* Avoid compiler warnings about unused variables. */ 00280 (void)reason; 00281 00282 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00283 } 00284 00285 /** 00286 * Get the GAP peripheral preferred connection parameters. These are the 00287 * defaults that the peripheral would like to have in a connection. The 00288 * choice of the connection parameters is eventually up to the central. 00289 * 00290 * @param[out] params 00291 * The structure where the parameters will be stored. Memory 00292 * for this is owned by the caller. 00293 * 00294 * @return BLE_ERROR_NONE if the parameters were successfully filled into 00295 * the given structure pointed to by params. 00296 */ 00297 virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) { 00298 /* Avoid compiler warnings about unused variables. */ 00299 (void)params; 00300 00301 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00302 } 00303 00304 /** 00305 * Set the GAP peripheral preferred connection parameters. These are the 00306 * defaults that the peripheral would like to have in a connection. The 00307 * choice of the connection parameters is eventually up to the central. 00308 * 00309 * @param[in] params 00310 * The structure containing the desired parameters. 00311 */ 00312 virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) { 00313 /* Avoid compiler warnings about unused variables. */ 00314 (void)params; 00315 00316 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00317 } 00318 00319 /** 00320 * Update connection parameters. 00321 * In the central role this will initiate a Link Layer connection parameter update procedure. 00322 * In the peripheral role, this will send the corresponding L2CAP request and wait for 00323 * the central to perform the procedure. 00324 * 00325 * @param[in] handle 00326 * Connection Handle. 00327 * @param[in] params 00328 * Pointer to desired connection parameters. If NULL is provided on a peripheral role, 00329 * the parameters in the PPCP characteristic of the GAP service will be used instead. 00330 */ 00331 virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) { 00332 /* avoid compiler warnings about unused variables */ 00333 (void)handle; 00334 (void)params; 00335 00336 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00337 } 00338 00339 /** 00340 * Set the device name characteristic in the GAP service. 00341 * @param[in] deviceName 00342 * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. 00343 */ 00344 virtual ble_error_t setDeviceName(const uint8_t *deviceName) { 00345 /* Avoid compiler warnings about unused variables. */ 00346 (void)deviceName; 00347 00348 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00349 } 00350 00351 /** 00352 * Get the value of the device name characteristic in the GAP service. 00353 * @param[out] deviceName 00354 * Pointer to an empty buffer where the UTF-8 *non NULL- 00355 * terminated* string will be placed. Set this 00356 * value to NULL in order to obtain the deviceName-length 00357 * from the 'length' parameter. 00358 * 00359 * @param[in/out] lengthP 00360 * (on input) Length of the buffer pointed to by deviceName; 00361 * (on output) the complete device name length (without the 00362 * null terminator). 00363 * 00364 * @note If the device name is longer than the size of the supplied buffer, 00365 * length will return the complete device name length, and not the 00366 * number of bytes actually returned in deviceName. The application may 00367 * use this information to retry with a suitable buffer size. 00368 */ 00369 virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { 00370 /* avoid compiler warnings about unused variables */ 00371 (void)deviceName; 00372 (void)lengthP; 00373 00374 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00375 } 00376 00377 /** 00378 * Set the appearance characteristic in the GAP service. 00379 * @param[in] appearance 00380 * The new value for the device-appearance. 00381 */ 00382 virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { 00383 /* Avoid compiler warnings about unused variables. */ 00384 (void)appearance; 00385 00386 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00387 } 00388 00389 /** 00390 * Get the appearance characteristic in the GAP service. 00391 * @param[out] appearance 00392 * The new value for the device-appearance. 00393 */ 00394 virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { 00395 /* Avoid compiler warnings about unused variables. */ 00396 (void)appearanceP; 00397 00398 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00399 } 00400 00401 /** 00402 * Set the radio's transmit power. 00403 * @param[in] txPower Radio transmit power in dBm. 00404 */ 00405 virtual ble_error_t setTxPower(int8_t txPower) { 00406 /* Avoid compiler warnings about unused variables. */ 00407 (void)txPower; 00408 00409 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00410 } 00411 00412 /** 00413 * Query the underlying stack for permitted arguments for setTxPower(). 00414 * 00415 * @param[out] valueArrayPP 00416 * Out parameter to receive the immutable array of Tx values. 00417 * @param[out] countP 00418 * Out parameter to receive the array's size. 00419 */ 00420 virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { 00421 /* Avoid compiler warnings about unused variables. */ 00422 (void)valueArrayPP; 00423 (void)countP; 00424 00425 *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */ 00426 } 00427 00428 protected: 00429 /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */ 00430 virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { 00431 (void)scanningParams; 00432 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00433 } 00434 00435 /* 00436 * APIs with non-virtual implementations. 00437 */ 00438 public: 00439 /** 00440 * Returns the current GAP state of the device using a bitmask that 00441 * describes whether the device is advertising or connected. 00442 */ 00443 GapState_t getState(void) const { 00444 return state; 00445 } 00446 00447 /** 00448 * Set the GAP advertising mode to use for this device. 00449 */ 00450 void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { 00451 _advParams.setAdvertisingType(advType); 00452 } 00453 00454 /** 00455 * @param[in] interval 00456 * Advertising interval in units of milliseconds. Advertising 00457 * is disabled if interval is 0. If interval is smaller than 00458 * the minimum supported value, then the minimum supported 00459 * value is used instead. This minimum value can be discovered 00460 * using getMinAdvertisingInterval(). 00461 * 00462 * This field must be set to 0 if connectionMode is equal 00463 * to ADV_CONNECTABLE_DIRECTED. 00464 * 00465 * @note: Decreasing this value will allow central devices to detect a 00466 * peripheral faster, at the expense of more power being used by the radio 00467 * due to the higher data transmit rate. 00468 * 00469 * @Note: [WARNING] This API previously used 0.625ms as the unit for its 00470 * 'interval' argument. That required an explicit conversion from 00471 * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is 00472 * no longer required as the new units are milliseconds. Any application 00473 * code depending on the old semantics needs to be updated accordingly. 00474 */ 00475 void setAdvertisingInterval(uint16_t interval) { 00476 if (interval == 0) { 00477 stopAdvertising(); 00478 } else if (interval < getMinAdvertisingInterval()) { 00479 interval = getMinAdvertisingInterval(); 00480 } 00481 _advParams.setInterval(interval); 00482 } 00483 00484 /** 00485 * @param[in] timeout 00486 * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 00487 * and 16383). Use 0 to disable the advertising timeout. 00488 */ 00489 void setAdvertisingTimeout(uint16_t timeout) { 00490 _advParams.setTimeout(timeout); 00491 } 00492 00493 /** 00494 * Start advertising. 00495 */ 00496 ble_error_t startAdvertising(void) { 00497 setAdvertisingData(); /* Update the underlying stack. */ 00498 return startAdvertising(_advParams); 00499 } 00500 00501 /** 00502 * Reset any advertising payload prepared from prior calls to 00503 * accumulateAdvertisingPayload(). This automatically propagates the re- 00504 * initialized advertising payload to the underlying stack. 00505 */ 00506 void clearAdvertisingPayload(void) { 00507 _advPayload.clear(); 00508 setAdvertisingData(); 00509 } 00510 00511 /** 00512 * Accumulate an AD structure in the advertising payload. Please note that 00513 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00514 * as an additional 31 bytes if the advertising payload is too 00515 * small. 00516 * 00517 * @param[in] flags 00518 * The flags to be added. Please refer to 00519 * GapAdvertisingData::Flags for valid flags. Multiple 00520 * flags may be specified in combination. 00521 */ 00522 ble_error_t accumulateAdvertisingPayload(uint8_t flags) { 00523 ble_error_t rc; 00524 if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) { 00525 return rc; 00526 } 00527 00528 return setAdvertisingData(); 00529 } 00530 00531 /** 00532 * Accumulate an AD structure in the advertising payload. Please note that 00533 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00534 * as an additional 31 bytes if the advertising payload is too 00535 * small. 00536 * 00537 * @param app 00538 * The appearance of the peripheral. 00539 */ 00540 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { 00541 setAppearance(app); 00542 00543 ble_error_t rc; 00544 if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) { 00545 return rc; 00546 } 00547 00548 return setAdvertisingData(); 00549 } 00550 00551 /** 00552 * Accumulate an AD structure in the advertising payload. Please note that 00553 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00554 * as an additional 31 bytes if the advertising payload is too 00555 * small. 00556 * 00557 * @param power 00558 * The max transmit power to be used by the controller (in dBm). 00559 */ 00560 ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { 00561 ble_error_t rc; 00562 if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) { 00563 return rc; 00564 } 00565 00566 return setAdvertisingData(); 00567 } 00568 00569 /** 00570 * Accumulate a variable length byte-stream as an AD structure in the 00571 * advertising payload. Please note that the payload is limited to 31 bytes. 00572 * The SCAN_RESPONSE message may be used as an additional 31 bytes if the 00573 * advertising payload is too small. 00574 * 00575 * @param type The type describing the variable length data. 00576 * @param data Data bytes. 00577 * @param len Length of data. 00578 */ 00579 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00580 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00581 setDeviceName(data); 00582 } 00583 00584 ble_error_t rc; 00585 if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) { 00586 return rc; 00587 } 00588 00589 return setAdvertisingData(); 00590 } 00591 00592 /** 00593 * Update a particular ADV field in the advertising payload (based on 00594 * matching type and length). Note: the length of the new data must be the 00595 * same as the old one. 00596 * 00597 * @param[in] type The ADV type field describing the variable length data. 00598 * @param[in] data Data bytes. 00599 * @param[in] len Length of data. 00600 * 00601 * @note: If advertisements are enabled, then the update will take effect immediately. 00602 * 00603 * @return BLE_ERROR_NONE if the advertisement payload was updated based on 00604 * a <type, len> match; otherwise, an appropriate error. 00605 */ 00606 ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00607 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00608 setDeviceName(data); 00609 } 00610 00611 ble_error_t rc; 00612 if ((rc = _advPayload.updateData(type, data, len)) != BLE_ERROR_NONE) { 00613 return rc; 00614 } 00615 00616 return setAdvertisingData(); 00617 } 00618 00619 /** 00620 * Set up a particular, user-constructed advertisement payload for the 00621 * underlying stack. It would be uncommon for this API to be used directly; 00622 * there are other APIs to build an advertisement payload (see above). 00623 */ 00624 ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) { 00625 _advPayload = payload; 00626 return setAdvertisingData(); 00627 } 00628 00629 /** 00630 * @return Read back advertising data. Useful for storing and 00631 * restoring payload. 00632 */ 00633 const GapAdvertisingData &getAdvertisingPayload(void) const { 00634 return _advPayload; 00635 } 00636 00637 /** 00638 * Accumulate a variable length byte-stream as an AD structure in the 00639 * scanResponse payload. 00640 * 00641 * @param[in] type The type describing the variable length data. 00642 * @param[in] data Data bytes. 00643 * @param[in] len Length of data. 00644 */ 00645 ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { 00646 ble_error_t rc; 00647 if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) { 00648 return rc; 00649 } 00650 00651 return setAdvertisingData(); 00652 } 00653 00654 /** 00655 * Reset any scan response prepared from prior calls to 00656 * accumulateScanResponse(). 00657 * 00658 * Note: This should be followed by a call to setAdvertisingPayload() or 00659 * startAdvertising() before the update takes effect. 00660 */ 00661 void clearScanResponse(void) { 00662 _scanResponse.clear(); 00663 setAdvertisingData(); 00664 } 00665 00666 /** 00667 * Set up parameters for GAP scanning (observer mode). 00668 * @param[in] interval 00669 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00670 * @param[in] window 00671 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00672 * @param[in] timeout 00673 * Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout. 00674 * @param[in] activeScanning 00675 * Set to True if active-scanning is required. This is used to fetch the 00676 * scan response from a peer if possible. 00677 * 00678 * The scanning window divided by the interval determines the duty cycle for 00679 * scanning. For example, if the interval is 100ms and the window is 10ms, 00680 * then the controller will scan for 10 percent of the time. It is possible 00681 * to have the interval and window set to the same value. In this case, 00682 * scanning is continuous, with a change of scanning frequency once every 00683 * interval. 00684 * 00685 * Once the scanning parameters have been configured, scanning can be 00686 * enabled by using startScan(). 00687 * 00688 * @Note: The scan interval and window are recommendations to the BLE stack. 00689 */ 00690 ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, 00691 uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, 00692 uint16_t timeout = 0, 00693 bool activeScanning = false) { 00694 ble_error_t rc; 00695 if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && 00696 ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && 00697 ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { 00698 _scanningParams.setActiveScanning(activeScanning); 00699 return BLE_ERROR_NONE; 00700 } 00701 00702 return rc; 00703 } 00704 00705 /** 00706 * Set up the scanInterval parameter for GAP scanning (observer mode). 00707 * @param[in] interval 00708 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00709 * 00710 * The scanning window divided by the interval determines the duty cycle for 00711 * scanning. For example, if the interval is 100ms and the window is 10ms, 00712 * then the controller will scan for 10 percent of the time. It is possible 00713 * to have the interval and window set to the same value. In this case, 00714 * scanning is continuous, with a change of scanning frequency once every 00715 * interval. 00716 * 00717 * Once the scanning parameters have been configured, scanning can be 00718 * enabled by using startScan(). 00719 */ 00720 ble_error_t setScanInterval(uint16_t interval) { 00721 return _scanningParams.setInterval(interval); 00722 } 00723 00724 /** 00725 * Set up the scanWindow parameter for GAP scanning (observer mode). 00726 * @param[in] window 00727 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. 00728 * 00729 * The scanning window divided by the interval determines the duty cycle for 00730 * scanning. For example, if the interval is 100ms and the window is 10ms, 00731 * then the controller will scan for 10 percent of the time. It is possible 00732 * to have the interval and window set to the same value. In this case, 00733 * scanning is continuous, with a change of scanning frequency once every 00734 * interval. 00735 * 00736 * Once the scanning parameters have been configured, scanning can be 00737 * enabled by using startScan(). 00738 * 00739 * If scanning is already active, the updated value of scanWindow will be 00740 * propagated to the underlying BLE stack. 00741 */ 00742 ble_error_t setScanWindow(uint16_t window) { 00743 ble_error_t rc; 00744 if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) { 00745 return rc; 00746 } 00747 00748 /* If scanning is already active, propagate the new setting to the stack. */ 00749 if (scanningActive) { 00750 return startRadioScan(_scanningParams); 00751 } 00752 00753 return BLE_ERROR_NONE; 00754 } 00755 00756 /** 00757 * Set up parameters for GAP scanning (observer mode). 00758 * @param[in] timeout 00759 * Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout. 00760 * 00761 * Once the scanning parameters have been configured, scanning can be 00762 * enabled by using startScan(). 00763 * 00764 * If scanning is already active, the updated value of scanTimeout will be 00765 * propagated to the underlying BLE stack. 00766 */ 00767 ble_error_t setScanTimeout(uint16_t timeout) { 00768 ble_error_t rc; 00769 if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) { 00770 return rc; 00771 } 00772 00773 /* If scanning is already active, propagate the new settings to the stack. */ 00774 if (scanningActive) { 00775 return startRadioScan(_scanningParams); 00776 } 00777 00778 return BLE_ERROR_NONE; 00779 } 00780 00781 /** 00782 * Set up parameters for GAP scanning (observer mode). 00783 * @param[in] activeScanning 00784 * Set to True if active-scanning is required. This is used to fetch the 00785 * scan response from a peer if possible. 00786 * 00787 * Once the scanning parameters have been configured, scanning can be 00788 * enabled by using startScan(). 00789 * 00790 * If scanning is already in progress, then active-scanning will be enabled 00791 * for the underlying BLE stack. 00792 */ 00793 ble_error_t setActiveScanning(bool activeScanning) { 00794 _scanningParams.setActiveScanning(activeScanning); 00795 00796 /* If scanning is already active, propagate the new settings to the stack. */ 00797 if (scanningActive) { 00798 return startRadioScan(_scanningParams); 00799 } 00800 00801 return BLE_ERROR_NONE; 00802 } 00803 00804 /** 00805 * Start scanning (Observer Procedure) based on the parameters currently in 00806 * effect. 00807 * 00808 * @param[in] callback 00809 * The application-specific callback to be invoked upon 00810 * receiving every advertisement report. This can be passed in 00811 * as NULL, in which case scanning may not be enabled at all. 00812 */ 00813 ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) { 00814 ble_error_t err = BLE_ERROR_NONE; 00815 if (callback) { 00816 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { 00817 scanningActive = true; 00818 onAdvertisementReport.attach(callback); 00819 } 00820 } 00821 00822 return err; 00823 } 00824 00825 /** 00826 * Same as above, but this takes an (object, method) pair for a callback. 00827 */ 00828 template<typename T> 00829 ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { 00830 ble_error_t err = BLE_ERROR_NONE; 00831 if (object && callbackMember) { 00832 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { 00833 scanningActive = true; 00834 onAdvertisementReport.attach(object, callbackMember); 00835 } 00836 } 00837 00838 return err; 00839 } 00840 00841 /** 00842 * Initialize radio-notification events to be generated from the stack. 00843 * This API doesn't need to be called directly. 00844 * 00845 * Radio Notification is a feature that enables ACTIVE and INACTIVE 00846 * (nACTIVE) signals from the stack that notify the application when the 00847 * radio is in use. 00848 * 00849 * The ACTIVE signal is sent before the radio event starts. The nACTIVE 00850 * signal is sent at the end of the radio event. These signals can be used 00851 * by the application programmer to synchronize application logic with radio 00852 * activity. For example, the ACTIVE signal can be used to shut off external 00853 * devices, to manage peak current drawn during periods when the radio is on, 00854 * or to trigger sensor data collection for transmission in the Radio Event. 00855 * 00856 * @return BLE_ERROR_NONE on successful initialization, otherwise an error code. 00857 */ 00858 virtual ble_error_t initRadioNotification(void) { 00859 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00860 } 00861 00862 private: 00863 ble_error_t setAdvertisingData(void) { 00864 return setAdvertisingData(_advPayload, _scanResponse); 00865 } 00866 00867 private: 00868 virtual ble_error_t setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) = 0; 00869 virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; 00870 00871 public: 00872 /** 00873 * Accessors to read back currently active advertising params. 00874 */ 00875 GapAdvertisingParams &getAdvertisingParams(void) { 00876 return _advParams; 00877 } 00878 const GapAdvertisingParams &getAdvertisingParams(void) const { 00879 return _advParams; 00880 } 00881 00882 /** 00883 * Set up a particular, user-constructed set of advertisement parameters for 00884 * the underlying stack. It would be uncommon for this API to be used 00885 * directly; there are other APIs to tweak advertisement parameters 00886 * individually. 00887 */ 00888 void setAdvertisingParams(const GapAdvertisingParams &newParams) { 00889 _advParams = newParams; 00890 } 00891 00892 /* Event callback handlers. */ 00893 public: 00894 /** 00895 * Set up a callback for timeout events. Refer to TimeoutSource_t for 00896 * possible event types. 00897 * @note It is possible to unregister callbacks using onTimeout().detach(callback) 00898 */ 00899 void onTimeout(TimeoutEventCallback_t callback) { 00900 timeoutCallbackChain.add(callback); 00901 } 00902 00903 /** 00904 * @brief provide access to the callchain of timeout event callbacks 00905 * It is possible to register callbacks using onTimeout().add(callback); 00906 * It is possible to unregister callbacks using onTimeout().detach(callback) 00907 * @return The timeout event callbacks chain 00908 */ 00909 TimeoutEventCallbackChain_t& onTimeout() { 00910 return timeoutCallbackChain; 00911 } 00912 00913 /** 00914 * Append to a chain of callbacks to be invoked upon GAP connection. 00915 * @note It is possible to unregister callbacks using onConnection().detach(callback) 00916 */ 00917 void onConnection(ConnectionEventCallback_t callback) {connectionCallChain.add(callback);} 00918 00919 template<typename T> 00920 void onConnection(T *tptr, void (T::*mptr)(const ConnectionCallbackParams_t*)) {connectionCallChain.add(tptr, mptr);} 00921 00922 /** 00923 * @brief provide access to the callchain of connection event callbacks 00924 * It is possible to register callbacks using onConnection().add(callback); 00925 * It is possible to unregister callbacks using onConnection().detach(callback) 00926 * @return The connection event callbacks chain 00927 */ 00928 ConnectionEventCallbackChain_t& onConnection() { 00929 return connectionCallChain; 00930 } 00931 00932 /** 00933 * Append to a chain of callbacks to be invoked upon GAP disconnection. 00934 * @note It is possible to unregister callbacks using onDisconnection().detach(callback) 00935 */ 00936 void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallChain.add(callback);} 00937 00938 template<typename T> 00939 void onDisconnection(T *tptr, void (T::*mptr)(const DisconnectionCallbackParams_t*)) {disconnectionCallChain.add(tptr, mptr);} 00940 00941 /** 00942 * @brief provide access to the callchain of disconnection event callbacks 00943 * It is possible to register callbacks using onDisconnection().add(callback); 00944 * It is possible to unregister callbacks using onDisconnection().detach(callback) 00945 * @return The disconnection event callbacks chain 00946 */ 00947 DisconnectionEventCallbackChain_t& onDisconnection() { 00948 return disconnectionCallChain; 00949 } 00950 00951 /** 00952 * Set the application callback for radio-notification events. 00953 * 00954 * Radio Notification is a feature that enables ACTIVE and INACTIVE 00955 * (nACTIVE) signals from the stack that notify the application when the 00956 * radio is in use. 00957 * 00958 * The ACTIVE signal is sent before the radio event starts. The nACTIVE 00959 * signal is sent at the end of the radio event. These signals can be used 00960 * by the application programmer to synchronize application logic with radio 00961 * activity. For example, the ACTIVE signal can be used to shut off external 00962 * devices, to manage peak current drawn during periods when the radio is on, 00963 * or to trigger sensor data collection for transmission in the Radio Event. 00964 * 00965 * @param callback 00966 * The application handler to be invoked in response to a radio 00967 * ACTIVE/INACTIVE event. 00968 * 00969 * Or in the other version: 00970 * 00971 * @param tptr 00972 * Pointer to the object of a class defining the member callback 00973 * function (mptr). 00974 * @param mptr 00975 * The member callback (within the context of an object) to be 00976 * invoked in response to a radio ACTIVE/INACTIVE event. 00977 */ 00978 void onRadioNotification(void (*callback)(bool param)) { 00979 radioNotificationCallback.attach(callback); 00980 } 00981 template <typename T> 00982 void onRadioNotification(T *tptr, void (T::*mptr)(bool)) { 00983 radioNotificationCallback.attach(tptr, mptr); 00984 } 00985 00986 protected: 00987 Gap() : 00988 _advParams(), 00989 _advPayload(), 00990 _scanningParams(), 00991 _scanResponse(), 00992 state(), 00993 scanningActive(false), 00994 timeoutCallbackChain(), 00995 radioNotificationCallback(), 00996 onAdvertisementReport(), 00997 connectionCallChain(), 00998 disconnectionCallChain() { 00999 _advPayload.clear(); 01000 _scanResponse.clear(); 01001 } 01002 01003 /* Entry points for the underlying stack to report events back to the user. */ 01004 public: 01005 void processConnectionEvent(Handle_t handle, 01006 Role_t role, 01007 AddressType_t peerAddrType, 01008 const Address_t peerAddr, 01009 AddressType_t ownAddrType, 01010 const Address_t ownAddr, 01011 const ConnectionParams_t *connectionParams) { 01012 state.connected = 1; 01013 ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); 01014 connectionCallChain.call(&callbackParams); 01015 } 01016 01017 void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { 01018 state.connected = 0; 01019 DisconnectionCallbackParams_t callbackParams(handle, reason); 01020 disconnectionCallChain.call(&callbackParams); 01021 } 01022 01023 void processAdvertisementReport(const Address_t peerAddr, 01024 int8_t rssi, 01025 bool isScanResponse, 01026 GapAdvertisingParams::AdvertisingType_t type, 01027 uint8_t advertisingDataLen, 01028 const uint8_t *advertisingData) { 01029 AdvertisementCallbackParams_t params; 01030 memcpy(params.peerAddr, peerAddr, ADDR_LEN); 01031 params.rssi = rssi; 01032 params.isScanResponse = isScanResponse; 01033 params.type = type; 01034 params.advertisingDataLen = advertisingDataLen; 01035 params.advertisingData = advertisingData; 01036 onAdvertisementReport.call(¶ms); 01037 } 01038 01039 void processTimeoutEvent(TimeoutSource_t source) { 01040 if (timeoutCallbackChain) { 01041 timeoutCallbackChain(source); 01042 } 01043 } 01044 01045 protected: 01046 GapAdvertisingParams _advParams; 01047 GapAdvertisingData _advPayload; 01048 GapScanningParams _scanningParams; 01049 GapAdvertisingData _scanResponse; 01050 01051 GapState_t state; 01052 bool scanningActive; 01053 01054 protected: 01055 TimeoutEventCallbackChain_t timeoutCallbackChain; 01056 RadioNotificationEventCallback_t radioNotificationCallback; 01057 AdvertisementReportCallback_t onAdvertisementReport; 01058 ConnectionEventCallbackChain_t connectionCallChain; 01059 DisconnectionEventCallbackChain_t disconnectionCallChain; 01060 01061 private: 01062 /* Disallow copy and assignment. */ 01063 Gap(const Gap &); 01064 Gap& operator=(const Gap &); 01065 }; 01066 01067 #endif // ifndef __GAP_H__
Generated on Tue Jul 12 2022 16:00:20 by
