Updated
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 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 Sun Jul 17 2022 08:42:21 by 1.7.2