Skip to content

Commit

Permalink
Add duration and callback parameter to NimBLEAdvertising::start
Browse files Browse the repository at this point in the history
* Adds functionality to advertise for a set duration, similar to NimBLEScan::start.
The first parameter being the duration (in seconds).
The second parameter is a pointer to a callback function that is invoked when advertising stops.

* NimBLEAdvertising::isAdvertising method added, returns true if advertising is currently active.
  • Loading branch information
h2zero authored Sep 14, 2020
1 parent 1a52245 commit 91b5916
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 15 deletions.
63 changes: 57 additions & 6 deletions src/NimBLEAdvertising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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.
Expand All @@ -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) {
Expand Down Expand Up @@ -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));
Expand All @@ -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.
Expand All @@ -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.
Expand Down
22 changes: 13 additions & 9 deletions src/NimBLEAdvertising.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class NimBLEAdvertising {
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);
Expand All @@ -87,20 +87,24 @@ class NimBLEAdvertising {
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<NimBLEUUID> 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);

};

Expand Down
6 changes: 6 additions & 0 deletions src/NimBLEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 91b5916

Please sign in to comment.