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