diff --git a/src/NimBLEAdvertising.cpp b/src/NimBLEAdvertising.cpp index 6b5cee7..36bdbf9 100644 --- a/src/NimBLEAdvertising.cpp +++ b/src/NimBLEAdvertising.cpp @@ -54,6 +54,11 @@ NimBLEAdvertising::NimBLEAdvertising() { m_advParams.itvl_min = 0; m_advParams.itvl_max = 0; + m_customAdvData = false; + m_customScanResponseData = false; + m_scanResp = true; + m_advDataSet = false; + } // NimBLEAdvertising @@ -217,8 +222,10 @@ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertiseme /** * @brief Start advertising. + * @param [in] duration The duration, in seconds, to advertise, 0 == advertise forever. + * @param [in] advCompleteCB A pointer to a callback to be invoked when advertising ends. */ -void NimBLEAdvertising::start() { +void NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdvertising *pAdv)) { NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); // If Host is not synced we cannot start advertising. @@ -244,6 +251,15 @@ void NimBLEAdvertising::start() { return; } + if(duration == 0){ + duration = BLE_HS_FOREVER; + } + else{ + duration = duration*1000; // convert duration to milliseconds + } + + m_advCompCB = advCompleteCB; + int rc = 0; if (!m_customAdvData && !m_advDataSet) { @@ -389,13 +405,13 @@ void NimBLEAdvertising::start() { } #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, + rc = ble_gap_adv_start(0, NULL, duration, &m_advParams, - (pServer != nullptr) ? NimBLEServer::handleGapEvent : NULL, - pServer); + (pServer != nullptr) ? NimBLEServer::handleGapEvent : NimBLEAdvertising::handleGapEvent, + (pServer != nullptr) ? (void*)pServer : (void*)this); #else - rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, - &m_advParams, NULL,NULL); + rc = ble_gap_adv_start(0, NULL, duration, + &m_advParams, NimBLEAdvertising::handleGapEvent, this); #endif if (rc != 0) { NIMBLE_LOGC(LOG_TAG, "Error enabling advertising; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); @@ -421,6 +437,25 @@ void NimBLEAdvertising::stop() { } // stop +/** + * @brief Handles the callback when advertising stops. + */ +void NimBLEAdvertising::advCompleteCB() { + if(m_advCompCB != nullptr) { + m_advCompCB(this); + } +} + + +/** + * @brief Check if currently advertising. + * @return true if advertising is active. + */ +bool NimBLEAdvertising::isAdvertising() { + return ble_gap_adv_active(); +} + + /* * Host reset seems to clear advertising data, * we need clear the flag so it reloads it. @@ -430,6 +465,22 @@ void NimBLEAdvertising::onHostReset() { } +/** + * @brief Handler for gap events when not using peripheral role. + * @param [in] event the event data. + * @param [in] arg pointer to the advertising instance. + */ +/*STATIC*/ +int NimBLEAdvertising::handleGapEvent(struct ble_gap_event *event, void *arg) { + NimBLEAdvertising *pAdv = (NimBLEAdvertising*)arg; + + if(event->type == BLE_GAP_EVENT_ADV_COMPLETE) { + pAdv->advCompleteCB(); + } + return 0; +} + + /** * @brief Add data to the payload to be advertised. * @param [in] data The data to be added to the payload. diff --git a/src/NimBLEAdvertising.h b/src/NimBLEAdvertising.h index a8c86ef..2fab710 100644 --- a/src/NimBLEAdvertising.h +++ b/src/NimBLEAdvertising.h @@ -77,7 +77,7 @@ public: void addServiceUUID(const NimBLEUUID &serviceUUID); void addServiceUUID(const char* serviceUUID); void removeServiceUUID(const NimBLEUUID &serviceUUID); - void start(); + void start(uint32_t duration = 0, void (*advCompleteCB)(NimBLEAdvertising *pAdv) = nullptr); void stop(); void setAppearance(uint16_t appearance); void setAdvertisementType(uint8_t adv_type); @@ -87,20 +87,24 @@ public: void setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly); void setScanResponseData(NimBLEAdvertisementData& advertisementData); void setScanResponse(bool); + void advCompleteCB(); + bool isAdvertising(); private: friend class NimBLEDevice; - void onHostReset(); + void onHostReset(); + static int handleGapEvent(struct ble_gap_event *event, void *arg); - ble_hs_adv_fields m_advData; - ble_hs_adv_fields m_scanData; - ble_gap_adv_params m_advParams; + ble_hs_adv_fields m_advData; + ble_hs_adv_fields m_scanData; + ble_gap_adv_params m_advParams; std::vector m_serviceUUIDs; - bool m_customAdvData = false; // Are we using custom advertising data? - bool m_customScanResponseData = false; // Are we using custom scan response data? - bool m_scanResp = true; - bool m_advDataSet = false; + bool m_customAdvData; + bool m_customScanResponseData; + bool m_scanResp; + bool m_advDataSet; + void (*m_advCompCB)(NimBLEAdvertising *pAdv); }; diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index f4ce6ac..8c75192 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -353,6 +353,12 @@ size_t NimBLEServer::getConnectedCount() { return 0; } // BLE_GAP_EVENT_NOTIFY_TX + case BLE_GAP_EVENT_ADV_COMPLETE: { + NIMBLE_LOGD(LOG_TAG, "Advertising Complete"); + NimBLEDevice::getAdvertising()->advCompleteCB(); + return 0; + } + case BLE_GAP_EVENT_CONN_UPDATE: { NIMBLE_LOGD(LOG_TAG, "Connection parameters updated."); return 0;