Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor NimBLEExtAdvertising #759

Merged
merged 3 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* NimBLE Extended Scanner Demo:
*
* Demonstrates the Bluetooth 5.x scanning capabilities of the NimBLE library.
*
* Created: on November 28, 2024
* Author: H2zero
*
*/

#include <Arduino.h>
#include <NimBLEDevice.h>

static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever
static NimBLEScan::Phy scanPhy = NimBLEScan::Phy::SCAN_ALL;

// Define a class to handle the callbacks when advertisements are received
class scanCallbacks: public NimBLEScanCallbacks {
void onResult(const NimBLEAdvertisedDevice* advertisedDevice) {
Serial.printf("Advertised Device found: %s\n PHY1: %d\n PHY2: %d\n", advertisedDevice->toString().c_str(),
advertisedDevice->getPrimaryPhy(), advertisedDevice->getSecondaryPhy());
}

// Callback to process the results of the completed scan or restart it
void onScanEnd(const NimBLEScanResults& scanResults, int reason) {
Serial.printf("Scan Ended, reason: %d; found %d devices\n", reason, scanResults.getCount());

// Try Different PHY's
switch (scanPhy) {
case NimBLEScan::Phy::SCAN_ALL:
Serial.prinln("Scanning only 1M PHY");
scanPhy = NimBLEScan::Phy::SCAN_1M;
break;
case NimBLEScan::Phy::SCAN_1M:
Serial.println("Scanning only CODED PHY");
scanPhy = NimBLEScan::Phy::SCAN_CODED;
break;
case NimBLEScan::Phy::SCAN_CODED:
Serial.println("Scanning all PHY's");
scanPhy = NimBLEScan::Phy::SCAN_ALL;
break;
}

NimBLEScan* pScan = NimBLEDevice::getScan();
pScan->setPhy(scanPhy);
pScan->start(scanTime);
}
} scanCb;

void setup() {
Serial.begin(115200);
Serial.printf("Starting Extended Scanner\n");

// Initialize NimBLE, no device name specified as we are not advertising
NimBLEDevice::init("");
NimBLEScan* pScan = NimBLEDevice::getScan();

// Set the callbacks that the scanner will call on events.
pScan->setScanCallbacks(&scanCb);

// Use active scanning to obtain scan response data from advertisers
pScan->setActiveScan(true);

// Set the initial PHY's to scan on, default is SCAN_ALL
pScan->setPhy(scanPhy);

// Start scanning for scanTime, 0 = forever
pScan->start(scanTime);
Serial.println("Scanning for peripherals");
}

void loop() {
delay(2000);
}
80 changes: 71 additions & 9 deletions src/NimBLEClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,49 @@ void NimBLEClient::setConfig(NimBLEClient::Config config) {
*/
void NimBLEClient::setConnectPhy(uint8_t mask) {
m_phyMask = mask;
}
} // setConnectPhy

/**
* @brief Request a change to the PHY used for this peer connection.
* @param [in] txPhyMask TX PHY. Can be mask of following:
* - BLE_GAP_LE_PHY_1M_MASK
* - BLE_GAP_LE_PHY_2M_MASK
* - BLE_GAP_LE_PHY_CODED_MASK
* - BLE_GAP_LE_PHY_ANY_MASK
* @param [in] rxPhyMask RX PHY. Can be mask of following:
* - BLE_GAP_LE_PHY_1M_MASK
* - BLE_GAP_LE_PHY_2M_MASK
* - BLE_GAP_LE_PHY_CODED_MASK
* - BLE_GAP_LE_PHY_ANY_MASK
* @param phyOptions Additional PHY options. Valid values are:
* - BLE_GAP_LE_PHY_CODED_ANY (default)
* - BLE_GAP_LE_PHY_CODED_S2
* - BLE_GAP_LE_PHY_CODED_S8
* @return True if successful.
*/
bool NimBLEClient::updatePhy(uint8_t txPhyMask, uint8_t rxPhyMask, uint16_t phyOptions) {
int rc = ble_gap_set_prefered_le_phy(m_connHandle, txPhyMask, rxPhyMask, phyOptions);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Failed to update phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
}

return rc == 0;
} // updatePhy

/**
* @brief Get the PHY used for this peer connection.
* @param [out] txPhy The TX PHY.
* @param [out] rxPhy The RX PHY.
* @return True if successful.
*/
bool NimBLEClient::getPhy(uint8_t* txPhy, uint8_t* rxPhy) {
int rc = ble_gap_read_le_phy(m_connHandle, txPhy, rxPhy);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Failed to read phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
}

return rc == 0;
} // getPhy
# endif

/**
Expand Down Expand Up @@ -1129,6 +1171,19 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
break;
} // BLE_GAP_EVENT_IDENTITY_RESOLVED

# if CONFIG_BT_NIMBLE_EXT_ADV
case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: {
NimBLEConnInfo peerInfo;
rc = ble_gap_conn_find(event->phy_updated.conn_handle, &peerInfo.m_desc);
if (rc != 0) {
return BLE_ATT_ERR_INVALID_HANDLE;
}

pClient->m_pClientCallbacks->onPhyUpdate(pClient, event->phy_updated.tx_phy, event->phy_updated.rx_phy);
return 0;
} // BLE_GAP_EVENT_PHY_UPDATE_COMPLETE
# endif

case BLE_GAP_EVENT_MTU: {
if (pClient->m_connHandle != event->mtu.conn_handle) {
return 0;
Expand Down Expand Up @@ -1224,30 +1279,31 @@ std::string NimBLEClient::toString() const {
} // toString

static const char* CB_TAG = "NimBLEClientCallbacks";

/**
* @brief Get the last error code reported by the NimBLE host
* @return int, the NimBLE error code.
*/
int NimBLEClient::getLastError() const {
int NimBLEClient::getLastError() const {
return m_lastErr;
} // getLastError

void NimBLEClientCallbacks::onConnect(NimBLEClient* pClient) {
NIMBLE_LOGD(CB_TAG, "onConnect: default");
}
} // onConnect

