BLE FORK
Fork of BLE_API by
Embed:
(wiki syntax)
Show/hide line numbers
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