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