void NimBLEClientCallbacks::onConnectFail(NimBLEClient* pClient, int reason) {
NIMBLE_LOGD(CB_TAG, "onConnectFail: default, reason: %d", reason);
}
} // onConnectFail

void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient, int reason) {
NIMBLE_LOGD(CB_TAG, "onDisconnect: default, reason: %d", reason);
}
} // onDisconnect

bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
NIMBLE_LOGD(CB_TAG, "onConnParamsUpdateRequest: default");
return true;
}
} // onConnParamsUpdateRequest

void NimBLEClientCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD(CB_TAG, "onPassKeyEntry: default: 123456");
Expand All @@ -1256,7 +1312,7 @@ void NimBLEClientCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {

void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD(CB_TAG, "onAuthenticationComplete: default");
}
} // onAuthenticationComplete

void NimBLEClientCallbacks::onIdentity(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD(CB_TAG, "onIdentity: default");
Expand All @@ -1265,10 +1321,16 @@ void NimBLEClientCallbacks::onIdentity(NimBLEConnInfo& connInfo) {
void NimBLEClientCallbacks::onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pin) {
NIMBLE_LOGD(CB_TAG, "onConfirmPasskey: default: true");
NimBLEDevice::injectConfirmPasskey(connInfo, true);
}
} // onConfirmPasskey

void NimBLEClientCallbacks::onMTUChange(NimBLEClient* pClient, uint16_t mtu) {
NIMBLE_LOGD(CB_TAG, "onMTUChange: default");
}
} // onMTUChange

# if CONFIG_BT_NIMBLE_EXT_ADV
void NimBLEClientCallbacks::onPhyUpdate(NimBLEClient* pClient, uint8_t txPhy, uint8_t rxPhy) {
NIMBLE_LOGD(CB_TAG, "onPhyUpdate: default, txPhy: %d, rxPhy: %d", txPhy, rxPhy);
} // onPhyUpdate
# endif

#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
19 changes: 18 additions & 1 deletion src/NimBLEClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ class NimBLEClient {
bool response = false);

# if CONFIG_BT_NIMBLE_EXT_ADV
void setConnectPhy(uint8_t mask);
void setConnectPhy(uint8_t phyMask);
bool updatePhy(uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions = 0);
bool getPhy(uint8_t* txPhy, uint8_t* rxPhy);
# endif

struct Config {
Expand Down Expand Up @@ -207,6 +209,21 @@ class NimBLEClientCallbacks {
* about the peer connection parameters.
*/
virtual void onMTUChange(NimBLEClient* pClient, uint16_t MTU);

# if CONFIG_BT_NIMBLE_EXT_ADV
/**
* @brief Called when the PHY update procedure is complete.
* @param [in] pClient A pointer to the client whose PHY was updated.
* about the peer connection parameters.
* @param [in] txPhy The transmit PHY.
* @param [in] rxPhy The receive PHY.
* Possible values:
* * BLE_GAP_LE_PHY_1M
* * BLE_GAP_LE_PHY_2M
* * BLE_GAP_LE_PHY_CODED
*/
virtual void onPhyUpdate(NimBLEClient* pClient, uint8_t txPhy, uint8_t rxPhy);
# endif
};

#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
Expand Down
25 changes: 25 additions & 0 deletions src/NimBLEDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,31 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
/* STACK FUNCTIONS */
/* -------------------------------------------------------------------------- */

# if CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
/**
* @brief Set the preferred default phy to use for connections.
* @param [in] txPhyMask TX PHY. Can be mask of following:
* - BLE_GAP_LE_PHY_1M_MASK
* - BLE_GAP_LE_PHY_2M_MASK
* - BLE_GAP_LE_PHY_CODED_MASK
* - BLE_GAP_LE_PHY_ANY_MASK
* @param [in] rxPhyMask RX PHY. Can be mask of following:
* - BLE_GAP_LE_PHY_1M_MASK
* - BLE_GAP_LE_PHY_2M_MASK
* - BLE_GAP_LE_PHY_CODED_MASK
* - BLE_GAP_LE_PHY_ANY_MASK
* @return True if successful.
*/
bool NimBLEDevice::setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask) {
int rc = ble_gap_set_prefered_default_le_phy(txPhyMask, rxPhyMask);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Failed to set default phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
}

return rc == 0;
}
# endif

/**
* @brief Host reset, we pass the message so we don't make calls until re-synced.
* @param [in] reason The reason code for the reset.
Expand Down
4 changes: 4 additions & 0 deletions src/NimBLEDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ class NimBLEDevice {
static void onSync(void);
static void host_task(void* param);

# if CONFIG_BT_NIMBLE_EXT_ADV
static bool setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask);
# endif

# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
static NimBLEScan* getScan();
# endif
Expand Down
Loading