diff --git a/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md b/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md index a76ef59a6..69bb956d7 100644 --- a/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md +++ b/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md @@ -2,6 +2,52 @@ All notable changes to this project will be documented in this file. +## [1.3.1] - 2021-08-04 + +### Fixed +- Corrected a compiler/linker error when an application or a library uses bluetooth classic due to the redefinition of `btInUse`. + +## [1.3.0] - 2021-08-02 + +### Added +- `NimBLECharacteristic::removeDescriptor`: Dynamically remove a descriptor from a characterisic. Takes effect after all connections are closed and sends a service changed indication. +- `NimBLEService::removeCharacteristic`: Dynamically remove a characteristic from a service. Takes effect after all connections are closed and sends a service changed indication +- `NimBLEServerCallbacks::onMTUChange`: This is callback is called when the MTU is updated after connection with a client. +- ESP32C3 support + +- Whitelist API: + - `NimBLEDevice::whiteListAdd`: Add a device to the whitelist. + - `NimBLEDevice::whiteListRemove`: Remove a device from the whitelist. + - `NimBLEDevice::onWhiteList`: Check if the device is on the whitelist. + - `NimBLEDevice::getWhiteListCount`: Gets the size of the whitelist + - `NimBLEDevice::getWhiteListAddress`: Get the address of a device on the whitelist by index value. + +- Bond management API: + - `NimBLEDevice::getNumBonds`: Gets the number of bonds stored. + - `NimBLEDevice::isBonded`: Checks if the device is bonded. + - `NimBLEDevice::deleteAllBonds`: Deletes all bonds. + - `NimBLEDevice::getBondedAddress`: Gets the address of a bonded device by the index value. + +- `NimBLECharacteristic::getCallbacks` to retrieve the current callback handler. +- Connection Information class: `NimBLEConnInfo`. +- `NimBLEScan::clearDuplicateCache`: This can be used to reset the cache of advertised devices so they will be immediately discovered again. + +### Changed +- FreeRTOS files have been removed as they are not used by the library. +- Services, characteristics and descriptors can now be created statically and added after. +- Excess logging and some asserts removed. +- Use ESP_LOGx macros to enable using local log level filtering. + +### Fixed +- `NimBLECharacteristicCallbacks::onSubscribe` Is now called after the connection is added to the vector. +- Corrected bonding failure when reinitializing the BLE stack. +- Writing to a characterisic with a std::string value now correctly writes values with null characters. +- Retrieving remote descriptors now uses the characterisic end handle correctly. +- Missing data in long writes to remote descriptors. +- Hanging on task notification when sending an indication from the characteristic callback. +- BLE controller memory could be released when using Arduino as a component. +- Complile errors with NimBLE release 1.3.0. + ## [1.2.0] - 2021-02-08 ### Added diff --git a/lib/libesp32_div/NimBLE-Arduino/README.md b/lib/libesp32_div/NimBLE-Arduino/README.md index 08e2a69c0..fd480fd83 100644 --- a/lib/libesp32_div/NimBLE-Arduino/README.md +++ b/lib/libesp32_div/NimBLE-Arduino/README.md @@ -72,9 +72,9 @@ such as increasing max connections, default is 3, absolute maximum connections i
# Development Status -This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@f4ae049.](https://github.com/espressif/esp-nimble) +This Library is tracking the esp-nimble repo, nimble-1.3.0-idf master branch, currently [@5bb7b40.](https://github.com/espressif/esp-nimble) -Also tracking the NimBLE related changes in ESP-IDF, master branch, currently [@3caa969.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) +Also tracking the NimBLE related changes in ESP-IDF, master branch, currently [@639e7ad.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble)
# Acknowledgments @@ -82,10 +82,4 @@ Also tracking the NimBLE related changes in ESP-IDF, master branch, currently [@ * [beegee-tokyo](https://github.com/beegee-tokyo) for contributing your time to test/debug and contributing the beacon examples. * [Jeroen88](https://github.com/Jeroen88) for the amazing help debugging and improving the client code.
- -# Todo -- Improve host reset handler -- Implement random address handling -- Implement bond management -- Add Bluetooth Mesh -
+ diff --git a/lib/libesp32_div/NimBLE-Arduino/docs/Migration_guide.md b/lib/libesp32_div/NimBLE-Arduino/docs/Migration_guide.md index 59854e5fd..62406c622 100644 --- a/lib/libesp32_div/NimBLE-Arduino/docs/Migration_guide.md +++ b/lib/libesp32_div/NimBLE-Arduino/docs/Migration_guide.md @@ -69,8 +69,6 @@ For example `BLEServer::createService(SERVICE_UUID)` will work just as it did be ### Characteristics -The constructor for `(Nim)BLECharacteristic` is now private, so if you currently subclass it to add logic you should switch to use `NimBLEService::createCharacteristic` instead. Any custom processing logic previously in a `BLECharacteristic` subclass should be moved to a `NimBLECharacteristicCallbacks` subclass instead, and passed into `NimBLECharacteristic::setCallbacks`. - `BLEService::createCharacteristic` (`NimBLEService::createCharacteristic`) is used the same way as originally except the properties parameter has changed. When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`. diff --git a/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino new file mode 100644 index 000000000..cddbcc91b --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino @@ -0,0 +1,67 @@ +/* + * NimBLE_Scan_Whitelist demo + * + * Created May 16, 2021 + * Author: h2zero + */ + +#include + +int scanTime = 5; //In seconds +NimBLEScan* pBLEScan; + +class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { + void onResult(BLEAdvertisedDevice* advertisedDevice) { + Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); + /* + * Here we add the device scanned to the whitelist based on service data but any + * advertised data can be used for your preffered data. + */ + if (advertisedDevice->haveServiceData()) { + /* If this is a device with data we want to capture, add it to the whitelist */ + if (advertisedDevice->getServiceData(NimBLEUUID("AABB")) != "") { + Serial.printf("Adding %s to whitelist\n", std::string(advertisedDevice->getAddress()).c_str()); + NimBLEDevice::whiteListAdd(advertisedDevice->getAddress()); + } + } + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Scanning..."); + + NimBLEDevice::init(""); + pBLEScan = NimBLEDevice::getScan(); + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(100); + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); + pBLEScan->setWindow(99); +} + +void loop() { + NimBLEScanResults foundDevices = pBLEScan->start(scanTime, false); + Serial.print("Devices found: "); + Serial.println(foundDevices.getCount()); + Serial.println("Scan done!"); + + Serial.println("Whitelist contains:"); + for (auto i=0; i 0) { + if (foundDevices.getCount() == 0) { + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); + } else { + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL); + } + } + pBLEScan->clearResults(); + delay(2000); +} diff --git a/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino index f66169ce8..409ec64d6 100644 --- a/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino +++ b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino @@ -39,6 +39,9 @@ class ServerCallbacks: public NimBLEServerCallbacks { Serial.println("Client disconnected - start advertising"); NimBLEDevice::startAdvertising(); }; + void onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc) { + Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle); + }; /********************* Security handled here ********************** ****** Note: these are the same return values as defaults ********/ diff --git a/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino new file mode 100644 index 000000000..4c7d33549 --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino @@ -0,0 +1,105 @@ +/* + * NimBLE_Server_Whitelist demo + * + * Created May 17, 2021 + * Author: h2zero + */ + +#include + +NimBLECharacteristic* pCharacteristic = nullptr; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint32_t value = 0; + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + + +class MyServerCallbacks: public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer) { + deviceConnected = true; + }; + + void onDisconnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) { + // Peer disconnected, add them to the whitelist + // This allows us to use the whitelist to filter connection attempts + // which will minimize reconnection time. + NimBLEDevice::whiteListAdd(NimBLEAddress(desc->peer_ota_addr)); + deviceConnected = false; + } +}; + +void onAdvComplete(NimBLEAdvertising *pAdvertising) { + Serial.println("Advertising stopped"); + if (deviceConnected) { + return; + } + // If advertising timed out without connection start advertising without whitelist filter + pAdvertising->setScanFilter(false,false); + pAdvertising->start(); +} + + +void setup() { + Serial.begin(115200); + + // Create the BLE Device + NimBLEDevice::init("ESP32"); + + // Create the BLE Server + NimBLEServer* pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + pServer->advertiseOnDisconnect(false); + + // Create the BLE Service + NimBLEService *pService = pServer->createService(SERVICE_UUID); + + // Create a BLE Characteristic + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + NIMBLE_PROPERTY::NOTIFY ); + + // Start the service + pService->start(); + + // Start advertising + NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(false); + pAdvertising->start(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + // notify changed value + if (deviceConnected) { + pCharacteristic->setValue((uint8_t*)&value, 4); + pCharacteristic->notify(); + value++; + } + // disconnecting + if (!deviceConnected && oldDeviceConnected) { + NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + if (NimBLEDevice::getWhiteListCount() > 0) { + // Allow anyone to scan but only whitelisted can connect. + pAdvertising->setScanFilter(false,true); + } + // advertise with whitelist for 30 seconds + pAdvertising->start(30, onAdvComplete); + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + // connecting + if (deviceConnected && !oldDeviceConnected) { + // do stuff here on connecting + oldDeviceConnected = deviceConnected; + } + + delay(2000); +} diff --git a/lib/libesp32_div/NimBLE-Arduino/library.json b/lib/libesp32_div/NimBLE-Arduino/library.json index a56985a06..29cff4dff 100644 --- a/lib/libesp32_div/NimBLE-Arduino/library.json +++ b/lib/libesp32_div/NimBLE-Arduino/library.json @@ -2,7 +2,7 @@ "name": "NimBLE-Arduino", "keywords": "esp32, bluetooth", "description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE", - "version": "1.2.0", + "version": "1.3.1", "frameworks": "arduino", "platforms": "espressif32" } diff --git a/lib/libesp32_div/NimBLE-Arduino/library.properties b/lib/libesp32_div/NimBLE-Arduino/library.properties index 4435958d1..b08519454 100644 --- a/lib/libesp32_div/NimBLE-Arduino/library.properties +++ b/lib/libesp32_div/NimBLE-Arduino/library.properties @@ -1,5 +1,5 @@ name=NimBLE-Arduino -version=1.2.0 +version=1.3.1 author=h2zero maintainer=h2zero sentence=Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.cpp b/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.cpp deleted file mode 100644 index 1c398cbf3..000000000 --- a/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - * FreeRTOS.cpp - * - * Created on: Feb 24, 2017 - * Author: kolban - */ -#include "sdkconfig.h" -#include "FreeRTOS.h" -#include "NimBLELog.h" - -#include // Include the base FreeRTOS definitions -#include // Include the task definitions -#include // Include the semaphore definitions -#include - -static const char* LOG_TAG = "FreeRTOS"; - - -/** - * Sleep for the specified number of milliseconds. - * @param[in] ms The period in milliseconds for which to sleep. - */ -void FreeRTOS::sleep(uint32_t ms) { - ::vTaskDelay(ms / portTICK_PERIOD_MS); -} // sleep - - -/** - * Start a new task. - * @param[in] task The function pointer to the function to be run in the task. - * @param[in] taskName A string identifier for the task. - * @param[in] param An optional parameter to be passed to the started task. - * @param[in] stackSize An optional paremeter supplying the size of the stack in which to run the task. - */ -void FreeRTOS::startTask(void task(void*), std::string taskName, void* param, uint32_t stackSize) { - ::xTaskCreate(task, taskName.data(), stackSize, param, 5, NULL); -} // startTask - - -/** - * Delete the task. - * @param[in] pTask An optional handle to the task to be deleted. If not supplied the calling task will be deleted. - */ -void FreeRTOS::deleteTask(TaskHandle_t pTask) { - ::vTaskDelete(pTask); -} // deleteTask - - -/** - * Get the time in milliseconds since the %FreeRTOS scheduler started. - * @return The time in milliseconds since the %FreeRTOS scheduler started. - */ -uint32_t FreeRTOS::getTimeSinceStart() { - return (uint32_t) (xTaskGetTickCount() * portTICK_PERIOD_MS); -} // getTimeSinceStart - - -/** - * @brief Wait for a semaphore to be released by trying to take it and - * then releasing it again. - * @param [in] owner A debug tag. - * @return The value associated with the semaphore. - */ -uint32_t FreeRTOS::Semaphore::wait(std::string owner) { - NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); - - if (m_usePthreads) { - pthread_mutex_lock(&m_pthread_mutex); - } else { - xSemaphoreTake(m_semaphore, portMAX_DELAY); - } - - if (m_usePthreads) { - pthread_mutex_unlock(&m_pthread_mutex); - } else { - xSemaphoreGive(m_semaphore); - } - - NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore released: %s", toString().c_str()); - return m_value; -} // wait - - -/** - * @brief Wait for a semaphore to be released in a given period of time by trying to take it and - * then releasing it again. The value associated with the semaphore can be taken by value() call after return - * @param [in] owner A debug tag. - * @param [in] timeoutMs timeout to wait in ms. - * @return True if we took the semaphore within timeframe. - */ -bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) { - NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); - - if (m_usePthreads && timeoutMs != portMAX_DELAY) { - assert(false); // We apparently don't have a timed wait for pthreads. - } - - auto ret = pdTRUE; - - if (m_usePthreads) { - pthread_mutex_lock(&m_pthread_mutex); - } else { - ret = xSemaphoreTake(m_semaphore, timeoutMs); - } - - if (m_usePthreads) { - pthread_mutex_unlock(&m_pthread_mutex); - } else { - xSemaphoreGive(m_semaphore); - } - - NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret); - return ret; -} // wait - - -/** - * @brief Construct a semaphore, the semaphore is given when created. - * @param [in] name A name string to provide debugging support. - */ -FreeRTOS::Semaphore::Semaphore(std::string name) { - m_usePthreads = false; // Are we using pThreads or FreeRTOS? - if (m_usePthreads) { - pthread_mutex_init(&m_pthread_mutex, nullptr); - } else { - //m_semaphore = xSemaphoreCreateMutex(); - m_semaphore = xSemaphoreCreateBinary(); - xSemaphoreGive(m_semaphore); - } - - m_name = name; - m_owner = std::string(""); - m_value = 0; -} - - -FreeRTOS::Semaphore::~Semaphore() { - if (m_usePthreads) { - pthread_mutex_destroy(&m_pthread_mutex); - } else { - vSemaphoreDelete(m_semaphore); - } -} - - -/** - * @brief Give the semaphore. - */ -void FreeRTOS::Semaphore::give() { - NIMBLE_LOGD(LOG_TAG, "Semaphore giving: %s", toString().c_str()); - m_owner = std::string(""); - - if (m_usePthreads) { - pthread_mutex_unlock(&m_pthread_mutex); - } else { - xSemaphoreGive(m_semaphore); - } -// #ifdef ARDUINO_ARCH_ESP32 -// FreeRTOS::sleep(10); -// #endif - -} // Semaphore::give - - -/** - * @brief Give a semaphore. - * The Semaphore is given with an associated value. - * @param [in] value The value to associate with the semaphore. - */ -void FreeRTOS::Semaphore::give(uint32_t value) { - m_value = value; - give(); -} // give - - -/** - * @brief Give a semaphore from an ISR. - */ -void FreeRTOS::Semaphore::giveFromISR() { - BaseType_t higherPriorityTaskWoken; - if (m_usePthreads) { - assert(false); - } else { - xSemaphoreGiveFromISR(m_semaphore, &higherPriorityTaskWoken); - } -} // giveFromISR - - -/** - * @brief Take a semaphore. - * Take a semaphore and wait indefinitely. - * @param [in] owner The new owner (for debugging) - * @return True if we took the semaphore. - */ -bool FreeRTOS::Semaphore::take(std::string owner) { - NIMBLE_LOGD(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); - bool rc = false; - if (m_usePthreads) { - pthread_mutex_lock(&m_pthread_mutex); - } else { - rc = ::xSemaphoreTake(m_semaphore, portMAX_DELAY) == pdTRUE; - } - m_owner = owner; - if (rc) { - NIMBLE_LOGD(LOG_TAG, "Semaphore taken: %s", toString().c_str()); - } else { - NIMBLE_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str()); - } - return rc; -} // Semaphore::take - - -/** - * @brief Take a semaphore. - * Take a semaphore but return if we haven't obtained it in the given period of milliseconds. - * @param [in] timeoutMs Timeout in milliseconds. - * @param [in] owner The new owner (for debugging) - * @return True if we took the semaphore. - */ -bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) { - NIMBLE_LOGD(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); - bool rc = false; - if (m_usePthreads) { - assert(false); // We apparently don't have a timed wait for pthreads. - } else { - rc = ::xSemaphoreTake(m_semaphore, timeoutMs / portTICK_PERIOD_MS) == pdTRUE; - } - m_owner = owner; - if (rc) { - NIMBLE_LOGD(LOG_TAG, "Semaphore taken: %s", toString().c_str()); - } else { - NIMBLE_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str()); - } - return rc; -} // Semaphore::take - - - -/** - * @brief Create a string representation of the semaphore. - * @return A string representation of the semaphore. - */ -std::string FreeRTOS::Semaphore::toString() { - char hex[9]; - std::string res = "name: " + m_name + " (0x"; - snprintf(hex, sizeof(hex), "%08x", (uint32_t)m_semaphore); - res += hex; - res += "), owner: " + m_owner; - return res; -} // toString - - -/** - * @brief Set the name of the semaphore. - * @param [in] name The name of the semaphore. - */ -void FreeRTOS::Semaphore::setName(std::string name) { - m_name = name; -} // setName - - -/** - * @brief Create a ring buffer. - * @param [in] length The amount of storage to allocate for the ring buffer. - * @param [in] type The type of buffer. One of RINGBUF_TYPE_NOSPLIT, RINGBUF_TYPE_ALLOWSPLIT, RINGBUF_TYPE_BYTEBUF. - */ -#ifdef ESP_IDF_VERSION //Quick hack to detect if using IDF version that replaced ringbuf_type_t -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) - Ringbuffer::Ringbuffer(size_t length, RingbufferType_t type) { -#else - Ringbuffer::Ringbuffer(size_t length, ringbuf_type_t type) { -#endif -#else - Ringbuffer::Ringbuffer(size_t length, ringbuf_type_t type) { -#endif - m_handle = ::xRingbufferCreate(length, type); -} // Ringbuffer - - -Ringbuffer::~Ringbuffer() { - ::vRingbufferDelete(m_handle); -} // ~Ringbuffer - - -/** - * @brief Receive data from the buffer. - * @param [out] size On return, the size of data returned. - * @param [in] wait How long to wait. - * @return A pointer to the storage retrieved. - */ -void* Ringbuffer::receive(size_t* size, TickType_t wait) { - return ::xRingbufferReceive(m_handle, size, wait); -} // receive - - -/** - * @brief Return an item. - * @param [in] item The item to be returned/released. - */ -void Ringbuffer::returnItem(void* item) { - ::vRingbufferReturnItem(m_handle, item); -} // returnItem - - -/** - * @brief Send data to the buffer. - * @param [in] data The data to place into the buffer. - * @param [in] length The length of data to place into the buffer. - * @param [in] wait How long to wait before giving up. The default is to wait indefinitely. - * @return - */ -bool Ringbuffer::send(void* data, size_t length, TickType_t wait) { - return ::xRingbufferSend(m_handle, data, length, wait) == pdTRUE; -} // send - - diff --git a/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.h b/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.h deleted file mode 100644 index fa33921fe..000000000 --- a/lib/libesp32_div/NimBLE-Arduino/src/FreeRTOS.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * FreeRTOS.h - * - * Created on: Feb 24, 2017 - * Author: kolban - */ - -#ifndef MAIN_FREERTOS_H_ -#define MAIN_FREERTOS_H_ - -#include // Include the base FreeRTOS definitions. -#include // Include the task definitions. -#include // Include the semaphore definitions. -#include // Include the ringbuffer definitions. - -#include -#include -#include - - -/** - * @brief Interface to %FreeRTOS functions. - */ -class FreeRTOS { -public: - static void sleep(uint32_t ms); - static void startTask(void task(void*), std::string taskName, void* param = nullptr, uint32_t stackSize = 2048); - static void deleteTask(TaskHandle_t pTask = nullptr); - - static uint32_t getTimeSinceStart(); - -/** - * @brief A binary semaphore class that operates like a mutex, it is already given when constructed. - */ - class Semaphore { - public: - Semaphore(std::string owner = ""); - ~Semaphore(); - void give(); - void give(uint32_t value); - void giveFromISR(); - void setName(std::string name); - bool take(std::string owner = ""); - bool take(uint32_t timeoutMs, std::string owner = ""); - std::string toString(); - bool timedWait(std::string owner = "", uint32_t timeoutMs = portMAX_DELAY); - uint32_t wait(std::string owner = ""); - /** - * @brief Get the value of the semaphore. - * @return The value stored if the semaphore was given with give(value); - */ - uint32_t value(){ return m_value; }; - - private: - SemaphoreHandle_t m_semaphore; - pthread_mutex_t m_pthread_mutex; - std::string m_name; - std::string m_owner; - uint32_t m_value; - bool m_usePthreads; - - }; -}; - - -/** - * @brief A wrapper class for a freeRTOS ringbuffer. - */ -class Ringbuffer { -public: -#ifdef ESP_IDF_VERSION //Quick hack to detect if using IDF version that replaced ringbuf_type_t -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) - Ringbuffer(size_t length, RingbufferType_t type = RINGBUF_TYPE_NOSPLIT); -#else - Ringbuffer(size_t length, ringbuf_type_t type = RINGBUF_TYPE_NOSPLIT); -#endif -#else - Ringbuffer(size_t length, ringbuf_type_t type = RINGBUF_TYPE_NOSPLIT); -#endif - ~Ringbuffer(); - - void* receive(size_t* size, TickType_t wait = portMAX_DELAY); - void returnItem(void* item); - bool send(void* data, size_t length, TickType_t wait = portMAX_DELAY); -private: - RingbufHandle_t m_handle; -}; - -#endif /* MAIN_FREERTOS_H_ */ diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLE2904.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLE2904.h index 0a6d036a4..d8800dd2f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLE2904.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLE2904.h @@ -42,6 +42,7 @@ struct BLE2904_Data { */ class NimBLE2904: public NimBLEDescriptor { public: + NimBLE2904(NimBLECharacteristic* pCharacterisitic = nullptr); static const uint8_t FORMAT_BOOLEAN = 1; static const uint8_t FORMAT_UINT2 = 2; static const uint8_t FORMAT_UINT4 = 3; @@ -77,7 +78,6 @@ public: void setUnit(uint16_t unit); private: - NimBLE2904(NimBLECharacteristic* pCharacterisitic); friend class NimBLECharacteristic; BLE2904_Data m_data; }; // BLE2904 diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp index c697fe752..ecfd49814 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp @@ -734,7 +734,7 @@ uint8_t* NimBLEAdvertisedDevice::getPayload() { * @param [in] length The length of the payload in bytes. * @param [in] append Indicates if the the data should be appended (scan response). */ -void NimBLEAdvertisedDevice::setPayload(uint8_t *payload, uint8_t length, bool append) { +void NimBLEAdvertisedDevice::setPayload(const uint8_t *payload, uint8_t length, bool append) { if(!append) { m_advLength = length; m_payload.assign(payload, payload + length); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h index ef354bc41..7d378ed0f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h @@ -137,7 +137,7 @@ private: void setAddress(NimBLEAddress address); void setAdvType(uint8_t advType); - void setPayload(uint8_t *payload, uint8_t length, bool append); + void setPayload(const uint8_t *payload, uint8_t length, bool append); void setRSSI(int rssi); uint8_t findAdvField(uint8_t type, uint8_t index = 0, uint8_t *data_loc = nullptr); uint8_t findServiceData(uint8_t index, uint8_t* bytes); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertising.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertising.cpp index 3e9ae4a64..3112efff0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertising.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEAdvertising.cpp @@ -383,6 +383,7 @@ 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. + * @return True if advertising started successfully. */ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdvertising *pAdv)) { NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", @@ -471,16 +472,14 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv } payloadLen += add; - if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16, + if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc((void*)m_advData.uuids16, (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) { NIMBLE_LOGC(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids16[m_advData.num_uuids16].value, - &it.getNative()->u16.value, 2); - - m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16; + memcpy((void*)&m_advData.uuids16[m_advData.num_uuids16], + &it.getNative()->u16, sizeof(ble_uuid16_t)); m_advData.uuids16_is_complete = 1; m_advData.num_uuids16++; } @@ -492,16 +491,14 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv } payloadLen += add; - if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc(m_advData.uuids32, + if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc((void*)m_advData.uuids32, (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) { NIMBLE_LOGC(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids32[m_advData.num_uuids32].value, - &it.getNative()->u32.value, 4); - - m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; + memcpy((void*)&m_advData.uuids32[m_advData.num_uuids32], + &it.getNative()->u32, sizeof(ble_uuid32_t)); m_advData.uuids32_is_complete = 1; m_advData.num_uuids32++; } @@ -513,16 +510,14 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv } payloadLen += add; - if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128, + if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc((void*)m_advData.uuids128, (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) { NIMBLE_LOGC(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids128[m_advData.num_uuids128].value, - &it.getNative()->u128.value, 16); - - m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; + memcpy((void*)&m_advData.uuids128[m_advData.num_uuids128], + &it.getNative()->u128, sizeof(ble_uuid128_t)); m_advData.uuids128_is_complete = 1; m_advData.num_uuids128++; } @@ -599,19 +594,19 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv } if(m_advData.num_uuids128 > 0) { - free(m_advData.uuids128); + free((void*)m_advData.uuids128); m_advData.uuids128 = nullptr; m_advData.num_uuids128 = 0; } if(m_advData.num_uuids32 > 0) { - free(m_advData.uuids32); + free((void*)m_advData.uuids32); m_advData.uuids32 = nullptr; m_advData.num_uuids32 = 0; } if(m_advData.num_uuids16 > 0) { - free(m_advData.uuids16); + free((void*)m_advData.uuids16); m_advData.uuids16 = nullptr; m_advData.num_uuids16 = 0; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.cpp index 0ffa9fb03..f3965a4dc 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.cpp @@ -45,15 +45,15 @@ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties * @param [in] pService - pointer to the service instance this characteristic belongs to. */ NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) { - m_uuid = uuid; - m_handle = NULL_HANDLE; - m_properties = properties; - m_pCallbacks = &defaultCallback; - m_pService = pService; - m_value = ""; - m_valMux = portMUX_INITIALIZER_UNLOCKED; - m_pTaskData = nullptr; - m_timestamp = 0; + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_properties = properties; + m_pCallbacks = &defaultCallback; + m_pService = pService; + m_value = ""; + m_valMux = portMUX_INITIALIZER_UNLOCKED; + m_timestamp = 0; + m_removed = 0; } // NimBLECharacteristic /** @@ -95,9 +95,62 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); } - m_dscVec.push_back(pDescriptor); + addDescriptor(pDescriptor); return pDescriptor; -} // createCharacteristic +} // createDescriptor + + +/** + * @brief Add a descriptor to the characteristic. + * @param [in] pDescriptor A pointer to the descriptor to add. + */ +void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) { + bool foundRemoved = false; + + if(pDescriptor->m_removed > 0) { + for(auto& it : m_dscVec) { + if(it == pDescriptor) { + foundRemoved = true; + pDescriptor->m_removed = 0; + } + } + } + + if(!foundRemoved) { + m_dscVec.push_back(pDescriptor); + } + + pDescriptor->setCharacteristic(this); + NimBLEDevice::getServer()->serviceChanged(); +} + + +/** + * @brief Remove a descriptor from the characterisitc. + * @param[in] pDescriptor A pointer to the descriptor instance to remove from the characterisitc. + * @param[in] deleteDsc If true it will delete the descriptor instance and free it's resources. + */ +void NimBLECharacteristic::removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc) { + // Check if the descriptor was already removed and if so, check if this + // is being called to delete the object and do so if requested. + // Otherwise, ignore the call and return. + if(pDescriptor->m_removed > 0) { + if(deleteDsc) { + for(auto it = m_dscVec.begin(); it != m_dscVec.end(); ++it) { + if ((*it) == pDescriptor) { + delete *it; + m_dscVec.erase(it); + break; + } + } + } + + return; + } + + pDescriptor->m_removed = deleteDsc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE; + NimBLEDevice::getServer()->serviceChanged(); +} // removeDescriptor /** @@ -165,6 +218,11 @@ NimBLEService* NimBLECharacteristic::getService() { } // getService +void NimBLECharacteristic::setService(NimBLEService *pService) { + m_pService = pService; +} + + /** * @brief Get the UUID of the characteristic. * @return The UUID of the characteristic. @@ -301,16 +359,13 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { subVal |= NIMBLE_SUB_INDICATE; } - if(m_pTaskData != nullptr) { - m_pTaskData->rc = (subVal & NIMBLE_SUB_INDICATE) ? 0 : - NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED; - xTaskNotifyGive(m_pTaskData->task); - } - NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", - event->subscribe.conn_handle, subVal); + event->subscribe.conn_handle, subVal); + + if(!event->subscribe.cur_indicate && event->subscribe.prev_indicate) { + NimBLEDevice::getServer()->clearIndicateWait(event->subscribe.conn_handle); + } - m_pCallbacks->onSubscribe(this, &desc, subVal); auto it = m_subscribedVec.begin(); for(;it != m_subscribedVec.end(); ++it) { @@ -322,16 +377,14 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { if(subVal > 0) { if(it == m_subscribedVec.end()) { m_subscribedVec.push_back({event->subscribe.conn_handle, subVal}); - return; + } else { + (*it).second = subVal; } - - (*it).second = subVal; - } else if(it != m_subscribedVec.end()) { m_subscribedVec.erase(it); - m_subscribedVec.shrink_to_fit(); } - + + m_pCallbacks->onSubscribe(this, &desc, subVal); } @@ -416,40 +469,20 @@ void NimBLECharacteristic::notify(bool is_notification) { // We also must create it in each loop iteration because it is consumed with each host call. os_mbuf *om = ble_hs_mbuf_from_flat((uint8_t*)value.data(), length); - NimBLECharacteristicCallbacks::Status statusRC; - if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) { - ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr}; - m_pTaskData = &taskData; + if(!NimBLEDevice::getServer()->setIndicateWait(it.first)) { + NIMBLE_LOGE(LOG_TAG, "prior Indication in progress"); + os_mbuf_free_chain(om); + return; + } rc = ble_gattc_indicate_custom(it.first, m_handle, om); if(rc != 0){ - statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; - } else { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - rc = m_pTaskData->rc; - } - - m_pTaskData = nullptr; - - if(rc == BLE_HS_EDONE) { - rc = 0; - statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_INDICATE; - } else if(rc == BLE_HS_ETIMEOUT) { - statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT; - } else { - statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE; + NimBLEDevice::getServer()->clearIndicateWait(it.first); } } else { - rc = ble_gattc_notify_custom(it.first, m_handle, om); - if(rc == 0) { - statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY; - } else { - statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; - } + ble_gattc_notify_custom(it.first, m_handle, om); } - - m_pCallbacks->onStatus(this, statusRC, rc); } NIMBLE_LOGD(LOG_TAG, "<< notify"); @@ -469,6 +502,13 @@ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallback } } // setCallbacks +/** + * @brief Get the callback handlers for this characteristic. + */ +NimBLECharacteristicCallbacks* NimBLECharacteristic::getCallbacks() { + return m_pCallbacks; +} //getCallbacks + /** * @brief Set the value of the characteristic. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.h index 9bb9d079b..6008d127f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLECharacteristic.h @@ -59,12 +59,26 @@ class NimBLECharacteristicCallbacks; */ class NimBLECharacteristic { public: + NimBLECharacteristic(const char* uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + NimBLECharacteristic(const NimBLEUUID &uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + + ~NimBLECharacteristic(); uint16_t getHandle(); NimBLEUUID getUUID(); std::string toString(); void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); + NimBLECharacteristicCallbacks* + getCallbacks(); void indicate(); void notify(bool is_notification = true); @@ -81,9 +95,11 @@ public: NIMBLE_PROPERTY::WRITE, uint16_t max_len = 100); + void addDescriptor(NimBLEDescriptor *pDescriptor); NimBLEDescriptor* getDescriptorByUUID(const char* uuid); NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid); NimBLEDescriptor* getDescriptorByHandle(uint16_t handle); + void removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc = false); std::string getValue(time_t *timestamp = nullptr); size_t getDataLength(); @@ -115,30 +131,15 @@ public: setValue((uint8_t*)&s, sizeof(T)); } - - - + NimBLEService* getService(); + uint16_t getProperties(); private: - friend class NimBLEServer; - friend class NimBLEService; + friend class NimBLEServer; + friend class NimBLEService; - NimBLECharacteristic(const char* uuid, - uint16_t properties = - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - NimBLECharacteristic(const NimBLEUUID &uuid, - uint16_t properties = - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - - ~NimBLECharacteristic(); - - NimBLEService* getService(); - uint16_t getProperties(); + void setService(NimBLEService *pService); void setSubscribe(struct ble_gap_event *event); static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); @@ -150,9 +151,9 @@ private: NimBLEService* m_pService; std::string m_value; std::vector m_dscVec; - ble_task_data_t *m_pTaskData; portMUX_TYPE m_valMux; time_t m_timestamp; + uint8_t m_removed; std::vector> m_subscribedVec; }; // NimBLECharacteristic diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp index ddeb1de70..a171b8cc0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp @@ -436,6 +436,24 @@ void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, } // updateConnParams +/** + * @brief Get detailed information about the current peer connection. + */ +NimBLEConnInfo NimBLEClient::getConnInfo() { + NimBLEConnInfo connInfo; + if (!isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Not connected"); + } else { + int rc = ble_gap_conn_find(m_conn_id, &connInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Connection info not found"); + } + } + + return connInfo; +} // getConnInfo + + /** * @brief Set the timeout to wait for connection attempt to complete. * @param [in] time The number of seconds before timeout. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.h index a4b847000..d90086c4a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.h @@ -23,6 +23,7 @@ #include "NimBLEAddress.h" #include "NimBLEUUID.h" #include "NimBLEUtils.h" +#include "NimBLEConnInfo.h" #include "NimBLEAdvertisedDevice.h" #include "NimBLERemoteService.h" @@ -71,6 +72,7 @@ public: void updateConnParams(uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout); void discoverAttributes(); + NimBLEConnInfo getConnInfo(); private: NimBLEClient(const NimBLEAddress &peerAddress); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEConnInfo.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEConnInfo.h new file mode 100644 index 000000000..e357d8cbc --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEConnInfo.h @@ -0,0 +1,55 @@ +#ifndef NIMBLECONNINFO_H_ +#define NIMBLECONNINFO_H_ + +#include "NimBLEAddress.h" + +/** + * @brief Connection information. + */ +class NimBLEConnInfo { +friend class NimBLEServer; +friend class NimBLEClient; + ble_gap_conn_desc m_desc; + NimBLEConnInfo() { m_desc = {}; } + NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; } +public: + /** @brief Gets the over-the-air address of the connected peer */ + NimBLEAddress getAddress() { return NimBLEAddress(m_desc.peer_ota_addr); } + + /** @brief Gets the ID address of the connected peer */ + NimBLEAddress getIdAddress() { return NimBLEAddress(m_desc.peer_id_addr); } + + /** @brief Gets the connection handle of the connected peer */ + uint16_t getConnHandle() { return m_desc.conn_handle; } + + /** @brief Gets the connection interval for this connection (in 1.25ms units) */ + uint16_t getConnInterval() { return m_desc.conn_itvl; } + + /** @brief Gets the supervision timeout for this connection (in 10ms units) */ + uint16_t getConnTimeout() { return m_desc.supervision_timeout; } + + /** @brief Gets the allowable latency for this connection (unit = number of intervals) */ + uint16_t getConnLatency() { return m_desc.conn_latency; } + + /** @brief Gets the maximum transmission unit size for this connection (in bytes) */ + uint16_t getMTU() { return ble_att_mtu(m_desc.conn_handle); } + + /** @brief Check if we are in the master role in this connection */ + bool isMaster() { return (m_desc.role == BLE_GAP_ROLE_MASTER); } + + /** @brief Check if we are in the slave role in this connection */ + bool isSlave() { return (m_desc.role == BLE_GAP_ROLE_SLAVE); } + + /** @brief Check if we are connected to a bonded peer */ + bool isBonded() { return (m_desc.sec_state.bonded == 1); } + + /** @brief Check if the connection in encrypted */ + bool isEncrypted() { return (m_desc.sec_state.encrypted == 1); } + + /** @brief Check if the the connection has been authenticated */ + bool isAuthenticated() { return (m_desc.sec_state.authenticated == 1); } + + /** @brief Gets the key size used to encrypt the connection */ + uint8_t getSecKeySize() { return m_desc.sec_state.key_size; } +}; +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.cpp index 95c3291f3..f94676607 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.cpp @@ -37,6 +37,7 @@ NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16 : NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) { } + /** * @brief NimBLEDescriptor constructor. */ @@ -47,11 +48,12 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_ m_value.attr_len = 0; // Initial length is 0. m_value.attr_max_len = max_len; // Maximum length of the data. m_handle = NULL_HANDLE; // Handle is initially unknown. - m_pCharacteristic = nullptr; // No initial characteristic. + m_pCharacteristic = pCharacteristic; m_pCallbacks = &defaultCallbacks; // No initial callback. m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value. m_valMux = portMUX_INITIALIZER_UNLOCKED; m_properties = 0; + m_removed = 0; if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t m_properties |= BLE_ATT_F_READ; @@ -122,6 +124,7 @@ uint8_t* NimBLEDescriptor::getValue() { return m_value.attr_value; } // getValue + /** * @brief Get the value of this descriptor as a string. * @return A std::string instance containing a copy of the descriptor's value. @@ -130,9 +133,18 @@ std::string NimBLEDescriptor::getStringValue() { return std::string((char *) m_value.attr_value, m_value.attr_len); } + +/** + * @brief Get the characteristic this descriptor belongs to. + * @return A pointer to the characteristic this descriptor belongs to. + */ +NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() { + return m_pCharacteristic; +} // getCharacteristic + + int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) { + struct ble_gatt_access_ctxt *ctxt, void *arg) { const ble_uuid_t *uuid; int rc; NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; @@ -169,7 +181,7 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, if((len + next->om_len) > pDescriptor->m_value.attr_max_len) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - memcpy(&buf[len-1], next->om_data, next->om_len); + memcpy(&buf[len], next->om_data, next->om_len); len += next->om_len; next = SLIST_NEXT(next, om_next); } @@ -237,6 +249,14 @@ void NimBLEDescriptor::setValue(const std::string &value) { setValue((uint8_t*) value.data(), value.length()); } // setValue +/** + * @brief Set the characteristic this descriptor belongs to. + * @param [in] pChar A pointer to the characteristic this descriptior belongs to. + */ +void NimBLEDescriptor::setCharacteristic(NimBLECharacteristic* pChar) { + m_pCharacteristic = pChar; +} // setCharacteristic + /** * @brief Return a string representation of the descriptor. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.h index 76318b729..5dc0ce89b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDescriptor.h @@ -43,46 +43,48 @@ class NimBLEDescriptorCallbacks; */ class NimBLEDescriptor { public: - uint16_t getHandle(); - NimBLEUUID getUUID(); - std::string toString(); + NimBLEDescriptor(const char* uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic = nullptr); - void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic = nullptr); - size_t getLength(); - uint8_t* getValue(); - std::string getStringValue(); + ~NimBLEDescriptor(); + + uint16_t getHandle(); + NimBLEUUID getUUID(); + std::string toString(); + + void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + + size_t getLength(); + uint8_t* getValue(); + std::string getStringValue(); + + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + NimBLECharacteristic* getCharacteristic(); - void setValue(const uint8_t* data, size_t size); - void setValue(const std::string &value); /** * @brief Convenience template to set the descriptor value to val. * @param [in] s The value to set. */ template - void setValue(const T &s) { + void setValue(const T &s) { setValue((uint8_t*)&s, sizeof(T)); } private: friend class NimBLECharacteristic; friend class NimBLEService; - friend class NimBLE2902; friend class NimBLE2904; - NimBLEDescriptor(const char* uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - ~NimBLEDescriptor(); - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); void setHandle(uint16_t handle); + void setCharacteristic(NimBLECharacteristic* pChar); NimBLEUUID m_uuid; uint16_t m_handle; @@ -91,6 +93,7 @@ private: uint8_t m_properties; attr_value_t m_value; portMUX_TYPE m_valMux; + uint8_t m_removed; }; // NimBLEDescriptor diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp index dc9caf3d5..bc253659a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -30,7 +30,7 @@ #include "services/gap/ble_svc_gap.h" #include "services/gatt/ble_svc_gatt.h" -#ifdef ARDUINO_ARCH_ESP32 +#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS #include "esp32-hal-bt.h" #endif @@ -60,6 +60,7 @@ ble_gap_event_listener NimBLEDevice::m_listener; std::list NimBLEDevice::m_cList; #endif std::list NimBLEDevice::m_ignoreList; +std::vector NimBLEDevice::m_whiteList; NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr; uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC; uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE; @@ -448,6 +449,211 @@ void NimBLEDevice::setScanFilterMode(uint8_t mode) { m_scanFilterMode = mode; } +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +/** + * @brief Gets the number of bonded peers stored + */ +/*STATIC*/ +int NimBLEDevice::getNumBonds() { + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + int num_peers, rc; + + rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + if (rc !=0) { + return 0; + } + + return num_peers; +} + + +/** + * @brief Deletes all bonding information. + */ + /*STATIC*/ +void NimBLEDevice::deleteAllBonds() { + ble_store_clear(); +} + + +/** + * @brief Deletes a peer bond. + * @param [in] address The address of the peer with which to delete bond info. + * @returns true on success. + */ +/*STATIC*/ +bool NimBLEDevice::deleteBond(const NimBLEAddress &address) { + ble_addr_t delAddr; + memcpy(&delAddr.val, address.getNative(),6); + delAddr.type = address.getType(); + + int rc = ble_gap_unpair(&delAddr); + if (rc != 0) { + return false; + } + + return true; +} + + +/** + * @brief Checks if a peer device is bonded. + * @param [in] address The address to check for bonding. + * @returns true if bonded. + */ +/*STATIC*/ +bool NimBLEDevice::isBonded(const NimBLEAddress &address) { + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + int num_peers, rc; + + rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + if (rc != 0) { + return false; + } + + for (int i = 0; i < num_peers; i++) { + NimBLEAddress storedAddr(peer_id_addrs[i]); + if(storedAddr == address) { + return true; + } + } + + return false; +} + + +/** + * @brief Get the address of a bonded peer device by index. + * @param [in] index The index to retrieve the peer address of. + * @returns NimBLEAddress of the found bonded peer or nullptr if not found. + */ +/*STATIC*/ +NimBLEAddress NimBLEDevice::getBondedAddress(int index) { + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + int num_peers, rc; + + rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + if (rc != 0) { + return nullptr; + } + + if (index > num_peers || index < 0) { + return nullptr; + } + + return NimBLEAddress(peer_id_addrs[index]); +} +#endif + +/** + * @brief Checks if a peer device is whitelisted. + * @param [in] address The address to check for in the whitelist. + * @returns true if the address is in the whitelist. + */ +bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) { + for (auto &it : m_whiteList) { + if (it == address) { + return true; + } + } + + return false; +} + + +/** + * @brief Add a peer address to the whitelist. + * @param [in] address The address to add to the whitelist. + * @returns true if successful. + */ +bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) { + if (NimBLEDevice::onWhiteList(address)) { + return true; + } + + m_whiteList.push_back(address); + std::vector wlVec; + wlVec.reserve(m_whiteList.size()); + + for (auto &it : m_whiteList) { + ble_addr_t wlAddr; + memcpy(&wlAddr.val, it.getNative(), 6); + wlAddr.type = it.getType(); + wlVec.push_back(wlAddr); + } + + int rc = ble_gap_wl_set(&wlVec[0], wlVec.size()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed adding to whitelist rc=%d", rc); + return false; + } + + return true; +} + + +/** + * @brief Remove a peer address from the whitelist. + * @param [in] address The address to remove from the whitelist. + * @returns true if successful. + */ +bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) { + if (!NimBLEDevice::onWhiteList(address)) { + return true; + } + + std::vector wlVec; + wlVec.reserve(m_whiteList.size()); + + for (auto &it : m_whiteList) { + if (it != address) { + ble_addr_t wlAddr; + memcpy(&wlAddr.val, it.getNative(), 6); + wlAddr.type = it.getType(); + wlVec.push_back(wlAddr); + } + } + + int rc = ble_gap_wl_set(&wlVec[0], wlVec.size()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed removing from whitelist rc=%d", rc); + return false; + } + + // Don't remove from the list unless NimBLE returned success + for (auto it = m_whiteList.begin(); it < m_whiteList.end(); ++it) { + if ((*it) == address) { + m_whiteList.erase(it); + break; + } + } + + return true; +} + + +/** + * @brief Gets the count of addresses in the whitelist. + * @returns The number of addresses in the whitelist. + */ +size_t NimBLEDevice::getWhiteListCount() { + return m_whiteList.size(); +} + + +/** + * @brief Gets the address at the vector index. + * @param [in] index The vector index to retrieve the address from. + * @returns the NimBLEAddress at the whitelist index or nullptr if not found. + */ +NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) { + if (index > m_whiteList.size()) { + NIMBLE_LOGE(LOG_TAG, "Invalid index; %u", index); + return nullptr; + } + return m_whiteList[index]; +} + /** * @brief Host reset, we pass the message so we don't make calls until resynced. @@ -534,7 +740,7 @@ void NimBLEDevice::setScanFilterMode(uint8_t mode) { int rc=0; esp_err_t errRc = ESP_OK; -#ifdef ARDUINO_ARCH_ESP32 +#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS // make sure the linker includes esp32-hal-bt.c so ardruino init doesn't release BLE memory. btStarted(); #endif @@ -551,8 +757,12 @@ void NimBLEDevice::setScanFilterMode(uint8_t mode) { esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +#ifdef CONFIG_IDF_TARGET_ESP32C3 + bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE; +#else bt_cfg.mode = ESP_BT_MODE_BLE; bt_cfg.ble_max_conn = CONFIG_BT_NIMBLE_MAX_CONNECTIONS; +#endif bt_cfg.normal_adv_size = m_scanDuplicateSize; bt_cfg.scan_duplicate_type = m_scanFilterMode; @@ -771,17 +981,23 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) { m_own_addr_type = own_addr_type; switch (own_addr_type) { +#ifdef CONFIG_IDF_TARGET_ESP32 case BLE_OWN_ADDR_PUBLIC: ble_hs_pvcy_rpa_config(NIMBLE_HOST_DISABLE_PRIVACY); break; +#endif case BLE_OWN_ADDR_RANDOM: setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); +#ifdef CONFIG_IDF_TARGET_ESP32 ble_hs_pvcy_rpa_config(useNRPA ? NIMBLE_HOST_ENABLE_NRPA : NIMBLE_HOST_ENABLE_RPA); +#endif break; case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT: case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT: setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); +#ifdef CONFIG_IDF_TARGET_ESP32 ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA); +#endif break; } } // setOwnAddrType diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h index 27549ed60..08a042fc2 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h @@ -95,6 +95,11 @@ public: static bool getInitialized(); static NimBLEAddress getAddress(); static std::string toString(); + static bool whiteListAdd(const NimBLEAddress & address); + static bool whiteListRemove(const NimBLEAddress & address); + static bool onWhiteList(const NimBLEAddress & address); + static size_t getWhiteListCount(); + static NimBLEAddress getWhiteListAddress(size_t index); #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) static NimBLEScan* getScan(); @@ -142,6 +147,14 @@ public: static std::list* getClientList(); #endif +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static bool deleteBond(const NimBLEAddress &address); + static int getNumBonds(); + static bool isBonded(const NimBLEAddress &address); + static void deleteAllBonds(); + static NimBLEAddress getBondedAddress(int index); +#endif + private: #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) friend class NimBLEClient; @@ -188,6 +201,7 @@ private: static uint8_t m_own_addr_type; static uint16_t m_scanDuplicateSize; static uint8_t m_scanFilterMode; + static std::vector m_whiteList; }; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLELog.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLELog.h index 6e9ed97f3..8c1314634 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLELog.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLELog.h @@ -7,17 +7,19 @@ */ #ifndef MAIN_NIMBLELOG_H_ #define MAIN_NIMBLELOG_H_ + #include "sdkconfig.h" + #if defined(CONFIG_BT_ENABLED) +#ifdef ARDUINO_ARCH_ESP32 #include "syscfg/syscfg.h" #include "modlog/modlog.h" - // If Arduino is being used, strip out the colors and ignore log printing below ui setting. // Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR // otherwise no messages will be printed above that level. -#ifdef ARDUINO_ARCH_ESP32 + #ifndef CORE_DEBUG_LEVEL #define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL #endif @@ -49,11 +51,15 @@ #define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__) #else -#define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "\033[0;31mE %s: "#format"\033[0m\n",tag,##__VA_ARGS__) -#define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(WARN, "\033[0;33mW %s: "#format"\033[0m\n",tag,##__VA_ARGS__) -#define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(INFO, "\033[0;32mI %s: "#format"\033[0m\n",tag,##__VA_ARGS__) -#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(DEBUG, "D %s: "#format"\n",tag,##__VA_ARGS__) -#define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "\033[1;31mCRIT %s: "#format"\033[0m\n",tag,##__VA_ARGS__) + +#include "esp_log.h" + +#define NIMBLE_LOGE(tag, format, ...) ESP_LOGE(tag, format, ##__VA_ARGS__) +#define NIMBLE_LOGW(tag, format, ...) ESP_LOGW(tag, format, ##__VA_ARGS__) +#define NIMBLE_LOGI(tag, format, ...) ESP_LOGI(tag, format, ##__VA_ARGS__) +#define NIMBLE_LOGD(tag, format, ...) ESP_LOGD(tag, format, ##__VA_ARGS__) +#define NIMBLE_LOGC(tag, format, ...) ESP_LOGE(tag, format, ##__VA_ARGS__) + #endif /*ARDUINO_ARCH_ESP32*/ #endif /*CONFIG_BT_ENABLED*/ diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp index 8bc5090b1..85c854971 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp @@ -55,6 +55,7 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic"; m_handle = chr->val_handle; m_defHandle = chr->def_handle; + m_endHandle = 0; m_charProp = chr->properties; m_pRemoteService = pRemoteService; m_notifyCallback = nullptr; @@ -146,31 +147,25 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_dsc *dsc, void *arg) { - NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", - error->status, (error->status == 0) ? dsc->handle : -1); + int rc = error->status; + NIMBLE_LOGD(LOG_TAG, "Descriptor Discovered >> status: %d handle: %d", + rc, (rc == 0) ? dsc->handle : -1); desc_filter_t *filter = (desc_filter_t*)arg; const NimBLEUUID *uuid_filter = filter->uuid; ble_task_data_t *pTaskData = (ble_task_data_t*)filter->task_data; NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; - int rc=0; - if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ + if (characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } - switch (error->status) { + switch (rc) { case 0: { - if(dsc->uuid.u.type == BLE_UUID_TYPE_16 && dsc->uuid.u16.value == uint16_t(0x2803)) { - NIMBLE_LOGD(LOG_TAG,"Descriptor NOT found - end of Characteristic definintion"); - rc = BLE_HS_EDONE; - break; - } - if(uuid_filter != nullptr) { - if(ble_uuid_cmp(&uuid_filter->getNative()->u, &dsc->uuid.u) != 0) { + if (uuid_filter != nullptr) { + if (ble_uuid_cmp(&uuid_filter->getNative()->u, &dsc->uuid.u) != 0) { return 0; } else { - NIMBLE_LOGD(LOG_TAG,"Descriptor Found"); rc = BLE_HS_EDONE; } } @@ -180,11 +175,10 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, break; } default: - rc = error->status; break; } - /** If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process. + /* If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process. * Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE. * If we get any other error code tell the application to abort by returning non-zero in the rc. */ @@ -202,6 +196,38 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, } +/** + * @brief callback from NimBLE when the next characteristic of the service is discovered. + */ +int NimBLERemoteCharacteristic::nextCharCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) +{ + int rc = error->status; + NIMBLE_LOGD(LOG_TAG, "Next Characteristic >> status: %d handle: %d", + rc, (rc == 0) ? chr->val_handle : -1); + + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteCharacteristic *pChar = (NimBLERemoteCharacteristic*)pTaskData->pATT; + + if (pChar->getRemoteService()->getClient()->getConnId() != conn_handle) { + return 0; + } + + if (rc == 0) { + pChar->m_endHandle = chr->def_handle - 1; + rc = BLE_HS_EDONE; + } else if (rc == BLE_HS_EDONE) { + pChar->m_endHandle = pChar->getRemoteService()->getEndHandle(); + } else { + pTaskData->rc = rc; + } + + xTaskNotifyGive(pTaskData->task); + return rc; +} + + /** * @brief Populate the descriptors (if any) for this characteristic. * @param [in] the end handle of the characteristic, or the service, whichever comes first. @@ -209,35 +235,57 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filter) { NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str()); - uint16_t endHandle = getRemoteService()->getEndHandle(this); - if(m_handle >= endHandle) { - return false; + // If this is the last handle then there are no descriptors + if (m_handle == getRemoteService()->getEndHandle()) { + return true; } int rc = 0; ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + + // If we don't know the end handle of this characteristic retrieve the next one in the service + // The end handle is the next characteristic definition handle -1. + if (m_endHandle == 0) { + rc = ble_gattc_disc_all_chrs(getRemoteService()->getClient()->getConnId(), + m_handle, + getRemoteService()->getEndHandle(), + NimBLERemoteCharacteristic::nextCharCB, + &taskData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error getting end handle rc=%d", rc); + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if (taskData.rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Could not retrieve end handle rc=%d", taskData.rc); + return false; + } + } + desc_filter_t filter = {uuid_filter, &taskData}; rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), m_handle, - endHandle, + m_endHandle, NimBLERemoteCharacteristic::descriptorDiscCB, &filter); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_dscs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); return false; } ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - if(taskData.rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: startHandle:%d endHandle:%d taskData.rc=%d %s", m_handle, endHandle, taskData.rc, NimBLEUtils::returnCodeToString(0x0100+taskData.rc)); - return false; + if (taskData.rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to retrieve descriptors; startHandle:%d endHandle:%d taskData.rc=%d", + m_handle, m_endHandle, taskData.rc); } - return true; NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size()); + return (taskData.rc == 0); } // retrieveDescriptors @@ -664,7 +712,7 @@ std::string NimBLERemoteCharacteristic::toString() { * @return false if not connected or cant perform write for some reason. */ bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool response) { - return writeValue((uint8_t*)newValue.c_str(), strlen(newValue.c_str()), response); + return writeValue((uint8_t*)newValue.c_str(), newValue.length(), response); } // writeValue diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h index 720a4da29..39e6d40fa 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h @@ -148,12 +148,15 @@ private: static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, void *arg); + static int nextCharCB(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg); // Private properties NimBLEUUID m_uuid; uint8_t m_charProp; uint16_t m_handle; uint16_t m_defHandle; + uint16_t m_endHandle; NimBLERemoteService* m_pRemoteService; std::string m_value; notify_callback m_notifyCallback; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.cpp index cb20e0b3f..efb6662a8 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.cpp @@ -223,6 +223,20 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) ulTaskNotifyTake(pdTRUE, portMAX_DELAY); if(taskData.rc == 0){ + if (uuid_filter == nullptr) { + if (m_characteristicVector.size() > 1) { + for (auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it ) { + auto nx = std::next(it, 1); + if (nx == m_characteristicVector.end()) { + break; + } + (*it)->m_endHandle = (*nx)->m_defHandle - 1; + } + } + + m_characteristicVector.back()->m_endHandle = getEndHandle(); + } + NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); return true; } @@ -249,23 +263,6 @@ uint16_t NimBLERemoteService::getEndHandle() { return m_endHandle; } // getEndHandle -/** - * @brief Get the end handle of specified NimBLERemoteCharacteristic. - */ - -uint16_t NimBLERemoteService::getEndHandle(NimBLERemoteCharacteristic *pCharacteristic) { - uint16_t endHandle = m_endHandle; - - for(auto &it: m_characteristicVector) { - uint16_t defHandle = it->getDefHandle() - 1; - if(defHandle > pCharacteristic->getDefHandle() && endHandle > defHandle) { - endHandle = defHandle; - } - } - - return endHandle; -} // getEndHandle - /** * @brief Get the service start handle. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.h index 4920844e4..751c9effb 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteService.h @@ -70,7 +70,6 @@ private: uint16_t getStartHandle(); uint16_t getEndHandle(); - uint16_t getEndHandle(NimBLERemoteCharacteristic *pCharacteristic); void releaseSemaphores(); // Properties diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.cpp index 00aeab03c..037055208 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.cpp @@ -110,7 +110,7 @@ NimBLEScan::~NimBLEScan() { advertisedDevice->m_timestamp = time(nullptr); advertisedDevice->setRSSI(event->disc.rssi); - advertisedDevice->setPayload(event->disc.data, event->disc.length_data, + advertisedDevice->setPayload(event->disc.data, event->disc.length_data, event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP); if (pScan->m_pAdvertisedDeviceCallbacks) { @@ -128,7 +128,7 @@ NimBLEScan::~NimBLEScan() { advertisedDevice->m_callbackSent = true; pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); } - // If not storing results and we have invoked the callback, delete the device. + // If not storing results and we have invoked the callback, delete the device. if(pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent) { pScan->erase(advertisedAddress); } @@ -316,6 +316,8 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul break; case BLE_HS_EALREADY: + // Clear the cache if already scanning in case an advertiser was missed. + clearDuplicateCache(); break; case BLE_HS_EBUSY: @@ -398,6 +400,16 @@ bool NimBLEScan::stop() { } // stop +/** + * @brief Clears the duplicate scan filter cache. + */ +void NimBLEScan::clearDuplicateCache() { +#ifdef CONFIG_IDF_TARGET_ESP32 // Not available for ESP32C3 + esp_ble_scan_dupilcate_list_flush(); +#endif +} + + /** * @brief Delete peer device from the scan results vector. * @param [in] address The address of the device to delete from the results. @@ -453,6 +465,7 @@ void NimBLEScan::clearResults() { delete it; } m_scanResults.m_advertisedDevicesVector.clear(); + clearDuplicateCache(); } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.h index 57e743009..49d67c8ec 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEScan.h @@ -70,6 +70,7 @@ public: void setDuplicateFilter(bool enabled); void setLimitedOnly(bool enabled); void setFilterPolicy(uint8_t filter); + void clearDuplicateCache(); bool stop(); void clearResults(); NimBLEScanResults getResults(); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.cpp index 423e87967..082c51ad8 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.cpp @@ -37,6 +37,7 @@ static NimBLEServerCallbacks defaultCallbacks; * the NimBLEDevice class. */ NimBLEServer::NimBLEServer() { + memset(m_indWait, BLE_HS_CONN_HANDLE_NONE, sizeof(m_indWait)); // m_svcChgChrHdl = 0xffff; // Future Use m_pServerCallbacks = &defaultCallbacks; m_gattsStarted = false; @@ -90,12 +91,7 @@ NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numH NimBLEService* pService = new NimBLEService(uuid, numHandles, this); m_svcVec.push_back(pService); // Save a reference to this service being on this server. - - if(m_gattsStarted) { - ble_svc_gatt_changed(0x0001, 0xffff); - m_svcChanged = true; - resetGATT(); - } + serviceChanged(); NIMBLE_LOGD(LOG_TAG, "<< createService"); return pService; @@ -156,6 +152,18 @@ NimBLEAdvertising* NimBLEServer::getAdvertising() { } // getAdvertising +/** + * @brief Sends a service changed notification and resets the GATT server. + */ +void NimBLEServer::serviceChanged() { + if(m_gattsStarted) { + m_svcChanged = true; + ble_svc_gatt_changed(0x0001, 0xffff); + resetGATT(); + } +} + + /** * @brief Start the GATT server. Required to be called after setup of all * services and characteristics / descriptors for the NimBLE host to register them. @@ -253,6 +261,63 @@ size_t NimBLEServer::getConnectedCount() { } // getConnectedCount +/** + * @brief Get the vector of the connected client ID's. + */ +std::vector NimBLEServer::getPeerDevices() { + return m_connectedPeersVec; +} // getPeerDevices + + +/** + * @brief Get the connection information of a connected peer by vector index. + * @param [in] index The vector index of the peer. + */ +NimBLEConnInfo NimBLEServer::getPeerInfo(size_t index) { + if (index >= m_connectedPeersVec.size()) { + NIMBLE_LOGE(LOG_TAG, "No peer at index %u", index); + return NimBLEConnInfo(); + } + + return getPeerIDInfo(m_connectedPeersVec[index]); +} // getPeerInfo + + +/** + * @brief Get the connection information of a connected peer by address. + * @param [in] address The address of the peer. + */ +NimBLEConnInfo NimBLEServer::getPeerInfo(const NimBLEAddress& address) { + ble_addr_t peerAddr; + memcpy(&peerAddr.val, address.getNative(),6); + peerAddr.type = address.getType(); + + NimBLEConnInfo peerInfo; + int rc = ble_gap_conn_find_by_addr(&peerAddr, &peerInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Peer info not found"); + } + + return peerInfo; +} // getPeerInfo + + +/** + * @brief Get the connection information of a connected peer by connection ID. + * @param [in] id The connection id of the peer. + */ +NimBLEConnInfo NimBLEServer::getPeerIDInfo(uint16_t id) { + NimBLEConnInfo peerInfo; + + int rc = ble_gap_conn_find(id, &peerInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Peer info not found"); + } + + return peerInfo; +} // getPeerIDInfo + + /** * @brief Handle a GATT Server Event. * @@ -280,7 +345,9 @@ size_t NimBLEServer::getConnectedCount() { server->m_connectedPeersVec.push_back(event->connect.conn_handle); rc = ble_gap_conn_find(event->connect.conn_handle, &desc); - assert(rc == 0); + if (rc != 0) { + return 0; + } server->m_pServerCallbacks->onConnect(server); server->m_pServerCallbacks->onConnect(server, &desc); @@ -335,7 +402,9 @@ size_t NimBLEServer::getConnectedCount() { (it->getProperties() & BLE_GATT_CHR_F_READ_ENC)) { rc = ble_gap_conn_find(event->subscribe.conn_handle, &desc); - assert(rc == 0); + if (rc != 0) { + break; + } if(!desc.sec_state.encrypted) { NimBLEDevice::startSecurity(event->subscribe.conn_handle); @@ -354,22 +423,54 @@ size_t NimBLEServer::getConnectedCount() { NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, event->mtu.value); + rc = ble_gap_conn_find(event->mtu.conn_handle, &desc); + if (rc != 0) { + return 0; + } + + server->m_pServerCallbacks->onMTUChange(event->mtu.value, &desc); return 0; } // BLE_GAP_EVENT_MTU case BLE_GAP_EVENT_NOTIFY_TX: { - if(event->notify_tx.indication && event->notify_tx.status != 0) { - for(auto &it : server->m_notifyChrVec) { - if(it->getHandle() == event->notify_tx.attr_handle) { - if(it->m_pTaskData != nullptr) { - it->m_pTaskData->rc = event->notify_tx.status; - xTaskNotifyGive(it->m_pTaskData->task); - } - break; - } + NimBLECharacteristic *pChar = nullptr; + + for(auto &it : server->m_notifyChrVec) { + if(it->getHandle() == event->notify_tx.attr_handle) { + pChar = it; } } + if(pChar == nullptr) { + return 0; + } + + NimBLECharacteristicCallbacks::Status statusRC; + + if(event->notify_tx.indication) { + if(event->notify_tx.status != 0) { + if(event->notify_tx.status == BLE_HS_EDONE) { + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_INDICATE; + } else if(rc == BLE_HS_ETIMEOUT) { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT; + } else { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE; + } + } else { + return 0; + } + + server->clearIndicateWait(event->notify_tx.conn_handle); + } else { + if(event->notify_tx.status == 0) { + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY; + } else { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; + } + } + + pChar->m_pCallbacks->onStatus(pChar, statusRC, event->notify_tx.status); + return 0; } // BLE_GAP_EVENT_NOTIFY_TX @@ -392,7 +493,10 @@ size_t NimBLEServer::getConnectedCount() { /* Delete the old bond. */ rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); - assert(rc == 0); + if (rc != 0){ + return BLE_GAP_REPEAT_PAIRING_IGNORE; + } + ble_store_util_delete_peer(&desc.peer_id_addr); /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should @@ -533,7 +637,7 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) { if(service->m_removed > 0) { if(deleteSvc) { for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ++it) { - if ((*it)->getUUID() == service->getUUID()) { + if ((*it) == service) { delete *it; m_svcVec.erase(it); break; @@ -549,32 +653,35 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) { return; } - service->m_removed = deleteSvc ? 2 : 1; - m_svcChanged = true; - - ble_svc_gatt_changed(0x0001, 0xffff); - resetGATT(); + service->m_removed = deleteSvc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE; + serviceChanged(); NimBLEDevice::getAdvertising()->removeServiceUUID(service->getUUID()); } /** - * @brief Adds a service which was already created, but removed from availability. + * @brief Adds a service which was either already created but removed from availability,\n + * or created and later added to services list. * @param [in] service The service object to add. * @note If it is desired to advertise the service it must be added by * calling NimBLEAdvertising::addServiceUUID. */ void NimBLEServer::addService(NimBLEService* service) { - // If adding a service that was not removed just return. + // Check that a service with the supplied UUID does not already exist. + if(getServiceByUUID(service->getUUID()) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s", + std::string(service->getUUID()).c_str()); + } + + // If adding a service that was not removed add it and return. + // Else reset GATT and send service changed notification. if(service->m_removed == 0) { + m_svcVec.push_back(service); return; } service->m_removed = 0; - m_svcChanged = true; - - ble_svc_gatt_changed(0x0001, 0xffff); - resetGATT(); + serviceChanged(); } @@ -593,7 +700,7 @@ void NimBLEServer::resetGATT() { for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ) { if ((*it)->m_removed > 0) { - if ((*it)->m_removed == 2) { + if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) { delete *it; it = m_svcVec.erase(it); } else { @@ -668,6 +775,27 @@ void NimBLEServer::updateConnParams(uint16_t conn_handle, }// updateConnParams +bool NimBLEServer::setIndicateWait(uint16_t conn_handle) { + for(auto i = 0; i < CONFIG_BT_NIMBLE_MAX_CONNECTIONS; i++) { + if(m_indWait[i] == conn_handle) { + return false; + } + } + + return true; +} + + +void NimBLEServer::clearIndicateWait(uint16_t conn_handle) { + for(auto i = 0; i < CONFIG_BT_NIMBLE_MAX_CONNECTIONS; i++) { + if(m_indWait[i] == conn_handle) { + m_indWait[i] = BLE_HS_CONN_HANDLE_NONE; + return; + } + } +} + + /** Default callback handlers */ void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) { @@ -688,6 +816,10 @@ void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer, ble_gap_conn_des NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default"); } // onDisconnect +void NimBLEServerCallbacks::onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onMTUChange(): Default"); +} // onMTUChange + uint32_t NimBLEServerCallbacks::onPassKeyRequest(){ NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456"); return 123456; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h index aaaf287d2..ebcf39f23 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h @@ -20,11 +20,15 @@ #include "nimconfig.h" #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#define NIMBLE_ATT_REMOVE_HIDE 1 +#define NIMBLE_ATT_REMOVE_DELETE 2 + #include "NimBLEUtils.h" #include "NimBLEAddress.h" #include "NimBLEAdvertising.h" #include "NimBLEService.h" #include "NimBLESecurity.h" +#include "NimBLEConnInfo.h" class NimBLEService; @@ -58,13 +62,17 @@ public: uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout); uint16_t getPeerMTU(uint16_t conn_id); -// std::vector getPeerDevices(); + std::vector getPeerDevices(); + NimBLEConnInfo getPeerInfo(size_t index); + NimBLEConnInfo getPeerInfo(const NimBLEAddress& address); + NimBLEConnInfo getPeerIDInfo(uint16_t id); void advertiseOnDisconnect(bool); private: NimBLEServer(); ~NimBLEServer(); friend class NimBLECharacteristic; + friend class NimBLEService; friend class NimBLEDevice; friend class NimBLEAdvertising; @@ -73,6 +81,7 @@ private: bool m_svcChanged; NimBLEServerCallbacks* m_pServerCallbacks; bool m_deleteCallbacks; + uint16_t m_indWait[CONFIG_BT_NIMBLE_MAX_CONNECTIONS]; std::vector m_connectedPeersVec; // uint16_t m_svcChgChrHdl; // Future use @@ -81,7 +90,10 @@ private: std::vector m_notifyChrVec; static int handleGapEvent(struct ble_gap_event *event, void *arg); + void serviceChanged(); void resetGATT(); + bool setIndicateWait(uint16_t conn_handle); + void clearIndicateWait(uint16_t conn_handle); }; // NimBLEServer @@ -124,6 +136,14 @@ public: */ virtual void onDisconnect(NimBLEServer* pServer, ble_gap_conn_desc* desc); + /** + * @brief Called when the connection MTU changes. + * @param [in] MTU The new MTU value. + * @param [in] desc A pointer to the connection description structure containig information + * about the connection. + */ + virtual void onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc); + /** * @brief Called when a client requests a passkey for pairing. * @return The passkey to be sent to the client. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.cpp index a830eec95..9c43e900c 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.cpp @@ -35,7 +35,7 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging. * @brief Construct an instance of the NimBLEService * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. - * @param [in] a pointer to the server instance that this service belongs to. + * @param [in] pServer A pointer to the server instance that this service belongs to. */ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer) : NimBLEService(NimBLEUUID(uuid), numHandles, pServer) { @@ -46,7 +46,7 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer * @brief Construct an instance of the BLEService * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. - * @param [in] a pointer to the server instance that this service belongs to. + * @param [in] pServer A pointer to the server instance that this service belongs to. */ NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) { m_uuid = uuid; @@ -118,7 +118,12 @@ NimBLEUUID NimBLEService::getUUID() { */ bool NimBLEService::start() { NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str()); - int rc = 0; + + // Rebuild the service definition if the server attributes have changed. + if(getServer()->m_svcChanged && m_pSvcDef != nullptr) { + delete(m_pSvcDef); + m_pSvcDef = nullptr; + } if(m_pSvcDef == nullptr) { // Nimble requires an array of services to be sent to the api @@ -132,8 +137,23 @@ bool NimBLEService::start() { svc[0].uuid = &m_uuid.getNative()->u; svc[0].includes = NULL; - size_t numChrs = m_chrVec.size(); + int removedCount = 0; + for(auto it = m_chrVec.begin(); it != m_chrVec.end(); ) { + if ((*it)->m_removed > 0) { + if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) { + delete *it; + it = m_chrVec.erase(it); + } else { + ++removedCount; + ++it; + } + continue; + } + ++it; + } + + size_t numChrs = m_chrVec.size() - removedCount; NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str()); if(!numChrs){ @@ -142,40 +162,60 @@ bool NimBLEService::start() { // Nimble requires the last characteristic to have it's uuid = 0 to indicate the end // of the characteristics for the service. We create 1 extra and set it to null // for this purpose. - pChr_a = new ble_gatt_chr_def[numChrs+1]; - NimBLECharacteristic* pCharacteristic = *m_chrVec.begin(); + pChr_a = new ble_gatt_chr_def[numChrs + 1]; + uint8_t i = 0; + for(auto chr_it = m_chrVec.begin(); chr_it != m_chrVec.end(); ++chr_it) { + if((*chr_it)->m_removed > 0) { + continue; + } - for(uint8_t i=0; i < numChrs;) { - uint8_t numDscs = pCharacteristic->m_dscVec.size(); + removedCount = 0; + for(auto it = (*chr_it)->m_dscVec.begin(); it != (*chr_it)->m_dscVec.end(); ) { + if ((*it)->m_removed > 0) { + if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) { + delete *it; + it = (*chr_it)->m_dscVec.erase(it); + } else { + ++removedCount; + ++it; + } + continue; + } + + ++it; + } + + size_t numDscs = (*chr_it)->m_dscVec.size() - removedCount; if(!numDscs){ pChr_a[i].descriptors = NULL; } else { // Must have last descriptor uuid = 0 so we have to create 1 extra pDsc_a = new ble_gatt_dsc_def[numDscs+1]; - NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin(); - for(uint8_t d=0; d < numDscs;) { - pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u; - pDsc_a[d].att_flags = pDescriptor->m_properties; + uint8_t d = 0; + for(auto dsc_it = (*chr_it)->m_dscVec.begin(); dsc_it != (*chr_it)->m_dscVec.end(); ++dsc_it ) { + if((*dsc_it)->m_removed > 0) { + continue; + } + pDsc_a[d].uuid = &(*dsc_it)->m_uuid.getNative()->u; + pDsc_a[d].att_flags = (*dsc_it)->m_properties; pDsc_a[d].min_key_size = 0; pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent; - pDsc_a[d].arg = pDescriptor; - d++; - pDescriptor = *(pCharacteristic->m_dscVec.begin() + d); + pDsc_a[d].arg = (*dsc_it); + ++d; } pDsc_a[numDscs].uuid = NULL; pChr_a[i].descriptors = pDsc_a; } - pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u; + pChr_a[i].uuid = &(*chr_it)->m_uuid.getNative()->u; pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent; - pChr_a[i].arg = pCharacteristic; - pChr_a[i].flags = pCharacteristic->m_properties; + pChr_a[i].arg = (*chr_it); + pChr_a[i].flags = (*chr_it)->m_properties; pChr_a[i].min_key_size = 0; - pChr_a[i].val_handle = &pCharacteristic->m_handle; - i++; - pCharacteristic = *(m_chrVec.begin() + i); + pChr_a[i].val_handle = &(*chr_it)->m_handle; + ++i; } pChr_a[numChrs].uuid = NULL; @@ -187,7 +227,7 @@ bool NimBLEService::start() { m_pSvcDef = svc; } - rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)m_pSvcDef); + int rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)m_pSvcDef); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); return false; @@ -239,13 +279,64 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid std::string(uuid).c_str()); } - // Remember this characteristic in our vector of characteristics. - m_chrVec.push_back(pCharacteristic); - + addCharacteristic(pCharacteristic); return pCharacteristic; } // createCharacteristic +/** + * @brief Add a characteristic to the service. + * @param[in] pCharacteristic A pointer to the characteristic instance to add to the service. + */ +void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) { + bool foundRemoved = false; + + if(pCharacteristic->m_removed > 0) { + for(auto& it : m_chrVec) { + if(it == pCharacteristic) { + foundRemoved = true; + pCharacteristic->m_removed = 0; + } + } + } + + if(!foundRemoved) { + m_chrVec.push_back(pCharacteristic); + } + + pCharacteristic->setService(this); + getServer()->serviceChanged(); +} // addCharacteristic + + +/** + * @brief Remove a characteristic from the service. + * @param[in] pCharacteristic A pointer to the characteristic instance to remove from the service. + * @param[in] deleteChr If true it will delete the characteristic instance and free it's resources. + */ +void NimBLEService::removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr) { + // Check if the characteristic was already removed and if so, check if this + // is being called to delete the object and do so if requested. + // Otherwise, ignore the call and return. + if(pCharacteristic->m_removed > 0) { + if(deleteChr) { + for(auto it = m_chrVec.begin(); it != m_chrVec.end(); ++it) { + if ((*it) == pCharacteristic) { + m_chrVec.erase(it); + delete *it; + break; + } + } + } + + return; + } + + pCharacteristic->m_removed = deleteChr ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE; + getServer()->serviceChanged(); +} // removeCharacteristic + + /** * @brief Get a pointer to the characteristic object with the specified UUID. * @param [in] uuid The UUID of the characteristic. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.h index 1203d3e3b..ebf913d32 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEService.h @@ -36,6 +36,10 @@ class NimBLECharacteristic; class NimBLEService { public: + NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); + NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); + ~NimBLEService(); + NimBLEServer* getServer(); NimBLEUUID getUUID(); @@ -55,6 +59,8 @@ public: NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE); + void addCharacteristic(NimBLECharacteristic* pCharacteristic); + void removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr = false); NimBLECharacteristic* getCharacteristic(const char* uuid, uint16_t instanceId = 0); NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid, uint16_t instanceId = 0); NimBLECharacteristic* getCharacteristicByHandle(uint16_t handle); @@ -65,9 +71,6 @@ public: private: - NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); - NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); - ~NimBLEService(); friend class NimBLEServer; friend class NimBLEDevice; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEUUID.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEUUID.cpp index ea58ae7b2..9338d7d00 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEUUID.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEUUID.cpp @@ -277,10 +277,6 @@ std::string NimBLEUUID::toString() const { */ bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const { if(m_valueSet && rhs.m_valueSet) { - NIMBLE_LOGD(LOG_TAG,"Comparing UUIDs; type %u to %u; UUID %s to %s", - m_uuid.u.type, rhs.m_uuid.u.type, - this->toString().c_str(), rhs.toString().c_str()); - if(m_uuid.u.type != rhs.m_uuid.u.type) { uint8_t uuidBase[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, diff --git a/lib/libesp32_div/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c b/lib/libesp32_div/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c index 9af13c355..2963e15b3 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c @@ -19,13 +19,6 @@ * under the License. */ -/* - * This file has been modified by Ryan Powell, aka h2zero. - * The modifications are for the purpose of improving performance and support - * for Esprssif versions used by the ardruino-esp32 core that are less current - * than the esp-idf releases. - */ - #include #include "sysinit/sysinit.h" #include "nimble/hci_common.h" @@ -44,6 +37,8 @@ #endif #define NIMBLE_VHCI_TIMEOUT_MS 2000 +#define BLE_HCI_EVENT_HDR_LEN (2) +#define BLE_HCI_CMD_HDR_LEN (3) static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb; static void *ble_hci_rx_cmd_hs_arg; @@ -276,7 +271,9 @@ void ble_hci_trans_buf_free(uint8_t *buf) */ int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) { - return BLE_ERR_UNSUPPORTED; + ble_hci_acl_pool.mpe_put_cb = cb; + ble_hci_acl_pool.mpe_put_arg = arg; + return 0; } int ble_hci_trans_reset(void) @@ -313,6 +310,7 @@ static struct os_mbuf *ble_hci_trans_acl_buf_alloc(void) static void ble_hci_rx_acl(uint8_t *data, uint16_t len) { struct os_mbuf *m; + int rc; int sr; if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) { return; @@ -321,9 +319,11 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) m = ble_hci_trans_acl_buf_alloc(); if (!m) { + ESP_LOGE(TAG, "%s failed to allocate ACL buffers; increase ACL_BUF_COUNT", __func__); return; } - if (os_mbuf_append(m, data, len)) { + if ((rc = os_mbuf_append(m, data, len)) != 0) { + ESP_LOGE(TAG, "%s failed to os_mbuf_append; rc = %d", __func__, rc); os_mbuf_free_chain(m); return; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/esp_nimble_cfg.h b/lib/libesp32_div/NimBLE-Arduino/src/esp_nimble_cfg.h index bafbeac8f..2cebffc85 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/esp_nimble_cfg.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/esp_nimble_cfg.h @@ -25,6 +25,10 @@ #define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292) #endif +#ifndef MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT (0) +#endif + #ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT #define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0) #endif @@ -43,11 +47,15 @@ /*** nimble */ #ifndef MYNEWT_VAL_BLE_EXT_ADV -#define MYNEWT_VAL_BLE_EXT_ADV (0) +#define MYNEWT_VAL_BLE_EXT_ADV (CONFIG_BT_NIMBLE_EXT_ADV) #endif #ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE -#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) +#ifdef CONFIG_BT_NIMBLE_EXT_ADV +#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (CONFIG_BT_NIMBLE_MAX_EXT_ADV_DATA_LEN) +#else +#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (0) +#endif #endif #ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS @@ -55,12 +63,20 @@ #endif #ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES +#ifdef CONFIG_BT_NIMBLE_EXT_ADV +#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES) +#else #define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0) #endif +#endif #ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#ifdef CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS) +#else #define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) #endif +#endif #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #ifdef CONFIG_BT_NIMBLE_ROLE_BROADCASTER @@ -267,9 +283,25 @@ #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU #endif +#ifndef MYNEWT_VAL_BLE_HS_LOG_LVL +#define MYNEWT_VAL_BLE_HS_LOG_LVL CONFIG_BT_NIMBLE_LOG_LEVEL +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV +#ifdef CONFIG_BT_NIMBLE_EXT_ADV +#define MYNEWT_VAL_BLE_PERIODIC_ADV (CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV) +#else #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_VERSION +#define MYNEWT_VAL_BLE_VERSION (50) +#endif #ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO #define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) @@ -479,6 +511,18 @@ #define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1) #endif +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS +#endif + +#ifndef MYNEWT_VAL_BLE_HS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM #endif @@ -547,8 +591,12 @@ #define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") #endif -#ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY +#if CONFIG_IDF_TARGET_ESP32 #define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (1) +#else +#ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY +#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY) +#endif #endif #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT @@ -615,6 +663,27 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS #endif +/*** @apache-mynewt-nimble/nimble/host/mesh */ +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_MOD (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT +#define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_ADV_LOG_MOD (11) +#endif + #ifndef MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST #ifdef CONFIG_BT_NIMBLE_NVS_PERSIST #define MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST (1) @@ -645,6 +714,9 @@ #define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) #endif +#ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (4) +#endif /*** @apache-mynewt-nimble/nimble/host/mesh */ /* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ @@ -758,6 +830,14 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_FRIEND_LOG_MOD (14) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT #define MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT (2) #endif @@ -802,6 +882,14 @@ #define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_LOG_MOD (9) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER #ifdef CONFIG_BT_NIMBLE_MESH_LOW_POWER #define MYNEWT_VAL_BLE_MESH_LOW_POWER (1) @@ -810,6 +898,14 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_MOD (15) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO #define MYNEWT_VAL_BLE_MESH_LPN_AUTO (1) #endif @@ -858,6 +954,10 @@ #define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10) #endif +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS +#define MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS (0) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT #define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (1) #endif @@ -866,10 +966,30 @@ #define MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_MODEL_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD (16) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE #define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10) #endif +#ifndef MYNEWT_VAL_BLE_MESH_NET_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_NET_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_NET_LOG_MOD (17) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NODE_COUNT +#define MYNEWT_VAL_BLE_MESH_NODE_COUNT CONFIG_BT_NIMBLE_MESH_NODE_COUNT +#endif + #ifndef MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT #define MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT (60) #endif @@ -915,6 +1035,22 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER +#ifdef CONFIG_BT_NIMBLE_MESH_PROVISIONER +#define MYNEWT_VAL_BLE_MESH_PROVISIONER (1) +#else +#define MYNEWT_VAL_BLE_MESH_PROVISIONER (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROV_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROV_LOG_MOD (18) +#endif + /* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY #ifdef CONFIG_BT_NIMBLE_MESH_PROXY @@ -928,6 +1064,13 @@ #define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROXY_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD (19) +#endif #ifndef MYNEWT_VAL_BLE_MESH_RELAY #ifdef CONFIG_BT_NIMBLE_MESH_RELAY @@ -949,6 +1092,10 @@ #define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2) #endif +#ifndef MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS +#define MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE #define MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE (128) #endif @@ -958,6 +1105,14 @@ #define MYNEWT_VAL_BLE_MESH_SETTINGS (0) #endif +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_MOD (20) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_SHELL #define MYNEWT_VAL_BLE_MESH_SHELL (0) #endif @@ -974,10 +1129,26 @@ #define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE (500) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE_SHELL +#define MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE_SHELL (1000) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_TESTING #define MYNEWT_VAL_BLE_MESH_TESTING (0) #endif +#ifndef MYNEWT_VAL_BLE_MESH_TRANS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_TRANS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD (21) +#endif + /* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX #define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6) @@ -987,6 +1158,103 @@ #define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4) #endif +/*** @apache-mynewt-nimble/nimble/host/services/ans */ +#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE (303) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/bas */ +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/dis */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("NimBLE") +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE (303) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) +#endif + /*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE @@ -1102,4 +1370,8 @@ #define MYNEWT_VAL_BLE_HCI_UART_STOP_BITS (1) #endif +#ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG +#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1) +#endif + #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_gap.h b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_gap.h index b4dbdb051..ed7fbb128 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_gap.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_gap.h @@ -128,6 +128,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PERIODIC_REPORT 21 #define BLE_GAP_EVENT_PERIODIC_SYNC_LOST 22 #define BLE_GAP_EVENT_SCAN_REQ_RCVD 23 +#define BLE_GAP_EVENT_PERIODIC_TRANSFER 24 /*** Reason codes for the subscribe GAP event. */ @@ -390,7 +391,7 @@ struct ble_gap_ext_disc_desc { uint8_t length_data; /** Advertising data */ - uint8_t *data; + const uint8_t *data; /** Directed advertising address. Valid if BLE_HCI_ADV_DIRECT_MASK props is * set (BLE_ADDR_ANY otherwise). @@ -420,7 +421,7 @@ struct ble_gap_disc_desc { int8_t rssi; /** Advertising data */ - uint8_t *data; + const uint8_t *data; /** Directed advertising address. Valid for BLE_HCI_ADV_RPT_EVTYPE_DIR_IND * event type (BLE_ADDR_ANY otherwise). @@ -890,7 +891,7 @@ struct ble_gap_event { uint8_t data_length; /** Advertising data */ - uint8_t *data; + const uint8_t *data; } periodic_report; /** @@ -924,6 +925,47 @@ struct ble_gap_event { /** Address of scanner */ ble_addr_t scan_addr; } scan_req_rcvd; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + /** + * Represents a periodic advertising sync transfer received. Valid for + * the following event types: + * o BLE_GAP_EVENT_PERIODIC_TRANSFER + */ + struct { + /** BLE_ERR_SUCCESS on success or error code on failure. Sync handle + * is valid only for success. + */ + uint8_t status; + + /** Periodic sync handle */ + uint16_t sync_handle; + + /** Connection handle */ + uint16_t conn_handle; + + /** Service Data */ + uint16_t service_data; + + /** Advertising Set ID */ + uint8_t sid; + + /** Advertiser address */ + ble_addr_t adv_addr; + + /** Advertising PHY, can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - LE_HCI_LE_PHY_2M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t adv_phy; + + /** Periodic advertising interval */ + uint16_t per_adv_itvl; + + /** Advertiser clock accuracy */ + uint8_t adv_clk_accuracy; + } periodic_transfer; #endif }; }; @@ -1097,6 +1139,23 @@ int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *rsp_fields); */ int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields); +/** + * Configure LE Data Length in controller (OGF = 0x08, OCF = 0x0022). + * + * @param conn_handle Connection handle. + * @param tx_octets The preferred value of payload octets that the Controller + * should use for a new connection (Range + * 0x001B-0x00FB). + * @param tx_time The preferred maximum number of microseconds that the local Controller + * should use to transmit a single link layer packet + * (Range 0x0148-0x4290). + * + * @return 0 on success, + * other error code on failure. + */ +int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, + uint16_t tx_time); + #if MYNEWT_VAL(BLE_EXT_ADV) /** @brief Extended advertising parameters */ struct ble_gap_ext_adv_params { @@ -1203,8 +1262,8 @@ int ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr); * @param instance Instance ID * @param duration The duration of the advertisement procedure. On * expiration, the procedure ends and - * a BLE_HS_FOREVER event is reported. - * Units are milliseconds. Specify 0 for no + * a BLE_GAP_EVENT_ADV_COMPLETE event is reported. + * Units are 10 milliseconds. Specify 0 for no * expiration. * @params max_events Number of advertising events that should be sent * before advertising ends and @@ -1297,6 +1356,9 @@ struct ble_gap_periodic_sync_params { /** Synchronization timeout for the periodic advertising train in 10ms units */ uint16_t sync_timeout; + + /** If reports should be initially disabled when sync is created */ + unsigned int reports_disabled:1; }; /** @@ -1359,7 +1421,7 @@ int ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data); * * @return 0 on success; nonzero on failure. */ -int ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, +int ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, const struct ble_gap_periodic_sync_params *params, ble_gap_event_fn *cb, void *cb_arg); @@ -1368,7 +1430,7 @@ int ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, * * @return 0 on success; nonzero on failure. */ -int ble_gap_periodic_adv_create_sync_cancel(void); +int ble_gap_periodic_adv_sync_create_cancel(void); /** * Terminate synchronization procedure. @@ -1377,7 +1439,74 @@ int ble_gap_periodic_adv_create_sync_cancel(void); * * @return 0 on success; nonzero on failure. */ -int ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle); +int ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle); + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +/** + * Disable or enable periodic reports for specified sync. + * + * @param sync_handle Handle identifying synchronization. + * @param enable If reports should be enabled. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable); + +/** + * Initialize sync transfer procedure for specified handles. + * + * This allows to transfer periodic sync to which host is synchronized. + * + * @param sync_handle Handle identifying synchronization. + * @param conn_handle Handle identifying connection. + * @param service_data Sync transfer service data + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_sync_transfer(uint16_t sync_handle, + uint16_t conn_handle, + uint16_t service_data); + +/** + * Initialize set info transfer procedure for specified handles. + * + * This allows to transfer periodic sync which is being advertised by host. + * + * @param instance Advertising instance with periodic adv enabled. + * @param conn_handle Handle identifying connection. + * @param service_data Sync transfer service data + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_sync_set_info(uint8_t instance, + uint16_t conn_handle, + uint16_t service_data); + +/** + * Enables or disables sync transfer reception on specified connection. + * When sync transfer arrives, BLE_GAP_EVENT_PERIODIC_TRANSFER is sent to the user. + * After that, sync transfer reception on that connection is terminated and user needs + * to call this API again when expect to receive next sync transfers. + * + * Note: If ACL connection gets disconnected before sync transfer arrived, user will + * not receive BLE_GAP_EVENT_PERIODIC_TRANSFER. Instead, sync transfer reception + * is terminated by the host automatically. + * + * @param conn_handle Handle identifying connection. + * @param params Parameters for enabled sync transfer reception. + * Specify NULL to disable reception. + * @param cb The callback to associate with this synchronization + * procedure. BLE_GAP_EVENT_PERIODIC_REPORT events + * are reported only by this callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_sync_receive(uint16_t conn_handle, + const struct ble_gap_periodic_sync_params *params, + ble_gap_event_fn *cb, void *cb_arg); +#endif /** * Add peer device to periodic synchronization list. @@ -1435,7 +1564,8 @@ int ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size); * On expiration, the procedure ends and a * BLE_GAP_EVENT_DISC_COMPLETE event is * reported. Units are milliseconds. Specify - * BLE_HS_FOREVER for no expiration. + * BLE_HS_FOREVER for no expiration. Specify + * 0 to use stack defaults. * @param disc_params Additional arguments specifying the particulars * of the discovery procedure. * @param cb The callback to associate with this discovery @@ -1661,6 +1791,15 @@ int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason); */ int ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count); +/** + * Removes the address from controller's white list. + * + * @param addrs The entry to be removed from the white list. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_wl_tx_rmv(const ble_addr_t *addrs); + /** * Initiates a connection parameter update procedure. * diff --git a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_adv.h b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_adv.h index b0d85c02a..e3b6ea709 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_adv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_adv.h @@ -35,7 +35,7 @@ extern "C" { struct ble_hs_adv_field { uint8_t length; uint8_t type; - uint8_t value[]; + uint8_t value[0]; }; typedef int (* ble_hs_adv_parse_func_t) (const struct ble_hs_adv_field *, @@ -46,22 +46,22 @@ struct ble_hs_adv_fields { uint8_t flags; /*** 0x02,0x03 - 16-bit service class UUIDs. */ - ble_uuid16_t *uuids16; + const ble_uuid16_t *uuids16; uint8_t num_uuids16; unsigned uuids16_is_complete:1; /*** 0x04,0x05 - 32-bit service class UUIDs. */ - ble_uuid32_t *uuids32; + const ble_uuid32_t *uuids32; uint8_t num_uuids32; unsigned uuids32_is_complete:1; /*** 0x06,0x07 - 128-bit service class UUIDs. */ - ble_uuid128_t *uuids128; + const ble_uuid128_t *uuids128; uint8_t num_uuids128; unsigned uuids128_is_complete:1; /*** 0x08,0x09 - Local name. */ - uint8_t *name; + const uint8_t *name; uint8_t name_len; unsigned name_is_complete:1; @@ -70,14 +70,14 @@ struct ble_hs_adv_fields { unsigned tx_pwr_lvl_is_present:1; /*** 0x0d - Slave connection interval range. */ - uint8_t *slave_itvl_range; + const uint8_t *slave_itvl_range; /*** 0x16 - Service data - 16-bit UUID. */ - uint8_t *svc_data_uuid16; + const uint8_t *svc_data_uuid16; uint8_t svc_data_uuid16_len; /*** 0x17 - Public target address. */ - uint8_t *public_tgt_addr; + const uint8_t *public_tgt_addr; uint8_t num_public_tgt_addrs; /*** 0x19 - Appearance. */ @@ -89,19 +89,19 @@ struct ble_hs_adv_fields { unsigned adv_itvl_is_present:1; /*** 0x20 - Service data - 32-bit UUID. */ - uint8_t *svc_data_uuid32; + const uint8_t *svc_data_uuid32; uint8_t svc_data_uuid32_len; /*** 0x21 - Service data - 128-bit UUID. */ - uint8_t *svc_data_uuid128; + const uint8_t *svc_data_uuid128; uint8_t svc_data_uuid128_len; /*** 0x24 - URI. */ - uint8_t *uri; + const uint8_t *uri; uint8_t uri_len; /*** 0xff - Manufacturer specific data. */ - uint8_t *mfg_data; + const uint8_t *mfg_data; uint8_t mfg_data_len; }; @@ -164,8 +164,8 @@ int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields, int ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields, uint8_t *dst, uint8_t *dst_len, uint8_t max_len); -int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src, - uint8_t src_len); +int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, + const uint8_t *src, uint8_t src_len); int ble_hs_adv_parse(const uint8_t *data, uint8_t length, ble_hs_adv_parse_func_t func, void *user_data); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_log.h b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_log.h index 3fb1db978..8d0a4596e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_log.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_hs_log.h @@ -22,6 +22,11 @@ #include "modlog/modlog.h" +/* Only include the logcfg header if this version of newt can generate it. */ +#if MYNEWT_VAL(NEWT_FEATURE_LOGCFG) +#include "logcfg/logcfg.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -29,13 +34,13 @@ extern "C" { struct os_mbuf; #define BLE_HS_LOG(lvl, ...) \ - MODLOG_ ## lvl(LOG_MODULE_NIMBLE_HOST, __VA_ARGS__) + BLE_HS_LOG_ ## lvl(__VA_ARGS__) #define BLE_HS_LOG_ADDR(lvl, addr) \ - MODLOG_ ## lvl(LOG_MODULE_NIMBLE_HOST, \ - "%02x:%02x:%02x:%02x:%02x:%02x", \ - (addr)[5], (addr)[4], (addr)[3], \ - (addr)[2], (addr)[1], (addr)[0]) + BLE_HS_LOG_ ## lvl("%02x:%02x:%02x:%02x:%02x:%02x", \ + (addr)[5], (addr)[4], (addr)[3], \ + (addr)[2], (addr)[1], (addr)[0]) + void ble_hs_log_mbuf(const struct os_mbuf *om); void ble_hs_log_flat_buf(const void *data, int len); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_l2cap.h b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_l2cap.h index 644bd9d0d..aef9682cc 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_l2cap.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_l2cap.h @@ -51,10 +51,14 @@ struct ble_hs_conn; #define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP 0x11 #define BLE_L2CAP_SIG_OP_UPDATE_REQ 0x12 #define BLE_L2CAP_SIG_OP_UPDATE_RSP 0x13 -#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ 0x14 -#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP 0x15 +#define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_REQ 0x14 +#define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP 0x15 #define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT 0x16 -#define BLE_L2CAP_SIG_OP_MAX 0x17 +#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ 0x17 +#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP 0x18 +#define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_REQ 0x19 +#define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP 0x1A +#define BLE_L2CAP_SIG_OP_MAX 0x1B #define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD 0x0000 #define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED 0x0001 @@ -70,12 +74,21 @@ struct ble_hs_conn; #define BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID 0x0009 #define BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED 0x000A #define BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS 0x000B +#define BLE_L2CAP_COC_ERR_INVALID_PARAMETERS 0x000C + +#define BLE_L2CAP_ERR_RECONFIG_SUCCEED 0x0000 +#define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MTU_NOT_ALLOWED 0x0001 +#define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED 0x0002 +#define BLE_L2CAP_ERR_RECONFIG_INVALID_DCID 0x0003 +#define BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM 0x0004 #define BLE_L2CAP_EVENT_COC_CONNECTED 0 #define BLE_L2CAP_EVENT_COC_DISCONNECTED 1 #define BLE_L2CAP_EVENT_COC_ACCEPT 2 #define BLE_L2CAP_EVENT_COC_DATA_RECEIVED 3 #define BLE_L2CAP_EVENT_COC_TX_UNSTALLED 4 +#define BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED 5 +#define BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED 6 typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status, void *arg); @@ -196,11 +209,44 @@ struct ble_l2cap_event { */ int status; } tx_unstalled; + + /** + * Represents reconfiguration done. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED + * o BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED + */ + struct { + /** + * The status of the reconfiguration attempt; + * o 0: the reconfiguration was successfully done. + * o BLE host error code: the reconfiguration attempt failed for + * the specified reason. + */ + int status; + + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** The L2CAP channel of the relevant L2CAP connection. */ + struct ble_l2cap_chan *chan; + } reconfigured; }; }; +struct ble_l2cap_chan_info { + uint16_t scid; + uint16_t dcid; + uint16_t our_l2cap_mtu; + uint16_t peer_l2cap_mtu; + uint16_t psm; + uint16_t our_coc_mtu; + uint16_t peer_coc_mtu; +}; + typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg); + uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan); int ble_l2cap_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); @@ -211,10 +257,7 @@ int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, int ble_l2cap_disconnect(struct ble_l2cap_chan *chan); int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); int ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); -int ble_l2cap_get_scid(struct ble_l2cap_chan *chan); -int ble_l2cap_get_dcid(struct ble_l2cap_chan *chan); -int ble_l2cap_get_our_mtu(struct ble_l2cap_chan *chan); -int ble_l2cap_get_peer_mtu(struct ble_l2cap_chan *chan); +int ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info); #ifdef __cplusplus } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_sm.h b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_sm.h index 9bd25adfc..ceebb8564 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/host/ble_sm.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/host/ble_sm.h @@ -84,7 +84,16 @@ extern "C" { #define BLE_SM_IOACT_INPUT 2 #define BLE_SM_IOACT_DISP 3 #define BLE_SM_IOACT_NUMCMP 4 -#define BLE_SM_IOACT_MAX_PLUS_ONE 5 +#define BLE_SM_IOACT_OOB_SC 5 +#define BLE_SM_IOACT_MAX_PLUS_ONE 6 + +struct ble_sm_sc_oob_data { + /** Random Number. */ + uint8_t r[16]; + + /** Confirm Value. */ + uint8_t c[16]; +}; struct ble_sm_io { uint8_t action; @@ -92,9 +101,15 @@ struct ble_sm_io { uint32_t passkey; uint8_t oob[16]; uint8_t numcmp_accept; + struct { + struct ble_sm_sc_oob_data *local; + struct ble_sm_sc_oob_data *remote; + } oob_sc_data; }; }; +int ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data); + #if NIMBLE_BLE_SM int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey); #else diff --git a/lib/libesp32_div/NimBLE-Arduino/src/log_common/ignore.h b/lib/libesp32_div/NimBLE-Arduino/src/log_common/ignore.h new file mode 100644 index 000000000..46282a029 --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/log_common/ignore.h @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_IGNORE_ +#define H_IGNORE_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * These macros prevent the "set but not used" warnings for log writes below + * the log level. + */ + +#define IGN_1(X) ((void)(X)) +#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__) +#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__) +#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__) +#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__) +#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__) +#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__) +#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__) +#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__) +#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__) +#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__) +#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__) +#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__) +#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__) +#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__) +#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__) +#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__) +#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__) +#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__) +#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__) + +#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \ + _13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME +#define IGNORE(...) \ + GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \ + IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \ + IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/log_common/log_common.h similarity index 72% rename from lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg_priv.h rename to lib/libesp32_div/NimBLE-Arduino/src/log_common/log_common.h index 4d4390f92..f13a61ad9 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/log_common/log_common.h @@ -17,18 +17,26 @@ * under the License. */ -#ifndef H_BLE_HS_DBG_PRIV_ -#define H_BLE_HS_DBG_PRIV_ +#ifndef H_LOG_COMMON_ +#define H_LOG_COMMON_ + +#include "log_common/ignore.h" #ifdef __cplusplus extern "C" { #endif -void ble_hs_dbg_event_disp(uint8_t *evbuf); -void ble_hs_dbg_set_sync_state(uint8_t sync_state); +#define LOG_LEVEL_DEBUG (0) +#define LOG_LEVEL_INFO (1) +#define LOG_LEVEL_WARN (2) +#define LOG_LEVEL_ERROR (3) +#define LOG_LEVEL_CRITICAL (4) +#define LOG_LEVEL_NONE (5) +/* Up to 7 custom log levels. */ +#define LOG_LEVEL_MAX (15) #ifdef __cplusplus } #endif -#endif /* H_HOST_DBG_ */ +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/logcfg/logcfg.h b/lib/libesp32_div/NimBLE-Arduino/src/logcfg/logcfg.h new file mode 100644 index 000000000..764f87f27 --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/logcfg/logcfg.h @@ -0,0 +1,147 @@ +/** + * This file was generated by Apache newt version: 1.8.0-dev + */ + +#ifndef H_MYNEWT_LOGCFG_ +#define H_MYNEWT_LOGCFG_ + +#include "modlog/modlog.h" +#include "log_common/log_common.h" + +#if (MYNEWT_VAL(BLE_HS_LOG_LVL) == LOG_LEVEL_DEBUG) +#define BLE_HS_LOG_DEBUG(...) MODLOG_DEBUG(4, __VA_ARGS__) +#else +#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#endif + +#if (MYNEWT_VAL(BLE_HS_LOG_LVL) <= LOG_LEVEL_INFO) +#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) +#else +#define BLE_HS_LOG_INFO(...) IGNORE(__VA_ARGS__) +#endif + +#if (MYNEWT_VAL(BLE_HS_LOG_LVL) <= LOG_LEVEL_WARN) +#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) +#else +#define BLE_HS_LOG_WARN(...) IGNORE(__VA_ARGS__) +#endif + +#if (MYNEWT_VAL(BLE_HS_LOG_LVL) <= LOG_LEVEL_ERROR) +#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) +#else +#define BLE_HS_LOG_ERROR(...) IGNORE(__VA_ARGS__) +#endif + +#if (MYNEWT_VAL(BLE_HS_LOG_LVL) <= LOG_LEVEL_CRITICAL) +#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) +#else +#define BLE_HS_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) +#endif + +#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) + +#define BLE_MESH_ACCESS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_ACCESS_LOG_INFO(...) MODLOG_INFO(10, __VA_ARGS__) +#define BLE_MESH_ACCESS_LOG_WARN(...) MODLOG_WARN(10, __VA_ARGS__) +#define BLE_MESH_ACCESS_LOG_ERROR(...) MODLOG_ERROR(10, __VA_ARGS__) +#define BLE_MESH_ACCESS_LOG_CRITICAL(...) MODLOG_CRITICAL(10, __VA_ARGS__) +#define BLE_MESH_ACCESS_LOG_DISABLED(...) MODLOG_DISABLED(10, __VA_ARGS__) + +#define BLE_MESH_ADV_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_ADV_LOG_INFO(...) MODLOG_INFO(11, __VA_ARGS__) +#define BLE_MESH_ADV_LOG_WARN(...) MODLOG_WARN(11, __VA_ARGS__) +#define BLE_MESH_ADV_LOG_ERROR(...) MODLOG_ERROR(11, __VA_ARGS__) +#define BLE_MESH_ADV_LOG_CRITICAL(...) MODLOG_CRITICAL(11, __VA_ARGS__) +#define BLE_MESH_ADV_LOG_DISABLED(...) MODLOG_DISABLED(11, __VA_ARGS__) + +#define BLE_MESH_BEACON_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_BEACON_LOG_INFO(...) MODLOG_INFO(12, __VA_ARGS__) +#define BLE_MESH_BEACON_LOG_WARN(...) MODLOG_WARN(12, __VA_ARGS__) +#define BLE_MESH_BEACON_LOG_ERROR(...) MODLOG_ERROR(12, __VA_ARGS__) +#define BLE_MESH_BEACON_LOG_CRITICAL(...) MODLOG_CRITICAL(12, __VA_ARGS__) +#define BLE_MESH_BEACON_LOG_DISABLED(...) MODLOG_DISABLED(12, __VA_ARGS__) + +#define BLE_MESH_CRYPTO_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_CRYPTO_LOG_INFO(...) MODLOG_INFO(13, __VA_ARGS__) +#define BLE_MESH_CRYPTO_LOG_WARN(...) MODLOG_WARN(13, __VA_ARGS__) +#define BLE_MESH_CRYPTO_LOG_ERROR(...) MODLOG_ERROR(13, __VA_ARGS__) +#define BLE_MESH_CRYPTO_LOG_CRITICAL(...) MODLOG_CRITICAL(13, __VA_ARGS__) +#define BLE_MESH_CRYPTO_LOG_DISABLED(...) MODLOG_DISABLED(13, __VA_ARGS__) + +#define BLE_MESH_FRIEND_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_FRIEND_LOG_INFO(...) MODLOG_INFO(14, __VA_ARGS__) +#define BLE_MESH_FRIEND_LOG_WARN(...) MODLOG_WARN(14, __VA_ARGS__) +#define BLE_MESH_FRIEND_LOG_ERROR(...) MODLOG_ERROR(14, __VA_ARGS__) +#define BLE_MESH_FRIEND_LOG_CRITICAL(...) MODLOG_CRITICAL(14, __VA_ARGS__) +#define BLE_MESH_FRIEND_LOG_DISABLED(...) MODLOG_DISABLED(14, __VA_ARGS__) + +#define BLE_MESH_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_LOG_INFO(...) MODLOG_INFO(9, __VA_ARGS__) +#define BLE_MESH_LOG_WARN(...) MODLOG_WARN(9, __VA_ARGS__) +#define BLE_MESH_LOG_ERROR(...) MODLOG_ERROR(9, __VA_ARGS__) +#define BLE_MESH_LOG_CRITICAL(...) MODLOG_CRITICAL(9, __VA_ARGS__) +#define BLE_MESH_LOG_DISABLED(...) MODLOG_DISABLED(9, __VA_ARGS__) + +#define BLE_MESH_LOW_POWER_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_LOW_POWER_LOG_INFO(...) MODLOG_INFO(15, __VA_ARGS__) +#define BLE_MESH_LOW_POWER_LOG_WARN(...) MODLOG_WARN(15, __VA_ARGS__) +#define BLE_MESH_LOW_POWER_LOG_ERROR(...) MODLOG_ERROR(15, __VA_ARGS__) +#define BLE_MESH_LOW_POWER_LOG_CRITICAL(...) MODLOG_CRITICAL(15, __VA_ARGS__) +#define BLE_MESH_LOW_POWER_LOG_DISABLED(...) MODLOG_DISABLED(15, __VA_ARGS__) + +#define BLE_MESH_MODEL_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_MODEL_LOG_INFO(...) MODLOG_INFO(16, __VA_ARGS__) +#define BLE_MESH_MODEL_LOG_WARN(...) MODLOG_WARN(16, __VA_ARGS__) +#define BLE_MESH_MODEL_LOG_ERROR(...) MODLOG_ERROR(16, __VA_ARGS__) +#define BLE_MESH_MODEL_LOG_CRITICAL(...) MODLOG_CRITICAL(16, __VA_ARGS__) +#define BLE_MESH_MODEL_LOG_DISABLED(...) MODLOG_DISABLED(16, __VA_ARGS__) + +#define BLE_MESH_NET_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_NET_LOG_INFO(...) MODLOG_INFO(17, __VA_ARGS__) +#define BLE_MESH_NET_LOG_WARN(...) MODLOG_WARN(17, __VA_ARGS__) +#define BLE_MESH_NET_LOG_ERROR(...) MODLOG_ERROR(17, __VA_ARGS__) +#define BLE_MESH_NET_LOG_CRITICAL(...) MODLOG_CRITICAL(17, __VA_ARGS__) +#define BLE_MESH_NET_LOG_DISABLED(...) MODLOG_DISABLED(17, __VA_ARGS__) + +#define BLE_MESH_PROV_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_PROV_LOG_INFO(...) MODLOG_INFO(18, __VA_ARGS__) +#define BLE_MESH_PROV_LOG_WARN(...) MODLOG_WARN(18, __VA_ARGS__) +#define BLE_MESH_PROV_LOG_ERROR(...) MODLOG_ERROR(18, __VA_ARGS__) +#define BLE_MESH_PROV_LOG_CRITICAL(...) MODLOG_CRITICAL(18, __VA_ARGS__) +#define BLE_MESH_PROV_LOG_DISABLED(...) MODLOG_DISABLED(18, __VA_ARGS__) + +#define BLE_MESH_PROXY_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_PROXY_LOG_INFO(...) MODLOG_INFO(19, __VA_ARGS__) +#define BLE_MESH_PROXY_LOG_WARN(...) MODLOG_WARN(19, __VA_ARGS__) +#define BLE_MESH_PROXY_LOG_ERROR(...) MODLOG_ERROR(19, __VA_ARGS__) +#define BLE_MESH_PROXY_LOG_CRITICAL(...) MODLOG_CRITICAL(19, __VA_ARGS__) +#define BLE_MESH_PROXY_LOG_DISABLED(...) MODLOG_DISABLED(19, __VA_ARGS__) + +#define BLE_MESH_SETTINGS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_SETTINGS_LOG_INFO(...) MODLOG_INFO(20, __VA_ARGS__) +#define BLE_MESH_SETTINGS_LOG_WARN(...) MODLOG_WARN(20, __VA_ARGS__) +#define BLE_MESH_SETTINGS_LOG_ERROR(...) MODLOG_ERROR(20, __VA_ARGS__) +#define BLE_MESH_SETTINGS_LOG_CRITICAL(...) MODLOG_CRITICAL(20, __VA_ARGS__) +#define BLE_MESH_SETTINGS_LOG_DISABLED(...) MODLOG_DISABLED(20, __VA_ARGS__) + +#define BLE_MESH_TRANS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_TRANS_LOG_INFO(...) MODLOG_INFO(21, __VA_ARGS__) +#define BLE_MESH_TRANS_LOG_WARN(...) MODLOG_WARN(21, __VA_ARGS__) +#define BLE_MESH_TRANS_LOG_ERROR(...) MODLOG_ERROR(21, __VA_ARGS__) +#define BLE_MESH_TRANS_LOG_CRITICAL(...) MODLOG_CRITICAL(21, __VA_ARGS__) +#define BLE_MESH_TRANS_LOG_DISABLED(...) MODLOG_DISABLED(21, __VA_ARGS__) +#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) +#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) +#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) +#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) +#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) + +#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) +#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) +#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) +#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) +#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) + +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/access.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/access.h index 71ca34e2d..1f99f412e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/access.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/access.h @@ -29,6 +29,12 @@ extern "C" { #define BT_MESH_KEY_UNUSED 0xffff #define BT_MESH_KEY_DEV 0xfffe +#define BT_MESH_KEY_DEV_LOCAL BT_MESH_KEY_DEV +#define BT_MESH_KEY_DEV_REMOTE 0xfffd +#define BT_MESH_KEY_DEV_ANY 0xfffc + +#define BT_MESH_IS_DEV_KEY(key) (key == BT_MESH_KEY_DEV_LOCAL || \ + key == BT_MESH_KEY_DEV_REMOTE) /** Helper to define a mesh element within an array. * @@ -137,11 +143,14 @@ struct bt_mesh_msg_ctx { /** Destination address of a received message. Not used for sending. */ u16_t recv_dst; + /** RSSI of received packet. Not used for sending. */ + s8_t recv_rssi; + /** Received TTL value. Not used for sending. */ - u8_t recv_ttl:7; + u8_t recv_ttl; /** Force sending reliably by using segment acknowledgement */ - u8_t send_rel:1; + bool send_rel; /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ u8_t send_ttl; @@ -171,7 +180,66 @@ struct bt_mesh_model_op { /** Helper to define an empty model array */ #define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){}) -#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \ +/** Length of a short Mesh MIC. */ +#define BT_MESH_MIC_SHORT 4 +/** Length of a long Mesh MIC. */ +#define BT_MESH_MIC_LONG 8 + +/** @def BT_MESH_MODEL_OP_LEN + * + * @brief Helper to determine the length of an opcode. + * + * @param _op Opcode. + */ +#define BT_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3) + +/** @def BT_MESH_MODEL_BUF_LEN + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a short MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BT_MESH_MODEL_BUF_LEN(_op, _payload_len) \ + (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT) + +/** @def BT_MESH_MODEL_BUF_LEN_LONG_MIC + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a long MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BT_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \ + (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG) + +/** @def BT_MESH_MODEL_BUF_DEFINE + * + * @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model message payload. + */ +#define BT_MESH_MODEL_BUF(_op, _payload_len) \ + NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len))) + +/** @def BT_MESH_MODEL_CB + * + * @brief Composition data SIG model entry with callback functions. + * + * @param _id Model ID. + * @param _op Array of model opcode handlers. + * @param _pub Model publish parameters. + * @param _user_data User data for the model. + * @param _cb Callback structure, or NULL to keep no callbacks. + */ +#define BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb) \ { \ .id = (_id), \ .op = _op, \ @@ -181,9 +249,21 @@ struct bt_mesh_model_op { .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \ BT_MESH_ADDR_UNASSIGNED }, \ .user_data = _user_data, \ + .cb = _cb, \ } -#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \ +/** @def BT_MESH_MODEL_VND_CB + * + * @brief Composition data vendor model entry with callback functions. + * + * @param _company Company ID. + * @param _id Model ID. + * @param _op Array of model opcode handlers. + * @param _pub Model publish parameters. + * @param _user_data User data for the model. + * @param _cb Callback structure, or NULL to keep no callbacks. + */ +#define BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, _cb) \ { \ .vnd.company = (_company), \ .vnd.id = (_id), \ @@ -194,8 +274,35 @@ struct bt_mesh_model_op { .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \ BT_MESH_ADDR_UNASSIGNED }, \ .user_data = _user_data, \ + .cb = _cb, \ } + +/** @def BT_MESH_MODEL + * + * @brief Composition data SIG model entry. + * + * @param _id Model ID. + * @param _op Array of model opcode handlers. + * @param _pub Model publish parameters. + * @param _user_data User data for the model. + */ +#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \ + BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, NULL) + +/** @def BT_MESH_MODEL_VND + * + * @brief Composition data vendor model entry. + * + * @param _company Company ID. + * @param _id Model ID. + * @param _op Array of model opcode handlers. + * @param _pub Model publish parameters. + * @param _user_data User data for the model. + */ +#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \ + BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, NULL) + /** @def BT_MESH_TRANSMIT * * @brief Encode transmission count & interval steps. @@ -276,6 +383,7 @@ struct bt_mesh_model_pub { u8_t period; /**< Publish Period. */ u8_t period_div:4, /**< Divisor for the Period. */ cred:1, /**< Friendship Credentials Flag. */ + fast_period:1,/**< Use FastPeriodDivisor */ count:3; /**< Retransmissions left. */ u32_t period_start; /**< Start of the current period. */ @@ -317,6 +425,52 @@ struct bt_mesh_model_pub { struct k_delayed_work timer; }; +/** Model callback functions. */ +struct bt_mesh_model_cb { + /** @brief Set value handler of user data tied to the model. + * + * @sa settings_handler::h_set + * + * @param model Model to set the persistent data of. + * @param val Data from the backend. + * + * @return 0 on success, error otherwise. + */ + int (*const settings_set)(struct bt_mesh_model *model, char *val); + + /** @brief Callback called when all settings have been loaded. + * + * This handler gets called after the settings have been loaded in + * full. + * + * @sa settings_handler::h_commit + * + * @param model Model this callback belongs to. + * + * @return 0 on success, error otherwise. + */ + int (*const settings_commit)(struct bt_mesh_model *model); + + /** @brief Model init callback. + * + * Called on every model instance during mesh initialization. + * + * @param model Model to be initialized. + * + * @return 0 on success, error otherwise. + */ + int (*const init)(struct bt_mesh_model *model); + + /** @brief Model reset callback. + * + * Called when the mesh node is reset. All model data is deleted on + * reset, and the model should clear its state. + * + * @param model Model this callback belongs to. + */ + void (*const reset)(struct bt_mesh_model *model); +}; + /** Abstraction that describes a Mesh Model instance */ struct bt_mesh_model { union { @@ -330,7 +484,7 @@ struct bt_mesh_model { /* Internal information, mainly for persistent storage */ u8_t elem_idx; /* Belongs to Nth element */ u8_t mod_idx; /* Is the Nth model in the element */ - u16_t flags; /* Information about what has changed */ + u16_t flags; /* Model flags for internal bookkeeping */ /* Model Publication */ struct bt_mesh_model_pub * const pub; @@ -343,6 +497,15 @@ struct bt_mesh_model { const struct bt_mesh_model_op * const op; + /* Model callback structure. */ + const struct bt_mesh_model_cb * const cb; + +#if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) + /* Pointer to the next model in a model extension tree. */ + struct bt_mesh_model *next; + /* Pointer to the first model this model extends. */ + struct bt_mesh_model *extends; +#endif /* Model-specific user data */ void *user_data; }; @@ -402,6 +565,76 @@ int bt_mesh_model_publish(struct bt_mesh_model *model); */ struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod); +/** @brief Find a SIG model. + * + * @param elem Element to search for the model in. + * @param id Model ID of the model. + * + * @return A pointer to the Mesh model matching the given parameters, or NULL + * if no SIG model with the given ID exists in the given element. + */ +struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, + u16_t id); + +/** @brief Find a vendor model. + * + * @param elem Element to search for the model in. + * @param company Company ID of the model. + * @param id Model ID of the model. + * + * @return A pointer to the Mesh model matching the given parameters, or NULL + * if no vendor model with the given ID exists in the given element. + */ +struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, + u16_t company, u16_t id); + +/** @brief Get whether the model is in the primary element of the device. + * + * @param mod Mesh model. + * + * @return true if the model is on the primary element, false otherwise. + */ +static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) +{ + return (mod->elem_idx == 0); +} + +/** @brief Immediately store the model's user data in persistent storage. + * + * @param mod Mesh model. + * @param vnd This is a vendor model. + * @param data Model data to store, or NULL to delete any model data. + * @param data_len Length of the model data. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, + const void *data, size_t data_len); + +/** @brief Let a model extend another. + * + * Mesh models may be extended to reuse their functionality, forming a more + * complex model. A Mesh model may extend any number of models, in any element. + * The extensions may also be nested, ie a model that extends another may itself + * be extended. Extensions may not be cyclical, and a model can only be extended + * by one other model. + * + * A set of models that extend each other form a model extension tree. + * + * All models in an extension tree share one subscription list per element. The + * access layer will utilize the combined subscription list of all models in an + * extension tree and element, giving the models extended subscription list + * capacity. + * + * @param[in] mod Mesh model. + * @param[in] base_mod The model being extended. + * + * @retval 0 Successfully extended the base_mod model. + * @retval -EALREADY The base_mod model is already extended. + */ +int bt_mesh_model_extend(struct bt_mesh_model *mod, + struct bt_mesh_model *base_mod); + /** Node Composition */ struct bt_mesh_comp { u16_t cid; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_cli.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_cli.h index 9d80ccda7..7dc237beb 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_cli.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_cli.h @@ -31,10 +31,11 @@ struct bt_mesh_cfg_cli { }; extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[]; +extern const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb; -#define BT_MESH_MODEL_CFG_CLI(cli_data) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_CLI, \ - bt_mesh_cfg_cli_op, NULL, cli_data) +#define BT_MESH_MODEL_CFG_CLI(cli_data) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_op, NULL, \ + cli_data, &bt_mesh_cfg_cli_cb) int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, u8_t *status, struct os_mbuf *comp); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_srv.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_srv.h index cb5d25e69..14d8a2956 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_srv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/cfg_srv.h @@ -61,10 +61,11 @@ struct bt_mesh_cfg_srv { }; extern const struct bt_mesh_model_op bt_mesh_cfg_srv_op[]; +extern const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb; -#define BT_MESH_MODEL_CFG_SRV(srv_data) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_SRV, \ - bt_mesh_cfg_srv_op, NULL, srv_data) +#define BT_MESH_MODEL_CFG_SRV(srv_data) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_SRV, bt_mesh_cfg_srv_op, NULL, \ + srv_data, &bt_mesh_cfg_srv_cb) #ifdef __cplusplus } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/glue.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/glue.h index d6aee21f9..388ecba39 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/glue.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/glue.h @@ -24,6 +24,8 @@ #include #include "syscfg/syscfg.h" +#include "logcfg/logcfg.h" +#include "modlog/modlog.h" #include "nimble/nimble_npl.h" #include "os/os_mbuf.h" @@ -179,13 +181,19 @@ extern "C" { #define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ #define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ -#define BT_DBG(fmt, ...) \ - if (BT_DBG_ENABLED) { \ - BLE_HS_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); \ - } -#define BT_INFO(fmt, ...) BLE_HS_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); -#define BT_WARN(fmt, ...) BLE_HS_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); -#define BT_ERR(fmt, ...) BLE_HS_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#ifndef MESH_LOG_MODULE +#define MESH_LOG_MODULE BLE_MESH_LOG +#endif + +#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) +#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ + +#define BLE_MESH_LOG(lvl, ...) CAT(MESH_LOG_MODULE, CAT(_, lvl))(__VA_ARGS__) + +#define BT_DBG(fmt, ...) BLE_MESH_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_INFO(fmt, ...) BLE_MESH_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_WARN(fmt, ...) BLE_MESH_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_ERR(fmt, ...) BLE_MESH_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); #define BT_GATT_ERR(_att_err) (-(_att_err)) typedef ble_addr_t bt_addr_le_t; @@ -217,6 +225,20 @@ static inline struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) #define K_NO_WAIT (0) #define K_FOREVER (-1) +#if MYNEWT_VAL(BLE_EXT_ADV) +#define BT_MESH_ADV_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)) + +#if MYNEWT_VAL(BLE_MESH_PROXY) +/* Note that BLE_MULTI_ADV_INSTANCES contains number of additional instances. + * Instance 0 is always there + */ +#if MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) < 1 +#error "Mesh needs at least BLE_MULTI_ADV_INSTANCES set to 1" +#endif +#define BT_MESH_ADV_GATT_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) - 1) +#endif /* BLE_MESH_PROXY */ +#endif /* BLE_EXT_ADV */ + /* This is by purpose */ static inline void net_buf_simple_init(struct os_mbuf *buf, size_t reserve_head) @@ -260,6 +282,11 @@ void net_buf_reserve(struct os_mbuf *om, size_t reserve); #define net_buf_clone(a, b) os_mbuf_dup(a) #define net_buf_add_be32(a, b) net_buf_simple_add_be32(a, b) #define net_buf_add_be16(a, b) net_buf_simple_add_be16(a, b) +#define net_buf_pull(a, b) net_buf_simple_pull(a, b) +#define net_buf_pull_mem(a, b) net_buf_simple_pull_mem(a, b) +#define net_buf_pull_u8(a) net_buf_simple_pull_u8(a) +#define net_buf_pull_be16(a) net_buf_simple_pull_be16(a) +#define net_buf_skip(a, b) net_buf_simple_pull_mem(a, b) #define BT_GATT_CCC_NOTIFY BLE_GATT_CHR_PROP_NOTIFY @@ -370,9 +397,11 @@ static inline unsigned int find_msb_set(u32_t op) #define CONFIG_BT_MESH_PB_ADV BLE_MESH_PB_ADV #define CONFIG_BT_MESH_PB_GATT BLE_MESH_PB_GATT #define CONFIG_BT_MESH_PROV BLE_MESH_PROV +#define CONFIG_BT_MESH_PROXY BLE_MESH_PROXY #define CONFIG_BT_TESTING BLE_MESH_TESTING #define CONFIG_BT_SETTINGS BLE_MESH_SETTINGS #define CONFIG_SETTINGS BLE_MESH_SETTINGS +#define CONFIG_BT_MESH_PROVISIONER BLE_MESH_PROVISIONER /* Above flags are used with IS_ENABLED macro */ #define IS_ENABLED(config) MYNEWT_VAL(config) @@ -394,6 +423,8 @@ static inline unsigned int find_msb_set(u32_t op) #define CONFIG_BT_MESH_IVU_DIVIDER MYNEWT_VAL(BLE_MESH_IVU_DIVIDER) #define CONFIG_BT_DEVICE_NAME MYNEWT_VAL(BLE_MESH_DEVICE_NAME) #define CONFIG_BT_MESH_TX_SEG_MAX MYNEWT_VAL(BLE_MESH_TX_SEG_MAX) +#define CONFIG_BT_MESH_LABEL_COUNT MYNEWT_VAL(BLE_MESH_LABEL_COUNT) +#define CONFIG_BT_MESH_NODE_COUNT MYNEWT_VAL(BLE_MESH_NODE_COUNT) #define printk console_printf @@ -459,7 +490,8 @@ void net_buf_slist_merge_slist(struct net_buf_slist_t *list, #define settings_load conf_load int settings_bytes_from_str(char *val_str, void *vp, int *len); -char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len); +char *settings_str_from_bytes(const void *vp, int vp_len, + char *buf, int buf_len); #define snprintk snprintf #define BT_SETTINGS_SIZE(in_size) ((((((in_size) - 1) / 3) * 4) + 4) + 1) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_cli.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_cli.h index 719d621e0..8ab8d6d5b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_cli.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_cli.h @@ -35,10 +35,11 @@ struct bt_mesh_health_cli { }; extern const struct bt_mesh_model_op bt_mesh_health_cli_op[]; +extern const struct bt_mesh_model_cb bt_mesh_health_cli_cb; -#define BT_MESH_MODEL_HEALTH_CLI(cli_data) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_CLI, \ - bt_mesh_health_cli_op, NULL, cli_data) +#define BT_MESH_MODEL_HEALTH_CLI(cli_data) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_HEALTH_CLI, bt_mesh_health_cli_op, \ + NULL, cli_data, &bt_mesh_health_cli_cb) int bt_mesh_health_cli_set(struct bt_mesh_model *model); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_srv.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_srv.h index 0638c982a..83982376f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_srv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/health_srv.h @@ -71,6 +71,7 @@ struct bt_mesh_health_srv { int bt_mesh_fault_update(struct bt_mesh_elem *elem); extern const struct bt_mesh_model_op bt_mesh_health_srv_op[]; +extern const struct bt_mesh_model_cb bt_mesh_health_srv_cb; /** @def BT_MESH_MODEL_HEALTH_SRV * @@ -84,9 +85,9 @@ extern const struct bt_mesh_model_op bt_mesh_health_srv_op[]; * * @return New mesh model instance. */ -#define BT_MESH_MODEL_HEALTH_SRV(srv, pub) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_SRV, \ - bt_mesh_health_srv_op, pub, srv) +#define BT_MESH_MODEL_HEALTH_SRV(srv, pub) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_op, \ + pub, srv, &bt_mesh_health_srv_cb) #ifdef __cplusplus } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/main.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/main.h index 515d1d527..4a5bedba1 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/main.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/main.h @@ -128,6 +128,28 @@ struct bt_mesh_prov { */ int (*input)(bt_mesh_input_action_t act, u8_t size); + /** @brief The other device finished their OOB input. + * + * This callback notifies the application that it should stop + * displaying its output OOB value, as the other party finished their + * OOB input. + */ + void (*input_complete)(void); + + /** @brief Unprovisioned beacon has been received. + * + * This callback notifies the application that an unprovisioned + * beacon has been received. + * + * @param uuid UUID + * @param oob_info OOB Information + * @param uri_hash Pointer to URI Hash value. NULL if no hash was + * present in the beacon. + */ + void (*unprovisioned_beacon)(u8_t uuid[16], + bt_mesh_prov_oob_info_t oob_info, + u32_t *uri_hash); + /** @brief Provisioning link has been opened. * * This callback notifies the application that a provisioning @@ -157,6 +179,18 @@ struct bt_mesh_prov { */ void (*complete)(u16_t net_idx, u16_t addr); + /** @brief A new node has been added to the provisioning database. + * + * This callback notifies the application that provisioning has + * been successfully completed, and that a node has been assigned + * the specified NetKeyIndex and primary element address. + * + * @param net_idx NetKeyIndex given during provisioning. + * @param addr Primary element address. + * @param num_elem Number of elements that this node has. + */ + void (*node_added)(u16_t net_idx, u16_t addr, u8_t num_elem); + /** @brief Node has been reset. * * This callback notifies the application that the local node @@ -321,6 +355,19 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, u32_t iv_index, u16_t addr, const u8_t dev_key[16]); +/** @brief Provision a Mesh Node using PB-ADV + * + * @param uuid UUID + * @param net_idx Network Key Index + * @param addr Address to assign to remote device. If addr is 0, the lowest + * available address will be chosen. + * @param attention_duration The attention duration to be send to remote device + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_provision_adv(const u8_t uuid[16], u16_t net_idx, u16_t addr, + u8_t attention_duration); + /** @brief Check if the local node has been provisioned. * * This API can be used to check if the local node has been provisioned diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_cli.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_cli.h index 33fbd6e9d..f2e77a47f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_cli.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_cli.h @@ -19,20 +19,19 @@ struct bt_mesh_gen_model_cli { void *op_param; }; -extern struct bt_mesh_gen_model_cli gen_onoff_cli; extern const struct bt_mesh_model_op gen_onoff_cli_op[]; +extern const struct bt_mesh_model_cb bt_mesh_gen_onoff_cli_cb; -#define BT_MESH_MODEL_GEN_ONOFF_CLI() \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, \ - gen_onoff_cli_op, NULL, &gen_onoff_cli) +#define BT_MESH_MODEL_GEN_ONOFF_CLI(cli_data, pub) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, pub,\ + cli_data, &bt_mesh_gen_onoff_cli_cb) -extern struct bt_mesh_gen_model_cli gen_level_cli; extern const struct bt_mesh_model_op gen_level_cli_op[]; +extern const struct bt_mesh_model_cb bt_mesh_gen_level_cli_cb; -#define BT_MESH_MODEL_GEN_LEVEL_CLI(pub) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI, \ - gen_level_cli_op, NULL, &gen_level_cli) - +#define BT_MESH_MODEL_GEN_LEVEL_CLI(cli_data, pub) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_LEVEL_CLI, gen_level_cli_op, pub,\ + cli_data, &bt_mesh_gen_level_cli_cb) int bt_mesh_gen_onoff_get(u16_t net_idx, u16_t addr, u16_t app_idx, u8_t *state); @@ -42,7 +41,6 @@ int bt_mesh_gen_level_get(u16_t net_idx, u16_t addr, u16_t app_idx, s16_t *level); int bt_mesh_gen_level_set(u16_t net_idx, u16_t addr, u16_t app_idx, s16_t val, s16_t *state); -int bt_mesh_gen_model_cli_init(struct bt_mesh_model *model, bool primary); #ifdef __cplusplus } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_srv.h b/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_srv.h index c4f4033df..e498ad346 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_srv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/mesh/model_srv.h @@ -11,43 +11,54 @@ extern "C" { #endif -struct bt_mesh_gen_onoff_srv_cb { +struct bt_mesh_gen_onoff_srv { + struct bt_mesh_model *model; + int (*get)(struct bt_mesh_model *model, u8_t *state); int (*set)(struct bt_mesh_model *model, u8_t state); }; extern const struct bt_mesh_model_op gen_onoff_srv_op[]; +extern const struct bt_mesh_model_cb gen_onoff_srv_cb; #define BT_MESH_MODEL_GEN_ONOFF_SRV(srv, pub) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, \ - gen_onoff_srv_op, pub, srv) + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, \ + gen_onoff_srv_op, pub, srv, &gen_onoff_srv_cb) + +struct bt_mesh_gen_level_srv { + struct bt_mesh_model *model; -struct bt_mesh_gen_level_srv_cb { int (*get)(struct bt_mesh_model *model, s16_t *level); int (*set)(struct bt_mesh_model *model, s16_t level); }; extern const struct bt_mesh_model_op gen_level_srv_op[]; +extern const struct bt_mesh_model_cb gen_level_srv_cb; #define BT_MESH_MODEL_GEN_LEVEL_SRV(srv, pub) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, \ - gen_level_srv_op, pub, srv) + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, \ + gen_level_srv_op, pub, srv, &gen_level_srv_cb) + +struct bt_mesh_light_lightness_srv { + struct bt_mesh_model *model; -struct bt_mesh_light_lightness_srv_cb { int (*get)(struct bt_mesh_model *model, s16_t *level); int (*set)(struct bt_mesh_model *model, s16_t level); }; extern const struct bt_mesh_model_op light_lightness_srv_op[]; +extern const struct bt_mesh_model_cb light_lightness_srv_cb; #define BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(srv, pub) \ - BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, \ - light_lightness_srv_op, pub, srv) + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, \ + light_lightness_srv_op, pub, srv, &light_lightness_srv_cb) - -void bt_mesh_set_gen_onoff_srv_cb(struct bt_mesh_gen_onoff_srv_cb *gen_onoff_cb); -void bt_mesh_set_gen_level_srv_cb(struct bt_mesh_gen_level_srv_cb *gen_level_cb); -void bt_mesh_set_light_lightness_srv_cb(struct bt_mesh_light_lightness_srv_cb *light_lightness_cb); +void bt_mesh_set_gen_onoff_srv_cb(int (*get)(struct bt_mesh_model *model, u8_t *state), + int (*set)(struct bt_mesh_model *model, u8_t state)); +void bt_mesh_set_gen_level_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level), + int (*set)(struct bt_mesh_model *model, s16_t level)); +void bt_mesh_set_light_lightness_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level), + int (*set)(struct bt_mesh_model *model, s16_t level)); #ifdef __cplusplus } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/ble.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/ble.h index 1d726958d..3fc2902ec 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/ble.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/ble.h @@ -73,13 +73,19 @@ struct ble_mbuf_hdr_rxinfo /* XXX: we could just use single phy_mode field */ int8_t phy; uint8_t phy_mode; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + int8_t rpa_index; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) void *user_data; #endif }; /* Flag definitions for rxinfo */ +#define BLE_MBUF_HDR_F_IGNORED (0x8000) +#define BLE_MBUF_HDR_F_SCAN_REQ_TXD (0x4000) #define BLE_MBUF_HDR_F_INITA_RESOLVED (0x2000) +#define BLE_MBUF_HDR_F_TARGETA_RESOLVED (0x2000) #define BLE_MBUF_HDR_F_EXT_ADV_SEC (0x1000) #define BLE_MBUF_HDR_F_EXT_ADV (0x0800) #define BLE_MBUF_HDR_F_RESOLVED (0x0400) @@ -89,7 +95,7 @@ struct ble_mbuf_hdr_rxinfo #define BLE_MBUF_HDR_F_DEVMATCH (0x0040) #define BLE_MBUF_HDR_F_MIC_FAILURE (0x0020) #define BLE_MBUF_HDR_F_SCAN_RSP_TXD (0x0010) -#define BLE_MBUF_HDR_F_SCAN_RSP_CHK (0x0008) +#define BLE_MBUF_HDR_F_SCAN_RSP_RXD (0x0008) #define BLE_MBUF_HDR_F_RXSTATE_MASK (0x0007) /* Transmit info. NOTE: no flags defined */ @@ -111,6 +117,12 @@ struct ble_mbuf_hdr uint32_t rem_usecs; }; +#define BLE_MBUF_HDR_IGNORED(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_IGNORED)) + +#define BLE_MBUF_HDR_SCAN_REQ_TXD(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_REQ_TXD)) + #define BLE_MBUF_HDR_EXT_ADV_SEC(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV_SEC)) @@ -120,8 +132,8 @@ struct ble_mbuf_hdr #define BLE_MBUF_HDR_DEVMATCH(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH)) -#define BLE_MBUF_HDR_SCAN_RSP_RCV(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_CHK)) +#define BLE_MBUF_HDR_SCAN_RSP_RXD(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD)) #define BLE_MBUF_HDR_AUX_INVALID(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_INVALID)) @@ -141,6 +153,9 @@ struct ble_mbuf_hdr #define BLE_MBUF_HDR_INITA_RESOLVED(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_INITA_RESOLVED)) +#define BLE_MBUF_HDR_TARGETA_RESOLVED(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED)) + #define BLE_MBUF_HDR_RX_STATE(hdr) \ ((uint8_t)((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RXSTATE_MASK)) @@ -235,11 +250,10 @@ enum ble_error_codes BLE_ERR_UNK_ADV_INDENT = 0x42, BLE_ERR_LIMIT_REACHED = 0x43, BLE_ERR_OPERATION_CANCELLED = 0x44, + BLE_ERR_PACKET_TOO_LONG = 0x45, BLE_ERR_MAX = 0xff }; -int ble_err_from_os(int os_err); - /* HW error codes */ #define BLE_HW_ERR_DO_NOT_USE (0) /* XXX: reserve this one for now */ #define BLE_HW_ERR_HCI_SYNC_LOSS (1) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/hci_common.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/hci_common.h index 1b049c88b..10b42e71d 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/hci_common.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/hci_common.h @@ -26,16 +26,22 @@ extern "C" { #endif -/* - * HCI Command Header - * - * Comprises the following fields - * -> Opcode group field & Opcode command field (2) - * -> Parameter Length (1) - * Length of all the parameters (does not include any part of the hci - * command header - */ -#define BLE_HCI_CMD_HDR_LEN (3) +#define BLE_HCI_MAX_DATA_LEN (MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE) - \ + sizeof(struct ble_hci_ev)) + +/* Generic command header */ +struct ble_hci_cmd { + uint16_t opcode; + uint8_t length; + uint8_t data[0]; +} __attribute__((packed)); + +/* Generic event header */ +struct ble_hci_ev { + uint8_t opcode; + uint8_t length; + uint8_t data[0]; +} __attribute__((packed)); #define BLE_HCI_OPCODE_NOP (0) @@ -64,173 +70,775 @@ extern "C" { /* List of OCF for Link Control commands (OGF=0x01) */ #define BLE_HCI_OCF_DISCONNECT_CMD (0x0006) +struct ble_hci_lc_disconnect_cp { + uint16_t conn_handle; + uint8_t reason; +} __attribute__((packed)); + #define BLE_HCI_OCF_RD_REM_VER_INFO (0x001D) +struct ble_hci_rd_rem_ver_info_cp { + uint16_t conn_handle; +} __attribute__((packed)); /* List of OCF for Controller and Baseband commands (OGF=0x03) */ #define BLE_HCI_OCF_CB_SET_EVENT_MASK (0x0001) +struct ble_hci_cb_set_event_mask_cp { + uint64_t event_mask; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_RESET (0x0003) + #define BLE_HCI_OCF_CB_READ_TX_PWR (0x002D) +struct ble_hci_cb_read_tx_pwr_cp { + uint16_t conn_handle; + uint8_t type; +} __attribute__((packed)); + +struct ble_hci_cb_read_tx_pwr_rp { + uint16_t conn_handle; + int8_t tx_level; +} __attribute__((packed)); + + #define BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC (0x0031) +struct ble_hci_cb_ctlr_to_host_fc_cp { + uint8_t enable; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_HOST_BUF_SIZE (0x0033) +struct ble_hci_cb_host_buf_size_cp { + uint16_t acl_data_len; + uint8_t sco_data_len; + uint16_t acl_num; + uint16_t sco_num; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS (0x0035) +struct ble_hci_cb_host_num_comp_pkts_entry { + uint16_t handle; + uint16_t count; +} __attribute__((packed)); +struct ble_hci_cb_host_num_comp_pkts_cp { + uint8_t handles; + struct ble_hci_cb_host_num_comp_pkts_entry h[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_SET_EVENT_MASK2 (0x0063) +struct ble_hci_cb_set_event_mask2_cp { + uint64_t event_mask2; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO (0x007B) +struct ble_hci_cb_rd_auth_pyld_tmo_cp { + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_cb_rd_auth_pyld_tmo_rp { + uint16_t conn_handle; + uint16_t tmo; +} __attribute__((packed)); + #define BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO (0x007C) +struct ble_hci_cb_wr_auth_pyld_tmo_cp { + uint16_t conn_handle; + uint16_t tmo; +} __attribute__((packed)); +struct ble_hci_cb_wr_auth_pyld_tmo_rp { + uint16_t conn_handle; +} __attribute__((packed)); /* List of OCF for Info Param commands (OGF=0x04) */ #define BLE_HCI_OCF_IP_RD_LOCAL_VER (0x0001) +struct ble_hci_ip_rd_local_ver_rp { + uint8_t hci_ver; + uint16_t hci_rev; + uint8_t lmp_ver; + uint16_t manufacturer; + uint16_t lmp_subver; +} __attribute__((packed)); + #define BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD (0x0002) +struct ble_hci_ip_rd_loc_supp_cmd_rp { + uint8_t commands[64]; +} __attribute__((packed)); + #define BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT (0x0003) +struct ble_hci_ip_rd_loc_supp_feat_rp { + uint64_t features; +} __attribute__((packed)); + #define BLE_HCI_OCF_IP_RD_BUF_SIZE (0x0005) +struct ble_hci_ip_rd_buf_size_rp { + uint16_t acl_data_len; + uint8_t sco_data_len; + uint16_t acl_num; + uint16_t sco_num; +} __attribute__((packed)); + #define BLE_HCI_OCF_IP_RD_BD_ADDR (0x0009) +struct ble_hci_ip_rd_bd_addr_rp { + uint8_t addr[6]; +} __attribute__((packed)); /* List of OCF for Status parameters commands (OGF = 0x05) */ #define BLE_HCI_OCF_RD_RSSI (0x0005) +struct ble_hci_rd_rssi_cp { + uint16_t handle; +} __attribute__((packed)); +struct ble_hci_rd_rssi_rp { + uint16_t handle; + int8_t rssi; +} __attribute__((packed)); /* List of OCF for LE commands (OGF = 0x08) */ #define BLE_HCI_OCF_LE_SET_EVENT_MASK (0x0001) +struct ble_hci_le_set_event_mask_cp { + uint64_t event_mask; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_BUF_SIZE (0x0002) +struct ble_hci_le_rd_buf_size_rp { + uint16_t data_len; + uint8_t data_packets; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT (0x0003) +struct ble_hci_le_rd_loc_supp_feat_rp { + uint64_t features; +} __attribute__((packed)); + /* NOTE: 0x0004 is intentionally left undefined */ #define BLE_HCI_OCF_LE_SET_RAND_ADDR (0x0005) +struct ble_hci_le_set_rand_addr_cp { + uint8_t addr[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_ADV_PARAMS (0x0006) +struct ble_hci_le_set_adv_params_cp { + uint16_t min_interval; + uint16_t max_interval; + uint8_t type; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t chan_map; + uint8_t filter_policy; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR (0x0007) +struct ble_hci_le_rd_adv_chan_txpwr_rp { + int8_t power_level; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_ADV_DATA (0x0008) +#define BLE_HCI_MAX_ADV_DATA_LEN (31) +struct ble_hci_le_set_adv_data_cp { + uint8_t adv_data_len; + uint8_t adv_data[BLE_HCI_MAX_ADV_DATA_LEN]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA (0x0009) +#define BLE_HCI_MAX_SCAN_RSP_DATA_LEN (31) +struct ble_hci_le_set_scan_rsp_data_cp { + uint8_t scan_rsp_len; + uint8_t scan_rsp[BLE_HCI_MAX_SCAN_RSP_DATA_LEN]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_ADV_ENABLE (0x000A) +struct ble_hci_le_set_adv_enable_cp { + uint8_t enable; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_SCAN_PARAMS (0x000B) +struct ble_hci_le_set_scan_params_cp { + uint8_t scan_type; + uint16_t scan_itvl; + uint16_t scan_window; + uint8_t own_addr_type; + uint8_t filter_policy; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_SCAN_ENABLE (0x000C) +struct ble_hci_le_set_scan_enable_cp { + uint8_t enable; + uint8_t filter_duplicates; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CREATE_CONN (0x000D) +struct ble_hci_le_create_conn_cp { + uint16_t scan_itvl; + uint16_t scan_window; + uint8_t filter_policy; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t own_addr_type; + uint16_t min_conn_itvl; + uint16_t max_conn_itvl; + uint16_t conn_latency; + uint16_t tmo; + uint16_t min_ce; + uint16_t max_ce; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CREATE_CONN_CANCEL (0x000E) + #define BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE (0x000F) +struct ble_hci_le_rd_white_list_rp { + uint8_t size; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CLEAR_WHITE_LIST (0x0010) + #define BLE_HCI_OCF_LE_ADD_WHITE_LIST (0x0011) +struct ble_hci_le_add_whte_list_cp { + uint8_t addr_type; + uint8_t addr[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RMV_WHITE_LIST (0x0012) +struct ble_hci_le_rmv_white_list_cp { + uint8_t addr_type; + uint8_t addr[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CONN_UPDATE (0x0013) +struct ble_hci_le_conn_update_cp { + uint16_t conn_handle; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS (0x0014) +struct ble_hci_le_set_host_chan_class_cp { + uint8_t chan_map[5]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_CHAN_MAP (0x0015) +struct ble_hci_le_rd_chan_map_cp { + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_rd_chan_map_rp { + uint16_t conn_handle; + uint8_t chan_map[5]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_REM_FEAT (0x0016) +struct ble_hci_le_rd_rem_feat_cp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_ENCRYPT (0x0017) +struct ble_hci_le_encrypt_cp { + uint8_t key[16]; + uint8_t data[16]; +} __attribute__((packed)); +struct ble_hci_le_encrypt_rp { + uint8_t data[16]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RAND (0x0018) +struct ble_hci_le_rand_rp { + uint64_t random_number; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_START_ENCRYPT (0x0019) +struct ble_hci_le_start_encrypt_cp { + uint16_t conn_handle; + uint64_t rand; + uint16_t div; + uint8_t ltk[16]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY (0x001A) +struct ble_hci_le_lt_key_req_reply_cp { + uint16_t conn_handle; + uint8_t ltk[16]; +} __attribute__((packed)); +struct ble_hci_le_lt_key_req_reply_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY (0x001B) +struct ble_hci_le_lt_key_req_neg_reply_cp { + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_lt_key_req_neg_reply_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_SUPP_STATES (0x001C) +struct ble_hci_le_rd_supp_states_rp { + uint64_t states; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RX_TEST (0x001D) +struct ble_hci_le_rx_test_cp { + uint8_t rx_chan; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_TX_TEST (0x001E) +struct ble_hci_le_tx_test_cp { + uint8_t tx_chan; + uint8_t test_data_len; + uint8_t payload; +} __attribute__((packed)); +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +struct ble_hci_le_tx_test_ext_cp { + uint8_t tx_chan; + uint8_t test_data_len; + uint8_t payload; + uint16_t interval; + uint16_t pkt_count; +} __attribute__((packed)); +#endif + #define BLE_HCI_OCF_LE_TEST_END (0x001F) +struct ble_hci_le_test_end_rp { + uint16_t num_packets; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_REM_CONN_PARAM_RR (0x0020) +struct ble_hci_le_rem_conn_param_rr_cp { + uint16_t conn_handle; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce; + uint16_t max_ce; +} __attribute__((packed)); +struct ble_hci_le_rem_conn_param_rr_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR (0x0021) +struct ble_hci_le_rem_conn_params_nrr_cp { + uint16_t conn_handle; + uint8_t reason; +} __attribute__((packed)); +struct ble_hci_le_rem_conn_params_nrr_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_DATA_LEN (0x0022) +struct ble_hci_le_set_data_len_cp { + uint16_t conn_handle; + uint16_t tx_octets; + uint16_t tx_time; +} __attribute__((packed)); +struct ble_hci_le_set_data_len_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN (0x0023) +struct ble_hci_le_rd_sugg_def_data_len_rp { + uint16_t max_tx_octets; + uint16_t max_tx_time; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN (0x0024) +struct ble_hci_le_wr_sugg_def_data_len_cp { + uint16_t max_tx_octets; + uint16_t max_tx_time; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_P256_PUBKEY (0x0025) + #define BLE_HCI_OCF_LE_GEN_DHKEY (0x0026) +struct ble_hci_le_gen_dhkey_cp { + uint8_t pkey[64]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_ADD_RESOLV_LIST (0x0027) +struct ble_hci_le_add_resolv_list_cp { + uint8_t peer_addr_type; + uint8_t peer_id_addr[6]; + uint8_t peer_irk[16]; + uint8_t local_irk[16]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RMV_RESOLV_LIST (0x0028) +struct ble_hci_le_rmv_resolve_list_cp { + uint8_t peer_addr_type; + uint8_t peer_id_addr[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CLR_RESOLV_LIST (0x0029) + #define BLE_HCI_OCF_LE_RD_RESOLV_LIST_SIZE (0x002A) +struct ble_hci_le_rd_resolv_list_size_rp { + uint8_t size; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR (0x002B) +struct ble_hci_le_rd_peer_recolv_addr_cp { + uint8_t peer_addr_type; + uint8_t peer_id_addr[6]; +} __attribute__((packed)); +struct ble_hci_le_rd_peer_recolv_addr_rp { + uint8_t rpa[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR (0x002C) +struct ble_hci_le_rd_local_recolv_addr_cp { + uint8_t peer_addr_type; + uint8_t peer_id_addr[6]; +} __attribute__((packed)); +struct ble_hci_le_rd_local_recolv_addr_rp { + uint8_t rpa[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_ADDR_RES_EN (0x002D) +struct ble_hci_le_set_addr_res_en_cp { + uint8_t enable; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_RPA_TMO (0x002E) +struct ble_hci_le_set_rpa_tmo_cp { + uint16_t rpa_timeout; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_MAX_DATA_LEN (0x002F) +struct ble_hci_le_rd_max_data_len_rp { + uint16_t max_tx_octests; + uint16_t max_tx_time; + uint16_t max_rx_octests; + uint16_t max_rx_time; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_PHY (0x0030) +struct ble_hci_le_rd_phy_cp { + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_rd_phy_rp { + uint16_t conn_handle; + uint8_t tx_phy; + uint8_t rx_phy; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_DEFAULT_PHY (0x0031) +struct ble_hci_le_set_default_phy_cp { + uint8_t all_phys; + uint8_t tx_phys; + uint8_t rx_phys; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_PHY (0x0032) -#define BLE_HCI_OCF_LE_ENH_RX_TEST (0x0033) -#define BLE_HCI_OCF_LE_ENH_TX_TEST (0x0034) +struct ble_hci_le_set_phy_cp { + uint16_t conn_handle; + uint8_t all_phys; + uint8_t tx_phys; + uint8_t rx_phys; + uint16_t phy_options; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_RX_TEST_V2 (0x0033) +struct ble_hci_le_rx_test_v2_cp { + uint8_t rx_chan; + uint8_t phy; + uint8_t index; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_TX_TEST_V2 (0x0034) +struct ble_hci_le_tx_test_v2_cp { + uint8_t tx_chan; + uint8_t test_data_len; + uint8_t payload; + uint8_t phy; +} __attribute__((packed)); +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +struct ble_hci_le_tx_test_v2_ext_cp { + uint8_t tx_chan; + uint8_t test_data_len; + uint8_t payload; + uint8_t phy; + uint16_t interval; + uint16_t pkt_count; +} __attribute__((packed)); +#endif + #define BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR (0x0035) +struct ble_hci_le_set_adv_set_rnd_addr_cp { + uint8_t adv_handle; + uint8_t addr[6]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM (0x0036) +struct ble_hci_le_set_ext_adv_params_cp { + uint8_t adv_handle; + uint16_t props; + uint8_t pri_itvl_min[3]; + uint8_t pri_itvl_max[3]; + uint8_t pri_chan_map; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t filter_policy; + int8_t tx_power; + uint8_t pri_phy; + uint8_t sec_max_skip; + uint8_t sec_phy; + uint8_t sid; + uint8_t scan_req_notif; +} __attribute__((packed)); +struct ble_hci_le_set_ext_adv_params_rp { + int8_t tx_power; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_ADV_DATA (0x0037) +struct ble_hci_le_set_ext_adv_data_cp { + uint8_t adv_handle; + uint8_t operation; + uint8_t fragment_pref; + uint8_t adv_data_len; + uint8_t adv_data[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA (0x0038) +struct ble_hci_le_set_ext_scan_rsp_data_cp { + uint8_t adv_handle; + uint8_t operation; + uint8_t fragment_pref; + uint8_t scan_rsp_len; + uint8_t scan_rsp[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE (0x0039) +struct adv_set { + uint8_t adv_handle; + uint16_t duration; + uint8_t max_events; +} __attribute__((packed)); +struct ble_hci_le_set_ext_adv_enable_cp { + uint8_t enable; + uint8_t num_sets; + struct adv_set sets[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_MAX_ADV_DATA_LEN (0x003A) +struct ble_hci_le_rd_max_adv_data_len_rp { + uint16_t max_adv_data_len; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS (0x003B) +struct ble_hci_le_rd_num_of_adv_sets_rp { + uint8_t num_sets; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_REMOVE_ADV_SET (0x003C) +struct ble_hci_le_remove_adv_set_cp { + uint8_t adv_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CLEAR_ADV_SETS (0x003D) + #define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS (0x003E) +struct ble_hci_le_set_periodic_adv_params_cp { + uint8_t adv_handle; + uint16_t min_itvl; + uint16_t max_itvl; + uint16_t props; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA (0x003F) +struct ble_hci_le_set_periodic_adv_data_cp { + uint8_t adv_handle; + uint8_t operation; + uint8_t adv_data_len; + uint8_t adv_data[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE (0x0040) +struct ble_hci_le_set_periodic_adv_enable_cp { + uint8_t enable; + uint8_t adv_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM (0x0041) +struct scan_params { + uint8_t type; + uint16_t itvl; + uint16_t window; +} __attribute__((packed)); +struct ble_hci_le_set_ext_scan_params_cp { + uint8_t own_addr_type; + uint8_t filter_policy; + uint8_t phys; + struct scan_params scans[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE (0x0042) +struct ble_hci_le_set_ext_scan_enable_cp { + uint8_t enable; + uint8_t filter_dup; + uint16_t duration; + uint16_t period; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_EXT_CREATE_CONN (0x0043) +struct conn_params { + uint16_t scan_itvl; + uint16_t scan_window; + uint16_t conn_min_itvl; + uint16_t conn_max_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce; + uint16_t max_ce; +} __attribute__((packed)); +struct ble_hci_le_ext_create_conn_cp { + uint8_t filter_policy; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t init_phy_mask; + struct conn_params conn_params[0]; +} __attribute__((packed)); + +#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER 0x01 +#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED 0x02 + #define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC (0x0044) +struct ble_hci_le_periodic_adv_create_sync_cp { + uint8_t options; + uint8_t sid; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint16_t skip; + uint16_t sync_timeout; + uint8_t sync_cte_type; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL (0x0045) + #define BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC (0x0046) +struct ble_hci_le_periodic_adv_term_sync_cp { + uint16_t sync_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST (0x0047) +struct ble_hci_le_add_dev_to_periodic_adv_list_cp { + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t sid; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST (0x0048) +struct ble_hci_le_rem_dev_from_periodic_adv_list_cp { + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t sid; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST (0x0049) + #define BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE (0x004A) +struct ble_hci_le_rd_periodic_adv_list_size_rp { + uint8_t list_size; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_TRANSMIT_POWER (0x004B) +struct ble_hci_le_rd_transmit_power_rp { + int8_t min_tx_power; + int8_t max_tx_power; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_RF_PATH_COMPENSATION (0x004C) +struct ble_hci_le_rd_rf_path_compensation_rp { + int16_t tx_path_compensation; + int16_t rx_path_compensation; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_WR_RF_PATH_COMPENSATION (0x004D) +struct ble_hci_le_wr_rf_path_compensation_cp { + int16_t tx_path_compensation; + int16_t rx_path_compensation; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_PRIVACY_MODE (0x004E) +struct ble_hci_le_set_privacy_mode_cp { + uint8_t peer_id_addr_type; + uint8_t peer_id_addr[6]; + uint8_t mode; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_RX_TEST_V3 (0x004F) +#define BLE_HCI_OCF_LE_TX_TEST_V3 (0x0050) +#define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS (0x0051) +#define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_ENABLE (0x0052) +#define BLE_HCI_OCF_LE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053) +#define BLE_HCI_OCF_LE_SET_CONN_CTE_RX_PARAMS (0x0054) +#define BLE_HCI_OCF_LE_SET_CONN_CTE_TX_PARAMS (0x0055) +#define BLE_HCI_OCF_LE_SET_CONN_CTE_REQ_ENABLE (0x0056) +#define BLE_HCI_OCF_LE_SET_CONN_CTE_RESP_ENABLE (0x0057) +#define BLE_HCI_OCF_LE_RD_ANTENNA_INFO (0x0058) + +#define BLE_HCI_OCF_LE_PERIODIC_ADV_RECEIVE_ENABLE (0x0059) +struct ble_hci_le_periodic_adv_receive_enable_cp { + uint16_t sync_handle; + uint8_t enable; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER (0x005A) +struct ble_hci_le_periodic_adv_sync_transfer_cp { + uint16_t conn_handle; + uint16_t service_data; + uint16_t sync_handle; +} __attribute__((packed)); +struct ble_hci_le_periodic_adv_sync_transfer_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_PERIODIC_ADV_SET_INFO_TRANSFER (0x005B) +struct ble_hci_le_periodic_adv_set_info_transfer_cp { + uint16_t conn_handle; + uint16_t service_data; + uint8_t adv_handle; +} __attribute__((packed)); +struct ble_hci_le_periodic_adv_set_info_transfer_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS (0x005C) +struct ble_hci_le_periodic_adv_sync_transfer_params_cp { + uint16_t conn_handle; + uint8_t mode; + uint16_t skip; + uint16_t sync_timeout; + uint8_t sync_cte_type; +} __attribute__((packed)); +struct ble_hci_le_periodic_adv_sync_transfer_params_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_DEFAULT_SYNC_TRANSFER_PARAMS (0x005D) +struct ble_hci_le_set_default_periodic_sync_transfer_params_cp { + uint8_t mode; + uint16_t skip; + uint16_t sync_timeout; + uint8_t sync_cte_type; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_GENERATE_DHKEY_V2 (0x005E) +#define BLE_HCI_OCF_LE_MODIFY_SCA (0x005F) + +#define BLE_HCI_OCF_LE_SET_HOST_FEAT (0x0074) +struct ble_hci_le_set_host_feat_cp { + uint8_t bit_num; + uint8_t val; +} __attribute__((packed)); /* Command Specific Definitions */ -#define BLE_HCI_VARIABLE_LEN (0xFF) - -/* --- Disconnect command (OGF 0x01, OCF 0x0006) --- */ -#define BLE_HCI_DISCONNECT_CMD_LEN (3) - -/* --- Set event mask (OGF 0x03, OCF 0x0001 --- */ -#define BLE_HCI_SET_EVENT_MASK_LEN (8) - /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ -#define BLE_HCI_CTLR_TO_HOST_FC_LEN (1) - #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) #define BLE_HCI_CTLR_TO_HOST_FC_ACL (1) #define BLE_HCI_CTLR_TO_HOST_FC_SYNC (2) #define BLE_HCI_CTLR_TO_HOST_FC_BOTH (3) -/* --- Host buffer size (OGF 0x03, OCF 0x0033) --- */ -#define BLE_HCI_HOST_BUF_SIZE_LEN (7) - -/* --- Host number of completed packets (OGF 0x03, OCF 0x0035) --- */ -#define BLE_HCI_HOST_NUM_COMP_PKTS_HDR_LEN (1) -#define BLE_HCI_HOST_NUM_COMP_PKTS_ENT_LEN (4) - -/* --- Read BD_ADDR (OGF 0x04, OCF 0x0009 --- */ -#define BLE_HCI_IP_RD_BD_ADDR_ACK_PARAM_LEN (6) - -/* --- Read buffer size (OGF 0x04, OCF 0x0005) --- */ -#define BLE_HCI_IP_RD_BUF_SIZE_LEN (0) -#define BLE_HCI_IP_RD_BUF_SIZE_RSPLEN (7) /* No status byte. */ - -/* --- Read/Write authenticated payload timeout (ocf 0x007B/0x007C) */ -#define BLE_HCI_RD_AUTH_PYLD_TMO_LEN (4) -#define BLE_HCI_WR_AUTH_PYLD_TMO_LEN (2) - -/* --- Read local version information (OGF 0x04, OCF 0x0001) --- */ -#define BLE_HCI_RD_LOC_VER_INFO_RSPLEN (8) /* No status byte. */ - -/* --- Read local supported command (OGF 0x04, OCF 0x0002) --- */ -#define BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN (64) /* No status byte. */ - -/* --- Read local supported features (OGF 0x04, OCF 0x0003) --- */ -#define BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN (8) /* No status byte. */ - -/* --- Read RSSI (OGF 0x05, OCF 0x0005) --- */ -#define BLE_HCI_READ_RSSI_LEN (2) -#define BLE_HCI_READ_RSSI_ACK_PARAM_LEN (3) /* No status byte. */ - -/* --- LE set event mask (OCF 0x0001) --- */ -#define BLE_HCI_SET_LE_EVENT_MASK_LEN (8) - -/* --- LE read buffer size (OCF 0x0002) --- */ -#define BLE_HCI_RD_BUF_SIZE_LEN (0) -#define BLE_HCI_RD_BUF_SIZE_RSPLEN (3) /* No status byte. */ - -/* --- LE read local supported features (OCF 0x0003) --- */ -#define BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN (8) /* No status byte. */ - -/* --- LE set random address (OCF 0x0005) */ -#define BLE_HCI_SET_RAND_ADDR_LEN (6) - /* --- LE set advertising parameters (OCF 0x0006) */ -#define BLE_HCI_SET_ADV_PARAM_LEN (15) - /* Advertising types */ #define BLE_HCI_ADV_TYPE_ADV_IND (0) #define BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD (1) @@ -263,23 +871,10 @@ extern "C" { #define BLE_HCI_ADV_PEER_ADDR_MAX (1) /* --- LE advertising channel tx power (OCF 0x0007) */ -#define BLE_HCI_ADV_CHAN_TXPWR_ACK_PARAM_LEN (2) /* Includes status byte. */ #define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) #define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) -/* --- LE set advertising data (OCF 0x0008) */ -#define BLE_HCI_MAX_ADV_DATA_LEN (31) -#define BLE_HCI_SET_ADV_DATA_LEN (32) - -/* --- LE set scan response data (OCF 0x0009) */ -#define BLE_HCI_MAX_SCAN_RSP_DATA_LEN (31) -#define BLE_HCI_SET_SCAN_RSP_DATA_LEN (32) - -/* --- LE set advertising enable (OCF 0x000a) */ -#define BLE_HCI_SET_ADV_ENABLE_LEN (1) - /* --- LE set scan enable (OCF 0x000c) */ -#define BLE_HCI_SET_SCAN_ENABLE_LEN (2) /* Connect peer address type */ #define BLE_HCI_CONN_PEER_ADDR_PUBLIC (0) @@ -316,7 +911,6 @@ extern "C" { #define BLE_HCI_ADV_CHANMASK_DEF (0x7) /* all channels */ /* Set scan parameters */ -#define BLE_HCI_SET_SCAN_PARAM_LEN (7) #define BLE_HCI_SCAN_TYPE_PASSIVE (0) #define BLE_HCI_SCAN_TYPE_ACTIVE (1) @@ -378,98 +972,19 @@ extern "C" { #define BLE_HCI_CONN_PEER_ADDR_RAND_ID (3) #define BLE_HCI_CONN_PEER_ADDR_MAX (3) -/* --- LE connection update (OCF 0x0013) */ -#define BLE_HCI_CONN_UPDATE_LEN (14) - -/* --- LE set host channel classification command (OCF 0x0014) */ -#define BLE_HCI_SET_HOST_CHAN_CLASS_LEN (5) - -/* --- LE read channel map command (OCF 0x0015) */ -#define BLE_HCI_RD_CHANMAP_LEN (2) -#define BLE_HCI_RD_CHANMAP_RSP_LEN (7) - -/* --- LE read remote features (OCF 0x0016) */ -#define BLE_HCI_CONN_RD_REM_FEAT_LEN (2) - -/* --- LE encrypt (OCF 0x0017) */ -#define BLE_HCI_LE_ENCRYPT_LEN (32) - -/* --- LE rand (OCF 0x0018) */ -#define BLE_HCI_LE_RAND_LEN (8) - -/* --- LE start encryption (OCF 0x0019) */ -#define BLE_HCI_LE_START_ENCRYPT_LEN (28) - -/* --- LE long term key request reply command (OCF 0x001a) */ -#define BLE_HCI_LT_KEY_REQ_REPLY_LEN (18) -#define BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN (2) /* No status byte. */ - -/* --- LE long term key request negative reply command (OCF 0x001b) */ -#define BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN (2) -#define BLE_HCI_LT_KEY_REQ_NEG_REPLY_ACK_PARAM_LEN (2) - -/* --- LE read supported states (OCF 0x001C) --- */ -#define BLE_HCI_RD_SUPP_STATES_RSPLEN (8) - -/* --- LE receiver test command (OCF 0x001D) --- */ -#define BLE_HCI_RX_TEST_LEN (1) - -/* --- LE transitter test command (OCF 0x001E) --- */ -#define BLE_HCI_TX_TEST_LEN (3) - -/* --- LE remote connection parameter request reply (OCF 0x0020) */ -#define BLE_HCI_CONN_PARAM_REPLY_LEN (14) - -/* --- LE remote connection parameter request negative reply (OCF 0x0021) */ -#define BLE_HCI_CONN_PARAM_NEG_REPLY_LEN (3) /* --- LE set data length (OCF 0x0022) */ -#define BLE_HCI_SET_DATALEN_LEN (6) -#define BLE_HCI_SET_DATALEN_ACK_PARAM_LEN (2) /* No status byte. */ #define BLE_HCI_SET_DATALEN_TX_OCTETS_MIN (0x001b) #define BLE_HCI_SET_DATALEN_TX_OCTETS_MAX (0x00fb) #define BLE_HCI_SET_DATALEN_TX_TIME_MIN (0x0148) #define BLE_HCI_SET_DATALEN_TX_TIME_MAX (0x4290) -/* --- LE read suggested default data length (OCF 0x0023) */ -#define BLE_HCI_RD_SUGG_DATALEN_RSPLEN (4) - -/* --- LE write suggested default data length (OCF 0x0024) */ -#define BLE_HCI_WR_SUGG_DATALEN_LEN (4) - -/* --- LE generate DHKEY command (OCF 0x0026) */ -#define BLE_HCI_GEN_DHKEY_LEN (64) - -/* --- LE add device to resolving list (OCF 0x0027) */ -#define BLE_HCI_ADD_TO_RESOLV_LIST_LEN (39) - -/* --- LE add device to resolving list (OCF 0x0028) */ -#define BLE_HCI_RMV_FROM_RESOLV_LIST_LEN (7) - -/* --- LE read peer resolvable address (OCF 0x002B) */ -#define BLE_HCI_RD_PEER_RESOLV_ADDR_LEN (7) - -/* --- LE read peer resolvable address (OCF 0x002C) */ -#define BLE_HCI_RD_LOC_RESOLV_ADDR_LEN (7) - -/* --- LE set address resolution enable (OCF 0x002D) */ -#define BLE_HCI_SET_ADDR_RESOL_ENA_LEN (1) - -/* --- LE set resolvable private address timeout (OCF 0x002E) */ -#define BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN (2) - -/* --- LE read maximum data length (OCF 0x002F) */ -#define BLE_HCI_RD_MAX_DATALEN_RSPLEN (8) - /* --- LE read maximum default PHY (OCF 0x0030) */ -#define BLE_HCI_LE_RD_PHY_LEN (2) -#define BLE_HCI_LE_RD_PHY_RSPLEN (4) #define BLE_HCI_LE_PHY_1M (1) #define BLE_HCI_LE_PHY_2M (2) #define BLE_HCI_LE_PHY_CODED (3) /* --- LE set default PHY (OCF 0x0031) */ -#define BLE_HCI_LE_SET_DEFAULT_PHY_LEN (3) #define BLE_HCI_LE_PHY_NO_TX_PREF_MASK (0x01) #define BLE_HCI_LE_PHY_NO_RX_PREF_MASK (0x02) #define BLE_HCI_LE_PHY_1M_PREF_MASK (0x01) @@ -481,27 +996,20 @@ extern "C" { BLE_HCI_LE_PHY_CODED_PREF_MASK) /* --- LE set PHY (OCF 0x0032) */ -#define BLE_HCI_LE_SET_PHY_LEN (7) #define BLE_HCI_LE_PHY_CODED_ANY (0x0000) #define BLE_HCI_LE_PHY_CODED_S2_PREF (0x0001) #define BLE_HCI_LE_PHY_CODED_S8_PREF (0x0002) /* --- LE enhanced receiver test (OCF 0x0033) */ -#define BLE_HCI_LE_ENH_RX_TEST_LEN (3) #define BLE_HCI_LE_PHY_1M (1) #define BLE_HCI_LE_PHY_2M (2) #define BLE_HCI_LE_PHY_CODED (3) /* --- LE enhanced transmitter test (OCF 0x0034) */ -#define BLE_HCI_LE_ENH_TX_TEST_LEN (4) #define BLE_HCI_LE_PHY_CODED_S8 (3) #define BLE_HCI_LE_PHY_CODED_S2 (4) -/* --- LE set advertising set random address (OCF 0x0035) */ -#define BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN (7) - /* --- LE set extended advertising parameters (OCF 0x0036) */ -#define BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN (25) #define BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE (0x0001) #define BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE (0x0002) #define BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED (0x0004) @@ -519,9 +1027,7 @@ extern "C" { /* --- LE set extended advertising data (OCF 0x0037) */ #define BLE_HCI_MAX_EXT_ADV_DATA_LEN (251) -#define BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN (4) -#define BLE_HCI_LE_SET_EXT_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN #define BLE_HCI_LE_SET_DATA_OPER_INT (0) #define BLE_HCI_LE_SET_DATA_OPER_FIRST (1) #define BLE_HCI_LE_SET_DATA_OPER_LAST (2) @@ -530,69 +1036,20 @@ extern "C" { /* --- LE set extended scan response data (OCF 0x0038) */ #define BLE_HCI_MAX_EXT_SCAN_RSP_DATA_LEN (251) -#define BLE_HCI_SET_EXT_SCAN_RSP_DATA_HDR_LEN (4) - -#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_LEN BLE_HCI_VARIABLE_LEN - - -/* --- LE set extended advertising enable (OCF 0x0039) */ -#define BLE_HCI_LE_SET_EXT_ADV_ENABLE_LEN BLE_HCI_VARIABLE_LEN - -/* --- LE remove advertising set (OCF 0x003C) */ -#define BLE_HCI_LE_REMOVE_ADV_SET_LEN (1) - -/* --- LE read maximum advertising data length (OCF 0x003A) */ -#define BLE_HCI_RD_MAX_ADV_DATA_LEN (2) - -/* --- LE read number of supported advertising sets (OCF 0x003B) */ -#define BLE_HCI_RD_NR_SUP_ADV_SETS (1) /* --- LE set periodic advertising parameters (OCF 0x003E) */ -#define BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN (7) #define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR (0x0040) #define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_MASK (0x0040) /* --- LE set periodic advertising data (OCF 0x003F) */ -#define BLE_HCI_LE_SET_PERIODIC_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN #define BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN (252) -#define BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN (3) - -/* --- LE periodic advertising enable (OCF 0x0040) */ -#define BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN (2) - -/* --- LE set extended scan parameters (OCF 0x0041) */ -#define BLE_HCI_LE_SET_EXT_SCAN_PARAM_LEN BLE_HCI_VARIABLE_LEN -#define BLE_HCI_LE_EXT_SCAN_BASE_LEN (3) -#define BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN (5) - -/* --- LE set extended scan enable (OCF 0x0042) */ -#define BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN (6) - -/* --- LE extended create connection (OCF 0x0043) */ -#define BLE_HCI_LE_EXT_CREATE_CONN_LEN BLE_HCI_VARIABLE_LEN -#define BLE_HCI_LE_EXT_CREATE_CONN_BASE_LEN (10) - -/* --- LE periodic advertising create sync (OCF 0x0044) */ -#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN (14) - -/* --- LE periodic advertising terminate (OCF 0x0046) */ -#define BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN (2) - -/* --- LE add device to periodic advertising list (OCF 0x0047) */ -#define BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN (8) /* --- LE remove device from periodic advertising list (OCF 0x0048) */ -#define BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN (8) - #define BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE 0x00 #define BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE 0x01 #define BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED 0x02 -/* --- LE write RF path (OCF 0x004D) */ -#define BLE_HCI_LE_WR_RF_PATH_COMPENSATION_LEN (4) - /* --- LE set privacy mode (OCF 0x004E) */ -#define BLE_HCI_LE_SET_PRIVACY_MODE_LEN (8) #define BLE_HCI_PRIVACY_NETWORK (0) #define BLE_HCI_PRIVACY_DEVICE (1) @@ -602,25 +1059,83 @@ extern "C" { #define BLE_HCI_EVCODE_CONN_DONE (0x03) #define BLE_HCI_EVCODE_CONN_REQUEST (0x04) #define BLE_HCI_EVCODE_DISCONN_CMP (0x05) +struct ble_hci_ev_disconn_cmp { + uint8_t status; + uint16_t conn_handle; + uint8_t reason; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_AUTH_CMP (0x06) #define BLE_HCI_EVCODE_REM_NAME_REQ_CMP (0x07) + #define BLE_HCI_EVCODE_ENCRYPT_CHG (0x08) +struct ble_hci_ev_enrypt_chg { + uint8_t status; + uint16_t connection_handle; + uint8_t enabled; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_CHG_LINK_KEY_CMP (0x09) #define BLE_HCI_EVCODE_MASTER_LINK_KEY_CMP (0x0A) #define BLE_HCI_EVCODE_RD_REM_SUPP_FEAT_CMP (0x0B) #define BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP (0x0C) +struct ble_hci_ev_rd_rem_ver_info_cmp { + uint8_t status; + uint16_t conn_handle; + uint8_t version; + uint16_t manufacturer; + uint16_t subversion; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_QOS_SETUP_CMP (0x0D) + #define BLE_HCI_EVCODE_COMMAND_COMPLETE (0x0E) +struct ble_hci_ev_command_complete { + uint8_t num_packets; + uint16_t opcode; + uint8_t status; + uint8_t return_params[0]; +} __attribute__((packed)); +/* NOP is exception and has no return parameters */ +struct ble_hci_ev_command_complete_nop { + uint8_t num_packets; + uint16_t opcode; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_COMMAND_STATUS (0x0F) +struct ble_hci_ev_command_status { + uint8_t status; + uint8_t num_packets; + uint16_t opcode; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_HW_ERROR (0x10) +struct ble_hci_ev_hw_error { + uint8_t hw_code; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_NUM_COMP_PKTS (0x13) +struct comp_pkt { + uint16_t handle; + uint16_t packets; +} __attribute__((packed));; +struct ble_hci_ev_num_comp_pkts { + uint8_t count; + struct comp_pkt completed[0]; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_MODE_CHANGE (0x14) #define BLE_HCI_EVCODE_RETURN_LINK_KEYS (0x15) #define BLE_HCI_EVCODE_PIN_CODE_REQ (0x16) #define BLE_HCI_EVCODE_LINK_KEY_REQ (0x17) #define BLE_HCI_EVCODE_LINK_KEY_NOTIFY (0x18) #define BLE_HCI_EVCODE_LOOPBACK_CMD (0x19) + #define BLE_HCI_EVCODE_DATA_BUF_OVERFLOW (0x1A) +struct ble_hci_ev_data_buf_overflow { + uint8_t link_type; +} __attribute__((packed)); + #define BLE_HCI_EVCODE_MAX_SLOTS_CHG (0x1B) #define BLE_HCI_EVCODE_READ_CLK_OFF_COMP (0x1C) #define BLE_HCI_EVCODE_CONN_PKT_TYPE_CHG (0x1D) @@ -635,7 +1150,13 @@ extern "C" { #define BLE_HCI_EVCODE_SYNCH_CONN_CHG (0x2D) #define BLE_HCI_EVCODE_SNIFF_SUBRATING (0x2E) #define BLE_HCI_EVCODE_EXT_INQ_RESULT (0x2F) + #define BLE_HCI_EVCODE_ENC_KEY_REFRESH (0x30) +struct ble_hci_ev_enc_key_refresh { + uint8_t status; + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_EVOCDE_IO_CAP_REQ (0x31) #define BLE_HCI_EVCODE_IO_CAP_RSP (0x32) #define BLE_HCI_EVCODE_USER_CONFIRM_REQ (0x33) @@ -648,7 +1169,13 @@ extern "C" { #define BLE_HCI_EVCODE_USER_PASSKEY_NOTIFY (0x3B) #define BLE_HCI_EVCODE_KEYPRESS_NOTIFY (0x3C) #define BLE_HCI_EVCODE_REM_HOST_SUPP_FEAT (0x3D) + #define BLE_HCI_EVCODE_LE_META (0x3E) +struct ble_hci_ev_le_meta { + uint8_t subevent; + uint8_t data[0]; +} __attribute__((packed)); + /* NOTE: 0x3F not defined */ #define BLE_HCI_EVCODE_PHYS_LINK_COMP (0x40) #define BLE_HCI_EVCODE_CHAN_SELECTED (0x41) @@ -673,63 +1200,251 @@ extern "C" { #define BLE_HCI_EVCODE_SLAVE_PAGE_RSP_TMO (0x54) #define BLE_HCI_EVCODE_SLAVE_BCAST_CHAN_MAP (0x55) #define BLE_HCI_EVCODE_INQ_RSP_NOTIFY (0x56) + #define BLE_HCI_EVCODE_AUTH_PYLD_TMO (0x57) +struct ble_hci_ev_auth_pyld_tmo { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_EVCODE_SAM_STATUS_CHG (0x58) + #define BLE_HCI_EVCODE_VENDOR_DEBUG (0xFF) +struct ble_hci_ev_vendor_debug { + uint8_t id; + uint8_t data[0]; +}__attribute__((packed)); /* LE sub-event codes */ #define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) +struct ble_hci_ev_le_subev_conn_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t role; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t mca; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_ADV_RPT (0x02) +struct adv_report { + uint8_t type; + uint8_t addr_type; + uint8_t addr[6]; + uint8_t data_len; + uint8_t data[0]; +} __attribute__((packed)); +struct ble_hci_ev_le_subev_adv_rpt { + uint8_t subev_code; + uint8_t num_reports; + struct adv_report reports[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE (0x03) +struct ble_hci_ev_le_subev_conn_upd_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT (0x04) +struct ble_hci_ev_le_subev_rd_rem_used_feat { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t features[8]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_LT_KEY_REQ (0x05) +struct ble_hci_ev_le_subev_lt_key_req { + uint8_t subev_code; + uint16_t conn_handle; + uint64_t rand; + uint16_t div; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ (0x06) +struct ble_hci_ev_le_subev_rem_conn_param_req { + uint8_t subev_code; + uint16_t conn_handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t timeout; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_DATA_LEN_CHG (0x07) +struct ble_hci_ev_le_subev_data_len_chg { + uint8_t subev_code; + uint16_t conn_handle; + uint16_t max_tx_octets; + uint16_t max_tx_time; + uint16_t max_rx_octets; + uint16_t max_rx_time; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_RD_LOC_P256_PUBKEY (0x08) +struct ble_hci_ev_le_subev_rd_loc_p256_pubkey { + uint8_t subev_code; + uint8_t status; + uint8_t public_key[64]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_GEN_DHKEY_COMPLETE (0x09) +struct ble_hci_ev_le_subev_gen_dhkey_complete { + uint8_t subev_code; + uint8_t status; + uint8_t dh_key[32]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE (0x0A) +struct ble_hci_ev_le_subev_enh_conn_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t role; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t local_rpa[6]; + uint8_t peer_rpa[6]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t mca; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT (0x0B) +struct dir_adv_report { + uint8_t type; + uint8_t addr_type; + uint8_t addr[6]; + uint8_t dir_addr_type; + uint8_t dir_addr[6]; + int8_t rssi; +} __attribute__((packed)); +struct ble_hci_ev_le_subev_direct_adv_rpt { + uint8_t subev_code; + uint8_t num_reports; + struct dir_adv_report reports[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE (0x0C) +struct ble_hci_ev_le_subev_phy_update_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t tx_phy; + uint8_t rx_phy; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_EXT_ADV_RPT (0x0D) +struct ext_adv_report { + uint16_t evt_type; + uint8_t addr_type; + uint8_t addr[6]; + uint8_t pri_phy; + uint8_t sec_phy; + uint8_t sid; + int8_t tx_power; + int8_t rssi; + uint16_t periodic_itvl; + uint8_t dir_addr_type; + uint8_t dir_addr[6]; + uint8_t data_len; + uint8_t data[0]; +} __attribute__((packed)); +struct ble_hci_ev_le_subev_ext_adv_rpt { + uint8_t subev_code; + uint8_t num_reports; + struct ext_adv_report reports[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E) +struct ble_hci_ev_le_subev_periodic_adv_sync_estab { + uint8_t subev_code; + uint8_t status; + uint16_t sync_handle; + uint8_t sid; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t phy; + uint16_t interval; + uint8_t aca; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT (0x0F) +struct ble_hci_ev_le_subev_periodic_adv_rpt { + uint8_t subev_code; + uint16_t sync_handle; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint8_t data_status; + uint8_t data_len; + uint8_t data[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST (0x10) +struct ble_hci_ev_le_subev_periodic_adv_sync_lost { + uint8_t subev_code; + uint16_t sync_handle; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT (0x11) +struct ble_hci_ev_le_subev_scan_timeout { + uint8_t subev_code; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED (0x12) +struct ble_hci_ev_le_subev_adv_set_terminated { + uint8_t subev_code; + uint8_t status; + uint8_t adv_handle; + uint16_t conn_handle; + uint8_t num_events; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD (0x13) +struct ble_hci_ev_le_subev_scan_req_rcvd { + uint8_t subev_code; + uint8_t adv_handle; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG (0x14) +struct ble_hci_ev_le_subev_chan_sel_alg { + uint8_t subev_code; + uint16_t conn_handle; + uint8_t csa; +} __attribute__((packed)); -/* Generic event header */ -#define BLE_HCI_EVENT_HDR_LEN (2) +#define BLE_HCI_LE_SUBEV_CONNLESS_IQ_RPT (0x15) +#define BLE_HCI_LE_SUBEV_CONN_IQ_RPT (0x16) +#define BLE_HCI_LE_SUBEV_CTE_REQ_FAILED (0x17) -/* Event specific definitions */ -/* Event disconnect complete */ -#define BLE_HCI_EVENT_DISCONN_COMPLETE_LEN (4) - -/* Event encryption change (code=0x08) */ -#define BLE_HCI_EVENT_ENCRYPT_CHG_LEN (4) - -/* Event hardware error (code=0x10) */ -#define BLE_HCI_EVENT_HW_ERROR_LEN (1) - -/* Event key refresh complete (code=0x30) */ -#define BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN (3) - -/* Event command complete */ -#define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN (5) -#define BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN (6) - -/* Event command status */ -#define BLE_HCI_EVENT_CMD_STATUS_LEN (6) - -/* Number of completed packets */ -#define BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN (1) -#define BLE_HCI_EVENT_NUM_COMP_PKTS_ENT_LEN (4) - -/* Read remote version informaton */ -#define BLE_HCI_EVENT_RD_RM_VER_LEN (8) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER (0x18) +struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint16_t service_data; + uint16_t sync_handle; + uint8_t sid; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t phy; + uint16_t interval; + uint8_t aca; +} __attribute__((packed)); /* Data buffer overflow event */ -#define BLE_HCI_EVENT_DATABUF_OVERFLOW_LEN (1) #define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) /* Advertising report */ @@ -747,11 +1462,7 @@ extern "C" { #define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND (0x1b) #define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_SCAN_IND (0x1a) -/* LE sub-event specific definitions */ -#define BLE_HCI_LE_MIN_LEN (1) /* Not including event hdr. */ - /* LE connection complete event (sub event 0x01) */ -#define BLE_HCI_LE_CONN_COMPLETE_LEN (19) #define BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER (0x00) #define BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE (0x01) @@ -759,53 +1470,9 @@ extern "C" { #define BLE_HCI_LE_CONN_HANDLE_MAX (0x0eff) /* LE advertising report event. (sub event 0x02) */ -#define BLE_HCI_LE_ADV_RPT_MIN_LEN (12) -#define BLE_HCI_LE_ADV_DIRECT_RPT_LEN (18) #define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN (1) #define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX (0x19) -/* Length of each record in an LE direct advertising report event. */ -#define BLE_HCI_LE_ADV_DIRECT_RPT_SUB_LEN (16) - -/* LE connection update complete event (sub event 0x03) */ -#define BLE_HCI_LE_CONN_UPD_LEN (10) - -/* LE long term key request event (sub event 0x05) */ -#define BLE_HCI_LE_LT_KEY_REQ_LEN (13) - -/* LE connection update complete event (sub event 0x03) */ -#define BLE_HCI_LE_RD_REM_USED_FEAT_LEN (12) - -/* LE remote connection parameter request event (sub event 0x06) */ -#define BLE_HCI_LE_REM_CONN_PARM_REQ_LEN (11) - -/* LE data length change event (sub event 0x07) */ -#define BLE_HCI_LE_DATA_LEN_CHG_LEN (11) - -/* LE PHY update complete event (sub event 0x0C) */ -#define BLE_HCI_LE_PHY_UPD_LEN (6) - -/* LE Periodic Advertising Sync Established Event (sub event 0x0e) */ -#define BLE_HCI_LE_PERIODIC_ADV_SYNC_ESTAB_LEN (16) - -/* LE Periodic Advertising Report Event (sub event 0x0f) */ -#define BLE_HCI_LE_PERIODIC_ADV_RPT_LEN (8) - -/* LE Periodic Advertising Sync Lost Event (sub event 0x10) */ -#define BLE_HCI_LE_PERIODIC_ADV_SYNC_LOST_LEN (3) - -/* LE Scan Timeout Event (sub event 0x11) */ -#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN (1) - -/* LE Advertising Set Terminated Event (sub event 0x12) */ -#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN (6) - -/* LE Scan Request Received event (sub event 0x13) */ -#define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD_LEN (9) - -/* LE Channel Selection Algorithm event (sub event 0x14) */ -#define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG_LEN (4) - /* Bluetooth Assigned numbers for version information.*/ #define BLE_HCI_VER_BCS_1_0b (0) #define BLE_HCI_VER_BCS_1_1 (1) @@ -817,6 +1484,8 @@ extern "C" { #define BLE_HCI_VER_BCS_4_1 (7) #define BLE_HCI_VER_BCS_4_2 (8) #define BLE_HCI_VER_BCS_5_0 (9) +#define BLE_HCI_VER_BCS_5_1 (10) +#define BLE_HCI_VER_BCS_5_2 (11) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -828,399 +1497,22 @@ extern "C" { #define BLE_LMP_VER_BCS_4_1 (7) #define BLE_LMP_VER_BCS_4_2 (8) #define BLE_LMP_VER_BCS_5_0 (9) +#define BLE_LMP_VER_BCS_5_1 (10) +#define BLE_LMP_VER_BCS_5_2 (11) -/* Sub-event 0x0A: enhanced connection complete */ -#define BLE_HCI_LE_ENH_CONN_COMPLETE_LEN (31) - -/*--- Shared data structures ---*/ - -/* Host buffer size (OGF=0x03, OCF=0x0033) */ -struct hci_host_buf_size -{ - uint16_t acl_pkt_len; - uint8_t sync_pkt_len; - uint16_t num_acl_pkts; - uint16_t num_sync_pkts; -}; - -/* Host number of completed packets (OGF=0x03, OCF=0x0035) */ -struct hci_host_num_comp_pkts_entry -{ - uint16_t conn_handle; - uint16_t num_pkts; -}; - -/* Read local version information (OGF=0x0004, OCF=0x0001) */ -struct hci_loc_ver_info -{ - uint8_t status; - uint8_t hci_version; - uint16_t hci_revision; - uint8_t lmp_pal_version; - uint16_t mfrg_name; - uint8_t lmp_pal_subversion; -}; - -/* set random address command (ocf = 0x0005) */ -struct hci_rand_addr -{ - uint8_t addr[6]; -}; - -/* set advertising parameters command (ocf = 0x0006) */ -struct hci_adv_params -{ - uint8_t adv_type; - uint8_t adv_channel_map; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t adv_filter_policy; - uint16_t adv_itvl_min; - uint16_t adv_itvl_max; - uint8_t peer_addr[BLE_DEV_ADDR_LEN]; -}; - -/* LE create connection command (ocf=0x000d). */ -struct hci_create_conn -{ - uint16_t scan_itvl; - uint16_t scan_window; - uint8_t filter_policy; - uint8_t peer_addr_type; - uint8_t peer_addr[BLE_DEV_ADDR_LEN]; - uint8_t own_addr_type; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -}; - -/* LE Read Local P-256 Public Key Complete Event */ -struct hci_le_subev_rd_loc_p256_pubkey { - uint8_t status; - uint8_t pubkey[64]; -} __attribute__((packed)); - -/* LE Generate DHKey Complete Event */ -struct hci_le_subev_gen_dhkey_complete { - uint8_t status; - uint8_t dhkey[32]; -} __attribute__((packed)); - -/* LE Directed Advertising Report Event */ -struct hci_le_subev_direct_adv_rpt_param { - uint8_t evt_type; - uint8_t addr_type; - uint8_t addr[6]; - uint8_t dir_addr_type; - uint8_t dir_addr[6]; - int8_t rssi; -} __attribute__((packed)); - -struct hci_le_subev_direct_adv_rpt { - uint8_t num_reports; - struct hci_le_subev_direct_adv_rpt_param params[0]; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_EXT_ADV) -/* LE create connection command (ocf=0x0043). */ -struct hci_ext_conn_params -{ - uint16_t scan_itvl; - uint16_t scan_window; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -}; - -struct hci_ext_create_conn -{ - uint8_t filter_policy; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[BLE_DEV_ADDR_LEN]; - uint8_t init_phy_mask; - struct hci_ext_conn_params params[3]; -}; - -struct hci_ext_adv_report_param { - uint16_t evt_type; - uint8_t addr_type; - uint8_t addr[6]; - uint8_t prim_phy; - uint8_t sec_phy; - uint8_t sid; - int8_t tx_power; - int8_t rssi; - uint16_t per_adv_itvl; - uint8_t dir_addr_type; - uint8_t dir_addr[6]; - uint8_t adv_data_len; - uint8_t adv_data[0]; -} __attribute__((packed)); - -struct hci_ext_adv_report { - /* We support one report per event for now */ - uint8_t subevt; - uint8_t num_reports; - struct hci_ext_adv_report_param params[0]; -} __attribute__((packed)); - -/* Ext Adv Set enable parameters, not in HCI order */ -struct hci_ext_adv_set -{ - uint8_t handle; - uint8_t events; - uint16_t duration; -}; - -/* Ext Advertising Parameters */ -struct hci_ext_adv_params -{ - uint16_t properties; - uint32_t min_interval; - uint32_t max_interval; - uint8_t chan_map; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t filter_policy; - int8_t tx_power; - uint8_t primary_phy; - uint8_t max_skip; - uint8_t secondary_phy; - uint8_t sid; - uint8_t scan_req_notif; -}; - -/* LE Extended Advertising Report Event */ -struct hci_le_subev_ext_adv_rpt { - uint8_t num_reports; - struct hci_ext_adv_report_param params[0]; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -/* LE Periodic Advertising Sync Established Event */ -struct hci_le_subev_periodic_adv_sync_estab { - uint8_t status; - uint16_t sync_handle; - uint8_t sid; - uint8_t adv_addr_type; - uint8_t adv_addr[6]; - uint8_t adv_phy; - uint16_t per_adv_ival; - uint8_t adv_clk_accuracy; -} __attribute__((packed)); - -/* LE Periodic Advertising Report Event */ -struct hci_le_subev_periodic_adv_rpt { - uint16_t sync_handle; - int8_t tx_power; - int8_t rssi; - uint8_t unused; - uint8_t data_status; - uint8_t data_length; - uint8_t data[0]; -} __attribute__((packed)); - -/* LE Periodic Advertising Sync Lost Event */ -struct hci_le_subev_periodic_adv_sync_lost { - uint16_t sync_handle; -} __attribute__((packed)); -#endif - -/* LE Advertising Set Terminated Event */ -struct hci_le_subev_adv_set_terminated { - uint8_t status; - uint8_t adv_handle; - uint16_t conn_handle; - uint8_t num_compl_ext_adv_ev; -} __attribute__((packed)); - -/* LE Scan Request Received Event */ -struct hci_le_subev_scan_req_rcvd { - uint8_t adv_handle; - uint8_t scan_addr_type; - uint8_t scan_addr[6]; -} __attribute__((packed)); +/* selected HCI and LMP version */ +#if MYNEWT_VAL(BLE_VERSION) == 50 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_0 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_0 +#elif MYNEWT_VAL(BLE_VERSION) == 51 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_1 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_1 +#elif MYNEWT_VAL(BLE_VERSION) == 52 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_2 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_2 #endif -/* LE Channel Selection Algorithm Event */ -struct hci_le_subev_chan_sel_alg { - uint16_t conn_handle; - uint8_t chan_sel_alg; -} __attribute__((packed)); - -/* LE connection update command (ocf=0x0013). */ -struct hci_conn_update -{ - uint16_t handle; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -}; - -/* LE start encryption command (ocf=0x0019) (note: fields out of order). */ -struct hci_start_encrypt -{ - uint16_t connection_handle; - uint16_t encrypted_diversifier; - uint64_t random_number; - uint8_t long_term_key[16]; -}; - -/* LE long term key request reply command (ocf=0x001a). */ -struct hci_lt_key_req_reply -{ - uint16_t conn_handle; - uint8_t long_term_key[16]; -}; - -/* LE Remote connection parameter request reply command */ -struct hci_conn_param_reply -{ - uint16_t handle; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -}; - -/* LE Remote connection parameter request negative reply command */ -struct hci_conn_param_neg_reply -{ - uint16_t handle; - uint8_t reason; -}; - -/* Encryption change event (code=0x08) (note: fields out of order) */ -struct hci_encrypt_change -{ - uint8_t status; - uint8_t encryption_enabled; - uint16_t connection_handle; -}; - -/* Encryption key refresh complete event (code=0x30) */ -struct hci_encrypt_key_refresh -{ - uint8_t status; - uint16_t connection_handle; -}; - -/* Connection complete LE meta subevent */ -struct hci_le_conn_complete -{ - uint8_t subevent_code; - uint8_t status; - uint16_t connection_handle; - uint8_t role; - uint8_t peer_addr_type; - uint8_t peer_addr[BLE_DEV_ADDR_LEN]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint8_t master_clk_acc; - uint8_t local_rpa[BLE_DEV_ADDR_LEN]; - uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; -}; - -/* Connection update complete LE meta subevent */ -struct hci_le_conn_upd_complete -{ - uint8_t subevent_code; - uint8_t status; - uint16_t connection_handle; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -}; - -/* Remote connection parameter request LE meta subevent */ -struct hci_le_conn_param_req -{ - uint8_t subevent_code; - uint16_t connection_handle; - uint16_t itvl_min; - uint16_t itvl_max; - uint16_t latency; - uint16_t timeout; -}; - -/* Read Remote Supported Features complete LE meta subevent */ -struct hci_le_rd_rem_supp_feat_complete -{ - uint8_t subevent_code; - uint8_t status; - uint16_t connection_handle; - uint8_t features[8]; -}; - -/* LE long term key request event (note: fields out of order). */ -struct hci_le_lt_key_req -{ - uint64_t random_number; - uint16_t connection_handle; - uint16_t encrypted_diversifier; - uint8_t subevent_code; -}; - -/* Disconnection complete event (note: fields out of order). */ -struct hci_disconn_complete -{ - uint16_t connection_handle; - uint8_t status; - uint8_t reason; -}; - -/* Read RSSI command-complete parameters (note: fields out of order). */ -struct hci_read_rssi_ack_params -{ - uint16_t connection_handle; - uint8_t status; - int8_t rssi; -}; - -/* PHY updated completed LE meta subevent */ -struct hci_le_phy_upd_complete -{ - uint8_t subevent_code; - uint8_t status; - uint16_t connection_handle; - uint8_t tx_phy; - uint8_t rx_phy; -}; - -/* LE Advertising Set Terminated subevent*/ -struct hci_le_adv_set_terminated -{ - uint8_t subevent_code; - uint8_t status; - uint8_t adv_handle; - uint16_t conn_handle; - uint8_t completed_events; -}; - -/* LE Scan Request Received subevent */ -struct hci_le_scan_req_rcvd -{ - uint8_t subevent_code; - uint8_t adv_handle; - uint8_t scan_addr_type; - uint8_t scan_addr[BLE_DEV_ADDR_LEN]; -}; - #define BLE_HCI_DATA_HDR_SZ 4 #define BLE_HCI_DATA_HANDLE(handle_pb_bc) (((handle_pb_bc) & 0x0fff) >> 0) #define BLE_HCI_DATA_PB(handle_pb_bc) (((handle_pb_bc) & 0x3000) >> 12) @@ -1237,16 +1529,6 @@ struct hci_data_hdr #define BLE_HCI_PB_FIRST_FLUSH 2 #define BLE_HCI_PB_FULL 3 -struct hci_add_dev_to_resolving_list { - uint8_t addr_type; - uint8_t addr[6]; - uint8_t local_irk[16]; - uint8_t peer_irk[16]; -}; - -/* External data structures */ -extern const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS]; - #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.c index a6a12316b..ff8e99997 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.c @@ -6,14 +6,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include -#include "mesh/mesh.h" - #include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ACCESS)) -#include "host/ble_hs_log.h" +#define MESH_LOG_MODULE BLE_MESH_ACCESS_LOG + +#include +#include + +#include "mesh/mesh.h" #include "mesh_priv.h" #include "adv.h" @@ -29,24 +28,6 @@ static const struct bt_mesh_comp *dev_comp; static u16_t dev_primary_addr; -static const struct { - const u16_t id; - int (*const init)(struct bt_mesh_model *model, bool primary); -} model_init[] = { - { BT_MESH_MODEL_ID_CFG_SRV, bt_mesh_cfg_srv_init }, - { BT_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_init }, -#if MYNEWT_VAL(BLE_MESH_CFG_CLI) - { BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_init }, -#endif -#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI) - { BT_MESH_MODEL_ID_HEALTH_CLI, bt_mesh_health_cli_init }, -#endif -#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) - { BT_MESH_MODEL_ID_GEN_ONOFF_CLI, bt_mesh_gen_model_cli_init }, - { BT_MESH_MODEL_ID_GEN_LEVEL_CLI, bt_mesh_gen_model_cli_init }, -#endif -}; - void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, @@ -101,7 +82,11 @@ s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) CODE_UNREACHABLE; } - return period >> mod->pub->period_div; + if (mod->pub->fast_period) { + return period >> mod->pub->period_div; + } else { + return period; + } } static s32_t next_period(struct bt_mesh_model *mod) @@ -146,7 +131,24 @@ static void publish_sent(int err, void *user_data) } } +static void publish_start(u16_t duration, int err, void *user_data) +{ + struct bt_mesh_model *mod = user_data; + struct bt_mesh_model_pub *pub = mod->pub; + + if (err) { + BT_ERR("Failed to publish: err %d", err); + return; + } + + /* Initialize the timestamp for the beginning of a new period */ + if (pub->count == BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit)) { + pub->period_start = k_uptime_get_32(); + } +} + static const struct bt_mesh_send_cb pub_sent_cb = { + .start = publish_start, .end = publish_sent, }; @@ -223,8 +225,6 @@ static void mod_publish(struct ble_npl_event *work) __ASSERT_NO_MSG(pub->update != NULL); - pub->period_start = k_uptime_get_32(); - err = pub->update(pub->mod); if (err) { BT_ERR("Failed to update publication message"); @@ -235,11 +235,6 @@ static void mod_publish(struct ble_npl_event *work) if (err) { BT_ERR("Publishing failed (err %d)", err); } - - if (pub->count) { - /* Retransmissions also control the timer */ - k_delayed_work_cancel(&pub->timer); - } } struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod) @@ -297,14 +292,8 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, mod->mod_idx = mod - elem->models; } - if (vnd) { - return; - } - - for (i = 0; i < ARRAY_SIZE(model_init); i++) { - if (model_init[i].id == mod->id) { - model_init[i].init(mod, primary); - } + if (mod->cb && mod->cb->init) { + mod->cb->init(mod); } } @@ -354,7 +343,7 @@ u16_t bt_mesh_primary_addr(void) return dev_primary_addr; } -u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr) +static u16_t *model_group_get(struct bt_mesh_model *mod, u16_t addr) { int i; @@ -367,6 +356,45 @@ u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr) return NULL; } +struct find_group_visitor_ctx { + u16_t *entry; + struct bt_mesh_model *mod; + u16_t addr; +}; + +static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, + u32_t depth, void *user_data) +{ + struct find_group_visitor_ctx *ctx = user_data; + + if (mod->elem_idx != ctx->mod->elem_idx) { + return BT_MESH_WALK_CONTINUE; + } + + ctx->entry = model_group_get(mod, ctx->addr); + if (ctx->entry) { + ctx->mod = mod; + return BT_MESH_WALK_STOP; + } + + return BT_MESH_WALK_CONTINUE; +} + +u16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, u16_t addr) +{ + struct find_group_visitor_ctx ctx = { + .mod = *mod, + .entry = NULL, + .addr = addr, + }; + + bt_mesh_model_tree_walk(bt_mesh_model_root(*mod), + find_group_mod_visitor, &ctx); + + *mod = ctx.mod; + return ctx.entry; +} + static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, u16_t group_addr) { @@ -377,7 +405,7 @@ static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, for (i = 0; i < elem->model_count; i++) { model = &elem->models[i]; - match = bt_mesh_model_find_group(model, group_addr); + match = model_group_get(model, group_addr); if (match) { return model; } @@ -386,7 +414,7 @@ static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, for (i = 0; i < elem->vnd_model_count; i++) { model = &elem->vnd_models[i]; - match = bt_mesh_model_find_group(model, group_addr); + match = model_group_get(model, group_addr); if (match) { return model; } @@ -397,17 +425,21 @@ static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr) { - int i; + u16_t index; - for (i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; + if (BT_MESH_ADDR_IS_UNICAST(addr)) { + index = (addr - dev_comp->elem[0].addr); + if (index < dev_comp->elem_count) { + return &dev_comp->elem[index]; + } else { + return NULL; + } + } - if (BT_MESH_ADDR_IS_GROUP(addr) || - BT_MESH_ADDR_IS_VIRTUAL(addr)) { - if (bt_mesh_elem_find_group(elem, addr)) { - return elem; - } - } else if (elem->addr == addr) { + for (index = 0; index < dev_comp->elem_count; index++) { + struct bt_mesh_elem *elem = &dev_comp->elem[index]; + + if (bt_mesh_elem_find_group(elem, addr)) { return elem; } } @@ -425,7 +457,9 @@ static bool model_has_key(struct bt_mesh_model *mod, u16_t key) int i; for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { - if (mod->keys[i] == key) { + if (mod->keys[i] == key || + (mod->keys[i] == BT_MESH_KEY_DEV_ANY && + BT_MESH_IS_DEV_KEY(key))) { return true; } } @@ -433,9 +467,19 @@ static bool model_has_key(struct bt_mesh_model *mod, u16_t key) return false; } +static bool model_has_dst(struct bt_mesh_model *mod, u16_t dst) +{ + if (BT_MESH_ADDR_IS_UNICAST(dst)) { + return (dev_comp->elem[mod->elem_idx].addr == dst); + } else if (BT_MESH_ADDR_IS_GROUP(dst) || BT_MESH_ADDR_IS_VIRTUAL(dst)) { + return bt_mesh_model_find_group(&mod, dst); + } + + return (mod->elem_idx == 0 && bt_mesh_fixed_group_match(dst)); +} + static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, - u8_t model_count, u16_t dst, - u16_t app_idx, u32_t opcode, + u8_t model_count, u32_t opcode, struct bt_mesh_model **model) { u8_t i; @@ -445,17 +489,6 @@ static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, *model = &models[i]; - if (BT_MESH_ADDR_IS_GROUP(dst) || - BT_MESH_ADDR_IS_VIRTUAL(dst)) { - if (!bt_mesh_model_find_group(*model, dst)) { - continue; - } - } - - if (!model_has_key(*model, app_idx)) { - continue; - } - for (op = (*model)->op; op->func; op++) { if (op->opcode == opcode) { return op; @@ -508,8 +541,7 @@ bool bt_mesh_fixed_group_match(u16_t addr) case BT_MESH_ADDR_ALL_NODES: return true; case BT_MESH_ADDR_PROXIES: - /* TODO: Proxy not yet supported */ - return false; + return (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); case BT_MESH_ADDR_FRIENDS: return (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED); case BT_MESH_ADDR_RELAYS: @@ -540,24 +572,13 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) for (i = 0; i < dev_comp->elem_count; i++) { struct bt_mesh_elem *elem = &dev_comp->elem[i]; - - if (BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) { - if (elem->addr != rx->ctx.recv_dst) { - continue; - } - } else if (BT_MESH_ADDR_IS_GROUP(rx->ctx.recv_dst) || - BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { - /* find_op() will do proper model/group matching */ - } else if (i != 0 || - !bt_mesh_fixed_group_match(rx->ctx.recv_dst)) { - continue; - } + struct net_buf_simple_state state; /* SIG models cannot contain 3-byte (vendor) OpCodes, and * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so * we only need to do the lookup in one of the model lists. */ - if (opcode < 0x10000) { + if (BT_MESH_MODEL_OP_LEN(opcode) < 3) { models = elem->models; count = elem->model_count; } else { @@ -565,29 +586,32 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) count = elem->vnd_model_count; } - op = find_op(models, count, rx->ctx.recv_dst, rx->ctx.app_idx, - opcode, &model); - if (op) { - struct net_buf_simple_state state; + op = find_op(models, count, opcode, &model); + if (!op) { + BT_DBG("No OpCode 0x%08x for elem %d", opcode, i); + continue; + } - if (buf->om_len < op->min_len) { - BT_ERR("Too short message for OpCode 0x%08x", - (unsigned) opcode); + if (!model_has_key(model, rx->ctx.app_idx)) { continue; } - /* The callback will likely parse the buffer, so - * store the parsing state in case multiple models - * receive the message. - */ - net_buf_simple_save(buf, &state); - op->func(model, &rx->ctx, buf); - net_buf_simple_restore(buf, &state); - - } else { - BT_DBG("No OpCode 0x%08x for elem %d", - (unsigned) opcode, i); + if (!model_has_dst(model, rx->ctx.recv_dst)) { + continue; } + + if (buf->om_len < op->min_len) { + BT_ERR("Too short message for OpCode 0x%08x", opcode); + continue; + } + + /* The callback will likely parse the buffer, so + * store the parsing state in case multiple models + * receive the message. + */ + net_buf_simple_save(buf, &state); + op->func(model, &rx->ctx, buf); + net_buf_simple_restore(buf, &state); } } @@ -595,21 +619,21 @@ void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode) { net_buf_simple_init(msg, 0); - if (opcode < 0x100) { - /* 1-byte OpCode */ + switch (BT_MESH_MODEL_OP_LEN(opcode)) { + case 1: net_buf_simple_add_u8(msg, opcode); - return; - } - - if (opcode < 0x10000) { - /* 2-byte OpCode */ + break; + case 2: net_buf_simple_add_be16(msg, opcode); - return; + break; + case 3: + net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); + net_buf_simple_add_le16(msg, opcode & 0xffff); + break; + default: + BT_WARN("Unknown opcode format"); + break; } - - /* 3-byte OpCode */ - net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); - net_buf_simple_add_le16(msg, opcode & 0xffff); } static int model_send(struct bt_mesh_model *model, @@ -732,7 +756,7 @@ done: return err; } -struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, +struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, u16_t company, u16_t id) { u8_t i; @@ -747,7 +771,7 @@ struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, return NULL; } -struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem, +struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, u16_t id) { u8_t i; @@ -765,3 +789,68 @@ const struct bt_mesh_comp *bt_mesh_comp_get(void) { return dev_comp; } + +struct bt_mesh_model *bt_mesh_model_root(struct bt_mesh_model *mod) +{ +#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS + while (mod->next) { + mod = mod->next; + } +#endif + return mod; +} + +void bt_mesh_model_tree_walk(struct bt_mesh_model *root, + enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, + u32_t depth, + void *user_data), + void *user_data) +{ + struct bt_mesh_model *m = root; + u32_t depth = 0; + + do { + if (cb(m, depth, user_data) == BT_MESH_WALK_STOP) { + return; + } +#if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) + if (m->extends) { + m = m->extends; + depth++; + } else if (m->flags & BT_MESH_MOD_NEXT_IS_PARENT) { + m = m->next->next; + depth--; + } else { + m = m->next; + } +#endif + } while (m && m != root); +} + +#if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) +int bt_mesh_model_extend(struct bt_mesh_model *mod, + struct bt_mesh_model *base_mod) +{ + /* Form a cyclical LCRS tree: + * The extends-pointer points to the first child, and the next-pointer + * points to the next sibling. The last sibling is marked by the + * BT_MESH_MOD_NEXT_IS_PARENT flag, and its next-pointer points back to + * the parent. This way, the whole tree is accessible from any node. + * + * We add children (extend them) by inserting them as the first child. + */ + if (base_mod->next) { + return -EALREADY; + } + + if (mod->extends) { + base_mod->next = mod->extends; + } else { + base_mod->next = mod; + base_mod->flags |= BT_MESH_MOD_NEXT_IS_PARENT; + } + + mod->extends = base_mod; + return 0; +} +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.h index 5ce7f1990..48514983f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/access.h @@ -16,6 +16,14 @@ enum { BT_MESH_MOD_BIND_PENDING = BIT(0), BT_MESH_MOD_SUB_PENDING = BIT(1), BT_MESH_MOD_PUB_PENDING = BIT(2), + BT_MESH_MOD_DATA_PRESENT = BIT(3), + BT_MESH_MOD_NEXT_IS_PARENT = BIT(4), +}; + +/* Tree walk return codes */ +enum bt_mesh_walk { + BT_MESH_WALK_STOP, + BT_MESH_WALK_CONTINUE, }; void bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count); @@ -25,12 +33,14 @@ u8_t bt_mesh_elem_count(void); /* Find local element based on unicast or group address */ struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr); -struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, - u16_t company, u16_t id); -struct bt_mesh_model * bt_mesh_model_find(struct bt_mesh_elem *elem, - u16_t id); +struct bt_mesh_model *bt_mesh_model_root(struct bt_mesh_model *mod); +void bt_mesh_model_tree_walk(struct bt_mesh_model *root, + enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, + u32_t depth, + void *user_data), + void *user_data); -u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr); +u16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, u16_t addr); bool bt_mesh_fixed_group_match(u16_t addr); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c index 5364ddc73..b8fb1c7de 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c @@ -7,12 +7,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "mesh/mesh.h" - #include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ADV)) -#include "host/ble_hs_log.h" +#define MESH_LOG_MODULE BLE_MESH_ADV_LOG +#include "mesh/mesh.h" #include "host/ble_hs_adv.h" #include "host/ble_gap.h" #include "nimble/hci_common.h" @@ -108,9 +106,14 @@ static inline void adv_send(struct os_mbuf *buf) adv_int = max(adv_int_min, BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); +#if MYNEWT_VAL(BLE_CONTROLLER) + duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * + (adv_int + 10)); +#else duration = (MESH_SCAN_WINDOW_MS + ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * (adv_int + 10))); +#endif BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type, buf->om_len, bt_hex(buf->om_data, buf->om_len)); @@ -188,6 +191,8 @@ mesh_adv_thread(void *args) if (BT_MESH_ADV(buf)->busy) { BT_MESH_ADV(buf)->busy = 0; adv_send(buf); + } else { + net_buf_unref(buf); } /* os_sched(NULL); */ @@ -395,6 +400,8 @@ done: int bt_mesh_scan_enable(void) { + int err; + #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params uncoded_params = { .itvl = MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW, @@ -402,7 +409,7 @@ int bt_mesh_scan_enable(void) BT_DBG(""); - return ble_gap_ext_disc(g_mesh_addr_type, 0, 0, 0, 0, 0, + err = ble_gap_ext_disc(g_mesh_addr_type, 0, 0, 0, 0, 0, &uncoded_params, NULL, NULL, NULL); #else struct ble_gap_disc_params scan_param = @@ -411,13 +418,28 @@ int bt_mesh_scan_enable(void) BT_DBG(""); - return ble_gap_disc(g_mesh_addr_type, BLE_HS_FOREVER, &scan_param, NULL, NULL); + err = ble_gap_disc(g_mesh_addr_type, BLE_HS_FOREVER, &scan_param, + NULL, NULL); #endif + if (err && err != BLE_HS_EALREADY) { + BT_ERR("starting scan failed (err %d)", err); + return err; + } + + return 0; } int bt_mesh_scan_disable(void) { + int err; + BT_DBG(""); - return ble_gap_disc_cancel(); + err = ble_gap_disc_cancel(); + if (err && err != BLE_HS_EALREADY) { + BT_ERR("stopping scan failed (err %d)", err); + return err; + } + + return 0; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h index 8e76e4197..4d0f7d8ba 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h @@ -42,15 +42,12 @@ struct bt_mesh_adv { busy:1; u8_t xmit; - union { - /* Address, used e.g. for Friend Queue messages */ - u16_t addr; + /* For transport layer segment sending */ + struct { + u8_t attempts; + } seg; - /* For transport layer segment sending */ - struct { - u8_t attempts; - } seg; - }; + u8_t flags; int ref_cnt; struct ble_npl_event ev; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c index da909852f..cd540aa8c 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c @@ -6,15 +6,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_BEACON_LOG + #include #include #include "os/os_mbuf.h" #include "mesh/mesh.h" -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_BEACON)) -#include "host/ble_hs_log.h" - #include "adv.h" #include "mesh_priv.h" #include "net.h" @@ -147,7 +146,6 @@ static int secure_beacon_send(void) static int unprovisioned_beacon_send(void) { -#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) const struct bt_mesh_prov *prov; u8_t uri_hash[16] = { 0 }; struct os_mbuf *buf; @@ -199,10 +197,43 @@ static int unprovisioned_beacon_send(void) net_buf_unref(buf); } -#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ return 0; } +static void unprovisioned_beacon_recv(struct os_mbuf *buf) +{ +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + const struct bt_mesh_prov *prov; + u8_t *uuid; + u16_t oob_info; + u32_t uri_hash_val; + u32_t *uri_hash = NULL; + + if (buf->om_len != 18 && buf->om_len != 22) { + BT_ERR("Invalid unprovisioned beacon length (%u)", buf->om_len); + return; + } + + uuid = net_buf_simple_pull_mem(buf, 16); + oob_info = net_buf_simple_pull_be16(buf); + + if (buf->om_len == 4) { + uri_hash_val = net_buf_simple_pull_be32(buf); + uri_hash = &uri_hash_val; + } + + BT_DBG("uuid %s", bt_hex(uuid, 16)); + + prov = bt_mesh_prov_get(); + + if (prov->unprovisioned_beacon) { + prov->unprovisioned_beacon(uuid, + (bt_mesh_prov_oob_info_t)oob_info, + uri_hash); + } +#endif +} + static void update_beacon_observation(void) { static bool first_half; @@ -249,11 +280,10 @@ static void beacon_send(struct ble_npl_event *work) k_delayed_work_submit(&beacon_timer, PROVISIONED_INTERVAL); } - } else { + } else if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) { unprovisioned_beacon_send(); k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); } - } static void secure_beacon_recv(struct os_mbuf *buf) @@ -351,7 +381,7 @@ void bt_mesh_beacon_recv(struct os_mbuf *buf) type = net_buf_simple_pull_u8(buf); switch (type) { case BEACON_TYPE_UNPROVISIONED: - BT_DBG("Ignoring unprovisioned device beacon"); + unprovisioned_beacon_recv(buf); break; case BEACON_TYPE_SECURE: secure_beacon_recv(buf); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c index 17f01b993..2c2f6c3ff 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c @@ -7,9 +7,9 @@ */ #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG #if MYNEWT_VAL(BLE_MESH_CFG_CLI) -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) #include "mesh/mesh.h" #include @@ -21,6 +21,9 @@ #define CID_NVAL 0xffff +/* 2 byte dummy opcode for getting compile time buffer sizes. */ +#define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff) + struct comp_data { u8_t *status; struct os_mbuf *comp; @@ -481,6 +484,38 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { BT_MESH_MODEL_OP_END, }; +static int cfg_cli_init(struct bt_mesh_model *model) +{ + BT_DBG(""); + + if (!bt_mesh_model_in_primary(model)) { + BT_ERR("Configuration Client only allowed in primary element"); + return -EINVAL; + } + + if (!model->user_data) { + BT_ERR("No Configuration Client context provided"); + return -EINVAL; + } + + cli = model->user_data; + cli->model = model; + + /* + * Configuration Model security is device-key based and both the local + * and remote keys are allowed to access this model. + */ + model->keys[0] = BT_MESH_KEY_DEV_ANY; + + k_sem_init(&cli->op_sync, 0, 1); + + return 0; +} + +const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb = { + .init = cfg_cli_init, +}; + static int cli_prepare(void *param, u32_t op) { if (!cli) { @@ -519,10 +554,10 @@ static int cli_wait(void) int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, u8_t *status, struct os_mbuf *comp) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEV_COMP_DATA_GET, 1); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -556,10 +591,10 @@ done: static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp, u8_t *val) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -588,10 +623,10 @@ done: static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp, u8_t new_val, u8_t *val) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 1); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -670,10 +705,10 @@ int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val, int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status, u8_t *transmit) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_GET, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -706,10 +741,10 @@ done: int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay, u8_t new_transmit, u8_t *status, u8_t *transmit) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_SET, 2); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -744,10 +779,10 @@ done: int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, const u8_t net_key[16], u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 18 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_ADD, 18); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -788,10 +823,10 @@ int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16], u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 19 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_ADD, 19); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -833,10 +868,10 @@ static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_BIND, 8); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -904,10 +939,10 @@ int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 8); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1014,10 +1049,10 @@ static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id, u16_t cid, u16_t *virt_addr, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 22 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 22); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1133,10 +1168,10 @@ static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid, struct bt_mesh_cfg_mod_pub *pub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 6 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_GET, 6); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1205,10 +1240,10 @@ static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid, struct bt_mesh_cfg_mod_pub *pub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 13 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_SET, 13); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1230,7 +1265,7 @@ static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, net_buf_simple_add_le16(msg, elem_addr); net_buf_simple_add_le16(msg, pub->addr); - net_buf_simple_add_le16(msg, (pub->app_idx & (pub->cred_flag << 12))); + net_buf_simple_add_le16(msg, (pub->app_idx | (pub->cred_flag << 12))); net_buf_simple_add_u8(msg, pub->ttl); net_buf_simple_add_u8(msg, pub->period); net_buf_simple_add_u8(msg, pub->transmit); @@ -1281,10 +1316,10 @@ int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_SET, 5); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1325,10 +1360,10 @@ done: int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_GET, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1366,10 +1401,10 @@ done: int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr, const struct bt_mesh_cfg_hb_pub *pub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_SET, 9); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV, + .app_idx = BT_MESH_KEY_DEV_REMOTE, .addr = addr, .send_ttl = BT_MESH_TTL_DEFAULT, }; @@ -1412,7 +1447,7 @@ done: int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_pub *pub, u8_t *status) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_GET, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = BT_MESH_KEY_DEV, @@ -1460,29 +1495,4 @@ void bt_mesh_cfg_cli_timeout_set(s32_t timeout) msg_timeout = timeout; } -int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary) -{ - BT_DBG("primary %u", primary); - - if (!primary) { - BT_ERR("Configuration Client only allowed in primary element"); - return -EINVAL; - } - - if (!model->user_data) { - BT_ERR("No Configuration Client context provided"); - return -EINVAL; - } - - cli = model->user_data; - cli->model = model; - - /* Configuration Model security is device-key based */ - model->keys[0] = BT_MESH_KEY_DEV; - - k_sem_init(&cli->op_sync, 0, 1); - - return 0; -} - #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c index 4ee9e8cfd..57aac90a3 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c @@ -6,16 +6,15 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + #include #include #include #include "mesh/mesh.h" -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_MODEL) -#include "host/ble_hs_log.h" - #include "mesh_priv.h" #include "adv.h" #include "net.h" @@ -34,61 +33,7 @@ static struct bt_mesh_cfg_srv *conf; -static struct label { - u16_t ref; - u16_t addr; - u8_t uuid[16]; -} labels[MYNEWT_VAL(BLE_MESH_LABEL_COUNT)]; - -static void hb_send(struct bt_mesh_model *model) -{ - - struct bt_mesh_cfg_srv *cfg = model->user_data; - u16_t feat = 0; - struct __packed { - u8_t init_ttl; - u16_t feat; - } hb; - struct bt_mesh_msg_ctx ctx = { - .net_idx = cfg->hb_pub.net_idx, - .app_idx = BT_MESH_KEY_UNUSED, - .addr = cfg->hb_pub.dst, - .send_ttl = cfg->hb_pub.ttl, - }; - struct bt_mesh_net_tx tx = { - .sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx), - .ctx = &ctx, - .src = bt_mesh_model_elem(model)->addr, - .xmit = bt_mesh_net_transmit_get(), - }; - - hb.init_ttl = cfg->hb_pub.ttl; - - if (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED) { - feat |= BT_MESH_FEAT_RELAY; - } - - if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { - feat |= BT_MESH_FEAT_PROXY; - } - - if (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED) { - feat |= BT_MESH_FEAT_FRIEND; - } - -#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) - if (bt_mesh.lpn.state != BT_MESH_LPN_DISABLED) { - feat |= BT_MESH_FEAT_LOW_POWER; - } -#endif - - hb.feat = sys_cpu_to_be16(feat); - - BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); - - bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), - NULL, NULL, NULL); -} +static struct label labels[CONFIG_BT_MESH_LABEL_COUNT]; static int comp_add_elem(struct os_mbuf *buf, struct bt_mesh_elem *elem, bool primary) @@ -175,9 +120,9 @@ static void dev_comp_data_get(struct bt_mesh_model *model, bt_hex(buf->om_data, buf->om_len)); page = net_buf_simple_pull_u8(buf); - if (page != 0) { - BT_WARN("Composition page %u not available", page); - page = 0; + if (page != 0U) { + BT_DBG("Composition page %u not available", page); + page = 0U; } bt_mesh_model_msg_init(sdu, OP_DEV_COMP_DATA_STATUS); @@ -481,7 +426,7 @@ static void app_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -508,7 +453,7 @@ static void app_key_update(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -564,7 +509,7 @@ static void app_key_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; struct bt_mesh_app_key *key; u8_t status; @@ -617,8 +562,8 @@ static void app_key_get(struct bt_mesh_model *model, struct os_mbuf *buf) { struct os_mbuf *msg = - NET_BUF_SIMPLE(2 + 3 + 4 + - IDX_LEN(MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT))); + BT_MESH_MODEL_BUF(OP_APP_KEY_LIST, + 3 + IDX_LEN(CONFIG_BT_MESH_APP_KEY_COUNT)); u16_t get_idx, i, prev; u8_t status; @@ -679,8 +624,7 @@ static void beacon_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_BEACON_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -699,8 +643,7 @@ static void beacon_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_BEACON_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -744,8 +687,7 @@ static void default_ttl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEFAULT_TTL_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -766,8 +708,7 @@ static void default_ttl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEFAULT_TTL_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -803,8 +744,7 @@ done: static void send_gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_GATT_PROXY_STATUS, 1); bt_mesh_model_msg_init(msg, OP_GATT_PROXY_STATUS); net_buf_simple_add_u8(msg, bt_mesh_gatt_proxy_get()); @@ -833,7 +773,6 @@ static void gatt_proxy_set(struct bt_mesh_model *model, struct os_mbuf *buf) { struct bt_mesh_cfg_srv *cfg = model->user_data; - struct bt_mesh_subnet *sub; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -866,33 +805,10 @@ static void gatt_proxy_set(struct bt_mesh_model *model, bt_mesh_store_cfg(); } - if (cfg->gatt_proxy == BT_MESH_GATT_PROXY_DISABLED) { - int i; - - /* Section 4.2.11.1: "When the GATT Proxy state is set to - * 0x00, the Node Identity state for all subnets shall be set - * to 0x00 and shall not be changed." - */ - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; - - if (sub->net_idx != BT_MESH_KEY_UNUSED) { - bt_mesh_proxy_identity_stop(sub); - } - } - - /* Section 4.2.11: "Upon transition from GATT Proxy state 0x01 - * to GATT Proxy state 0x00 the GATT Bearer Server shall - * disconnect all GATT Bearer Clients. - */ - bt_mesh_proxy_gatt_disconnect(); - } - bt_mesh_adv_update(); - sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); - if ((cfg->hb_pub.feat & BT_MESH_FEAT_PROXY) && sub) { - hb_send(model); + if (cfg->hb_pub.feat & BT_MESH_FEAT_PROXY) { + bt_mesh_heartbeat_send(); } send_status: @@ -903,8 +819,7 @@ static void net_transmit_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_TRANSMIT_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -925,8 +840,7 @@ static void net_transmit_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_TRANSMIT_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -961,8 +875,7 @@ static void relay_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_STATUS, 2); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -984,8 +897,7 @@ static void relay_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_STATUS, 2); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -995,7 +907,6 @@ static void relay_set(struct bt_mesh_model *model, if (!cfg) { BT_WARN("No Configuration Server context available"); } else if (buf->om_data[0] == 0x00 || buf->om_data[0] == 0x01) { - struct bt_mesh_subnet *sub; bool change; if (cfg->relay == BT_MESH_RELAY_NOT_SUPPORTED) { @@ -1016,9 +927,8 @@ static void relay_set(struct bt_mesh_model *model, BT_MESH_TRANSMIT_COUNT(cfg->relay_retransmit), BT_MESH_TRANSMIT_INT(cfg->relay_retransmit)); - sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); - if ((cfg->hb_pub.feat & BT_MESH_FEAT_RELAY) && sub && change) { - hb_send(model); + if ((cfg->hb_pub.feat & BT_MESH_FEAT_RELAY) && change) { + bt_mesh_heartbeat_send(); } } else { BT_WARN("Invalid Relay value 0x%02x", buf->om_data[0]); @@ -1044,8 +954,7 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, bool vnd, struct bt_mesh_model *mod, u8_t status, u8_t *mod_id) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 14 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_STATUS, 14); bt_mesh_model_msg_init(msg, OP_MOD_PUB_STATUS); @@ -1188,25 +1097,61 @@ send_status: status, mod_id); } -#if MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 -static u8_t va_add(u8_t *label_uuid, u16_t *addr) +struct label *get_label(u16_t index) { - struct label *free_slot = NULL; + if (index >= ARRAY_SIZE(labels)) { + return NULL; + } + + return &labels[index]; +} + +#if CONFIG_BT_MESH_LABEL_COUNT > 0 +static inline void va_store(struct label *store) +{ + atomic_set_bit(store->flags, BT_MESH_VA_CHANGED); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_label(); + } +} + +static struct label *va_find(const u8_t *label_uuid, + struct label **free_slot) +{ + struct label *match = NULL; int i; + if (free_slot != NULL) { + *free_slot = NULL; + } + for (i = 0; i < ARRAY_SIZE(labels); i++) { - if (!labels[i].ref) { - free_slot = &labels[i]; + if (labels[i].ref == 0) { + if (free_slot != NULL) { + *free_slot = &labels[i]; + } continue; } if (!memcmp(labels[i].uuid, label_uuid, 16)) { - *addr = labels[i].addr; - labels[i].ref++; - return STATUS_SUCCESS; + match = &labels[i]; } } + return match; +} + +static u8_t va_add(u8_t *label_uuid, u16_t *addr) +{ + struct label *update, *free_slot = NULL; + + update = va_find(label_uuid, &free_slot); + if (update) { + update->ref++; + va_store(update); + return 0; + } + if (!free_slot) { return STATUS_INSUFF_RESOURCES; } @@ -1218,23 +1163,24 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr) free_slot->ref = 1; free_slot->addr = *addr; memcpy(free_slot->uuid, label_uuid, 16); + va_store(free_slot); return STATUS_SUCCESS; } static u8_t va_del(u8_t *label_uuid, u16_t *addr) { - int i; + struct label *update; - for (i = 0; i < ARRAY_SIZE(labels); i++) { - if (!memcmp(labels[i].uuid, label_uuid, 16)) { - if (addr) { - *addr = labels[i].addr; - } + update = va_find(label_uuid, NULL); + if (update) { + update->ref--; - labels[i].ref--; - return STATUS_SUCCESS; + if (addr) { + *addr = update->addr; } + + va_store(update); } if (addr) { @@ -1244,28 +1190,36 @@ static u8_t va_del(u8_t *label_uuid, u16_t *addr) return STATUS_CANNOT_REMOVE; } -static void mod_sub_list_clear(struct bt_mesh_model *mod) +static size_t mod_sub_list_clear(struct bt_mesh_model *mod) { u8_t *label_uuid; + size_t clear_count; int i; /* Unref stored labels related to this model */ - for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) { if (!BT_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + mod->groups[i] = BT_MESH_ADDR_UNASSIGNED; + clear_count++; + } + continue; } label_uuid = bt_mesh_label_uuid_get(mod->groups[i]); - if (!label_uuid) { - BT_ERR("Label UUID not found"); - continue; - } - va_del(label_uuid, NULL); + mod->groups[i] = BT_MESH_ADDR_UNASSIGNED; + clear_count++; + + if (label_uuid) { + va_del(label_uuid, NULL); + } else { + BT_ERR("Label UUID not found"); + } } - /* Clear all subscriptions (0x0000 is the unassigned address) */ - memset(mod->groups, 0, sizeof(mod->groups)); + return clear_count; } static void mod_pub_va_set(struct bt_mesh_model *model, @@ -1300,8 +1254,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, retransmit = net_buf_simple_pull_u8(buf); mod_id = buf->om_data; - BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", - elem_addr, pub_addr, cred_flag); + BT_DBG("elem_addr 0x%04x cred_flag %u", elem_addr, cred_flag); BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", pub_app_idx, pub_ttl, pub_period); BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit, @@ -1335,10 +1288,20 @@ send_status: status, mod_id); } #else -static void mod_sub_list_clear(struct bt_mesh_model *mod) +static size_t mod_sub_list_clear(struct bt_mesh_model *mod) { - /* Clear all subscriptions (0x0000 is the unassigned address) */ - memset(mod->groups, 0, sizeof(mod->groups)); + size_t clear_count; + int i; + + /* Unref stored labels related to this model */ + for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + mod->groups[i] = BT_MESH_ADDR_UNASSIGNED; + clear_count++; + } + } + + return clear_count; } static void mod_pub_va_set(struct bt_mesh_model *model, @@ -1395,8 +1358,7 @@ static void send_mod_sub_status(struct bt_mesh_model *model, u16_t elem_addr, u16_t sub_addr, u8_t *mod_id, bool vnd) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_SUB_STATUS, 9); BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, elem_addr, sub_addr); @@ -1429,8 +1391,8 @@ static void mod_sub_add(struct bt_mesh_model *model, struct bt_mesh_elem *elem; u8_t *mod_id; u8_t status; + u16_t *entry; bool vnd; - int i; elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { @@ -1463,33 +1425,31 @@ static void mod_sub_add(struct bt_mesh_model *model, goto send_status; } - if (bt_mesh_model_find_group(mod, sub_addr)) { + if (bt_mesh_model_find_group(&mod, sub_addr)) { /* Tried to add existing subscription */ + BT_DBG("found existing subscription"); status = STATUS_SUCCESS; goto send_status; } - for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { - if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) { - mod->groups[i] = sub_addr; - break; - } - } - - if (i == ARRAY_SIZE(mod->groups)) { + entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED); + if (!entry) { status = STATUS_INSUFF_RESOURCES; - } else { - status = STATUS_SUCCESS; - - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); - } - - if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { - bt_mesh_lpn_group_add(sub_addr); - } + goto send_status; } + *entry = sub_addr; + status = STATUS_SUCCESS; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(sub_addr); + } + + send_status: send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); @@ -1547,7 +1507,7 @@ static void mod_sub_del(struct bt_mesh_model *model, bt_mesh_lpn_group_del(&sub_addr, 1); } - match = bt_mesh_model_find_group(mod, sub_addr); + match = bt_mesh_model_find_group(&mod, sub_addr); if (match) { *match = BT_MESH_ADDR_UNASSIGNED; @@ -1561,6 +1521,18 @@ send_status: mod_id, vnd); } +static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, + u32_t depth, void *user_data) +{ + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); + } + + mod_sub_list_clear(mod); + + return BT_MESH_WALK_CONTINUE; +} + static void mod_sub_overwrite(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) @@ -1603,13 +1575,10 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, goto send_status; } - if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { - bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); - } - - mod_sub_list_clear(mod); - if (ARRAY_SIZE(mod->groups) > 0) { + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), + mod_sub_clear_visitor, NULL); + mod->groups[0] = sub_addr; status = STATUS_SUCCESS; @@ -1665,11 +1634,8 @@ static void mod_sub_del_all(struct bt_mesh_model *model, goto send_status; } - if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { - bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); - } - - mod_sub_list_clear(mod); + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_clear_visitor, + NULL); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { bt_mesh_store_mod_sub(mod); @@ -1682,17 +1648,52 @@ send_status: BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); } +struct mod_sub_list_ctx { + u16_t elem_idx; + struct os_mbuf *msg; +}; + +static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, + u32_t depth, void *ctx) +{ + struct mod_sub_list_ctx *visit = ctx; + int count = 0; + int i; + + if (mod->elem_idx != visit->elem_idx) { + return BT_MESH_WALK_CONTINUE; + } + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) { + continue; + } + + if (net_buf_simple_tailroom(visit->msg) < + 2 + BT_MESH_MIC_SHORT) { + BT_WARN("No room for all groups"); + return BT_MESH_WALK_STOP; + } + + net_buf_simple_add_le16(visit->msg, mod->groups[i]); + count++; + } + + BT_DBG("sublist: model %u:%x: %u groups", mod->elem_idx, mod->id, + count); + + return BT_MESH_WALK_CONTINUE; +} + static void mod_sub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = - NET_BUF_SIMPLE(2 + 5 + 4 + - MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); + struct os_mbuf *msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct mod_sub_list_ctx visit_ctx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t addr, id; - int i; addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(addr)) { @@ -1727,11 +1728,10 @@ static void mod_sub_get(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, addr); net_buf_simple_add_le16(msg, id); - for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { - if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { - net_buf_simple_add_le16(msg, mod->groups[i]); - } - } + visit_ctx.msg = msg; + visit_ctx.elem_idx = mod->elem_idx; + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor, + &visit_ctx); send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { @@ -1747,13 +1747,10 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = - NET_BUF_SIMPLE(2 + 7 + 4 + - MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); + struct os_mbuf *msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t company, addr, id; - int i; addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(addr)) { @@ -1792,11 +1789,8 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, company); net_buf_simple_add_le16(msg, id); - for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { - if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { - net_buf_simple_add_le16(msg, mod->groups[i]); - } - } + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor, + msg); send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { @@ -1818,9 +1812,9 @@ static void mod_sub_va_add(struct bt_mesh_model *model, struct bt_mesh_elem *elem; u8_t *label_uuid; u8_t *mod_id; + u16_t *entry; u8_t status; bool vnd; - int i; elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { @@ -1854,33 +1848,31 @@ static void mod_sub_va_add(struct bt_mesh_model *model, goto send_status; } - if (bt_mesh_model_find_group(mod, sub_addr)) { + if (bt_mesh_model_find_group(&mod, sub_addr)) { /* Tried to add existing subscription */ status = STATUS_SUCCESS; goto send_status; } - for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { - if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) { - mod->groups[i] = sub_addr; - break; - } - } - if (i == ARRAY_SIZE(mod->groups)) { + entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED); + if (!entry) { status = STATUS_INSUFF_RESOURCES; - } else { - if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { - bt_mesh_lpn_group_add(sub_addr); + goto send_status; } - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); - } + *entry = sub_addr; - status = STATUS_SUCCESS; + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(sub_addr); } + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + status = STATUS_SUCCESS; + send_status: send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); @@ -1936,7 +1928,7 @@ static void mod_sub_va_del(struct bt_mesh_model *model, bt_mesh_lpn_group_del(&sub_addr, 1); } - match = bt_mesh_model_find_group(mod, sub_addr); + match = bt_mesh_model_find_group(&mod, sub_addr); if (match) { *match = BT_MESH_ADDR_UNASSIGNED; @@ -1992,13 +1984,10 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, goto send_status; } - if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { - bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); - } - - mod_sub_list_clear(mod); - if (ARRAY_SIZE(mod->groups) > 0) { + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), + mod_sub_clear_visitor, NULL); + status = va_add(label_uuid, &sub_addr); if (status == STATUS_SUCCESS) { mod->groups[0] = sub_addr; @@ -2145,8 +2134,7 @@ static void send_net_key_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t idx, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_STATUS, 3); bt_mesh_model_msg_init(msg, OP_NET_KEY_STATUS); @@ -2361,8 +2349,8 @@ static void net_key_get(struct bt_mesh_model *model, struct os_mbuf *buf) { struct os_mbuf *msg = - NET_BUF_SIMPLE(2 + 4 + - IDX_LEN(MYNEWT_VAL(BLE_MESH_SUBNET_COUNT))); + BT_MESH_MODEL_BUF(OP_NET_KEY_LIST, + IDX_LEN(CONFIG_BT_MESH_SUBNET_COUNT)); u16_t prev, i; bt_mesh_model_msg_init(msg, OP_NET_KEY_LIST); @@ -2399,8 +2387,7 @@ static void node_identity_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_IDENTITY_STATUS, 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; @@ -2441,8 +2428,7 @@ static void node_identity_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_IDENTITY_STATUS, 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; @@ -2474,12 +2460,7 @@ static void node_identity_set(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, STATUS_SUCCESS); net_buf_simple_add_le16(msg, idx); - /* Section 4.2.11.1: "When the GATT Proxy state is set to - * 0x00, the Node Identity state for all subnets shall be set - * to 0x00 and shall not be changed." - */ - if (MYNEWT_VAL(BLE_MESH_GATT_PROXY) && - bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) { if (node_id) { bt_mesh_proxy_identity_start(sub); } else { @@ -2522,7 +2503,7 @@ static void mod_app_bind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_STATUS, 9); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2583,7 +2564,7 @@ static void mod_app_unbind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_STATUS, 9); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2638,7 +2619,11 @@ static void mod_app_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + KEY_LIST_LEN + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(max(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, + 9 + KEY_LIST_LEN), + BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, + 9 + KEY_LIST_LEN))); + struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u8_t *mod_id, status; @@ -2709,8 +2694,7 @@ static void node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_RESET_STATUS, 0); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -2733,8 +2717,7 @@ static void node_reset(struct bt_mesh_model *model, static void send_friend_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_FRIEND_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; bt_mesh_model_msg_init(msg, OP_FRIEND_STATUS); @@ -2762,7 +2745,6 @@ static void friend_set(struct bt_mesh_model *model, struct os_mbuf *buf) { struct bt_mesh_cfg_srv *cfg = model->user_data; - struct bt_mesh_subnet *sub; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -2796,9 +2778,8 @@ static void friend_set(struct bt_mesh_model *model, } } - sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); - if ((cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) && sub) { - hb_send(model); + if (cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) { + bt_mesh_heartbeat_send(); } send_status: @@ -2809,8 +2790,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_LPN_TIMEOUT_STATUS, 5); struct bt_mesh_friend *frnd; u16_t lpn_addr; s32_t timeout; @@ -2859,8 +2839,7 @@ static void send_krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t idx, u8_t phase, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_KRP_STATUS, 4); bt_mesh_model_msg_init(msg, OP_KRP_STATUS); @@ -2999,8 +2978,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status, struct hb_pub_param *orig_msg) { - /* Needed size: opcode (1 byte) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 10 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_STATUS, 10); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); @@ -3125,8 +3103,7 @@ failed: static void hb_sub_send_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_STATUS, 9); struct bt_mesh_cfg_srv *cfg = model->user_data; u16_t period; s64_t uptime; @@ -3306,7 +3283,6 @@ const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { static void hb_publish(struct ble_npl_event *work) { struct bt_mesh_cfg_srv *cfg = ble_npl_event_get_arg(work); - struct bt_mesh_model *model = cfg->model; struct bt_mesh_subnet *sub; u16_t period_ms; @@ -3329,7 +3305,7 @@ static void hb_publish(struct ble_npl_event *work) k_delayed_work_submit(&cfg->hb_pub.timer, period_ms); } - hb_send(model); + bt_mesh_heartbeat_send(); if (cfg->hb_pub.count != 0xffff) { cfg->hb_pub.count--; @@ -3353,10 +3329,17 @@ static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg) return true; } -int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary) +static int cfg_srv_init(struct bt_mesh_model *model) { struct bt_mesh_cfg_srv *cfg = model->user_data; + BT_DBG(""); + + if (!bt_mesh_model_in_primary(model)) { + BT_ERR("Configuration Server only allowed in primary element"); + return -EINVAL; + } + if (!cfg) { BT_ERR("No Configuration Server context provided"); return -EINVAL; @@ -3367,8 +3350,11 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary) return -EINVAL; } - /* Configuration Model security is device-key based */ - model->keys[0] = BT_MESH_KEY_DEV; + /* + * Configuration Model security is device-key based and only the local + * device-key is allowed to access this model. + */ + model->keys[0] = BT_MESH_KEY_DEV_LOCAL; if (!(MYNEWT_VAL(BLE_MESH_RELAY))) { cfg->relay = BT_MESH_RELAY_NOT_SUPPORTED; @@ -3394,19 +3380,33 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary) return 0; } +const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = { + .init = cfg_srv_init, +}; + static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + size_t clear_count; + /* Clear model state that isn't otherwise cleared. E.g. AppKey * binding and model publication is cleared as a consequence - * of removing all app keys, however model subscription clearing - * must be taken care of here. + * of removing all app keys, however model subscription and user data + * clearing must be taken care of here. */ - mod_sub_list_clear(mod); + clear_count = mod_sub_list_clear(mod); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + if (clear_count) { + bt_mesh_store_mod_sub(mod); + } + + bt_mesh_model_data_store(mod, vnd, NULL, 0); + } + + if (mod->cb && mod->cb->reset) { + mod->cb->reset(mod); } } @@ -3415,6 +3415,8 @@ void bt_mesh_cfg_reset(void) struct bt_mesh_cfg_srv *cfg = conf; int i; + BT_DBG(""); + if (!cfg) { return; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c index 79553cba4..20b110378 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c @@ -6,6 +6,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_CRYPTO_LOG + #include #include #include @@ -26,12 +29,8 @@ #include #include #include - #endif -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_CRYPTO)) -#include "host/ble_hs_log.h" - #include "crypto.h" #define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4) @@ -315,7 +314,7 @@ static int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13], } } - for (i = 0; i < aad_len; i++, j++) { + for (; i < aad_len; i++, j++) { pmsg[i] = Xn[i] ^ aad[j]; } @@ -479,7 +478,7 @@ static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13], } } - for (i = 0; i < aad_len; i++, j++) { + for (; i < aad_len; i++, j++) { pmsg[i] = Xn[i] ^ aad[j]; } @@ -569,7 +568,6 @@ static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13], return 0; } -#if (MYNEWT_VAL(BLE_MESH_PROXY)) static void create_proxy_nonce(u8_t nonce[13], const u8_t *pdu, u32_t iv_index) { @@ -595,7 +593,6 @@ static void create_proxy_nonce(u8_t nonce[13], const u8_t *pdu, /* IV Index */ sys_put_be32(iv_index, &nonce[9]); } -#endif /* PROXY */ static void create_net_nonce(u8_t nonce[13], const u8_t *pdu, u32_t iv_index) @@ -661,15 +658,11 @@ int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, bt_hex(key, 16), mic_len); BT_DBG("PDU (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - if (proxy) { + if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && proxy) { create_proxy_nonce(nonce, buf->om_data, iv_index); } else { create_net_nonce(nonce, buf->om_data, iv_index); } -#else - create_net_nonce(nonce, buf->om_data, iv_index); -#endif BT_DBG("Nonce %s", bt_hex(nonce, 13)); @@ -692,15 +685,11 @@ int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, BT_DBG("iv_index %u, key %s mic_len %u", (unsigned) iv_index, bt_hex(key, 16), mic_len); -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - if (proxy) { + if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && proxy) { create_proxy_nonce(nonce, buf->om_data, iv_index); } else { create_net_nonce(nonce, buf->om_data, iv_index); } -#else - create_net_nonce(nonce, buf->om_data, iv_index); -#endif BT_DBG("Nonce %s", bt_hex(nonce, 13)); @@ -728,12 +717,11 @@ static void create_app_nonce(u8_t nonce[13], bool dev_key, u8_t aszmic, sys_put_be32(iv_index, &nonce[9]); } -int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct os_mbuf *buf, const u8_t *ad, - u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) +static int mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, + u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) { u8_t nonce[13]; - int err; BT_DBG("AppKey %s", bt_hex(key, 16)); BT_DBG("dev_key %u src 0x%04x dst 0x%04x", dev_key, src, dst); @@ -745,8 +733,35 @@ int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, BT_DBG("Nonce %s", bt_hex(nonce, 13)); - err = bt_mesh_ccm_encrypt(key, nonce, buf->om_data, buf->om_len, ad, - ad ? 16 : 0, buf->om_data, APP_MIC_LEN(aszmic)); + return bt_mesh_ccm_encrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, buf->om_data, + APP_MIC_LEN(aszmic)); +} + +int bt_mesh_app_encrypt_in_place(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, u16_t src, + u16_t dst, u32_t seq_num, u32_t iv_index) +{ + int err; + + err = mesh_app_encrypt(key, dev_key, aszmic, buf, ad, src, dst, + seq_num, iv_index); + if (!err) { + BT_DBG("Encr: %s", bt_hex(buf->om_data, buf->om_len)); + } + + return err; +} + +int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, + u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) +{ + int err; + + err = mesh_app_encrypt(key, dev_key, aszmic, buf, ad, src, dst, + seq_num, iv_index); + if (!err) { net_buf_simple_add(buf, APP_MIC_LEN(aszmic)); BT_DBG("Encr: %s", bt_hex(buf->om_data, buf->om_len)); @@ -755,23 +770,43 @@ int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, return err; } -int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct os_mbuf *buf, struct os_mbuf *out, - const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, - u32_t iv_index) +static int mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, struct os_mbuf *out, + const u8_t *ad, u16_t src, u16_t dst, + u32_t seq_num, u32_t iv_index) { u8_t nonce[13]; - int err; - BT_DBG("EncData (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("EncData (len %u) %s", buf->om_len, + bt_hex(buf->om_data, buf->om_len)); create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); BT_DBG("AppKey %s", bt_hex(key, 16)); BT_DBG("Nonce %s", bt_hex(nonce, 13)); - err = bt_mesh_ccm_decrypt(key, nonce, buf->om_data, buf->om_len, ad, - ad ? 16 : 0, out->om_data, APP_MIC_LEN(aszmic)); + return bt_mesh_ccm_decrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, out->om_data, + APP_MIC_LEN(aszmic)); +} + +int bt_mesh_app_decrypt_in_place(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, u16_t src, + u16_t dst, u32_t seq_num, u32_t iv_index) +{ + return mesh_app_decrypt(key, dev_key, aszmic, buf, buf, + ad, src, dst, seq_num, iv_index); +} + +int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, struct os_mbuf *out, + const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, + u32_t iv_index) +{ + int err; + + err = mesh_app_decrypt(key, dev_key, aszmic, buf, out, + ad, src, dst, seq_num, iv_index); if (!err) { net_buf_simple_add(out, buf->om_len); } @@ -900,6 +935,12 @@ int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13], return bt_mesh_ccm_decrypt(key, nonce, data, 25, NULL, 0, out, 8); } +int bt_mesh_prov_encrypt(const u8_t key[16], u8_t nonce[13], + const u8_t data[25], u8_t out[25 + 8]) +{ + return bt_mesh_ccm_encrypt(key, nonce, data, 25, NULL, 0, out, 8); +} + int bt_mesh_beacon_auth(const u8_t beacon_key[16], u8_t flags, const u8_t net_id[8], u32_t iv_index, u8_t auth[8]) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h index a56e6b9e8..745cf324a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h @@ -131,10 +131,18 @@ int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, u32_t iv_index, bool proxy); +int bt_mesh_app_encrypt_in_place(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf*buf, const u8_t *ad, u16_t src, + u16_t dst, u32_t seq_num, u32_t iv_index); + int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, struct os_mbuf*buf, const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index); +int bt_mesh_app_decrypt_in_place(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, u16_t src, + u16_t dst, u32_t seq_num, u32_t iv_index); + int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, struct os_mbuf*buf, struct os_mbuf*out, const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, @@ -157,4 +165,6 @@ int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16], int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13], const u8_t data[25 + 8], u8_t out[25]); +int bt_mesh_prov_encrypt(const u8_t key[16], u8_t nonce[13], + const u8_t data[25], u8_t out[25 + 8]); #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h index 2c257ee38..ee615ae9e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h @@ -115,11 +115,16 @@ #define STATUS_UNSPECIFIED 0x10 #define STATUS_INVALID_BINDING 0x11 -int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary); -int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary); +enum { + BT_MESH_VA_CHANGED, /* Label information changed */ +}; -int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary); -int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary); +struct label { + u16_t ref; + u16_t addr; + u8_t uuid[16]; + atomic_t flags[1]; +}; void bt_mesh_cfg_reset(void); @@ -127,6 +132,8 @@ void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); void bt_mesh_attention(struct bt_mesh_model *model, u8_t time); +struct label *get_label(u16_t index); + u8_t *bt_mesh_label_uuid_get(u16_t addr); struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c index a9f25f777..9056a8658 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c @@ -1,4 +1,4 @@ -/* Bluetooth Mesh */ + /* Bluetooth Mesh */ /* * Copyright (c) 2017 Intel Corporation @@ -6,17 +6,15 @@ * SPDX-License-Identifier: Apache-2.0 */ - #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_CRYPTO_LOG + #if MYNEWT_VAL(BLE_MESH_FRIEND) #include #include #include -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_FRIEND)) -#include "host/ble_hs_log.h" - #include "mesh/mesh.h" #include "mesh/slist.h" #include "mesh_priv.h" @@ -40,9 +38,9 @@ static os_membuf_t friend_buf_mem[OS_MEMPOOL_SIZE( struct os_mbuf_pool friend_os_mbuf_pool; static struct os_mempool friend_buf_mempool; +#define NET_BUF_FRAGS BIT(0) -#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), \ - struct friend_adv, adv) +#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), struct friend_adv, adv) /* PDUs from Friend to the LPN should only be transmitted once with the * smallest possible interval (20ms). @@ -63,54 +61,15 @@ struct friend_pdu_info { static struct friend_adv { struct bt_mesh_adv adv; - u64_t seq_auth; + u16_t app_idx; } adv_pool[FRIEND_BUF_COUNT]; static struct bt_mesh_adv *adv_alloc(int id) { + adv_pool[id].app_idx = BT_MESH_KEY_UNUSED; return &adv_pool[id].adv; } -static void discard_buffer(void) -{ - struct bt_mesh_friend *frnd = &bt_mesh.frnd[0]; - struct os_mbuf *buf; - int i; - - /* Find the Friend context with the most queued buffers */ - for (i = 1; i < ARRAY_SIZE(bt_mesh.frnd); i++) { - if (bt_mesh.frnd[i].queue_size > frnd->queue_size) { - frnd = &bt_mesh.frnd[i]; - } - } - - buf = net_buf_slist_get(&frnd->queue); - __ASSERT_NO_MSG(buf != NULL); - BT_WARN("Discarding buffer %p for LPN 0x%04x", buf, frnd->lpn); - net_buf_unref(buf); -} - -static struct os_mbuf *friend_buf_alloc(u16_t src) -{ - struct os_mbuf *buf; - - do { - buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc, - BT_MESH_ADV_DATA, - FRIEND_XMIT, K_NO_WAIT); - if (!buf) { - discard_buffer(); - } - } while (!buf); - - BT_MESH_ADV(buf)->addr = src; - FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL; - - BT_DBG("allocated buf %p", buf); - - return buf; -} - static bool is_lpn_unicast(struct bt_mesh_friend *frnd, u16_t addr) { if (frnd->lpn == BT_MESH_ADDR_UNASSIGNED) { @@ -150,6 +109,17 @@ struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, return NULL; } +static void purge_buffers(struct net_buf_slist_t *list) +{ + struct os_mbuf *buf; + + while (!net_buf_slist_is_empty(list)) { + buf = (void *)net_buf_slist_get(list); + BT_MESH_ADV(buf)->flags &= ~NET_BUF_FRAGS; + net_buf_unref(buf); + } +} + /* Intentionally start a little bit late into the ReceiveWindow when * it's large enough. This may improve reliability with some platforms, * like the PTS, where the receiver might not have sufficiently compensated @@ -184,16 +154,13 @@ static void friend_clear(struct bt_mesh_friend *frnd) frnd->last = NULL; } - while (!net_buf_slist_is_empty(&frnd->queue)) { - net_buf_unref(net_buf_slist_get(&frnd->queue)); - } + purge_buffers(&frnd->queue); for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; - while (!net_buf_slist_is_empty(&seg->queue)) { - net_buf_unref(net_buf_slist_get(&seg->queue)); - } + purge_buffers(&seg->queue); + seg->seg_count = 0U; } frnd->valid = 0; @@ -327,29 +294,16 @@ static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd, struct friend_pdu_info *info, struct os_mbuf *sdu) { - struct bt_mesh_subnet *sub; - const u8_t *enc, *priv; struct os_mbuf *buf; - u8_t nid; - sub = bt_mesh_subnet_get(frnd->net_idx); - __ASSERT_NO_MSG(sub != NULL); - - buf = friend_buf_alloc(info->src); - - /* Friend Offer needs master security credentials */ - if (info->ctl && TRANS_CTL_OP(sdu->om_data) == TRANS_CTL_OP_FRIEND_OFFER) { - enc = sub->keys[sub->kr_flag].enc; - priv = sub->keys[sub->kr_flag].privacy; - nid = sub->keys[sub->kr_flag].nid; - } else { - if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) { - BT_ERR("friend_cred_get failed"); - goto failed; - } + buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc, + BT_MESH_ADV_DATA, + FRIEND_XMIT, K_NO_WAIT); + if (!buf) { + return NULL; } - net_buf_add_u8(buf, (nid | (info->iv_index & 1) << 7)); + net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */ if (info->ctl) { net_buf_add_u8(buf, info->ttl | 0x80); @@ -364,25 +318,187 @@ static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd, net_buf_add_mem(buf, sdu->om_data, sdu->om_len); - /* We re-encrypt and obfuscate using the received IVI rather than - * the normal TX IVI (which may be different) since the transport - * layer nonce includes the IVI. - */ - if (bt_mesh_net_encrypt(enc, buf, info->iv_index, false)) { - BT_ERR("Re-encrypting failed"); - goto failed; - } - - if (bt_mesh_net_obfuscate(buf->om_data, info->iv_index, priv)) { - BT_ERR("Re-obfuscating failed"); - goto failed; - } - return buf; +} -failed: - net_buf_unref(buf); - return NULL; +struct unseg_app_sdu_meta { + struct bt_mesh_net_rx net; + const u8_t *key; + struct bt_mesh_subnet *subnet; + bool is_dev_key; + u8_t aid; + u8_t *ad; +}; + +static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, + struct os_mbuf *buf, + struct unseg_app_sdu_meta *meta) +{ + u16_t app_idx = FRIEND_ADV(buf)->app_idx; + int err; + + meta->subnet = bt_mesh_subnet_get(frnd->net_idx); + meta->is_dev_key = (app_idx == BT_MESH_KEY_DEV); + meta->is_dev_key = BT_MESH_IS_DEV_KEY(app_idx); + bt_mesh_net_header_parse(buf, &meta->net); + err = bt_mesh_app_key_get(meta->subnet, app_idx, meta->net.ctx.recv_dst, + &meta->key, &meta->aid); + if (err) { + return err; + } + + if (BT_MESH_ADDR_IS_VIRTUAL(meta->net.ctx.recv_dst)) { + meta->ad = bt_mesh_label_uuid_get(meta->net.ctx.recv_dst); + if (!meta->ad) { + return -ENOENT; + } + } else { + meta->ad = NULL; + } + + return 0; +} + +static int unseg_app_sdu_decrypt(struct bt_mesh_friend *frnd, + struct os_mbuf *buf, + const struct unseg_app_sdu_meta *meta) +{ + struct net_buf_simple_state state; + int err; + + BT_DBG(""); + + net_buf_simple_save(buf, &state); + net_buf_simple_pull_mem(buf, 10); + buf->om_len -= 4; + + err = bt_mesh_app_decrypt_in_place(meta->key, meta->is_dev_key, + 0, buf, meta->ad, meta->net.ctx.addr, + meta->net.ctx.recv_dst, meta->net.seq, + BT_MESH_NET_IVI_TX); + + net_buf_simple_restore(buf, &state); + return err; +} + +static int unseg_app_sdu_encrypt(struct bt_mesh_friend *frnd, + struct os_mbuf *buf, + const struct unseg_app_sdu_meta *meta) +{ + struct net_buf_simple_state state; + int err; + + BT_DBG(""); + + net_buf_simple_save(buf, &state); + net_buf_simple_pull_mem(buf, 10); + buf->om_len -= 4; + + err = bt_mesh_app_encrypt_in_place(meta->key, meta->is_dev_key, 0, buf, + meta->ad, meta->net.ctx.addr, + meta->net.ctx.recv_dst, bt_mesh.seq, + BT_MESH_NET_IVI_TX); + + net_buf_simple_restore(buf, &state); + return err; +} + +static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, + struct os_mbuf *buf) +{ + struct unseg_app_sdu_meta meta; + int err; + + BT_DBG(""); + + if (FRIEND_ADV(buf)->app_idx == BT_MESH_KEY_UNUSED) { + return 0; + } + + err = unseg_app_sdu_unpack(frnd, buf, &meta); + if (err) { + return err; + } + + /* No need to reencrypt the message if the sequence number is + * unchanged. + */ + if (meta.net.seq == bt_mesh.seq) { + return 0; + } + + err = unseg_app_sdu_decrypt(frnd, buf, &meta); + if (err) { + BT_WARN("Decryption failed! %d", err); + return err; + } + + err = unseg_app_sdu_encrypt(frnd, buf, &meta); + if (err) { + BT_WARN("Re-encryption failed! %d", err); + } + + return err; +} + +static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct os_mbuf *buf, + bool master_cred) +{ + struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx); + const u8_t *enc, *priv; + u32_t iv_index; + u16_t src; + u8_t nid; + int err; + + if (master_cred) { + enc = sub->keys[sub->kr_flag].enc; + priv = sub->keys[sub->kr_flag].privacy; + nid = sub->keys[sub->kr_flag].nid; + } else { + if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) { + BT_ERR("friend_cred_get failed"); + return -ENOENT; + } + } + + src = sys_get_be16(&buf->om_data[5]); + + if (bt_mesh_elem_find(src)) { + u32_t seq; + + if (FRIEND_ADV(buf)->app_idx != BT_MESH_KEY_UNUSED) { + err = unseg_app_sdu_prepare(frnd, buf); + if (err) { + return err; + } + } + + seq = bt_mesh_next_seq(); + buf->om_data[2] = seq >> 16; + buf->om_data[3] = seq >> 8; + buf->om_data[4] = seq; + + iv_index = BT_MESH_NET_IVI_TX; + FRIEND_ADV(buf)->app_idx = BT_MESH_KEY_UNUSED; + } else { + u8_t ivi = (buf->om_data[0] >> 7); + iv_index = (bt_mesh.iv_index - ((bt_mesh.iv_index & 1) != ivi)); + } + + buf->om_data[0] = (nid | (iv_index & 1) << 7); + + if (bt_mesh_net_encrypt(enc, buf, iv_index, false)) { + BT_ERR("Encrypting failed"); + return -EINVAL; + } + + if (bt_mesh_net_obfuscate(buf->om_data, iv_index, priv)) { + BT_ERR("Obfuscating failed"); + return -EINVAL; + } + + return 0; } static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd, @@ -390,7 +506,6 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd, struct os_mbuf *sdu) { struct friend_pdu_info info; - u32_t seq; BT_DBG("LPN 0x%04x", frnd->lpn); @@ -402,10 +517,7 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd, info.ctl = 1; info.ttl = 0; - seq = bt_mesh_next_seq(); - info.seq[0] = seq >> 16; - info.seq[1] = seq >> 8; - info.seq[2] = seq; + memset(info.seq, 0, sizeof(info.seq)); info.iv_index = BT_MESH_NET_IVI_TX; @@ -455,6 +567,10 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact) goto done; } + if (encrypt_friend_pdu(frnd, buf, false)) { + return; + } + if (frnd->last) { BT_DBG("Discarding last PDU"); net_buf_unref(frnd->last); @@ -693,8 +809,8 @@ static void clear_procedure_start(struct bt_mesh_friend *frnd) { BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); - frnd->clear.start = k_uptime_get_32() + (2 * frnd->poll_to); - frnd->clear.repeat_sec = 1; + frnd->clear.start = k_uptime_get_32(); + frnd->clear.repeat_sec = 1U; send_friend_clear(frnd); } @@ -763,6 +879,10 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi) goto done; } + if (encrypt_friend_pdu(frnd, buf, true)) { + return; + } + frnd->counter++; if (frnd->last) { @@ -886,7 +1006,7 @@ init_friend: frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr); BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", - frnd->lpn, rx->rssi, frnd->recv_delay, + frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, (unsigned) frnd->poll_to); if (BT_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) && @@ -895,45 +1015,70 @@ init_friend: } k_delayed_work_submit(&frnd->timer, - offer_delay(frnd, rx->rssi, msg->criteria)); + offer_delay(frnd, rx->ctx.recv_rssi, + msg->criteria)); friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter, frnd->counter); - enqueue_offer(frnd, rx->rssi); + enqueue_offer(frnd, rx->ctx.recv_rssi); return 0; } +static bool is_seg(struct bt_mesh_friend_seg *seg, u16_t src, u16_t seq_zero) +{ + struct os_mbuf *buf = (void *)net_buf_slist_peek_head(&seg->queue); + struct net_buf_simple_state state; + u16_t buf_seq_zero; + u16_t buf_src; + + if (!buf) { + return false; + } + + net_buf_simple_save(buf, &state); + net_buf_skip(buf, 5); /* skip IVI, NID, CTL, TTL, SEQ */ + buf_src = net_buf_pull_be16(buf); + net_buf_skip(buf, 3); /* skip DST, OP/AID */ + buf_seq_zero = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK); + net_buf_simple_restore(buf, &state); + + return ((src == buf_src) && (seq_zero == buf_seq_zero)); +} + static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, - u16_t src, u64_t *seq_auth) + u16_t src, u16_t seq_zero, + u8_t seg_count) { struct bt_mesh_friend_seg *unassigned = NULL; int i; for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; - struct os_mbuf *buf = (void *)net_buf_slist_peek_head(&seg->queue); - if (buf && BT_MESH_ADV(buf)->addr == src && - FRIEND_ADV(buf)->seq_auth == *seq_auth) { + if (is_seg(seg, src, seq_zero)) { return seg; } - if (!unassigned && !buf) { + if (!unassigned && !net_buf_slist_peek_head(&seg->queue)) { unassigned = seg; } } + if (unassigned) { + unassigned->seg_count = seg_count; + } + return unassigned; } static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, enum bt_mesh_friend_pdu_type type, + u16_t src, u8_t seg_count, struct os_mbuf *buf) { struct bt_mesh_friend_seg *seg; - struct friend_adv *adv; BT_DBG("type %u", type); @@ -946,11 +1091,11 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, return; } - adv = FRIEND_ADV(buf); - seg = get_seg(frnd, BT_MESH_ADV(buf)->addr, &adv->seq_auth); + u16_t seq_zero = (((buf->om_data[10] << 8 | buf->om_data[11]) >> 2) & TRANS_SEQ_ZERO_MASK); + + seg = get_seg(frnd, src, seq_zero, seg_count); if (!seg) { - BT_ERR("No free friend segment RX contexts for 0x%04x", - BT_MESH_ADV(buf)->addr); + BT_ERR("No free friend segment RX contexts for 0x%04x", src); net_buf_unref(buf); return; } @@ -962,19 +1107,13 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, enqueue_update(frnd, 1); } - /* Only acks should have a valid SeqAuth in the Friend queue - * (otherwise we can't easily detect them there), so clear - * the SeqAuth information from the segments before merging. - */ - struct os_mbuf *m; - struct os_mbuf_pkthdr *pkthdr; - NET_BUF_SLIST_FOR_EACH_NODE(&seg->queue, pkthdr) { - m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); - FRIEND_ADV(m)->seq_auth = TRANS_SEQ_AUTH_NVAL; - frnd->queue_size++; - } - net_buf_slist_merge_slist(&frnd->queue, &seg->queue); + + frnd->queue_size += seg->seg_count; + seg->seg_count = 0U; + } else { + /* Mark the buffer as having more to come after it */ + BT_MESH_ADV(buf)->flags |= NET_BUF_FRAGS; } } @@ -1040,13 +1179,21 @@ static void friend_timeout(struct ble_npl_event *work) return; } - frnd->last = net_buf_slist_get(&frnd->queue); + frnd->last = (void *)net_buf_slist_get(&frnd->queue); if (!frnd->last) { - BT_WARN("Friendship not established with 0x%04x", frnd->lpn); + BT_WARN("Friendship not established with 0x%04x", + frnd->lpn); friend_clear(frnd); return; } + if (encrypt_friend_pdu(frnd, frnd->last, false)) { + return; + } + + /* Clear the flag we use for segment tracking */ + BT_MESH_ADV(frnd->last)->flags &= ~NET_BUF_FRAGS; + BT_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", frnd->last, frnd->lpn); frnd->queue_size--; @@ -1093,6 +1240,42 @@ int bt_mesh_friend_init(void) return 0; } +static bool is_segack(struct os_mbuf *buf, u64_t *seqauth, u16_t src) +{ + struct net_buf_simple_state state; + bool found = false; + + if (buf->om_len != 16) { + return false; + } + + net_buf_simple_save(buf, &state); + + net_buf_skip(buf, 1); /* skip IVI, NID */ + + if (!(net_buf_pull_u8(buf) >> 7)) { + goto end; + } + + net_buf_pull(buf, 3); /* skip SEQNUM */ + + if (src != net_buf_pull_be16(buf)) { + goto end; + } + + net_buf_skip(buf, 2); /* skip dst */ + + if (TRANS_CTL_OP((u8_t *) net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) { + goto end; + } + + found = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) == + (*seqauth & TRANS_SEQ_ZERO_MASK); +end: + net_buf_simple_restore(buf, &state); + return found; +} + static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, u16_t src) { @@ -1104,8 +1287,7 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, cur != NULL; prev = cur, cur = net_buf_slist_peek_next(cur)) { struct os_mbuf *buf = (void *)cur; - if (BT_MESH_ADV(buf)->addr == src && - FRIEND_ADV(buf)->seq_auth == *seq_auth) { + if (is_segack(buf, seq_auth, src)) { BT_DBG("Removing old ack from Friend Queue"); net_buf_slist_remove(&frnd->queue, prev, cur); @@ -1120,11 +1302,20 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf) + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf) { struct friend_pdu_info info; struct os_mbuf *buf; + /* Because of network loopback, tx packets will also be passed into + * this rx function. These packets have already been added to the + * queue, and should be ignored. + */ + if (bt_mesh_elem_find(rx->ctx.addr)) { + return; + } + BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, (unsigned) frnd->queue_size); @@ -1155,11 +1346,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, return; } - if (seq_auth) { - FRIEND_ADV(buf)->seq_auth = *seq_auth; - } - - enqueue_friend_pdu(frnd, type, buf); + enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); BT_DBG("Queued message for LPN 0x%04x, queue_size %u", frnd->lpn, (unsigned) frnd->queue_size); @@ -1168,11 +1355,11 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf) + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf) { struct friend_pdu_info info; struct os_mbuf *buf; - u32_t seq; BT_DBG("LPN 0x%04x", frnd->lpn); @@ -1186,10 +1373,9 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, info.ttl = tx->ctx->send_ttl; info.ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED); - seq = bt_mesh_next_seq(); - info.seq[0] = seq >> 16; - info.seq[1] = seq >> 8; - info.seq[2] = seq; + info.seq[0] = (bt_mesh.seq >> 16); + info.seq[1] = (bt_mesh.seq >> 8); + info.seq[2] = bt_mesh.seq; info.iv_index = BT_MESH_NET_IVI_TX; @@ -1199,11 +1385,15 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, return; } - if (seq_auth) { - FRIEND_ADV(buf)->seq_auth = *seq_auth; + if (type == BT_MESH_FRIEND_PDU_SINGLE && !info.ctl) { + /* Unsegmented application packets may be reencrypted later, + * as they depend on the the sequence number being the same + * when encrypting in transport and network. + */ + FRIEND_ADV(buf)->app_idx = tx->ctx->app_idx; } - enqueue_friend_pdu(frnd, type, buf); + enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); BT_DBG("Queued message for LPN 0x%04x", frnd->lpn); } @@ -1253,9 +1443,112 @@ bool bt_mesh_friend_match(u16_t net_idx, u16_t addr) return false; } +static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr, + u64_t *seq_auth, u8_t seg_count) +{ + u32_t total = 0; + int i; + + if (seg_count > CONFIG_BT_MESH_FRIEND_QUEUE_SIZE) { + return false; + } + + for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { + struct bt_mesh_friend_seg *seg = &frnd->seg[i]; + + if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) { + /* If there's a segment queue for this message then the + * space verification has already happened. + */ + return true; + } + + total += seg->seg_count; + } + + /* If currently pending segments combined with this segmented message + * are more than the Friend Queue Size, then there's no space. This + * is because we don't have a mechanism of aborting already pending + * segmented messages to free up buffers. + */ + return (CONFIG_BT_MESH_FRIEND_QUEUE_SIZE - total) > seg_count; +} + +bool bt_mesh_friend_queue_has_space(u16_t net_idx, u16_t src, u16_t dst, + u64_t *seq_auth, u8_t seg_count) +{ + bool someone_has_space = false, friend_match = false; + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (!friend_lpn_matches(frnd, net_idx, dst)) { + continue; + } + + friend_match = true; + + if (friend_queue_has_space(frnd, src, seq_auth, seg_count)) { + someone_has_space = true; + } + } + + /* If there were no matched LPNs treat this as success, so the + * transport layer can continue its work. + */ + if (!friend_match) { + return true; + } + + /* From the transport layers perspective it's good enough that at + * least one Friend Queue has space. If there were multiple Friend + * matches then the destination must be a group address, in which + * case e.g. segment acks are not sent. + */ + return someone_has_space; +} + +static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, u16_t addr, + u64_t *seq_auth, u8_t seg_count) +{ + bool pending_segments; + u8_t avail_space; + + if (!friend_queue_has_space(frnd, addr, seq_auth, seg_count)) { + return false; + } + + avail_space = CONFIG_BT_MESH_FRIEND_QUEUE_SIZE - frnd->queue_size; + pending_segments = false; + + while (pending_segments || avail_space < seg_count) { + struct os_mbuf *buf = (void *)net_buf_slist_get(&frnd->queue); + + if (!buf) { + BT_ERR("Unable to free up enough buffers"); + return false; + } + + frnd->queue_size--; + avail_space++; + + pending_segments = (BT_MESH_ADV(buf)->flags & NET_BUF_FRAGS); + BT_DBG("PENDING SEGMENTS %d", pending_segments); + + /* Make sure old slist entry state doesn't remain */ + BT_MESH_ADV(buf)->flags &= ~NET_BUF_FRAGS; + + net_buf_unref(buf); + } + + return true; +} + void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf) + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf) { int i; @@ -1272,16 +1565,25 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; - if (friend_lpn_matches(frnd, rx->sub->net_idx, - rx->ctx.recv_dst)) { - friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, sbuf); + if (!friend_lpn_matches(frnd, rx->sub->net_idx, + rx->ctx.recv_dst)) { + continue; } + + if (!friend_queue_prepare_space(frnd, rx->ctx.addr, seq_auth, + seg_count)) { + continue; + } + + friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, seg_count, + sbuf); } } bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf) + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf) { bool matched = false; int i; @@ -1297,10 +1599,19 @@ bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; - if (friend_lpn_matches(frnd, tx->sub->net_idx, tx->ctx->addr)) { - friend_lpn_enqueue_tx(frnd, tx, type, seq_auth, sbuf); - matched = true; + if (!friend_lpn_matches(frnd, tx->sub->net_idx, + tx->ctx->addr)) { + continue; } + + if (!friend_queue_prepare_space(frnd, tx->src, seq_auth, + seg_count)) { + continue; + } + + friend_lpn_enqueue_tx(frnd, tx, type, seq_auth, seg_count, + sbuf); + matched = true; } return matched; @@ -1323,26 +1634,16 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) { struct bt_mesh_friend_seg *seg = &frnd->seg[j]; - struct os_mbuf *buf; - buf = (void *)net_buf_slist_peek_head(&seg->queue); - if (!buf) { - continue; - } - - if (BT_MESH_ADV(buf)->addr != src) { - continue; - } - - if (FRIEND_ADV(buf)->seq_auth != *seq_auth) { + if (!is_seg(seg, src, *seq_auth & TRANS_SEQ_ZERO_MASK)) { continue; } BT_WARN("Clearing incomplete segments for 0x%04x", src); - while (!net_buf_slist_is_empty(&seg->queue)) { - net_buf_unref(net_buf_slist_get(&seg->queue)); - } + purge_buffers(&seg->queue); + seg->seg_count = 0U; + break; } } } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h index 053de146c..10ffa8190 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h @@ -22,12 +22,17 @@ bool bt_mesh_friend_match(u16_t net_idx, u16_t addr); struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, bool valid, bool established); +bool bt_mesh_friend_queue_has_space(u16_t net_idx, u16_t src, u16_t dst, + u64_t *seq_auth, u8_t seg_count); + void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf); + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf); bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, struct os_mbuf *sbuf); + u64_t *seq_auth, u8_t seg_count, + struct os_mbuf *sbuf); void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, u64_t *seq_auth); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c index 3b765ee65..7da73d15b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c @@ -17,6 +17,9 @@ * under the License. */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_LOG + #include "mesh/glue.h" #include "adv.h" #ifndef MYNEWT @@ -27,22 +30,6 @@ #include "base64/base64.h" #endif -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) - -#if MYNEWT_VAL(BLE_EXT_ADV) -#define BT_MESH_ADV_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)) - -#if MYNEWT_VAL(BLE_MESH_PROXY) -/* Note that BLE_MULTI_ADV_INSTANCES contains number of additional instances. - * Instance 0 is always there - */ -#if MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) < 1 -#error "Mesh needs at least BLE_MULTI_ADV_INSTANCES set to 1" -#endif -#define BT_MESH_ADV_GATT_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) - 1) -#endif /* BLE_MESH_PROXY */ -#endif /* BLE_EXT_ADV */ - extern u8_t g_mesh_addr_type; #if MYNEWT_VAL(BLE_EXT_ADV) @@ -133,13 +120,16 @@ bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) mbedtls_aes_init(&s); if (mbedtls_aes_setkey_enc(&s, key, 128) != 0) { + mbedtls_aes_free(&s); return BLE_HS_EUNKNOWN; } if (mbedtls_aes_crypt_ecb(&s, MBEDTLS_AES_ENCRYPT, plaintext, enc_data) != 0) { + mbedtls_aes_free(&s); return BLE_HS_EUNKNOWN; } + mbedtls_aes_free(&s); return 0; } @@ -872,13 +862,11 @@ void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev, void net_buf_slist_merge_slist(struct net_buf_slist_t *list, struct net_buf_slist_t *list_to_append) { - struct os_mbuf_pkthdr *pkthdr; - - STAILQ_FOREACH(pkthdr, list_to_append, omp_next) { - STAILQ_INSERT_TAIL(list, pkthdr, omp_next); + if (!STAILQ_EMPTY(list_to_append)) { + *(list)->stqh_last = list_to_append->stqh_first; + (list)->stqh_last = list_to_append->stqh_last; + STAILQ_INIT(list_to_append); } - - STAILQ_INIT(list); } #if MYNEWT_VAL(BLE_MESH_SETTINGS) @@ -889,7 +877,8 @@ int settings_bytes_from_str(char *val_str, void *vp, int *len) return 0; } -char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len) +char *settings_str_from_bytes(const void *vp, int vp_len, + char *buf, int buf_len) { if (BASE64_ENCODE_SIZE(vp_len) > buf_len) { return NULL; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c index 68543415c..193279c28 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c @@ -6,14 +6,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + #include #include #include -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) -#include "host/ble_hs_log.h" - #include "mesh/mesh.h" #include "mesh_priv.h" #include "adv.h" @@ -206,7 +205,7 @@ static int cli_wait(void) int bt_mesh_health_attention_get(u16_t net_idx, u16_t addr, u16_t app_idx, u8_t *attention) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_ATTENTION_GET, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -241,7 +240,7 @@ done: int bt_mesh_health_attention_set(u16_t net_idx, u16_t addr, u16_t app_idx, u8_t attention, u8_t *updated_attention) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_ATTENTION_SET, 1); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -287,7 +286,7 @@ done: int bt_mesh_health_period_get(u16_t net_idx, u16_t addr, u16_t app_idx, u8_t *divisor) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_PERIOD_GET, 0); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -322,7 +321,7 @@ done: int bt_mesh_health_period_set(u16_t net_idx, u16_t addr, u16_t app_idx, u8_t divisor, u8_t *updated_divisor) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_PERIOD_SET, 1); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -369,7 +368,7 @@ int bt_mesh_health_fault_test(u16_t net_idx, u16_t addr, u16_t app_idx, u16_t cid, u8_t test_id, u8_t *faults, size_t *fault_count) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_FAULT_TEST, 3); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -420,7 +419,7 @@ int bt_mesh_health_fault_clear(u16_t net_idx, u16_t addr, u16_t app_idx, u16_t cid, u8_t *test_id, u8_t *faults, size_t *fault_count) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_FAULT_CLEAR, 2); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -470,7 +469,7 @@ int bt_mesh_health_fault_get(u16_t net_idx, u16_t addr, u16_t app_idx, u16_t cid, u8_t *test_id, u8_t *faults, size_t *fault_count) { - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_FAULT_GET, 2); struct bt_mesh_msg_ctx ctx = { .net_idx = net_idx, .app_idx = app_idx, @@ -528,11 +527,11 @@ int bt_mesh_health_cli_set(struct bt_mesh_model *model) return 0; } -int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary) +static int health_cli_init(struct bt_mesh_model *model) { struct bt_mesh_health_cli *cli = model->user_data; - BT_DBG("primary %u", primary); + BT_DBG("primary %u", bt_mesh_model_in_primary(model)); if (!cli) { BT_ERR("No Health Client context provided"); @@ -551,3 +550,7 @@ int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary) return 0; } + +const struct bt_mesh_model_cb bt_mesh_health_cli_cb = { + .init = health_cli_init, +}; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c index 97e3e043b..16de83a99 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c @@ -6,14 +6,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + #include #include #include -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) -#include "host/ble_hs_log.h" - #include "mesh/mesh.h" #include "mesh_priv.h" #include "adv.h" @@ -218,8 +217,7 @@ done: static void send_attention_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_ATTENTION_STATUS, 1); struct bt_mesh_health_srv *srv = model->user_data; u8_t time; @@ -273,8 +271,7 @@ static void attention_set(struct bt_mesh_model *model, static void send_health_period_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_PERIOD_STATUS, 1); bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS); @@ -347,8 +344,10 @@ static int health_pub_update(struct bt_mesh_model *mod) BT_DBG(""); count = health_get_current(mod, pub->msg); - if (!count) { - pub->period_div = 0; + if (count) { + pub->fast_period = 1U; + } else { + pub->fast_period = 0U; } return 0; @@ -363,6 +362,15 @@ int bt_mesh_fault_update(struct bt_mesh_elem *elem) return -EINVAL; } + /* Let periodic publishing, if enabled, take care of sending the + * Health Current Status. + */ + if (bt_mesh_model_pub_period_get(mod)) { + return 0; + } + + health_pub_update(mod); + return bt_mesh_model_publish(mod); } @@ -376,12 +384,12 @@ static void attention_off(struct ble_npl_event *work) } } -int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary) +static int health_srv_init(struct bt_mesh_model *model) { struct bt_mesh_health_srv *srv = model->user_data; if (!srv) { - if (!primary) { + if (!bt_mesh_model_in_primary(model)) { return 0; } @@ -401,13 +409,17 @@ int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary) srv->model = model; - if (primary) { + if (bt_mesh_model_in_primary(model)) { health_srv = srv; } return 0; } +const struct bt_mesh_model_cb bt_mesh_health_srv_cb = { + .init = health_srv_init, +}; + void bt_mesh_attention(struct bt_mesh_model *model, u8_t time) { struct bt_mesh_health_srv *srv; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c index 0dd00ac6c..ec012a5f0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c @@ -7,14 +7,12 @@ */ #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_LOW_POWER_LOG #if MYNEWT_VAL(BLE_MESH_LOW_POWER) #include -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) -#include "host/ble_hs_log.h" - #include "mesh/mesh.h" #include "mesh_priv.h" #include "crypto.h" @@ -66,7 +64,7 @@ static void (*lpn_cb)(u16_t friend_addr, bool established); -#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) +#if MYNEWT_VAL(BLE_MESH_LOW_POWER_LOG_LVL) == LOG_LEVEL_DEBUG static const char *state2str(int state) { switch (state) { @@ -92,11 +90,11 @@ static const char *state2str(int state) return "(unknown)"; } } -#endif /* CONFIG_BLUETOOTH_MESH_DEBUG_LPN */ +#endif static inline void lpn_set_state(int state) { -#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) +#if MYNEWT_VAL(BLE_MESH_LOW_POWER_LOG_LVL) == LOG_LEVEL_DEBUG BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); #endif bt_mesh.lpn.state = state; @@ -196,6 +194,7 @@ static int send_friend_clear(void) static void clear_friendship(bool force, bool disable) { + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); struct bt_mesh_lpn *lpn = &bt_mesh.lpn; BT_DBG("force %u disable %u", force, disable); @@ -243,6 +242,10 @@ static void clear_friendship(bool force, bool disable) */ lpn->groups_changed = 1; + if (cfg->hb_pub.feat & BT_MESH_FEAT_LOW_POWER) { + bt_mesh_heartbeat_send(); + } + if (disable) { lpn_set_state(BT_MESH_LPN_DISABLED); return; @@ -311,7 +314,7 @@ static void req_sent(u16_t duration, int err, void *user_data) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; -#if BT_DBG_ENABLED +#if MYNEWT_VAL(BLE_MESH_LOW_POWER_LOG_LVL) == LOG_LEVEL_DEBUG BT_DBG("req 0x%02x duration %u err %d state %s", lpn->sent_req, duration, err, state2str(lpn->state)); #endif @@ -725,7 +728,7 @@ static void lpn_timeout(struct ble_npl_event *work) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; -#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) +#if MYNEWT_VAL(BLE_MESH_LOW_POWER_LOG_LVL) == LOG_LEVEL_DEBUG BT_DBG("state: %s", state2str(lpn->state)); #endif @@ -758,6 +761,7 @@ static void lpn_timeout(struct ble_npl_event *work) } lpn->counter++; lpn_set_state(BT_MESH_LPN_ENABLED); + lpn->sent_req = 0U; k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); break; case BT_MESH_LPN_ESTABLISHED: @@ -940,6 +944,8 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, } if (!lpn->established) { + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + /* This is normally checked on the transport layer, however * in this state we're also still accepting master * credentials so we need to ensure the right ones (Friend @@ -954,6 +960,10 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, BT_INFO("Friendship established with 0x%04x", lpn->frnd); + if (cfg->hb_pub.feat & BT_MESH_FEAT_LOW_POWER) { + bt_mesh_heartbeat_send(); + } + if (lpn_cb) { lpn_cb(lpn->frnd, true); } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c index 80b638b1f..52fbdbf66 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c @@ -6,15 +6,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_LOG + #include #include #include "os/os_mbuf.h" #include "mesh/mesh.h" - -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) -#include "host/ble_hs_log.h" #include "host/ble_uuid.h" #include "adv.h" @@ -50,7 +49,7 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, } if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { - if (bt_mesh_proxy_prov_disable() == 0) { + if (bt_mesh_proxy_prov_disable(false) == 0) { pb_gatt_enabled = true; } else { pb_gatt_enabled = false; @@ -88,6 +87,26 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, return 0; } +int bt_mesh_provision_adv(const u8_t uuid[16], u16_t net_idx, u16_t addr, + u8_t attention_duration) +{ + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + return -EINVAL; + } + + if (bt_mesh_subnet_get(net_idx) == NULL) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) { + return bt_mesh_pb_adv_open(uuid, net_idx, addr, + attention_duration); + } + + return -ENOTSUP; +} + void bt_mesh_reset(void) { if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { @@ -149,14 +168,12 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } - if (MYNEWT_VAL(BLE_MESH_DEBUG)) { - char uuid_buf[BLE_UUID_STR_LEN]; - const struct bt_mesh_prov *prov = bt_mesh_prov_get(); - ble_uuid_t *uuid = BLE_UUID128_DECLARE(); + char uuid_buf[BLE_UUID_STR_LEN]; + const struct bt_mesh_prov *prov = bt_mesh_prov_get(); + ble_uuid_t *uuid = BLE_UUID128_DECLARE(); - memcpy(BLE_UUID128(uuid)->value, prov->uuid, 16); - BT_INFO("Device UUID: %s", ble_uuid_to_str(uuid, uuid_buf)); - } + memcpy(BLE_UUID128(uuid)->value, prov->uuid, 16); + BT_INFO("Device UUID: %s", ble_uuid_to_str(uuid, uuid_buf)); if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) { @@ -189,8 +206,7 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) { - bt_mesh_proxy_prov_disable(); - bt_mesh_adv_update(); + bt_mesh_proxy_prov_disable(true); } return 0; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h index 0a26c903b..f09bb2309 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h @@ -32,6 +32,7 @@ struct bt_mesh_net; #define OP_LIGHT_LIGHTNESS_GET BT_MESH_MODEL_OP_2(0x82, 0x4b) #define OP_LIGHT_LIGHTNESS_SET BT_MESH_MODEL_OP_2(0x82, 0x4c) #define OP_LIGHT_LIGHTNESS_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x4d) +#define OP_LIGHT_LIGHTNESS_STATUS BT_MESH_MODEL_OP_2(0x82, 0x4e) bool bt_mesh_is_provisioned(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c index c9e9cf622..b00cfa520 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c @@ -4,16 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "mesh/mesh.h" #include "mesh/model_cli.h" #include "mesh_priv.h" static s32_t msg_timeout = K_SECONDS(5); -struct bt_mesh_gen_model_cli gen_onoff_cli; -struct bt_mesh_gen_model_cli gen_level_cli; +static struct bt_mesh_gen_model_cli *gen_onoff_cli; +static struct bt_mesh_gen_model_cli *gen_level_cli; static u8_t transaction_id = 0; @@ -90,11 +91,53 @@ const struct bt_mesh_model_op gen_onoff_cli_op[] = { BT_MESH_MODEL_OP_END, }; +static int onoff_cli_init(struct bt_mesh_model *model) +{ + BT_DBG(""); + + if (!model->user_data) { + BT_ERR("No Generic OnOff Client context provided"); + return -EINVAL; + } + + gen_onoff_cli = model->user_data; + gen_onoff_cli->model = model; + + k_sem_init(&gen_onoff_cli->op_sync, 0, 1); + + return 0; +} + +const struct bt_mesh_model_cb bt_mesh_gen_onoff_cli_cb = { + .init = onoff_cli_init, +}; + const struct bt_mesh_model_op gen_level_cli_op[] = { { OP_GEN_LEVEL_STATUS, 2, gen_level_status }, BT_MESH_MODEL_OP_END, }; +static int level_cli_init(struct bt_mesh_model *model) +{ + BT_DBG(""); + + if (!model->user_data) { + BT_ERR("No Generic Level Client context provided"); + return -EINVAL; + } + + gen_level_cli = model->user_data; + gen_level_cli->model = model; + + k_sem_init(&gen_level_cli->op_sync, 0, 1); + + return 0; +} + +const struct bt_mesh_model_cb bt_mesh_gen_level_cli_cb = { + .init = level_cli_init, +}; + static int cli_wait(struct bt_mesh_gen_model_cli *cli, void *param, u32_t op) { int err; @@ -129,13 +172,13 @@ int bt_mesh_gen_onoff_get(u16_t net_idx, u16_t addr, u16_t app_idx, bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_GET); - err = bt_mesh_model_send(gen_onoff_cli.model, &ctx, msg, NULL, NULL); + err = bt_mesh_model_send(gen_onoff_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); goto done; } - err = cli_wait(&gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); + err = cli_wait(gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); done: os_mbuf_free_chain(msg); return err; @@ -165,7 +208,7 @@ int bt_mesh_gen_onoff_set(u16_t net_idx, u16_t addr, u16_t app_idx, net_buf_simple_add_u8(msg, val); net_buf_simple_add_u8(msg, transaction_id); - err = bt_mesh_model_send(gen_onoff_cli.model, &ctx, msg, NULL, NULL); + err = bt_mesh_model_send(gen_onoff_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); goto done; @@ -175,7 +218,7 @@ int bt_mesh_gen_onoff_set(u16_t net_idx, u16_t addr, u16_t app_idx, goto done; } - err = cli_wait(&gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); + err = cli_wait(gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); done: if (err == 0) { transaction_id++; @@ -201,13 +244,13 @@ int bt_mesh_gen_level_get(u16_t net_idx, u16_t addr, u16_t app_idx, bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_GET); - err = bt_mesh_model_send(gen_level_cli.model, &ctx, msg, NULL, NULL); + err = bt_mesh_model_send(gen_level_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); goto done; } - err = cli_wait(&gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); + err = cli_wait(gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); done: os_mbuf_free_chain(msg); return err; @@ -237,7 +280,7 @@ int bt_mesh_gen_level_set(u16_t net_idx, u16_t addr, u16_t app_idx, net_buf_simple_add_le16(msg, val); net_buf_simple_add_u8(msg, transaction_id); - err = bt_mesh_model_send(gen_level_cli.model, &ctx, msg, NULL, NULL); + err = bt_mesh_model_send(gen_level_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); goto done; @@ -247,7 +290,7 @@ int bt_mesh_gen_level_set(u16_t net_idx, u16_t addr, u16_t app_idx, goto done; } - err = cli_wait(&gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); + err = cli_wait(gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); done: if (err == 0) { transaction_id++; @@ -256,21 +299,3 @@ done: return err; } -int bt_mesh_gen_model_cli_init(struct bt_mesh_model *model, bool primary) -{ - struct bt_mesh_gen_model_cli *cli = model->user_data; - - BT_DBG("primary %u", primary); - - if (!cli) { - BT_ERR("No Generic Model Client context provided"); - return -EINVAL; - } - - cli->model = model; - - k_sem_init(&cli->op_sync, 0, 1); - - return 0; -} - diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c index 1420b1ccc..5f5a8df42 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c @@ -4,17 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + #include "mesh/mesh.h" - -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) - #include "mesh/model_srv.h" #include "mesh_priv.h" +static struct bt_mesh_gen_onoff_srv *gen_onoff_srv; +static struct bt_mesh_gen_level_srv *gen_level_srv; +static struct bt_mesh_light_lightness_srv *light_lightness_srv; + static void gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - struct bt_mesh_gen_onoff_srv_cb *cb = model->user_data; + struct bt_mesh_gen_onoff_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(3); u8_t *state; @@ -46,7 +50,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct bt_mesh_gen_onoff_srv_cb *cb = model->user_data; + struct bt_mesh_gen_onoff_srv *cb = model->user_data; u8_t state; state = buf->om_data[0]; @@ -71,7 +75,7 @@ static void gen_onoff_set(struct bt_mesh_model *model, static void gen_level_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - struct bt_mesh_gen_level_srv_cb *cb = model->user_data; + struct bt_mesh_gen_level_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(4); s16_t *level; @@ -102,7 +106,7 @@ static void gen_level_get(struct bt_mesh_model *model, static void gen_level_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct bt_mesh_gen_level_srv_cb *cb = model->user_data; + struct bt_mesh_gen_level_srv *cb = model->user_data; s16_t level; level = (s16_t) net_buf_simple_pull_le16(buf); @@ -124,11 +128,11 @@ static void gen_level_set(struct bt_mesh_model *model, static void light_lightness_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - struct bt_mesh_light_lightness_srv_cb *cb = model->user_data; + struct bt_mesh_light_lightness_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(4); s16_t *lightness; - bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_STATUS); + bt_mesh_model_msg_init(msg, OP_LIGHT_LIGHTNESS_STATUS); lightness = net_buf_simple_add(msg, 2); if (cb && cb->get) { cb->get(model, lightness); @@ -155,7 +159,7 @@ static void light_lightness_get(struct bt_mesh_model *model, static void light_lightness_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct bt_mesh_light_lightness_srv_cb *cb = model->user_data; + struct bt_mesh_light_lightness_srv *cb = model->user_data; s16_t lightness; lightness = (s16_t) net_buf_simple_pull_le16(buf); @@ -194,3 +198,69 @@ const struct bt_mesh_model_op light_lightness_srv_op[] = { { OP_LIGHT_LIGHTNESS_SET_UNACK, 3, light_lightness_set_unack }, BT_MESH_MODEL_OP_END, }; + +static int onoff_srv_init(struct bt_mesh_model *model) +{ + struct bt_mesh_gen_onoff_srv *cfg = model->user_data; + + BT_DBG(""); + + if (!cfg) { + BT_ERR("No Generic OnOff Server context provided"); + return -EINVAL; + } + + cfg->model = model; + + gen_onoff_srv = cfg; + + return 0; +} + +const struct bt_mesh_model_cb gen_onoff_srv_cb = { + .init = onoff_srv_init, +}; + +static int level_srv_init(struct bt_mesh_model *model) +{ + struct bt_mesh_gen_level_srv *cfg = model->user_data; + + BT_DBG(""); + + if (!cfg) { + BT_ERR("No Generic Level Server context provided"); + return -EINVAL; + } + + cfg->model = model; + + gen_level_srv = cfg; + + return 0; +} + +const struct bt_mesh_model_cb gen_level_srv_cb = { + .init = level_srv_init, +}; + +static int lightness_srv_init(struct bt_mesh_model *model) +{ + struct bt_mesh_light_lightness_srv *cfg = model->user_data; + + BT_DBG(""); + + if (!cfg) { + BT_ERR("No Light Lightness Server context provided"); + return -EINVAL; + } + + cfg->model = model; + + light_lightness_srv = cfg; + + return 0; +} + +const struct bt_mesh_model_cb light_lightness_srv_cb = { + .init = lightness_srv_init, +}; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.c index 455893354..cf11c2d4f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.c @@ -6,6 +6,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_NET_LOG + #include #include #include @@ -13,10 +16,6 @@ #include "os/os_mbuf.h" #include "mesh/mesh.h" -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_NET) -#include "host/ble_hs_log.h" - #include "crypto.h" #include "adv.h" #include "mesh_priv.h" @@ -60,9 +59,7 @@ #define FRIEND_CRED_COUNT 0 #endif -#if FRIEND_CRED_COUNT > 0 static struct friend_cred friend_cred[FRIEND_CRED_COUNT]; -#endif static u64_t msg_cache[MYNEWT_VAL(BLE_MESH_MSG_CACHE_SIZE)]; static u16_t msg_cache_next; @@ -80,6 +77,13 @@ struct bt_mesh_net bt_mesh = { .net_idx = BT_MESH_KEY_UNUSED, } }, +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) + .nodes = { + [0 ... (CONFIG_BT_MESH_NODE_COUNT - 1)] = { + .net_idx = BT_MESH_KEY_UNUSED, + } + }, +#endif }; static u32_t dup_cache[4]; @@ -131,7 +135,8 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx, } /* Add to the cache */ - msg_cache[msg_cache_next++] = hash; + rx->msg_cache_idx = msg_cache_next++; + msg_cache[rx->msg_cache_idx] = hash; msg_cache_next %= ARRAY_SIZE(msg_cache); return false; @@ -203,8 +208,6 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, return 0; } -#if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || \ - (MYNEWT_VAL(BLE_MESH_FRIEND))) int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]) { u16_t lpn_addr, frnd_addr; @@ -251,7 +254,8 @@ int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]) void friend_cred_refresh(u16_t net_idx) { int i; - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -261,6 +265,7 @@ void friend_cred_refresh(u16_t net_idx) sizeof(cred->cred[0])); } } +#pragma GCC diagnostic pop } int friend_cred_update(struct bt_mesh_subnet *sub) @@ -268,7 +273,8 @@ int friend_cred_update(struct bt_mesh_subnet *sub) int err, i; BT_DBG("net_idx 0x%04x", sub->net_idx); - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -282,7 +288,7 @@ int friend_cred_update(struct bt_mesh_subnet *sub) return err; } } - +#pragma GCC diagnostic pop return 0; } @@ -293,7 +299,8 @@ struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, int i, err; BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (cred = NULL, i = 0; i < ARRAY_SIZE(friend_cred); i++) { if ((friend_cred[i].addr == BT_MESH_ADDR_UNASSIGNED) || (friend_cred[i].addr == addr && @@ -302,7 +309,7 @@ struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, break; } } - +#pragma GCC diagnostic pop if (!cred) { BT_WARN("No free friend credential slots"); return NULL; @@ -342,7 +349,8 @@ void friend_cred_clear(struct friend_cred *cred) int friend_cred_del(u16_t net_idx, u16_t addr) { int i; - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -351,7 +359,7 @@ int friend_cred_del(u16_t net_idx, u16_t addr) return 0; } } - +#pragma GCC diagnostic pop return -ENOENT; } @@ -361,7 +369,8 @@ int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, int i; BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -387,16 +396,9 @@ int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, return 0; } - +#pragma GCC diagnostic pop return -ENOENT; } -#else -int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, - const u8_t **enc, const u8_t **priv) -{ - return -ENOENT; -} -#endif /* FRIEND || LOW_POWER */ u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) { @@ -719,6 +721,14 @@ u32_t bt_mesh_next_seq(void) bt_mesh_store_seq(); } + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && + bt_mesh.seq > IV_UPDATE_SEQ_LIMIT && + bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY)) { + bt_mesh_beacon_ivu_initiator(true); + bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true); + bt_mesh_net_sec_update(NULL); + } + return seq; } @@ -728,6 +738,7 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, { const u8_t *enc, *priv; u32_t seq; + u16_t dst; int err; BT_DBG("net_idx 0x%04x new_key %u len %u", sub->net_idx, new_key, @@ -753,6 +764,9 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, buf->om_data[3] = seq >> 8; buf->om_data[4] = seq; + /* Get destination, in case it's a proxy client */ + dst = DST(buf->om_data); + err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, false); if (err) { BT_ERR("encrypt failed (err %d)", err); @@ -765,13 +779,11 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, return err; } - bt_mesh_adv_send(buf, cb, cb_data); - - if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && - bt_mesh.seq > IV_UPDATE_SEQ_LIMIT) { - bt_mesh_beacon_ivu_initiator(true); - bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true); - bt_mesh_net_sec_update(NULL); + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + bt_mesh_proxy_relay(buf, dst)) { + send_cb_finalize(cb, cb_data); + } else { + bt_mesh_adv_send(buf, cb, cb_data); } return 0; @@ -886,15 +898,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, /* Notify completion if this only went * through the Mesh Proxy. */ - if (cb) { - if (cb->start) { - cb->start(0, 0, cb_data); - } - - if (cb->end) { - cb->end(0, cb_data); - } - } + send_cb_finalize(cb, cb_data); err = 0; goto done; @@ -1019,8 +1023,6 @@ static int net_decrypt(struct bt_mesh_subnet *sub, const u8_t *enc, return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), false); } -#if (MYNEWT_VAL(BLE_MESH_LOW_POWER) || \ - MYNEWT_VAL(BLE_MESH_FRIEND)) static int friend_decrypt(struct bt_mesh_subnet *sub, const u8_t *data, size_t data_len, struct bt_mesh_net_rx *rx, struct os_mbuf *buf) @@ -1028,7 +1030,8 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const u8_t *data, int i; BT_DBG("NID 0x%02x net_idx 0x%04x", NID(data), sub->net_idx); - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -1053,10 +1056,9 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const u8_t *data, return 0; } } - +#pragma GCC diagnostic pop return -ENOENT; } -#endif static bool net_find_and_decrypt(const u8_t *data, size_t data_len, struct bt_mesh_net_rx *rx, @@ -1073,15 +1075,14 @@ static bool net_find_and_decrypt(const u8_t *data, size_t data_len, continue; } -#if (MYNEWT_VAL(BLE_MESH_LOW_POWER) || \ - MYNEWT_VAL(BLE_MESH_FRIEND)) - if (!friend_decrypt(sub, data, data_len, rx, buf)) { - rx->friend_cred = 1; + if ((IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) || + IS_ENABLED(CONFIG_BT_MESH_FRIEND)) && + !friend_decrypt(sub, data, data_len, rx, buf)) { + rx->friend_cred = 1U; rx->ctx.net_idx = sub->net_idx; rx->sub = sub; return true; } -#endif if (NID(data) == sub->keys[0].nid && !net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy, @@ -1233,6 +1234,17 @@ done: net_buf_unref(buf); } +void bt_mesh_net_header_parse(struct os_mbuf *buf, + struct bt_mesh_net_rx *rx) +{ + rx->old_iv = (IVI(buf->om_data) != (bt_mesh.iv_index & 0x01)); + rx->ctl = CTL(buf->om_data); + rx->ctx.recv_ttl = TTL(buf->om_data); + rx->seq = SEQ(buf->om_data); + rx->ctx.addr = SRC(buf->om_data); + rx->ctx.recv_dst = DST(buf->om_data); +} + int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { @@ -1303,7 +1315,7 @@ void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, enum bt_mesh_net_if net_if) { struct os_mbuf *buf = NET_BUF_SIMPLE(29); - struct bt_mesh_net_rx rx = { .rssi = rssi }; + struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi }; struct net_buf_simple_state state; BT_DBG("rssi %d net_if %u", rssi, net_if); @@ -1320,15 +1332,33 @@ void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, /* Save the state so the buffer can later be relayed */ net_buf_simple_save(buf, &state); - if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) && - net_if == BT_MESH_NET_IF_PROXY) { - bt_mesh_proxy_addr_add(data, rx.ctx.addr); - } - rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || bt_mesh_elem_find(rx.ctx.recv_dst)); - bt_mesh_trans_recv(buf, &rx); + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) && + net_if == BT_MESH_NET_IF_PROXY) { + bt_mesh_proxy_addr_add(data, rx.ctx.addr); + + if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_DISABLED && + !rx.local_match) { + BT_INFO("Proxy is disabled; ignoring message"); + goto done; + } + } + + /* The transport layer has indicated that it has rejected the message, + * but would like to see it again if it is received in the future. + * This can happen if a message is received when the device is in + * Low Power mode, but the message was not encrypted with the friend + * credentials. Remove it from the message cache so that we accept + * it again in the future. + */ + if (bt_mesh_trans_recv(buf, &rx) == -EAGAIN) { + BT_WARN("Removing rejected message from Network Message Cache"); + msg_cache[rx.msg_cache_idx] = 0ULL; + /* Rewind the next index now that we're not using this entry */ + msg_cache_next = rx.msg_cache_idx; + } /* Relay if this was a group/virtual address, or if the destination * was neither a local element nor an LPN we're Friends for. diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.h index e55102c06..976da0053 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/net.h @@ -41,6 +41,13 @@ struct bt_mesh_app_key { } keys[2]; }; +struct bt_mesh_node { + u16_t addr; + u16_t net_idx; + u8_t dev_key[16]; + u8_t num_elem; +}; + struct bt_mesh_subnet { u32_t beacon_sent; /* Timestamp of last sent beacon */ u8_t beacons_last; /* Number of beacons during last @@ -78,7 +85,7 @@ struct bt_mesh_subnet { struct bt_mesh_rpl { u16_t src; bool old_iv; -#if defined(CONFIG_BT_SETTINGS) +#if (MYNEWT_VAL(BLE_MESH_SETTINGS)) bool store; #endif u32_t seq; @@ -115,6 +122,12 @@ struct bt_mesh_friend { struct bt_mesh_friend_seg { struct net_buf_slist_t queue; + + /* The target number of segments, i.e. not necessarily + * the current number of segments, in the queue. This is + * used for Friend Queue free space calculations. + */ + u8_t seg_count; } seg[FRIEND_SEG_RX]; struct os_mbuf *last; @@ -208,7 +221,7 @@ enum { BT_MESH_IVU_TEST, /* IV Update test mode */ BT_MESH_IVU_PENDING, /* Update blocked by SDU in progress */ - /* pending storage actions */ + /* pending storage actions, must reside within first 32 flags */ BT_MESH_RPL_PENDING, BT_MESH_KEYS_PENDING, BT_MESH_NET_PENDING, @@ -217,6 +230,8 @@ enum { BT_MESH_HB_PUB_PENDING, BT_MESH_CFG_PENDING, BT_MESH_MOD_PENDING, + BT_MESH_VA_PENDING, + BT_MESH_NODES_PENDING, /* Don't touch - intentionally last */ BT_MESH_FLAG_COUNT, @@ -249,6 +264,10 @@ struct bt_mesh_net { u8_t dev_key[16]; +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) + struct bt_mesh_node nodes[MYNEWT_VAL(BLE_MESH_NODE_COUNT)]; +#endif + struct bt_mesh_app_key app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)]; struct bt_mesh_subnet sub[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)]; @@ -276,7 +295,7 @@ struct bt_mesh_net_rx { net_if:2, /* Network interface */ local_match:1, /* Matched a local element */ friend_match:1; /* Matched an LPN we're friends for */ - s8_t rssi; + u16_t msg_cache_idx; /* Index of entry in message cache */ }; /* Encoding context for Network/Transport data */ @@ -346,6 +365,8 @@ u32_t bt_mesh_next_seq(void); void bt_mesh_net_start(void); void bt_mesh_net_init(void); +void bt_mesh_net_header_parse(struct os_mbuf *buf, + struct bt_mesh_net_rx *rx); /* Friendship Credential Management */ struct friend_cred { @@ -372,4 +393,20 @@ struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, void friend_cred_clear(struct friend_cred *cred); int friend_cred_del(u16_t net_idx, u16_t addr); +static inline void send_cb_finalize(const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (!cb) { + return; + } + + if (cb->start) { + cb->start(0, 0, cb_data); + } + + if (cb->end) { + cb->end(0, cb_data); + } +} + #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.c new file mode 100644 index 000000000..127ef21e4 --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2019 Tobias Svehagen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_PROV_LOG + +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) + +#include "mesh/mesh.h" + +#include "mesh_priv.h" +#include "net.h" +#include "access.h" +#include "settings.h" + +/* + * Check if an address range from addr_start for addr_start + num_elem - 1 is + * free for use. When a conflict is found, next will be set to the next address + * available after the conflicting range and -EAGAIN will be returned. + */ +static int addr_is_free(u16_t addr_start, u8_t num_elem, u16_t *next) +{ + const struct bt_mesh_comp *comp = bt_mesh_comp_get(); + u16_t addr_end = addr_start + num_elem - 1; + u16_t other_start, other_end; + int i; + + if (comp == NULL) { + return -EINVAL; + } + + if (!BT_MESH_ADDR_IS_UNICAST(addr_start) || + !BT_MESH_ADDR_IS_UNICAST(addr_end) || + num_elem == 0 || next == NULL) { + return -EINVAL; + } + + other_start = bt_mesh_primary_addr(); + other_end = other_start + comp->elem_count - 1; + + /* Compare with local element addresses */ + if (!(addr_end < other_start || addr_start > other_end)) { + *next = other_end + 1; + return -EAGAIN; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) { + struct bt_mesh_node *node = &bt_mesh.nodes[i]; + + if (node->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + other_start = node->addr; + other_end = other_start + node->num_elem - 1; + + if (!(addr_end < other_start || addr_start > other_end)) { + *next = other_end + 1; + return -EAGAIN; + } + } + + return 0; +} + +/* + * Find the lowest possible starting address that can fit num_elem elements. If + * a free address range cannot be found, BT_MESH_ADDR_UNASSIGNED will be + * returned. Otherwise the first address in the range is returned. + * + * NOTE: This is quite an ineffective algorithm as it might need to look + * through the array of nodes N+2 times. A more effective algorithm + * could be used if the nodes were stored in a sorted list. + */ +static u16_t find_lowest_free_addr(u8_t num_elem) +{ + u16_t addr = 1, next; + int err, i; + + /* + * It takes a maximum of node count + 2 to find a free address if there + * is any. +1 for our own address and +1 for making sure that the + * address range is valid. + */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes) + 2; ++i) { + err = addr_is_free(addr, num_elem, &next); + if (err == 0) { + break; + } else if (err != -EAGAIN) { + addr = BT_MESH_ADDR_UNASSIGNED; + break; + } + + addr = next; + } + + return addr; +} + +struct bt_mesh_node *bt_mesh_node_find(u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) { + struct bt_mesh_node *node = &bt_mesh.nodes[i]; + + if (addr >= node->addr && + addr <= node->addr + node->num_elem - 1) { + return node; + } + } + + return NULL; +} + +struct bt_mesh_node *bt_mesh_node_alloc(u16_t addr, u8_t num_elem, + u16_t net_idx) +{ + int i; + + BT_DBG(""); + + if (addr == BT_MESH_ADDR_UNASSIGNED) { + addr = find_lowest_free_addr(num_elem); + if (addr == BT_MESH_ADDR_UNASSIGNED) { + return NULL; + } + } else if (!addr_is_free(addr, num_elem, NULL)) { + return NULL; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) { + struct bt_mesh_node *node = &bt_mesh.nodes[i]; + + if (node->addr == BT_MESH_ADDR_UNASSIGNED) { + node->addr = addr; + node->num_elem = num_elem; + node->net_idx = net_idx; + return node; + } + } + + return NULL; +} + +void bt_mesh_node_del(struct bt_mesh_node *node, bool store) +{ + BT_DBG("Node addr 0x%04x store %u", node->addr, store); + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_clear_node(node); + } + + node->addr = BT_MESH_ADDR_UNASSIGNED; + (void)memset(node->dev_key, 0, sizeof(node->dev_key)); +} + +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.h new file mode 100644 index 000000000..f86193d9e --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/nodes.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2019 Tobias Svehagen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct bt_mesh_node *bt_mesh_node_find(u16_t addr); +struct bt_mesh_node *bt_mesh_node_alloc(u16_t addr, u8_t num_elem, + u16_t net_idx); +void bt_mesh_node_del(struct bt_mesh_node *node, bool store); \ No newline at end of file diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c index 5c519e75a..fe92c0e34 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c @@ -5,14 +5,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_PROV_LOG + #if MYNEWT_VAL(BLE_MESH_PROV) #include -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROV)) -#include "host/ble_hs_log.h" - #include "mesh/mesh.h" #include "mesh_priv.h" @@ -25,6 +25,8 @@ #include "proxy.h" #include "prov.h" #include "testing.h" +#include "settings.h" +#include "nodes.h" /* 3 transmissions, 20ms interval */ #define PROV_XMIT BT_MESH_TRANSMIT(2, 20) @@ -69,6 +71,8 @@ #define PROV_COMPLETE 0x08 #define PROV_FAILED 0x09 +#define PROV_NO_PDU 0xff + #define PROV_ALG_P256 0x00 #define GPCF(gpc) (gpc & 0x03) @@ -98,22 +102,40 @@ #define XACT_NVAL 0xff enum { - REMOTE_PUB_KEY, /* Remote key has been received */ + WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */ LINK_ACTIVE, /* Link has been opened */ - HAVE_DHKEY, /* DHKey has been calculated */ - SEND_CONFIRM, /* Waiting to send Confirm value */ + LINK_ACK_RECVD, /* Ack for link has been received */ + LINK_CLOSING, /* Link is closing down */ + SEND_PUB_KEY, /* Waiting to send PubKey */ WAIT_NUMBER, /* Waiting for number input from user */ WAIT_STRING, /* Waiting for string input from user */ + NOTIFY_INPUT_COMPLETE, /* Notify that input has been completed. */ LINK_INVALID, /* Error occurred during provisioning */ + PROVISIONER, /* The link was opened as provisioner */ NUM_FLAGS, }; +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) +#define PROVISIONER_LINK 1 +#else +#define PROVISIONER_LINK 0 +#endif + +struct provisioner_link { + struct bt_mesh_node *node; + u16_t addr; + u16_t net_idx; + u8_t attention_duration; +}; + struct prov_link { ATOMIC_DEFINE(flags, NUM_FLAGS); #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) uint16_t conn_handle; /* GATT connection */ #endif + struct provisioner_link provisioner[PROVISIONER_LINK]; + u8_t dhkey[32]; /* Calculated DHKey */ u8_t expect; /* Next expected PDU */ @@ -168,6 +190,7 @@ struct prov_rx { #define RETRANSMIT_TIMEOUT K_MSEC(500) #define BUF_TIMEOUT K_MSEC(400) +#define CLOSING_TIMEOUT K_SECONDS(3) #define TRANSACTION_TIMEOUT K_SECONDS(30) #define PROTOCOL_TIMEOUT K_SECONDS(60) @@ -200,6 +223,11 @@ static int reset_state(void) bt_mesh_attention(NULL, 0); } + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + link.provisioner->node != NULL) { + bt_mesh_node_del(link.provisioner->node, false); + } + #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) /* Clear everything except the retransmit and protocol timer * delayed work objects. @@ -210,6 +238,9 @@ static int reset_state(void) #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) link.rx.buf = bt_mesh_proxy_get_buf(); #else + if (!rx_buf) { + rx_buf = NET_BUF_SIMPLE(65); + } net_buf_simple_init(rx_buf, 0); link.rx.buf = rx_buf; #endif /* PB_GATT */ @@ -364,7 +395,7 @@ static void send_reliable(void) } } -static int bearer_ctl_send(u8_t op, void *data, u8_t data_len) +static int bearer_ctl_send(u8_t op, const void *data, u8_t data_len) { struct os_mbuf *buf; @@ -402,11 +433,20 @@ static u8_t last_seg(u8_t len) static inline u8_t next_transaction_id(void) { - if (link.tx.id != 0 && link.tx.id != 0xFF) { - return ++link.tx.id; + if (atomic_test_bit(link.flags, PROVISIONER)) { + if (link.tx.id != 0x7F) { + link.tx.id++; + } else { + link.tx.id = 0; + } + } else { + if (link.tx.id != 0U && link.tx.id != 0xFF) { + link.tx.id++; + } else { + link.tx.id = 0x80; + } } - link.tx.id = 0x80; return link.tx.id; } @@ -576,10 +616,63 @@ done: os_mbuf_free_chain(buf); } +#if MYNEWT_VAL(BLE_MESH_PB_ADV) +static void send_invite(void) +{ + struct os_mbuf *inv = PROV_BUF(2); + + BT_DBG(""); + + prov_buf_init(inv, PROV_INVITE); + net_buf_simple_add_u8(inv, link.provisioner->attention_duration); + + link.conf_inputs[0] = link.provisioner->attention_duration; + + if (prov_send(inv)) { + BT_ERR("Failed to send invite"); + goto done; + } + + link.expect = PROV_CAPABILITIES; + +done: + os_mbuf_free_chain(inv); +} +#endif + +static void send_start(void) +{ + struct os_mbuf *start = PROV_BUF(6); + + BT_DBG(""); + + prov_buf_init(start, PROV_START); + + net_buf_simple_add_u8(start, PROV_ALG_P256); + net_buf_simple_add_u8(start, PUB_KEY_NO_OOB); + net_buf_simple_add_u8(start, AUTH_METHOD_NO_OOB); + memset(link.auth, 0, sizeof(link.auth)); + + net_buf_simple_add_u8(start, 0); /* Auth Action */ + net_buf_simple_add_u8(start, 0); /* Auth Size */ + + memcpy(&link.conf_inputs[12], &start->om_data[1], 5); + + if (prov_send(start)) { + BT_ERR("Failed to send start"); + } + + os_mbuf_free_chain(start); +} + static void prov_capabilities(const u8_t *data) { u16_t algorithms, output_action, input_action; + if (!IS_ENABLED(CONFIG_BT_MESH_PROVISIONER)) { + return; + } + BT_DBG("Elements: %u", data[0]); algorithms = sys_get_be16(&data[1]); @@ -596,6 +689,26 @@ static void prov_capabilities(const u8_t *data) input_action = sys_get_be16(&data[9]); BT_DBG("Input OOB Action: 0x%04x", input_action); + + if (data[0] == 0) { + BT_ERR("Invalid number of elements"); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + link.provisioner->node = bt_mesh_node_alloc(link.provisioner->addr, + data[0], + link.provisioner->net_idx); + if (link.provisioner->node == NULL) { + prov_send_fail_msg(PROV_ERR_RESOURCES); + return; + } + + memcpy(&link.conf_inputs[1], data, 11); + + atomic_set_bit(link.flags, SEND_PUB_KEY); + + send_start(); } static bt_mesh_output_action_t output_action(u8_t action) @@ -669,6 +782,8 @@ static int prov_auth(u8_t method, u8_t action, u8_t size) return -EINVAL; } + atomic_set_bit(link.flags, NOTIFY_INPUT_COMPLETE); + if (output == BT_MESH_DISPLAY_STRING) { unsigned char str[9]; u8_t i; @@ -810,7 +925,11 @@ static void send_confirm(void) goto done; } - link.expect = PROV_RANDOM; + if (atomic_test_bit(link.flags, PROVISIONER)) { + link.expect = PROV_CONFIRM; + } else { + link.expect = PROV_RANDOM; + } done: os_mbuf_free_chain(cfm); @@ -824,6 +943,7 @@ static void send_input_complete(void) if (prov_send(buf)) { BT_ERR("Failed to send Provisioning Input Complete"); } + link.expect = PROV_CONFIRM; os_mbuf_free_chain(buf); } @@ -840,14 +960,6 @@ int bt_mesh_input_number(u32_t num) send_input_complete(); - if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { - return 0; - } - - if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { - send_confirm(); - } - return 0; } @@ -863,43 +975,9 @@ int bt_mesh_input_string(const char *str) send_input_complete(); - if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { - return 0; - } - - if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { - send_confirm(); - } - return 0; } -static void prov_dh_key_cb(const u8_t key[32]) -{ - BT_DBG("%p", key); - - if (!key) { - BT_ERR("DHKey generation failed"); - prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - return; - } - - sys_memcpy_swap(link.dhkey, key, 32); - - BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32)); - - atomic_set_bit(link.flags, HAVE_DHKEY); - - if (atomic_test_bit(link.flags, WAIT_NUMBER) || - atomic_test_bit(link.flags, WAIT_STRING)) { - return; - } - - if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { - send_confirm(); - } -} - static void send_pub_key(void) { struct os_mbuf *buf = PROV_BUF(65); @@ -914,56 +992,112 @@ static void send_pub_key(void) BT_DBG("Local Public Key: %s", bt_hex(key, 64)); - /* Copy remote key in little-endian for bt_dh_key_gen(). - * X and Y halves are swapped independently. Use response - * buffer as a temporary storage location. The bt_dh_key_gen() - * will also take care of validating the remote public key. - */ - sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32); - sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32); - - if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) { - BT_ERR("Failed to generate DHKey"); - prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - return; - } - prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); - memcpy(&link.conf_inputs[81], &buf->om_data[1], 64); + if (atomic_test_bit(link.flags, PROVISIONER)) { + /* PublicKeyProvisioner */ + memcpy(&link.conf_inputs[17], &buf->om_data[1], 64); + } else { + /* PublicKeyRemote */ + memcpy(&link.conf_inputs[81], &buf->om_data[1], 64); + } if (prov_send(buf)) { BT_ERR("Failed to send Public Key"); - return; + goto done; } - link.expect = PROV_CONFIRM; + if (atomic_test_bit(link.flags, PROVISIONER)) { + link.expect = PROV_PUB_KEY; + } else { + if (atomic_test_bit(link.flags, WAIT_NUMBER) || + atomic_test_bit(link.flags, WAIT_STRING)) { + link.expect = PROV_NO_PDU; /* Wait for input */ + } else { + link.expect = PROV_CONFIRM; + } + } done: os_mbuf_free_chain(buf); } +static void prov_dh_key_cb(const u8_t dhkey[32]) +{ + BT_DBG("%p", dhkey); + + if (!dhkey) { + BT_ERR("DHKey generation failed"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + + sys_memcpy_swap(link.dhkey, dhkey, 32); + + BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32)); + + if (atomic_test_bit(link.flags, PROVISIONER)) { + send_confirm(); + } else { + send_pub_key(); + } +} + +static void prov_dh_key_gen(void) +{ + u8_t remote_pk_le[64], *remote_pk; + + if (atomic_test_bit(link.flags, PROVISIONER)) { + remote_pk = &link.conf_inputs[81]; + } else { + remote_pk = &link.conf_inputs[17]; + } + + /* Copy remote key in little-endian for bt_dh_key_gen(). + * X and Y halves are swapped independently. The bt_dh_key_gen() + * will also take care of validating the remote public key. + */ + sys_memcpy_swap(remote_pk_le, remote_pk, 32); + sys_memcpy_swap(&remote_pk_le[32], &remote_pk[32], 32); + + if (bt_dh_key_gen(remote_pk_le, prov_dh_key_cb)) { + BT_ERR("Failed to generate DHKey"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + } +} + static void prov_pub_key(const u8_t *data) { BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); - memcpy(&link.conf_inputs[17], data, 64); + if (atomic_test_bit(link.flags, PROVISIONER)) { + /* PublicKeyDevice */ + memcpy(&link.conf_inputs[81], data, 64); - if (!bt_pub_key_get()) { - /* Clear retransmit timer */ #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) prov_clear_tx(); #endif - atomic_set_bit(link.flags, REMOTE_PUB_KEY); - BT_WARN("Waiting for local public key"); - return; + } else { + /* PublicKeyProvisioner */ + memcpy(&link.conf_inputs[17], data, 64); + + if (!bt_pub_key_get()) { + /* Clear retransmit timer */ +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + prov_clear_tx(); +#endif + + atomic_set_bit(link.flags, WAIT_PUB_KEY); + BT_WARN("Waiting for local public key"); + return; + } } - send_pub_key(); + prov_dh_key_gen(); } static void pub_key_ready(const u8_t *pkey) @@ -975,53 +1109,145 @@ static void pub_key_ready(const u8_t *pkey) BT_DBG("Local public key ready"); - if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) { - send_pub_key(); + if (atomic_test_and_clear_bit(link.flags, WAIT_PUB_KEY)) { + if (atomic_test_bit(link.flags, PROVISIONER)) { + send_pub_key(); + } else { + prov_dh_key_gen(); + } + } +} + +static void notify_input_complete(void) +{ + if (atomic_test_and_clear_bit(link.flags, NOTIFY_INPUT_COMPLETE) && + prov->input_complete) { + prov->input_complete(); } } static void prov_input_complete(const u8_t *data) { BT_DBG(""); + notify_input_complete(); } -static void prov_confirm(const u8_t *data) +static void send_prov_data(void) { - BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + struct os_mbuf *pdu = PROV_BUF(34); + struct bt_mesh_subnet *sub; + u8_t session_key[16]; + u8_t nonce[13]; + int err; - memcpy(link.conf, data, 16); - - if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { -#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) - prov_clear_tx(); -#endif - atomic_set_bit(link.flags, SEND_CONFIRM); - } else { - send_confirm(); - } -} - -static void prov_random(const u8_t *data) -{ - struct os_mbuf *rnd = PROV_BUF(16); - u8_t conf_verify[16]; - - BT_DBG("Remote Random: %s", bt_hex(data, 16)); - - if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) { - BT_ERR("Unable to calculate confirmation verification"); + err = bt_mesh_session_key(link.dhkey, link.prov_salt, session_key); + if (err) { + BT_ERR("Unable to generate session key"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); goto done; } - if (memcmp(conf_verify, link.conf, 16)) { - BT_ERR("Invalid confirmation value"); - BT_DBG("Received: %s", bt_hex(link.conf, 16)); - BT_DBG("Calculated: %s", bt_hex(conf_verify, 16)); - prov_send_fail_msg(PROV_ERR_CFM_FAILED); + BT_DBG("SessionKey: %s", bt_hex(session_key, 16)); + + err = bt_mesh_prov_nonce(link.dhkey, link.prov_salt, nonce); + if (err) { + BT_ERR("Unable to generate session nonce"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); goto done; } + BT_DBG("Nonce: %s", bt_hex(nonce, 13)); + + err = bt_mesh_dev_key(link.dhkey, link.prov_salt, + link.provisioner->node->dev_key); + if (err) { + BT_ERR("Unable to generate device key"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("DevKey: %s", bt_hex(link.provisioner->node->dev_key, 16)); + + sub = bt_mesh_subnet_get(link.provisioner->node->net_idx); + if (sub == NULL) { + BT_ERR("No subnet with net_idx %u", + link.provisioner->node->net_idx); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + prov_buf_init(pdu, PROV_DATA); + net_buf_simple_add_mem(pdu, sub->keys[sub->kr_flag].net, 16); + net_buf_simple_add_be16(pdu, link.provisioner->node->net_idx); + net_buf_simple_add_u8(pdu, bt_mesh_net_flags(sub)); + net_buf_simple_add_be32(pdu, bt_mesh.iv_index); + net_buf_simple_add_be16(pdu, link.provisioner->node->addr); + net_buf_simple_add(pdu, 8); /* For MIC */ + + BT_DBG("net_idx %u, iv_index 0x%08x, addr 0x%04x", + link.provisioner->node->net_idx, bt_mesh.iv_index, + link.provisioner->node->addr); + + err = bt_mesh_prov_encrypt(session_key, nonce, &pdu->om_data[1], + &pdu->om_data[1]); + if (err) { + BT_ERR("Unable to encrypt provisioning data"); + prov_send_fail_msg(PROV_ERR_DECRYPT); + goto done; + } + + if (prov_send(pdu)) { + BT_ERR("Failed to send Provisioning Data"); + goto done; + } + + link.expect = PROV_COMPLETE; + +done: + os_mbuf_free_chain(pdu); +} + +static void prov_complete(const u8_t *data) +{ + if (!IS_ENABLED(CONFIG_BT_MESH_PROVISIONER)) { + return; + } + + struct bt_mesh_node *node = link.provisioner->node; +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + u8_t reason = CLOSE_REASON_SUCCESS; +#endif + + BT_DBG("key %s, net_idx %u, num_elem %u, addr 0x%04x", + bt_hex(node->dev_key, 16), node->net_idx, node->num_elem, + node->addr); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_node(node); + } + + link.provisioner->node = NULL; + link.expect = PROV_NO_PDU; + atomic_set_bit(link.flags, LINK_CLOSING); + +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason)); +#endif + + bt_mesh_prov_node_added(node->net_idx, node->addr, node->num_elem); + + /* + * According to mesh profile spec (5.3.1.4.3), the close message should + * be restransmitted at least three times. Retransmit the LINK_CLOSE + * message until CLOSING_TIMEOUT has elapsed instead of resetting the + * link here. + */ +} + +static void send_random(void) +{ + struct os_mbuf *rnd = PROV_BUF(17); + prov_buf_init(rnd, PROV_RANDOM); net_buf_simple_add_mem(rnd, link.rand, 16); @@ -1030,19 +1256,75 @@ static void prov_random(const u8_t *data) goto done; } - if (bt_mesh_prov_salt(link.conf_salt, data, link.rand, + if (atomic_test_bit(link.flags, PROVISIONER)) { + link.expect = PROV_RANDOM; + } else { + link.expect = PROV_DATA; + } + +done: + os_mbuf_free_chain(rnd); +} + +static void prov_random(const u8_t *data) +{ + u8_t conf_verify[16]; + const u8_t *prov_rand, *dev_rand; + + BT_DBG("Remote Random: %s", bt_hex(data, 16)); + + if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) { + BT_ERR("Unable to calculate confirmation verification"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + + if (memcmp(conf_verify, link.conf, 16)) { + BT_ERR("Invalid confirmation value"); + BT_DBG("Received: %s", bt_hex(link.conf, 16)); + BT_DBG("Calculated: %s", bt_hex(conf_verify, 16)); + prov_send_fail_msg(PROV_ERR_CFM_FAILED); + return; + } + + if (atomic_test_bit(link.flags, PROVISIONER)) { + prov_rand = link.rand; + dev_rand = data; + } else { + prov_rand = data; + dev_rand = link.rand; + } + + if (bt_mesh_prov_salt(link.conf_salt, prov_rand, dev_rand, link.prov_salt)) { BT_ERR("Failed to generate provisioning salt"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - goto done; + return; } BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16)); - link.expect = PROV_DATA; + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + atomic_test_bit(link.flags, PROVISIONER)) { + send_prov_data(); + } else { + send_random(); + } +} -done: - os_mbuf_free_chain(rnd); +static void prov_confirm(const u8_t *data) +{ + BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + + memcpy(link.conf, data, 16); + + notify_input_complete(); + + if (atomic_test_bit(link.flags, PROVISIONER)) { + send_random(); + } else { + send_confirm(); + } } static inline bool is_pb_gatt(void) @@ -1119,7 +1401,7 @@ static void prov_data(const u8_t *data) } /* Ignore any further PDUs on this link */ - link.expect = 0; + link.expect = PROV_NO_PDU; /* Store info, since bt_mesh_provision() will end up clearing it */ if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { @@ -1145,11 +1427,6 @@ done: os_mbuf_free_chain(msg); } -static void prov_complete(const u8_t *data) -{ - BT_DBG(""); -} - static void prov_failed(const u8_t *data) { BT_WARN("Error: 0x%02x", data[0]); @@ -1174,7 +1451,7 @@ static const struct { #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) static void prov_retransmit(struct ble_npl_event *work) { - int i; + int i, timeout; BT_DBG(""); @@ -1183,7 +1460,13 @@ static void prov_retransmit(struct ble_npl_event *work) return; } - if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) { + if (atomic_test_bit(link.flags, LINK_CLOSING)) { + timeout = CLOSING_TIMEOUT; + } else { + timeout = TRANSACTION_TIMEOUT; + } + + if (k_uptime_get() - link.tx.start > timeout) { BT_WARN("Giving up transaction"); reset_adv_link(); return; @@ -1248,12 +1531,26 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf) bearer_ctl_send(LINK_ACK, NULL, 0); link.expect = PROV_INVITE; - } static void link_ack(struct prov_rx *rx, struct os_mbuf *buf) { BT_DBG("Link ack: len %u", buf->om_len); + + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + atomic_test_bit(link.flags, PROVISIONER)) { + if (atomic_test_and_set_bit(link.flags, LINK_ACK_RECVD)) { + return; + } + + prov_clear_tx(); + + if (prov->link_open) { + prov->link_open(BT_MESH_PROV_ADV); + } + + send_invite(); + } } static void link_close(struct prov_rx *rx, struct os_mbuf *buf) @@ -1398,7 +1695,21 @@ static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf) } if (rx->xact_id == link.tx.id) { - prov_clear_tx(); + /* Don't clear resending of LINK_CLOSE messages */ + if (!atomic_test_bit(link.flags, LINK_CLOSING)) { + prov_clear_tx(); + } + + /* Send the PubKey when the the Start message is ACK'ed */ + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + atomic_test_and_clear_bit(link.flags, SEND_PUB_KEY)) { + if (!bt_pub_key_get()) { + atomic_set_bit(link.flags, WAIT_PUB_KEY); + BT_WARN("Waiting for local public key"); + } else { + send_pub_key(); + } + } } } @@ -1456,9 +1767,9 @@ static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf) } static const struct { - void (*const func)(struct prov_rx *rx, struct os_mbuf *buf); - const u8_t require_link; - const u8_t min_len; + void (*func)(struct prov_rx *rx, struct os_mbuf *buf); + bool require_link; + u8_t min_len; } gen_prov[] = { { gen_prov_start, true, 3 }, { gen_prov_ack, true, 0 }, @@ -1510,6 +1821,31 @@ void bt_mesh_pb_adv_recv(struct os_mbuf *buf) gen_prov_recv(&rx, buf); } + +int bt_mesh_pb_adv_open(const u8_t uuid[16], u16_t net_idx, u16_t addr, + u8_t attention_duration) +{ + BT_DBG("uuid %s", bt_hex(uuid, 16)); + + if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) { + return -EBUSY; + } + + atomic_set_bit(link.flags, PROVISIONER); + + bt_rand(&link.id, sizeof(link.id)); + link.tx.id = 0x7F; + link.provisioner->addr = addr; + link.provisioner->net_idx = net_idx; + link.provisioner->attention_duration = attention_duration; + + net_buf_simple_init(link.rx.buf, 0); + + bearer_ctl_send(LINK_OPEN, uuid, 16); + + return 0; +} + #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) @@ -1655,6 +1991,13 @@ void bt_mesh_prov_complete(u16_t net_idx, u16_t addr) } } +void bt_mesh_prov_node_added(u16_t net_idx, u16_t addr, u8_t num_elem) +{ + if (prov->node_added) { + prov->node_added(net_idx, addr, num_elem); + } +} + void bt_mesh_prov_reset(void) { if (prov->reset) { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h index 3675b6cc7..96e5a447c 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h @@ -13,6 +13,9 @@ #include "mesh/mesh.h" #include "../src/ble_hs_conn_priv.h" +int bt_mesh_pb_adv_open(const u8_t uuid[16], u16_t net_idx, u16_t addr, + u8_t attention_duration); + void bt_mesh_pb_adv_recv(struct os_mbuf *buf); bool bt_prov_active(void); @@ -28,6 +31,7 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov); void bt_mesh_prov_reset_link(void); void bt_mesh_prov_complete(u16_t net_idx, u16_t addr); +void bt_mesh_prov_node_added(u16_t net_idx, u16_t addr, u8_t num_elem); void bt_mesh_prov_reset(void); #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c index 609da54d2..134a36dd6 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c @@ -7,13 +7,11 @@ */ #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG #if MYNEWT_VAL(BLE_MESH_PROXY) #include "mesh/mesh.h" - -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROXY)) -#include "host/ble_hs_log.h" #include "host/ble_att.h" #include "services/gatt/ble_svc_gatt.h" #include "../../host/src/ble_hs_priv.h" @@ -654,10 +652,7 @@ static void proxy_connected(uint16_t conn_handle) static void proxy_disconnected(uint16_t conn_handle, int reason) { int i; - - BT_INFO("conn_handle %d reason %d", conn_handle, reason); - - conn_count--; + bool disconnected = false; for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; @@ -670,11 +665,16 @@ static void proxy_disconnected(uint16_t conn_handle, int reason) k_delayed_work_cancel(&client->sar_timer); client->conn_handle = BLE_HS_CONN_HANDLE_NONE; + conn_count--; + disconnected = true; break; } } - bt_mesh_adv_update(); + if (disconnected) { + BT_INFO("conn_handle %d reason %d", conn_handle, reason); + bt_mesh_adv_update(); + } } struct os_mbuf *bt_mesh_proxy_get_buf(void) @@ -740,7 +740,7 @@ int bt_mesh_proxy_prov_enable(void) return 0; } -int bt_mesh_proxy_prov_disable(void) +int bt_mesh_proxy_prov_disable(bool disconnect) { uint16_t handle; int rc; @@ -767,13 +767,23 @@ int bt_mesh_proxy_prov_disable(void) for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE) - && (client->filter_type == PROV)) { + if ((client->conn_handle == BLE_HS_CONN_HANDLE_NONE) + || (client->filter_type != PROV)) { + continue; + } + + if (disconnect) { + rc = ble_gap_terminate(client->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); + } else { bt_mesh_pb_gatt_close(client->conn_handle); client->filter_type = NONE; } } + bt_mesh_adv_update(); + return 0; } #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ @@ -907,16 +917,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); - if (client->filter_type == WHITELIST) { - for (i = 0; i < ARRAY_SIZE(client->filter); i++) { - if (client->filter[i] == addr) { - return true; - } - } - - return false; - } - if (client->filter_type == BLACKLIST) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i] == addr) { @@ -927,6 +927,18 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return true; } + if (addr == BT_MESH_ADDR_ALL_NODES) { + return true; + } + + if (client->filter_type == WHITELIST) { + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + return true; + } + } + } + return false; } @@ -1146,7 +1158,7 @@ static bool advertise_subnet(struct bt_mesh_subnet *sub) } return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || - bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); + bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED); } static struct bt_mesh_subnet *next_sub(void) @@ -1189,7 +1201,7 @@ static s32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) BT_DBG(""); if (conn_count == CONFIG_BT_MAX_CONN) { - BT_WARN("Connectable advertising deferred (max connections)"); + BT_DBG("Connectable advertising deferred (max connections)"); return remaining; } @@ -1213,11 +1225,7 @@ static s32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) } if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { - if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { - net_id_adv(sub); - } else { - return gatt_proxy_advertise(next_sub()); - } + net_id_adv(sub); } subnet_count = sub_count(); @@ -1353,12 +1361,39 @@ void bt_mesh_proxy_adv_stop(void) } } -int -ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) +static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) { +#if MYNEWT_VAL(BLE_EXT_ADV) + /* When EXT ADV is enabled then mesh proxy is connected + * when proxy advertising instance is completed. + * Therefore no need to handle BLE_GAP_EVENT_CONNECT + */ + if (event->type == BLE_GAP_EVENT_ADV_COMPLETE) { + /* Reason 0 means advertising has been completed because + * connection has been established + */ + if (event->adv_complete.reason != 0) { + return; + } + if (event->adv_complete.instance != BT_MESH_ADV_GATT_INST) { + return; + } + + proxy_connected(event->adv_complete.conn_handle); + } +#else if (event->type == BLE_GAP_EVENT_CONNECT) { proxy_connected(event->connect.conn_handle); + } +#endif +} + +int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) +{ + if ((event->type == BLE_GAP_EVENT_CONNECT) || + (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { + ble_mesh_handle_connect(event, arg); } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { proxy_disconnected(event->disconnect.conn.conn_handle, event->disconnect.reason); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h index 9f19be07b..64338a0a3 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h @@ -19,7 +19,7 @@ int bt_mesh_proxy_send(uint16_t conn_handle, u8_t type, struct os_mbuf *msg); int bt_mesh_proxy_prov_enable(void); -int bt_mesh_proxy_prov_disable(void); +int bt_mesh_proxy_prov_disable(bool disconnect); int bt_mesh_proxy_gatt_enable(void); int bt_mesh_proxy_gatt_disable(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c index f0f4a27ea..88d9b302e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c @@ -5,11 +5,10 @@ */ #include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_SETTINGS_LOG #if MYNEWT_VAL(BLE_MESH_SETTINGS) -#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_SETTINGS) - #include "mesh/mesh.h" #include "mesh/glue.h" #include "net.h" @@ -19,6 +18,7 @@ #include "foundation.h" #include "proxy.h" #include "settings.h" +#include "nodes.h" #include "config/config.h" @@ -105,6 +105,31 @@ struct mod_pub_val { cred:1; }; +/* Virtual Address information */ +struct va_val { + u16_t ref; + u16_t addr; + u8_t uuid[16]; +} __packed; + +/* Node storage information */ +struct node_val { + u16_t net_idx; + u8_t dev_key[16]; + u8_t num_elem; +} __packed; + +struct node_update { + u16_t addr; + bool clear; +}; + +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) +static struct node_update node_updates[CONFIG_BT_MESH_NODE_COUNT]; +#else +static struct node_update node_updates[0]; +#endif + /* We need this so we don't overwrite app-hardcoded values in case FCB * contains a history of changes but then has a NULL at the end. */ @@ -658,6 +683,14 @@ static int mod_set(bool vnd, int argc, char **argv, char *val) return mod_set_pub(mod, val); } + if (!strcmp(argv[1], "data")) { + mod->flags |= BT_MESH_MOD_DATA_PRESENT; + + if (mod->cb && mod->cb->settings_set) { + return mod->cb->settings_set(mod, val); + } + } + BT_WARN("Unknown module key %s", argv[1]); return -ENOENT; } @@ -672,6 +705,115 @@ static int vnd_mod_set(int argc, char **argv, char *val) return mod_set(true, argc, argv, val); } +#if CONFIG_BT_MESH_LABEL_COUNT > 0 +static int va_set(int argc, char **argv, char *val) +{ + struct va_val va; + struct label *lab; + u16_t index; + int len, err; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + index = strtol(argv[0], NULL, 16); + + if (val == NULL) { + BT_WARN("Mesh Virtual Address length = 0"); + return 0; + } + + err = settings_bytes_from_str(val, &va, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(struct va_val)) { + BT_ERR("Invalid length for virtual address"); + return -EINVAL; + } + + if (va.ref == 0) { + BT_WARN("Ignore Mesh Virtual Address ref = 0"); + return 0; + } + + lab = get_label(index); + if (lab == NULL) { + BT_WARN("Out of labels buffers"); + return -ENOBUFS; + } + + memcpy(lab->uuid, va.uuid, 16); + lab->addr = va.addr; + lab->ref = va.ref; + + BT_DBG("Restored Virtual Address, addr 0x%04x ref 0x%04x", + lab->addr, lab->ref); + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) +static int node_set(int argc, char **argv, char *str) +{ + struct bt_mesh_node *node; + struct node_val val; + u16_t addr; + int len, err; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + addr = strtol(argv[0], NULL, 16); + + if (str == NULL) { + BT_DBG("val (null)"); + BT_DBG("Deleting node 0x%04x", addr); + + node = bt_mesh_node_find(addr); + if (node) { + bt_mesh_node_del(node, false); + } + + return 0; + } + + err = settings_bytes_from_str(str, &val, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(struct node_val)) { + BT_ERR("Invalid length for node_val"); + return -EINVAL; + } + + node = bt_mesh_node_find(addr); + if (!node) { + node = bt_mesh_node_alloc(addr, val.num_elem, val.net_idx); + } + + if (!node) { + BT_ERR("No space for a new node"); + return -ENOMEM; + } + + memcpy(node->dev_key, &val.dev_key, 16); + + BT_DBG("Node 0x%04x recovered from storage", addr); + + return 0; +} +#endif + const struct mesh_setting { const char *name; int (*func)(int argc, char **argv, char *val); @@ -686,6 +828,12 @@ const struct mesh_setting { { "Cfg", cfg_set }, { "s", sig_mod_set }, { "v", vnd_mod_set }, +#if CONFIG_BT_MESH_LABEL_COUNT > 0 + { "Va", va_set }, +#endif +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) + { "Node", node_set }, +#endif }; static int mesh_set(int argc, char **argv, char *val) @@ -756,6 +904,10 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, k_delayed_work_submit(&mod->pub->timer, ms); } } + + if (mod->cb && mod->cb->settings_commit) { + mod->cb->settings_commit(mod); + } } static int mesh_commit(void) @@ -772,7 +924,7 @@ static int mesh_commit(void) } if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - bt_mesh_proxy_prov_disable(); + bt_mesh_proxy_prov_disable(true); } for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { @@ -820,24 +972,41 @@ static int mesh_commit(void) return 0; } +/* Pending flags that use K_NO_WAIT as the storage timeout */ +#define NO_WAIT_PENDING_BITS (BIT(BT_MESH_NET_PENDING) | \ + BIT(BT_MESH_IV_PENDING) | \ + BIT(BT_MESH_SEQ_PENDING)) + +/* Pending flags that use CONFIG_BT_MESH_STORE_TIMEOUT */ +#define GENERIC_PENDING_BITS (BIT(BT_MESH_KEYS_PENDING) | \ + BIT(BT_MESH_HB_PUB_PENDING) | \ + BIT(BT_MESH_CFG_PENDING) | \ + BIT(BT_MESH_MOD_PENDING) | \ + BIT(BT_MESH_NODES_PENDING)) + static void schedule_store(int flag) { - s32_t timeout; + s32_t timeout, remaining; atomic_set_bit(bt_mesh.flags, flag); - if (atomic_test_bit(bt_mesh.flags, BT_MESH_NET_PENDING) || - atomic_test_bit(bt_mesh.flags, BT_MESH_IV_PENDING) || - atomic_test_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING)) { + if (atomic_get(bt_mesh.flags) & NO_WAIT_PENDING_BITS) { timeout = K_NO_WAIT; } else if (atomic_test_bit(bt_mesh.flags, BT_MESH_RPL_PENDING) && - (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < - CONFIG_BT_MESH_STORE_TIMEOUT)) { + (!(atomic_get(bt_mesh.flags) & GENERIC_PENDING_BITS) || + (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < + CONFIG_BT_MESH_STORE_TIMEOUT))) { timeout = K_SECONDS(CONFIG_BT_MESH_RPL_STORE_TIMEOUT); } else { timeout = K_SECONDS(CONFIG_BT_MESH_STORE_TIMEOUT); } + remaining = k_delayed_work_remaining_get(&pending_store); + if (remaining && remaining < timeout) { + BT_DBG("Not rescheduling due to existing earlier deadline"); + return; + } + BT_DBG("Waiting %d seconds", (int) (timeout / MSEC_PER_SEC)); k_delayed_work_submit(&pending_store, timeout); @@ -845,14 +1014,26 @@ static void schedule_store(int flag) static void clear_iv(void) { - BT_DBG("Clearing IV"); - settings_save_one("bt_mesh/IV", NULL); + int err; + + err = settings_save_one("bt_mesh/IV", NULL); + if (err) { + BT_ERR("Failed to clear IV"); + } else { + BT_DBG("Cleared IV"); + } } static void clear_net(void) { - BT_DBG("Clearing Network"); - settings_save_one("bt_mesh/Net", NULL); + int err; + + err = settings_save_one("bt_mesh/Net", NULL); + if (err) { + BT_ERR("Failed to clear Network"); + } else { + BT_DBG("Cleared Network"); + } } static void store_pending_net(void) @@ -860,6 +1041,7 @@ static void store_pending_net(void) char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; struct net_val net; char *str; + int err; BT_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(), bt_hex(bt_mesh.dev_key, 16)); @@ -874,7 +1056,12 @@ static void store_pending_net(void) } BT_DBG("Saving Network as value %s", str); - settings_save_one("bt_mesh/Net", str); + err = settings_save_one("bt_mesh/Net", str); + if (err) { + BT_ERR("Failed to store Network"); + } else { + BT_DBG("Stored Network"); + } } void bt_mesh_store_net(void) @@ -887,6 +1074,7 @@ static void store_pending_iv(void) char buf[BT_SETTINGS_SIZE(sizeof(struct iv_val))]; struct iv_val iv; char *str; + int err; iv.iv_index = bt_mesh.iv_index; iv.iv_update = atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); @@ -899,7 +1087,12 @@ static void store_pending_iv(void) } BT_DBG("Saving IV as value %s", str); - settings_save_one("bt_mesh/IV", str); + err = settings_save_one("bt_mesh/IV", str); + if (err) { + BT_ERR("Failed to store IV"); + } else { + BT_DBG("Stored IV"); + } } void bt_mesh_store_iv(bool only_duration) @@ -917,6 +1110,7 @@ static void store_pending_seq(void) char buf[BT_SETTINGS_SIZE(sizeof(struct seq_val))]; struct seq_val seq; char *str; + int err; seq.val[0] = bt_mesh.seq; seq.val[1] = bt_mesh.seq >> 8; @@ -929,7 +1123,12 @@ static void store_pending_seq(void) } BT_DBG("Saving Seq as value %s", str); - settings_save_one("bt_mesh/Seq", str); + err = settings_save_one("bt_mesh/Seq", str); + if (err) { + BT_ERR("Failed to store Seq"); + } else { + BT_DBG("Stored Seq"); + } } void bt_mesh_store_seq(void) @@ -948,6 +1147,7 @@ static void store_rpl(struct bt_mesh_rpl *entry) struct rpl_val rpl; char path[18]; char *str; + int err; BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, (unsigned) entry->seq, entry->old_iv); @@ -964,12 +1164,17 @@ static void store_rpl(struct bt_mesh_rpl *entry) snprintk(path, sizeof(path), "bt_mesh/RPL/%x", entry->src); BT_DBG("Saving RPL %s as value %s", path, str); - settings_save_one(path, str); + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store RPL"); + } else { + BT_DBG("Stored RPL"); + } } static void clear_rpl(void) { - int i; + int i, err; BT_DBG(""); @@ -982,7 +1187,12 @@ static void clear_rpl(void) } snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); - settings_save_one(path, NULL); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear RPL"); + } else { + BT_DBG("Cleared RPL"); + } memset(rpl, 0, sizeof(*rpl)); } @@ -1010,6 +1220,7 @@ static void store_pending_hb_pub(void) struct bt_mesh_hb_pub *pub = bt_mesh_hb_pub_get(); struct hb_pub_val val; char *str; + int err; if (!pub) { return; @@ -1035,7 +1246,12 @@ static void store_pending_hb_pub(void) BT_DBG("Saving Heartbeat Publication as value %s", str ? str : "(null)"); - settings_save_one("bt_mesh/HBPub", str); + err = settings_save_one("bt_mesh/HBPub", str); + if (err) { + BT_ERR("Failed to store Heartbeat Publication"); + } else { + BT_DBG("Stored Heartbeat Publication"); + } } static void store_pending_cfg(void) @@ -1044,6 +1260,7 @@ static void store_pending_cfg(void) struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); struct cfg_val val; char *str; + int err; if (!cfg) { return; @@ -1064,33 +1281,56 @@ static void store_pending_cfg(void) } BT_DBG("Saving configuration as value %s", str); - settings_save_one("bt_mesh/Cfg", str); + err = settings_save_one("bt_mesh/Cfg", str); + if (err) { + BT_ERR("Failed to store configuration"); + } else { + BT_DBG("Stored configuration"); + } } static void clear_cfg(void) { - BT_DBG("Clearing configuration"); - settings_save_one("bt_mesh/Cfg", NULL); + int err; + + err = settings_save_one("bt_mesh/Cfg", NULL); + if (err) { + BT_ERR("Failed to clear configuration"); + } else { + BT_DBG("Cleared configuration"); + } } static void clear_app_key(u16_t app_idx) { char path[20]; + int err; BT_DBG("AppKeyIndex 0x%03x", app_idx); snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); - settings_save_one(path, NULL); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx); + } else { + BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); + } } static void clear_net_key(u16_t net_idx) { char path[20]; + int err; BT_DBG("NetKeyIndex 0x%03x", net_idx); snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); - settings_save_one(path, NULL); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx); + } else { + BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); + } } static void store_net_key(struct bt_mesh_subnet *sub) @@ -1099,6 +1339,7 @@ static void store_net_key(struct bt_mesh_subnet *sub) struct net_key_val key; char path[20]; char *str; + int err; BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, bt_hex(sub->keys[0].net, 16)); @@ -1117,7 +1358,12 @@ static void store_net_key(struct bt_mesh_subnet *sub) snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", sub->net_idx); BT_DBG("Saving NetKey %s as value %s", path, str); - settings_save_one(path, str); + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store NetKey"); + } else { + BT_DBG("Stored NetKey"); + } } static void store_app_key(struct bt_mesh_app_key *app) @@ -1126,6 +1372,7 @@ static void store_app_key(struct bt_mesh_app_key *app) struct app_key_val key; char path[20]; char *str; + int err; key.net_idx = app->net_idx; key.updated = app->updated; @@ -1141,7 +1388,12 @@ static void store_app_key(struct bt_mesh_app_key *app) snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app->app_idx); BT_DBG("Saving AppKey %s as value %s", path, str); - settings_save_one(path, str); + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store AppKey"); + } else { + BT_DBG("Stored AppKey"); + } } static void store_pending_keys(void) @@ -1190,6 +1442,104 @@ static void store_pending_keys(void) } } +static void store_node(struct bt_mesh_node *node) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct node_val))]; + struct node_val val; + char path[20]; + char *str; + int err; + + val.net_idx = node->net_idx; + val.num_elem = node->num_elem; + memcpy(val.dev_key, node->dev_key, 16); + + snprintk(path, sizeof(path), "bt_mesh/Node/%x", node->addr); + + str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Node as value"); + return; + } + + + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store Node %s value", path); + } else { + BT_DBG("Stored Node %s value", path); + } +} + +static void clear_node(u16_t addr) +{ + char path[20]; + int err; + + BT_DBG("Node 0x%04x", addr); + + snprintk(path, sizeof(path), "bt_mesh/Node/%x", addr); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear Node 0x%04x", addr); + } else { + BT_DBG("Cleared Node 0x%04x", addr); + } +} + +static void store_pending_nodes(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(node_updates); ++i) { + struct node_update *update = &node_updates[i]; + + if (update->addr == BT_MESH_ADDR_UNASSIGNED) { + continue; + } + + if (update->clear) { + clear_node(update->addr); + } else { + struct bt_mesh_node *node; + + node = bt_mesh_node_find(update->addr); + if (node) { + store_node(node); + } else { + BT_WARN("Node 0x%04x not found", update->addr); + } + } + + update->addr = BT_MESH_ADDR_UNASSIGNED; + } +} + +static struct node_update *node_update_find(u16_t addr, + struct node_update **free_slot) +{ + struct node_update *match; + int i; + + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(node_updates); i++) { + struct node_update *update = &node_updates[i]; + + if (update->addr == BT_MESH_ADDR_UNASSIGNED) { + *free_slot = update; + continue; + } + + if (update->addr == addr) { + match = update; + } + } + + return match; +} + static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, const char *key, char *path, size_t path_len) { @@ -1207,7 +1557,7 @@ static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; char buf[BT_SETTINGS_SIZE(sizeof(keys))]; char path[20]; - int i, count; + int i, count, err; char *val; for (i = 0, count = 0; i < ARRAY_SIZE(mod->keys); i++) { @@ -1230,7 +1580,12 @@ static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) encode_mod_path(mod, vnd, "bind", path, sizeof(path)); BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - settings_save_one(path, val); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store bind"); + } else { + BT_DBG("Stored bind"); + } } static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) @@ -1238,10 +1593,10 @@ static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; char buf[BT_SETTINGS_SIZE(sizeof(groups))]; char path[20]; - int i, count; + int i, count, err; char *val; - for (i = 0, count = 0; i < ARRAY_SIZE(mod->groups); i++) { + for (i = 0, count = 0; i < CONFIG_BT_MESH_MODEL_GROUP_COUNT; i++) { if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { groups[count++] = mod->groups[i]; } @@ -1261,7 +1616,12 @@ static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) encode_mod_path(mod, vnd, "sub", path, sizeof(path)); BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - settings_save_one(path, val); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store sub"); + } else { + BT_DBG("Stored sub"); + } } static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) @@ -1270,6 +1630,7 @@ static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) struct mod_pub_val pub; char path[20]; char *val; + int err; if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) { val = NULL; @@ -1293,7 +1654,12 @@ static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) encode_mod_path(mod, vnd, "pub", path, sizeof(path)); BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - settings_save_one(path, val); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store pub"); + } else { + BT_DBG("Stored pub"); + } } static void store_pending_mod(struct bt_mesh_model *mod, @@ -1320,6 +1686,52 @@ static void store_pending_mod(struct bt_mesh_model *mod, } } +#define IS_VA_DEL(_label) ((_label)->ref == 0) +static void store_pending_va(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct va_val))]; + struct label *lab; + struct va_val va; + char path[18]; + char *val; + u16_t i; + int err = 0; + + for (i = 0; (lab = get_label(i)) != NULL; i++) { + if (!atomic_test_and_clear_bit(lab->flags, + BT_MESH_VA_CHANGED)) { + continue; + } + + snprintk(path, sizeof(path), "bt_mesh/Va/%x", i); + + if (IS_VA_DEL(lab)) { + val = NULL; + } else { + va.ref = lab->ref; + va.addr = lab->addr; + memcpy(va.uuid, lab->uuid, 16); + + val = settings_str_from_bytes(&va, sizeof(va), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return; + } + + err = settings_save_one(path, val); + } + + if (err) { + BT_ERR("Failed to %s %s value (err %d)", + IS_VA_DEL(lab) ? "delete" : "store", path, err); + } else { + BT_DBG("%s %s value", + IS_VA_DEL(lab) ? "Deleted" : "Stored", path); + } + } +} + static void store_pending(struct ble_npl_event *work) { BT_DBG(""); @@ -1371,6 +1783,15 @@ static void store_pending(struct ble_npl_event *work) if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_MOD_PENDING)) { bt_mesh_model_foreach(store_pending_mod, NULL); } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_VA_PENDING)) { + store_pending_va(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) && + atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_NODES_PENDING)) { + store_pending_nodes(); + } } void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) @@ -1552,6 +1973,93 @@ void bt_mesh_store_mod_pub(struct bt_mesh_model *mod) schedule_store(BT_MESH_MOD_PENDING); } + +void bt_mesh_store_label(void) +{ + schedule_store(BT_MESH_VA_PENDING); +} + +void bt_mesh_store_node(struct bt_mesh_node *node) +{ + struct node_update *update, *free_slot; + + BT_DBG("Node 0x%04x", node->addr); + + update = node_update_find(node->addr, &free_slot); + if (update) { + update->clear = false; + schedule_store(BT_MESH_NODES_PENDING); + return; + } + + if (!free_slot) { + store_node(node); + return; + } + + free_slot->addr = node->addr; + + schedule_store(BT_MESH_NODES_PENDING); +} + +void bt_mesh_clear_node(struct bt_mesh_node *node) +{ + struct node_update *update, *free_slot; + + BT_DBG("Node 0x%04x", node->addr); + + update = node_update_find(node->addr, &free_slot); + if (update) { + update->clear = true; + schedule_store(BT_MESH_NODES_PENDING); + return; + } + + if (!free_slot) { + clear_node(node->addr); + return; + } + + free_slot->addr = node->addr; + + schedule_store(BT_MESH_NODES_PENDING); +} + +int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, + const void *data, size_t data_len) +{ + char path[20]; + char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; + char *val; + int err; + + encode_mod_path(mod, vnd, "data", path, sizeof(path)); + + if (data_len) { + mod->flags |= BT_MESH_MOD_DATA_PRESENT; + val = settings_str_from_bytes(data, data_len, + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return -EINVAL; + } + err = settings_save_one(path, val); + } else if (mod->flags & BT_MESH_MOD_DATA_PRESENT) { + mod->flags &= ~BT_MESH_MOD_DATA_PRESENT; + err = settings_save_one(path, NULL); + } else { + /* Nothing to delete */ + err = 0; + } + + if (err) { + BT_ERR("Failed to store %s value", path); + } else { + BT_DBG("Stored %s value", path); + } + return err; +} + static struct conf_handler bt_mesh_settings_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h index 7bd028477..c630814e5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h @@ -15,10 +15,13 @@ void bt_mesh_store_cfg(void); void bt_mesh_store_mod_bind(struct bt_mesh_model *mod); void bt_mesh_store_mod_sub(struct bt_mesh_model *mod); void bt_mesh_store_mod_pub(struct bt_mesh_model *mod); +void bt_mesh_store_label(void); +void bt_mesh_store_node(struct bt_mesh_node *node); void bt_mesh_clear_net(void); void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub); void bt_mesh_clear_app_key(struct bt_mesh_app_key *key); void bt_mesh_clear_rpl(void); +void bt_mesh_clear_node(struct bt_mesh_node *node); void bt_mesh_settings_init(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c index 94a7b58be..91fbd9785 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c @@ -222,37 +222,46 @@ static struct bt_mesh_health_cli health_cli = { #endif /* MYNEWT_VAL(BLE_MESH_HEALTH_CLI) */ #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) -static struct bt_mesh_model_pub gen_onoff_pub; -static struct bt_mesh_model_pub gen_level_pub; +static struct bt_mesh_gen_model_cli gen_onoff_cli; +static struct bt_mesh_model_pub gen_onoff_cli_pub; +static struct bt_mesh_model_pub gen_onoff_srv_pub; +static struct bt_mesh_gen_model_cli gen_level_cli; +static struct bt_mesh_model_pub gen_level_cli_pub; +static struct bt_mesh_model_pub gen_level_srv_pub; static struct bt_mesh_model_pub light_lightness_pub; -static struct bt_mesh_gen_onoff_srv_cb gen_onoff_srv_cb = { +static struct bt_mesh_gen_onoff_srv gen_onoff_srv = { .get = light_model_gen_onoff_get, .set = light_model_gen_onoff_set, }; -static struct bt_mesh_gen_level_srv_cb gen_level_srv_cb = { +static struct bt_mesh_gen_level_srv gen_level_srv = { .get = light_model_gen_level_get, .set = light_model_gen_level_set, }; -static struct bt_mesh_light_lightness_srv_cb light_lightness_srv_cb = { +static struct bt_mesh_light_lightness_srv light_lightness_srv = { .get = light_model_light_lightness_get, .set = light_model_light_lightness_set, }; -void bt_mesh_set_gen_onoff_srv_cb(struct bt_mesh_gen_onoff_srv_cb *gen_onoff_cb) +void bt_mesh_set_gen_onoff_srv_cb(int (*get)(struct bt_mesh_model *model, u8_t *state), + int (*set)(struct bt_mesh_model *model, u8_t state)) { - gen_onoff_srv_cb = *gen_onoff_cb; + gen_onoff_srv.get = get; + gen_onoff_srv.set = set; } -void bt_mesh_set_gen_level_srv_cb(struct bt_mesh_gen_level_srv_cb *gen_level_cb) +void bt_mesh_set_gen_level_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level), + int (*set)(struct bt_mesh_model *model, s16_t level)) { - gen_level_srv_cb = *gen_level_cb; + gen_level_srv.get = get; + gen_level_srv.set = set; } -void bt_mesh_set_light_lightness_srv_cb(struct bt_mesh_light_lightness_srv_cb *light_lightness_cb) +void bt_mesh_set_light_lightness_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level), + int (*set)(struct bt_mesh_model *model, s16_t level)) { - light_lightness_srv_cb = *light_lightness_cb; + light_lightness_srv.get = get; + light_lightness_srv.set = set; } - #endif static struct bt_mesh_model root_models[] = { @@ -265,11 +274,11 @@ static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_HEALTH_CLI(&health_cli), #endif #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) - BT_MESH_MODEL_GEN_ONOFF_SRV(&gen_onoff_srv_cb, &gen_onoff_pub), - BT_MESH_MODEL_GEN_ONOFF_CLI(), - BT_MESH_MODEL_GEN_LEVEL_SRV(&gen_level_srv_cb, &gen_level_pub), - BT_MESH_MODEL_GEN_LEVEL_CLI(), - BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(&light_lightness_srv_cb, &light_lightness_pub), + BT_MESH_MODEL_GEN_ONOFF_SRV(&gen_onoff_srv, &gen_onoff_srv_pub), + BT_MESH_MODEL_GEN_ONOFF_CLI(&gen_onoff_cli, &gen_onoff_cli_pub), + BT_MESH_MODEL_GEN_LEVEL_SRV(&gen_level_srv, &gen_level_srv_pub), + BT_MESH_MODEL_GEN_LEVEL_CLI(&gen_level_cli, &gen_level_cli_pub), + BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(&light_lightness_srv, &light_lightness_pub), #endif }; @@ -323,11 +332,25 @@ static void prov_complete(u16_t net_idx, u16_t addr) { printk("Local node provisioned, net_idx 0x%04x address 0x%04x\n", net_idx, addr); - net.net_idx = net_idx, net.local = addr; + net.net_idx = net_idx, net.dst = addr; } +static void prov_node_added(u16_t net_idx, u16_t addr, u8_t num_elem) +{ + printk("Node provisioned, net_idx 0x%04x address " + "0x%04x elements %d", net_idx, addr, num_elem); + + net.net_idx = net_idx, + net.dst = addr; +} + +static void prov_input_complete(void) +{ + printk("Input complete"); +} + static void prov_reset(void) { printk("The local node has been reset and needs reprovisioning\n"); @@ -467,6 +490,7 @@ static struct bt_mesh_prov prov = { .link_open = link_open, .link_close = link_close, .complete = prov_complete, + .node_added = prov_node_added, .reset = prov_reset, .static_val = NULL, .static_val_len = 0, @@ -477,6 +501,7 @@ static struct bt_mesh_prov prov = { .input_size = MYNEWT_VAL(BLE_MESH_OOB_INPUT_SIZE), .input_actions = MYNEWT_VAL(BLE_MESH_OOB_INPUT_ACTIONS), .input = input, + .input_complete = prov_input_complete, }; static int cmd_static_oob(int argc, char *argv[]) @@ -794,19 +819,6 @@ struct shell_cmd_help cmd_net_send_help = { NULL, "", NULL }; -static int cmd_iv_update(int argc, char *argv[]) -{ - if (bt_mesh_iv_update()) { - printk("Transitioned to IV Update In Progress state\n"); - } else { - printk("Transitioned to IV Update Normal state\n"); - } - - printk("IV Index is 0x%08lx\n", bt_mesh.iv_index); - - return 0; -} - static int cmd_rpl_clear(int argc, char *argv[]) { bt_mesh_rpl_clear(); @@ -857,6 +869,20 @@ struct shell_cmd_help cmd_lpn_unsubscribe_help = { }; #endif +#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) +static int cmd_iv_update(int argc, char *argv[]) +{ + if (bt_mesh_iv_update()) { + printk("Transitioned to IV Update In Progress state\n"); + } else { + printk("Transitioned to IV Update Normal state\n"); + } + + printk("IV Index is 0x%08lx\n", bt_mesh.iv_index); + + return 0; +} + static int cmd_iv_update_test(int argc, char *argv[]) { bool enable; @@ -880,6 +906,7 @@ static int cmd_iv_update_test(int argc, char *argv[]) struct shell_cmd_help cmd_iv_update_test_help = { NULL, "", NULL }; +#endif #if MYNEWT_VAL(BLE_MESH_CFG_CLI) @@ -1802,6 +1829,37 @@ static int cmd_pb_adv(int argc, char *argv[]) { return cmd_pb(BT_MESH_PROV_ADV, argc, argv); } + +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) +static int cmd_provision_adv(int argc, char *argv[]) +{ + u8_t uuid[16]; + u8_t attention_duration; + u16_t net_idx; + u16_t addr; + size_t len; + int err; + + len = hex2bin(argv[1], uuid, sizeof(uuid)); + (void)memset(uuid + len, 0, sizeof(uuid) - len); + + net_idx = strtoul(argv[2], NULL, 0); + addr = strtoul(argv[3], NULL, 0); + attention_duration = strtoul(argv[4], NULL, 0); + + err = bt_mesh_provision_adv(uuid, net_idx, addr, attention_duration); + if (err) { + printk("Provisioning failed (err %d)", err); + } + + return 0; +} + +struct shell_cmd_help cmd_provision_adv_help = { + NULL, " " , NULL +}; +#endif /* CONFIG_BT_MESH_PROVISIONER */ + #endif /* CONFIG_BT_MESH_PB_ADV */ #if MYNEWT_VAL(BLE_MESH_PB_GATT) @@ -2403,6 +2461,13 @@ static const struct shell_cmd mesh_commands[] = { .sc_cmd_func = cmd_pb_adv, .help = &cmd_pb_help, }, +#if MYNEWT_VAL(BLE_MESH_PROVISIONER) + { + .sc_cmd = "provision-adv", + .sc_cmd_func = cmd_provision_adv, + .help = &cmd_provision_adv_help, + }, +#endif #endif #if MYNEWT_VAL(BLE_MESH_PB_GATT) { @@ -2482,6 +2547,7 @@ static const struct shell_cmd mesh_commands[] = { .sc_cmd_func = cmd_net_send, .help = &cmd_net_send_help, }, +#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) { .sc_cmd = "iv-update", .sc_cmd_func = cmd_iv_update, @@ -2492,6 +2558,7 @@ static const struct shell_cmd mesh_commands[] = { .sc_cmd_func = cmd_iv_update_test, .help = &cmd_iv_update_test_help, }, +#endif { .sc_cmd = "rpl-clear", .sc_cmd_func = cmd_rpl_clear, diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_cmd_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_cmd_priv.h index ddc952bff..70f33260a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_cmd_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_cmd_priv.h @@ -357,7 +357,6 @@ void ble_att_error_rsp_parse(const void *payload, int len, struct ble_att_error_rsp *rsp); void ble_att_error_rsp_write(void *payload, int len, const struct ble_att_error_rsp *rsp); -void ble_att_error_rsp_log(const struct ble_att_error_rsp *cmd); void ble_att_mtu_req_parse(const void *payload, int len, struct ble_att_mtu_cmd *cmd); void ble_att_mtu_req_write(void *payload, int len, @@ -366,43 +365,34 @@ void ble_att_mtu_rsp_parse(const void *payload, int len, struct ble_att_mtu_cmd *cmd); void ble_att_mtu_rsp_write(void *payload, int len, const struct ble_att_mtu_cmd *cmd); -void ble_att_mtu_cmd_log(const struct ble_att_mtu_cmd *cmd); void ble_att_find_info_req_parse(const void *payload, int len, struct ble_att_find_info_req *req); void ble_att_find_info_req_write(void *payload, int len, const struct ble_att_find_info_req *req); -void ble_att_find_info_req_log(const struct ble_att_find_info_req *cmd); void ble_att_find_info_rsp_parse(const void *payload, int len, struct ble_att_find_info_rsp *rsp); void ble_att_find_info_rsp_write(void *payload, int len, const struct ble_att_find_info_rsp *rsp); -void ble_att_find_info_rsp_log(const struct ble_att_find_info_rsp *cmd); void ble_att_find_type_value_req_parse( const void *payload, int len, struct ble_att_find_type_value_req *req); void ble_att_find_type_value_req_write( void *payload, int len, const struct ble_att_find_type_value_req *req); -void ble_att_find_type_value_req_log( - const struct ble_att_find_type_value_req *cmd); void ble_att_read_type_req_parse(const void *payload, int len, struct ble_att_read_type_req *req); void ble_att_read_type_req_write(void *payload, int len, const struct ble_att_read_type_req *req); -void ble_att_read_type_req_log(const struct ble_att_read_type_req *cmd); void ble_att_read_type_rsp_parse(const void *payload, int len, struct ble_att_read_type_rsp *rsp); void ble_att_read_type_rsp_write(void *payload, int len, const struct ble_att_read_type_rsp *rsp); -void ble_att_read_type_rsp_log(const struct ble_att_read_type_rsp *cmd); void ble_att_read_req_parse(const void *payload, int len, struct ble_att_read_req *req); void ble_att_read_req_write(void *payload, int len, const struct ble_att_read_req *req); -void ble_att_read_req_log(const struct ble_att_read_req *cmd); void ble_att_read_blob_req_parse(const void *payload, int len, struct ble_att_read_blob_req *req); void ble_att_read_blob_req_write(void *payload, int len, const struct ble_att_read_blob_req *req); -void ble_att_read_blob_req_log(const struct ble_att_read_blob_req *cmd); void ble_att_read_mult_req_parse(const void *payload, int len); void ble_att_read_mult_req_write(void *payload, int len); void ble_att_read_mult_rsp_parse(const void *payload, int len); @@ -411,14 +401,10 @@ void ble_att_read_group_type_req_parse( const void *payload, int len, struct ble_att_read_group_type_req *req); void ble_att_read_group_type_req_write( void *payload, int len, const struct ble_att_read_group_type_req *req); -void ble_att_read_group_type_req_log( - const struct ble_att_read_group_type_req *cmd); void ble_att_read_group_type_rsp_parse( const void *payload, int len, struct ble_att_read_group_type_rsp *rsp); void ble_att_read_group_type_rsp_write( void *payload, int len, const struct ble_att_read_group_type_rsp *rsp); -void ble_att_read_group_type_rsp_log( - const struct ble_att_read_group_type_rsp *cmd); void ble_att_write_req_parse(const void *payload, int len, struct ble_att_write_req *req); void ble_att_write_req_write(void *payload, int len, @@ -427,20 +413,16 @@ void ble_att_write_cmd_parse(const void *payload, int len, struct ble_att_write_req *req); void ble_att_write_cmd_write(void *payload, int len, const struct ble_att_write_req *req); -void ble_att_write_cmd_log(const struct ble_att_write_cmd *cmd); -void ble_att_write_req_log(const struct ble_att_write_req *req); void ble_att_prep_write_req_parse(const void *payload, int len, struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_req_write(void *payload, int len, const struct ble_att_prep_write_cmd *cmd); -void ble_att_prep_write_cmd_log(const struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_rsp_parse(const void *payload, int len, struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_rsp_write(void *payload, int len, const struct ble_att_prep_write_cmd *cmd); void ble_att_exec_write_req_parse(const void *payload, int len, struct ble_att_exec_write_req *req); -void ble_att_exec_write_req_log(const struct ble_att_exec_write_req *cmd); void ble_att_exec_write_req_write(void *payload, int len, const struct ble_att_exec_write_req *req); void ble_att_exec_write_rsp_parse(const void *payload, int len); @@ -449,14 +431,12 @@ void ble_att_notify_req_parse(const void *payload, int len, struct ble_att_notify_req *req); void ble_att_notify_req_write(void *payload, int len, const struct ble_att_notify_req *req); -void ble_att_notify_req_log(const struct ble_att_notify_req *cmd); void ble_att_indicate_req_parse(const void *payload, int len, struct ble_att_indicate_req *req); void ble_att_indicate_req_write(void *payload, int len, const struct ble_att_indicate_req *req); void ble_att_indicate_rsp_parse(const void *payload, int len); void ble_att_indicate_rsp_write(void *payload, int len); -void ble_att_indicate_req_log(const struct ble_att_indicate_req *cmd); void *ble_att_cmd_prepare(uint8_t opcode, size_t len, struct os_mbuf *txom); void *ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_priv.h index 2201d4ddb..73b6aeab0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_att_priv.h @@ -170,12 +170,6 @@ void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); int ble_att_init(void); -#define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ - BLE_HS_LOG_CMD((is_tx), "att", (cmd_name), (conn_handle), (log_cb), (cmd)) - -#define BLE_ATT_LOG_EMPTY_CMD(is_tx, cmd_name, conn_handle) \ - BLE_HS_LOG_EMPTY_CMD((is_tx), "att", (cmd_name), (conn_handle)) - /*** @svr */ int ble_att_svr_start(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h index 90c32e22a..2b6b40696 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h @@ -81,23 +81,40 @@ void ble_gap_rx_le_scan_timeout(void); #if MYNEWT_VAL(BLE_EXT_ADV) void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc); -void ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt); +void ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminated *ev); #if MYNEWT_VAL(BLE_PERIODIC_ADV) -void ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab *evt); -void ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt); -void ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *evt); +void ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev); +void ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_rpt *ev); +void ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev); +void ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev); #endif -void ble_gap_rx_scan_req_rcvd(struct hci_le_scan_req_rcvd *evt); +void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev); #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); -void ble_gap_rx_rd_rem_sup_feat_complete(struct hci_le_rd_rem_supp_feat_complete *evt); -int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance); -void ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt); -void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt); -void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt); +void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev); + +struct ble_gap_conn_complete +{ + uint8_t status; + uint16_t connection_handle; + uint8_t role; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t master_clk_acc; + uint8_t local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; +}; + +int ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance); +void ble_gap_rx_disconn_complete(const struct ble_hci_ev_disconn_cmp *ev); +void ble_gap_rx_update_complete(const struct ble_hci_ev_le_subev_conn_upd_complete *ev); +void ble_gap_rx_param_req(const struct ble_hci_ev_le_subev_rem_conn_param_req *ev); int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); -void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); +void ble_gap_rx_phy_update_complete(const struct ble_hci_ev_le_subev_phy_update_complete *ev); void ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored, int bonded); void ble_gap_passkey_event(uint16_t conn_handle, @@ -118,6 +135,7 @@ int ble_gap_master_in_progress(void); void ble_gap_preempt(void); void ble_gap_preempt_done(void); +int ble_gap_terminate_with_conn(struct ble_hs_conn *conn, uint8_t hci_reason); void ble_gap_conn_broken(uint16_t conn_handle, int reason); void ble_gap_reset_state(int reason); int32_t ble_gap_timer(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_conn_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_conn_priv.h index 92aacd405..0e451194d 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_conn_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_conn_priv.h @@ -38,6 +38,15 @@ typedef uint8_t ble_hs_conn_flags_t; #define BLE_HS_CONN_F_TERMINATING 0x02 #define BLE_HS_CONN_F_TX_FRAG 0x04 /* Cur ACL packet partially txed. */ +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) +#define BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN_REM \ + ((MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) % (8 * sizeof(uint32_t))) ? 1 : 0) + +#define BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN \ + (MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) / (8 * sizeof(uint32_t)) + \ + BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN_REM) +#endif + struct ble_hs_conn { SLIST_ENTRY(ble_hs_conn) bhc_next; uint16_t bhc_handle; @@ -61,6 +70,9 @@ struct ble_hs_conn { struct ble_l2cap_chan_list bhc_channels; struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */ ble_npl_time_t bhc_rx_timeout; +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + uint32_t l2cap_coc_cid_mask[BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN]; +#endif /** * Count of packets sent over this connection that the controller has not @@ -86,6 +98,10 @@ struct ble_hs_conn { ble_gap_event_fn *bhc_cb; void *bhc_cb_arg; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + struct ble_hs_periodic_sync *psync; +#endif }; struct ble_hs_conn_addrs { @@ -110,15 +126,19 @@ struct ble_l2cap_chan *ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn, uint16_t cid); struct ble_l2cap_chan *ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn, uint16_t cid); +bool ble_hs_conn_chan_exist(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); int ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); -void -ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); +void ble_hs_conn_delete_chan(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan); void ble_hs_conn_addrs(const struct ble_hs_conn *conn, struct ble_hs_conn_addrs *addrs); int32_t ble_hs_conn_timer(void); +typedef int ble_hs_conn_foreach_fn(struct ble_hs_conn *conn, void *arg); +void ble_hs_conn_foreach(ble_hs_conn_foreach_fn *cb, void *arg); + int ble_hs_conn_init(void); #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_flow_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_flow_priv.h index b1aa8c2fc..753eaf8ff 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_flow_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_flow_priv.h @@ -26,7 +26,7 @@ extern "C" { #endif void ble_hs_flow_connection_broken(uint16_t conn_handle); -void ble_hs_flow_fill_acl_usrhdr(struct os_mbuf *om); +void ble_hs_flow_track_data_mbuf(struct os_mbuf *om); int ble_hs_flow_startup(void); #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_hci_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_hci_priv.h index ff3604727..362f12cbd 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_hci_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_hci_priv.h @@ -48,7 +48,7 @@ struct os_mbuf; struct ble_hs_hci_ack { int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */ - uint8_t *bha_params; + const uint8_t *bha_params; int bha_params_len; uint16_t bha_opcode; uint8_t bha_hci_handle; @@ -81,11 +81,8 @@ struct hci_periodic_adv_params extern uint16_t ble_hs_hci_avail_pkts; -int ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, - void *evt_buf, uint8_t evt_buf_len, - uint8_t *out_evt_buf_len); -int ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len); -void ble_hs_hci_rx_ack(uint8_t *ack_ev); +int ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, + void *rsp, uint8_t rsp_len); void ble_hs_hci_init(void); void ble_hs_hci_deinit(void); @@ -103,78 +100,11 @@ int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_pwr); int ble_hs_hci_util_rand(void *dst, int len); int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); -int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, - uint16_t tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); -int ble_hs_hci_evt_process(uint8_t *data); +int ble_hs_hci_evt_process(const struct ble_hci_ev *ev); -void ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, - void *buf); -int ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len); -void ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_read_buffer_size(void); -void ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst, - int dst_len); -int ble_hs_hci_cmd_le_set_adv_enable(uint8_t enable); -int ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type, - uint16_t scan_itvl, - uint16_t scan_window, - uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint8_t *dst, uint8_t dst_len); -int ble_hs_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups); -int ble_hs_hci_cmd_build_le_create_connection( - const struct hci_create_conn *hcc, uint8_t *cmd, int cmd_len); -int ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr, - uint8_t addr_type, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_reset(void); -int ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable); -int ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd); -int ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - const struct hci_host_num_comp_pkts_entry *entry, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_read_adv_pwr(void); -int ble_hs_hci_cmd_le_create_conn_cancel(void); -int ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu); -void ble_hs_hci_cmd_build_le_lt_key_req_reply( - const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_conn_param_reply( - const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr); -void ble_hs_hci_cmd_build_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn); -void ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst, int dst_len); +int ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len); int ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts); void ble_hs_hci_add_avail_pkts(uint16_t delta); @@ -184,145 +114,9 @@ uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, int ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om); int ble_hs_hci_acl_tx(struct ble_hs_conn *conn, struct os_mbuf **om); -int ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, uint16_t tx_time, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_add_to_resolv_list( - const struct hci_add_dev_to_resolving_list *padd, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_remove_from_resolv_list( - uint8_t addr_type, const uint8_t *addr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_peer_resolv_addr( - uint8_t peer_identity_addr_type, const uint8_t *peer_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_lcl_resolv_addr( - uint8_t local_identity_addr_type, const uint8_t *local_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_addr_res_en( - uint8_t enable, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout( - uint16_t timeout, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr, - uint8_t *dst, int dst_len); - -#if MYNEWT_VAL(BLE_EXT_ADV) -int ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint16_t duration, - uint16_t period, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle, - const uint8_t *addr, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation, - uint8_t frag_pref, struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num, - const struct hci_ext_adv_set *sets, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle, - const struct hci_ext_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle, - uint8_t *cmd, int cmd_len); - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -int -ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle, - const struct hci_periodic_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable, - uint8_t handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, uint8_t operation, - struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy, - uint8_t adv_sid, - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint16_t skip, - uint16_t sync_timeout, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -#endif - -#endif - -int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy, - uint8_t mod_idx, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, - uint8_t test_data_len, - uint8_t packet_payload_idx, - uint8_t phy, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst, - uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, - int dst_len); - -int ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, - uint8_t rx_phys_mask, - uint8_t *dst, int dst_len); - -int ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst, int dst_len); - int ble_hs_hci_frag_num_mbufs(void); int ble_hs_hci_frag_num_mbufs_free(void); -#if MYNEWT_VAL(BLE_EXT_ADV) -#endif - -int ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst, - int dst_len); #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h index 49269546c..538d07a97 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h @@ -26,7 +26,6 @@ #include "ble_att_priv.h" #include "ble_gap_priv.h" #include "ble_gatt_priv.h" -#include "ble_hs_dbg_priv.h" #include "ble_hs_hci_priv.h" #include "ble_hs_atomic_priv.h" #include "ble_hs_conn_priv.h" @@ -118,7 +117,8 @@ int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); -uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); +uint8_t ble_hs_misc_own_addr_type_to_id(uint8_t addr_type); +uint8_t ble_hs_misc_peer_addr_type_to_id(uint8_t addr_type); int ble_hs_misc_restore_irks(void); int ble_hs_locked_by_cur_task(void); @@ -142,31 +142,6 @@ int ble_mqueue_init(struct ble_mqueue *mq, ble_npl_event_fn *ev_fn, void *ev_arg struct os_mbuf *ble_mqueue_get(struct ble_mqueue *mq); int ble_mqueue_put(struct ble_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *om); -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG && !BLE_MONITOR - -#define BLE_HS_LOG_CMD(is_tx, cmd_type, cmd_name, conn_handle, \ - log_cb, cmd) do \ -{ \ - BLE_HS_LOG(DEBUG, "%sed %s command: %s; conn=%d ", \ - (is_tx) ? "tx" : "rx", (cmd_type), (cmd_name), (conn_handle)); \ - (log_cb)(cmd); \ - BLE_HS_LOG(DEBUG, "\n"); \ -} while (0) - -#define BLE_HS_LOG_EMPTY_CMD(is_tx, cmd_type, cmd_name, conn_handle) do \ -{ \ - BLE_HS_LOG(DEBUG, "%sed %s command: %s; conn=%d ", \ - (is_tx) ? "tx" : "rx", (cmd_type), (cmd_name), (conn_handle)); \ - BLE_HS_LOG(DEBUG, "\n"); \ -} while (0) - -#else - -#define BLE_HS_LOG_CMD(is_tx, cmd_type, cmd_name, conn_handle, log_cb, cmd) -#define BLE_HS_LOG_EMPTY_CMD(is_tx, cmd_type, cmd_name, conn_handle) - -#endif - #if MYNEWT_VAL(BLE_HS_DEBUG) #define BLE_HS_DBG_ASSERT(x) assert(x) #define BLE_HS_DBG_ASSERT_EVAL(x) assert(x) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_coc_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_coc_priv.h index 0a1a97b77..5ebdaa050 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_coc_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_coc_priv.h @@ -57,25 +57,46 @@ struct ble_l2cap_coc_srv { int ble_l2cap_coc_init(void); int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); -int ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, +int ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm, struct ble_l2cap_chan **chan); -struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(uint16_t conn_handle, +struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn, uint16_t psm, uint16_t mtu, struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg); -void ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan); +void ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); void ble_l2cap_coc_le_credits_update(uint16_t conn_handle, uint16_t dcid, uint16_t credits); int ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); int ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); +void ble_l2cap_coc_set_new_mtu_mps(struct ble_l2cap_chan *chan, uint16_t mtu, uint16_t mps); #else -#define ble_l2cap_coc_init() 0 -#define ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg) BLE_HS_ENOTSUP -#define ble_l2cap_coc_recv_ready(chan, sdu_rx) BLE_HS_ENOTSUP -#define ble_l2cap_coc_cleanup_chan(chan) -#define ble_l2cap_coc_send(chan, sdu_tx) BLE_HS_ENOTSUP +static inline int +ble_l2cap_coc_init(void) { + return 0; +} + +static inline int +ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, + ble_l2cap_event_fn *cb, void *cb_arg) { + return BLE_HS_ENOTSUP; +} + +static inline int +ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, + struct os_mbuf *sdu_rx) { + return BLE_HS_ENOTSUP; +} + +static inline void +ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { +} + +static inline int +ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx) { + return BLE_HS_ENOTSUP; +} #endif #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_priv.h index 640974d2a..e3409743b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_priv.h @@ -65,8 +65,20 @@ struct ble_l2cap_chan { uint16_t conn_handle; uint16_t dcid; uint16_t scid; - uint16_t my_mtu; - uint16_t peer_mtu; /* 0 if not exchanged. */ + + /* Unions just to avoid confusion on MPS/MTU. + * In CoC context, L2CAP MTU is MPS + */ + union { + uint16_t my_mtu; + uint16_t my_coc_mps; + }; + + union { + uint16_t peer_mtu; + uint16_t peer_coc_mps; + }; + ble_l2cap_chan_flags flags; struct os_mbuf *rx_buf; @@ -102,7 +114,7 @@ struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len); struct ble_l2cap_chan *ble_l2cap_chan_alloc(uint16_t conn_handle); -void ble_l2cap_chan_free(struct ble_l2cap_chan *chan); +void ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan); @@ -118,6 +130,13 @@ void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); int ble_l2cap_init(void); +/* Below experimental API is available when BLE_VERSION >= 52 */ +int ble_l2cap_enhanced_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu); + #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_sig_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_sig_priv.h index 1a6fb8293..a698cd0d8 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_sig_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_l2cap_sig_priv.h @@ -74,6 +74,32 @@ struct ble_l2cap_sig_le_con_rsp { uint16_t result; } __attribute__((packed)); +struct ble_l2cap_sig_credit_base_connect_req { + uint16_t psm; + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t scids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_connect_rsp { + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t result; + uint16_t dcids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_reconfig_req { + uint16_t mtu; + uint16_t mps; + uint16_t dcids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_reconfig_rsp { + uint16_t result; +} __attribute__((packed)); + struct ble_l2cap_sig_disc_req { uint16_t dcid; uint16_t scid; @@ -107,9 +133,43 @@ int ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan); int ble_l2cap_sig_le_credits(uint16_t conn_handle, uint16_t scid, uint16_t credits); #else -#define ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg) \ - BLE_HS_ENOTSUP -#define ble_l2cap_sig_disconnect(chan) BLE_HS_ENOTSUP +static inline int +ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, void *cb_arg) +{ + return BLE_HS_ENOTSUP; +} + +static inline int +ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan) +{ + return BLE_HS_ENOTSUP; +} +#endif + +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +int ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], + uint8_t num, uint16_t new_mtu); +#else +static inline int +ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg) +{ + return BLE_HS_ENOTSUP; +} +static inline int +ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], + uint8_t num, uint16_t new_mtu) +{ + return BLE_HS_ENOTSUP; +} #endif void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h index bbb4b03ae..def0a32f5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h @@ -269,6 +269,8 @@ struct ble_sm_proc { struct ble_sm_public_key pub_key_peer; uint8_t mackey[16]; uint8_t dhkey[32]; + const struct ble_sm_sc_oob_data *oob_data_local; + const struct ble_sm_sc_oob_data *oob_data_remote; #endif }; @@ -294,44 +296,33 @@ void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey); int ble_sm_num_procs(void); -void ble_sm_pair_cmd_log(struct ble_sm_pair_cmd *cmd); -void ble_sm_pair_confirm_log(struct ble_sm_pair_confirm *cmd); -void ble_sm_pair_random_log(struct ble_sm_pair_random *cmd); -void ble_sm_pair_fail_log(struct ble_sm_pair_fail *cmd); -void ble_sm_enc_info_log(struct ble_sm_enc_info *cmd); -void ble_sm_master_id_log(struct ble_sm_master_id *cmd); -void ble_sm_id_info_log(struct ble_sm_id_info *cmd); -void ble_sm_id_addr_info_log(struct ble_sm_id_addr_info *cmd); -void ble_sm_sign_info_log(struct ble_sm_sign_info *cmd); -void ble_sm_sec_req_log(struct ble_sm_sec_req *cmd); -void ble_sm_public_key_log(struct ble_sm_public_key *cmd); -void ble_sm_dhkey_check_log(struct ble_sm_dhkey_check *cmd); - -int ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out); -int ble_sm_alg_c1(uint8_t *k, uint8_t *r, - uint8_t *preq, uint8_t *pres, +int ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2, + uint8_t *out); +int ble_sm_alg_c1(const uint8_t *k, const uint8_t *r, + const uint8_t *preq, const uint8_t *pres, uint8_t iat, uint8_t rat, - uint8_t *ia, uint8_t *ra, + const uint8_t *ia, const uint8_t *ra, uint8_t *out_enc_data); -int ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z, - uint8_t *out_enc_data); -int ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, - uint32_t *passkey); -int ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t, - uint8_t *a1, uint8_t a2t, uint8_t *a2, - uint8_t *mackey, uint8_t *ltk); +int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, + uint8_t z, uint8_t *out_enc_data); +int ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, + const uint8_t *y, uint32_t *passkey); +int ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + uint8_t a1t, const uint8_t *a1, uint8_t a2t, + const uint8_t *a2, uint8_t *mackey, uint8_t *ltk); int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r, const uint8_t *iocap, uint8_t a1t, const uint8_t *a1, uint8_t a2t, const uint8_t *a2, uint8_t *check); -int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, - uint8_t *our_priv_key, uint8_t *out_dhkey); +int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, + const uint8_t *peer_pub_key_y, + const uint8_t *our_priv_key, uint8_t *out_dhkey); int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); void ble_sm_alg_ecc_init(void); -void ble_sm_enc_change_rx(struct hci_encrypt_change *evt); -void ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt); -int ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt); +void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev); +void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev); +int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev); #if MYNEWT_VAL(BLE_SM_LEGACY) int ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action); @@ -364,6 +355,10 @@ void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg); void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **rxom, struct ble_sm_result *res); +bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, + bool oob_data_local_present, + bool oob_data_remote_present); +void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res); void ble_sm_sc_init(void); #else #define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP) @@ -399,12 +394,9 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); -int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); +int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, + uint8_t *enc_data); int ble_sm_init(void); - -#define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ - BLE_HS_LOG_CMD((is_tx), "sm", (cmd_name), (conn_handle), (log_cb), (cmd)) - #else #define ble_sm_enc_change_rx(evt) ((void)(evt)) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.c index f85cbc863..caf1b4f12 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.c @@ -6,6 +6,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_TRANS_LOG #include #include @@ -13,10 +15,6 @@ #include "mesh/mesh.h" #include "mesh_priv.h" -#include "syscfg/syscfg.h" -#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_TRANS)) -#include "host/ble_hs_log.h" - #include "crypto.h" #include "adv.h" #include "net.h" @@ -27,6 +25,7 @@ #include "settings.h" #include "transport.h" #include "testing.h" +#include "nodes.h" /* The transport layer needs at least three buffers for itself to avoid * deadlocks. Ensure that there are a sufficient number of advertising @@ -52,7 +51,7 @@ BUILD_ASSERT(CONFIG_BT_MESH_ADV_BUF_COUNT >= (CONFIG_BT_MESH_TX_SEG_MAX + 3)); #define SEQ_AUTH(iv_index, seq) (((u64_t)iv_index) << 24 | (u64_t)seq) /* Number of retransmit attempts (after the initial transmit) per segment */ -#define SEG_RETRANSMIT_ATTEMPTS 4 +#define SEG_RETRANSMIT_ATTEMPTS (MYNEWT_VAL(BLE_MESH_SEG_RETRANSMIT_ATTEMPTS)) /* "This timer shall be set to a minimum of 200 + 50 * TTL milliseconds.". * We use 400 since 300 is a common send duration for standard HCI, and we @@ -119,7 +118,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct os_mbuf *sdu, net_buf_reserve(buf, BT_MESH_NET_HDR_LEN); - if (tx->ctx->app_idx == BT_MESH_KEY_DEV) { + if (BT_MESH_IS_DEV_KEY(tx->ctx->app_idx)) { net_buf_add_u8(buf, UNSEG_HDR(0, 0)); } else { net_buf_add_u8(buf, UNSEG_HDR(1, tx->aid)); @@ -128,17 +127,32 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct os_mbuf *sdu, net_buf_add_mem(buf, sdu->om_data, sdu->om_len); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { + if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, + tx->src, tx->ctx->addr, + NULL, 1)) { + if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + BT_ERR("Not enough space in Friend Queue"); + net_buf_unref(buf); + return -ENOBUFS; + } else { + BT_WARN("No space in Friend Queue"); + goto send; + } + } + if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - NULL, buf) && + NULL, 1, buf) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. */ net_buf_unref(buf); + send_cb_finalize(cb, cb_data); return 0; } } +send: return bt_mesh_net_send(tx, buf, cb, cb_data); } @@ -318,7 +332,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu, return -EBUSY; } - if (net_tx->ctx->app_idx == BT_MESH_KEY_DEV) { + if (BT_MESH_IS_DEV_KEY(net_tx->ctx->app_idx)) { seg_hdr = SEG_HDR(0, 0); } else { seg_hdr = SEG_HDR(1, net_tx->aid); @@ -340,10 +354,21 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu, tx->ttl = net_tx->ctx->send_ttl; } - seq_zero = tx->seq_auth & 0x1fff; + seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK; BT_DBG("SeqZero 0x%04x", seq_zero); + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && + !bt_mesh_friend_queue_has_space(tx->sub->net_idx, net_tx->src, + tx->dst, &tx->seq_auth, + tx->seg_n + 1) && + BT_MESH_ADDR_IS_UNICAST(tx->dst)) { + BT_ERR("Not enough space in Friend Queue for %u segments", + tx->seg_n + 1); + seg_tx_reset(tx); + return -ENOBUFS; + } + for (seg_o = 0; sdu->om_len; seg_o++) { struct os_mbuf *seg; u16_t len; @@ -371,8 +396,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu, net_buf_add_mem(seg, sdu->om_data, len); net_buf_simple_pull(sdu, len); - tx->seg[seg_o] = net_buf_ref(seg); - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { enum bt_mesh_friend_pdu_type type; @@ -384,16 +407,19 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu, if (bt_mesh_friend_enqueue_tx(net_tx, type, &tx->seq_auth, + tx->seg_n + 1, seg) && BT_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. */ net_buf_unref(seg); - return 0; + continue; } } + tx->seg[seg_o] = net_buf_ref(seg); + BT_DBG("Sending %u/%u", seg_o, tx->seg_n); err = bt_mesh_net_send(net_tx, seg, @@ -406,6 +432,17 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu, } } + /* This can happen if segments only went into the Friend Queue */ + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !tx->seg[0]) { + seg_tx_reset(tx); + + /* If there was a callback notify sending immediately since + * there's no other way to track this (at least currently) + * with the Friend Queue. + */ + send_cb_finalize(cb, cb_data); + } + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && bt_mesh_lpn_established()) { bt_mesh_lpn_poll(); @@ -435,6 +472,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, { const u8_t *key; u8_t *ad; + u8_t aid; int err; if (net_buf_simple_tailroom(msg) < 4) { @@ -444,33 +482,21 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, if (msg->om_len > 11) { tx->ctx->send_rel = 1; + tx->ctx->send_rel = true; } BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx, tx->ctx->app_idx, tx->ctx->addr); BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); - if (tx->ctx->app_idx == BT_MESH_KEY_DEV) { - key = bt_mesh.dev_key; - tx->aid = 0; - } else { - struct bt_mesh_app_key *app_key; - - app_key = bt_mesh_app_key_find(tx->ctx->app_idx); - if (!app_key) { - return -EINVAL; - } - - if (tx->sub->kr_phase == BT_MESH_KR_PHASE_2 && - app_key->updated) { - key = app_key->keys[1].val; - tx->aid = app_key->keys[1].id; - } else { - key = app_key->keys[0].val; - tx->aid = app_key->keys[0].id; - } + err = bt_mesh_app_key_get(tx->sub, tx->ctx->app_idx, + tx->ctx->addr, &key, &aid); + if (err) { + return err; } + tx->aid = aid; + if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) { tx->aszmic = 0; } else { @@ -483,10 +509,9 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, ad = NULL; } - err = bt_mesh_app_encrypt(key, tx->ctx->app_idx == BT_MESH_KEY_DEV, - tx->aszmic, msg, ad, tx->src, - tx->ctx->addr, bt_mesh.seq, - BT_MESH_NET_IVI_TX); + err = bt_mesh_app_encrypt(key, BT_MESH_IS_DEV_KEY(tx->ctx->app_idx), + tx->aszmic, msg, ad, tx->src, tx->ctx->addr, + bt_mesh.seq, BT_MESH_NET_IVI_TX); if (err) { return err; } @@ -500,26 +525,23 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, return err; } -int bt_mesh_trans_resend(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, - const struct bt_mesh_send_cb *cb, void *cb_data) +static void update_rpl(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx) { - struct net_buf_simple_state state; - int err; + rpl->src = rx->ctx.addr; + rpl->seq = rx->seq; + rpl->old_iv = rx->old_iv; - net_buf_simple_save(msg, &state); - - if (tx->ctx->send_rel || msg->om_len > 15) { - err = send_seg(tx, msg, cb, cb_data); - } else { - err = send_unseg(tx, msg, cb, cb_data); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_rpl(rpl); } - - net_buf_simple_restore(msg, &state); - - return err; } -static bool is_replay(struct bt_mesh_net_rx *rx) +/* Check the Replay Protection List for a replay attempt. If non-NULL match + * parameter is given the RPL slot is returned but it is not immediately + * updated (needed for segmented messages), whereas if a NULL match is given + * the RPL is immediately updated (used for unsegmented messages). + */ +static bool is_replay(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) { int i; @@ -528,17 +550,20 @@ static bool is_replay(struct bt_mesh_net_rx *rx) return false; } + /* The RPL is used only for the local node */ + if (!rx->local_match) { + return false; + } + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; /* Empty slot */ if (!rpl->src) { - rpl->src = rx->ctx.addr; - rpl->seq = rx->seq; - rpl->old_iv = rx->old_iv; - - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_rpl(rpl); + if (match) { + *match = rpl; + } else { + update_rpl(rpl, rx); } return false; @@ -552,11 +577,10 @@ static bool is_replay(struct bt_mesh_net_rx *rx) if ((!rx->old_iv && rpl->old_iv) || rpl->seq < rx->seq) { - rpl->seq = rx->seq; - rpl->old_iv = rx->old_iv; - - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_rpl(rpl); + if (match) { + *match = rpl; + } else { + update_rpl(rpl, rx); } return false; @@ -591,7 +615,6 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u32_t seq, u8_t hdr, if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !rx->local_match) { BT_DBG("Ignoring PDU for LPN 0x%04x of this Friend", rx->ctx.recv_dst); - err = 0; goto done; } @@ -611,14 +634,45 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u32_t seq, u8_t hdr, rx->ctx.recv_dst, seq, BT_MESH_NET_IVI_RX(rx)); if (err) { - BT_ERR("Unable to decrypt with DevKey"); - err = -EINVAL; + BT_WARN("Unable to decrypt with local DevKey"); + } else { + rx->ctx.app_idx = BT_MESH_KEY_DEV_LOCAL; + bt_mesh_model_recv(rx, sdu); goto done; } - rx->ctx.app_idx = BT_MESH_KEY_DEV; - bt_mesh_model_recv(rx, sdu); - goto done; + if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER)) { + struct bt_mesh_node *node; + + /* + * There is no way of knowing if we should use our + * local DevKey or the remote DevKey to decrypt the + * message so we must try both. + */ + + node = bt_mesh_node_find(rx->ctx.addr); + if (node == NULL) { + BT_ERR("No node found for addr 0x%04x", + rx->ctx.addr); + return -EINVAL; + } + + net_buf_simple_init(sdu, 0); + err = bt_mesh_app_decrypt(node->dev_key, true, aszmic, + buf, sdu, ad, rx->ctx.addr, + rx->ctx.recv_dst, seq, + BT_MESH_NET_IVI_RX(rx)); + if (err) { + BT_ERR("Unable to decrypt with node DevKey"); + return -EINVAL; + } + + rx->ctx.app_idx = BT_MESH_KEY_DEV_REMOTE; + bt_mesh_model_recv(rx, sdu); + return 0; + } + + return -EINVAL; } for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { @@ -675,7 +729,7 @@ static struct seg_tx *seg_tx_lookup(u16_t seq_zero, u8_t obo, u16_t addr) for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { tx = &seg_tx[i]; - if ((tx->seq_auth & 0x1fff) != seq_zero) { + if ((tx->seq_auth & TRANS_SEQ_ZERO_MASK) != seq_zero) { continue; } @@ -713,7 +767,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, seq_zero = net_buf_simple_pull_be16(buf); obo = seq_zero >> 15; - seq_zero = (seq_zero >> 2) & 0x1fff; + seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match) { BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst); @@ -876,7 +930,7 @@ static int trans_unseg(struct os_mbuf *buf, struct bt_mesh_net_rx *rx, return -EINVAL; } - if (rx->local_match && is_replay(rx)) { + if (is_replay(rx, NULL)) { BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst, (unsigned) rx->seq); return -EINVAL; @@ -945,7 +999,7 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - seq_auth, buf) && + seq_auth, 1, buf) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. @@ -973,7 +1027,7 @@ static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, .src = obo ? bt_mesh_primary_addr() : src, .xmit = bt_mesh_net_transmit_get(), }; - u16_t seq_zero = *seq_auth & 0x1fff; + u16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK; u8_t buf[6]; BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, @@ -1156,10 +1210,12 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, } static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, - enum bt_mesh_friend_pdu_type *pdu_type, u64_t *seq_auth) + enum bt_mesh_friend_pdu_type *pdu_type, u64_t *seq_auth, + u8_t *seg_count) { + struct bt_mesh_rpl *rpl = NULL; struct seg_rx *rx; - u8_t *hdr = buf->om_data; + u8_t *hdr = buf->om_data; u16_t seq_zero; u8_t seg_n; u8_t seg_o; @@ -1170,13 +1226,19 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, return -EINVAL; } + if (is_replay(net_rx, &rpl)) { + BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq); + return -EINVAL; + } + BT_DBG("ASZMIC %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); net_buf_simple_pull(buf, 1); seq_zero = net_buf_simple_pull_be16(buf); seg_o = (seq_zero & 0x03) << 3; - seq_zero = (seq_zero >> 2) & 0x1fff; + seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; seg_n = net_buf_simple_pull_u8(buf); seg_o |= seg_n >> 5; seg_n &= 0x1f; @@ -1206,6 +1268,8 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, ((((net_rx->seq & BIT_MASK(14)) - seq_zero)) & BIT_MASK(13)))); + *seg_count = seg_n + 1; + /* Look for old RX sessions */ rx = seg_rx_find(net_rx, seq_auth); if (rx) { @@ -1227,9 +1291,15 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, if (rx->block == BLOCK_COMPLETE(rx->seg_n)) { BT_WARN("Got segment for already complete SDU"); + send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); + + if (rpl) { + update_rpl(rpl, net_rx); + } + return -EALREADY; } @@ -1250,6 +1320,22 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, return -EMSGSIZE; } + /* Verify early that there will be space in the Friend Queue(s) in + * case this message is destined to an LPN of ours. + */ + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && + net_rx->friend_match && !net_rx->local_match && + !bt_mesh_friend_queue_has_space(net_rx->sub->net_idx, + net_rx->ctx.addr, + net_rx->ctx.recv_dst, seq_auth, + *seg_count)) { + BT_ERR("No space in Friend Queue for %u segments", *seg_count); + send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, + net_rx->ctx.send_ttl, seq_auth, 0, + net_rx->friend_match); + return -ENOBUFS; + } + /* Look for free slot for a new RX session */ rx = seg_rx_alloc(net_rx, hdr, seq_auth, seg_n); if (!rx) { @@ -1317,13 +1403,8 @@ found_rx: BT_DBG("Complete SDU"); - if (net_rx->local_match && is_replay(net_rx)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", - net_rx->ctx.addr, net_rx->ctx.recv_dst, - (unsigned) net_rx->seq); - /* Clear the segment's bit */ - rx->block &= ~BIT(seg_o); - return -EINVAL; + if (rpl) { + update_rpl(rpl, net_rx); } *pdu_type = BT_MESH_FRIEND_PDU_COMPLETE; @@ -1349,6 +1430,7 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) u64_t seq_auth = TRANS_SEQ_AUTH_NVAL; enum bt_mesh_friend_pdu_type pdu_type = BT_MESH_FRIEND_PDU_SINGLE; struct net_buf_simple_state state; + u8_t seg_count = 0; int err; if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { @@ -1396,8 +1478,9 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) return 0; } - err = trans_seg(buf, rx, &pdu_type, &seq_auth); + err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); } else { + seg_count = 1; err = trans_unseg(buf, rx, &seq_auth); } @@ -1422,9 +1505,11 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match && !err) { if (seq_auth == TRANS_SEQ_AUTH_NVAL) { - bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, buf); + bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, + seg_count, buf); } else { - bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, buf); + bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, + seg_count, buf); } } @@ -1483,3 +1568,101 @@ void bt_mesh_rpl_clear(void) BT_DBG(""); memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); } + +void bt_mesh_heartbeat_send(void) +{ + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + u16_t feat = 0U; + struct __packed { + u8_t init_ttl; + u16_t feat; + } hb; + struct bt_mesh_msg_ctx ctx = { + .net_idx = cfg->hb_pub.net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = cfg->hb_pub.dst, + .send_ttl = cfg->hb_pub.ttl, + }; + struct bt_mesh_net_tx tx = { + .sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx), + .ctx = &ctx, + .src = bt_mesh_model_elem(cfg->model)->addr, + .xmit = bt_mesh_net_transmit_get(), + }; + + /* Do nothing if heartbeat publication is not enabled */ + if (cfg->hb_pub.dst == BT_MESH_ADDR_UNASSIGNED) { + return; + } + + hb.init_ttl = cfg->hb_pub.ttl; + + if (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED) { + feat |= BT_MESH_FEAT_RELAY; + } + + if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + feat |= BT_MESH_FEAT_PROXY; + } + + if (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED) { + feat |= BT_MESH_FEAT_FRIEND; + } + + if (bt_mesh_lpn_established()) { + feat |= BT_MESH_FEAT_LOW_POWER; + } + + hb.feat = sys_cpu_to_be16(feat); + + BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); + + bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), + NULL, NULL, NULL); +} + +int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, + u16_t addr, const u8_t **key, u8_t *aid) +{ + struct bt_mesh_app_key *app_key; + + if (app_idx == BT_MESH_KEY_DEV_LOCAL || + (app_idx == BT_MESH_KEY_DEV_REMOTE && + bt_mesh_elem_find(addr) != NULL)) { + *aid = 0; + *key = bt_mesh.dev_key; + return 0; + } else if (app_idx == BT_MESH_KEY_DEV_REMOTE) { + if (!IS_ENABLED(CONFIG_BT_MESH_PROVISIONER)) { + return -EINVAL; + } + + struct bt_mesh_node *node = bt_mesh_node_find(addr); + if (!node) { + return -EINVAL; + } + + *key = node->dev_key; + *aid = 0; + return 0; + } + + if (!subnet) { + return -EINVAL; + } + + app_key = bt_mesh_app_key_find(app_idx); + if (!app_key) { + return -ENOENT; + } + + if (subnet->kr_phase == BT_MESH_KR_PHASE_2 && app_key->updated) { + *key = app_key->keys[1].val; + *aid = app_key->keys[1].id; + } else { + *key = app_key->keys[0].val; + *aid = app_key->keys[0].id; + } + + return 0; +} diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.h index ac6b3f8ee..eff768e9f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/transport.h @@ -13,6 +13,7 @@ #define BT_MESH_TX_SDU_MAX (CONFIG_BT_MESH_TX_SEG_MAX * 12) +#define TRANS_SEQ_ZERO_MASK ((u16_t)BIT_MASK(13)) #define TRANS_CTL_OP_MASK ((u8_t)BIT_MASK(7)) #define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK) #define TRANS_CTL_HDR(op, seg) ((op & TRANS_CTL_OP_MASK) | (seg << 7)) @@ -97,3 +98,8 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx); void bt_mesh_trans_init(void); void bt_mesh_rpl_clear(void); + +void bt_mesh_heartbeat_send(void); + +int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, + u16_t addr, const u8_t **key, u8_t *aid); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/gap/src/ble_svc_gap.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/gap/src/ble_svc_gap.c index 7a1e76f98..e79b2b872 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/gap/src/ble_svc_gap.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/gap/src/ble_svc_gap.c @@ -161,7 +161,7 @@ ble_svc_gap_appearance_write_access(struct ble_gatt_access_ctxt *ctxt) return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - rc = ble_hs_mbuf_to_flat(ctxt->om, ble_svc_gap_appearance, om_len, NULL); + rc = ble_hs_mbuf_to_flat(ctxt->om, &ble_svc_gap_appearance, om_len, NULL); if (rc != 0) { return BLE_ATT_ERR_UNLIKELY; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/tps/src/ble_hs_hci_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/tps/src/ble_hs_hci_priv.h index ff3604727..362f12cbd 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/tps/src/ble_hs_hci_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/services/tps/src/ble_hs_hci_priv.h @@ -48,7 +48,7 @@ struct os_mbuf; struct ble_hs_hci_ack { int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */ - uint8_t *bha_params; + const uint8_t *bha_params; int bha_params_len; uint16_t bha_opcode; uint8_t bha_hci_handle; @@ -81,11 +81,8 @@ struct hci_periodic_adv_params extern uint16_t ble_hs_hci_avail_pkts; -int ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, - void *evt_buf, uint8_t evt_buf_len, - uint8_t *out_evt_buf_len); -int ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len); -void ble_hs_hci_rx_ack(uint8_t *ack_ev); +int ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, + void *rsp, uint8_t rsp_len); void ble_hs_hci_init(void); void ble_hs_hci_deinit(void); @@ -103,78 +100,11 @@ int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_pwr); int ble_hs_hci_util_rand(void *dst, int len); int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); -int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, - uint16_t tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); -int ble_hs_hci_evt_process(uint8_t *data); +int ble_hs_hci_evt_process(const struct ble_hci_ev *ev); -void ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, - void *buf); -int ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len); -void ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_read_buffer_size(void); -void ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst, - int dst_len); -int ble_hs_hci_cmd_le_set_adv_enable(uint8_t enable); -int ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type, - uint16_t scan_itvl, - uint16_t scan_window, - uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint8_t *dst, uint8_t dst_len); -int ble_hs_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups); -int ble_hs_hci_cmd_build_le_create_connection( - const struct hci_create_conn *hcc, uint8_t *cmd, int cmd_len); -int ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr, - uint8_t addr_type, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_reset(void); -int ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable); -int ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd); -int ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - const struct hci_host_num_comp_pkts_entry *entry, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_read_adv_pwr(void); -int ble_hs_hci_cmd_le_create_conn_cancel(void); -int ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu); -void ble_hs_hci_cmd_build_le_lt_key_req_reply( - const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_conn_param_reply( - const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr); -void ble_hs_hci_cmd_build_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn); -void ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst, int dst_len); +int ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len); int ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts); void ble_hs_hci_add_avail_pkts(uint16_t delta); @@ -184,145 +114,9 @@ uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, int ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om); int ble_hs_hci_acl_tx(struct ble_hs_conn *conn, struct os_mbuf **om); -int ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, uint16_t tx_time, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_add_to_resolv_list( - const struct hci_add_dev_to_resolving_list *padd, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_remove_from_resolv_list( - uint8_t addr_type, const uint8_t *addr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_peer_resolv_addr( - uint8_t peer_identity_addr_type, const uint8_t *peer_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_lcl_resolv_addr( - uint8_t local_identity_addr_type, const uint8_t *local_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_addr_res_en( - uint8_t enable, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout( - uint16_t timeout, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr, - uint8_t *dst, int dst_len); - -#if MYNEWT_VAL(BLE_EXT_ADV) -int ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint16_t duration, - uint16_t period, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle, - const uint8_t *addr, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation, - uint8_t frag_pref, struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num, - const struct hci_ext_adv_set *sets, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle, - const struct hci_ext_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle, - uint8_t *cmd, int cmd_len); - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -int -ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle, - const struct hci_periodic_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable, - uint8_t handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, uint8_t operation, - struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy, - uint8_t adv_sid, - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint16_t skip, - uint16_t sync_timeout, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -#endif - -#endif - -int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy, - uint8_t mod_idx, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, - uint8_t test_data_len, - uint8_t packet_payload_idx, - uint8_t phy, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst, - uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, - int dst_len); - -int ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, - uint8_t rx_phys_mask, - uint8_t *dst, int dst_len); - -int ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst, int dst_len); - int ble_hs_hci_frag_num_mbufs(void); int ble_hs_hci_frag_num_mbufs_free(void); -#if MYNEWT_VAL(BLE_EXT_ADV) -#endif - -int ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst, - int dst_len); #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_clt.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_clt.c index b33f8375e..09fc9ea23 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_clt.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_clt.c @@ -43,8 +43,6 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom) rsp = (struct ble_att_error_rsp *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "error rsp", conn_handle, ble_att_error_rsp_log, rsp); - ble_gattc_rx_err(conn_handle, le16toh(rsp->baep_handle), le16toh(rsp->baep_error_code)); @@ -96,8 +94,6 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) return rc; } - BLE_ATT_LOG_CMD(1, "mtu req", conn_handle, ble_att_mtu_cmd_log, req); - ble_hs_lock(); rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); @@ -124,8 +120,6 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) if (rc == 0) { cmd = (struct ble_att_mtu_cmd *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "mtu rsp", conn_handle, ble_att_mtu_cmd_log, cmd); - ble_hs_lock(); rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); @@ -172,9 +166,6 @@ ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, req->bafq_start_handle = htole16(start_handle); req->bafq_end_handle = htole16(end_handle); - BLE_ATT_LOG_CMD(1, "find info req", conn_handle, - ble_att_find_info_req_log, req); - return ble_att_tx(conn_handle, txom); } @@ -247,9 +238,6 @@ ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) rsp = (struct ble_att_find_info_rsp *)(*om)->om_data; - BLE_ATT_LOG_CMD(0, "find info rsp", conn_handle, ble_att_find_info_rsp_log, - rsp); - /* Strip the response base from the front of the mbuf. */ os_mbuf_adj((*om), sizeof(*rsp)); @@ -306,9 +294,6 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, req->bavq_attr_type = htole16(attribute_type); memcpy(req->bavq_value, attribute_value, value_len); - BLE_ATT_LOG_CMD(1, "find type value req", conn_handle, - ble_att_find_type_value_req_log, req); - return ble_att_tx(conn_handle, txom); } @@ -344,8 +329,6 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) struct ble_att_find_type_value_hinfo hinfo; int rc; - BLE_ATT_LOG_EMPTY_CMD(0, "find type value rsp", conn_handle); - /* Parse the Handles-Information-List field, passing each entry to GATT. */ rc = 0; while (OS_MBUF_PKTLEN(*rxom) > 0) { @@ -393,9 +376,6 @@ ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, ble_uuid_flat(uuid, req->uuid); - BLE_ATT_LOG_CMD(1, "read type req", conn_handle, - ble_att_read_type_req_log, req); - return ble_att_tx(conn_handle, txom); } @@ -419,9 +399,6 @@ ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) rsp = (struct ble_att_read_type_rsp *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read type rsp", conn_handle, ble_att_read_type_rsp_log, - rsp); - data_len = rsp->batp_length; /* Strip the response base from the front of the mbuf. */ @@ -487,8 +464,6 @@ ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) return rc; } - BLE_ATT_LOG_CMD(1, "read req", conn_handle, ble_att_read_req_log, req); - return 0; } @@ -499,8 +474,6 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "read rsp", conn_handle); - /* Pass the Attribute Value field to GATT. */ ble_gattc_rx_read_rsp(conn_handle, 0, rxom); return 0; @@ -538,9 +511,6 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) return rc; } - BLE_ATT_LOG_CMD(1, "read blob req", conn_handle, - ble_att_read_blob_req_log, req); - return 0; } @@ -551,8 +521,6 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "read blob rsp", conn_handle); - /* Pass the Attribute Value field to GATT. */ ble_gattc_rx_read_blob_rsp(conn_handle, 0, rxom); return 0; @@ -573,8 +541,6 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles, struct os_mbuf *txom; int i; - BLE_ATT_LOG_EMPTY_CMD(1, "reqd mult req", conn_handle); - if (num_handles < 1) { return BLE_HS_EINVAL; } @@ -600,8 +566,6 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "read mult rsp", conn_handle); - /* Pass the Attribute Value field to GATT. */ ble_gattc_rx_read_mult_rsp(conn_handle, 0, rxom); return 0; @@ -637,9 +601,6 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle, req->bagq_end_handle = htole16(end_handle); ble_uuid_flat(uuid, req->uuid); - BLE_ATT_LOG_CMD(1, "read group type req", conn_handle, - ble_att_read_group_type_req_log, req); - return ble_att_tx(conn_handle, txom); } @@ -686,9 +647,6 @@ ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) rsp = (struct ble_att_read_group_type_rsp *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read group type rsp", conn_handle, - ble_att_read_group_type_rsp_log, rsp); - len = rsp->bagp_length; /* Strip the base from the front of the response. */ @@ -735,8 +693,6 @@ ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, req->bawq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - BLE_ATT_LOG_CMD(1, "write req", conn_handle, ble_att_write_req_log, req); - return ble_att_tx(conn_handle, txom2); } @@ -774,8 +730,6 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, cmd->handle = htole16(handle); os_mbuf_concat(txom2, txom); - BLE_ATT_LOG_CMD(1, "write cmd", conn_handle, ble_att_write_cmd_log, cmd); - return ble_att_tx(conn_handle, txom2); } @@ -786,8 +740,6 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "write rsp", conn_handle); - /* No payload. */ ble_gattc_rx_write_rsp(conn_handle); return 0; @@ -835,9 +787,6 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, req->bapc_offset = htole16(offset); os_mbuf_concat(txom2, txom); - BLE_ATT_LOG_CMD(1, "prep write req", conn_handle, - ble_att_prep_write_cmd_log, req); - return ble_att_tx(conn_handle, txom2); err: @@ -866,8 +815,6 @@ ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) } rsp = (struct ble_att_prep_write_cmd *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "prep write rsp", conn_handle, - ble_att_prep_write_cmd_log, rsp); handle = le16toh(rsp->bapc_handle); offset = le16toh(rsp->bapc_offset); @@ -908,9 +855,6 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) return rc; } - BLE_ATT_LOG_CMD(1, "exec write req", conn_handle, - ble_att_exec_write_req_log, req); - return 0; } @@ -921,8 +865,6 @@ ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "exec write rsp", conn_handle); - ble_gattc_rx_exec_write_rsp(conn_handle, 0); return 0; } @@ -957,8 +899,6 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, req->banq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - BLE_ATT_LOG_CMD(1, "notify req", conn_handle, ble_att_notify_req_log, req); - return ble_att_tx(conn_handle, txom2); err: @@ -996,9 +936,6 @@ ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, req->baiq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - BLE_ATT_LOG_CMD(1, "indicate req", conn_handle, ble_att_indicate_req_log, - req); - return ble_att_tx(conn_handle, txom2); err: @@ -1013,8 +950,6 @@ ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_ENOTSUP; #endif - BLE_ATT_LOG_EMPTY_CMD(0, "indicate rsp", conn_handle); - /* No payload. */ ble_gattc_rx_indicate_rsp(conn_handle); return 0; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c index bad192df5..81b070f9c 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c @@ -135,13 +135,6 @@ ble_att_error_rsp_write(void *payload, int len, dst->baep_error_code = src->baep_error_code; } -void -ble_att_error_rsp_log(const struct ble_att_error_rsp *cmd) -{ - BLE_HS_LOG(DEBUG, "req_op=%d handle=0x%04x error_code=%d", - cmd->baep_req_op, cmd->baep_handle, cmd->baep_error_code); -} - void ble_att_mtu_req_parse(const void *payload, int len, struct ble_att_mtu_cmd *dst) @@ -189,12 +182,6 @@ ble_att_mtu_rsp_write(void *payload, int len, dst->bamc_mtu = htole16(src->bamc_mtu); } -void -ble_att_mtu_cmd_log(const struct ble_att_mtu_cmd *cmd) -{ - BLE_HS_LOG(DEBUG, "mtu=%d", cmd->bamc_mtu); -} - void ble_att_find_info_req_parse(const void *payload, int len, struct ble_att_find_info_req *dst) @@ -221,13 +208,6 @@ ble_att_find_info_req_write(void *payload, int len, dst->bafq_end_handle = htole16(src->bafq_end_handle); } -void -ble_att_find_info_req_log(const struct ble_att_find_info_req *cmd) -{ - BLE_HS_LOG(DEBUG, "start_handle=0x%04x end_handle=0x%04x", - cmd->bafq_start_handle, cmd->bafq_end_handle); -} - void ble_att_find_info_rsp_parse(const void *payload, int len, struct ble_att_find_info_rsp *dst) @@ -252,12 +232,6 @@ ble_att_find_info_rsp_write(void *payload, int len, dst->bafp_format = src->bafp_format; } -void -ble_att_find_info_rsp_log(const struct ble_att_find_info_rsp *cmd) -{ - BLE_HS_LOG(DEBUG, "format=%d", cmd->bafp_format); -} - void ble_att_find_type_value_req_parse(const void *payload, int len, struct ble_att_find_type_value_req *dst) @@ -286,14 +260,6 @@ ble_att_find_type_value_req_write( dst->bavq_attr_type = htole16(src->bavq_attr_type); } -void -ble_att_find_type_value_req_log(const struct ble_att_find_type_value_req *cmd) -{ - BLE_HS_LOG(DEBUG, "start_handle=0x%04x end_handle=0x%04x attr_type=%d", - cmd->bavq_start_handle, cmd->bavq_end_handle, - cmd->bavq_attr_type); -} - void ble_att_read_type_req_parse(const void *payload, int len, struct ble_att_read_type_req *dst) @@ -320,13 +286,6 @@ ble_att_read_type_req_write(void *payload, int len, dst->batq_end_handle = htole16(src->batq_end_handle); } -void -ble_att_read_type_req_log(const struct ble_att_read_type_req *cmd) -{ - BLE_HS_LOG(DEBUG, "start_handle=0x%04x end_handle=0x%04x", - cmd->batq_start_handle, cmd->batq_end_handle); -} - void ble_att_read_type_rsp_parse(const void *payload, int len, struct ble_att_read_type_rsp *dst) @@ -351,12 +310,6 @@ ble_att_read_type_rsp_write(void *payload, int len, dst->batp_length = src->batp_length; } -void -ble_att_read_type_rsp_log(const struct ble_att_read_type_rsp *cmd) -{ - BLE_HS_LOG(DEBUG, "length=%d", cmd->batp_length); -} - void ble_att_read_req_parse(const void *payload, int len, struct ble_att_read_req *dst) @@ -381,12 +334,6 @@ ble_att_read_req_write(void *payload, int len, dst->barq_handle = htole16(src->barq_handle); } -void -ble_att_read_req_log(const struct ble_att_read_req *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x", cmd->barq_handle); -} - void ble_att_read_blob_req_parse(const void *payload, int len, struct ble_att_read_blob_req *dst) @@ -413,13 +360,6 @@ ble_att_read_blob_req_write(void *payload, int len, dst->babq_offset = htole16(src->babq_offset); } -void -ble_att_read_blob_req_log(const struct ble_att_read_blob_req *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x offset=%d", cmd->babq_handle, - cmd->babq_offset); -} - void ble_att_read_mult_req_parse(const void *payload, int len) { @@ -474,13 +414,6 @@ ble_att_read_group_type_req_write( dst->bagq_end_handle = htole16(src->bagq_end_handle); } -void -ble_att_read_group_type_req_log(const struct ble_att_read_group_type_req *cmd) -{ - BLE_HS_LOG(DEBUG, "start_handle=0x%04x end_handle=0x%04x", - cmd->bagq_start_handle, cmd->bagq_end_handle); -} - void ble_att_read_group_type_rsp_parse(const void *payload, int len, struct ble_att_read_group_type_rsp *dst) @@ -505,12 +438,6 @@ ble_att_read_group_type_rsp_write( dst->bagp_length = src->bagp_length; } -void -ble_att_read_group_type_rsp_log(const struct ble_att_read_group_type_rsp *cmd) -{ - BLE_HS_LOG(DEBUG, "length=%d", cmd->bagp_length); -} - void ble_att_write_req_parse(const void *payload, int len, struct ble_att_write_req *dst) @@ -556,18 +483,6 @@ ble_att_write_cmd_write(void *payload, int len, dst->bawq_handle = htole16(src->bawq_handle); } -void -ble_att_write_cmd_log(const struct ble_att_write_cmd *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x", cmd->handle); -} - -void -ble_att_write_req_log(const struct ble_att_write_req *req) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x", req->bawq_handle); -} - void ble_att_prep_write_req_parse(const void *payload, int len, struct ble_att_prep_write_cmd *dst) @@ -620,13 +535,6 @@ ble_att_prep_write_rsp_write(void *payload, int len, dst->bapc_offset = htole16(src->bapc_offset); } -void -ble_att_prep_write_cmd_log(const struct ble_att_prep_write_cmd *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x offset=%d", cmd->bapc_handle, - cmd->bapc_offset); -} - void ble_att_exec_write_req_parse(const void *payload, int len, struct ble_att_exec_write_req *dst) @@ -651,12 +559,6 @@ ble_att_exec_write_req_write(void *payload, int len, dst->baeq_flags = src->baeq_flags; } -void -ble_att_exec_write_req_log(const struct ble_att_exec_write_req *cmd) -{ - BLE_HS_LOG(DEBUG, "flags=0x%02x", cmd->baeq_flags); -} - void ble_att_exec_write_rsp_parse(const void *payload, int len) { @@ -695,12 +597,6 @@ ble_att_notify_req_write(void *payload, int len, dst->banq_handle = htole16(src->banq_handle); } -void -ble_att_notify_req_log(const struct ble_att_notify_req *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x", cmd->banq_handle); -} - void ble_att_indicate_req_parse(const void *payload, int len, struct ble_att_indicate_req *dst) @@ -725,12 +621,6 @@ ble_att_indicate_req_write(void *payload, int len, dst->baiq_handle = htole16(src->baiq_handle); } -void -ble_att_indicate_req_log(const struct ble_att_indicate_req *cmd) -{ - BLE_HS_LOG(DEBUG, "handle=0x%04x", cmd->baiq_handle); -} - void ble_att_indicate_rsp_parse(const void *payload, int len) { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd_priv.h index ddc952bff..70f33260a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd_priv.h @@ -357,7 +357,6 @@ void ble_att_error_rsp_parse(const void *payload, int len, struct ble_att_error_rsp *rsp); void ble_att_error_rsp_write(void *payload, int len, const struct ble_att_error_rsp *rsp); -void ble_att_error_rsp_log(const struct ble_att_error_rsp *cmd); void ble_att_mtu_req_parse(const void *payload, int len, struct ble_att_mtu_cmd *cmd); void ble_att_mtu_req_write(void *payload, int len, @@ -366,43 +365,34 @@ void ble_att_mtu_rsp_parse(const void *payload, int len, struct ble_att_mtu_cmd *cmd); void ble_att_mtu_rsp_write(void *payload, int len, const struct ble_att_mtu_cmd *cmd); -void ble_att_mtu_cmd_log(const struct ble_att_mtu_cmd *cmd); void ble_att_find_info_req_parse(const void *payload, int len, struct ble_att_find_info_req *req); void ble_att_find_info_req_write(void *payload, int len, const struct ble_att_find_info_req *req); -void ble_att_find_info_req_log(const struct ble_att_find_info_req *cmd); void ble_att_find_info_rsp_parse(const void *payload, int len, struct ble_att_find_info_rsp *rsp); void ble_att_find_info_rsp_write(void *payload, int len, const struct ble_att_find_info_rsp *rsp); -void ble_att_find_info_rsp_log(const struct ble_att_find_info_rsp *cmd); void ble_att_find_type_value_req_parse( const void *payload, int len, struct ble_att_find_type_value_req *req); void ble_att_find_type_value_req_write( void *payload, int len, const struct ble_att_find_type_value_req *req); -void ble_att_find_type_value_req_log( - const struct ble_att_find_type_value_req *cmd); void ble_att_read_type_req_parse(const void *payload, int len, struct ble_att_read_type_req *req); void ble_att_read_type_req_write(void *payload, int len, const struct ble_att_read_type_req *req); -void ble_att_read_type_req_log(const struct ble_att_read_type_req *cmd); void ble_att_read_type_rsp_parse(const void *payload, int len, struct ble_att_read_type_rsp *rsp); void ble_att_read_type_rsp_write(void *payload, int len, const struct ble_att_read_type_rsp *rsp); -void ble_att_read_type_rsp_log(const struct ble_att_read_type_rsp *cmd); void ble_att_read_req_parse(const void *payload, int len, struct ble_att_read_req *req); void ble_att_read_req_write(void *payload, int len, const struct ble_att_read_req *req); -void ble_att_read_req_log(const struct ble_att_read_req *cmd); void ble_att_read_blob_req_parse(const void *payload, int len, struct ble_att_read_blob_req *req); void ble_att_read_blob_req_write(void *payload, int len, const struct ble_att_read_blob_req *req); -void ble_att_read_blob_req_log(const struct ble_att_read_blob_req *cmd); void ble_att_read_mult_req_parse(const void *payload, int len); void ble_att_read_mult_req_write(void *payload, int len); void ble_att_read_mult_rsp_parse(const void *payload, int len); @@ -411,14 +401,10 @@ void ble_att_read_group_type_req_parse( const void *payload, int len, struct ble_att_read_group_type_req *req); void ble_att_read_group_type_req_write( void *payload, int len, const struct ble_att_read_group_type_req *req); -void ble_att_read_group_type_req_log( - const struct ble_att_read_group_type_req *cmd); void ble_att_read_group_type_rsp_parse( const void *payload, int len, struct ble_att_read_group_type_rsp *rsp); void ble_att_read_group_type_rsp_write( void *payload, int len, const struct ble_att_read_group_type_rsp *rsp); -void ble_att_read_group_type_rsp_log( - const struct ble_att_read_group_type_rsp *cmd); void ble_att_write_req_parse(const void *payload, int len, struct ble_att_write_req *req); void ble_att_write_req_write(void *payload, int len, @@ -427,20 +413,16 @@ void ble_att_write_cmd_parse(const void *payload, int len, struct ble_att_write_req *req); void ble_att_write_cmd_write(void *payload, int len, const struct ble_att_write_req *req); -void ble_att_write_cmd_log(const struct ble_att_write_cmd *cmd); -void ble_att_write_req_log(const struct ble_att_write_req *req); void ble_att_prep_write_req_parse(const void *payload, int len, struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_req_write(void *payload, int len, const struct ble_att_prep_write_cmd *cmd); -void ble_att_prep_write_cmd_log(const struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_rsp_parse(const void *payload, int len, struct ble_att_prep_write_cmd *cmd); void ble_att_prep_write_rsp_write(void *payload, int len, const struct ble_att_prep_write_cmd *cmd); void ble_att_exec_write_req_parse(const void *payload, int len, struct ble_att_exec_write_req *req); -void ble_att_exec_write_req_log(const struct ble_att_exec_write_req *cmd); void ble_att_exec_write_req_write(void *payload, int len, const struct ble_att_exec_write_req *req); void ble_att_exec_write_rsp_parse(const void *payload, int len); @@ -449,14 +431,12 @@ void ble_att_notify_req_parse(const void *payload, int len, struct ble_att_notify_req *req); void ble_att_notify_req_write(void *payload, int len, const struct ble_att_notify_req *req); -void ble_att_notify_req_log(const struct ble_att_notify_req *cmd); void ble_att_indicate_req_parse(const void *payload, int len, struct ble_att_indicate_req *req); void ble_att_indicate_req_write(void *payload, int len, const struct ble_att_indicate_req *req); void ble_att_indicate_rsp_parse(const void *payload, int len); void ble_att_indicate_rsp_write(void *payload, int len); -void ble_att_indicate_req_log(const struct ble_att_indicate_req *cmd); void *ble_att_cmd_prepare(uint8_t opcode, size_t len, struct os_mbuf *txom); void *ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_priv.h index 2201d4ddb..73b6aeab0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_priv.h @@ -170,12 +170,6 @@ void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); int ble_att_init(void); -#define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ - BLE_HS_LOG_CMD((is_tx), "att", (cmd_name), (conn_handle), (log_cb), (cmd)) - -#define BLE_ATT_LOG_EMPTY_CMD(is_tx, cmd_name, conn_handle) \ - BLE_HS_LOG_EMPTY_CMD((is_tx), "att", (cmd_name), (conn_handle)) - /*** @svr */ int ble_att_svr_start(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_svr.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_svr.c index 045c1ca06..afcf90372 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_svr.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_att_svr.c @@ -578,8 +578,6 @@ ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, rsp->baep_handle = htole16(handle); rsp->baep_error_code = error_code; - BLE_ATT_LOG_CMD(1, "error rsp", conn_handle, ble_att_error_rsp_log, rsp); - return ble_att_tx(conn_handle, txom); } @@ -706,8 +704,6 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **rxom, cmd->bamc_mtu = htole16(mtu); - BLE_ATT_LOG_CMD(1, "mtu rsp", conn_handle, ble_att_mtu_cmd_log, cmd); - rc = 0; done: @@ -735,7 +731,6 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) } cmd = (struct ble_att_mtu_cmd *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "mtu req", conn_handle, ble_att_mtu_cmd_log, cmd); mtu = le16toh(cmd->bamc_mtu); @@ -889,9 +884,6 @@ ble_att_svr_build_find_info_rsp(uint16_t conn_handle, goto done; } - BLE_ATT_LOG_CMD(1, "find info rsp", conn_handle, ble_att_find_info_rsp_log, - rsp); - rc = 0; done: @@ -927,9 +919,6 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) start_handle = le16toh(req->bafq_start_handle); end_handle = le16toh(req->bafq_end_handle); - BLE_ATT_LOG_CMD(0, "find info req", conn_handle, ble_att_find_info_req_log, - req); - /* Tx error response if start handle is greater than end handle or is equal * to 0 (Vol. 3, Part F, 3.4.3.1). */ @@ -1202,8 +1191,6 @@ ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, goto done; } - BLE_ATT_LOG_EMPTY_CMD(1, "find type value rsp", conn_handle); - rc = 0; done: @@ -1240,8 +1227,6 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) start_handle = le16toh(req->bavq_start_handle); end_handle = le16toh(req->bavq_end_handle); attr_type = (ble_uuid16_t) BLE_UUID16_INIT(le16toh(req->bavq_attr_type)); - BLE_ATT_LOG_CMD(0, "find type value req", conn_handle, - ble_att_find_type_value_req_log, req); /* Tx error response if start handle is greater than end handle or is equal * to 0 (Vol. 3, Part F, 3.4.3.3). @@ -1377,8 +1362,6 @@ done: /* Fill the response base. */ rsp->batp_length = htole16(sizeof(*data) + prev_attr_len); - BLE_ATT_LOG_CMD(1, "read type rsp", conn_handle, - ble_att_read_type_rsp_log, rsp); } *out_txom = txom; @@ -1421,9 +1404,6 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) req = (struct ble_att_read_type_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read type req", conn_handle, ble_att_read_type_req_log, - req); - start_handle = le16toh(req->batq_start_handle); end_handle = le16toh(req->batq_end_handle); @@ -1481,7 +1461,6 @@ ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_read_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read req", conn_handle, ble_att_read_req_log, req); err_handle = le16toh(req->barq_handle); @@ -1531,8 +1510,6 @@ ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_read_blob_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read blob req", conn_handle, ble_att_read_blob_req_log, - req); err_handle = le16toh(req->babq_handle); offset = le16toh(req->babq_offset); @@ -1554,8 +1531,6 @@ ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - BLE_ATT_LOG_EMPTY_CMD(1, "read blob rsp", conn_handle); - rc = 0; done: @@ -1618,7 +1593,6 @@ ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, } } - BLE_ATT_LOG_EMPTY_CMD(1, "read mult rsp", conn_handle); rc = 0; done: @@ -1638,8 +1612,6 @@ ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) uint8_t att_err; int rc; - BLE_ATT_LOG_EMPTY_CMD(0, "read mult req", conn_handle); - /* Initialize some values in case of early error. */ txom = NULL; err_handle = 0; @@ -1875,8 +1847,6 @@ done: } if (rc == 0 || rc == BLE_HS_EMSGSIZE) { - BLE_ATT_LOG_CMD(1, "read group type rsp", conn_handle, - ble_att_read_group_type_rsp_log, rsp); rc = 0; } @@ -1918,8 +1888,6 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_read_group_type_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "read group type req", conn_handle, - ble_att_read_group_type_req_log, req); start_handle = le16toh(req->bagq_start_handle); end_handle = le16toh(req->bagq_end_handle); @@ -2017,9 +1985,6 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) req = (struct ble_att_write_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "write req", conn_handle, - ble_att_write_req_log, req); - handle = le16toh(req->bawq_handle); /* Allocate the write response. This must be done prior to processing the @@ -2038,8 +2003,6 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - BLE_ATT_LOG_EMPTY_CMD(1, "write rsp", conn_handle); - rc = 0; done: @@ -2066,8 +2029,6 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_write_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "write cmd", conn_handle, - ble_att_write_req_log, req); handle = le16toh(req->bawq_handle); @@ -2362,9 +2323,6 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) req = (struct ble_att_prep_write_cmd *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "prep write req", conn_handle, - ble_att_prep_write_cmd_log, req); - err_handle = le16toh(req->bapc_handle); attr_entry = ble_att_svr_find_by_handle(le16toh(req->bapc_handle)); @@ -2412,9 +2370,6 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) os_mbuf_prepend(txom, 1); txom->om_data[0] = BLE_ATT_OP_PREP_WRITE_RSP; - BLE_ATT_LOG_CMD(1, "prep write rsp", conn_handle, - ble_att_prep_write_cmd_log, req); - rc = 0; done: @@ -2450,8 +2405,6 @@ ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_exec_write_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "exec write req", conn_handle, - ble_att_exec_write_req_log, req); flags = req->baeq_flags; @@ -2518,9 +2471,6 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) req = (struct ble_att_notify_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "notify req", conn_handle, - ble_att_notify_req_log, req); - handle = le16toh(req->banq_handle); if (handle == 0) { @@ -2592,8 +2542,6 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) } req = (struct ble_att_indicate_req *)(*rxom)->om_data; - BLE_ATT_LOG_CMD(0, "indicate req", conn_handle, - ble_att_indicate_req_log, req); handle = le16toh(req->baiq_handle); @@ -2616,8 +2564,6 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) ble_gap_notify_rx_event(conn_handle, handle, *rxom, 1); *rxom = NULL; - BLE_ATT_LOG_EMPTY_CMD(1, "indicate rsp", conn_handle); - rc = 0; done: diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap.c index d77ff6a87..17ff4eae0 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap.c @@ -90,6 +90,7 @@ #define BLE_GAP_UPDATE_TIMEOUT_MS 40000 /* ms */ +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) static const struct ble_gap_conn_params ble_gap_conn_params_dflt = { .scan_itvl = 0x0010, .scan_window = 0x0010, @@ -100,6 +101,22 @@ static const struct ble_gap_conn_params ble_gap_conn_params_dflt = { .min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN, .max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN, }; +#endif + +#if NIMBLE_BLE_CONNECT && CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT +struct ble_gap_connect_reattempt_ctxt { + uint8_t own_addr_type; + ble_addr_t peer_addr; + int32_t duration_ms; + struct ble_gap_conn_params conn_params; + ble_gap_event_fn *cb; + void *cb_arg; +}; + +static struct ble_gap_connect_reattempt_ctxt ble_conn_reattempt[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; +static uint16_t reattempt_idx; +static bool conn_cookie_enabled; +#endif /** * The state of the in-progress master connection. If no master connection is @@ -165,6 +182,7 @@ struct ble_gap_slave_state { unsigned int configured:1; /** If instance is configured */ unsigned int scannable:1; unsigned int directed:1; + unsigned int high_duty_directed:1; unsigned int legacy_pdu:1; unsigned int rnd_addr_set:1; #if MYNEWT_VAL(BLE_PERIODIC_ADV) @@ -206,15 +224,23 @@ static struct os_mempool ble_gap_update_entry_pool; static struct ble_gap_update_entry_list ble_gap_update_entries; static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry); + +#if NIMBLE_BLE_CONNECT static struct ble_gap_update_entry * ble_gap_update_entry_find(uint16_t conn_handle, struct ble_gap_update_entry **out_prev); -static struct ble_gap_update_entry * -ble_gap_update_entry_remove(uint16_t conn_handle); + static void ble_gap_update_l2cap_cb(uint16_t conn_handle, int status, void *arg); +#endif +static struct ble_gap_update_entry * +ble_gap_update_entry_remove(uint16_t conn_handle); + +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static int ble_gap_adv_enable_tx(int enable); +#endif + static int ble_gap_conn_cancel_tx(void); #if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV) @@ -290,7 +316,7 @@ ble_gap_log_duration(int32_t duration_ms) } #endif -#if !MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) && !MYNEWT_VAL(BLE_EXT_ADV) static void ble_gap_log_conn(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *params) @@ -322,6 +348,7 @@ ble_gap_log_disc(uint8_t own_addr_type, int32_t duration_ms, } #endif +#if NIMBLE_BLE_CONNECT static void ble_gap_log_update(uint16_t conn_handle, const struct ble_gap_upd_params *params) @@ -333,7 +360,9 @@ ble_gap_log_update(uint16_t conn_handle, params->latency, params->supervision_timeout, params->min_ce_len, params->max_ce_len); } +#endif +#if MYNEWT_VAL(BLE_WHITELIST) static void ble_gap_log_wl(const ble_addr_t *addr, uint8_t white_list_count) { @@ -347,6 +376,7 @@ ble_gap_log_wl(const ble_addr_t *addr, uint8_t white_list_count) BLE_HS_LOG(INFO, "} "); } } +#endif #if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static void @@ -527,10 +557,9 @@ ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode) int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy) { + struct ble_hci_le_rd_phy_cp cmd; + struct ble_hci_le_rd_phy_rp rsp; struct ble_hs_conn *conn; - uint8_t buf[BLE_HCI_LE_RD_PHY_LEN]; - uint8_t rspbuf[4]; - uint8_t rsplen; int rc; ble_hs_lock(); @@ -541,25 +570,21 @@ ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy) return BLE_HS_ENOTCONN; } - rc = ble_hs_hci_cmd_build_le_read_phy(conn_handle, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + cmd.conn_handle = htole16(conn_handle); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_PHY), - buf, sizeof(buf), rspbuf, sizeof(rspbuf), &rsplen); + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (rsplen != sizeof(rspbuf)) { + /* sanity check for response */ + if (le16toh(rsp.conn_handle) != conn_handle) { return BLE_HS_ECONTROLLER; } - /* First two octets is conn_handle. We can ignore it */ - - *tx_phy = rspbuf[2]; - *rx_phy = rspbuf[3]; + *tx_phy = rsp.tx_phy; + *rx_phy = rsp.rx_phy; return 0; } @@ -567,27 +592,45 @@ ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy) int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask) { - uint8_t buf[BLE_HCI_LE_SET_DEFAULT_PHY_LEN]; - int rc; + struct ble_hci_le_set_default_phy_cp cmd; - rc = ble_hs_hci_cmd_build_le_set_default_phy(tx_phys_mask, rx_phys_mask, - buf, sizeof(buf)); - if (rc != 0) { - return rc; + if (tx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (rx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + memset(&cmd, 0, sizeof(cmd)); + + if (tx_phys_mask == 0) { + cmd.all_phys |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK; + } else { + cmd.tx_phys = tx_phys_mask; + } + + if (rx_phys_mask == 0) { + cmd.all_phys |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK; + } else { + cmd.rx_phys = rx_phys_mask; } return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DEFAULT_PHY), - buf, sizeof(buf), NULL, 0, NULL); + &cmd, sizeof(cmd), NULL, 0); } int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, uint8_t rx_phys_mask, uint16_t phy_opts) { + struct ble_hci_le_set_phy_cp cmd; struct ble_hs_conn *conn; - uint8_t buf[BLE_HCI_LE_SET_PHY_LEN]; - int rc; ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); @@ -597,16 +640,41 @@ ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, return BLE_HS_ENOTCONN; } - rc = ble_hs_hci_cmd_build_le_set_phy(conn_handle, tx_phys_mask, - rx_phys_mask, phy_opts, buf, - sizeof(buf)); - if (rc != 0) { - return rc; + if (tx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; } - return ble_hs_hci_cmd_tx( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PHY), - buf, sizeof(buf), NULL, 0, NULL); + if (rx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (phy_opts > BLE_HCI_LE_PHY_CODED_S8_PREF) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + memset(&cmd, 0, sizeof(cmd)); + cmd.conn_handle = htole16(conn_handle); + + if (tx_phys_mask == 0) { + cmd.all_phys |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK; + } else { + cmd.tx_phys = tx_phys_mask; + } + + if (rx_phys_mask == 0) { + cmd.all_phys |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK; + } else { + cmd.rx_phys = rx_phys_mask; + } + + cmd.phy_options = htole16(phy_opts); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PHY), + &cmd, sizeof(cmd), NULL, 0); } /***************************************************************************** @@ -679,6 +747,7 @@ ble_gap_is_preempted(void) return false; } +#if NIMBLE_BLE_CONNECT static void ble_gap_master_reset_state(void) { @@ -688,6 +757,7 @@ ble_gap_master_reset_state(void) ble_hs_timer_resched(); } +#endif static void ble_gap_slave_reset_state(uint8_t instance) @@ -700,6 +770,7 @@ ble_gap_slave_reset_state(uint8_t instance) #endif } +#if NIMBLE_BLE_CONNECT static bool ble_gap_has_client(struct ble_gap_master_state *out_state) { @@ -725,6 +796,7 @@ ble_gap_master_extract_state(struct ble_gap_master_state *out_state, ble_hs_unlock(); } +#endif static void ble_gap_slave_extract_cb(uint8_t instance, @@ -747,41 +819,24 @@ ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle, ble_gap_event_fn *cb; void *cb_arg; + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_ADV_COMPLETE; + event.adv_complete.reason = reason; +#if MYNEWT_VAL(BLE_EXT_ADV) + event.adv_complete.instance = instance; + event.adv_complete.conn_handle = conn_handle; + event.adv_complete.num_ext_adv_events = num_events; +#endif + + ble_gap_event_listener_call(&event); + ble_gap_slave_extract_cb(instance, &cb, &cb_arg); if (cb != NULL) { - memset(&event, 0, sizeof event); - event.type = BLE_GAP_EVENT_ADV_COMPLETE; - event.adv_complete.reason = reason; -#if MYNEWT_VAL(BLE_EXT_ADV) - event.adv_complete.instance = instance; - event.adv_complete.conn_handle = conn_handle; - event.adv_complete.num_ext_adv_events = num_events; -#endif cb(&event, cb_arg); } } -#if MYNEWT_VAL(BLE_EXT_ADV) -static void -ble_gap_scan_req_rcvd(uint8_t instance, uint8_t scan_addr_type, - uint8_t *scan_addr) -{ - struct ble_gap_event event; - ble_gap_event_fn *cb; - void *cb_arg; - - ble_gap_slave_extract_cb(instance, &cb, &cb_arg); - if (cb != NULL) { - memset(&event, 0, sizeof event); - event.type = BLE_GAP_EVENT_SCAN_REQ_RCVD; - event.scan_req_rcvd.instance = instance; - event.scan_req_rcvd.scan_addr.type = scan_addr_type; - memcpy(event.scan_req_rcvd.scan_addr.val, scan_addr, 6); - cb(&event, cb_arg); - } -} -#endif - +#if NIMBLE_BLE_CONNECT static int ble_gap_master_connect_failure(int status) { @@ -825,6 +880,95 @@ ble_gap_master_connect_cancelled(void) } } +#if CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT +static void +ble_gap_update_notify(uint16_t conn_handle, int status); + +static int +ble_gap_find_retry_conn_param(const struct ble_gap_conn_desc *conn_desc) +{ + int i; + + for(i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + if (memcmp(&ble_conn_reattempt[i].peer_addr, &conn_desc->peer_ota_addr, sizeof(ble_addr_t)) == 0) { + return i; + } + } + /* No matching entry found. Return invalid index */ + return MYNEWT_VAL(BLE_MAX_CONNECTIONS); +} + +int +ble_gap_master_connect_reattempt(uint16_t conn_handle) +{ + struct ble_gap_snapshot snap; + struct ble_gap_conn_desc conn; + struct ble_gap_update_entry *entry; + int idx; + int rc = BLE_HS_EUNKNOWN; + + snap.desc = &conn; + rc = ble_gap_find_snapshot(conn_handle, &snap); + if (rc != 0) { + return rc; + } + + if (conn.role == BLE_GAP_ROLE_MASTER) { + idx = ble_gap_find_retry_conn_param(&conn); + if (idx >= MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { + return BLE_HS_EINVAL; + } + + /* XXX Connection state in host needs to be removed and cleaned + * up to validate the connection when re-attempting. */ + + /* If there was a connection update in progress, indicate to the + * application that it did not complete. + */ + ble_hs_lock(); + entry = ble_gap_update_entry_remove(conn_handle); + ble_hs_unlock(); + + if (entry != NULL) { + ble_gap_update_notify(conn_handle, BLE_ERR_CONN_ESTABLISHMENT); + ble_gap_update_entry_free(entry); + } + + ble_l2cap_sig_conn_broken(conn_handle, BLE_ERR_CONN_ESTABLISHMENT); + ble_sm_connection_broken(conn_handle); + ble_gatts_connection_broken(conn_handle); + ble_gattc_connection_broken(conn_handle); + ble_hs_flow_connection_broken(conn_handle);; + + rc = ble_hs_atomic_conn_delete(conn_handle); + if (rc != 0) { + return rc; + } + + /* Utilize cookie to get the index updated correctly for re-attempt */ + ble_conn_reattempt[idx].cb_arg = &conn; + conn_cookie_enabled = true; + + rc = ble_gap_connect(ble_conn_reattempt[idx].own_addr_type, + &ble_conn_reattempt[idx].peer_addr, + ble_conn_reattempt[idx].duration_ms, + &ble_conn_reattempt[idx].conn_params, + ble_conn_reattempt[idx].cb, + ble_conn_reattempt[idx].cb_arg); + if (rc != 0) { + return rc; + } + } else { + rc = BLE_HS_EUNKNOWN; + } + + return rc; +} +#endif + +#endif + +#if NIMBLE_BLE_SCAN static void ble_gap_disc_report(void *desc) { @@ -848,7 +992,6 @@ ble_gap_disc_report(void *desc) ble_gap_event_listener_call(&event); } -#if NIMBLE_BLE_SCAN static void ble_gap_disc_complete(void) { @@ -907,7 +1050,7 @@ ble_gap_master_ticks_until_exp(void) return 0; } -#if !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static uint32_t ble_gap_slave_ticks_until_exp(void) { @@ -975,6 +1118,7 @@ ble_gap_update_next_exp(int32_t *out_ticks_from_now) } +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) static void ble_gap_master_set_timer(uint32_t ticks_from_now) { @@ -983,6 +1127,7 @@ ble_gap_master_set_timer(uint32_t ticks_from_now) ble_hs_timer_resched(); } +#endif #if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static void @@ -995,6 +1140,7 @@ ble_gap_slave_set_timer(uint32_t ticks_from_now) } #endif +#if NIMBLE_BLE_CONNECT /** * Called when an error is encountered while the master-connection-fsm is * active. @@ -1017,7 +1163,7 @@ ble_gap_master_failed(int status) #endif default: - //BLE_HS_DBG_ASSERT(0); + BLE_HS_DBG_ASSERT(0); break; } } @@ -1037,6 +1183,7 @@ ble_gap_update_failed(uint16_t conn_handle, int status) ble_gap_update_notify(conn_handle, status); } +#endif void ble_gap_conn_broken(uint16_t conn_handle, int reason) @@ -1088,6 +1235,7 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) STATS_INC(ble_gap_stats, disconnect); } +#if NIMBLE_BLE_CONNECT static void ble_gap_update_to_l2cap(const struct ble_gap_upd_params *params, struct ble_l2cap_sig_update_params *l2cap_params) @@ -1097,43 +1245,40 @@ ble_gap_update_to_l2cap(const struct ble_gap_upd_params *params, l2cap_params->slave_latency = params->latency; l2cap_params->timeout_multiplier = params->supervision_timeout; } - -void -ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt) -{ -#if !NIMBLE_BLE_CONNECT - return; #endif +void +ble_gap_rx_disconn_complete(const struct ble_hci_ev_disconn_cmp *ev) +{ +#if NIMBLE_BLE_CONNECT struct ble_gap_event event; + uint16_t handle = le16toh(ev->conn_handle); STATS_INC(ble_gap_stats, rx_disconnect); - if (evt->status == 0) { - ble_gap_conn_broken(evt->connection_handle, - BLE_HS_HCI_ERR(evt->reason)); + if (ev->status == 0) { + ble_gap_conn_broken(handle, BLE_HS_HCI_ERR(ev->reason)); } else { memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_TERM_FAILURE; - event.term_failure.conn_handle = evt->connection_handle; - event.term_failure.status = BLE_HS_HCI_ERR(evt->status); + event.term_failure.conn_handle = handle; + event.term_failure.status = BLE_HS_HCI_ERR(ev->status); ble_gap_event_listener_call(&event); - ble_gap_call_conn_event_cb(&event, evt->connection_handle); + ble_gap_call_conn_event_cb(&event, handle); } +#endif } void -ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt) +ble_gap_rx_update_complete(const struct ble_hci_ev_le_subev_conn_upd_complete *ev) { -#if !NIMBLE_BLE_CONNECT - return; -#endif - +#if NIMBLE_BLE_CONNECT struct ble_gap_update_entry *entry; struct ble_l2cap_sig_update_params l2cap_params; struct ble_gap_event event; struct ble_hs_conn *conn; + uint16_t conn_handle; int cb_status; int call_cb; int rc; @@ -1145,14 +1290,16 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt) ble_hs_lock(); - conn = ble_hs_conn_find(evt->connection_handle); + conn_handle = le16toh(ev->conn_handle); + + conn = ble_hs_conn_find(conn_handle); if (conn != NULL) { - switch (evt->status) { + switch (ev->status) { case 0: /* Connection successfully updated. */ - conn->bhc_itvl = evt->conn_itvl; - conn->bhc_latency = evt->conn_latency; - conn->bhc_supervision_timeout = evt->supervision_timeout; + conn->bhc_itvl = le16toh(ev->conn_itvl); + conn->bhc_latency = le16toh(ev->conn_latency); + conn->bhc_supervision_timeout = le16toh(ev->supervision_timeout); break; case BLE_ERR_UNSUPP_REM_FEATURE: @@ -1161,7 +1308,7 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt) * Request Procedure. If we are the slave, fail over to the L2CAP * update procedure. */ - entry = ble_gap_update_entry_find(evt->connection_handle, NULL); + entry = ble_gap_update_entry_find(conn_handle, NULL); if (entry != NULL && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { ble_gap_update_to_l2cap(&entry->params, &l2cap_params); entry->exp_os_ticks = ble_npl_time_get() + @@ -1176,15 +1323,14 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt) /* We aren't failing over to L2CAP, the update procedure is complete. */ if (l2cap_params.itvl_min == 0) { - entry = ble_gap_update_entry_remove(evt->connection_handle); + entry = ble_gap_update_entry_remove(conn_handle); ble_gap_update_entry_free(entry); } ble_hs_unlock(); if (l2cap_params.itvl_min != 0) { - rc = ble_l2cap_sig_update(evt->connection_handle, - &l2cap_params, + rc = ble_l2cap_sig_update(conn_handle, &l2cap_params, ble_gap_update_l2cap_cb, NULL); if (rc == 0) { call_cb = 0; @@ -1194,12 +1340,13 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt) } } else { call_cb = 1; - cb_status = BLE_HS_HCI_ERR(evt->status); + cb_status = BLE_HS_HCI_ERR(ev->status); } if (call_cb) { - ble_gap_update_notify(evt->connection_handle, cb_status); + ble_gap_update_notify(conn_handle, cb_status); } +#endif } /** @@ -1211,34 +1358,6 @@ ble_gap_master_in_progress(void) return ble_gap_master.op != BLE_GAP_OP_NULL; } -static int -ble_gap_accept_master_conn(void) -{ - int rc; - - switch (ble_gap_master.op) { - case BLE_GAP_OP_NULL: - case BLE_GAP_OP_M_DISC: - rc = BLE_HS_ENOENT; - break; - - case BLE_GAP_OP_M_CONN: - rc = 0; - break; - - default: - BLE_HS_DBG_ASSERT(0); - rc = BLE_HS_ENOENT; - break; - } - - if (rc == 0) { - STATS_INC(ble_gap_stats, connect_mst); - } - - return rc; -} - static int ble_gap_adv_active_instance(uint8_t instance) { @@ -1286,6 +1405,35 @@ ble_gap_reset_state(int reason) #endif } +#if NIMBLE_BLE_CONNECT +static int +ble_gap_accept_master_conn(void) +{ + int rc; + + switch (ble_gap_master.op) { + case BLE_GAP_OP_NULL: + case BLE_GAP_OP_M_DISC: + rc = BLE_HS_ENOENT; + break; + + case BLE_GAP_OP_M_CONN: + rc = 0; + break; + + default: + BLE_HS_DBG_ASSERT(0); + rc = BLE_HS_ENOENT; + break; + } + + if (rc == 0) { + STATS_INC(ble_gap_stats, connect_mst); + } + + return rc; +} + static int ble_gap_accept_slave_conn(uint8_t instance) { @@ -1309,9 +1457,11 @@ ble_gap_accept_slave_conn(uint8_t instance) return rc; } +#endif +#if NIMBLE_BLE_SCAN static int -ble_gap_rx_adv_report_sanity_check(uint8_t *adv_data, uint8_t adv_data_len) +ble_gap_rx_adv_report_sanity_check(const uint8_t *adv_data, uint8_t adv_data_len) { const struct ble_hs_adv_field *flags; int rc; @@ -1336,30 +1486,28 @@ ble_gap_rx_adv_report_sanity_check(uint8_t *adv_data, uint8_t adv_data_len) return 0; } +#endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc) { -#if !NIMBLE_BLE_SCAN - return; -#endif - +#if NIMBLE_BLE_SCAN if (ble_gap_rx_adv_report_sanity_check(desc->data, desc->length_data)) { return; } ble_gap_disc_report(desc); +#endif } -#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN +#if MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_SCAN void ble_gap_rx_le_scan_timeout(void) { ble_gap_disc_complete(); } -#endif -#if MYNEWT_VAL(BLE_EXT_ADV) void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc) { @@ -1369,31 +1517,43 @@ ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc) ble_gap_disc_report(desc); } +#endif void -ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt) +ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminated *ev) { uint16_t conn_handle; int reason; /* Currently spec allows only 0x3c and 0x43 when advertising was stopped * due to timeout or events limit, mp this for timeout error for now */ - if (evt->status) { + if (ev->status) { reason = BLE_HS_ETIMEOUT; conn_handle = 0; } else { reason = 0; - conn_handle = evt->conn_handle; + conn_handle = le16toh(ev->conn_handle); } - ble_gap_adv_finished(evt->adv_handle, reason, conn_handle, - evt->completed_events); + ble_gap_adv_finished(ev->adv_handle, reason, conn_handle, ev->num_events); } void -ble_gap_rx_scan_req_rcvd(struct hci_le_scan_req_rcvd *evt) +ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev) { - ble_gap_scan_req_rcvd(evt->adv_handle, evt->scan_addr_type, evt->scan_addr); + struct ble_gap_event event; + ble_gap_event_fn *cb; + void *cb_arg; + + ble_gap_slave_extract_cb(ev->adv_handle, &cb, &cb_arg); + if (cb != NULL) { + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_SCAN_REQ_RCVD; + event.scan_req_rcvd.instance = ev->adv_handle; + event.scan_req_rcvd.scan_addr.type = ev->peer_addr_type; + memcpy(event.scan_req_rcvd.scan_addr.val, ev->peer_addr, BLE_DEV_ADDR_LEN); + cb(&event, cb_arg); + } } #endif @@ -1401,8 +1561,9 @@ ble_gap_rx_scan_req_rcvd(struct hci_le_scan_req_rcvd *evt) #if MYNEWT_VAL(BLE_PERIODIC_ADV) void -ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab *evt) +ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev) { + uint16_t sync_handle; struct ble_gap_event event; ble_gap_event_fn *cb; void *cb_arg; @@ -1410,27 +1571,29 @@ ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab * memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_PERIODIC_SYNC; - event.periodic_sync.status = evt->status; + event.periodic_sync.status = ev->status; ble_hs_lock(); BLE_HS_DBG_ASSERT(ble_gap_sync.psync); - if (!evt->status) { - ble_gap_sync.psync->sync_handle = evt->sync_handle; - ble_gap_sync.psync->adv_sid = evt->sid; - memcpy(ble_gap_sync.psync->advertiser_addr.val, evt->adv_addr, 6); - ble_gap_sync.psync->advertiser_addr.type = evt->adv_addr_type; + if (!ev->status) { + sync_handle = le16toh(ev->sync_handle); + + ble_gap_sync.psync->sync_handle = sync_handle; + ble_gap_sync.psync->adv_sid = ev->sid; + memcpy(ble_gap_sync.psync->advertiser_addr.val, ev->peer_addr, 6); + ble_gap_sync.psync->advertiser_addr.type = ev->peer_addr_type; ble_gap_sync.psync->cb = ble_gap_sync.cb; ble_gap_sync.psync->cb_arg = ble_gap_sync.cb_arg; - event.periodic_sync.sync_handle = evt->sync_handle; - event.periodic_sync.sid = evt->sid; + event.periodic_sync.sync_handle = sync_handle; + event.periodic_sync.sid = ev->sid; event.periodic_sync.adv_addr = ble_gap_sync.psync->advertiser_addr; - event.periodic_sync.adv_phy = evt->adv_phy; - event.periodic_sync.per_adv_ival = evt->per_adv_ival; - event.periodic_sync.adv_clk_accuracy = evt->adv_clk_accuracy; + event.periodic_sync.adv_phy = ev->phy; + event.periodic_sync.per_adv_ival = ev->interval; + event.periodic_sync.adv_clk_accuracy = ev->aca; ble_hs_periodic_sync_insert(ble_gap_sync.psync); } else { @@ -1454,7 +1617,7 @@ ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab * } void -ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt) +ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_rpt *ev) { struct ble_hs_periodic_sync *psync; struct ble_gap_event event; @@ -1462,7 +1625,7 @@ ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt) void *cb_arg = NULL; ble_hs_lock(); - psync = ble_hs_periodic_sync_find_by_handle(evt->sync_handle); + psync = ble_hs_periodic_sync_find_by_handle(le16toh(ev->sync_handle)); if (psync) { cb = psync->cb; cb_arg = psync->cb_arg; @@ -1476,12 +1639,12 @@ ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt) memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_PERIODIC_REPORT; - event.periodic_report.sync_handle = evt->sync_handle; - event.periodic_report.tx_power = evt->tx_power; - event.periodic_report.rssi = evt->rssi; - event.periodic_report.data_status = evt->data_status; - event.periodic_report.data_length = evt->data_length; - event.periodic_report.data = evt->data; + event.periodic_report.sync_handle = psync->sync_handle; + event.periodic_report.tx_power = ev->tx_power; + event.periodic_report.rssi = ev->rssi; + event.periodic_report.data_status = ev->data_status; + event.periodic_report.data_length = ev->data_len; + event.periodic_report.data = ev->data; /* TODO should we allow for listener too? this can be spammy and is more * like ACL data, not general event @@ -1490,22 +1653,16 @@ ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt) } void -ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *evt) +ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev) { struct ble_hs_periodic_sync *psync; struct ble_gap_event event; ble_gap_event_fn *cb; void *cb_arg; - memset(&event, 0, sizeof event); - - event.type = BLE_GAP_EVENT_PERIODIC_SYNC_LOST; - event.periodic_sync_lost.sync_handle = evt->sync_handle; - event.periodic_sync_lost.reason = BLE_HS_ETIMEOUT; - ble_hs_lock(); /* The handle must be in the list */ - psync = ble_hs_periodic_sync_find_by_handle(evt->sync_handle); + psync = ble_hs_periodic_sync_find_by_handle(le16toh(ev->sync_handle)); BLE_HS_DBG_ASSERT(psync); cb = psync->cb; @@ -1515,6 +1672,12 @@ ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *ev ble_hs_periodic_sync_remove(psync); ble_hs_unlock(); + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_PERIODIC_SYNC_LOST; + event.periodic_sync_lost.sync_handle = psync->sync_handle; + event.periodic_sync_lost.reason = BLE_HS_ETIMEOUT; + /* remove any sync_lost event from queue */ ble_npl_eventq_remove(ble_hs_evq_get(), &psync->lost_ev); @@ -1528,38 +1691,132 @@ ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *ev } #endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +static int +periodic_adv_transfer_disable(uint16_t conn_handle) +{ + struct ble_hci_le_periodic_adv_sync_transfer_params_cp cmd; + struct ble_hci_le_periodic_adv_sync_transfer_params_rp rsp; + uint16_t opcode; + int rc; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS); + + cmd.conn_handle = htole16(conn_handle); + cmd.sync_cte_type = 0x00; + cmd.mode = 0x00; + cmd.skip = 0x0000; + cmd.sync_timeout = 0x000a; + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + if (!rc) { + BLE_HS_DBG_ASSERT(le16toh(rsp.conn_handle) == conn_handle); + } + + return rc; +} + +void +ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev) +{ + struct ble_hci_le_periodic_adv_term_sync_cp cmd_term; + struct ble_gap_event event; + struct ble_hs_conn *conn; + ble_gap_event_fn *cb; + uint16_t sync_handle; + uint16_t conn_handle; + uint16_t opcode; + void *cb_arg; + + conn_handle = le16toh(ev->conn_handle); + + ble_hs_lock(); + + /* Unfortunately spec sucks here as it doesn't explicitly stop + * transfer reception on first transfer... for now just disable it on + * every transfer event we get. + */ + periodic_adv_transfer_disable(conn_handle); + + conn = ble_hs_conn_find(le16toh(ev->conn_handle)); + if (!conn || !conn->psync) { + /* terminate sync if we didn't expect it */ + if (!ev->status) { + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC); + cmd_term.sync_handle = ev->sync_handle; + ble_hs_hci_cmd_tx(opcode, &cmd_term, sizeof(cmd_term), NULL, 0); + } + + ble_hs_unlock(); + return; + } + + cb = conn->psync->cb; + cb_arg = conn->psync->cb_arg; + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_PERIODIC_TRANSFER; + event.periodic_transfer.status = ev->status; + + /* only sync handle is not valid on error */ + if (ev->status) { + sync_handle = 0; + ble_hs_periodic_sync_free(conn->psync); + } else { + sync_handle = le16toh(ev->sync_handle); + + conn->psync->sync_handle = sync_handle; + conn->psync->adv_sid = ev->sid; + memcpy(conn->psync->advertiser_addr.val, ev->peer_addr, 6); + conn->psync->advertiser_addr.type = ev->peer_addr_type; + ble_hs_periodic_sync_insert(conn->psync); + } + + conn->psync = NULL; + + event.periodic_transfer.sync_handle = sync_handle; + event.periodic_transfer.conn_handle = conn_handle; + event.periodic_transfer.service_data = le16toh(ev->service_data); + event.periodic_transfer.sid = ev->sid; + memcpy(event.periodic_transfer.adv_addr.val, ev->peer_addr, 6); + event.periodic_transfer.adv_addr.type = ev->peer_addr_type; + + event.periodic_transfer.adv_phy = ev->phy; + event.periodic_transfer.per_adv_itvl = le16toh(ev->interval); + event.periodic_transfer.adv_clk_accuracy = ev->aca; + + ble_hs_unlock(); + + ble_gap_event_listener_call(&event); + if (cb) { + cb(&event, cb_arg); + } +} +#endif + +#if NIMBLE_BLE_CONNECT static int ble_gap_rd_rem_sup_feat_tx(uint16_t handle) { - uint8_t buf[BLE_HCI_CONN_RD_REM_FEAT_LEN]; - int rc; + struct ble_hci_le_rd_rem_feat_cp cmd; - rc = ble_hs_hci_cmd_build_le_read_remote_feat(handle, buf, sizeof buf); - if (rc != 0) { - return BLE_HS_EUNKNOWN; - } + cmd.conn_handle = htole16(handle); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_RD_REM_FEAT), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_RD_REM_FEAT), + &cmd, sizeof(cmd), NULL, 0); } +#endif /** * Processes an incoming connection-complete HCI event. * instance parameter is valid only for slave connection. */ int -ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance) +ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) { -#if !NIMBLE_BLE_CONNECT - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_CONNECT struct ble_gap_event event; struct ble_hs_conn *conn; int rc; @@ -1691,26 +1948,26 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance) ble_gap_rd_rem_sup_feat_tx(evt->connection_handle); return 0; +#else + return BLE_HS_ENOTSUP; +#endif } void -ble_gap_rx_rd_rem_sup_feat_complete( - struct hci_le_rd_rem_supp_feat_complete *evt) +ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev) { -#if !NIMBLE_BLE_CONNECT - return; -#endif - +#if NIMBLE_BLE_CONNECT struct ble_hs_conn *conn; ble_hs_lock(); - conn = ble_hs_conn_find(evt->connection_handle); - if (conn != NULL && evt->status == 0) { - conn->supported_feat = get_le32(evt->features); + conn = ble_hs_conn_find(le16toh(ev->conn_handle)); + if ((conn != NULL) && (ev->status == 0)) { + conn->supported_feat = get_le32(ev->features); } ble_hs_unlock(); +#endif } int @@ -1730,19 +1987,20 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle, } void -ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt) +ble_gap_rx_phy_update_complete(const struct ble_hci_ev_le_subev_phy_update_complete *ev) { struct ble_gap_event event; + uint16_t conn_handle = le16toh(ev->conn_handle); memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_PHY_UPDATE_COMPLETE; - event.phy_updated.status = evt->status; - event.phy_updated.conn_handle = evt->connection_handle; - event.phy_updated.tx_phy = evt->tx_phy; - event.phy_updated.rx_phy = evt->rx_phy; + event.phy_updated.status = ev->status; + event.phy_updated.conn_handle = conn_handle; + event.phy_updated.tx_phy = ev->tx_phy; + event.phy_updated.rx_phy = ev->rx_phy; ble_gap_event_listener_call(&event); - ble_gap_call_conn_event_cb(&event, evt->connection_handle); + ble_gap_call_conn_event_cb(&event, conn_handle); } static int32_t @@ -1801,7 +2059,7 @@ ble_gap_master_timer(void) return BLE_HS_FOREVER; } -#if !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static int32_t ble_gap_slave_timer(void) { @@ -1900,7 +2158,7 @@ ble_gap_timer(void) min_ticks = min(master_ticks, update_ticks); -#if !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) min_ticks = min(min_ticks, ble_gap_slave_timer()); #endif @@ -1911,12 +2169,10 @@ ble_gap_timer(void) * $white list * *****************************************************************************/ +#if MYNEWT_VAL(BLE_WHITELIST) static int ble_gap_wl_busy(void) { -#if !MYNEWT_VAL(BLE_WHITELIST) - return BLE_HS_ENOTSUP; -#endif #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) if (ble_host_rpa_enabled()) { @@ -1933,52 +2189,56 @@ ble_gap_wl_busy(void) static int ble_gap_wl_tx_add(const ble_addr_t *addr) { - uint8_t buf[BLE_HCI_ADD_WHITE_LIST_LEN]; - int rc; + struct ble_hci_le_add_whte_list_cp cmd; - rc = ble_hs_hci_cmd_build_le_add_to_whitelist(addr->val, addr->type, - buf, sizeof buf); - if (rc != 0) { - return rc; + if (addr->type > BLE_ADDR_RANDOM) { + return BLE_HS_EINVAL; } - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_ADD_WHITE_LIST), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + memcpy(cmd.addr, addr->val, BLE_DEV_ADDR_LEN); + cmd.addr_type = addr->type; - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_ADD_WHITE_LIST), + &cmd, sizeof(cmd), NULL, 0); } static int ble_gap_wl_tx_clear(void) { - int rc; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CLEAR_WHITE_LIST), + NULL, 0, NULL, 0 ); +} +#endif - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_WHITE_LIST), - NULL, 0); - if (rc != 0) { - return rc; +int +ble_gap_wl_tx_rmv(const ble_addr_t *addr) +{ + struct ble_hci_le_rmv_white_list_cp cmd; + + if (addr->type > BLE_ADDR_RANDOM) { + return BLE_HS_EINVAL; } - return 0; + memcpy(cmd.addr, addr->val, BLE_DEV_ADDR_LEN); + cmd.addr_type = addr->type; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_RMV_WHITE_LIST), + &cmd, sizeof(cmd), NULL, 0); } int ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count) { -#if !MYNEWT_VAL(BLE_WHITELIST) - return BLE_HS_ENOTSUP; -#endif - #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) if (ble_host_rpa_enabled()) { return BLE_HS_ENOTSUP; } #endif + +#if MYNEWT_VAL(BLE_WHITELIST) int rc; int i; @@ -2030,37 +2290,30 @@ done: STATS_INC(ble_gap_stats, wl_set_fail); } return rc; +#else + return BLE_HS_ENOTSUP; +#endif } /***************************************************************************** * $stop advertise * *****************************************************************************/ - +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) static int ble_gap_adv_enable_tx(int enable) { - uint8_t buf[BLE_HCI_SET_ADV_ENABLE_LEN]; - uint16_t opcode; - int rc; + struct ble_hci_le_set_adv_enable_cp cmd; - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE); - ble_hs_hci_cmd_build_le_set_adv_enable(!!enable, buf, sizeof buf); + cmd.enable = !!enable; - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_ADV_ENABLE), + &cmd, sizeof(cmd), NULL, 0); } static int ble_gap_adv_stop_no_lock(void) { -#if !NIMBLE_BLE_ADVERTISE - return BLE_HS_ENOTSUP; -#endif - bool active; int rc; @@ -2092,14 +2345,12 @@ done: return rc; } +#endif int ble_gap_adv_stop(void) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) int rc; ble_hs_lock(); @@ -2107,6 +2358,9 @@ ble_gap_adv_stop(void) ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } /***************************************************************************** @@ -2162,6 +2416,8 @@ ble_gap_adv_dflt_itvls(uint8_t conn_mode, default: BLE_HS_DBG_ASSERT(0); + *out_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN; + *out_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX; break; } } @@ -2172,52 +2428,43 @@ ble_gap_adv_params_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr, { const ble_addr_t *peer_any = BLE_ADDR_ANY; - struct hci_adv_params hci_adv_params; - uint8_t buf[BLE_HCI_SET_ADV_PARAM_LEN]; - int rc; + struct ble_hci_le_set_adv_params_cp cmd; + uint16_t opcode; + uint16_t min; + uint16_t max; + + /* Fill optional fields if application did not specify them. */ + if ((adv_params->itvl_min == 0) && (adv_params->itvl_max == 0)) { + ble_gap_adv_dflt_itvls(adv_params->conn_mode, &min, &max); + cmd.min_interval = htole16(min); + cmd.max_interval = htole16(max); + } else { + cmd.min_interval = htole16(adv_params->itvl_min); + cmd.max_interval = htole16(adv_params->itvl_max); + } + + cmd.type = ble_gap_adv_type(adv_params); + cmd.own_addr_type = own_addr_type; if (peer_addr == NULL) { peer_addr = peer_any; } - hci_adv_params.own_addr_type = own_addr_type; - hci_adv_params.peer_addr_type = peer_addr->type; - memcpy(hci_adv_params.peer_addr, peer_addr->val, - sizeof hci_adv_params.peer_addr); + cmd.peer_addr_type = peer_addr->type; + memcpy(&cmd.peer_addr, peer_addr->val, sizeof(cmd.peer_addr)); - /* Fill optional fields if application did not specify them. */ - if (adv_params->itvl_min == 0 && adv_params->itvl_max == 0) { - ble_gap_adv_dflt_itvls(adv_params->conn_mode, - &hci_adv_params.adv_itvl_min, - &hci_adv_params.adv_itvl_max); - } else { - hci_adv_params.adv_itvl_min = adv_params->itvl_min; - hci_adv_params.adv_itvl_max = adv_params->itvl_max; - } if (adv_params->channel_map == 0) { - hci_adv_params.adv_channel_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; + cmd.chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; } else { - hci_adv_params.adv_channel_map = adv_params->channel_map; + cmd.chan_map = adv_params->channel_map; } /* Zero is the default value for filter policy and high duty cycle */ - hci_adv_params.adv_filter_policy = adv_params->filter_policy; + cmd.filter_policy = adv_params->filter_policy; - hci_adv_params.adv_type = ble_gap_adv_type(adv_params); - rc = ble_hs_hci_cmd_build_le_set_adv_params(&hci_adv_params, - buf, sizeof buf); - if (rc != 0) { - return BLE_HS_EINVAL; - } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_PARAMS); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_ADV_PARAMS), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } static int @@ -2297,9 +2544,7 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, const struct ble_gap_adv_params *adv_params, ble_gap_event_fn *cb, void *cb_arg) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#else +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) uint32_t duration_ticks; int rc; @@ -2376,83 +2621,66 @@ done: STATS_INC(ble_gap_stats, adv_start_fail); } return rc; +#else + return BLE_HS_ENOTSUP; #endif } int ble_gap_adv_set_data(const uint8_t *data, int data_len) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#endif - - uint8_t buf[BLE_HCI_SET_ADV_DATA_LEN]; +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) + struct ble_hci_le_set_adv_data_cp cmd; uint16_t opcode; - int rc; STATS_INC(ble_gap_stats, adv_set_data); - ble_hs_lock(); + /* Check for valid parameters */ + if (((data == NULL) && (data_len != 0)) || + (data_len > BLE_HCI_MAX_ADV_DATA_LEN)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + memcpy(cmd.adv_data, data, data_len); + cmd.adv_data_len = data_len; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_DATA); - rc = ble_hs_hci_cmd_build_le_set_adv_data(data, data_len, buf, - sizeof(buf)); - if (rc != 0) { - goto done; - } - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); - if (rc != 0) { - goto done; - } - - rc = 0; - -done: - ble_hs_unlock(); - return rc; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif } int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#endif - - uint8_t buf[BLE_HCI_SET_SCAN_RSP_DATA_LEN]; +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) + struct ble_hci_le_set_scan_rsp_data_cp cmd; uint16_t opcode; - int rc; - ble_hs_lock(); + + /* Check for valid parameters */ + if (((data == NULL) && (data_len != 0)) || + (data_len > BLE_HCI_MAX_SCAN_RSP_DATA_LEN)) { + return BLE_HS_EINVAL; + } + + memcpy(cmd.scan_rsp, data, data_len); + cmd.scan_rsp_len = data_len; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA); - rc = ble_hs_hci_cmd_build_le_set_scan_rsp_data(data, data_len, - buf, sizeof(buf)); - if (rc != 0) { - rc = BLE_HS_HCI_ERR(rc); - goto done; - } - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); - if (rc != 0) { - goto done; - } - - rc = 0; - -done: - ble_hs_unlock(); - return rc; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif } int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_sz; int rc; @@ -2468,15 +2696,15 @@ ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields) { -#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_sz; int rc; @@ -2492,6 +2720,9 @@ ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int @@ -2507,87 +2738,81 @@ ble_gap_ext_adv_params_tx(uint8_t instance, int8_t *selected_tx_power) { - struct hci_ext_adv_params hci_adv_params; - uint8_t buf[BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN]; - uint8_t rsp; + struct ble_hci_le_set_ext_adv_params_cp cmd; + struct ble_hci_le_set_ext_adv_params_rp rsp; int rc; - memset(&hci_adv_params, 0, sizeof(hci_adv_params)); + memset(&cmd, 0, sizeof(cmd)); + + cmd.adv_handle = instance; if (params->connectable) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; } if (params->scannable) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; } if (params->directed) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; - hci_adv_params.peer_addr_type = params->peer.type; - memcpy(hci_adv_params.peer_addr, params->peer.val, 6); + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; + cmd.peer_addr_type = params->peer.type; + memcpy(cmd.peer_addr, params->peer.val, BLE_DEV_ADDR_LEN); } if (params->high_duty_directed) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; } if (params->legacy_pdu) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; } if (params->anonymous) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; } if (params->include_tx_power) { - hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; } /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { /* TODO for now limited to legacy values*/ - hci_adv_params.min_interval = BLE_GAP_ADV_FAST_INTERVAL1_MIN; - hci_adv_params.max_interval = BLE_GAP_ADV_FAST_INTERVAL2_MAX; - + put_le24(cmd.pri_itvl_min, BLE_GAP_ADV_FAST_INTERVAL1_MIN); + put_le24(cmd.pri_itvl_max, BLE_GAP_ADV_FAST_INTERVAL2_MAX); } else { - hci_adv_params.min_interval = params->itvl_min; - hci_adv_params.max_interval = params->itvl_max; + put_le24(cmd.pri_itvl_min, params->itvl_min); + put_le24(cmd.pri_itvl_max, params->itvl_max); } if (params->channel_map == 0) { - hci_adv_params.chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; + cmd.pri_chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; } else { - hci_adv_params.chan_map = params->channel_map; + cmd.pri_chan_map = params->channel_map; } /* Zero is the default value for filter policy and high duty cycle */ - hci_adv_params.filter_policy = params->filter_policy; - hci_adv_params.tx_power = params->tx_power; + cmd.filter_policy = params->filter_policy; + cmd.tx_power = params->tx_power; if (params->legacy_pdu) { - hci_adv_params.primary_phy = BLE_HCI_LE_PHY_1M; - hci_adv_params.secondary_phy = BLE_HCI_LE_PHY_1M; + cmd.pri_phy = BLE_HCI_LE_PHY_1M; + cmd.sec_phy = BLE_HCI_LE_PHY_1M; } else { - hci_adv_params.primary_phy = params->primary_phy; - hci_adv_params.secondary_phy = params->secondary_phy; + cmd.pri_phy = params->primary_phy; + cmd.sec_phy = params->secondary_phy; } - hci_adv_params.own_addr_type = params->own_addr_type; - hci_adv_params.max_skip = 0; - hci_adv_params.sid = params->sid; - hci_adv_params.scan_req_notif = params->scan_req_notif; + cmd.own_addr_type = params->own_addr_type; + cmd.sec_max_skip = 0; + cmd.sid = params->sid; + cmd.scan_req_notif = params->scan_req_notif; - rc = ble_hs_hci_cmd_build_le_ext_adv_params(instance, &hci_adv_params, - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), - buf, sizeof(buf), &rsp, 1, NULL); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } if (selected_tx_power) { - *selected_tx_power = rsp; + *selected_tx_power = rsp.tx_power; } return 0; @@ -2677,6 +2902,7 @@ ble_gap_ext_adv_configure(uint8_t instance, ble_gap_slave[instance].connectable = params->connectable; ble_gap_slave[instance].scannable = params->scannable; ble_gap_slave[instance].directed = params->directed; + ble_gap_slave[instance].high_duty_directed = params->high_duty_directed; ble_gap_slave[instance].legacy_pdu = params->legacy_pdu; ble_hs_unlock(); @@ -2686,18 +2912,15 @@ ble_gap_ext_adv_configure(uint8_t instance, static int ble_gap_ext_adv_set_addr_no_lock(uint8_t instance, const uint8_t *addr) { - uint8_t buf[BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN]; + struct ble_hci_le_set_adv_set_rnd_addr_cp cmd; int rc; - rc = ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(instance, addr, buf, - sizeof(buf)); - if (rc != 0) { - return rc; - } + cmd.adv_handle = instance; + memcpy(cmd.addr, addr, BLE_DEV_ADDR_LEN); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR), - buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR), + &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { return rc; } @@ -2727,9 +2950,9 @@ ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr) int ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) { + struct ble_hci_le_set_ext_adv_enable_cp *cmd; + uint8_t buf[sizeof(*cmd) + sizeof(cmd->sets[0])]; const uint8_t *rnd_addr; - uint8_t buf[6]; - struct hci_ext_adv_set set; uint16_t opcode; int rc; @@ -2748,7 +2971,9 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) return BLE_HS_EALREADY; } - if (ble_gap_slave[instance].directed && duration > 1280) { + /* HD directed duration shall not be 0 or larger than >1.28s */ + if (ble_gap_slave[instance].high_duty_directed && + ((duration == 0) || (duration > 128)) ) { ble_hs_unlock(); return BLE_HS_EINVAL; } @@ -2800,17 +3025,16 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE); - set.handle = instance; - set.duration = duration; - set.events = max_events; + cmd = (void *) buf; - rc = ble_hs_hci_cmd_build_le_ext_adv_enable(1, 1, &set, buf, sizeof(buf)); - if (rc != 0) { - ble_hs_unlock(); - return rc; - } + cmd->enable = 0x01; + cmd->num_sets = 1; - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + cmd->sets[0].adv_handle = instance; + cmd->sets[0].duration = htole16(duration); + cmd->sets[0].max_events = max_events; + + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(buf), NULL, 0); if (rc != 0) { ble_hs_unlock(); return rc; @@ -2825,8 +3049,8 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) static int ble_gap_ext_adv_stop_no_lock(uint8_t instance) { - uint8_t buf[6]; - struct hci_ext_adv_set set; + struct ble_hci_le_set_ext_adv_enable_cp *cmd; + uint8_t buf[sizeof(*cmd) + sizeof(cmd->sets[0])]; uint16_t opcode; bool active; int rc; @@ -2837,18 +3061,17 @@ ble_gap_ext_adv_stop_no_lock(uint8_t instance) active = ble_gap_adv_active_instance(instance); + cmd = (void *) buf; + + cmd->enable = 0x00; + cmd->num_sets = 1; + cmd->sets[0].adv_handle = instance; + cmd->sets[0].duration = 0x0000; + cmd->sets[0].max_events = 0x00; + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE); - set.handle = instance; - set.duration = 0; - set.events = 0; - - rc = ble_hs_hci_cmd_build_le_ext_adv_enable(0, 1, &set, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(buf), NULL, 0); if (rc != 0) { return rc; } @@ -2925,65 +3148,63 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) { /* in that case we always fit all data in single HCI command */ #if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_EXT_ADV_DATA_LEN - static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \ + static uint8_t buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; + struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)buf; uint16_t len = OS_MBUF_PKTLEN(*data); - int rc; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode); + cmd->adv_handle = instance; + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; + cmd->fragment_pref = 0; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); - rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, - BLE_HCI_LE_SET_DATA_OPER_COMPLETE, - 0, *data, len, buf, sizeof(buf)); - if (rc) { - return rc; - } - - os_mbuf_adj(*data, MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)); + os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); #else - static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \ + static uint8_t buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ BLE_HCI_MAX_EXT_ADV_DATA_LEN]; + struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)buf; uint16_t len = OS_MBUF_PKTLEN(*data); uint8_t op; int rc; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode); + cmd->adv_handle = instance; + /* complete data */ if (len <= BLE_HCI_MAX_EXT_ADV_DATA_LEN) { - rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, - BLE_HCI_LE_SET_DATA_OPER_COMPLETE, - 0, *data, len, buf,sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; + cmd->fragment_pref = 0; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); } /* first fragment */ op = BLE_HCI_LE_SET_DATA_OPER_FIRST; do { - rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, op, 0, *data, - BLE_HCI_MAX_EXT_ADV_DATA_LEN, - buf, sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = op; + cmd->fragment_pref = 0; + cmd->adv_data_len = BLE_HCI_MAX_EXT_ADV_DATA_LEN; + os_mbuf_copydata(*data, 0, BLE_HCI_MAX_EXT_ADV_DATA_LEN, cmd->adv_data); os_mbuf_adj(*data, BLE_HCI_MAX_EXT_ADV_DATA_LEN); *data = os_mbuf_trim_front(*data); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); if (rc) { return rc; } @@ -2993,18 +3214,16 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) } while (len > BLE_HCI_MAX_EXT_ADV_DATA_LEN); /* last fragment */ - rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, - BLE_HCI_LE_SET_DATA_OPER_LAST, - 0, *data, len, buf, sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_LAST; + cmd->fragment_pref = 0; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); #endif } @@ -3105,7 +3324,7 @@ done: int ble_gap_ext_adv_remove(uint8_t instance) { - uint8_t buf[BLE_HCI_LE_REMOVE_ADV_SET_LEN]; + struct ble_hci_le_remove_adv_set_cp cmd; uint16_t opcode; int rc; @@ -3124,15 +3343,10 @@ ble_gap_ext_adv_remove(uint8_t instance) return BLE_HS_EBUSY; } + cmd.adv_handle = instance; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REMOVE_ADV_SET); - rc = ble_hs_hci_cmd_build_le_ext_adv_remove(instance, buf, sizeof(buf)); - if (rc != 0) { - ble_hs_unlock(); - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { ble_hs_unlock(); return rc; @@ -3172,7 +3386,7 @@ ble_gap_ext_adv_clear(void) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_ADV_SETS); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, NULL, 0); + rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, NULL, 0); if (rc != 0) { ble_hs_unlock(); return rc; @@ -3187,44 +3401,34 @@ ble_gap_ext_adv_clear(void) #if MYNEWT_VAL(BLE_PERIODIC_ADV) static int ble_gap_periodic_adv_params_tx(uint8_t instance, - const struct ble_gap_periodic_adv_params *params) + const struct ble_gap_periodic_adv_params *params) { - struct hci_periodic_adv_params hci_adv_params; - uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN]; - int rc; + struct ble_hci_le_set_periodic_adv_params_cp cmd; + uint16_t opcode; - memset(&hci_adv_params, 0, sizeof(hci_adv_params)); - - if (params->include_tx_power) { - hci_adv_params.properties |= BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR; - } + cmd.adv_handle = instance; /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { - hci_adv_params.min_interval = 30 / 1.25; //30 ms - hci_adv_params.max_interval = 60 / 1.25; //150 ms + /* TODO defines for those */ + cmd.min_itvl = htole16(30 / 1.25); //30 ms + cmd.max_itvl = htole16(60 / 1.25); //150 ms } else { - hci_adv_params.min_interval = params->itvl_min; - hci_adv_params.max_interval = params->itvl_max; + cmd.min_itvl = htole16( params->itvl_min); + cmd.max_itvl = htole16(params->itvl_max); } - rc = ble_hs_hci_cmd_build_le_periodic_adv_params(instance, &hci_adv_params, buf, - sizeof(buf)); - if (rc != 0) { - return rc; + if (params->include_tx_power) { + cmd.props = BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR; + } else { + cmd.props = 0; } - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS), buf, - sizeof(buf)); + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } static int @@ -3292,7 +3496,7 @@ ble_gap_periodic_adv_configure(uint8_t instance, int ble_gap_periodic_adv_start(uint8_t instance) { - uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN]; + struct ble_hci_le_set_periodic_adv_enable_cp cmd; uint16_t opcode; int rc; @@ -3308,16 +3512,12 @@ ble_gap_periodic_adv_start(uint8_t instance) return BLE_HS_EINVAL; } - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE); - rc = ble_hs_hci_cmd_build_le_periodic_adv_enable(1, instance, buf, - sizeof(buf)); - if (rc != 0) { - ble_hs_unlock(); - return rc; - } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + cmd.enable = 0x01; + cmd.adv_handle = instance; + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { ble_hs_unlock(); return rc; @@ -3330,57 +3530,51 @@ ble_gap_periodic_adv_start(uint8_t instance) } static int -ble_gap_periodic_adv_set(uint8_t instance, uint16_t opcode, - struct os_mbuf **data) +ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) { /* In that case we always fit all data in single HCI command */ #if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN - - static uint8_t buf[BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + + static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; + struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; uint16_t len = OS_MBUF_PKTLEN(*data); - int rc; + uint16_t opcode; - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode); + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA); - rc = ble_hs_hci_cmd_build_le_periodic_adv_data( - instance, - BLE_HCI_LE_SET_DATA_OPER_COMPLETE, - *data, len, - buf, sizeof(buf)); + cmd->adv_handle = instance; + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); - if (rc) { - return rc; - } - - os_mbuf_adj(*data, MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)); + os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); #else - static uint8_t buf[BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + + static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN]; + struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; uint16_t len = OS_MBUF_PKTLEN(*data); + uint16_t opcode; uint8_t op; int rc; - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode); + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA); + cmd->adv_handle = instance; /* Complete data */ if (len <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN) { - rc = ble_hs_hci_cmd_build_le_periodic_adv_data(instance, - BLE_HCI_LE_SET_DATA_OPER_COMPLETE, *data, len, buf, - sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); } /* If the periodic advertising is already enabled, the periodic advertising @@ -3395,16 +3589,16 @@ ble_gap_periodic_adv_set(uint8_t instance, uint16_t opcode, op = BLE_HCI_LE_SET_DATA_OPER_FIRST; do{ - rc = ble_hs_hci_cmd_build_le_periodic_adv_data(instance, op, *data, - BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN, buf, sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = op; + cmd->adv_data_len = BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN; + os_mbuf_copydata(*data, 0, BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN, + cmd->adv_data); os_mbuf_adj(*data, BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN); *data = os_mbuf_trim_front(*data); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); if (rc) { return rc; } @@ -3414,19 +3608,15 @@ ble_gap_periodic_adv_set(uint8_t instance, uint16_t opcode, } while (len > BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN); /* Last fragment */ - rc = ble_hs_hci_cmd_build_le_periodic_adv_data( - instance, - BLE_HCI_LE_SET_DATA_OPER_LAST, - *data, len, buf, sizeof(buf)); - if (rc) { - return rc; - } + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_LAST; + cmd->adv_data_len = len; + os_mbuf_copydata(*data, 0, len, cmd->adv_data); os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, - BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN + len); + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); #endif } @@ -3469,8 +3659,7 @@ ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } - rc = ble_gap_periodic_adv_set(instance, - BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA, &data); + rc = ble_gap_periodic_adv_set(instance, &data); ble_hs_unlock(); @@ -3482,18 +3671,16 @@ done: static int ble_gap_periodic_adv_stop_no_lock(uint8_t instance) { - uint8_t buf[BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN]; + struct ble_hci_le_set_periodic_adv_enable_cp cmd; uint16_t opcode; int rc; + cmd.enable = 0x00; + cmd.adv_handle = instance; + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE); - rc = ble_hs_hci_cmd_build_le_periodic_adv_enable(0, instance, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { return rc; } @@ -3548,14 +3735,25 @@ ble_gap_npl_sync_lost(struct ble_npl_event *ev) } int -ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, +ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, const struct ble_gap_periodic_sync_params *params, ble_gap_event_fn *cb, void *cb_arg) { - uint8_t buf[BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN]; + struct ble_hci_le_periodic_adv_create_sync_cp cmd; struct ble_hs_periodic_sync *psync; uint16_t opcode; - int rc = 0; + int rc; + + if (addr && (addr->type > BLE_ADDR_RANDOM)) { + return BLE_HS_EINVAL; + } + if (adv_sid > 0x0f) { + return BLE_HS_EINVAL; + } + if ((params->skip > 0x1f3) || (params->sync_timeout > 0x4000) || + (params->sync_timeout < 0x0A)) { + return BLE_HS_EINVAL; + } ble_hs_lock(); @@ -3581,24 +3779,22 @@ ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, ble_npl_event_init(&psync->lost_ev, ble_gap_npl_sync_lost, psync); if (addr) { - rc = ble_hs_hci_cmd_build_le_periodic_adv_create_sync(0x00, adv_sid, - addr->type, addr->val, params->skip, - params->sync_timeout, buf, sizeof(buf)); + cmd.options = 0x00; + cmd.peer_addr_type = addr->type; + memcpy(cmd.peer_addr, addr->val, BLE_DEV_ADDR_LEN); } else { - rc = ble_hs_hci_cmd_build_le_periodic_adv_create_sync(0x01, adv_sid, - BLE_ADDR_ANY->type, BLE_ADDR_ANY->val, params->skip, - params->sync_timeout, buf, sizeof(buf)); + cmd.options = 0x01; + cmd.peer_addr_type = BLE_ADDR_ANY->type; + memcpy(cmd.peer_addr, BLE_ADDR_ANY->val, BLE_DEV_ADDR_LEN); } - if (rc != 0) { - ble_hs_periodic_sync_free(psync); - ble_hs_unlock(); - return rc; - } + cmd.sid = adv_sid; + cmd.skip = params->skip; + cmd.sync_timeout = htole16(params->sync_timeout); + cmd.sync_cte_type = 0x00; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); - + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); if (!rc) { /* This shall be reset upon receiving sync_established event, * or if the sync is cancelled before receiving that event. @@ -3617,7 +3813,7 @@ ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, } int -ble_gap_periodic_adv_create_sync_cancel(void) +ble_gap_periodic_adv_sync_create_cancel(void) { uint16_t opcode; int rc = 0; @@ -3632,15 +3828,7 @@ ble_gap_periodic_adv_create_sync_cancel(void) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, NULL, 0); - - if (!rc) { - ble_gap_sync.op = BLE_GAP_OP_NULL; - ble_gap_sync.cb = NULL; - ble_gap_sync.cb_arg = NULL; - ble_hs_periodic_sync_free(ble_gap_sync.psync); - ble_gap_sync.psync = NULL; - } + rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, NULL, 0); ble_hs_unlock(); @@ -3648,12 +3836,12 @@ ble_gap_periodic_adv_create_sync_cancel(void) } int -ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle) +ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle) { - uint8_t buf[BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN]; - uint16_t opcode; + struct ble_hci_le_periodic_adv_term_sync_cp cmd; struct ble_hs_periodic_sync *psync; - int rc = 0; + uint16_t opcode; + int rc; ble_hs_lock(); @@ -3675,15 +3863,9 @@ ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC); - rc = ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(sync_handle, - buf, sizeof(buf)); - if (rc != 0) { - ble_hs_unlock(); - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + cmd.sync_handle = htole16(sync_handle); + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); if (rc == 0) { /* Remove the handle from the list */ ble_hs_periodic_sync_remove(psync); @@ -3698,52 +3880,245 @@ ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle) return rc; } - +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) int -ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr, - uint8_t adv_sid) +ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable) { - uint8_t buf[BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN]; + struct ble_hci_le_periodic_adv_receive_enable_cp cmd; + struct ble_hs_periodic_sync *psync; uint16_t opcode; - int rc = 0; + int rc; - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST); + ble_hs_lock(); - rc = ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(peer_addr->type, - peer_addr->val, - adv_sid, buf, - sizeof(buf)); - if (rc != 0) { - return rc; + if (ble_gap_sync.op == BLE_GAP_OP_SYNC) { + ble_hs_unlock(); + return BLE_HS_EBUSY; } - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); + psync = ble_hs_periodic_sync_find_by_handle(sync_handle); + if (!psync) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_RECEIVE_ENABLE); + + cmd.sync_handle = htole16(sync_handle); + cmd.enable = enable ? 0x01 : 0x00; + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); + + ble_hs_unlock(); return rc; } +int +ble_gap_periodic_adv_sync_transfer(uint16_t sync_handle, uint16_t conn_handle, + uint16_t service_data) +{ + struct ble_hci_le_periodic_adv_sync_transfer_cp cmd; + struct ble_hci_le_periodic_adv_sync_transfer_rp rsp; + struct ble_hs_periodic_sync *psync; + struct ble_hs_conn *conn; + uint16_t opcode; + int rc; + + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + psync = ble_hs_periodic_sync_find_by_handle(sync_handle); + if (!psync) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER); + + cmd.conn_handle = htole16(conn_handle); + cmd.sync_handle = htole16(sync_handle); + cmd.service_data = htole16(service_data); + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + if (!rc) { + BLE_HS_DBG_ASSERT(le16toh(rsp.conn_handle) == conn_handle); + } + + ble_hs_unlock(); + + return rc; +} + +int +ble_gap_periodic_adv_sync_set_info(uint8_t instance, uint16_t conn_handle, + uint16_t service_data) +{ + struct ble_hci_le_periodic_adv_set_info_transfer_cp cmd; + struct ble_hci_le_periodic_adv_set_info_transfer_rp rsp; + struct ble_hs_conn *conn; + uint16_t opcode; + int rc; + + if (instance >= BLE_ADV_INSTANCES) { + return BLE_HS_EINVAL; + } + + ble_hs_lock(); + if (ble_gap_slave[instance].periodic_op != BLE_GAP_OP_S_PERIODIC_ADV) { + /* periodic adv not enabled */ + ble_hs_unlock(); + return BLE_HS_EINVAL; + } + + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SET_INFO_TRANSFER); + + cmd.conn_handle = htole16(conn_handle); + cmd.adv_handle = instance; + cmd.service_data = htole16(service_data); + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + if (!rc) { + BLE_HS_DBG_ASSERT(le16toh(rsp.conn_handle) == conn_handle); + } + + ble_hs_unlock(); + + return rc; +} + +static int +periodic_adv_transfer_enable(uint16_t conn_handle, + const struct ble_gap_periodic_sync_params *params) +{ + struct ble_hci_le_periodic_adv_sync_transfer_params_cp cmd; + struct ble_hci_le_periodic_adv_sync_transfer_params_rp rsp; + uint16_t opcode; + int rc; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS); + + cmd.conn_handle = htole16(conn_handle); + cmd.sync_cte_type = 0x00; + cmd.mode = params->reports_disabled ? 0x01 : 0x02; + cmd.skip = htole16(params->skip); + cmd.sync_timeout = htole16(params->sync_timeout); + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + if (!rc) { + BLE_HS_DBG_ASSERT(le16toh(rsp.conn_handle) == conn_handle); + } + + return rc; +} + +int +ble_gap_periodic_adv_sync_receive(uint16_t conn_handle, + const struct ble_gap_periodic_sync_params *params, + ble_gap_event_fn *cb, void *cb_arg) +{ + struct ble_hs_conn *conn; + int rc; + + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + if (params) { + if (conn->psync) { + ble_hs_unlock(); + return BLE_HS_EALREADY; + } + + conn->psync = ble_hs_periodic_sync_alloc(); + if (!conn->psync) { + ble_hs_unlock(); + return BLE_HS_ENOMEM; + } + + rc = periodic_adv_transfer_enable(conn_handle, params); + if (rc) { + ble_hs_periodic_sync_free(conn->psync); + conn->psync = NULL; + } else { + conn->psync->cb = cb; + conn->psync->cb_arg = cb_arg; + ble_npl_event_init(&conn->psync->lost_ev, ble_gap_npl_sync_lost, + conn->psync); + } + } else { + if (!conn->psync) { + ble_hs_unlock(); + return BLE_HS_EALREADY; + } + + rc = periodic_adv_transfer_disable(conn_handle); + if (!rc) { + ble_hs_periodic_sync_free(conn->psync); + conn->psync = NULL; + } + } + + ble_hs_unlock(); + + return rc; +} +#endif + +int +ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr, + uint8_t adv_sid) +{ + struct ble_hci_le_add_dev_to_periodic_adv_list_cp cmd; + uint16_t opcode; + + if ((peer_addr->type > BLE_ADDR_RANDOM) || (adv_sid > 0x0f)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd.peer_addr_type = peer_addr->type; + memcpy(cmd.peer_addr, peer_addr->val, BLE_DEV_ADDR_LEN); + cmd.sid = adv_sid; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST); + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} + int ble_gap_rem_dev_from_periodic_adv_list(const ble_addr_t *peer_addr, uint8_t adv_sid) { - uint8_t buf[BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN]; + struct ble_hci_le_rem_dev_from_periodic_adv_list_cp cmd; uint16_t opcode; - int rc = 0; + + if ((peer_addr->type > BLE_ADDR_RANDOM) || (adv_sid > 0x0f)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd.peer_addr_type = peer_addr->type; + memcpy(cmd.peer_addr, peer_addr->val, BLE_DEV_ADDR_LEN); + cmd.sid = adv_sid; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST); - rc = ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(peer_addr->type, - peer_addr->val, - adv_sid, buf, - sizeof(buf)); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf)); - - return rc; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } int @@ -3754,7 +4129,7 @@ ble_gap_clear_periodic_adv_list(void) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST); - rc = ble_hs_hci_cmd_tx_empty_ack(opcode, NULL, 0); + rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, NULL, 0); return rc; } @@ -3762,23 +4137,18 @@ ble_gap_clear_periodic_adv_list(void) int ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size) { - uint8_t rspbuf[1]; - uint8_t rsplen; + struct ble_hci_le_rd_periodic_adv_list_size_rp rsp; uint16_t opcode; int rc = 0; opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE); - rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, rspbuf, sizeof(rspbuf), &rsplen); + rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (rsplen != sizeof(rspbuf)) { - return BLE_HS_ECONTROLLER; - } - - *per_adv_list_size = rspbuf[0]; + *per_adv_list_size = rsp.list_size; return 0; } @@ -3794,58 +4164,73 @@ ble_gap_ext_disc_tx_params(uint8_t own_addr_type, uint8_t filter_policy, const struct ble_hs_hci_ext_scan_param *uncoded_params, const struct ble_hs_hci_ext_scan_param *coded_params) { - uint8_t buf[BLE_HCI_LE_EXT_SCAN_BASE_LEN + - 2 * BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN]; - uint8_t phy_mask = 0; - struct ble_hs_hci_ext_scan_param param[2] = {{0}}; - struct ble_hs_hci_ext_scan_param *p = param; - int phy_count = 0; - uint8_t len; - int rc; + struct ble_hci_le_set_ext_scan_params_cp *cmd; + struct scan_params *params; + uint8_t buf[sizeof(*cmd) + 2 * sizeof(*params)]; + uint8_t len = sizeof(*cmd); + + /* Check own addr type */ + if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check scanner filter policy */ + if (filter_policy > BLE_HCI_SCAN_FILT_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd = (void *) buf; + params = cmd->scans; + + cmd->filter_policy = filter_policy; + cmd->own_addr_type = own_addr_type; + cmd->phys = 0; if (uncoded_params) { - phy_mask |= BLE_HCI_LE_PHY_1M_PREF_MASK; - memcpy(¶m[phy_count], uncoded_params, sizeof(*uncoded_params)); - phy_count++; + cmd->phys |= BLE_HCI_LE_PHY_1M_PREF_MASK; + + params->type = uncoded_params->scan_type; + params->itvl = htole16(uncoded_params->scan_itvl); + params->window = htole16(uncoded_params->scan_window); + + len += sizeof(*params); + params++; } if (coded_params) { - phy_mask |= BLE_HCI_LE_PHY_CODED_PREF_MASK; - memcpy(¶m[phy_count], coded_params, sizeof(*coded_params)); - phy_count++; + cmd->phys |= BLE_HCI_LE_PHY_CODED_PREF_MASK; + + params->type = coded_params->scan_type; + params->itvl = htole16(coded_params->scan_itvl); + params->window = htole16(coded_params->scan_window); + + len += sizeof(*params); + params++; } - rc = ble_hs_hci_cmd_build_le_set_ext_scan_params(own_addr_type, - filter_policy, - phy_mask, - phy_count, - &p, buf, sizeof(buf)); - - if (rc != 0) { - return BLE_HS_EINVAL; + if (!cmd->phys) { + return BLE_ERR_INV_HCI_CMD_PARMS; } - len = BLE_HCI_LE_EXT_SCAN_BASE_LEN + - BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN * phy_count; - - return ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM), - buf, len); + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM), + cmd, len, NULL, 0); } static int ble_gap_ext_disc_enable_tx(uint8_t enable, uint8_t filter_duplicates, uint16_t duration, uint16_t period) { - uint8_t buf[BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN]; + struct ble_hci_le_set_ext_scan_enable_cp cmd; - ble_hs_hci_cmd_build_le_set_ext_scan_enable(enable, filter_duplicates, - duration, period, - buf, sizeof buf); + cmd.enable = enable; + cmd.filter_dup = filter_duplicates; + cmd.duration = htole16(duration); + cmd.period = htole16(period); - return ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE), - buf, sizeof(buf)); + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE), + &cmd, sizeof(cmd), NULL, 0); } #endif #endif @@ -3854,53 +4239,38 @@ ble_gap_ext_disc_enable_tx(uint8_t enable, uint8_t filter_duplicates, static int ble_gap_disc_enable_tx(int enable, int filter_duplicates) { - uint8_t buf[BLE_HCI_SET_SCAN_ENABLE_LEN]; - int rc; + struct ble_hci_le_set_scan_enable_cp cmd; + uint16_t opcode; - ble_hs_hci_cmd_build_le_set_scan_enable(!!enable, !!filter_duplicates, - buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_ENABLE), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + cmd.enable = !!enable; + cmd.filter_duplicates = !!filter_duplicates; - return 0; + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_ENABLE); + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } static int ble_gap_disc_tx_params(uint8_t own_addr_type, const struct ble_gap_disc_params *disc_params) { - uint8_t buf[BLE_HCI_SET_SCAN_PARAM_LEN]; - uint8_t scan_type; - int rc; + struct ble_hci_le_set_scan_params_cp cmd; + uint16_t opcode; if (disc_params->passive) { - scan_type = BLE_HCI_SCAN_TYPE_PASSIVE; + cmd.scan_type = BLE_HCI_SCAN_TYPE_PASSIVE; } else { - scan_type = BLE_HCI_SCAN_TYPE_ACTIVE; + cmd.scan_type = BLE_HCI_SCAN_TYPE_ACTIVE; } - rc = ble_hs_hci_cmd_build_le_set_scan_params(scan_type, - disc_params->itvl, - disc_params->window, - own_addr_type, - disc_params->filter_policy, - buf, sizeof buf); - if (rc != 0) { - return BLE_HS_EINVAL; - } + cmd.scan_itvl = htole16(disc_params->itvl); + cmd.scan_window = htole16(disc_params->window); + cmd.own_addr_type = own_addr_type; + cmd.filter_policy = disc_params->filter_policy; - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_PARAMS), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_PARAMS); - return 0; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } #endif @@ -3945,10 +4315,7 @@ done: int ble_gap_disc_cancel(void) { -#if !NIMBLE_BLE_SCAN - return BLE_HS_ENOTSUP; -#else - +#if NIMBLE_BLE_SCAN int rc; ble_hs_lock(); @@ -3956,6 +4323,8 @@ ble_gap_disc_cancel(void) ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; #endif } @@ -4035,10 +4404,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, const struct ble_gap_ext_disc_params *coded_params, ble_gap_event_fn *cb, void *cb_arg) { -#if !NIMBLE_BLE_SCAN || !MYNEWT_VAL(BLE_EXT_ADV) - return BLE_HS_ENOTSUP; -#else - +#if NIMBLE_BLE_SCAN && MYNEWT_VAL(BLE_EXT_ADV) struct ble_hs_hci_ext_scan_param ucp; struct ble_hs_hci_ext_scan_param cp; int rc; @@ -4110,6 +4476,8 @@ done: STATS_INC(ble_gap_stats, discover_fail); } return rc; +#else + return BLE_HS_ENOTSUP; #endif } @@ -4142,6 +4510,20 @@ ble_gap_disc_validate(uint8_t own_addr_type, return BLE_HS_EINVAL; } + /* Check interval and window */ + if ((disc_params->itvl < BLE_HCI_SCAN_ITVL_MIN) || + (disc_params->itvl > BLE_HCI_SCAN_ITVL_MAX) || + (disc_params->window < BLE_HCI_SCAN_WINDOW_MIN) || + (disc_params->window > BLE_HCI_SCAN_WINDOW_MAX) || + (disc_params->itvl < disc_params->window)) { + return BLE_HS_EINVAL; + } + + /* Check scanner filter policy */ + if (disc_params->filter_policy > BLE_HCI_SCAN_FILT_MAX) { + return BLE_HS_EINVAL; + } + return ble_gap_disc_ext_validate(own_addr_type); } #endif @@ -4151,10 +4533,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, const struct ble_gap_disc_params *disc_params, ble_gap_event_fn *cb, void *cb_arg) { -#if !NIMBLE_BLE_SCAN - return BLE_HS_ENOTSUP; -#else - +#if NIMBLE_BLE_SCAN #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params p = {0}; @@ -4162,6 +4541,12 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, p.passive = disc_params->passive; p.window = disc_params->window; + if (duration_ms == BLE_HS_FOREVER) { + duration_ms = 0; + } else if (duration_ms == 0) { + duration_ms = BLE_GAP_DISC_DUR_DFLT; + } + return ble_gap_ext_disc(own_addr_type, duration_ms/10, 0, disc_params->filter_duplicates, disc_params->filter_policy, disc_params->limited, @@ -4241,6 +4626,8 @@ done: } return rc; #endif +#else + return BLE_HS_ENOTSUP; #endif } @@ -4251,7 +4638,7 @@ ble_gap_disc_active(void) return ble_gap_master.op == BLE_GAP_OP_M_DISC; } -#if !MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) && !MYNEWT_VAL(BLE_EXT_ADV) /***************************************************************************** * $connection establishment procedures * *****************************************************************************/ @@ -4260,64 +4647,84 @@ static int ble_gap_conn_create_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *params) { - uint8_t buf[BLE_HCI_CREATE_CONN_LEN]; - struct hci_create_conn hcc; - int rc; - - hcc.scan_itvl = params->scan_itvl; - hcc.scan_window = params->scan_window; + struct ble_hci_le_create_conn_cp cmd; + uint16_t opcode; + cmd.scan_itvl = htole16(params->scan_itvl); + cmd.scan_window = htole16(params->scan_window); if (peer_addr == NULL) { /* Application wants to connect to any device in the white list. The * peer address type and peer address fields are ignored by the * controller; fill them with dummy values. */ - hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL; - hcc.peer_addr_type = 0; - memset(hcc.peer_addr, 0, sizeof hcc.peer_addr); + cmd.filter_policy = BLE_HCI_CONN_FILT_USE_WL; + cmd.peer_addr_type = 0; + memset(cmd.peer_addr, 0, sizeof(cmd.peer_addr)); } else { - hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL; - hcc.peer_addr_type = peer_addr->type; - memcpy(hcc.peer_addr, peer_addr->val, sizeof hcc.peer_addr); + cmd.filter_policy = BLE_HCI_CONN_FILT_NO_WL; + cmd.peer_addr_type = peer_addr->type; + memcpy(cmd.peer_addr, peer_addr->val, sizeof(cmd.peer_addr)); } - hcc.own_addr_type = own_addr_type; - hcc.conn_itvl_min = params->itvl_min; - hcc.conn_itvl_max = params->itvl_max; - hcc.conn_latency = params->latency; - hcc.supervision_timeout = params->supervision_timeout; - hcc.min_ce_len = params->min_ce_len; - hcc.max_ce_len = params->max_ce_len; + cmd.own_addr_type = own_addr_type; + cmd.min_conn_itvl = htole16(params->itvl_min); + cmd.max_conn_itvl = htole16(params->itvl_max); + cmd.conn_latency = htole16(params->latency); + cmd.tmo = htole16(params->supervision_timeout); + cmd.min_ce = htole16(params->min_ce_len); + cmd.max_ce = htole16(params->max_ce_len); - rc = ble_hs_hci_cmd_build_le_create_connection(&hcc, buf, sizeof buf); - if (rc != 0) { - return BLE_HS_EUNKNOWN; - } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CREATE_CONN); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CREATE_CONN), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } #endif #if MYNEWT_VAL(BLE_EXT_ADV) -static void -ble_gap_copy_params(struct hci_ext_conn_params *hcc_params, - const struct ble_gap_conn_params *gap_params) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) +static int +ble_gap_check_conn_params(uint8_t phy, const struct ble_gap_conn_params *params) { - hcc_params->scan_itvl = gap_params->scan_itvl; - hcc_params->scan_window = gap_params->scan_window; - hcc_params->conn_itvl_max = gap_params->itvl_max; - hcc_params->conn_itvl_min = gap_params->itvl_min; - hcc_params->max_ce_len = gap_params->max_ce_len; - hcc_params->min_ce_len = gap_params->min_ce_len; - hcc_params->conn_latency = gap_params->latency; - hcc_params->supervision_timeout = gap_params->supervision_timeout; + if (phy != BLE_HCI_LE_PHY_2M) { + /* Check scan interval and window */ + if ((params->scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || + (params->scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || + (params->scan_window < BLE_HCI_SCAN_WINDOW_MIN) || + (params->scan_window > BLE_HCI_SCAN_WINDOW_MAX) || + (params->scan_itvl < params->scan_window)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } + /* Check connection interval min */ + if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + /* Check connection interval max */ + if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || + (params->itvl_max < params->itvl_min)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection latency */ + if ((params->latency < BLE_HCI_CONN_LATENCY_MIN) || + (params->latency > BLE_HCI_CONN_LATENCY_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check supervision timeout */ + if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection event length */ + if (params->min_ce_len > params->max_ce_len) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + return 0; } static int @@ -4327,57 +4734,110 @@ ble_gap_ext_conn_create_tx( const struct ble_gap_conn_params *phy_2m_conn_params, const struct ble_gap_conn_params *phy_coded_conn_params) { - uint8_t buf[sizeof(struct hci_ext_create_conn)]; - struct hci_ext_create_conn hcc = {0}; + struct ble_hci_le_ext_create_conn_cp *cmd; + struct conn_params *params; + uint8_t buf[sizeof(*cmd) + 3 * sizeof(*params)]; + uint8_t len = sizeof(*cmd); int rc; + /* Check own addr type */ + if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (phy_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd = (void *) buf; + params = cmd->conn_params; + if (peer_addr == NULL) { /* Application wants to connect to any device in the white list. The * peer address type and peer address fields are ignored by the * controller; fill them with dummy values. */ - hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL; - hcc.peer_addr_type = 0; - memset(hcc.peer_addr, 0, sizeof hcc.peer_addr); + cmd->filter_policy = BLE_HCI_CONN_FILT_USE_WL; + cmd->peer_addr_type = 0; + memset(cmd->peer_addr, 0, sizeof(cmd->peer_addr)); } else { - hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL; - hcc.peer_addr_type = peer_addr->type;; - memcpy(hcc.peer_addr, peer_addr->val, sizeof hcc.peer_addr); + /* Check peer addr type */ + if (peer_addr->type > BLE_HCI_CONN_PEER_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd->filter_policy = BLE_HCI_CONN_FILT_NO_WL; + cmd->peer_addr_type = peer_addr->type; + memcpy(cmd->peer_addr, peer_addr->val, sizeof(cmd->peer_addr)); } - hcc.own_addr_type = own_addr_type; - - hcc.init_phy_mask = phy_mask; + cmd->own_addr_type = own_addr_type; + cmd->init_phy_mask = phy_mask; if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { - /* XXX same structs */ - ble_gap_copy_params(&hcc.params[0], phy_1m_conn_params); + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_1M, phy_1m_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_1m_conn_params->scan_itvl); + params->scan_window = htole16(phy_1m_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_1m_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_1m_conn_params->itvl_max); + params->conn_latency = htole16(phy_1m_conn_params->latency); + params->supervision_timeout = htole16(phy_1m_conn_params->supervision_timeout); + params->min_ce = htole16(phy_1m_conn_params->min_ce_len); + params->max_ce = htole16(phy_1m_conn_params->max_ce_len); + + params++; + len += sizeof(*params); } if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { - /* XXX same structs */ - ble_gap_copy_params(&hcc.params[1], phy_2m_conn_params); + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_2M, phy_2m_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_2m_conn_params->scan_itvl); + params->scan_window = htole16(phy_2m_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_2m_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_2m_conn_params->itvl_max); + params->conn_latency = htole16(phy_2m_conn_params->latency); + params->supervision_timeout = htole16(phy_2m_conn_params->supervision_timeout); + params->min_ce = htole16(phy_2m_conn_params->min_ce_len); + params->max_ce = htole16(phy_2m_conn_params->max_ce_len); + + params++; + len += sizeof(*params); } if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { - /* XXX same structs */ - ble_gap_copy_params(&hcc.params[2], phy_coded_conn_params); + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_CODED, phy_coded_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_coded_conn_params->scan_itvl); + params->scan_window = htole16(phy_coded_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_coded_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_coded_conn_params->itvl_max); + params->conn_latency = htole16(phy_coded_conn_params->latency); + params->supervision_timeout = htole16(phy_coded_conn_params->supervision_timeout); + params->min_ce = htole16(phy_coded_conn_params->min_ce_len); + params->max_ce = htole16(phy_coded_conn_params->max_ce_len); + + params++; + len += sizeof(*params); } - rc = ble_hs_hci_cmd_build_le_ext_create_conn(&hcc, buf, sizeof buf); - if (rc != 0) { - return BLE_HS_EUNKNOWN; - } - - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_EXT_CREATE_CONN), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_EXT_CREATE_CONN), + cmd, len, NULL, 0); } +#endif /** * Initiates a connect procedure. @@ -4438,10 +4898,7 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *phy_coded_conn_params, ble_gap_event_fn *cb, void *cb_arg) { -#if !MYNEWT_VAL(BLE_ROLE_CENTRAL) - return BLE_HS_ENOTSUP; -#endif - +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) ble_npl_time_t duration_ticks; int rc; @@ -4551,6 +5008,10 @@ done: STATS_INC(ble_gap_stats, initiate_fail); } return rc; +#else + return BLE_HS_ENOTSUP; +#endif + } #endif @@ -4560,10 +5021,7 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *conn_params, ble_gap_event_fn *cb, void *cb_arg) { -#if !MYNEWT_VAL(BLE_ROLE_CENTRAL) - return BLE_HS_ENOTSUP; -#endif - +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) #if MYNEWT_VAL(BLE_EXT_ADV) return ble_gap_ext_connect(own_addr_type, peer_addr, duration_ms, BLE_GAP_LE_PHY_1M_MASK, @@ -4652,6 +5110,31 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, ble_gap_master.op = BLE_GAP_OP_M_CONN; +#if CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT + /* ble_gap_connect_reattempt save the connection parameters */ + if ((cb_arg != NULL) && conn_cookie_enabled) { + struct ble_gap_conn_desc *conn_desc = cb_arg; + /* reattempt_idx should follow conn handle corresponding to MASTER role */ + reattempt_idx = conn_desc->conn_handle; + /* Reset cookie_enabled flag, it will be set again by reattempt call */ + conn_cookie_enabled = false; + } + + ble_conn_reattempt[reattempt_idx].own_addr_type = own_addr_type; + memcpy(&ble_conn_reattempt[reattempt_idx].peer_addr, peer_addr, + sizeof(ble_addr_t)); + ble_conn_reattempt[reattempt_idx].duration_ms = duration_ms; + memcpy(&ble_conn_reattempt[reattempt_idx].conn_params, + conn_params, + sizeof(struct ble_gap_conn_params)); + ble_conn_reattempt[reattempt_idx].cb = cb; + ble_conn_reattempt[reattempt_idx].cb_arg = cb_arg; + /* reattempt_idx need to be within limits. This may end up being unnecessary + * operation. However, it is better to be sure as it can get tricky with + * multiple connections and client + server roles XXX*/ + reattempt_idx = (reattempt_idx + 1) % MYNEWT_VAL(BLE_MAX_CONNECTIONS); +#endif + rc = ble_gap_conn_create_tx(own_addr_type, peer_addr, conn_params); if (rc != 0) { @@ -4673,6 +5156,10 @@ done: } return rc; #endif +#else + return BLE_HS_ENOTSUP; +#endif + } int @@ -4685,11 +5172,38 @@ ble_gap_conn_active(void) /***************************************************************************** * $terminate connection procedure * *****************************************************************************/ +int +ble_gap_terminate_with_conn(struct ble_hs_conn *conn, uint8_t hci_reason) +{ + struct ble_hci_lc_disconnect_cp cmd; + int rc; + + BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); + if (conn->bhc_flags & BLE_HS_CONN_F_TERMINATING) { + return BLE_HS_EALREADY; + } + + BLE_HS_LOG(INFO, "GAP procedure initiated: terminate connection; " + "conn_handle=%d hci_reason=%d\n", + conn->bhc_handle, hci_reason); + + cmd.conn_handle = htole16(conn->bhc_handle); + cmd.reason = hci_reason; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, + BLE_HCI_OCF_DISCONNECT_CMD), + &cmd, sizeof(cmd), NULL, 0); + if (rc != 0) { + return rc; + } + + conn->bhc_flags |= BLE_HS_CONN_F_TERMINATING; + return 0; +} int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason) { - uint8_t buf[BLE_HCI_DISCONNECT_CMD_LEN]; struct ble_hs_conn *conn; int rc; @@ -4703,26 +5217,7 @@ ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason) goto done; } - if (conn->bhc_flags & BLE_HS_CONN_F_TERMINATING) { - rc = BLE_HS_EALREADY; - goto done; - } - - BLE_HS_LOG(INFO, "GAP procedure initiated: terminate connection; " - "conn_handle=%d hci_reason=%d\n", - conn_handle, hci_reason); - - ble_hs_hci_cmd_build_disconnect(conn_handle, hci_reason, - buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, - BLE_HCI_OCF_DISCONNECT_CMD), - buf, sizeof(buf)); - if (rc != 0) { - goto done; - } - - conn->bhc_flags |= BLE_HS_CONN_F_TERMINATING; - rc = 0; + rc = ble_gap_terminate_with_conn(conn, hci_reason); done: ble_hs_unlock(); @@ -4742,9 +5237,9 @@ ble_gap_conn_cancel_tx(void) { int rc; - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CREATE_CONN_CANCEL), - NULL, 0); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CREATE_CONN_CANCEL), + NULL, 0, NULL, 0); if (rc != 0) { return rc; } @@ -4752,13 +5247,10 @@ ble_gap_conn_cancel_tx(void) return 0; } +#if NIMBLE_BLE_CONNECT static int ble_gap_conn_cancel_no_lock(void) { -#if !MYNEWT_VAL(BLE_ROLE_CENTRAL) - return BLE_HS_ENOTSUP; -#endif - int rc; STATS_INC(ble_gap_stats, cancel); @@ -4785,14 +5277,12 @@ done: return rc; } +#endif int ble_gap_conn_cancel(void) { -#if !MYNEWT_VAL(BLE_ROLE_CENTRAL) - return BLE_HS_ENOTSUP; -#endif - +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) int rc; ble_hs_lock(); @@ -4800,12 +5290,17 @@ ble_gap_conn_cancel(void) ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; +#endif + } /***************************************************************************** * $update connection parameters * *****************************************************************************/ +#if NIMBLE_BLE_CONNECT static struct ble_gap_update_entry * ble_gap_update_entry_alloc(void) { @@ -4818,6 +5313,7 @@ ble_gap_update_entry_alloc(void) return entry; } +#endif static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry) @@ -4877,6 +5373,7 @@ ble_gap_update_entry_remove(uint16_t conn_handle) return entry; } +#if NIMBLE_BLE_CONNECT static void ble_gap_update_l2cap_cb(uint16_t conn_handle, int status, void *arg) { @@ -4903,71 +5400,51 @@ static int ble_gap_tx_param_pos_reply(uint16_t conn_handle, struct ble_gap_upd_params *params) { - uint8_t buf[BLE_HCI_CONN_PARAM_REPLY_LEN]; - struct hci_conn_param_reply pos_reply; - int rc; + struct ble_hci_le_rem_conn_param_rr_cp cmd; - pos_reply.handle = conn_handle; - pos_reply.conn_itvl_min = params->itvl_min; - pos_reply.conn_itvl_max = params->itvl_max; - pos_reply.conn_latency = params->latency; - pos_reply.supervision_timeout = params->supervision_timeout; - pos_reply.min_ce_len = params->min_ce_len; - pos_reply.max_ce_len = params->max_ce_len; + cmd.conn_handle = htole16(conn_handle); + cmd.conn_itvl_min = htole16(params->itvl_min); + cmd.conn_itvl_max = htole16(params->itvl_max); + cmd.conn_latency = htole16(params->latency); + cmd.supervision_timeout = htole16(params->supervision_timeout); + cmd.min_ce = htole16(params->min_ce_len); + cmd.max_ce = htole16(params->max_ce_len); - ble_hs_hci_cmd_build_le_conn_param_reply(&pos_reply, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_RR), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_REM_CONN_PARAM_RR), + &cmd, sizeof(cmd), NULL, 0); } static int ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason) { - uint8_t buf[BLE_HCI_CONN_PARAM_NEG_REPLY_LEN]; - struct hci_conn_param_neg_reply neg_reply; - int rc; + struct ble_hci_le_rem_conn_params_nrr_cp cmd; - neg_reply.handle = conn_handle; - neg_reply.reason = reject_reason; + cmd.conn_handle = htole16(conn_handle); + cmd.reason = reject_reason; - ble_hs_hci_cmd_build_le_conn_param_neg_reply(&neg_reply, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR), + &cmd, sizeof(cmd), NULL, 0); } - -void -ble_gap_rx_param_req(struct hci_le_conn_param_req *evt) -{ -#if !NIMBLE_BLE_CONNECT - return; #endif +void +ble_gap_rx_param_req(const struct ble_hci_ev_le_subev_rem_conn_param_req *ev) +{ +#if NIMBLE_BLE_CONNECT struct ble_gap_upd_params peer_params; struct ble_gap_upd_params self_params; struct ble_gap_event event; - uint8_t reject_reason; + uint16_t conn_handle; int rc; - reject_reason = 0; /* Silence warning. */ - memset(&event, 0, sizeof event); - peer_params.itvl_min = evt->itvl_min; - peer_params.itvl_max = evt->itvl_max; - peer_params.latency = evt->latency; - peer_params.supervision_timeout = evt->timeout; + peer_params.itvl_min = le16toh(ev->min_interval); + peer_params.itvl_max = le16toh(ev->max_interval); + peer_params.latency = le16toh(ev->latency); + peer_params.supervision_timeout = le16toh(ev->timeout); peer_params.min_ce_len = 0; peer_params.max_ce_len = 0; @@ -4977,55 +5454,43 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt) */ self_params = peer_params; + conn_handle = le16toh(ev->conn_handle); + memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_CONN_UPDATE_REQ; - event.conn_update_req.conn_handle = evt->connection_handle; + event.conn_update_req.conn_handle = conn_handle; event.conn_update_req.self_params = &self_params; event.conn_update_req.peer_params = &peer_params; - rc = ble_gap_call_conn_event_cb(&event, evt->connection_handle); - if (rc != 0) { - reject_reason = rc; - } - + rc = ble_gap_call_conn_event_cb(&event, conn_handle); if (rc == 0) { - rc = ble_gap_tx_param_pos_reply(evt->connection_handle, &self_params); + rc = ble_gap_tx_param_pos_reply(conn_handle, &self_params); if (rc != 0) { - ble_gap_update_failed(evt->connection_handle, rc); + ble_gap_update_failed(conn_handle, rc); } } else { - ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason); + ble_gap_tx_param_neg_reply(conn_handle, rc); } +#endif } +#if NIMBLE_BLE_CONNECT static int ble_gap_update_tx(uint16_t conn_handle, const struct ble_gap_upd_params *params) { - uint8_t buf[BLE_HCI_CONN_UPDATE_LEN]; - struct hci_conn_update cmd; - int rc; + struct ble_hci_le_conn_update_cp cmd; - cmd.handle = conn_handle; - cmd.conn_itvl_min = params->itvl_min; - cmd.conn_itvl_max = params->itvl_max; - cmd.conn_latency = params->latency; - cmd.supervision_timeout = params->supervision_timeout; - cmd.min_ce_len = params->min_ce_len; - cmd.max_ce_len = params->max_ce_len; + cmd.conn_handle = htole16(conn_handle); + cmd.conn_itvl_min = htole16(params->itvl_min); + cmd.conn_itvl_max = htole16(params->itvl_max); + cmd.conn_latency = htole16(params->latency); + cmd.supervision_timeout = htole16(params->supervision_timeout); + cmd.min_ce_len = htole16(params->min_ce_len); + cmd.max_ce_len = htole16(params->max_ce_len); - rc = ble_hs_hci_cmd_build_le_conn_update(&cmd, buf, sizeof buf); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CONN_UPDATE), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CONN_UPDATE), + &cmd, sizeof(cmd), NULL, 0); } static bool @@ -5057,15 +5522,13 @@ ble_gap_validate_conn_params(const struct ble_gap_upd_params *params) return true; } +#endif int ble_gap_update_params(uint16_t conn_handle, const struct ble_gap_upd_params *params) { -#if !NIMBLE_BLE_CONNECT - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_CONNECT struct ble_l2cap_sig_update_params l2cap_params; struct ble_gap_update_entry *entry; struct ble_gap_update_entry *dup; @@ -5149,6 +5612,9 @@ done: ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } /***************************************************************************** @@ -5157,10 +5623,7 @@ done: int ble_gap_security_initiate(uint16_t conn_handle) { -#if !NIMBLE_BLE_SM - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_SM struct ble_store_value_sec value_sec; struct ble_store_key_sec key_sec; struct ble_hs_conn_addrs addrs; @@ -5221,6 +5684,9 @@ done: } return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int @@ -5241,10 +5707,7 @@ ble_gap_encryption_initiate(uint16_t conn_handle, uint64_t rand_val, int auth) { -#if !NIMBLE_BLE_SM - return BLE_HS_ENOTSUP; -#endif - +#if NIMBLE_BLE_SM ble_hs_conn_flags_t conn_flags; int rc; @@ -5260,6 +5723,9 @@ ble_gap_encryption_initiate(uint16_t conn_handle, rc = ble_sm_enc_initiate(conn_handle, key_size, ltk, ediv, rand_val, auth); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int @@ -5275,7 +5741,7 @@ ble_gap_unpair(const ble_addr_t *peer_addr) conn = ble_hs_conn_find_by_addr(peer_addr); if (conn != NULL) { - ble_gap_terminate(conn->bhc_handle, BLE_ERR_REM_USER_CONN_TERM); + ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM); } ble_hs_unlock(); @@ -5345,10 +5811,7 @@ void ble_gap_passkey_event(uint16_t conn_handle, struct ble_gap_passkey_params *passkey_params) { -#if !NIMBLE_BLE_SM - return; -#endif - +#if NIMBLE_BLE_SM struct ble_gap_event event; BLE_HS_LOG(DEBUG, "send passkey action request %d\n", @@ -5359,16 +5822,14 @@ ble_gap_passkey_event(uint16_t conn_handle, event.passkey.conn_handle = conn_handle; event.passkey.params = *passkey_params; ble_gap_call_conn_event_cb(&event, conn_handle); +#endif } void ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored, int bonded) { -#if !NIMBLE_BLE_SM - return; -#endif - +#if NIMBLE_BLE_SM struct ble_gap_event event; memset(&event, 0, sizeof event); @@ -5398,15 +5859,13 @@ ble_gap_enc_event(uint16_t conn_handle, int status, if (bonded) { ble_gatts_bonding_established(conn_handle); } +#endif } void ble_gap_identity_event(uint16_t conn_handle) { -#if !NIMBLE_BLE_SM - return; -#endif - +#if NIMBLE_BLE_SM struct ble_gap_event event; BLE_HS_LOG(DEBUG, "send identity changed"); @@ -5415,15 +5874,13 @@ ble_gap_identity_event(uint16_t conn_handle) event.type = BLE_GAP_EVENT_IDENTITY_RESOLVED; event.identity_resolved.conn_handle = conn_handle; ble_gap_call_conn_event_cb(&event, conn_handle); +#endif } int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp) { -#if !NIMBLE_BLE_SM - return 0; -#endif - +#if NIMBLE_BLE_SM struct ble_gap_event event; int rc; @@ -5432,6 +5889,9 @@ ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp) event.repeat_pairing = *rp; rc = ble_gap_call_conn_event_cb(&event, rp->conn_handle); return rc; +#else + return 0; +#endif } /***************************************************************************** @@ -5477,10 +5937,7 @@ void ble_gap_notify_tx_event(int status, uint16_t conn_handle, uint16_t attr_handle, int is_indication) { -#if !MYNEWT_VAL(BLE_GATT_NOTIFY) && !MYNEWT_VAL(BLE_GATT_INDICATE) - return; -#endif - +#if MYNEWT_VAL(BLE_GATT_NOTIFY) || MYNEWT_VAL(BLE_GATT_INDICATE) struct ble_gap_event event; memset(&event, 0, sizeof event); @@ -5489,7 +5946,9 @@ ble_gap_notify_tx_event(int status, uint16_t conn_handle, uint16_t attr_handle, event.notify_tx.status = status; event.notify_tx.attr_handle = attr_handle; event.notify_tx.indication = is_indication; + ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, conn_handle); +#endif } /***************************************************************************** diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h index 90c32e22a..2b6b40696 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h @@ -81,23 +81,40 @@ void ble_gap_rx_le_scan_timeout(void); #if MYNEWT_VAL(BLE_EXT_ADV) void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc); -void ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt); +void ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminated *ev); #if MYNEWT_VAL(BLE_PERIODIC_ADV) -void ble_gap_rx_peroidic_adv_sync_estab(struct hci_le_subev_periodic_adv_sync_estab *evt); -void ble_gap_rx_periodic_adv_rpt(struct hci_le_subev_periodic_adv_rpt *evt); -void ble_gap_rx_periodic_adv_sync_lost(struct hci_le_subev_periodic_adv_sync_lost *evt); +void ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev); +void ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_rpt *ev); +void ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev); +void ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev); #endif -void ble_gap_rx_scan_req_rcvd(struct hci_le_scan_req_rcvd *evt); +void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev); #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); -void ble_gap_rx_rd_rem_sup_feat_complete(struct hci_le_rd_rem_supp_feat_complete *evt); -int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance); -void ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt); -void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt); -void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt); +void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev); + +struct ble_gap_conn_complete +{ + uint8_t status; + uint16_t connection_handle; + uint8_t role; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t master_clk_acc; + uint8_t local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; +}; + +int ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance); +void ble_gap_rx_disconn_complete(const struct ble_hci_ev_disconn_cmp *ev); +void ble_gap_rx_update_complete(const struct ble_hci_ev_le_subev_conn_upd_complete *ev); +void ble_gap_rx_param_req(const struct ble_hci_ev_le_subev_rem_conn_param_req *ev); int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); -void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); +void ble_gap_rx_phy_update_complete(const struct ble_hci_ev_le_subev_phy_update_complete *ev); void ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored, int bonded); void ble_gap_passkey_event(uint16_t conn_handle, @@ -118,6 +135,7 @@ int ble_gap_master_in_progress(void); void ble_gap_preempt(void); void ble_gap_preempt_done(void); +int ble_gap_terminate_with_conn(struct ble_hs_conn *conn, uint8_t hci_reason); void ble_gap_conn_broken(uint16_t conn_handle, int reason); void ble_gap_reset_state(int reason); int32_t ble_gap_timer(void); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gattc.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gattc.c index c3ff060b0..a6e114cc2 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gattc.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gattc.c @@ -912,7 +912,7 @@ ble_gattc_proc_matches_conn_rx_entry(struct ble_gattc_proc *proc, void *arg) criteria->matching_rx_entry = ble_gattc_rx_entry_find( proc->op, criteria->rx_entries, criteria->num_rx_entries); - return 1; + return (criteria->matching_rx_entry != NULL); } static void diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c index fccf10274..e53cc116f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c @@ -719,6 +719,8 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle, /* Successful writes get persisted for bonded connections. */ if (conn->bhc_sec_state.bonded) { out_cccd->peer_addr = conn->bhc_peer_addr; + out_cccd->peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); out_cccd->chr_val_handle = chr_val_handle; out_cccd->flags = clt_cfg->flags; out_cccd->value_changed = 0; @@ -1464,6 +1466,8 @@ ble_gatts_rx_indicate_ack(uint16_t conn_handle, uint16_t chr_val_handle) !(clt_cfg->flags & BLE_GATTS_CLT_CFG_F_MODIFIED); if (persist) { cccd_value.peer_addr = conn->bhc_peer_addr; + cccd_value.peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); cccd_value.chr_val_handle = chr_val_handle; cccd_value.flags = clt_cfg->flags; cccd_value.value_changed = 0; @@ -1692,13 +1696,12 @@ ble_gatts_bonding_established(uint16_t conn_handle) BLE_HS_DBG_ASSERT(conn->bhc_sec_state.bonded); cccd_value.peer_addr = conn->bhc_peer_addr; + cccd_value.peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); gatt_srv = &conn->bhc_gatt_svr; for (i = 0; i < gatt_srv->num_clt_cfgs; ++i) { - clt_cfg = (gatt_srv->clt_cfgs + i); - if (clt_cfg == NULL) { - continue; - } + clt_cfg = &gatt_srv->clt_cfgs[i]; if (clt_cfg->flags != 0) { cccd_value.chr_val_handle = clt_cfg->chr_val_handle; @@ -1743,6 +1746,8 @@ ble_gatts_bonding_restored(uint16_t conn_handle) BLE_HS_DBG_ASSERT(conn->bhc_sec_state.bonded); cccd_key.peer_addr = conn->bhc_peer_addr; + cccd_key.peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); cccd_key.chr_val_handle = 0; cccd_key.idx = 0; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs.c index adb8046a7..d819e20df 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs.c @@ -504,20 +504,20 @@ ble_hs_sched_start(void) static void ble_hs_event_rx_hci_ev(struct ble_npl_event *ev) { - uint8_t *hci_evt; + const struct ble_hci_ev *hci_ev; int rc; - hci_evt = ble_npl_event_get_arg(ev); + hci_ev = ble_npl_event_get_arg(ev); rc = os_memblock_put(&ble_hs_hci_ev_pool, ev); BLE_HS_DBG_ASSERT_EVAL(rc == 0); #if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, hci_evt, - hci_evt[1] + BLE_HCI_EVENT_HDR_LEN); + ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, hci_ev, + hci_ev->length + sizeof(*hci_ev)); #endif - ble_hs_hci_evt_process(hci_evt); + ble_hs_hci_evt_process(hci_ev); } static void @@ -684,7 +684,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) /* If flow control is enabled, mark this packet with its corresponding * connection handle. */ - ble_hs_flow_fill_acl_usrhdr(om); + ble_hs_flow_track_data_mbuf(om); rc = ble_mqueue_put(&ble_hs_rx_q, ble_hs_evq, om); if (rc != 0) { @@ -747,8 +747,10 @@ ble_hs_init(void) rc = ble_hs_conn_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#if MYNEWT_VAL(BLE_PERIODIC_ADV) rc = ble_hs_periodic_sync_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif rc = ble_l2cap_init(); SYSINIT_PANIC_ASSERT(rc == 0); @@ -784,15 +786,15 @@ ble_hs_init(void) ble_hs_dbg_mutex_locked = 0; #endif - /* Configure the HCI transport to communicate with a host. */ - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - #ifdef MYNEWT ble_hs_evq_set((struct ble_npl_eventq *)os_eventq_dflt_get()); #else ble_hs_evq_set(nimble_port_get_dflt_eventq()); #endif + /* Configure the HCI transport to communicate with a host. */ + ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); + #if BLE_MONITOR rc = ble_monitor_init(); SYSINIT_PANIC_ASSERT(rc == 0); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_adv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_adv.c index 1066182d0..1d938b958 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_adv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_adv.c @@ -63,8 +63,8 @@ ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len, static int ble_hs_adv_set_flat_mbuf(uint8_t type, int data_len, const void *data, - uint8_t *dst, uint8_t *dst_len, uint8_t max_len, - struct os_mbuf *om) + uint8_t *dst, uint8_t *dst_len, uint8_t max_len, + struct os_mbuf *om) { int rc; @@ -235,11 +235,10 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, uint8_t type; int8_t tx_pwr_lvl; + uint8_t dst_len_local; int rc; - if (dst_len) { - *dst_len = 0; - } + dst_len_local = 0; /*** 0x01 - Flags. */ /* The application has two options concerning the flags field: @@ -251,7 +250,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, */ if (adv_fields->flags != 0) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_FLAGS, 1, - &adv_fields->flags, dst, dst_len, + &adv_fields->flags, dst, &dst_len_local, max_len, om); if (rc != 0) { @@ -268,7 +267,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } rc = ble_hs_adv_set_array_uuid16(type, adv_fields->num_uuids16, - adv_fields->uuids16, dst, dst_len, + adv_fields->uuids16, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -284,7 +283,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } rc = ble_hs_adv_set_array_uuid32(type, adv_fields->num_uuids32, - adv_fields->uuids32, dst, dst_len, + adv_fields->uuids32, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -300,7 +299,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } rc = ble_hs_adv_set_array_uuid128(type, adv_fields->num_uuids128, - adv_fields->uuids128, dst, dst_len, + adv_fields->uuids128, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -316,7 +315,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } rc = ble_hs_adv_set_flat_mbuf(type, adv_fields->name_len, - adv_fields->name, dst, dst_len, max_len, + adv_fields->name, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -338,7 +337,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1, - &tx_pwr_lvl, dst, dst_len, max_len, om); + &tx_pwr_lvl, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; } @@ -349,7 +348,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN, adv_fields->slave_itvl_range, dst, - dst_len, max_len, om); + &dst_len_local, max_len, om); if (rc != 0) { return rc; } @@ -359,7 +358,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, if (adv_fields->svc_data_uuid16 != NULL && adv_fields->svc_data_uuid16_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16, adv_fields->svc_data_uuid16_len, - adv_fields->svc_data_uuid16, dst, dst_len, + adv_fields->svc_data_uuid16, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -373,7 +372,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR, BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN * adv_fields->num_public_tgt_addrs, - adv_fields->public_tgt_addr, dst, dst_len, + adv_fields->public_tgt_addr, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -384,7 +383,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, if (adv_fields->appearance_is_present) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_APPEARANCE, BLE_HS_ADV_APPEARANCE_LEN, - &adv_fields->appearance, dst, dst_len, + &adv_fields->appearance, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -394,7 +393,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, /*** 0x1a - Advertising interval. */ if (adv_fields->adv_itvl_is_present) { rc = ble_hs_adv_set_array16(BLE_HS_ADV_TYPE_ADV_ITVL, 1, - &adv_fields->adv_itvl, dst, dst_len, + &adv_fields->adv_itvl, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -405,7 +404,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, if (adv_fields->svc_data_uuid32 != NULL && adv_fields->svc_data_uuid32_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID32, adv_fields->svc_data_uuid32_len, - adv_fields->svc_data_uuid32, dst, dst_len, + adv_fields->svc_data_uuid32, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -417,7 +416,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID128, adv_fields->svc_data_uuid128_len, adv_fields->svc_data_uuid128, dst, - dst_len, max_len, om); + &dst_len_local, max_len, om); if (rc != 0) { return rc; } @@ -426,7 +425,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, /*** 0x24 - URI. */ if (adv_fields->uri != NULL && adv_fields->uri_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len, - adv_fields->uri, dst, dst_len, max_len, + adv_fields->uri, dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; @@ -438,12 +437,16 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_MFG_DATA, adv_fields->mfg_data_len, adv_fields->mfg_data, - dst, dst_len, max_len, om); + dst, &dst_len_local, max_len, om); if (rc != 0) { return rc; } } + if (dst_len) { + *dst_len = dst_len_local; + } + return 0; } @@ -489,7 +492,7 @@ ble_hs_adv_parse_uuids16(struct ble_hs_adv_fields *adv_fields, for (i = 0; i < adv_fields->num_uuids16; i++) { ble_uuid_init_from_buf(&uuid, data + i * 2, 2); - adv_fields->uuids16[i] = uuid.u16; + ble_hs_adv_uuids16[i] = uuid.u16; } return 0; @@ -511,7 +514,7 @@ ble_hs_adv_parse_uuids32(struct ble_hs_adv_fields *adv_fields, for (i = 0; i < adv_fields->num_uuids32; i++) { ble_uuid_init_from_buf(&uuid, data + i * 4, 4); - adv_fields->uuids32[i] = uuid.u32; + ble_hs_adv_uuids32[i] = uuid.u32; } return 0; @@ -533,7 +536,7 @@ ble_hs_adv_parse_uuids128(struct ble_hs_adv_fields *adv_fields, for (i = 0; i < adv_fields->num_uuids128; i++) { ble_uuid_init_from_buf(&uuid, data + i * 16, 16); - adv_fields->uuids128[i] = uuid.u128; + ble_hs_adv_uuids128[i] = uuid.u128; } return 0; @@ -541,11 +544,12 @@ ble_hs_adv_parse_uuids128(struct ble_hs_adv_fields *adv_fields, static int ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, - uint8_t *total_len, uint8_t *src, uint8_t src_len) + uint8_t *total_len, const uint8_t *src, + uint8_t src_len) { uint8_t data_len; uint8_t type; - uint8_t *data; + const uint8_t *data; int rc; if (src_len < 1) { @@ -715,8 +719,8 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, } int -ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src, - uint8_t src_len) +ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, + const uint8_t *src, uint8_t src_len) { uint8_t field_len; int rc; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_atomic.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_atomic.c index 5d51fbe1a..f26ba7acc 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_atomic.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_atomic.c @@ -28,6 +28,11 @@ ble_hs_atomic_conn_delete(uint16_t conn_handle) conn = ble_hs_conn_find(conn_handle); if (conn != NULL) { ble_hs_conn_remove(conn); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + if (conn->psync) { + ble_hs_periodic_sync_free(conn->psync); + } +#endif ble_hs_conn_free(conn); } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c index b45128e23..31830c98a 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c @@ -84,14 +84,29 @@ ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn, uint16_t cid) if (chan->dcid == cid) { return chan; } - if (chan->dcid > cid) { - return NULL; - } } return NULL; } +bool +ble_hs_conn_chan_exist(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) +{ +#if !NIMBLE_BLE_CONNECT + return NULL; +#endif + + struct ble_l2cap_chan *tmp; + + SLIST_FOREACH(tmp, &conn->bhc_channels, next) { + if (chan == tmp) { + return true; + } + } + + return false; +} + int ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { @@ -197,7 +212,21 @@ ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) } SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next); - ble_l2cap_chan_free(chan); + ble_l2cap_chan_free(conn, chan); +} + +void +ble_hs_conn_foreach(ble_hs_conn_foreach_fn *cb, void *arg) +{ + struct ble_hs_conn *conn; + + BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); + + SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) { + if (cb(conn, arg) != 0) { + return; + } + } } void @@ -377,7 +406,7 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, /* Determine our address information. */ addrs->our_id_addr.type = - ble_hs_misc_addr_type_to_id(conn->bhc_our_addr_type); + ble_hs_misc_own_addr_type_to_id(conn->bhc_our_addr_type); #if MYNEWT_VAL(BLE_EXT_ADV) /* With EA enabled random address for slave connection is per advertising diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn_priv.h index 92aacd405..0e451194d 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn_priv.h @@ -38,6 +38,15 @@ typedef uint8_t ble_hs_conn_flags_t; #define BLE_HS_CONN_F_TERMINATING 0x02 #define BLE_HS_CONN_F_TX_FRAG 0x04 /* Cur ACL packet partially txed. */ +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) +#define BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN_REM \ + ((MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) % (8 * sizeof(uint32_t))) ? 1 : 0) + +#define BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN \ + (MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) / (8 * sizeof(uint32_t)) + \ + BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN_REM) +#endif + struct ble_hs_conn { SLIST_ENTRY(ble_hs_conn) bhc_next; uint16_t bhc_handle; @@ -61,6 +70,9 @@ struct ble_hs_conn { struct ble_l2cap_chan_list bhc_channels; struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */ ble_npl_time_t bhc_rx_timeout; +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + uint32_t l2cap_coc_cid_mask[BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN]; +#endif /** * Count of packets sent over this connection that the controller has not @@ -86,6 +98,10 @@ struct ble_hs_conn { ble_gap_event_fn *bhc_cb; void *bhc_cb_arg; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + struct ble_hs_periodic_sync *psync; +#endif }; struct ble_hs_conn_addrs { @@ -110,15 +126,19 @@ struct ble_l2cap_chan *ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn, uint16_t cid); struct ble_l2cap_chan *ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn, uint16_t cid); +bool ble_hs_conn_chan_exist(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); int ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); -void -ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); +void ble_hs_conn_delete_chan(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan); void ble_hs_conn_addrs(const struct ble_hs_conn *conn, struct ble_hs_conn_addrs *addrs); int32_t ble_hs_conn_timer(void); +typedef int ble_hs_conn_foreach_fn(struct ble_hs_conn *conn, void *arg); +void ble_hs_conn_foreach(ble_hs_conn_foreach_fn *cb, void *arg); + int ble_hs_conn_init(void); #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg.c deleted file mode 100644 index 6659c00df..000000000 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_dbg.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include -#include -#include -#include "os/os.h" -#include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" -#include "host/ble_monitor.h" -#include "ble_hs_priv.h" - -static void -ble_hs_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata) -{ - int8_t rssi; - uint8_t advlen; - uint8_t status; - int i; - int imax; - uint8_t *dptr; - char *adv_ptr; - char adv_data_buf[32]; - - switch (subev) { - case BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE: - case BLE_HCI_LE_SUBEV_CONN_COMPLETE: - status = evdata[0]; - if (status == BLE_ERR_SUCCESS) { - BLE_HS_LOG(DEBUG, "LE connection complete. handle=%u role=%u " - "paddrtype=%u addr=%x.%x.%x.%x.%x.%x ", - get_le16(evdata + 1), evdata[3], evdata[4], - evdata[10], evdata[9], evdata[8], evdata[7], - evdata[6], evdata[5]); - - evdata += 11; - if (subev == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) { - BLE_HS_LOG(DEBUG, "local_rpa=%x.%x.%x.%x.%x.%x " - "peer_rpa=%x.%x.%x.%x.%x.%x ", - evdata[5], evdata[4], evdata[3], evdata[2], - evdata[1], evdata[0], - evdata[11], evdata[10], evdata[9], evdata[8], - evdata[7], evdata[6]); - - evdata += 12; - } - BLE_HS_LOG(DEBUG, "itvl=%u latency=%u spvn_tmo=%u mca=%u\n", - get_le16(evdata), get_le16(evdata + 2), - get_le16(evdata + 4), evdata[6]); - } else { - BLE_HS_LOG(DEBUG, "LE connection complete. FAIL (status=%u)\n", - status); - } - break; - case BLE_HCI_LE_SUBEV_ADV_RPT: - advlen = evdata[9]; - rssi = evdata[10 + advlen]; - BLE_HS_LOG(DEBUG, "LE advertising report. len=%u num=%u evtype=%u " - "addrtype=%u addr=%x.%x.%x.%x.%x.%x advlen=%u " - "rssi=%d\n", len, evdata[0], evdata[1], evdata[2], - evdata[8], evdata[7], evdata[6], evdata[5], - evdata[4], evdata[3], advlen, rssi); - if (advlen) { - dptr = &evdata[10]; - while (advlen > 0) { - memset(adv_data_buf, 0, 32); - imax = advlen; - if (imax > 8) { - imax = 8; - } - adv_ptr = &adv_data_buf[0]; - for (i = 0; i < imax; ++i) { - snprintf(adv_ptr, 4, "%02x ", *dptr); - adv_ptr += 3; - ++dptr; - } - advlen -= imax; - BLE_HS_LOG(DEBUG, "%s\n", adv_data_buf); - } - } - break; - case BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE: - status = evdata[0]; - if (status == BLE_ERR_SUCCESS) { - BLE_HS_LOG(DEBUG, "LE Connection Update Complete. handle=%u " - "itvl=%u latency=%u timeout=%u\n", - get_le16(evdata + 1), get_le16(evdata + 3), - get_le16(evdata + 5), get_le16(evdata + 7)); - } else { - BLE_HS_LOG(DEBUG, "LE Connection Update Complete. FAIL " - "(status=%u)\n", status); - } - break; - - case BLE_HCI_LE_SUBEV_DATA_LEN_CHG: - BLE_HS_LOG(DEBUG, "LE Data Length Change. handle=%u max_tx_bytes=%u " - "max_tx_time=%u max_rx_bytes=%u max_rx_time=%u\n", - get_le16(evdata), get_le16(evdata + 2), - get_le16(evdata + 4), get_le16(evdata + 6), - get_le16(evdata + 8)); - break; - case BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ: - BLE_HS_LOG(DEBUG, "LE Remote Connection Parameter Request. handle=%u " - "min_itvl=%u max_itvl=%u latency=%u timeout=%u\n", - get_le16(evdata), get_le16(evdata + 2), - get_le16(evdata + 4), get_le16(evdata + 6), - get_le16(evdata + 8)); - break; - - case BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT: - status = evdata[0]; - if (status == BLE_ERR_SUCCESS) { - BLE_HS_LOG(DEBUG, "LE Remote Used Features. handle=%u feat=", - get_le16(evdata + 1)); - for (i = 0; i < BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN; ++i) { - BLE_HS_LOG(DEBUG, "%02x ", evdata[3 + i]); - } - BLE_HS_LOG(DEBUG, "\n"); - } else { - BLE_HS_LOG(DEBUG, "LE Remote Used Features. FAIL (status=%u)\n", - status); - } - break; - - case BLE_HCI_LE_SUBEV_LT_KEY_REQ: - BLE_HS_LOG(DEBUG, "LE LTK Req. handle=%u rand=%x%x encdiv=%u\n", - get_le16(evdata), get_le32(evdata + 6), - get_le32(evdata + 2), get_le16(evdata + 10)); - break; - - case BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE: - BLE_HS_LOG(DEBUG, "PHY update. handle=%u tx=%u rx=%u\n", - get_le16(evdata + 1), evdata[3], evdata[4]); - break; - - case BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT: - { - struct hci_le_subev_direct_adv_rpt *data = (void *) evdata; - struct hci_le_subev_direct_adv_rpt_param *params = data->params; - - if (len < sizeof(*data) || - len < sizeof(*data) + data->num_reports * sizeof(*params)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Directed Advertising Report " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Directed Advertising Report len=%u " - "num=0x%02x ", len, data->num_reports); - - for (i = 0; i < data->num_reports; i++) { - BLE_HS_LOG(DEBUG, "[%d]={evttype=0x%02x}\n", i, params->evt_type); - params += 1; - } - break; - } - - case BLE_HCI_LE_SUBEV_RD_LOC_P256_PUBKEY: - { - struct hci_le_subev_rd_loc_p256_pubkey *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Read Local P-256 Public Key " - "Complete Event len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Read Local P-256 Public Key Complete " - "len=%u status=0x%02x\n", len, data->status); - break; - } - - case BLE_HCI_LE_SUBEV_GEN_DHKEY_COMPLETE: - { - struct hci_le_subev_gen_dhkey_complete *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Generate DHKey Complete " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Generate DHKey Complete Event len=%u " - "status=0x%02x\n", len, data->status); - break; - } - -#if MYNEWT_VAL(BLE_EXT_ADV) - case BLE_HCI_LE_SUBEV_EXT_ADV_RPT: - { - struct hci_le_subev_ext_adv_rpt *data = (void *) evdata; - struct hci_ext_adv_report_param *params; - - if (len < sizeof(*data) + sizeof(*params)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Extended Advertising Report " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Extended Advertising Report len=%u num=0x%02x ", - len, data->num_reports); - - for (i = 0, dptr = &evdata[1]; i < data->num_reports; i++) { - params = (void *) dptr; - BLE_HS_LOG(DEBUG, "[%d]={evttype=0x%04x advlen=%u}\n", - i, le16toh(params->evt_type), params->adv_data_len); - dptr += sizeof(*params) + params->adv_data_len; - } - break; - } -#if MYNEWT_VAL(BLE_PERIODIC_ADV) - case BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB: - { - struct hci_le_subev_periodic_adv_sync_estab *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Sync " - "Established len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Periodic Advertising Sync Established " - "len=%u status=0x%02x handle=0x%04x", len, data->status, - le16toh(data->sync_handle)); - break; - } - - case BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT: - { - struct hci_le_subev_periodic_adv_rpt *data = (void *) evdata; - - if (len < sizeof(*data) || len != sizeof(*data) + data->data_length) { - BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Report " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Periodic Advertising Report " - "len=%u handle=0x%04x data_status=0x%02x data_len=0x%02x", - len, le16toh(data->sync_handle), data->data_status, - data->data_length); - break; - } - - case BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST: - { - struct hci_le_subev_periodic_adv_sync_lost *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Periodic Advertising Sync Lost " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Periodic Advertising Sync Lost " - "len=%u handle=0x%04x", len, le16toh(data->sync_handle)); - break; - } -#endif - - case BLE_HCI_LE_SUBEV_SCAN_TIMEOUT: - if (len) { - BLE_HS_LOG(DEBUG, "Corrupted LE Scan Timeout len=%u", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Scan Timeout Event len=%u", len); - break; - - case BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED: - { - struct hci_le_subev_adv_set_terminated *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Advertising Set Terminated " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Advertising Set Terminated len=%u " - "status=0x%02x adv_handle=0x%02x conn_handle=0x%04x " - "num_compl_ext_adv_ev=0x%02x", len, data->status, - data->adv_handle, le16toh(data->conn_handle), - data->num_compl_ext_adv_ev); - break; - } - - case BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD: - { - struct hci_le_subev_scan_req_rcvd *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Scan Request Received " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Scan Request Received len=%u " - "adv_handle=0x%02x", len, data->adv_handle); - break; - } -#endif /* MYNEWT_VAL(BLE_EXT_ADV) */ - - case BLE_HCI_LE_SUBEV_CHAN_SEL_ALG: - { - struct hci_le_subev_chan_sel_alg *data = (void *) evdata; - - if (len != sizeof(*data)) { - BLE_HS_LOG(DEBUG, "Corrupted LE Channel Selection Algorithm " - "len=%u\n", len); - break; - } - - BLE_HS_LOG(DEBUG, "LE Channel Selection Algorithm len=%u " - "conn_handle=0x%04x chan_sel_alg=0x%02x\n", len, - le16toh(data->conn_handle), data->chan_sel_alg); - break; - } - - default: - BLE_HS_LOG(DEBUG, "LE Meta SubEvent op=0x%02x\n", subev); - break; - } -} - -/** - * Display a disconnection complete command. - * - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_disconn_comp_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t status; - uint8_t reason; - uint16_t handle; - - status = evdata[0]; - handle = get_le16(evdata + 1); - /* Ignore reason if status is not success */ - if (status != BLE_ERR_SUCCESS) { - reason = 0; - } else { - reason = evdata[3]; - } - BLE_HS_LOG(DEBUG, "Disconnection Complete: status=%u handle=%u " - "reason=%u\n", status, handle, reason); -} - -/** - * Display an encryption change event or encryption key refresh event - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_encrypt_chg_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t status; - uint8_t enabled; - uint16_t handle; - - status = evdata[0]; - handle = get_le16(evdata + 1); - - /* Ignore reason if status is not success */ - if (status != BLE_ERR_SUCCESS) { - enabled = 0; - } else { - enabled = evdata[3]; - } - BLE_HS_LOG(DEBUG, "Encrypt change: status=%u handle=%u state=%u\n", - status, handle, enabled); -} - -/** - * Display an encryption encryption key refresh event - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_encrypt_refresh_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t status; - uint16_t handle; - - status = evdata[0]; - handle = get_le16(evdata + 1); - - BLE_HS_LOG(DEBUG, "Encrypt key refresh: status=%u handle=%u\n", - status, handle); -} - -/** - * Display a version information event - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_rd_rem_ver_disp(uint8_t *evdata, uint8_t len) -{ - BLE_HS_LOG(DEBUG, "Remote Version Info: status=%u handle=%u vers_nr=%u " - "compid=%u subver=%u\n", - evdata[0], get_le16(evdata + 1), evdata[3], - get_le16(evdata + 4), get_le16(evdata + 6)); -} - -/** - * Display the number of completed packets event - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_num_comp_pkts_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t handles; - uint8_t *handle_ptr; - uint16_t handle; - uint16_t pkts; - - handles = evdata[0]; - if (len != ((handles * 4) + 1)) { - BLE_HS_LOG(DEBUG, "ERR: Number of Completed Packets bad length: " - "num_handles=%u len=%u\n", handles, len); - return; - - } - - BLE_HS_LOG(DEBUG, "Number of Completed Packets: num_handles=%u\n", - handles); - if (handles) { - handle_ptr = evdata + 1; - while (handles) { - handle = get_le16(handle_ptr); - pkts = get_le16(handle_ptr + 2); - handle_ptr += 4; - BLE_HS_LOG(DEBUG, "handle:%u pkts:%u\n", handle, pkts); - --handles; - } - } -} - -/** - * Display the authenticated payload timeout event - * - * @param evdata - * @param len - */ -static void -ble_hs_dbg_auth_pyld_tmo_disp(uint8_t *evdata, uint8_t len) -{ - uint16_t handle; - - if (len != sizeof(uint16_t)) { - BLE_HS_LOG(DEBUG, "ERR: AuthPyldTmoEvent bad length %u\n", len); - return; - - } - - handle = get_le16(evdata); - BLE_HS_LOG(DEBUG, "AuthPyldTmo: handle=%u\n", handle); -} - - -static void -ble_hs_dbg_cmd_comp_info_params(uint8_t status, uint8_t ocf, uint8_t *evdata) -{ - int i; - uint8_t *dptr; - - if (status != BLE_ERR_SUCCESS) { - return; - } - - switch (ocf) { - case BLE_HCI_OCF_IP_RD_LOCAL_VER: - BLE_HS_LOG(DEBUG, "hci_ver=%u hci_rev=%u lmp_ver=%u mfrg=%u " - "lmp_subver=%u", - evdata[0], get_le16(evdata + 1), evdata[3], - get_le16(evdata + 4), get_le16(evdata + 6)); - break; - case BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD: - BLE_HS_LOG(DEBUG, "supp_cmds="); - dptr = evdata; - for (i = 0; i < 8; ++i) { - BLE_HS_LOG(DEBUG, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:", - dptr[0], dptr[1], dptr[2], dptr[3], - dptr[4], dptr[5], dptr[6], dptr[7]); - dptr += 8; - } - break; - case BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT: - BLE_HS_LOG(DEBUG, "supp_feat=0x%x%08x", - get_le32(evdata + 4), get_le32(evdata)); - break; - case BLE_HCI_OCF_IP_RD_BD_ADDR: - BLE_HS_LOG(DEBUG, "bd_addr=%x:%x:%x:%x:%x:%x", - evdata[5], evdata[4], evdata[3], - evdata[2], evdata[1], evdata[0]); - break; - default: - break; - } -} - -static void -ble_hs_dbg_cmd_complete_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t cmd_pkts; - uint8_t ogf; - uint8_t ocf; - uint8_t status; - uint16_t opcode; - - if (len < 3) { - BLE_HS_LOG(DEBUG, "Invalid command complete: len=%d " - "(expected >= 3)", len); - goto done; - } - - cmd_pkts = evdata[0]; - opcode = get_le16(evdata + 1); - ogf = BLE_HCI_OGF(opcode); - ocf = BLE_HCI_OCF(opcode); - - BLE_HS_LOG(DEBUG, "Command complete: cmd_pkts=%u ogf=0x%x ocf=0x%x", - cmd_pkts, ogf, ocf); - - if (len == 3) { - goto done; - } - - status = evdata[3]; - BLE_HS_LOG(DEBUG, " status=%u ", status); - - /* Move past header and status */ - evdata += 4; - - /* Display parameters based on command. */ - switch (ogf) { - case BLE_HCI_OGF_INFO_PARAMS: - ble_hs_dbg_cmd_comp_info_params(status, ocf, evdata); - break; - case BLE_HCI_OGF_STATUS_PARAMS: - switch (ocf) { - case BLE_HCI_OCF_RD_RSSI: - BLE_HS_LOG(DEBUG, "handle=%u rssi=%d", get_le16(evdata), - (int8_t)evdata[2]); - break; - default: - break; - } - break; - case BLE_HCI_OGF_LE: - switch (ocf) { - case BLE_HCI_OCF_LE_RD_CHAN_MAP: - BLE_HS_LOG(DEBUG, "handle=%u chanmap=%x.%x.%x.%x.%x", - get_le16(evdata), evdata[2], evdata[3], evdata[4], - evdata[5], evdata[6]); - break; - case BLE_HCI_OCF_LE_RD_MAX_DATA_LEN: - BLE_HS_LOG(DEBUG, "txoct=%u txtime=%u rxoct=%u rxtime=%u", - get_le16(evdata), get_le16(evdata + 2), - get_le16(evdata + 4), get_le16(evdata + 6)); - break; - case BLE_HCI_OCF_LE_RD_SUPP_STATES: - BLE_HS_LOG(DEBUG, "states=0x%x%08x", get_le32(evdata + 4), - get_le32(evdata)); - break; - case BLE_HCI_OCF_LE_ENCRYPT: - BLE_HS_LOG(DEBUG, "encdata=0x%02x%02x%02x%02x%02x%02x%02x%02x", - evdata[15], evdata[14], evdata[13], evdata[12], - evdata[11], evdata[10], evdata[9], evdata[8]); - BLE_HS_LOG(DEBUG, "%02x%02x%02x%02x%02x%02x%02x%02x", - evdata[7], evdata[6], evdata[5], evdata[4], - evdata[3], evdata[2], evdata[1], evdata[0]); - - break; - case BLE_HCI_OCF_LE_RAND: - BLE_HS_LOG(DEBUG, "rand=0x%02x%02x%02x%02x%02x%02x%02x%02x", - evdata[0], evdata[1], evdata[2], evdata[3], - evdata[4], evdata[5], evdata[6], evdata[7]); - break; - case BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN: - BLE_HS_LOG(DEBUG, "txoct=%u txtime=%u", get_le16(evdata), - get_le16(evdata + 2)); - break; - case BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY: - case BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY: - case BLE_HCI_OCF_LE_SET_DATA_LEN: - BLE_HS_LOG(DEBUG, "handle=%u", get_le16(evdata)); - break; - default: - break; - } - break; - default: - break; - } - -done: - BLE_HS_LOG(DEBUG, "\n"); -} - -static void -ble_hs_dbg_cmd_status_disp(uint8_t *evdata, uint8_t len) -{ - uint8_t ogf; - uint8_t ocf; - uint16_t opcode; - - opcode = get_le16(evdata + 2); - ogf = BLE_HCI_OGF(opcode); - ocf = BLE_HCI_OCF(opcode); - - BLE_HS_LOG(DEBUG, "Command Status: status=%u cmd_pkts=%u ocf=0x%x " - "ogf=0x%x\n", evdata[0], evdata[1], ocf, ogf); -} - -void -ble_hs_dbg_event_disp(uint8_t *evbuf) -{ -#if MYNEWT_VAL(LOG_LEVEL) > LOG_LEVEL_DEBUG || BLE_MONITOR - return; -#endif - - uint8_t *evdata; - uint8_t evcode; - uint8_t len; - - /* Extract event code and length; move pointer to event parameter data */ - evcode = evbuf[0]; - len = evbuf[1]; - evdata = evbuf + BLE_HCI_EVENT_HDR_LEN; - - switch (evcode) { - case BLE_HCI_EVCODE_DISCONN_CMP: - ble_hs_dbg_disconn_comp_disp(evdata, len); - break; - case BLE_HCI_EVCODE_ENC_KEY_REFRESH: - ble_hs_dbg_encrypt_refresh_disp(evdata, len); - break; - case BLE_HCI_EVCODE_ENCRYPT_CHG: - ble_hs_dbg_encrypt_chg_disp(evdata, len); - break; - case BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP: - ble_hs_dbg_rd_rem_ver_disp(evdata, len); - break; - case BLE_HCI_EVCODE_COMMAND_COMPLETE: - ble_hs_dbg_cmd_complete_disp(evdata, len); - break; - case BLE_HCI_EVCODE_COMMAND_STATUS: - ble_hs_dbg_cmd_status_disp(evdata, len); - break; - case BLE_HCI_EVCODE_NUM_COMP_PKTS: - ble_hs_dbg_num_comp_pkts_disp(evdata, len); - break; - case BLE_HCI_EVCODE_LE_META: - ble_hs_dbg_le_event_disp(evdata[0], len-1, evdata + 1); - break; - case BLE_HCI_EVCODE_AUTH_PYLD_TMO: - ble_hs_dbg_auth_pyld_tmo_disp(evdata, len); - break; - default: - BLE_HS_LOG(DEBUG, "Unknown event 0x%x len=%u\n", evcode, len); - break; - } -} - -void -ble_hs_dbg_set_sync_state(uint8_t sync_state) -{ - ble_hs_sync_state = sync_state; -} diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow.c index 35e3cd9ab..2520c8541 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow.c @@ -40,14 +40,31 @@ static ble_npl_event_fn ble_hs_flow_event_cb; static struct ble_npl_event ble_hs_flow_ev; +/* Connection handle associated with each mbuf in ACL pool */ +static uint16_t ble_hs_flow_mbuf_conn_handle[ MYNEWT_VAL(BLE_ACL_BUF_COUNT) ]; + +static inline int +ble_hs_flow_mbuf_index(const struct os_mbuf *om) +{ + const struct os_mempool *mp = om->om_omp->omp_pool; + uintptr_t addr = (uintptr_t)om; + int idx; + + idx = (addr - mp->mp_membuf_addr) / mp->mp_block_size; + + BLE_HS_DBG_ASSERT(mp->mp_membuf_addr + idx * mp->mp_block_size == addr); + + return idx; +} + static int ble_hs_flow_tx_num_comp_pkts(void) { uint8_t buf[ - BLE_HCI_HOST_NUM_COMP_PKTS_HDR_LEN + - BLE_HCI_HOST_NUM_COMP_PKTS_ENT_LEN + sizeof(struct ble_hci_cb_host_num_comp_pkts_cp) + + sizeof(struct ble_hci_cb_host_num_comp_pkts_entry) ]; - struct hci_host_num_comp_pkts_entry entry; + struct ble_hci_cb_host_num_comp_pkts_cp *cmd = (void *) buf; struct ble_hs_conn *conn; int rc; @@ -62,16 +79,12 @@ ble_hs_flow_tx_num_comp_pkts(void) if (conn->bhc_completed_pkts > 0) { /* Only specify one connection per command. */ - buf[0] = 1; + /* TODO could combine this in single HCI command */ + cmd->handles = 1; /* Append entry for this connection. */ - entry.conn_handle = conn->bhc_handle; - entry.num_pkts = conn->bhc_completed_pkts; - rc = ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - &entry, - buf + BLE_HCI_HOST_NUM_COMP_PKTS_HDR_LEN, - sizeof buf - BLE_HCI_HOST_NUM_COMP_PKTS_HDR_LEN); - BLE_HS_DBG_ASSERT(rc == 0); + cmd->h[0].handle = htole16(conn->bhc_handle); + cmd->h[0].count = htole16(conn->bhc_completed_pkts); conn->bhc_completed_pkts = 0; @@ -147,18 +160,13 @@ ble_hs_flow_acl_free(struct os_mempool_ext *mpe, void *data, void *arg) struct ble_hs_conn *conn; const struct os_mbuf *om; uint16_t conn_handle; + int idx; int rc; om = data; - /* An ACL data packet must be a single mbuf, and it must contain the - * corresponding connection handle in its user header. - */ - assert(OS_MBUF_IS_PKTHDR(om)); - assert(OS_MBUF_USRHDR_LEN(om) >= sizeof conn_handle); - - /* Copy the connection handle out of the mbuf. */ - memcpy(&conn_handle, OS_MBUF_USRHDR(om), sizeof conn_handle); + idx = ble_hs_flow_mbuf_index(om); + conn_handle = ble_hs_flow_mbuf_conn_handle[idx]; /* Free the mbuf back to its pool. */ rc = os_memblock_put_from_cb(&mpe->mpe_mp, data); @@ -194,23 +202,19 @@ ble_hs_flow_connection_broken(uint16_t conn_handle) } /** - * Fills the user header of an incoming data packet. On function return, the - * header contains the connection handle associated with the sender. + * Associates incoming data packet with a connection handle of the sender. * * If flow control is disabled, this function is a no-op. */ void -ble_hs_flow_fill_acl_usrhdr(struct os_mbuf *om) +ble_hs_flow_track_data_mbuf(struct os_mbuf *om) { #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) const struct hci_data_hdr *hdr; - uint16_t *conn_handle; - - BLE_HS_DBG_ASSERT(OS_MBUF_USRHDR_LEN(om) >= sizeof *conn_handle); - conn_handle = OS_MBUF_USRHDR(om); + int idx = ble_hs_flow_mbuf_index(om); hdr = (void *)om->om_data; - *conn_handle = BLE_HCI_DATA_HANDLE(hdr->hdh_handle_pb_bc); + ble_hs_flow_mbuf_conn_handle[idx] = BLE_HCI_DATA_HANDLE(hdr->hdh_handle_pb_bc); #endif } @@ -224,29 +228,39 @@ int ble_hs_flow_startup(void) { #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) - struct hci_host_buf_size buf_size_cmd; + struct ble_hci_cb_ctlr_to_host_fc_cp enable_cmd; + struct ble_hci_cb_host_buf_size_cp buf_size_cmd = { + .acl_data_len = htole16(MYNEWT_VAL(BLE_ACL_BUF_SIZE)), + .acl_num = htole16(MYNEWT_VAL(BLE_ACL_BUF_COUNT)), + }; int rc; ble_npl_event_init(&ble_hs_flow_ev, ble_hs_flow_event_cb, NULL); /* Assume failure. */ ble_hci_trans_set_acl_free_cb(NULL, NULL); + #if MYNEWT_VAL(SELFTEST) ble_npl_callout_stop(&ble_hs_flow_timer); #endif - rc = ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(BLE_HCI_CTLR_TO_HOST_FC_ACL); + enable_cmd.enable = BLE_HCI_CTLR_TO_HOST_FC_ACL; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC), + &enable_cmd, sizeof(enable_cmd), NULL, 0); if (rc != 0) { return rc; } - buf_size_cmd = (struct hci_host_buf_size) { - .acl_pkt_len = MYNEWT_VAL(BLE_ACL_BUF_SIZE), - .num_acl_pkts = MYNEWT_VAL(BLE_ACL_BUF_COUNT), - }; - rc = ble_hs_hci_cmd_tx_host_buf_size(&buf_size_cmd); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_HOST_BUF_SIZE), + &buf_size_cmd, sizeof(buf_size_cmd), NULL, 0); if (rc != 0) { - ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(BLE_HCI_CTLR_TO_HOST_FC_OFF); + enable_cmd.enable = BLE_HCI_CTLR_TO_HOST_FC_OFF; + ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC), + &enable_cmd, sizeof(enable_cmd), NULL, 0); return rc; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow_priv.h index b1aa8c2fc..753eaf8ff 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_flow_priv.h @@ -26,7 +26,7 @@ extern "C" { #endif void ble_hs_flow_connection_broken(uint16_t conn_handle); -void ble_hs_flow_fill_acl_usrhdr(struct os_mbuf *om); +void ble_hs_flow_track_data_mbuf(struct os_mbuf *om); int ble_hs_flow_startup(void); #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c index 92ffde8fd..3cfed27e2 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c @@ -25,7 +25,6 @@ #include "nimble/ble_hci_trans.h" #include "host/ble_monitor.h" #include "ble_hs_priv.h" -#include "ble_hs_dbg_priv.h" #include "ble_monitor_priv.h" #define BLE_HCI_CMD_TIMEOUT_MS 2000 @@ -33,10 +32,13 @@ static struct ble_npl_mutex ble_hs_hci_mutex; static struct ble_npl_sem ble_hs_hci_sem; -static uint8_t *ble_hs_hci_ack; +static struct ble_hci_ev *ble_hs_hci_ack; static uint16_t ble_hs_hci_buf_sz; static uint8_t ble_hs_hci_max_pkts; + +/* For now 32-bits of features is enough */ static uint32_t ble_hs_hci_sup_feat; + static uint8_t ble_hs_hci_version; #define BLE_HS_HCI_FRAG_DATABUF_SIZE \ @@ -128,71 +130,66 @@ ble_hs_hci_add_avail_pkts(uint16_t delta) } static int -ble_hs_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len, +ble_hs_hci_rx_cmd_complete(const void *data, int len, struct ble_hs_hci_ack *out_ack) { + const struct ble_hci_ev_command_complete *ev = data; + const struct ble_hci_ev_command_complete_nop *nop = data; uint16_t opcode; - uint8_t *params; - uint8_t params_len; - uint8_t num_pkts; - if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) { - return BLE_HS_ECONTROLLER; + if (len < sizeof(*ev)) { + if (len < sizeof(*nop)) { + return BLE_HS_ECONTROLLER; + } + + /* nop is special as it doesn't have status and response */ + + opcode = le16toh(nop->opcode); + if (opcode != BLE_HCI_OPCODE_NOP) { + return BLE_HS_ECONTROLLER; + } + + /* TODO Process num_pkts field. */ + + out_ack->bha_status = 0; + out_ack->bha_params = NULL; + out_ack->bha_params_len = 0; + return 0; } - num_pkts = data[2]; - opcode = get_le16(data + 3); - params = data + 5; + opcode = le16toh(ev->opcode); - /* XXX: Process num_pkts field. */ - (void)num_pkts; + /* TODO Process num_pkts field. */ out_ack->bha_opcode = opcode; - params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN; - if (params_len > 0) { - out_ack->bha_status = BLE_HS_HCI_ERR(params[0]); - } else if (opcode == BLE_HCI_OPCODE_NOP) { - out_ack->bha_status = 0; - } else { - out_ack->bha_status = BLE_HS_ECONTROLLER; - } - - /* Don't include the status byte in the parameters blob. */ - if (params_len > 1) { - out_ack->bha_params = params + 1; - out_ack->bha_params_len = params_len - 1; + out_ack->bha_status = BLE_HS_HCI_ERR(ev->status); + out_ack->bha_params_len = len - sizeof(*ev); + if (out_ack->bha_params_len) { + out_ack->bha_params = ev->return_params; } else { out_ack->bha_params = NULL; - out_ack->bha_params_len = 0; } return 0; } static int -ble_hs_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len, +ble_hs_hci_rx_cmd_status(const void *data, int len, struct ble_hs_hci_ack *out_ack) { - uint16_t opcode; - uint8_t num_pkts; - uint8_t status; + const struct ble_hci_ev_command_status *ev = data; - if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - status = data[2]; - num_pkts = data[3]; - opcode = get_le16(data + 4); - /* XXX: Process num_pkts field. */ - (void)num_pkts; - out_ack->bha_opcode = opcode; + out_ack->bha_opcode = le16toh(ev->opcode); out_ack->bha_params = NULL; out_ack->bha_params_len = 0; - out_ack->bha_status = BLE_HS_HCI_ERR(status); + out_ack->bha_status = BLE_HS_HCI_ERR(ev->status); return 0; } @@ -202,9 +199,6 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, uint8_t *params_buf, uint8_t params_buf_len, struct ble_hs_hci_ack *out_ack) { - uint8_t event_code; - uint8_t param_len; - uint8_t event_len; int rc; BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); @@ -212,25 +206,19 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, /* Count events received */ STATS_INC(ble_hs_stats, hci_event); - /* Display to console */ - ble_hs_dbg_event_disp(ble_hs_hci_ack); - - event_code = ble_hs_hci_ack[0]; - param_len = ble_hs_hci_ack[1]; - event_len = param_len + 2; /* Clear ack fields up front to silence spurious gcc warnings. */ memset(out_ack, 0, sizeof *out_ack); - switch (event_code) { + switch (ble_hs_hci_ack->opcode) { case BLE_HCI_EVCODE_COMMAND_COMPLETE: - rc = ble_hs_hci_rx_cmd_complete(event_code, ble_hs_hci_ack, - event_len, out_ack); + rc = ble_hs_hci_rx_cmd_complete(ble_hs_hci_ack->data, + ble_hs_hci_ack->length, out_ack); break; case BLE_HCI_EVCODE_COMMAND_STATUS: - rc = ble_hs_hci_rx_cmd_status(event_code, ble_hs_hci_ack, - event_len, out_ack); + rc = ble_hs_hci_rx_cmd_status(ble_hs_hci_ack->data, + ble_hs_hci_ack->length, out_ack); break; default: @@ -273,20 +261,20 @@ ble_hs_hci_wait_for_ack(void) rc = BLE_HS_ETIMEOUT_HCI; } else { ble_hs_hci_ack = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); - rc = ble_hs_hci_phony_ack_cb(ble_hs_hci_ack, 260); + rc = ble_hs_hci_phony_ack_cb((void *)ble_hs_hci_ack, 260); } #else rc = ble_npl_sem_pend(&ble_hs_hci_sem, - ble_npl_time_ms_to_ticks32(BLE_HCI_CMD_TIMEOUT_MS)); + ble_npl_time_ms_to_ticks32(BLE_HCI_CMD_TIMEOUT_MS)); switch (rc) { case 0: BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); #if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, ble_hs_hci_ack, - ble_hs_hci_ack[1] + BLE_HCI_EVENT_HDR_LEN); + ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, (void *) ble_hs_hci_ack, + sizeof(*ble_hs_hci_ack) + ble_hs_hci_ack->length); #endif break; @@ -304,9 +292,8 @@ ble_hs_hci_wait_for_ack(void) } int -ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, - void *evt_buf, uint8_t evt_buf_len, - uint8_t *out_evt_buf_len) +ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, + void *rsp, uint8_t rsp_len) { struct ble_hs_hci_ack ack; int rc; @@ -325,21 +312,23 @@ ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, goto done; } - rc = ble_hs_hci_process_ack(opcode, evt_buf, evt_buf_len, &ack); + rc = ble_hs_hci_process_ack(opcode, rsp, rsp_len, &ack); if (rc != 0) { ble_hs_sched_reset(rc); goto done; } - if (out_evt_buf_len != NULL) { - *out_evt_buf_len = ack.bha_params_len; - } - rc = ack.bha_status; + /* on success we should always get full response */ + if (!rc && (ack.bha_params_len != rsp_len)) { + ble_hs_sched_reset(rc); + goto done; + } + done: if (ble_hs_hci_ack != NULL) { - ble_hci_trans_buf_free(ble_hs_hci_ack); + ble_hci_trans_buf_free((uint8_t *) ble_hs_hci_ack); ble_hs_hci_ack = NULL; } @@ -347,20 +336,7 @@ done: return rc; } -int -ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len) -{ - int rc; - - rc = ble_hs_hci_cmd_tx(opcode, cmd, cmd_len, NULL, 0, NULL); - if (rc != 0) { - return rc; - } - - return 0; -} - -void +static void ble_hs_hci_rx_ack(uint8_t *ack_ev) { if (ble_npl_sem_get_count(&ble_hs_hci_sem) > 0) { @@ -373,30 +349,27 @@ ble_hs_hci_rx_ack(uint8_t *ack_ev) /* Unblock the application now that the HCI command buffer is populated * with the acknowledgement. */ - ble_hs_hci_ack = ack_ev; + ble_hs_hci_ack = (struct ble_hci_ev *) ack_ev; ble_npl_sem_release(&ble_hs_hci_sem); } int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) { - int enqueue = 0; + struct ble_hci_ev *ev = (void *) hci_ev; + struct ble_hci_ev_command_complete *cmd_complete = (void *) ev->data; + struct ble_hci_ev_command_status *cmd_status = (void *) ev->data; + int enqueue; BLE_HS_DBG_ASSERT(hci_ev != NULL); - switch (hci_ev[0]) { + switch (ev->opcode) { case BLE_HCI_EVCODE_COMMAND_COMPLETE: - if (hci_ev[3] == 0 && hci_ev[4] == 0) { - enqueue = 1; - } + enqueue = (cmd_complete->opcode == BLE_HCI_OPCODE_NOP); break; - case BLE_HCI_EVCODE_COMMAND_STATUS: - if (hci_ev[4] == 0 && hci_ev[5] == 0) { - enqueue = 1; - } + enqueue = (cmd_status->opcode == BLE_HCI_OPCODE_NOP); break; - default: enqueue = 1; break; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_cmd.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_cmd.c index 38acdaa34..7aa9e4e74 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_cmd.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_cmd.c @@ -25,21 +25,31 @@ #include "nimble/hci_common.h" #include "nimble/ble_hci_trans.h" #include "host/ble_monitor.h" -#include "ble_hs_dbg_priv.h" #include "ble_hs_priv.h" #include "ble_monitor_priv.h" +/* + * HCI Command Header + * + * Comprises the following fields + * -> Opcode group field & Opcode command field (2) + * -> Parameter Length (1) + * Length of all the parameters (does not include any part of the hci + * command header + */ +#define BLE_HCI_CMD_HDR_LEN (3) + static int -ble_hs_hci_cmd_transport(uint8_t *cmdbuf) +ble_hs_hci_cmd_transport(struct ble_hci_cmd *cmd) { int rc; #if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_COMMAND_PKT, cmdbuf, - cmdbuf[2] + BLE_HCI_CMD_HDR_LEN); + ble_monitor_send(BLE_MONITOR_OPCODE_COMMAND_PKT, cmd, + cmd->length + sizeof(*cmd)); #endif - rc = ble_hci_trans_hs_cmd_tx(cmdbuf); + rc = ble_hci_trans_hs_cmd_tx((uint8_t *) cmd); switch (rc) { case 0: return 0; @@ -52,19 +62,6 @@ ble_hs_hci_cmd_transport(uint8_t *cmdbuf) } } -void -ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, void *buf) -{ - uint16_t opcode; - uint8_t *u8ptr; - - u8ptr = buf; - - opcode = (ogf << 10) | ocf; - put_le16(u8ptr, opcode); - u8ptr[2] = len; -} - static int ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) { @@ -90,7 +87,7 @@ ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) #endif buf--; - rc = ble_hs_hci_cmd_transport(buf); + rc = ble_hs_hci_cmd_transport((void *) buf); if (rc == 0) { STATS_INC(ble_hs_stats, hci_cmd); @@ -102,7 +99,7 @@ ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) } int -ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len) +ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len) { switch (ble_hs_sync_state) { case BLE_HS_SYNC_STATE_BAD: @@ -124,1726 +121,3 @@ ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len) return ble_hs_hci_cmd_send(opcode, buf_len, buf); } - - -/** - * Send a LE command from the host to the controller. - * - * @param ocf - * @param len - * @param cmddata - * - * @return int - */ -static int -ble_hs_hci_cmd_le_send(uint16_t ocf, uint8_t len, void *cmddata) -{ - return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE, ocf), len, cmddata); -} - -static int -ble_hs_hci_cmd_body_le_whitelist_chg(const uint8_t *addr, uint8_t addr_type, - uint8_t *dst) -{ - if (addr_type > BLE_ADDR_RANDOM) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = addr_type; - memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN); - - return 0; -} - -static int -ble_hs_hci_cmd_body_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst) -{ - uint16_t itvl; - - BLE_HS_DBG_ASSERT(adv != NULL); - - /* Make sure parameters are valid */ - if ((adv->adv_itvl_min > adv->adv_itvl_max) || - (adv->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) || - (adv->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX) || - (adv->adv_filter_policy > BLE_HCI_ADV_FILT_MAX) || - (adv->adv_type > BLE_HCI_ADV_TYPE_MAX) || - (adv->adv_channel_map == 0) || - ((adv->adv_channel_map & 0xF8) != 0)) { - /* These parameters are not valid */ - return -1; - } - -/* When build with nimBLE controller we know it is BT5 compliant so no need - * to limit non-connectable advertising interval - */ -#if MYNEWT_VAL(BLE_CONTROLLER) - itvl = BLE_HCI_ADV_ITVL_MIN; -#else -#if MYNEWT_VAL(ESP_BLE_MESH) - itvl = BLE_HCI_ADV_ITVL_MIN; -#else - /* Make sure interval is valid for advertising type. */ - if (((adv->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) || - (adv->adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND)) && - ble_hs_hci_get_hci_version() < BLE_HCI_VER_BCS_5_0) { - itvl = BLE_HCI_ADV_ITVL_NONCONN_MIN; - } else { - itvl = BLE_HCI_ADV_ITVL_MIN; - } -#endif -#endif - - /* Do not check if high duty-cycle directed */ - if (adv->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) { - if ((adv->adv_itvl_min < itvl) || - (adv->adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) { - return -1; - } - } - - put_le16(dst, adv->adv_itvl_min); - put_le16(dst + 2, adv->adv_itvl_max); - dst[4] = adv->adv_type; - dst[5] = adv->own_addr_type; - dst[6] = adv->peer_addr_type; - memcpy(dst + 7, adv->peer_addr, BLE_DEV_ADDR_LEN); - dst[13] = adv->adv_channel_map; - dst[14] = adv->adv_filter_policy; - - return 0; -} - -int -ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_PARAM_LEN); - - return ble_hs_hci_cmd_body_le_set_adv_params(adv, dst); -} - -/** - * Set advertising data - * - * OGF = 0x08 (LE) - * OCF = 0x0008 - * - * @param data - * @param len - * @param dst - * - * @return int - */ -static int -ble_hs_hci_cmd_body_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst) -{ - /* Check for valid parameters */ - if (((data == NULL) && (len != 0)) || (len > BLE_HCI_MAX_ADV_DATA_LEN)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - memset(dst, 0, BLE_HCI_SET_ADV_DATA_LEN); - dst[0] = len; - memcpy(dst + 1, data, len); - - return 0; -} - -/** - * Set advertising data - * - * OGF = 0x08 (LE) - * OCF = 0x0008 - * - * @param data - * @param len - * @param dst - * - * @return int - */ -int -ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_DATA_LEN); - - return ble_hs_hci_cmd_body_le_set_adv_data(data, len, dst); -} - -static int -ble_hs_hci_cmd_body_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst) -{ - /* Check for valid parameters */ - if (((data == NULL) && (len != 0)) || - (len > BLE_HCI_MAX_SCAN_RSP_DATA_LEN)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - memset(dst, 0, BLE_HCI_SET_SCAN_RSP_DATA_LEN); - dst[0] = len; - memcpy(dst + 1, data, len); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_RSP_DATA_LEN); - - return ble_hs_hci_cmd_body_le_set_scan_rsp_data(data, len, dst); -} - -static void -ble_hs_hci_cmd_body_set_event_mask(uint64_t event_mask, uint8_t *dst) -{ - put_le64(dst, event_mask); -} - -void -ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_EVENT_MASK_LEN); - - ble_hs_hci_cmd_body_set_event_mask(event_mask, dst); -} - -void -ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_EVENT_MASK_LEN); - - ble_hs_hci_cmd_body_set_event_mask(event_mask, dst); -} - -static void -ble_hs_hci_cmd_body_disconnect(uint16_t handle, uint8_t reason, uint8_t *dst) -{ - put_le16(dst + 0, handle); - dst[2] = reason; -} - -void -ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_DISCONNECT_CMD_LEN); - - ble_hs_hci_cmd_body_disconnect(handle, reason, dst); -} - -static void -ble_hs_hci_cmd_body_le_set_event_mask(uint64_t event_mask, uint8_t *dst) -{ - put_le64(dst, event_mask); -} - -void -ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_LE_EVENT_MASK_LEN); - - ble_hs_hci_cmd_body_le_set_event_mask(event_mask, dst); -} - -static void -ble_hs_hci_cmd_body_le_set_adv_enable(uint8_t enable, uint8_t *dst) -{ - dst[0] = enable; -} - -void -ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst, - int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_ENABLE_LEN); - - ble_hs_hci_cmd_body_le_set_adv_enable(enable, dst); -} - -static int -ble_hs_hci_cmd_body_le_set_scan_params( - uint8_t scan_type, uint16_t scan_itvl, uint16_t scan_window, - uint8_t own_addr_type, uint8_t filter_policy, uint8_t *dst) { - - /* Make sure parameters are valid */ - if ((scan_type != BLE_HCI_SCAN_TYPE_PASSIVE) && - (scan_type != BLE_HCI_SCAN_TYPE_ACTIVE)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check interval and window */ - if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || - (scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || - (scan_window < BLE_HCI_SCAN_WINDOW_MIN) || - (scan_window > BLE_HCI_SCAN_WINDOW_MAX) || - (scan_itvl < scan_window)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check own addr type */ - if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check scanner filter policy */ - if (filter_policy > BLE_HCI_SCAN_FILT_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = scan_type; - put_le16(dst + 1, scan_itvl); - put_le16(dst + 3, scan_window); - dst[5] = own_addr_type; - dst[6] = filter_policy; - - return 0; -} - -int -ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type, - uint16_t scan_itvl, - uint16_t scan_window, - uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_PARAM_LEN); - - return ble_hs_hci_cmd_body_le_set_scan_params(scan_type, scan_itvl, - scan_window, own_addr_type, - filter_policy, dst); -} - -static void -ble_hs_hci_cmd_body_le_set_scan_enable(uint8_t enable, uint8_t filter_dups, - uint8_t *dst) -{ - dst[0] = enable; - dst[1] = filter_dups; -} - -void -ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, uint8_t filter_dups, - uint8_t *dst, uint8_t dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_ENABLE_LEN); - - ble_hs_hci_cmd_body_le_set_scan_enable(enable, filter_dups, dst); -} - -static int -ble_hs_hci_cmd_body_le_create_connection(const struct hci_create_conn *hcc, - uint8_t *cmd) -{ - /* Check scan interval and scan window */ - if ((hcc->scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || - (hcc->scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || - (hcc->scan_window < BLE_HCI_SCAN_WINDOW_MIN) || - (hcc->scan_window > BLE_HCI_SCAN_WINDOW_MAX) || - (hcc->scan_itvl < hcc->scan_window)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check initiator filter policy */ - if (hcc->filter_policy > BLE_HCI_CONN_FILT_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check peer addr type */ - if (hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check own addr type */ - if (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection interval min */ - if ((hcc->conn_itvl_min < BLE_HCI_CONN_ITVL_MIN) || - (hcc->conn_itvl_min > BLE_HCI_CONN_ITVL_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection interval max */ - if ((hcc->conn_itvl_max < BLE_HCI_CONN_ITVL_MIN) || - (hcc->conn_itvl_max > BLE_HCI_CONN_ITVL_MAX) || - (hcc->conn_itvl_max < hcc->conn_itvl_min)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection latency */ - if ( -#if BLE_HCI_CONN_LATENCY_MIN - (hcc->conn_latency < BLE_HCI_CONN_LATENCY_MIN) || -#endif - (hcc->conn_latency > BLE_HCI_CONN_LATENCY_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check supervision timeout */ - if ((hcc->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || - (hcc->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection event length */ - if (hcc->min_ce_len > hcc->max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - put_le16(cmd + 0, hcc->scan_itvl); - put_le16(cmd + 2, hcc->scan_window); - cmd[4] = hcc->filter_policy; - cmd[5] = hcc->peer_addr_type; - memcpy(cmd + 6, hcc->peer_addr, BLE_DEV_ADDR_LEN); - cmd[12] = hcc->own_addr_type; - put_le16(cmd + 13, hcc->conn_itvl_min); - put_le16(cmd + 15, hcc->conn_itvl_max); - put_le16(cmd + 17, hcc->conn_latency); - put_le16(cmd + 19, hcc->supervision_timeout); - put_le16(cmd + 21, hcc->min_ce_len); - put_le16(cmd + 23, hcc->max_ce_len); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_create_connection(const struct hci_create_conn *hcc, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_CREATE_CONN_LEN); - - return ble_hs_hci_cmd_body_le_create_connection(hcc, cmd); -} - -int -ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr, - uint8_t addr_type, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_ADD_WHITE_LIST_LEN); - - return ble_hs_hci_cmd_body_le_whitelist_chg(addr, addr_type, dst); -} - -/** - * Reset the controller and link manager. - * - * @return int - */ -int -ble_hs_hci_cmd_reset(void) -{ - return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, - BLE_HCI_OCF_CB_RESET), - 0, NULL); -} - -/** Set controller to host flow control (OGF 0x03, OCF 0x0031). */ -int -ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable) -{ - if (fc_enable > BLE_HCI_CTLR_TO_HOST_FC_BOTH) { - return BLE_HS_EINVAL; - } - - return ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, - BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC), - &fc_enable, 1); -} - -/* Host buffer size (OGF 0x03, OCF 0x0033). */ -int -ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd) -{ - uint8_t buf[BLE_HCI_HOST_BUF_SIZE_LEN]; - - put_le16(buf + 0, cmd->acl_pkt_len); - buf[2] = cmd->sync_pkt_len; - put_le16(buf + 3, cmd->num_acl_pkts); - put_le16(buf + 5, cmd->num_sync_pkts); - - return ble_hs_hci_cmd_tx_empty_ack( - BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_HOST_BUF_SIZE), - buf, sizeof buf); -} - -/* Host number of completed packets (OGF 0x03, OCF 0x0035). */ -int -ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - const struct hci_host_num_comp_pkts_entry *entry, - uint8_t *dst, int dst_len) -{ - if (dst_len < BLE_HCI_HOST_NUM_COMP_PKTS_ENT_LEN) { - return BLE_HS_EMSGSIZE; - } - - put_le16(dst + 0, entry->conn_handle); - put_le16(dst + 2, entry->num_pkts); - - return 0; -} - -/** - * Read the transmit power level used for LE advertising channel packets. - * - * @return int - */ -int -ble_hs_hci_cmd_read_adv_pwr(void) -{ - return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR), - 0, NULL); -} - -int -ble_hs_hci_cmd_le_create_conn_cancel(void) -{ - return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CREATE_CONN_CANCEL), - 0, NULL); -} - -static int -ble_hs_hci_cmd_body_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst) -{ - /* XXX: add parameter checking later */ - put_le16(dst + 0, hcu->handle); - put_le16(dst + 2, hcu->conn_itvl_min); - put_le16(dst + 4, hcu->conn_itvl_max); - put_le16(dst + 6, hcu->conn_latency); - put_le16(dst + 8, hcu->supervision_timeout); - put_le16(dst + 10, hcu->min_ce_len); - put_le16(dst + 12, hcu->max_ce_len); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_UPDATE_LEN); - - return ble_hs_hci_cmd_body_le_conn_update(hcu, dst); -} - -int -ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu) -{ - uint8_t cmd[BLE_HCI_CONN_UPDATE_LEN]; - int rc; - - rc = ble_hs_hci_cmd_body_le_conn_update(hcu, cmd); - if (rc != 0) { - return rc; - } - - return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_CONN_UPDATE, - BLE_HCI_CONN_UPDATE_LEN, cmd); -} - -static void -ble_hs_hci_cmd_body_le_lt_key_req_reply(const struct hci_lt_key_req_reply *hkr, - uint8_t *dst) -{ - put_le16(dst + 0, hkr->conn_handle); - memcpy(dst + 2, hkr->long_term_key, sizeof hkr->long_term_key); -} - -/** - * Sends the long-term key (LTK) to the controller. - * - * Note: This function expects the 128-bit key to be in little-endian byte - * order. - * - * OGF = 0x08 (LE) - * OCF = 0x001a - * - * @param key - * @param pt - * - * @return int - */ -void -ble_hs_hci_cmd_build_le_lt_key_req_reply( - const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LT_KEY_REQ_REPLY_LEN); - - ble_hs_hci_cmd_body_le_lt_key_req_reply(hkr, dst); -} - -void -ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN); - - put_le16(dst, conn_handle); -} - -static void -ble_hs_hci_cmd_body_le_conn_param_reply(const struct hci_conn_param_reply *hcr, - uint8_t *dst) -{ - put_le16(dst + 0, hcr->handle); - put_le16(dst + 2, hcr->conn_itvl_min); - put_le16(dst + 4, hcr->conn_itvl_max); - put_le16(dst + 6, hcr->conn_latency); - put_le16(dst + 8, hcr->supervision_timeout); - put_le16(dst + 10, hcr->min_ce_len); - put_le16(dst + 12, hcr->max_ce_len); -} - -void -ble_hs_hci_cmd_build_le_conn_param_reply( - const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_PARAM_REPLY_LEN); - - ble_hs_hci_cmd_body_le_conn_param_reply(hcr, dst); -} - -int -ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr) -{ - uint8_t cmd[BLE_HCI_CONN_PARAM_REPLY_LEN]; - - put_le16(cmd + 0, hcr->handle); - put_le16(cmd + 2, hcr->conn_itvl_min); - put_le16(cmd + 4, hcr->conn_itvl_max); - put_le16(cmd + 6, hcr->conn_latency); - put_le16(cmd + 8, hcr->supervision_timeout); - put_le16(cmd + 10, hcr->min_ce_len); - put_le16(cmd + 12, hcr->max_ce_len); - - return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_REM_CONN_PARAM_RR, - BLE_HCI_CONN_PARAM_REPLY_LEN, cmd); -} - -static void -ble_hs_hci_cmd_body_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst) -{ - put_le16(dst + 0, hcn->handle); - dst[2] = hcn->reason; -} - - -void -ble_hs_hci_cmd_build_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_PARAM_NEG_REPLY_LEN); - - ble_hs_hci_cmd_body_le_conn_param_neg_reply(hcn, dst); -} - -int -ble_hs_hci_cmd_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn) -{ - uint8_t cmd[BLE_HCI_CONN_PARAM_NEG_REPLY_LEN]; - - ble_hs_hci_cmd_body_le_conn_param_neg_reply(hcn, cmd); - - return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR, - BLE_HCI_CONN_PARAM_NEG_REPLY_LEN, cmd); -} - -static void -ble_hs_hci_cmd_body_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst) -{ - put_le16(dst + 0, cmd->connection_handle); - put_le64(dst + 2, cmd->random_number); - put_le16(dst + 10, cmd->encrypted_diversifier); - memcpy(dst + 12, cmd->long_term_key, sizeof cmd->long_term_key); -} - -/* - * OGF=0x08 OCF=0x0019 - */ -void -ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_START_ENCRYPT_LEN); - - ble_hs_hci_cmd_body_le_start_encrypt(cmd, dst); -} - -/** - * Read the RSSI for a given connection handle - * - * NOTE: OGF=0x05 OCF=0x0005 - * - * @param handle - * - * @return int - */ -static void -ble_hs_hci_cmd_body_read_rssi(uint16_t handle, uint8_t *dst) -{ - put_le16(dst, handle); -} - -void -ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_READ_RSSI_LEN); - - ble_hs_hci_cmd_body_read_rssi(handle, dst); -} - -/** - * LE Set Host Channel Classification - * - * OGF = 0x08 (LE) - * OCF = 0x0014 - */ -void -ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_HOST_CHAN_CLASS_LEN); - - memcpy(dst, chan_map, BLE_HCI_SET_HOST_CHAN_CLASS_LEN); -} - -/** - * LE Read Channel Map - * - * OGF = 0x08 (LE) - * OCF = 0x0015 - */ -void -ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_CHANMAP_LEN); - - put_le16(dst + 0, conn_handle); -} - -static int -ble_hs_hci_cmd_body_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, - uint16_t tx_time, uint8_t *dst) -{ - - if (tx_octets < BLE_HCI_SET_DATALEN_TX_OCTETS_MIN || - tx_octets > BLE_HCI_SET_DATALEN_TX_OCTETS_MAX) { - - return BLE_HS_EINVAL; - } - - if (tx_time < BLE_HCI_SET_DATALEN_TX_TIME_MIN || - tx_time > BLE_HCI_SET_DATALEN_TX_TIME_MAX) { - - return BLE_HS_EINVAL; - } - - put_le16(dst + 0, connection_handle); - put_le16(dst + 2, tx_octets); - put_le16(dst + 4, tx_time); - - return 0; -} - -/* - * OGF=0x08 OCF=0x0022 - */ -int -ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, uint16_t tx_time, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_DATALEN_LEN); - - return ble_hs_hci_cmd_body_set_data_len(connection_handle, tx_octets, - tx_time, dst); -} - -/** - * IRKs are in little endian. - */ -static int -ble_hs_hci_cmd_body_add_to_resolv_list(uint8_t addr_type, const uint8_t *addr, - const uint8_t *peer_irk, - const uint8_t *local_irk, - uint8_t *dst) -{ - if (addr_type > BLE_ADDR_RANDOM) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = addr_type; - memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN); - memcpy(dst + 1 + 6, peer_irk , 16); - memcpy(dst + 1 + 6 + 16, local_irk , 16); - /* 16 + 16 + 6 + 1 == 39 */ - return 0; -} - -/** - * OGF=0x08 OCF=0x0027 - * - * IRKs are in little endian. - */ -int -ble_hs_hci_cmd_build_add_to_resolv_list( - const struct hci_add_dev_to_resolving_list *padd, - uint8_t *dst, - int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_ADD_TO_RESOLV_LIST_LEN); - - return ble_hs_hci_cmd_body_add_to_resolv_list( - padd->addr_type, padd->addr, padd->peer_irk, padd->local_irk, dst); -} - -static int -ble_hs_hci_cmd_body_remove_from_resolv_list(uint8_t addr_type, - const uint8_t *addr, - uint8_t *dst) -{ - if (addr_type > BLE_ADDR_RANDOM) { - addr_type = addr_type % 2; - } - - dst[0] = addr_type; - memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN); - return 0; -} - - -int -ble_hs_hci_cmd_build_remove_from_resolv_list(uint8_t addr_type, - const uint8_t *addr, - uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RMV_FROM_RESOLV_LIST_LEN); - - return ble_hs_hci_cmd_body_remove_from_resolv_list(addr_type, addr, dst); -} - -static int -ble_hs_hci_cmd_body_read_peer_resolv_addr(uint8_t peer_identity_addr_type, - const uint8_t *peer_identity_addr, - uint8_t *dst) -{ - if (peer_identity_addr_type > BLE_ADDR_RANDOM) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = peer_identity_addr_type; - memcpy(dst + 1, peer_identity_addr, BLE_DEV_ADDR_LEN); - return 0; -} - -int -ble_hs_hci_cmd_build_read_peer_resolv_addr(uint8_t peer_identity_addr_type, - const uint8_t *peer_identity_addr, - uint8_t *dst, - int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_PEER_RESOLV_ADDR_LEN); - - return ble_hs_hci_cmd_body_read_peer_resolv_addr(peer_identity_addr_type, - peer_identity_addr, dst); -} - -static int -ble_hs_hci_cmd_body_read_lcl_resolv_addr( - uint8_t local_identity_addr_type, - const uint8_t *local_identity_addr, - uint8_t *dst) -{ - if (local_identity_addr_type > BLE_ADDR_RANDOM) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = local_identity_addr_type; - memcpy(dst + 1, local_identity_addr, BLE_DEV_ADDR_LEN); - return 0; -} - -/* - * OGF=0x08 OCF=0x002c - */ -int -ble_hs_hci_cmd_build_read_lcl_resolv_addr(uint8_t local_identity_addr_type, - const uint8_t *local_identity_addr, - uint8_t *dst, - int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_LOC_RESOLV_ADDR_LEN); - - return ble_hs_hci_cmd_body_read_lcl_resolv_addr(local_identity_addr_type, - local_identity_addr, dst); -} - -static int -ble_hs_hci_cmd_body_set_addr_res_en(uint8_t enable, uint8_t *dst) -{ - if (enable > 1) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = enable; - return 0; -} - -/* - * OGF=0x08 OCF=0x002d - */ -int -ble_hs_hci_cmd_build_set_addr_res_en(uint8_t enable, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADDR_RESOL_ENA_LEN); - - return ble_hs_hci_cmd_body_set_addr_res_en(enable, dst); -} - -static int -ble_hs_hci_cmd_body_set_resolv_priv_addr_timeout(uint16_t timeout, - uint8_t *dst) -{ - if (timeout == 0 || timeout > 0xA1B8) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - put_le16(dst, timeout); - return 0; -} - -/* - * OGF=0x08 OCF=0x002e - */ -int -ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout( - uint16_t timeout, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN); - - return ble_hs_hci_cmd_body_set_resolv_priv_addr_timeout(timeout, dst); -} - -/* - * OGF=0x08 OCF=0x0030 - */ -int -ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_RD_PHY_LEN); - - put_le16(dst, conn_handle); - - return 0; -} - -static int -ble_hs_hci_verify_le_phy_params(uint8_t tx_phys_mask, uint8_t rx_phys_mask, - uint16_t phy_opts) -{ - if (tx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | - BLE_HCI_LE_PHY_2M_PREF_MASK | - BLE_HCI_LE_PHY_CODED_PREF_MASK)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - if (rx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | - BLE_HCI_LE_PHY_2M_PREF_MASK | - BLE_HCI_LE_PHY_CODED_PREF_MASK)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - if (phy_opts > BLE_HCI_LE_PHY_CODED_S8_PREF) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - return 0; -} - -static int -ble_hs_hci_cmd_body_le_set_default_phy(uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint8_t *dst) -{ - int rc; - - rc = ble_hs_hci_verify_le_phy_params(tx_phys_mask, rx_phys_mask, 0); - if (rc !=0 ) { - return rc; - } - - if (tx_phys_mask == 0) { - dst[0] |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK; - } else { - dst[1] = tx_phys_mask; - } - - if (rx_phys_mask == 0){ - dst[0] |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK; - } else { - dst[2] = rx_phys_mask; - } - - return 0; -} - -/* - * OGF=0x08 OCF=0x0031 - */ -int -ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask, - uint8_t *dst, int dst_len) -{ - - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_DEFAULT_PHY_LEN); - - memset(dst, 0, dst_len); - - return ble_hs_hci_cmd_body_le_set_default_phy(tx_phys_mask, rx_phys_mask, - dst); -} - -static int -ble_hs_hci_cmd_body_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst) -{ - int rc; - - rc = ble_hs_hci_verify_le_phy_params(tx_phys_mask, rx_phys_mask, phy_opts); - if (rc != 0) { - return rc; - } - - put_le16(dst, conn_handle); - - if (tx_phys_mask == 0) { - dst[2] |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK; - } else { - dst[3] = tx_phys_mask; - } - - if (rx_phys_mask == 0){ - dst[2] |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK; - } else { - dst[4] = rx_phys_mask; - } - - put_le16(dst + 5, phy_opts); - - return 0; -} - -/* - * OGF=0x08 OCF=0x0032 - */ -int -ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst, int dst_len) -{ - - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_PHY_LEN); - - memset(dst, 0, dst_len); - - return ble_hs_hci_cmd_body_le_set_phy(conn_handle, tx_phys_mask, - rx_phys_mask, phy_opts, dst); -} - -static int -ble_hs_hci_cmd_body_le_enhanced_recv_test(uint8_t chan, uint8_t phy, - uint8_t mod_idx, uint8_t *dst) -{ - /* Parameters check according to Bluetooth 5.0 Vol 2, Part E - * 7.8.50 LE Enhanced Receiver Test Command - */ - if (phy > BLE_HCI_LE_PHY_CODED || chan > 0x27 || mod_idx > 1) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = chan; - dst[1] = phy; - dst[2] = mod_idx; - - return 0; -} - -/* - * OGF=0x08 OCF=0x0033 - */ -int -ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy, - uint8_t mod_idx, - uint8_t *dst, uint16_t dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_ENH_RX_TEST_LEN); - - return ble_hs_hci_cmd_body_le_enhanced_recv_test(rx_chan, phy, mod_idx, dst); -} - -static int -ble_hs_hci_cmd_body_le_enhanced_trans_test(uint8_t chan, uint8_t test_data_len, - uint8_t packet_payload_idx, - uint8_t phy, - uint8_t *dst) -{ - /* Parameters check according to Bluetooth 5.0 Vol 2, Part E - * 7.8.51 LE Enhanced Transmitter Test Command - */ - if (phy > BLE_HCI_LE_PHY_CODED_S2 || chan > 0x27 || - packet_payload_idx > 0x07) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = chan; - dst[1] = test_data_len; - dst[2] = packet_payload_idx; - dst[3] = phy; - - return 0; -} - -/* - * OGF=0x08 OCF=0x0034 - */ -int -ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, uint8_t test_data_len, - uint8_t packet_payload_idx, uint8_t phy, - uint8_t *dst, uint16_t dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_ENH_TX_TEST_LEN); - - return ble_hs_hci_cmd_body_le_enhanced_trans_test(tx_chan, test_data_len, - packet_payload_idx, - phy, dst); -} - -#if MYNEWT_VAL(BLE_EXT_ADV) -static int -ble_hs_hci_check_scan_params(uint16_t scan_itvl, uint16_t scan_window) -{ - /* Check interval and window */ - if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || - (scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || - (scan_window < BLE_HCI_SCAN_WINDOW_MIN) || - (scan_window > BLE_HCI_SCAN_WINDOW_MAX) || - (scan_itvl < scan_window)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - return 0; -} - -static int -ble_hs_hci_cmd_body_le_set_ext_scan_param(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst) -{ - int i; - int rc; - uint8_t *dst_params; - struct ble_hs_hci_ext_scan_param *p; - - if (phy_mask > - (BLE_HCI_LE_PHY_1M_PREF_MASK | BLE_HCI_LE_PHY_CODED_PREF_MASK)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check own addr type */ - if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check scanner filter policy */ - if (filter_policy > BLE_HCI_SCAN_FILT_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = own_addr_type; - dst[1] = filter_policy; - dst[2] = phy_mask; - dst_params = &dst[3]; - - for (i = 0; i < phy_count; i++) { - p = (*params) + i; - rc = ble_hs_hci_check_scan_params(p->scan_itvl, p->scan_window); - if (rc) { - return rc; - } - - dst_params[0] = p->scan_type; - put_le16(dst_params + 1, p->scan_itvl); - put_le16(dst_params + 3, p->scan_window); - - dst_params += BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN; - } - - return 0; -} - -/* - * OGF=0x08 OCF=0x0041 - */ -int -ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst, uint16_t dst_len) -{ - if (phy_count == 0) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_EXT_SCAN_BASE_LEN + - BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN * phy_count); - - return ble_hs_hci_cmd_body_le_set_ext_scan_param(own_addr_type, - filter_policy, - phy_mask, - phy_count, - params, - dst); -} - -static int -ble_hs_hci_cmd_body_le_set_ext_scan_enable(uint8_t enable, uint8_t filter_dups, - uint16_t duration, uint16_t period, - uint8_t *dst) -{ - if (enable > 0x01 || filter_dups > 0x03) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = enable; - dst[1] = filter_dups; - put_le16(dst + 2, duration); - put_le16(dst + 4, period); - - return 0; -} - -/* - * OGF=0x08 OCF=0x0042 - */ -int -ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint16_t duration, - uint16_t period, - uint8_t *dst, uint16_t dst_len) -{ - - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN); - - return ble_hs_hci_cmd_body_le_set_ext_scan_enable(enable, filter_dups, - duration, period, dst); -} - -static int -ble_hs_hci_check_conn_params(uint8_t phy, - const struct hci_ext_conn_params *params) -{ - if (phy != BLE_HCI_LE_PHY_2M) { - if (ble_hs_hci_check_scan_params(params->scan_itvl, params->scan_window)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - } - /* Check connection interval min */ - if ((params->conn_itvl_min < BLE_HCI_CONN_ITVL_MIN) || - (params->conn_itvl_min > BLE_HCI_CONN_ITVL_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - /* Check connection interval max */ - if ((params->conn_itvl_max < BLE_HCI_CONN_ITVL_MIN) || - (params->conn_itvl_max > BLE_HCI_CONN_ITVL_MAX) || - (params->conn_itvl_max < params->conn_itvl_min)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection latency */ - if ( -#if BLE_HCI_CONN_LATENCY_MIN - (params->conn_latency < BLE_HCI_CONN_LATENCY_MIN) || -#endif - (params->conn_latency > BLE_HCI_CONN_LATENCY_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check supervision timeout */ - if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || - (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection event length */ - if (params->min_ce_len > params->max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - return 0; -} - -static int -ble_hs_hci_cmd_body_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd) -{ - int iter = 0; - const struct hci_ext_conn_params *params; - - /* Check initiator filter policy */ - if (hcc->filter_policy > BLE_HCI_CONN_FILT_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - cmd[iter] = hcc->filter_policy; - iter++; - /* Check own addr type */ - if (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - cmd[iter] = hcc->own_addr_type; - iter++; - - /* Check peer addr type */ - if (hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - cmd[iter] = hcc->peer_addr_type; - iter++; - - memcpy(cmd + iter, hcc->peer_addr, BLE_DEV_ADDR_LEN); - iter += BLE_DEV_ADDR_LEN; - - if (hcc->init_phy_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | - BLE_HCI_LE_PHY_2M_PREF_MASK | - BLE_HCI_LE_PHY_CODED_PREF_MASK)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - cmd[iter] = hcc->init_phy_mask; - iter++; - - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_1M_PREF_MASK) { - params = &hcc->params[0]; - if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_1M, params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - put_le16(cmd + iter, params->scan_itvl); - put_le16(cmd + iter + 2, params->scan_window); - put_le16(cmd + iter + 4, params->conn_itvl_min); - put_le16(cmd + iter + 6, params->conn_itvl_max); - put_le16(cmd + iter + 8, params->conn_latency); - put_le16(cmd + iter + 10, params->supervision_timeout); - put_le16(cmd + iter + 12, params->min_ce_len); - put_le16(cmd + iter + 14, params->max_ce_len); - iter += 16; - } - - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_2M_PREF_MASK) { - params = &hcc->params[1]; - if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_2M, params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - put_le16(cmd + iter, 0); - put_le16(cmd + iter + 2, 0); - put_le16(cmd + iter + 4, params->conn_itvl_min); - put_le16(cmd + iter + 6, params->conn_itvl_max); - put_le16(cmd + iter + 8, params->conn_latency); - put_le16(cmd + iter + 10, params->supervision_timeout); - put_le16(cmd + iter + 12, params->min_ce_len); - put_le16(cmd + iter + 14, params->max_ce_len); - iter += 16; - } - - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_CODED_PREF_MASK) { - params = &hcc->params[2]; - if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_CODED, params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - put_le16(cmd + iter, params->scan_itvl); - put_le16(cmd + iter + 2, params->scan_window); - put_le16(cmd + iter + 4, params->conn_itvl_min); - put_le16(cmd + iter + 6, params->conn_itvl_max); - put_le16(cmd + iter + 8, params->conn_latency); - put_le16(cmd + iter + 10, params->supervision_timeout); - put_le16(cmd + iter + 12, params->min_ce_len); - put_le16(cmd + iter + 14, params->max_ce_len); - iter += 16; - } - - return 0; -} - -int -ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd, int cmd_len) -{ - uint8_t size; - - size = BLE_HCI_LE_EXT_CREATE_CONN_BASE_LEN; - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_1M_PREF_MASK) { - size += sizeof(struct hci_ext_conn_params); - } - - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_2M_PREF_MASK) { - size += sizeof(struct hci_ext_conn_params); - } - - if (hcc->init_phy_mask & BLE_HCI_LE_PHY_CODED_PREF_MASK) { - size += sizeof(struct hci_ext_conn_params); - } - - BLE_HS_DBG_ASSERT(cmd_len >= size); - - return ble_hs_hci_cmd_body_le_ext_create_conn(hcc, cmd); -} - -int -ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle, - const uint8_t *addr, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN); - - cmd[0] = handle; - memcpy(cmd + 1, addr, BLE_DEV_ADDR_LEN); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation, - uint8_t frag_pref, struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len); - - cmd[0] = handle; - cmd[1] = operation; - cmd[2] = frag_pref; - cmd[3] = data_len; - os_mbuf_copydata(data, 0, data_len, cmd + 4); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num, - const struct hci_ext_adv_set *sets, - uint8_t *cmd, int cmd_len) -{ - int i; - - BLE_HS_DBG_ASSERT(cmd_len >= 2 + (sets_num * 4)); - - cmd[0] = enable; - cmd[1] = sets_num; - - cmd += 2; - - for (i = 0; i < sets_num; i++) { - cmd[0] = sets[i].handle; - put_le16(&cmd[1], sets[i].duration); - cmd[3] = sets[i].events; - - cmd += 4; - } - - return 0; -} - -int -ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle, - const struct hci_ext_adv_params *params, - uint8_t *cmd, int cmd_len) -{ - uint32_t tmp; - - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN); - - cmd[0] = handle; - put_le16(&cmd[1], params->properties); - - tmp = htole32(params->min_interval); - memcpy(&cmd[3], &tmp, 3); - - tmp = htole32(params->max_interval); - memcpy(&cmd[6], &tmp, 3); - - cmd[9] = params->chan_map; - cmd[10] = params->own_addr_type; - cmd[11] = params->peer_addr_type; - memcpy(&cmd[12], params->peer_addr, BLE_DEV_ADDR_LEN); - cmd[18] = params->filter_policy; - cmd[19] = params->tx_power; - cmd[20] = params->primary_phy; - cmd[21] = params->max_skip; - cmd[22] = params->secondary_phy; - cmd[23] = params->sid; - cmd[24] = params->scan_req_notif; - - return 0; -} -int -ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_REMOVE_ADV_SET_LEN); - - cmd[0] = handle; - - return 0; -} - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -int -ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle, - const struct hci_periodic_adv_params *params, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN); - - if (handle > 0xEF){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (params->max_interval > 0xFFFF || params->max_interval < 6){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (params->min_interval > 0xFFFF || params->min_interval < 6){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = handle; - - put_le16(&cmd[1], params->min_interval); - put_le16(&cmd[3], params->max_interval); - put_le16(&cmd[5], params->properties); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable, - uint8_t handle, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN); - - if (enable > 1){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = enable; - cmd[1] = handle; - - return 0; -} - -int -ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, - uint8_t operation, - struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= 3 + data_len); - - if (!data){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (!data->om_data){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (handle > 0xEF){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = handle; - cmd[1] = operation; - cmd[2] = data_len; - os_mbuf_copydata(data, 0, data_len, cmd + 3); - - return 0; -} - -int -ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy, - uint8_t adv_sid, - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint16_t skip, - uint16_t sync_timeout, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN); - - if (filter_policy > 1 || adv_add_type > 1){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (adv_sid > 0x0f){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - if (skip > 0x1f3 || sync_timeout > 0x4000 || sync_timeout < 0x0A){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - cmd[0] = filter_policy; - cmd[1] = adv_sid; - cmd[2] = adv_add_type; - memcpy(&cmd[3], adv_addr, 6); - put_le16(&cmd[9], skip); - put_le16(&cmd[11], sync_timeout); - cmd[13] = 0x00; - return 0; -} - -int -ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN); - - if (sync_handle > 0xEF){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = sync_handle; - - return 0; -} - -int -ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list( - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN); - - if (adv_add_type > 1 || adv_sid > 0x0f){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = adv_add_type; - memcpy(&cmd[1], adv_addr, 6); - cmd[7] = adv_sid; - - return 0; -} - -int -ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list( - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len) -{ - BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN); - - if (adv_add_type > 1 || adv_sid > 0x0f){ - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - cmd[0] = adv_add_type; - memcpy(&cmd[1], adv_addr, 6); - cmd[7] = adv_sid; - - return 0; -} -#endif - -#endif - -static int -ble_hs_hci_cmd_body_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst) -{ - /* In this command addr type can be either: - * - public identity (0x00) - * - random (static) identity (0x01) - */ - if (addr_type > BLE_ADDR_RANDOM) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - dst[0] = addr_type; - memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN); - dst[7] = priv_mode; - - return 0; -} - -/* - * OGF=0x08 OCF=0x004e - */ -int -ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst, - uint16_t dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_PRIVACY_MODE_LEN); - - return ble_hs_hci_cmd_body_le_set_priv_mode(addr, addr_type, priv_mode, dst); -} - -static int -ble_hs_hci_cmd_body_set_random_addr(const struct hci_rand_addr *paddr, - uint8_t *dst) -{ - memcpy(dst, paddr->addr, BLE_DEV_ADDR_LEN); - return 0; -} - -int -ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr, - uint8_t *dst, int dst_len) -{ - struct hci_rand_addr r_addr; - - memcpy(r_addr.addr, addr, sizeof(r_addr.addr)); - - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_RAND_ADDR_LEN); - - return ble_hs_hci_cmd_body_set_random_addr(&r_addr, dst); -} - -static void -ble_hs_hci_cmd_body_le_read_remote_feat(uint16_t handle, uint8_t *dst) -{ - put_le16(dst, handle); -} - -int -ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst, - int dst_len) -{ - BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_RD_REM_FEAT_LEN); - - ble_hs_hci_cmd_body_le_read_remote_feat(handle, dst); - - return 0; -} diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c index 30dc92f28..4a6b0716e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c @@ -26,13 +26,24 @@ #include "host/ble_gap.h" #include "host/ble_monitor.h" #include "ble_hs_priv.h" -#include "ble_hs_dbg_priv.h" #include "ble_hs_resolv_priv.h" +#if CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT +static uint16_t reattempt_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; +extern int ble_gap_master_connect_reattempt(uint16_t conn_handle); + +#ifdef CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT +#define MAX_REATTEMPT_ALLOWED CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT +#else +#define MAX_REATTEMPT_ALLOWED 0 +#endif +#endif + _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ, "struct hci_data_hdr must be 4 bytes"); -typedef int ble_hs_hci_evt_fn(uint8_t event_code, uint8_t *data, int len); +typedef int ble_hs_hci_evt_fn(uint8_t event_code, const void *data, + unsigned int len); static ble_hs_hci_evt_fn ble_hs_hci_evt_disconn_complete; static ble_hs_hci_evt_fn ble_hs_hci_evt_encrypt_change; static ble_hs_hci_evt_fn ble_hs_hci_evt_hw_error; @@ -40,7 +51,8 @@ static ble_hs_hci_evt_fn ble_hs_hci_evt_num_completed_pkts; static ble_hs_hci_evt_fn ble_hs_hci_evt_enc_key_refresh; static ble_hs_hci_evt_fn ble_hs_hci_evt_le_meta; -typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, uint8_t *data, int len); +typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, const void *data, + unsigned int len); static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_upd_complete; @@ -56,6 +68,9 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_estab; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_enh_conn_complete; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; + /* Statistics */ struct host_hci_stats { @@ -91,7 +106,7 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE] = ble_hs_hci_evt_le_conn_upd_complete, [BLE_HCI_LE_SUBEV_LT_KEY_REQ] = ble_hs_hci_evt_le_lt_key_req, [BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ] = ble_hs_hci_evt_le_conn_parm_req, - [BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE] = ble_hs_hci_evt_le_conn_complete, + [BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE] = ble_hs_hci_evt_le_enh_conn_complete, [BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT] = ble_hs_hci_evt_le_dir_adv_rpt, [BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE] = ble_hs_hci_evt_le_phy_update_complete, [BLE_HCI_LE_SUBEV_EXT_ADV_RPT] = ble_hs_hci_evt_le_ext_adv_rpt, @@ -102,6 +117,7 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_SCAN_TIMEOUT] = ble_hs_hci_evt_le_scan_timeout, [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ @@ -134,27 +150,50 @@ ble_hs_hci_evt_le_dispatch_find(uint8_t event_code) } static int -ble_hs_hci_evt_disconn_complete(uint8_t event_code, uint8_t *data, int len) +ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, + unsigned int len) { - struct hci_disconn_complete evt; + const struct ble_hci_ev_disconn_cmp *ev = data; const struct ble_hs_conn *conn; - if (len < BLE_HCI_EVENT_DISCONN_COMPLETE_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.status = data[2]; - evt.connection_handle = get_le16(data + 3); - evt.reason = data[5]; - ble_hs_lock(); - conn = ble_hs_conn_find(evt.connection_handle); + conn = ble_hs_conn_find(le16toh(ev->conn_handle)); if (conn != NULL) { ble_hs_hci_add_avail_pkts(conn->bhc_outstanding_pkts); } ble_hs_unlock(); - ble_gap_rx_disconn_complete(&evt); +#if CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT + int rc; + + if (ev->reason == BLE_ERR_CONN_ESTABLISHMENT && (conn != NULL)) { + BLE_HS_LOG(DEBUG, "Reattempt connection; reason = 0x%x, status = %d," + " reattempt count = %d ", ev->reason, ev->status, + reattempt_conn[ev->conn_handle]); + if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { + if (reattempt_conn[ev->conn_handle] < MAX_REATTEMPT_ALLOWED) { + reattempt_conn[ev->conn_handle] += 1; + rc = ble_gap_master_connect_reattempt(ev->conn_handle); + if (rc != 0) { + BLE_HS_LOG(DEBUG, "Master reconnect attempt failed; rc = %d", rc); + } + } else { + reattempt_conn[ev->conn_handle] = 0; + } + } + } else { + /* Disconnect completed with some other reason than + * BLE_ERR_CONN_ESTABLISHMENT, reset the corresponding reattempt count + * */ + reattempt_conn[ev->conn_handle] = 0; + } +#endif + + ble_gap_rx_disconn_complete(ev); /* The connection termination may have freed up some capacity in the * controller for additional ACL data packets. Wake up any stalled @@ -166,86 +205,68 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, uint8_t *data, int len) } static int -ble_hs_hci_evt_encrypt_change(uint8_t event_code, uint8_t *data, int len) +ble_hs_hci_evt_encrypt_change(uint8_t event_code, const void *data, + unsigned int len) { - struct hci_encrypt_change evt; + const struct ble_hci_ev_enrypt_chg *ev = data; - if (len < BLE_HCI_EVENT_ENCRYPT_CHG_LEN) { + if (len != sizeof (*ev)) { return BLE_HS_ECONTROLLER; } - evt.status = data[2]; - evt.connection_handle = get_le16(data + 3); - evt.encryption_enabled = data[5]; - - ble_sm_enc_change_rx(&evt); + ble_sm_enc_change_rx(ev); return 0; } static int -ble_hs_hci_evt_hw_error(uint8_t event_code, uint8_t *data, int len) +ble_hs_hci_evt_hw_error(uint8_t event_code, const void *data, unsigned int len) { - uint8_t hw_code; + const struct ble_hci_ev_hw_error *ev = data; - if (len < BLE_HCI_EVENT_HW_ERROR_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - hw_code = data[0]; - ble_hs_hw_error(hw_code); + ble_hs_hw_error(ev->hw_code); return 0; } static int -ble_hs_hci_evt_enc_key_refresh(uint8_t event_code, uint8_t *data, int len) +ble_hs_hci_evt_enc_key_refresh(uint8_t event_code, const void *data, + unsigned int len) { - struct hci_encrypt_key_refresh evt; + const struct ble_hci_ev_enc_key_refresh *ev = data; - if (len < BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.status = data[2]; - evt.connection_handle = get_le16(data + 3); - - ble_sm_enc_key_refresh_rx(&evt); + ble_sm_enc_key_refresh_rx(ev); return 0; } static int -ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, - int len) +ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, const void *data, + unsigned int len) { + const struct ble_hci_ev_num_comp_pkts *ev = data; struct ble_hs_conn *conn; uint16_t num_pkts; - uint16_t handle; - uint8_t num_handles; - int off; int i; - if (len < BLE_HCI_EVENT_HDR_LEN + BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN) { + if (len != sizeof(*ev) + (ev->count * sizeof(ev->completed[0]))) { return BLE_HS_ECONTROLLER; } - off = BLE_HCI_EVENT_HDR_LEN; - num_handles = data[off]; - if (len < BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN + - num_handles * BLE_HCI_EVENT_NUM_COMP_PKTS_ENT_LEN) { - return BLE_HS_ECONTROLLER; - } - off++; - - for (i = 0; i < num_handles; i++) { - handle = get_le16(data + off); - num_pkts = get_le16(data + off + 2); - off += (2 * sizeof(uint16_t)); + for (i = 0; i < ev->count; i++) { + num_pkts = le16toh(ev->completed[i].packets); if (num_pkts > 0) { ble_hs_lock(); - conn = ble_hs_conn_find(handle); + conn = ble_hs_conn_find(le16toh(ev->completed[i].handle)); if (conn != NULL) { if (conn->bhc_outstanding_pkts < num_pkts) { ble_hs_sched_reset(BLE_HS_ECONTROLLER); @@ -266,87 +287,121 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, } static int -ble_hs_hci_evt_le_meta(uint8_t event_code, uint8_t *data, int len) +ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len) { + const struct ble_hci_ev_le_meta *ev = data; ble_hs_hci_evt_le_fn *fn; - uint8_t subevent; - int rc; - if (len < BLE_HCI_EVENT_HDR_LEN + BLE_HCI_LE_MIN_LEN) { + if (len < sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - subevent = data[2]; - fn = ble_hs_hci_evt_le_dispatch_find(subevent); + fn = ble_hs_hci_evt_le_dispatch_find(ev->subevent); if (fn) { - rc = fn(subevent, data + BLE_HCI_EVENT_HDR_LEN, - len - BLE_HCI_EVENT_HDR_LEN); - if (rc != 0) { - return rc; - } + return fn(ev->subevent, data, len); } return 0; } #if MYNEWT_VAL(BLE_EXT_ADV) -static struct hci_le_conn_complete pend_conn_complete; +static struct ble_gap_conn_complete pend_conn_complete; #endif static int -ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data, + unsigned int len) { - struct hci_le_conn_complete evt; - int extended_offset = 0; + const struct ble_hci_ev_le_subev_enh_conn_complete *ev = data; + struct ble_gap_conn_complete evt; - if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) { - return BLE_HS_ECONTROLLER; - } - - /* this code processes two different events that are really similar */ - if ((subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) && - ( len < BLE_HCI_LE_ENH_CONN_COMPLETE_LEN)) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } memset(&evt, 0, sizeof(evt)); - evt.subevent_code = data[0]; - evt.status = data[1]; + evt.status = ev->status; if (evt.status == BLE_ERR_SUCCESS) { - evt.connection_handle = get_le16(data + 2); - evt.role = data[4]; - evt.peer_addr_type = data[5]; - memcpy(evt.peer_addr, data + 6, BLE_DEV_ADDR_LEN); + evt.connection_handle = le16toh(ev->conn_handle); + evt.role = ev->role; + evt.peer_addr_type = ev->peer_addr_type; + memcpy(evt.peer_addr, ev->peer_addr, BLE_DEV_ADDR_LEN); + memcpy(evt.local_rpa, ev->local_rpa, BLE_DEV_ADDR_LEN); + memcpy(evt.peer_rpa,ev->peer_rpa, BLE_DEV_ADDR_LEN); - /* enhanced connection event has the same information with these - * extra fields stuffed into the middle */ - if (subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) { - memcpy(evt.local_rpa, data + 12, BLE_DEV_ADDR_LEN); - memcpy(evt.peer_rpa, data + 18, BLE_DEV_ADDR_LEN); - extended_offset = 12; #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - /* RPA needs to be resolved here, as controller is not aware of the - * address is RPA in Host based RPA */ - if (ble_host_rpa_enabled()) { - uint8_t *local_id_rpa = ble_hs_get_rpa_local(); - memcpy(evt.local_rpa, local_id_rpa, 6); - } - - struct ble_hs_resolv_entry *rl = NULL; - ble_rpa_replace_peer_params_with_rl(evt.peer_addr, - &evt.peer_addr_type, &rl); -#endif - } else { - memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN); - memset(evt.peer_rpa, 0, BLE_DEV_ADDR_LEN); + /* RPA needs to be resolved here, as controller is not aware of the + * address is RPA in Host based RPA */ + if (ble_host_rpa_enabled()) { + uint8_t *local_id_rpa = ble_hs_get_rpa_local(); + memcpy(evt.local_rpa, local_id_rpa, BLE_DEV_ADDR_LEN); } - evt.conn_itvl = get_le16(data + 12 + extended_offset); - evt.conn_latency = get_le16(data + 14 + extended_offset); - evt.supervision_timeout = get_le16(data + 16 + extended_offset); - evt.master_clk_acc = data[18 + extended_offset]; + struct ble_hs_resolv_entry *rl = NULL; + ble_rpa_replace_peer_params_with_rl(evt.peer_addr, + &evt.peer_addr_type, &rl); +#endif + evt.conn_itvl = le16toh(ev->conn_itvl); + evt.conn_latency = le16toh(ev->conn_latency); + evt.supervision_timeout = le16toh(ev->supervision_timeout); + evt.master_clk_acc = ev->mca; + } else { +#if MYNEWT_VAL(BLE_HS_DEBUG) + evt.connection_handle = BLE_HS_CONN_HANDLE_NONE; +#endif + } + +#if MYNEWT_VAL(BLE_EXT_ADV) + if (evt.status == BLE_ERR_DIR_ADV_TMO || + evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { + /* store this until we get set terminated event with adv handle */ + memcpy(&pend_conn_complete, &evt, sizeof(evt)); + return 0; + } +#endif + return ble_gap_rx_conn_complete(&evt, 0); + +} + +static int +ble_hs_hci_evt_le_conn_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_conn_complete *ev = data; + struct ble_gap_conn_complete evt; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + memset(&evt, 0, sizeof(evt)); + + evt.status = ev->status; + + if (evt.status == BLE_ERR_SUCCESS) { + evt.connection_handle = le16toh(ev->conn_handle); + evt.role = ev->role; + evt.peer_addr_type = ev->peer_addr_type; + memcpy(evt.peer_addr, ev->peer_addr, BLE_DEV_ADDR_LEN); + +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /* RPA needs to be resolved here, as controller is not aware of the + * address is RPA in Host based RPA */ + if (ble_host_rpa_enabled()) { + uint8_t *local_id_rpa = ble_hs_get_rpa_local(); + memcpy(evt.local_rpa, local_id_rpa, BLE_DEV_ADDR_LEN); + } + + struct ble_hs_resolv_entry *rl = NULL; + ble_rpa_replace_peer_params_with_rl(evt.peer_addr, + &evt.peer_addr_type, &rl); +#endif + evt.conn_itvl = le16toh(ev->conn_itvl); + evt.conn_latency = le16toh(ev->conn_latency); + evt.supervision_timeout = le16toh(ev->supervision_timeout); + evt.master_clk_acc = ev->mca; } else { #if MYNEWT_VAL(BLE_HS_DEBUG) evt.connection_handle = BLE_HS_CONN_HANDLE_NONE; @@ -365,51 +420,58 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) } static int -ble_hs_hci_evt_le_adv_rpt_first_pass(uint8_t *data, int len) +ble_hs_hci_evt_le_adv_rpt_first_pass(const void *data, unsigned int len) { - uint8_t num_reports; - int off; + const struct ble_hci_ev_le_subev_adv_rpt *ev = data; + const struct adv_report *rpt; int i; - if (len < BLE_HCI_LE_ADV_RPT_MIN_LEN) { + if (len < sizeof(*ev)) { return BLE_HS_ECONTROLLER; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" + len -= sizeof(*ev); + data += sizeof(*ev); - num_reports = data[1]; - if (num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || - num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { + if (ev->num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || + ev->num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { return BLE_HS_EBADDATA; } - off = 2; /* Subevent code and num reports. */ - for (i = 0; i < num_reports; i++) { - /* Move past event type (1), address type (1) and address (6) */ - off += 8; - - /* Add advertising data length (N), length (1) and rssi (1) */ - off += data[off]; - off += 2; - - /* Make sure we are not past length */ - if (off > len) { + for (i = 0; i < ev->num_reports; i++) { + /* extra byte for RSSI after adv data */ + if (len < sizeof(*rpt) + 1) { return BLE_HS_ECONTROLLER; } + + rpt = data; + + len -= sizeof(*rpt) + 1; + data += sizeof(rpt) + 1; + + if (rpt->data_len > len) { + return BLE_HS_ECONTROLLER; + } + + len -= rpt->data_len; + data += rpt->data_len; } /* Make sure length was correct */ - if (off != len) { + if (len) { return BLE_HS_ECONTROLLER; } - +#pragma GCC diagnostic pop return 0; } static int -ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len) { + const struct ble_hci_ev_le_subev_adv_rpt *ev = data; struct ble_gap_disc_desc desc = {0}; - uint8_t num_reports; - int off; + const struct adv_report *rpt; int rc; int i; @@ -418,51 +480,38 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len) if (rc != 0) { return rc; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" + data += sizeof(*ev); desc.direct_addr = *BLE_ADDR_ANY; - off = 2; /* skip sub-event and num reports */ - num_reports = data[1]; - for (i = 0; i < num_reports; i++) { - desc.event_type = data[off]; - ++off; + for (i = 0; i < ev->num_reports; i++) { + rpt = data; - desc.addr.type = data[off]; - ++off; + data += sizeof(rpt) + rpt->data_len + 1; - memcpy(desc.addr.val, data + off, 6); - off += 6; - - desc.length_data = data[off]; - ++off; - - desc.data = data + off; - off += desc.length_data; - - desc.rssi = data[off]; - ++off; + desc.event_type = rpt->type; + desc.addr.type = rpt->addr_type; + memcpy(desc.addr.val, rpt->addr, BLE_DEV_ADDR_LEN); + desc.length_data = rpt->data_len; + desc.data = rpt->data; + desc.rssi = rpt->data[rpt->data_len]; ble_gap_rx_adv_report(&desc); } - +#pragma GCC diagnostic pop return 0; } static int -ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, const void *data, unsigned int len) { + const struct ble_hci_ev_le_subev_direct_adv_rpt *ev = data; struct ble_gap_disc_desc desc = {0}; - uint8_t num_reports; - int suboff; - int off; int i; - if (len < BLE_HCI_LE_ADV_DIRECT_RPT_LEN) { - return BLE_HS_ECONTROLLER; - } - - num_reports = data[1]; - if (len != 2 + num_reports * BLE_HCI_LE_ADV_DIRECT_RPT_SUB_LEN) { + if (len < sizeof(*ev) || len != ev->num_reports * sizeof(ev->reports[0])) { return BLE_HS_ECONTROLLER; } @@ -470,32 +519,13 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t *data, int len) desc.data = NULL; desc.length_data = 0; - for (i = 0; i < num_reports; i++) { - suboff = 0; - - off = 2 + suboff * num_reports + i; - desc.event_type = data[off]; - suboff++; - - off = 2 + suboff * num_reports + i; - desc.addr.type = data[off]; - suboff++; - - off = 2 + suboff * num_reports + i * 6; - memcpy(desc.addr.val, data + off, 6); - suboff += 6; - - off = 2 + suboff * num_reports + i; - desc.direct_addr.type = data[off]; - suboff++; - - off = 2 + suboff * num_reports + i * 6; - memcpy(desc.direct_addr.val, data + off, 6); - suboff += 6; - - off = 2 + suboff * num_reports + i; - desc.rssi = data[off]; - suboff++; + for (i = 0; i < ev->num_reports; i++) { + desc.event_type = ev->reports[i].type; + desc.addr.type = ev->reports[i].addr_type; + memcpy(desc.addr.val, ev->reports[i].addr, BLE_DEV_ADDR_LEN); + desc.direct_addr.type = ev->reports[i].dir_addr_type; + memcpy(desc.direct_addr.val, ev->reports[i].dir_addr, BLE_DEV_ADDR_LEN); + desc.rssi = ev->reports[i].rssi; ble_gap_rx_adv_report(&desc); } @@ -504,27 +534,21 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t *data, int len) } static int -ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, - uint8_t *data, - int len) +ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, const void *data, + unsigned int len) { - struct hci_le_rd_rem_supp_feat_complete evt; + const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev = data; - if (len < BLE_HCI_LE_RD_REM_USED_FEAT_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.status = data[1]; - evt.connection_handle = get_le16(data + 2); - memcpy(evt.features, data + 4, 8); - - ble_gap_rx_rd_rem_sup_feat_complete(&evt); + ble_gap_rx_rd_rem_sup_feat_complete(ev); return 0; } -#if MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN static int ble_hs_hci_decode_legacy_type(uint16_t evt_type) { @@ -546,47 +570,42 @@ ble_hs_hci_decode_legacy_type(uint16_t evt_type) #endif static int -ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, + unsigned int len) { -#if MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN + const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; + const struct ext_adv_report *report; struct ble_gap_ext_disc_desc desc; - struct hci_ext_adv_report *ext_adv; - struct hci_ext_adv_report_param *params; - int num_reports; int i; int legacy_event_type; - if (len < sizeof(*ext_adv)) { + if (len < sizeof(*ev)) { return BLE_HS_EBADDATA; } - ext_adv = (struct hci_ext_adv_report *) data; - num_reports = ext_adv->num_reports; - if (num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || - num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { - + if (ev->num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || + ev->num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { return BLE_HS_EBADDATA; } - if (len < (sizeof(*ext_adv) + ext_adv->num_reports * sizeof(*params))) { - return BLE_HS_ECONTROLLER; - } + /* TODO properly validate len of the event */ - params = &ext_adv->params[0]; - for (i = 0; i < num_reports; i++) { + report = &ev->reports[0]; + for (i = 0; i < ev->num_reports; i++) { memset(&desc, 0, sizeof(desc)); - desc.props = (params->evt_type) & 0x1F; + desc.props = (report->evt_type) & 0x1F; if (desc.props & BLE_HCI_ADV_LEGACY_MASK) { - legacy_event_type = ble_hs_hci_decode_legacy_type(params->evt_type); + legacy_event_type = ble_hs_hci_decode_legacy_type(report->evt_type); if (legacy_event_type < 0) { - params += 1; + report = (const void *) &report->data[report->data_len]; continue; } desc.legacy_event_type = legacy_event_type; desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE; } else { - switch(params->evt_type & BLE_HCI_ADV_DATA_STATUS_MASK) { + switch(report->evt_type & BLE_HCI_ADV_DATA_STATUS_MASK) { case BLE_HCI_ADV_DATA_STATUS_COMPLETE: desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE; break; @@ -600,296 +619,247 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len) assert(false); } } - desc.addr.type = params->addr_type; - memcpy(desc.addr.val, params->addr, 6); - desc.length_data = params->adv_data_len; - desc.data = params->adv_data; - desc.rssi = params->rssi; - desc.tx_power = params->tx_power; - memcpy(desc.direct_addr.val, params->dir_addr, 6); - desc.direct_addr.type = params->dir_addr_type; - desc.sid = params->sid; - desc.prim_phy = params->prim_phy; - desc.sec_phy = params->sec_phy; - desc.periodic_adv_itvl = params->per_adv_itvl; + desc.addr.type = report->addr_type; + memcpy(desc.addr.val, report->addr, 6); + desc.length_data = report->data_len; + desc.data = report->data; + desc.rssi = report->rssi; + desc.tx_power = report->tx_power; + memcpy(desc.direct_addr.val, report->dir_addr, 6); + desc.direct_addr.type = report->dir_addr_type; + desc.sid = report->sid; + desc.prim_phy = report->pri_phy; + desc.sec_phy = report->sec_phy; + desc.periodic_adv_itvl = report->periodic_itvl; + ble_gap_rx_ext_adv_report(&desc); - params += 1; + + report = (const void *) &report->data[report->data_len]; } #endif return 0; } static int -ble_hs_hci_evt_le_periodic_adv_sync_estab(uint8_t subevent, uint8_t *data, - int len) +ble_hs_hci_evt_le_periodic_adv_sync_estab(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_PERIODIC_ADV) - struct hci_le_subev_periodic_adv_sync_estab evt; + const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev = data; - if (len < BLE_HCI_LE_PERIODIC_ADV_SYNC_ESTAB_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.status = data[1]; - evt.sync_handle = get_le16(data + 2); - evt.sid = data[4]; - evt.adv_addr_type = data[5]; - memcpy(evt.adv_addr, &data[6], 6); - evt.adv_phy = data[12]; - evt.per_adv_ival = get_le16(data + 13); - evt.adv_clk_accuracy = data[15]; - - ble_gap_rx_peroidic_adv_sync_estab(&evt); + ble_gap_rx_peroidic_adv_sync_estab(ev); #endif return 0; } static int -ble_hs_hci_evt_le_periodic_adv_rpt(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_periodic_adv_rpt(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_PERIODIC_ADV) - struct hci_le_subev_periodic_adv_rpt* evt; + const struct ble_hci_ev_le_subev_periodic_adv_rpt *ev = data; - if (len < BLE_HCI_LE_PERIODIC_ADV_RPT_LEN) { + if (len < sizeof(*ev) || len != (sizeof(*ev) + ev->data_len)) { return BLE_HS_EBADDATA; } - evt = (struct hci_le_subev_periodic_adv_rpt *)(data + 1); - ble_gap_rx_periodic_adv_rpt(evt); + ble_gap_rx_periodic_adv_rpt(ev); #endif return 0; } static int -ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, uint8_t *data, - int len) +ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_PERIODIC_ADV) - struct hci_le_subev_periodic_adv_sync_lost evt; + const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev = data; - if (len < BLE_HCI_LE_PERIODIC_ADV_SYNC_LOST_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_EBADDATA; } - evt.sync_handle = get_le16(data + 1); - - ble_gap_rx_periodic_adv_sync_lost(&evt); + ble_gap_rx_periodic_adv_sync_lost(ev); #endif return 0; } +static int +ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, + unsigned int len) +{ +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_periodic_adv_sync_transfer(ev); + +#endif + return 0; +} static int -ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN - ble_gap_rx_le_scan_timeout(); + const struct ble_hci_ev_le_subev_scan_timeout *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_le_scan_timeout(); #endif - return 0; + return 0; } static int -ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_EXT_ADV) - struct hci_le_adv_set_terminated evt; + const struct ble_hci_ev_le_subev_adv_set_terminated *ev = data; - if (len < BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.status = data[1]; - evt.adv_handle = data[2]; - evt.conn_handle = get_le16(data + 3); - evt.completed_events = data[5]; - - if (evt.status == 0) { + if (ev->status == 0) { /* ignore return code as we need to terminate advertising set anyway */ - ble_gap_rx_conn_complete(&pend_conn_complete, evt.adv_handle); + ble_gap_rx_conn_complete(&pend_conn_complete, ev->adv_handle); } - ble_gap_rx_adv_set_terminated(&evt); + ble_gap_rx_adv_set_terminated(ev); #endif return 0; } static int -ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const void *data, + unsigned int len) { #if MYNEWT_VAL(BLE_EXT_ADV) - struct hci_le_scan_req_rcvd evt; + const struct ble_hci_ev_le_subev_scan_req_rcvd *ev = data; - if (len != BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.adv_handle = data[1]; - evt.scan_addr_type = data[2]; - memcpy(evt.scan_addr, data + 3, 6); - - ble_gap_rx_scan_req_rcvd(&evt); + ble_gap_rx_scan_req_rcvd(ev); #endif return 0; } static int -ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, const void *data, + unsigned int len) { - struct hci_le_conn_upd_complete evt; + const struct ble_hci_ev_le_subev_conn_upd_complete *ev = data; - if (len < BLE_HCI_LE_CONN_UPD_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.status = data[1]; - evt.connection_handle = get_le16(data + 2); - evt.conn_itvl = get_le16(data + 4); - evt.conn_latency = get_le16(data + 6); - evt.supervision_timeout = get_le16(data + 8); + if (ev->status == 0) { + BLE_HS_DBG_ASSERT(le16toh(ev->conn_itvl) >= BLE_HCI_CONN_ITVL_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->conn_itvl) <= BLE_HCI_CONN_ITVL_MAX); - if (evt.status == 0) { - if (evt.conn_itvl < BLE_HCI_CONN_ITVL_MIN || - evt.conn_itvl > BLE_HCI_CONN_ITVL_MAX) { + BLE_HS_DBG_ASSERT(le16toh(ev->conn_latency) >= BLE_HCI_CONN_LATENCY_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->conn_latency) <= BLE_HCI_CONN_LATENCY_MAX); - return BLE_HS_EBADDATA; - } - if ( -#if BLE_HCI_CONN_LATENCY_MIN - (evt.conn_latency < BLE_HCI_CONN_LATENCY_MIN) || -#endif - evt.conn_latency > BLE_HCI_CONN_LATENCY_MAX) { - - return BLE_HS_EBADDATA; - } - if (evt.supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN || - evt.supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX) { - - return BLE_HS_EBADDATA; - } + BLE_HS_DBG_ASSERT(le16toh(ev->supervision_timeout) >= BLE_HCI_CONN_SPVN_TIMEOUT_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->supervision_timeout) <= BLE_HCI_CONN_SPVN_TIMEOUT_MAX); } - ble_gap_rx_update_complete(&evt); + ble_gap_rx_update_complete(ev); return 0; } static int -ble_hs_hci_evt_le_lt_key_req(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_lt_key_req(uint8_t subevent, const void *data, unsigned int len) { - struct hci_le_lt_key_req evt; + const struct ble_hci_ev_le_subev_lt_key_req *ev = data; - if (len < BLE_HCI_LE_LT_KEY_REQ_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.connection_handle = get_le16(data + 1); - evt.random_number = get_le64(data + 3); - evt.encrypted_diversifier = get_le16(data + 11); - - ble_sm_ltk_req_rx(&evt); + ble_sm_ltk_req_rx(ev); return 0; } static int -ble_hs_hci_evt_le_conn_parm_req(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_conn_parm_req(uint8_t subevent, const void *data, unsigned int len) { - struct hci_le_conn_param_req evt; + const struct ble_hci_ev_le_subev_rem_conn_param_req *ev = data; - if (len < BLE_HCI_LE_REM_CONN_PARM_REQ_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.connection_handle = get_le16(data + 1); - evt.itvl_min = get_le16(data + 3); - evt.itvl_max = get_le16(data + 5); - evt.latency = get_le16(data + 7); - evt.timeout = get_le16(data + 9); + BLE_HS_DBG_ASSERT(le16toh(ev->min_interval) >= BLE_HCI_CONN_ITVL_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->max_interval) <= BLE_HCI_CONN_ITVL_MAX); + BLE_HS_DBG_ASSERT(le16toh(ev->max_interval) >= le16toh(ev->min_interval)); - if (evt.itvl_min < BLE_HCI_CONN_ITVL_MIN || - evt.itvl_max > BLE_HCI_CONN_ITVL_MAX || - evt.itvl_min > evt.itvl_max) { + BLE_HS_DBG_ASSERT(le16toh(ev->latency) >= BLE_HCI_CONN_LATENCY_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->latency) <= BLE_HCI_CONN_LATENCY_MAX); - return BLE_HS_EBADDATA; - } - if ( -#if BLE_HCI_CONN_LATENCY_MIN - (evt.latency < BLE_HCI_CONN_LATENCY_MIN) || -#endif - evt.latency > BLE_HCI_CONN_LATENCY_MAX) { + BLE_HS_DBG_ASSERT(le16toh(ev->timeout) >= BLE_HCI_CONN_SPVN_TIMEOUT_MIN); + BLE_HS_DBG_ASSERT(le16toh(ev->timeout) <= BLE_HCI_CONN_SPVN_TIMEOUT_MAX); - return BLE_HS_EBADDATA; - } - if (evt.timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN || - evt.timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX) { - - return BLE_HS_EBADDATA; - } - - ble_gap_rx_param_req(&evt); + ble_gap_rx_param_req(ev); return 0; } static int -ble_hs_hci_evt_le_phy_update_complete(uint8_t subevent, uint8_t *data, int len) +ble_hs_hci_evt_le_phy_update_complete(uint8_t subevent, const void *data, + unsigned int len) { - struct hci_le_phy_upd_complete evt; + const struct ble_hci_ev_le_subev_phy_update_complete *ev = data; - if (len < BLE_HCI_LE_PHY_UPD_LEN) { + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } - evt.subevent_code = data[0]; - evt.status = data[1]; - evt.connection_handle = get_le16(data + 2); - evt.tx_phy = data[4]; - evt.rx_phy = data[5]; - - ble_gap_rx_phy_update_complete(&evt); + ble_gap_rx_phy_update_complete(ev); return 0; } int -ble_hs_hci_evt_process(uint8_t *data) +ble_hs_hci_evt_process(const struct ble_hci_ev *ev) { const struct ble_hs_hci_evt_dispatch_entry *entry; - uint8_t event_code; - uint8_t param_len; - int event_len; int rc; /* Count events received */ STATS_INC(ble_hs_stats, hci_event); - /* Display to console */ - ble_hs_dbg_event_disp(data); - /* Process the event */ - event_code = data[0]; - param_len = data[1]; - - event_len = param_len + 2; - - entry = ble_hs_hci_evt_dispatch_find(event_code); + entry = ble_hs_hci_evt_dispatch_find(ev->opcode); if (entry == NULL) { STATS_INC(ble_hs_stats, hci_unknown_event); rc = BLE_HS_ENOTSUP; } else { - rc = entry->cb(event_code, data, event_len); + rc = entry->cb(ev->opcode, ev->data, ev->length); } - ble_hci_trans_buf_free(data); + ble_hci_trans_buf_free((uint8_t *) ev); return rc; } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_priv.h index ff3604727..362f12cbd 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_priv.h @@ -48,7 +48,7 @@ struct os_mbuf; struct ble_hs_hci_ack { int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */ - uint8_t *bha_params; + const uint8_t *bha_params; int bha_params_len; uint16_t bha_opcode; uint8_t bha_hci_handle; @@ -81,11 +81,8 @@ struct hci_periodic_adv_params extern uint16_t ble_hs_hci_avail_pkts; -int ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, - void *evt_buf, uint8_t evt_buf_len, - uint8_t *out_evt_buf_len); -int ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len); -void ble_hs_hci_rx_ack(uint8_t *ack_ev); +int ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, + void *rsp, uint8_t rsp_len); void ble_hs_hci_init(void); void ble_hs_hci_deinit(void); @@ -103,78 +100,11 @@ int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_pwr); int ble_hs_hci_util_rand(void *dst, int len); int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); -int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, - uint16_t tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); -int ble_hs_hci_evt_process(uint8_t *data); +int ble_hs_hci_evt_process(const struct ble_hci_ev *ev); -void ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, - void *buf); -int ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len); -void ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_read_buffer_size(void); -void ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst, - int dst_len); -int ble_hs_hci_cmd_le_set_adv_enable(uint8_t enable); -int ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type, - uint16_t scan_itvl, - uint16_t scan_window, - uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint8_t *dst, uint8_t dst_len); -int ble_hs_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups); -int ble_hs_hci_cmd_build_le_create_connection( - const struct hci_create_conn *hcc, uint8_t *cmd, int cmd_len); -int ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr, - uint8_t addr_type, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_reset(void); -int ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable); -int ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd); -int ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - const struct hci_host_num_comp_pkts_entry *entry, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_read_adv_pwr(void); -int ble_hs_hci_cmd_le_create_conn_cancel(void); -int ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu); -void ble_hs_hci_cmd_build_le_lt_key_req_reply( - const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_conn_param_reply( - const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr); -void ble_hs_hci_cmd_build_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn); -void ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst, int dst_len); +int ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len); int ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts); void ble_hs_hci_add_avail_pkts(uint16_t delta); @@ -184,145 +114,9 @@ uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, int ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om); int ble_hs_hci_acl_tx(struct ble_hs_conn *conn, struct os_mbuf **om); -int ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, uint16_t tx_time, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_add_to_resolv_list( - const struct hci_add_dev_to_resolving_list *padd, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_remove_from_resolv_list( - uint8_t addr_type, const uint8_t *addr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_peer_resolv_addr( - uint8_t peer_identity_addr_type, const uint8_t *peer_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_lcl_resolv_addr( - uint8_t local_identity_addr_type, const uint8_t *local_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_addr_res_en( - uint8_t enable, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout( - uint16_t timeout, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr, - uint8_t *dst, int dst_len); - -#if MYNEWT_VAL(BLE_EXT_ADV) -int ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint16_t duration, - uint16_t period, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle, - const uint8_t *addr, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation, - uint8_t frag_pref, struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num, - const struct hci_ext_adv_set *sets, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle, - const struct hci_ext_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle, - uint8_t *cmd, int cmd_len); - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -int -ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle, - const struct hci_periodic_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable, - uint8_t handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, uint8_t operation, - struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy, - uint8_t adv_sid, - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint16_t skip, - uint16_t sync_timeout, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -#endif - -#endif - -int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy, - uint8_t mod_idx, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, - uint8_t test_data_len, - uint8_t packet_payload_idx, - uint8_t phy, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst, - uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, - int dst_len); - -int ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, - uint8_t rx_phys_mask, - uint8_t *dst, int dst_len); - -int ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst, int dst_len); - int ble_hs_hci_frag_num_mbufs(void); int ble_hs_hci_frag_num_mbufs_free(void); -#if MYNEWT_VAL(BLE_EXT_ADV) -#endif - -int ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst, - int dst_len); #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_util.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_util.c index e99dcbdff..996e0fc10 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_util.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_util.c @@ -37,18 +37,19 @@ ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc) int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr) { - uint8_t params_len; + struct ble_hci_le_rd_adv_chan_txpwr_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR), - NULL, 0,out_tx_pwr, 1, ¶ms_len); + NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (params_len != 1 || - *out_tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN || + *out_tx_pwr = rsp.power_level; + + if (*out_tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN || *out_tx_pwr > BLE_HCI_ADV_CHAN_TXPWR_MAX) { BLE_HS_LOG(WARN, "advertiser txpwr out of range\n"); } @@ -59,8 +60,7 @@ ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr) int ble_hs_hci_util_rand(void *dst, int len) { - uint8_t rsp_buf[BLE_HCI_LE_RAND_LEN]; - uint8_t params_len; + struct ble_hci_le_rand_rp rsp; uint8_t *u8ptr; int chunk_sz; int rc; @@ -68,16 +68,13 @@ ble_hs_hci_util_rand(void *dst, int len) u8ptr = dst; while (len > 0) { rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RAND), - NULL, 0, rsp_buf, sizeof rsp_buf, ¶ms_len); + NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (params_len != sizeof rsp_buf) { - return BLE_HS_ECONTROLLER; - } - chunk_sz = min(len, sizeof rsp_buf); - memcpy(u8ptr, rsp_buf, chunk_sz); + chunk_sz = min(len, sizeof(rsp)); + memcpy(u8ptr, &rsp.random_number, chunk_sz); len -= chunk_sz; u8ptr += chunk_sz; @@ -89,30 +86,25 @@ ble_hs_hci_util_rand(void *dst, int len) int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi) { - uint8_t buf[BLE_HCI_READ_RSSI_LEN]; - uint8_t params[BLE_HCI_READ_RSSI_ACK_PARAM_LEN]; - uint16_t params_conn_handle; - uint8_t params_len; + struct ble_hci_rd_rssi_cp cmd; + struct ble_hci_rd_rssi_rp rsp; + int rc; - ble_hs_hci_cmd_build_read_rssi(conn_handle, buf, sizeof buf); + cmd.handle = htole16(conn_handle); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_STATUS_PARAMS, - BLE_HCI_OCF_RD_RSSI), buf, sizeof(buf), - params, sizeof(params), ¶ms_len); + BLE_HCI_OCF_RD_RSSI), &cmd, sizeof(cmd), + &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (params_len != BLE_HCI_READ_RSSI_ACK_PARAM_LEN) { + if (le16toh(rsp.handle) != conn_handle) { return BLE_HS_ECONTROLLER; } - params_conn_handle = get_le16(params + 0); - if (params_conn_handle != conn_handle) { - return BLE_HS_ECONTROLLER; - } - - *out_rssi = params[2]; + *out_rssi = rsp.rssi; return 0; } @@ -120,57 +112,45 @@ ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi) int ble_hs_hci_util_set_random_addr(const uint8_t *addr) { - uint8_t buf[BLE_HCI_SET_RAND_ADDR_LEN]; - int rc; + struct ble_hci_le_set_rand_addr_cp cmd; - /* set the address in the controller */ + memcpy(cmd.addr, addr, BLE_DEV_ADDR_LEN); - rc = ble_hs_hci_cmd_build_set_random_addr(addr, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } - - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_RAND_ADDR), - buf, BLE_HCI_SET_RAND_ADDR_LEN); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_RAND_ADDR), + &cmd, sizeof(cmd), NULL, 0); } int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) { - - uint8_t buf[BLE_HCI_SET_DATALEN_LEN]; - uint8_t params[BLE_HCI_SET_DATALEN_ACK_PARAM_LEN]; - uint16_t params_conn_handle; - uint8_t params_len; + struct ble_hci_le_set_data_len_cp cmd; + struct ble_hci_le_set_data_len_rp rsp; int rc; - rc = ble_hs_hci_cmd_build_set_data_len(conn_handle, tx_octets, tx_time, - buf, sizeof buf); - if (rc != 0) { - return BLE_HS_HCI_ERR(rc); + if (tx_octets < BLE_HCI_SET_DATALEN_TX_OCTETS_MIN || + tx_octets > BLE_HCI_SET_DATALEN_TX_OCTETS_MAX) { + return BLE_HS_EINVAL; } + if (tx_time < BLE_HCI_SET_DATALEN_TX_TIME_MIN || + tx_time > BLE_HCI_SET_DATALEN_TX_TIME_MAX) { + return BLE_HS_EINVAL; + } + + cmd.conn_handle = htole16(conn_handle); + cmd.tx_octets = htole16(tx_octets); + cmd.tx_time = htole16(tx_time); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DATA_LEN), - buf, sizeof(buf), params, - BLE_HCI_SET_DATALEN_ACK_PARAM_LEN, ¶ms_len); + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (params_len != BLE_HCI_SET_DATALEN_ACK_PARAM_LEN) { - return BLE_HS_ECONTROLLER; - } - - params_conn_handle = get_le16(params + 0); - if (params_conn_handle != conn_handle) { + if (le16toh(rsp.conn_handle) != conn_handle) { return BLE_HS_ECONTROLLER; } @@ -200,31 +180,24 @@ ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, int ble_hs_hci_read_chan_map(uint16_t conn_handle, uint8_t *out_chan_map) { - uint8_t buf[BLE_HCI_RD_CHANMAP_LEN]; - uint8_t params[BLE_HCI_RD_CHANMAP_RSP_LEN]; - uint16_t params_conn_handle; - uint8_t params_len; + struct ble_hci_le_rd_chan_map_cp cmd; + struct ble_hci_le_rd_chan_map_rp rsp; int rc; - ble_hs_hci_cmd_build_le_read_chan_map(conn_handle, buf, sizeof buf); + cmd.conn_handle = htole16(conn_handle); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_CHAN_MAP), - buf, sizeof(buf), params, BLE_HCI_RD_CHANMAP_RSP_LEN, - ¶ms_len); + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (params_len != BLE_HCI_RD_CHANMAP_RSP_LEN) { + if (le16toh(rsp.conn_handle) != conn_handle) { return BLE_HS_ECONTROLLER; } - params_conn_handle = get_le16(params + 0); - if (params_conn_handle != conn_handle) { - return BLE_HS_ECONTROLLER; - } - - memcpy(out_chan_map, params + 2, 5); + memcpy(out_chan_map, rsp.chan_map, 5); return 0; } @@ -232,16 +205,11 @@ ble_hs_hci_read_chan_map(uint16_t conn_handle, uint8_t *out_chan_map) int ble_hs_hci_set_chan_class(const uint8_t *chan_map) { - uint8_t buf[BLE_HCI_SET_HOST_CHAN_CLASS_LEN]; - int rc; + struct ble_hci_le_set_host_chan_class_cp cmd; - ble_hs_hci_cmd_build_le_set_host_chan_class(chan_map, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + memcpy(cmd.chan_map, chan_map, sizeof(cmd.chan_map)); - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS), + &cmd, sizeof(cmd), NULL, 0); } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c index db32f90df..e30a3a1bc 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c @@ -153,20 +153,24 @@ ble_hs_id_set_rnd(const uint8_t *rnd_addr) { uint8_t addr_type_byte; int rc; - int i, rnd_part_sum = 0; + int ones; ble_hs_lock(); - /* Make sure random part of rnd_addr is not all ones or zeros */ + /* Make sure random part of rnd_addr is not all ones or zeros. Reference: + * Core v5.0, Vol 6, Part B, section 1.3.2.1 */ addr_type_byte = rnd_addr[5] & 0xc0; - for (i = 0; i < BLE_DEV_ADDR_LEN; i++) { - rnd_part_sum += *(rnd_addr + i); - } - rnd_part_sum -= addr_type_byte; - /* All ones in random part: 5*(0xFF) + 0x3F = 0x53A */ + /* count bits set to 1 in random part of address */ + ones = __builtin_popcount(rnd_addr[0]); + ones += __builtin_popcount(rnd_addr[1]); + ones += __builtin_popcount(rnd_addr[2]); + ones += __builtin_popcount(rnd_addr[3]); + ones += __builtin_popcount(rnd_addr[4]); + ones += __builtin_popcount(rnd_addr[5] & 0x3f); + if ((addr_type_byte != 0x00 && addr_type_byte != 0xc0) || - (rnd_part_sum == 0) || (rnd_part_sum == 0x53A)) { + (ones == 0 || ones == 46)) { rc = BLE_HS_EINVAL; goto done; } @@ -178,8 +182,6 @@ ble_hs_id_set_rnd(const uint8_t *rnd_addr) memcpy(ble_hs_id_rnd, rnd_addr, 6); - rc = 0; - done: ble_hs_unlock(); return rc; @@ -286,7 +288,7 @@ ble_hs_id_addr_type_usable(uint8_t own_addr_type) case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT: case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT: - id_addr_type = ble_hs_misc_addr_type_to_id(own_addr_type); + id_addr_type = ble_hs_misc_own_addr_type_to_id(own_addr_type); rc = ble_hs_id_addr(id_addr_type, NULL, &nrpa); if (rc != 0) { return rc; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c index 00200d316..dfb46b741 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c @@ -81,7 +81,7 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, } uint8_t -ble_hs_misc_addr_type_to_id(uint8_t own_addr_type) +ble_hs_misc_own_addr_type_to_id(uint8_t own_addr_type) { switch (own_addr_type) { case BLE_OWN_ADDR_PUBLIC: @@ -98,6 +98,24 @@ ble_hs_misc_addr_type_to_id(uint8_t own_addr_type) } } +uint8_t +ble_hs_misc_peer_addr_type_to_id(uint8_t peer_addr_type) +{ + switch (peer_addr_type) { + case BLE_ADDR_PUBLIC: + case BLE_ADDR_PUBLIC_ID: + return BLE_ADDR_PUBLIC; + + case BLE_ADDR_RANDOM: + case BLE_ADDR_RANDOM_ID: + return BLE_ADDR_RANDOM; + + default: + BLE_HS_DBG_ASSERT(0); + return BLE_ADDR_PUBLIC; + } +} + static int ble_hs_misc_restore_one_irk(int obj_type, union ble_store_value *val, void *cookie) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_periodic_sync.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_periodic_sync.c index c594ce53a..dad535138 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_periodic_sync.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_periodic_sync.c @@ -24,6 +24,7 @@ #include "host/ble_hs_id.h" #include "ble_hs_priv.h" +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles; static struct os_mempool ble_hs_periodic_sync_pool; @@ -150,3 +151,4 @@ ble_hs_periodic_sync_init(void) return 0; } +#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h index 49269546c..538d07a97 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h @@ -26,7 +26,6 @@ #include "ble_att_priv.h" #include "ble_gap_priv.h" #include "ble_gatt_priv.h" -#include "ble_hs_dbg_priv.h" #include "ble_hs_hci_priv.h" #include "ble_hs_atomic_priv.h" #include "ble_hs_conn_priv.h" @@ -118,7 +117,8 @@ int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); -uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); +uint8_t ble_hs_misc_own_addr_type_to_id(uint8_t addr_type); +uint8_t ble_hs_misc_peer_addr_type_to_id(uint8_t addr_type); int ble_hs_misc_restore_irks(void); int ble_hs_locked_by_cur_task(void); @@ -142,31 +142,6 @@ int ble_mqueue_init(struct ble_mqueue *mq, ble_npl_event_fn *ev_fn, void *ev_arg struct os_mbuf *ble_mqueue_get(struct ble_mqueue *mq); int ble_mqueue_put(struct ble_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *om); -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG && !BLE_MONITOR - -#define BLE_HS_LOG_CMD(is_tx, cmd_type, cmd_name, conn_handle, \ - log_cb, cmd) do \ -{ \ - BLE_HS_LOG(DEBUG, "%sed %s command: %s; conn=%d ", \ - (is_tx) ? "tx" : "rx", (cmd_type), (cmd_name), (conn_handle)); \ - (log_cb)(cmd); \ - BLE_HS_LOG(DEBUG, "\n"); \ -} while (0) - -#define BLE_HS_LOG_EMPTY_CMD(is_tx, cmd_type, cmd_name, conn_handle) do \ -{ \ - BLE_HS_LOG(DEBUG, "%sed %s command: %s; conn=%d ", \ - (is_tx) ? "tx" : "rx", (cmd_type), (cmd_name), (conn_handle)); \ - BLE_HS_LOG(DEBUG, "\n"); \ -} while (0) - -#else - -#define BLE_HS_LOG_CMD(is_tx, cmd_type, cmd_name, conn_handle, log_cb, cmd) -#define BLE_HS_LOG_EMPTY_CMD(is_tx, cmd_type, cmd_name, conn_handle) - -#endif - #if MYNEWT_VAL(BLE_HS_DEBUG) #define BLE_HS_DBG_ASSERT(x) assert(x) #define BLE_HS_DBG_ASSERT_EVAL(x) assert(x) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c index 69f3da543..9e92c660f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c @@ -36,87 +36,66 @@ const uint8_t ble_hs_pvcy_default_irk[16] = { static int ble_hs_pvcy_set_addr_timeout(uint16_t timeout) { + struct ble_hci_le_set_rpa_tmo_cp cmd; + #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) return ble_hs_resolv_set_rpa_tmo(timeout); #endif - uint8_t buf[BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN]; - int rc; - - rc = ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout(timeout, buf, - sizeof(buf)); - if (rc != 0) { - return rc; + if (timeout == 0 || timeout > 0xA1B8) { + return BLE_ERR_INV_HCI_CMD_PARMS; } + cmd.rpa_timeout = htole16(timeout); + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RPA_TMO), - buf, sizeof(buf), NULL, 0, NULL); + &cmd, sizeof(cmd), NULL, 0); } #if (!MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)) static int ble_hs_pvcy_set_resolve_enabled(int enable) { - uint8_t buf[BLE_HCI_SET_ADDR_RESOL_ENA_LEN]; - int rc; + struct ble_hci_le_set_addr_res_en_cp cmd; - rc = ble_hs_hci_cmd_build_set_addr_res_en(enable, buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + cmd.enable = enable; - rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_ADDR_RES_EN), - buf, sizeof(buf), NULL, 0, NULL); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_ADDR_RES_EN), + &cmd, sizeof(cmd), NULL, 0); } #endif int ble_hs_pvcy_remove_entry(uint8_t addr_type, const uint8_t *addr) { - uint8_t buf[BLE_HCI_RMV_FROM_RESOLV_LIST_LEN]; + struct ble_hci_le_rmv_resolve_list_cp cmd; int rc; - rc = ble_hs_hci_cmd_build_remove_from_resolv_list(addr_type, addr, - buf, sizeof(buf)); - if (rc != 0) { - return rc; + if (addr_type > BLE_ADDR_RANDOM) { + addr_type = addr_type % 2; } + cmd.peer_addr_type = addr_type; + memcpy(cmd.peer_id_addr, addr, BLE_DEV_ADDR_LEN); #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - rc = ble_hs_resolv_list_rmv(buf[0], &buf[1]); + rc = ble_hs_resolv_list_rmv(addr_type, &cmd.peer_id_addr[0]); #else rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RMV_RESOLV_LIST), - buf, sizeof(buf), NULL, 0, NULL); + &cmd, sizeof(cmd), NULL, 0); #endif - if (rc != 0) { - return rc; - } - - return 0; + return rc; } #if (!MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)) static int ble_hs_pvcy_clear_entries(void) { - int rc; - - rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CLR_RESOLV_LIST), - NULL, 0, NULL, 0, NULL); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CLR_RESOLV_LIST), + NULL, 0, NULL, 0); } #endif @@ -124,21 +103,20 @@ static int ble_hs_pvcy_add_entry_hci(const uint8_t *addr, uint8_t addr_type, const uint8_t *irk) { - struct hci_add_dev_to_resolving_list add; - uint8_t buf[BLE_HCI_ADD_TO_RESOLV_LIST_LEN]; + struct ble_hci_le_add_resolv_list_cp cmd; int rc; - add.addr_type = addr_type; - memcpy(add.addr, addr, 6); - memcpy(add.local_irk, ble_hs_pvcy_irk, 16); - memcpy(add.peer_irk, irk, 16); - - rc = ble_hs_hci_cmd_build_add_to_resolv_list(&add, buf, sizeof(buf)); - if (rc != 0) { - return rc; + if (addr_type > BLE_ADDR_RANDOM) { + return BLE_ERR_INV_HCI_CMD_PARMS; } + + cmd.peer_addr_type = addr_type; + memcpy(cmd.peer_id_addr, addr, 6); + memcpy(cmd.local_irk, ble_hs_pvcy_irk, 16); + memcpy(cmd.peer_irk, irk, 16); + #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - rc = ble_hs_resolv_list_add(buf); + rc = ble_hs_resolv_list_add((uint8_t *) &cmd); if (rc != 0) { return rc; } @@ -148,12 +126,11 @@ ble_hs_pvcy_add_entry_hci(const uint8_t *addr, uint8_t addr_type, rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ADD_RESOLV_LIST), - buf, sizeof(buf), NULL, 0, NULL); + &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { return rc; } - /* FIXME Controller is BT5.0 and default privacy mode is network which * can cause problems for apps which are not aware of it. We need to * sort it out somehow. For now we set device mode for all of the peer @@ -304,18 +281,19 @@ ble_hs_pvcy_our_irk(const uint8_t **out_irk) int ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode) { - uint8_t buf[BLE_HCI_LE_SET_PRIVACY_MODE_LEN]; - int rc; + struct ble_hci_le_set_privacy_mode_cp cmd; - rc = ble_hs_hci_cmd_build_le_set_priv_mode(addr->val, addr->type, priv_mode, - buf, sizeof(buf)); - if (rc != 0) { - return rc; + if (addr->type > BLE_ADDR_RANDOM) { + return BLE_ERR_INV_HCI_CMD_PARMS; } + cmd.mode = priv_mode; + cmd.peer_id_addr_type = addr->type; + memcpy(cmd.peer_id_addr, addr->val, BLE_DEV_ADDR_LEN); + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PRIVACY_MODE), - buf, sizeof(buf), NULL, 0, NULL); + &cmd, sizeof(cmd), NULL, 0); } bool diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c index 46e5577f6..6add1018b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c @@ -96,7 +96,7 @@ ble_rpa_remove_peer_dev_rec(struct ble_hs_dev_records *p_dev_rec) ble_store_num_peer_dev_rec--; if ((i != ble_store_num_peer_dev_rec) && (ble_store_num_peer_dev_rec != 0)) { memmove(&peer_dev_rec[i], &peer_dev_rec[i + 1], - (ble_store_num_peer_dev_rec - i + 1) * sizeof(struct ble_hs_dev_records )); + (ble_store_num_peer_dev_rec - i) * sizeof(struct ble_hs_dev_records )); } BLE_HS_LOG(DEBUG, " RPA: removed device at index = %d, no. of peer records" @@ -567,9 +567,25 @@ ble_hs_resolv_list_add(uint8_t *cmdbuf) addr_type = cmdbuf[0]; ident_addr = cmdbuf + 1; +/*--------------------------------------------------------------------------------*/ + /* Temporary workaround to resolve an issue when deinitializing the stack + * and reinitializing. If the a peer deletes the bonding info after deiniting + * it will not be able to re-bond without this. Awaiting upstream fix. + */ +/* if (ble_hs_is_on_resolv_list(ident_addr, addr_type)) { return BLE_HS_EINVAL; } +*/ + int position = ble_hs_is_on_resolv_list(ident_addr, addr_type); + if (position) { + memmove(&g_ble_hs_resolv_list[position], + &g_ble_hs_resolv_list[position + 1], + (g_ble_hs_resolv_data.rl_cnt - position) * sizeof (struct + ble_hs_resolv_entry)); + --g_ble_hs_resolv_data.rl_cnt; + } +/*--------------------------------------------------------------------------------*/ rl = &g_ble_hs_resolv_list[g_ble_hs_resolv_data.rl_cnt]; memset(rl, 0, sizeof(*rl)); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_startup.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_startup.c index b21db7513..83026ac18 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_startup.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_startup.c @@ -27,26 +27,20 @@ static int ble_hs_startup_read_sup_f_tx(void) { - uint8_t ack_params[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN]; - uint8_t ack_params_len; + struct ble_hci_ip_rd_loc_supp_feat_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT), - NULL,0, ack_params, sizeof ack_params, - &ack_params_len); + NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) { - return BLE_HS_ECONTROLLER; - } - /* for now we don't use it outside of init sequence so check this here * LE Supported (Controller) byte 4, bit 6 */ - if (!(ack_params[4] & 0x60)) { + if (!(rsp.features & 0x0000006000000000)) { BLE_HS_LOG(ERROR, "Controller doesn't support LE\n"); return BLE_HS_ECONTROLLER; } @@ -58,26 +52,18 @@ ble_hs_startup_read_sup_f_tx(void) static int ble_hs_startup_read_local_ver_tx(void) { - uint8_t ack_params[BLE_HCI_RD_LOC_VER_INFO_RSPLEN]; - uint8_t ack_params_len; - uint8_t hci_version; + struct ble_hci_ip_rd_local_ver_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER), - NULL,0, ack_params, sizeof ack_params, - &ack_params_len); + NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_RD_LOC_VER_INFO_RSPLEN) { - return BLE_HS_ECONTROLLER; - } - /* For now we are interested only in HCI Version */ - hci_version = ack_params[0]; - ble_hs_hci_set_hci_version(hci_version); + ble_hs_hci_set_hci_version(rsp.hci_ver); return 0; } @@ -85,26 +71,17 @@ ble_hs_startup_read_local_ver_tx(void) static int ble_hs_startup_le_read_sup_f_tx(void) { - uint8_t ack_params[BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN]; - uint8_t ack_params_len; - uint32_t feat; + struct ble_hci_le_rd_loc_supp_feat_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT), - NULL,0, ack_params, sizeof ack_params, - &ack_params_len); + NULL,0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN) { - return BLE_HS_ECONTROLLER; - } - - /* For now 32-bits of features is enough */ - feat = get_le32(ack_params); - ble_hs_hci_set_le_supported_feat(feat); + ble_hs_hci_set_le_supported_feat(le64toh(rsp.features)); return 0; } @@ -112,23 +89,18 @@ ble_hs_startup_le_read_sup_f_tx(void) static int ble_hs_startup_le_read_buf_sz_tx(uint16_t *out_pktlen, uint8_t *out_max_pkts) { - uint8_t ack_params[BLE_HCI_RD_BUF_SIZE_RSPLEN]; - uint8_t ack_params_len; + struct ble_hci_le_rd_buf_size_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE), NULL, 0, - ack_params, sizeof ack_params, &ack_params_len); + &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN) { - return BLE_HS_ECONTROLLER; - } - - *out_pktlen = get_le16(ack_params + 0); - *out_max_pkts = ack_params[2]; + *out_pktlen = le16toh(rsp.data_len); + *out_max_pkts = rsp.data_packets; return 0; } @@ -136,23 +108,18 @@ ble_hs_startup_le_read_buf_sz_tx(uint16_t *out_pktlen, uint8_t *out_max_pkts) static int ble_hs_startup_read_buf_sz_tx(uint16_t *out_pktlen, uint16_t *out_max_pkts) { - uint8_t ack_params[BLE_HCI_IP_RD_BUF_SIZE_RSPLEN]; - uint8_t ack_params_len; + struct ble_hci_ip_rd_buf_size_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BUF_SIZE), NULL, 0, - ack_params, sizeof ack_params, &ack_params_len); + &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_IP_RD_BUF_SIZE_RSPLEN) { - return BLE_HS_ECONTROLLER; - } - - *out_pktlen = get_le16(ack_params + 0); - *out_max_pkts = get_le16(ack_params + 3); + *out_pktlen = le16toh(rsp.acl_data_len); + *out_max_pkts = le16toh(rsp.acl_num); return 0; } @@ -192,30 +159,24 @@ ble_hs_startup_read_buf_sz(void) static int ble_hs_startup_read_bd_addr(void) { - uint8_t ack_params[BLE_HCI_IP_RD_BD_ADDR_ACK_PARAM_LEN]; - uint8_t ack_params_len; + struct ble_hci_ip_rd_bd_addr_rp rsp; int rc; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BD_ADDR), - NULL, 0, ack_params, sizeof ack_params, - &ack_params_len); + NULL, 0, &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != sizeof ack_params) { - return BLE_HS_ECONTROLLER; - } - - ble_hs_id_set_pub(ack_params); + ble_hs_id_set_pub(rsp.addr); return 0; } static int ble_hs_startup_le_set_evmask_tx(void) { - uint8_t buf[BLE_HCI_SET_LE_EVENT_MASK_LEN]; + struct ble_hci_le_set_event_mask_cp cmd; uint8_t version; uint64_t mask; int rc; @@ -267,10 +228,21 @@ ble_hs_startup_le_set_evmask_tx(void) mask |= 0x00000000000ff800; } - ble_hs_hci_cmd_build_le_set_event_mask(mask, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_EVENT_MASK), - buf, sizeof(buf)); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + if (version >= BLE_HCI_VER_BCS_5_1) { + /** + * Enable the following LE events: + * 0x0000000000800000 LE Periodic Advertising Sync Transfer Received event + */ + mask |= 0x0000000000800000; + } +#endif + + cmd.event_mask = htole64(mask); + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EVENT_MASK), + &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { return rc; } @@ -281,7 +253,8 @@ ble_hs_startup_le_set_evmask_tx(void) static int ble_hs_startup_set_evmask_tx(void) { - uint8_t buf[BLE_HCI_SET_EVENT_MASK_LEN]; + struct ble_hci_cb_set_event_mask_cp cmd; + struct ble_hci_cb_set_event_mask2_cp cmd2; uint8_t version; int rc; @@ -296,10 +269,11 @@ ble_hs_startup_set_evmask_tx(void) * 0x0000800000000000 Encryption Key Refresh Complete Event * 0x2000000000000000 LE Meta-Event */ - ble_hs_hci_cmd_build_set_event_mask(0x2000800002008090, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, - BLE_HCI_OCF_CB_SET_EVENT_MASK), - buf, sizeof(buf)); + cmd.event_mask = htole64(0x2000800002008090); + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_SET_EVENT_MASK), + &cmd, sizeof(cmd), NULL, 0); if (rc != 0) { return rc; } @@ -309,10 +283,10 @@ ble_hs_startup_set_evmask_tx(void) * Enable the following events: * 0x0000000000800000 Authenticated Payload Timeout Event */ - ble_hs_hci_cmd_build_set_event_mask2(0x0000000000800000, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, - BLE_HCI_OCF_CB_SET_EVENT_MASK2), - buf, sizeof(buf)); + cmd2.event_mask2 = htole64(0x0000000000800000); + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_SET_EVENT_MASK2), + &cmd2, sizeof(cmd2), NULL, 0); if (rc != 0) { return rc; } @@ -324,16 +298,9 @@ ble_hs_startup_set_evmask_tx(void) static int ble_hs_startup_reset_tx(void) { - int rc; - - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, - BLE_HCI_OCF_CB_RESET), - NULL, 0); - if (rc != 0) { - return rc; - } - - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_RESET), + NULL, 0, NULL, 0); } int diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_stop.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_stop.c index ff540b931..b90d3ec6f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_stop.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_hs_stop.c @@ -21,9 +21,12 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "ble_hs_priv.h" +#include "nimble/nimble_npl.h" +#ifndef MYNEWT +#include "nimble/nimble_port.h" +#endif -static ble_npl_event_fn ble_hs_stop_term_event_cb; -static struct ble_npl_event ble_hs_stop_term_ev; +#define BLE_HOST_STOP_TIMEOUT_MS MYNEWT_VAL(BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT) static struct ble_gap_event_listener ble_hs_stop_gap_listener; @@ -33,6 +36,11 @@ static struct ble_gap_event_listener ble_hs_stop_gap_listener; SLIST_HEAD(ble_hs_stop_listener_slist, ble_hs_stop_listener); static struct ble_hs_stop_listener_slist ble_hs_stop_listeners; +/* Track number of connections */ +static uint8_t ble_hs_stop_conn_cnt; + +static struct ble_npl_callout ble_hs_stop_terminate_tmo; + /** * Called when a stop procedure has completed. */ @@ -42,6 +50,8 @@ ble_hs_stop_done(int status) struct ble_hs_stop_listener_slist slist; struct ble_hs_stop_listener *listener; + ble_npl_callout_stop(&ble_hs_stop_terminate_tmo); + ble_hs_lock(); ble_gap_event_listener_unregister(&ble_hs_stop_gap_listener); @@ -82,7 +92,7 @@ ble_hs_stop_terminate_all_periodic_sync(void) * ble_hs_periodic_sync_first yields the next psync handle */ sync_handle = psync->sync_handle; - rc = ble_gap_periodic_adv_terminate_sync(sync_handle); + rc = ble_gap_periodic_adv_sync_terminate(sync_handle); if (rc != 0 && rc != BLE_HS_ENOTCONN) { BLE_HS_LOG(ERROR, "failed to terminate periodic sync=0x%04x, rc=%d\n", sync_handle, rc); @@ -95,47 +105,41 @@ ble_hs_stop_terminate_all_periodic_sync(void) #endif /** - * Terminates the first open connection. - * - * If there are no open connections, Check for any active periodic sync - * handles. + * Terminates connection. */ -static void -ble_hs_stop_terminate_next_conn(void) +static int +ble_hs_stop_terminate_conn(struct ble_hs_conn *conn, void *arg) { - uint16_t handle; int rc; - handle = ble_hs_atomic_first_conn_handle(); - if (handle == BLE_HS_CONN_HANDLE_NONE) { - /* No open connections. Signal completion of the stop procedure. */ - ble_hs_stop_done(0); - return; - } - - rc = ble_gap_terminate(handle, BLE_ERR_REM_USER_CONN_TERM); + rc = ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM); if (rc == 0) { /* Terminate procedure successfully initiated. Let the GAP event * handler deal with the result. */ + ble_hs_stop_conn_cnt++; } else { - BLE_HS_LOG(ERROR, - "ble_hs_stop: failed to terminate connection; rc=%d\n", rc); - ble_hs_stop_done(rc); + /* If failed, just make sure we are not going to wait for connection complete event, + * just count it as already disconnected + */ + BLE_HS_LOG(ERROR, "ble_hs_stop: failed to terminate connection; rc=%d\n", rc); } + + return 0; } /** - * Event handler. Attempts to terminate the first open connection if there is - * one. All additional connections are terminated elsewhere in the GAP event - * handler. - * - * If there are no connections, signals completion of the stop procedure. + * This is called when host graceful disconnect timeout fires. That means some devices + * are out of range and disconnection completed did no happen yet. */ static void -ble_hs_stop_term_event_cb(struct ble_npl_event *ev) +ble_hs_stop_terminate_timeout_cb(struct ble_npl_event *ev) { - ble_hs_stop_terminate_next_conn(); + BLE_HS_LOG(ERROR, "ble_hs_stop_terminate_timeout_cb," + "%d connection(s) still up \n", ble_hs_stop_conn_cnt); + + /* TODO: Shall we send error here? */ + ble_hs_stop_done(0); } /** @@ -151,7 +155,11 @@ ble_hs_stop_gap_event(struct ble_gap_event *event, void *arg) if (event->type == BLE_GAP_EVENT_DISCONNECT || event->type == BLE_GAP_EVENT_TERM_FAILURE) { - ble_hs_stop_terminate_next_conn(); + ble_hs_stop_conn_cnt--; + + if (ble_hs_stop_conn_cnt == 0) { + ble_hs_stop_done(0); + } } return 0; @@ -233,12 +241,6 @@ ble_hs_stop(struct ble_hs_stop_listener *listener, ble_gap_preempt(); ble_gap_preempt_done(); - rc = ble_gap_event_listener_register(&ble_hs_stop_gap_listener, - ble_hs_stop_gap_event, NULL); - if (rc != 0) { - return rc; - } - #if MYNEWT_VAL(BLE_PERIODIC_ADV) /* Check for active periodic sync first and terminate it all */ rc = ble_hs_stop_terminate_all_periodic_sync(); @@ -247,11 +249,23 @@ ble_hs_stop(struct ble_hs_stop_listener *listener, } #endif - /* Schedule termination of all open connections in the host task. This is - * done even if there are no open connections so that the result of the - * stop procedure is signaled in a consistent manner (asynchronously). - */ - ble_npl_eventq_put(ble_hs_evq_get(), &ble_hs_stop_term_ev); + rc = ble_gap_event_listener_register(&ble_hs_stop_gap_listener, + ble_hs_stop_gap_event, NULL); + if (rc != 0) { + return rc; + } + + ble_hs_lock(); + ble_hs_conn_foreach(ble_hs_stop_terminate_conn, NULL); + ble_hs_unlock(); + + if (ble_hs_stop_conn_cnt > 0) { + ble_npl_callout_reset(&ble_hs_stop_terminate_tmo, + ble_npl_time_ms_to_ticks32(BLE_HOST_STOP_TIMEOUT_MS)); + } else { + /* No connections, stop is completed */ + ble_hs_stop_done(0); + } return 0; } @@ -259,5 +273,11 @@ ble_hs_stop(struct ble_hs_stop_listener *listener, void ble_hs_stop_init(void) { - ble_npl_event_init(&ble_hs_stop_term_ev, ble_hs_stop_term_event_cb, NULL); +#ifdef MYNEWT + ble_npl_callout_init(&ble_hs_stop_terminate_tmo, ble_npl_eventq_dflt_get(), + ble_hs_stop_terminate_timeout_cb, NULL); +#else + ble_npl_callout_init(&ble_hs_stop_terminate_tmo, nimble_port_get_dflt_eventq(), + ble_hs_stop_terminate_timeout_cb, NULL); +#endif } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap.c index a9252b8e0..0d9f082d4 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap.c @@ -70,7 +70,7 @@ ble_l2cap_chan_alloc(uint16_t conn_handle) } void -ble_l2cap_chan_free(struct ble_l2cap_chan *chan) +ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { int rc; @@ -79,7 +79,7 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan) } os_mbuf_free_chain(chan->rx_buf); - ble_l2cap_coc_cleanup_chan(chan); + ble_l2cap_coc_cleanup_chan(conn, chan); #if MYNEWT_VAL(BLE_HS_DEBUG) memset(chan, 0xff, sizeof *chan); @@ -155,7 +155,62 @@ ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, return ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg); } -int ble_l2cap_disconnect(struct ble_l2cap_chan *chan) +int +ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info) +{ + if (!chan || !chan_info) { + return BLE_HS_EINVAL; + } + + memset(chan_info, 0, sizeof(*chan_info)); + chan_info->dcid = chan->dcid; + chan_info->scid = chan->scid; + chan_info->our_l2cap_mtu = chan->my_mtu; + chan_info->peer_l2cap_mtu = chan->peer_mtu; + +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + chan_info->psm = chan->psm; + chan_info->our_coc_mtu = chan->coc_rx.mtu; + chan_info->peer_coc_mtu = chan->coc_tx.mtu; +#endif + + return 0; +} + +int +ble_l2cap_enhanced_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg) +{ + return ble_l2cap_sig_ecoc_connect(conn_handle, psm, mtu, + num, sdu_rx, cb, cb_arg); +} + +int +ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu) +{ + int i; + uint16_t conn_handle; + + if (num == 0 || !chans) { + return BLE_HS_EINVAL; + } + + conn_handle = chans[0]->conn_handle; + + for (i = 1; i < num; i++) { + if (conn_handle != chans[i]->conn_handle) { + BLE_HS_LOG(ERROR, "All channels should have same conn handle\n"); + return BLE_HS_EINVAL; + } + } + + return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu); +} + +int +ble_l2cap_disconnect(struct ble_l2cap_chan *chan) { return ble_l2cap_sig_disconnect(chan); } @@ -188,23 +243,18 @@ ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) static void ble_l2cap_append_rx(struct ble_l2cap_chan *chan, struct os_mbuf *frag) { - int rc; - - (void)rc; - #if MYNEWT_VAL(BLE_L2CAP_JOIN_RX_FRAGS) - /* Copy the data from the incoming fragment into the packet in progress. */ - rc = os_mbuf_appendfrom(chan->rx_buf, frag, 0, OS_MBUF_PKTLEN(frag)); - if (rc == 0) { - os_mbuf_free_chain(frag); - return; - } -#endif + struct os_mbuf *m; + /* Copy the data from the incoming fragment into the packet in progress. */ + m = os_mbuf_pack_chains(chan->rx_buf, frag); + assert(m); +#else /* Join disabled or append failed due to mbuf shortage. Just attach the * mbuf to the end of the packet. */ os_mbuf_concat(chan->rx_buf, frag); +#endif } static int diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc.c index bc597f936..41a831565 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc.c @@ -88,17 +88,56 @@ ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, return 0; } -static uint16_t -ble_l2cap_coc_get_cid(void) +static inline void +ble_l2cap_set_used_cid(uint32_t *cid_mask, int bit) { - static uint16_t next_cid = BLE_L2CAP_COC_CID_START; + cid_mask[bit / 32] |= (1 << (bit % 32)); +} - if (next_cid > BLE_L2CAP_COC_CID_END) { - next_cid = BLE_L2CAP_COC_CID_START; +static inline void +ble_l2cap_clear_used_cid(uint32_t *cid_mask, int bit) +{ + cid_mask[bit / 32] &= ~(1 << (bit % 32)); +} + +static inline int +ble_l2cap_get_first_available_bit(uint32_t *cid_mask) +{ + int i; + int bit = 0; + + for (i = 0; i < BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN; i++) { + /* Find first available index by finding first available bit + * in the mask. + * Note: + * a) If bit == 0 means all the bits are used + * b) this function returns 1 + index + */ + bit = __builtin_ffs(~(unsigned int)(cid_mask[i])); + if (bit != 0) { + break; + } } - /*TODO: Make it smarter*/ - return next_cid++; + if (i == BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN) { + return -1; + } + + return (i * 32 + bit - 1); +} + +static int +ble_l2cap_coc_get_cid(uint32_t *cid_mask) +{ + int bit; + + bit = ble_l2cap_get_first_available_bit(cid_mask); + if (bit < 0) { + return -1; + } + + ble_l2cap_set_used_cid(cid_mask, bit); + return BLE_L2CAP_COC_CID_START + bit; } static struct ble_l2cap_coc_srv * @@ -145,22 +184,26 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) /* Create a shortcut to rx endpoint */ rx = &chan->coc_rx; + BLE_HS_DBG_ASSERT(rx != NULL); om_total = OS_MBUF_PKTLEN(*om); - rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SDU_SIZE); - if (rc != 0) { - return rc; - } /* First LE frame */ if (OS_MBUF_PKTLEN(rx->sdu) == 0) { uint16_t sdu_len; + rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SDU_SIZE); + if (rc != 0) { + return rc; + } + sdu_len = get_le16((*om)->om_data); if (sdu_len > rx->mtu) { - /* TODO Disconnect?*/ BLE_HS_LOG(INFO, "error: sdu_len > rx->mtu (%d>%d)\n", sdu_len, rx->mtu); + + /* Disconnect peer with invalid behaviour */ + ble_l2cap_disconnect(chan); return BLE_HS_EBADDATA; } @@ -231,14 +274,25 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) return 0; } +void +ble_l2cap_coc_set_new_mtu_mps(struct ble_l2cap_chan *chan, uint16_t mtu, uint16_t mps) +{ + chan->my_coc_mps = mps; + chan->coc_rx.mtu = mtu; + chan->initial_credits = mtu / chan->my_coc_mps; + if (mtu % chan->my_coc_mps) { + chan->initial_credits++; + } +} + struct ble_l2cap_chan * -ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, +ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn, uint16_t psm, uint16_t mtu, struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg) { struct ble_l2cap_chan *chan; - chan = ble_l2cap_chan_alloc(conn_handle); + chan = ble_l2cap_chan_alloc(conn->bhc_handle); if (!chan) { return NULL; } @@ -246,8 +300,8 @@ ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, chan->psm = psm; chan->cb = cb; chan->cb_arg = cb_arg; - chan->scid = ble_l2cap_coc_get_cid(); - chan->my_mtu = MYNEWT_VAL(BLE_L2CAP_COC_MPS); + chan->scid = ble_l2cap_coc_get_cid(conn->l2cap_coc_cid_mask); + chan->my_coc_mps = MYNEWT_VAL(BLE_L2CAP_COC_MPS); chan->rx_fn = ble_l2cap_coc_rx_fn; chan->coc_rx.mtu = mtu; chan->coc_rx.sdu = sdu_rx; @@ -255,8 +309,8 @@ ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, /* Number of credits should allow to send full SDU with on given * L2CAP MTU */ - chan->coc_rx.credits = mtu / chan->my_mtu; - if (mtu % chan->my_mtu) { + chan->coc_rx.credits = mtu / chan->my_coc_mps; + if (mtu % chan->my_coc_mps) { chan->coc_rx.credits++; } @@ -265,7 +319,7 @@ ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, } int -ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, +ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm, struct ble_l2cap_chan **chan) { struct ble_l2cap_coc_srv *srv; @@ -276,7 +330,7 @@ ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, return BLE_HS_ENOTSUP; } - *chan = ble_l2cap_coc_chan_alloc(conn_handle, psm, srv->mtu, NULL, srv->cb, + *chan = ble_l2cap_coc_chan_alloc(conn, psm, srv->mtu, NULL, srv->cb, srv->cb_arg); if (!*chan) { return BLE_HS_ENOMEM; @@ -303,7 +357,7 @@ ble_l2cap_event_coc_disconnected(struct ble_l2cap_chan *chan) } void -ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan) +ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { /* PSM 0 is used for fixed channels. */ if (chan->psm == 0) { @@ -312,6 +366,11 @@ ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan) ble_l2cap_event_coc_disconnected(chan); + if (conn && chan->scid) { + ble_l2cap_clear_used_cid(conn->l2cap_coc_cid_mask, + chan->scid - BLE_L2CAP_COC_CID_START); + } + os_mbuf_free_chain(chan->coc_rx.sdu); os_mbuf_free_chain(chan->coc_tx.sdu); } @@ -364,7 +423,7 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) } /* Take into account peer MTU */ - len = min(left_to_send, chan->peer_mtu); + len = min(left_to_send, chan->peer_coc_mps); /* Prepare packet */ txom = ble_hs_mbuf_l2cap_pkt(); @@ -540,46 +599,6 @@ ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx) return ble_l2cap_coc_continue_tx(chan); } -int -ble_l2cap_get_scid(struct ble_l2cap_chan *chan) -{ - if (!chan) { - return 0; - } - - return chan->scid; -} - -int -ble_l2cap_get_dcid(struct ble_l2cap_chan *chan) -{ - if (!chan) { - return 0; - } - - return chan->dcid; -} - -int -ble_l2cap_get_our_mtu(struct ble_l2cap_chan *chan) -{ - if (!chan) { - return 0; - } - - return chan->my_mtu; -} - -int -ble_l2cap_get_peer_mtu(struct ble_l2cap_chan *chan) -{ - if (!chan) { - return 0; - } - - return chan->peer_mtu; -} - int ble_l2cap_coc_init(void) { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc_priv.h index 0a1a97b77..5ebdaa050 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_coc_priv.h @@ -57,25 +57,46 @@ struct ble_l2cap_coc_srv { int ble_l2cap_coc_init(void); int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); -int ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, +int ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm, struct ble_l2cap_chan **chan); -struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(uint16_t conn_handle, +struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn, uint16_t psm, uint16_t mtu, struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg); -void ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan); +void ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); void ble_l2cap_coc_le_credits_update(uint16_t conn_handle, uint16_t dcid, uint16_t credits); int ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); int ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); +void ble_l2cap_coc_set_new_mtu_mps(struct ble_l2cap_chan *chan, uint16_t mtu, uint16_t mps); #else -#define ble_l2cap_coc_init() 0 -#define ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg) BLE_HS_ENOTSUP -#define ble_l2cap_coc_recv_ready(chan, sdu_rx) BLE_HS_ENOTSUP -#define ble_l2cap_coc_cleanup_chan(chan) -#define ble_l2cap_coc_send(chan, sdu_tx) BLE_HS_ENOTSUP +static inline int +ble_l2cap_coc_init(void) { + return 0; +} + +static inline int +ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, + ble_l2cap_event_fn *cb, void *cb_arg) { + return BLE_HS_ENOTSUP; +} + +static inline int +ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, + struct os_mbuf *sdu_rx) { + return BLE_HS_ENOTSUP; +} + +static inline void +ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { +} + +static inline int +ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx) { + return BLE_HS_ENOTSUP; +} #endif #ifdef __cplusplus diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_priv.h index 640974d2a..e3409743b 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_priv.h @@ -65,8 +65,20 @@ struct ble_l2cap_chan { uint16_t conn_handle; uint16_t dcid; uint16_t scid; - uint16_t my_mtu; - uint16_t peer_mtu; /* 0 if not exchanged. */ + + /* Unions just to avoid confusion on MPS/MTU. + * In CoC context, L2CAP MTU is MPS + */ + union { + uint16_t my_mtu; + uint16_t my_coc_mps; + }; + + union { + uint16_t peer_mtu; + uint16_t peer_coc_mps; + }; + ble_l2cap_chan_flags flags; struct os_mbuf *rx_buf; @@ -102,7 +114,7 @@ struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len); struct ble_l2cap_chan *ble_l2cap_chan_alloc(uint16_t conn_handle); -void ble_l2cap_chan_free(struct ble_l2cap_chan *chan); +void ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan); @@ -118,6 +130,13 @@ void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); int ble_l2cap_init(void); +/* Below experimental API is available when BLE_VERSION >= 52 */ +int ble_l2cap_enhanced_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu); + #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c index bc73d954a..58f96b0f3 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c @@ -56,8 +56,17 @@ #define BLE_L2CAP_SIG_PROC_OP_UPDATE 0 #define BLE_L2CAP_SIG_PROC_OP_CONNECT 1 -#define BLE_L2CAP_SIG_PROC_OP_DISCONNECT 2 -#define BLE_L2CAP_SIG_PROC_OP_MAX 3 +#define BLE_L2CAP_SIG_PROC_OP_RECONFIG 2 +#define BLE_L2CAP_SIG_PROC_OP_DISCONNECT 3 +#define BLE_L2CAP_SIG_PROC_OP_MAX 4 + +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +#define BLE_L2CAP_ECOC_MIN_MTU (64) + +#define BLE_L2CAP_MAX_COC_CONN_REQ (5) +#else +#define BLE_L2CAP_MAX_COC_CONN_REQ (1) +#endif struct ble_l2cap_sig_proc { STAILQ_ENTRY(ble_l2cap_sig_proc) next; @@ -73,11 +82,20 @@ struct ble_l2cap_sig_proc { void *cb_arg; } update; struct { - struct ble_l2cap_chan *chan; + uint8_t chan_cnt; + struct ble_l2cap_chan *chan[BLE_L2CAP_MAX_COC_CONN_REQ]; } connect; struct { struct ble_l2cap_chan *chan; } disconnect; +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) + struct { + uint8_t cid_cnt; + uint16_t cids[BLE_L2CAP_MAX_COC_CONN_REQ]; + uint16_t new_mps; + uint16_t new_mtu; + } reconfig; +#endif }; }; @@ -105,7 +123,19 @@ static ble_l2cap_sig_rx_fn ble_l2cap_sig_le_credits_rx; #define ble_l2cap_sig_coc_rsp_rx ble_l2cap_sig_rx_noop #define ble_l2cap_sig_disc_rsp_rx ble_l2cap_sig_rx_noop #define ble_l2cap_sig_disc_req_rx ble_l2cap_sig_rx_noop -#define ble_l2cap_sig_le_credits_rx ble_l2cap_sig_rx_noop +#define ble_l2cap_sig_le_credits_rx ble_l2cap_sig_rx_noop +#endif + +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +static ble_l2cap_sig_rx_fn ble_l2cap_sig_credit_base_con_req_rx; +static ble_l2cap_sig_rx_fn ble_l2cap_sig_credit_base_con_rsp_rx; +static ble_l2cap_sig_rx_fn ble_l2cap_sig_credit_base_reconfig_req_rx; +static ble_l2cap_sig_rx_fn ble_l2cap_sig_credit_base_reconfig_rsp_rx; +#else +#define ble_l2cap_sig_credit_base_con_req_rx ble_l2cap_sig_rx_noop +#define ble_l2cap_sig_credit_base_con_rsp_rx ble_l2cap_sig_rx_noop +#define ble_l2cap_sig_credit_base_reconfig_req_rx ble_l2cap_sig_rx_noop +#define ble_l2cap_sig_credit_base_reconfig_rsp_rx ble_l2cap_sig_rx_noop #endif static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = { @@ -121,9 +151,13 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = { [BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP] = ble_l2cap_sig_rx_noop, [BLE_L2CAP_SIG_OP_UPDATE_REQ] = ble_l2cap_sig_update_req_rx, [BLE_L2CAP_SIG_OP_UPDATE_RSP] = ble_l2cap_sig_update_rsp_rx, - [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ] = ble_l2cap_sig_coc_req_rx, - [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP] = ble_l2cap_sig_coc_rsp_rx, + [BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_REQ] = ble_l2cap_sig_coc_req_rx, + [BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP] = ble_l2cap_sig_coc_rsp_rx, [BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT] = ble_l2cap_sig_le_credits_rx, + [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ] = ble_l2cap_sig_credit_base_con_req_rx, + [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP] = ble_l2cap_sig_credit_base_con_rsp_rx, + [BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_REQ] = ble_l2cap_sig_credit_base_reconfig_req_rx, + [BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP] = ble_l2cap_sig_credit_base_reconfig_rsp_rx, }; static uint8_t ble_l2cap_sig_cur_id; @@ -286,6 +320,7 @@ ble_l2cap_sig_proc_extract(uint16_t conn_handle, uint8_t op, } break; } + prev = proc; } ble_hs_unlock(); @@ -611,29 +646,461 @@ ble_l2cap_event_coc_accept(struct ble_l2cap_chan *chan, uint16_t peer_sdu_size) static void ble_l2cap_sig_coc_connect_cb(struct ble_l2cap_sig_proc *proc, int status) { + struct ble_hs_conn *conn; struct ble_l2cap_chan *chan; + int i; + bool some_not_connected = false; if (!proc) { return; } - chan = proc->connect.chan; - if (!chan || !chan->cb) { + for (i = 0; i < proc->connect.chan_cnt; i++) { + chan = proc->connect.chan[i]; + if (!chan || !chan->cb) { + continue; + } + + if ((status == 0) && (chan->dcid != 0)) { + ble_l2cap_event_coc_connected(chan, status); + /* Let's forget about connected channel now. + * Not connected will be freed later on. + */ + proc->connect.chan[i] = NULL; + continue; + } + some_not_connected = true; + ble_l2cap_event_coc_connected(chan, status ? status : BLE_HS_EREJECT); + } + + if (!some_not_connected) { return; } - ble_l2cap_event_coc_connected(chan, status); + /* Free not connected channels*/ - if (status) { - /* Normally in channel free we send disconnected event to application. - * However in case on error during creation connection we send connected - * event with error status. To avoid additional disconnected event lets - * clear callbacks since we don't needed it anymore.*/ - chan->cb = NULL; - ble_l2cap_chan_free(chan); + ble_hs_lock(); + conn = ble_hs_conn_find(chan->conn_handle); + for (i = 0; i < proc->connect.chan_cnt; i++) { + chan = proc->connect.chan[i]; + if (chan) { + /* Normally in channel free we send disconnected event to application. + * However in case on error during creation connection we send connected + * event with error status. To avoid additional disconnected event lets + * clear callbacks since we don't needed it anymore. + */ + chan->cb = NULL; + ble_l2cap_chan_free(conn, chan); + } + } + ble_hs_unlock(); +} + +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +static void +ble_l2cap_event_coc_reconfigured(uint16_t conn_handle, uint16_t status, + struct ble_l2cap_chan *chan, bool peer) +{ + struct ble_l2cap_event event = { }; + + if (peer) { + event.type = BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED; + } else { + event.type = BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED; + } + event.reconfigured.conn_handle = conn_handle; + event.reconfigured.chan = chan; + event.reconfigured.status = status; + + chan->cb(&event, chan->cb_arg); +} + +static int +ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, + struct ble_l2cap_sig_hdr *hdr, + struct os_mbuf **om) +{ + struct ble_l2cap_chan *chan[BLE_L2CAP_MAX_COC_CONN_REQ] = {0}; + struct ble_l2cap_sig_credit_base_reconfig_req *req; + struct ble_l2cap_sig_credit_base_reconfig_rsp *rsp; + struct ble_hs_conn *conn; + struct os_mbuf *txom; + int i; + int rc; + uint8_t cid_cnt; + uint8_t reduction_mps = 0; + + rc = ble_hs_mbuf_pullup_base(om, hdr->length); + if (rc != 0) { + return rc; + } + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + ble_hs_unlock(); + return 0; + } + + rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP, + hdr->identifier, sizeof(*rsp) , &txom); + if (!rsp) { + /* TODO: Reuse request buffer for the response. For now in such a case + * remote will timeout. + */ + BLE_HS_LOG(ERROR, "No memory for the response\n"); + ble_hs_unlock(); + return 0; + } + + if (hdr->length <= sizeof(*req)) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + goto failed; + } + + req = (struct ble_l2cap_sig_credit_base_reconfig_req *)(*om)->om_data; + + if ((req->mps < BLE_L2CAP_ECOC_MIN_MTU) || (req->mtu < BLE_L2CAP_ECOC_MIN_MTU)) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + goto failed; + } + + /* Assume request will succeed. If not, result will be updated */ + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_SUCCEED); + + cid_cnt = (hdr->length - sizeof(*req)) / sizeof(uint16_t); + if (cid_cnt > BLE_L2CAP_MAX_COC_CONN_REQ) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + goto failed; + } + + for (i = 0; i < cid_cnt; i++) { + chan[i] = ble_hs_conn_chan_find_by_dcid(conn, req->dcids[i]); + if (!chan[i]) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_INVALID_DCID); + goto failed; + } + + if (chan[i]->peer_coc_mps > req->mps) { + reduction_mps++; + if (reduction_mps > 1) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED); + goto failed; + } + } + + if (chan[i]->coc_tx.mtu > req->mtu) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_REDUCTION_MTU_NOT_ALLOWED); + goto failed; + } + } + + ble_hs_unlock(); + + for (i = 0; i < cid_cnt; i++) { + chan[i]->coc_tx.mtu = req->mtu; + chan[i]->peer_coc_mps = req->mps; + ble_l2cap_event_coc_reconfigured(conn_handle, 0, chan[i], true); + } + + ble_l2cap_sig_tx(conn_handle, txom); + return 0; + +failed: + ble_hs_unlock(); + ble_l2cap_sig_tx(conn_handle, txom); + return 0; +} + +static void +ble_l2cap_sig_coc_reconfig_cb(struct ble_l2cap_sig_proc *proc, int status) +{ + int i; + struct ble_l2cap_chan *chan[BLE_L2CAP_MAX_COC_CONN_REQ] = {0}; + struct ble_hs_conn *conn; + + ble_hs_lock(); + + conn = ble_hs_conn_find(proc->conn_handle); + if (!conn) { + ble_hs_unlock(); + return; + } + + for (i = 0; i< proc->reconfig.cid_cnt; i++) { + chan[i] = ble_hs_conn_chan_find_by_scid(conn, proc->reconfig.cids[i]); + if (status == 0) { + ble_l2cap_coc_set_new_mtu_mps(chan[i], proc->reconfig.new_mtu, proc->reconfig.new_mps); + } + } + + ble_hs_unlock(); + + for (i = 0; i < proc->reconfig.cid_cnt; i++) { + ble_l2cap_event_coc_reconfigured(proc->conn_handle, status, chan[i], false); } } +static int +ble_l2cap_sig_credit_base_reconfig_rsp_rx(uint16_t conn_handle, + struct ble_l2cap_sig_hdr *hdr, + struct os_mbuf **om) +{ + struct ble_l2cap_sig_proc *proc; + struct ble_l2cap_sig_credit_base_reconfig_rsp *rsp; + int rc; + + proc = ble_l2cap_sig_proc_extract(conn_handle, + BLE_L2CAP_SIG_PROC_OP_RECONFIG, + hdr->identifier); + if (!proc) { + return 0; + } + + rc = ble_hs_mbuf_pullup_base(om, hdr->length); + if (rc != 0) { + return rc; + } + + rsp = (struct ble_l2cap_sig_credit_base_reconfig_rsp *)(*om)->om_data; + ble_l2cap_sig_coc_reconfig_cb(proc, (rsp->result > 0) ? BLE_HS_EREJECT : 0); + + return 0; +} + +static int +ble_l2cap_sig_credit_base_con_req_rx(uint16_t conn_handle, + struct ble_l2cap_sig_hdr *hdr, + struct os_mbuf **om) +{ + int rc; + struct ble_l2cap_sig_credit_base_connect_req *req; + struct os_mbuf *txom; + struct ble_l2cap_sig_credit_base_connect_rsp *rsp; + struct ble_l2cap_chan *chans[5] = { 0 }; + struct ble_hs_conn *conn; + uint16_t scid; + uint8_t num_of_scids; + uint8_t chan_created = 0; + int i; + uint8_t len; + + rc = ble_hs_mbuf_pullup_base(om, hdr->length); + if (rc != 0) { + return rc; + } + + len = (hdr->length > sizeof(*req)) ? hdr->length : sizeof(*req); + + rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP, + hdr->identifier, len , &txom); + if (!rsp) { + /* Well, nothing smart we can do if there is no memory for response. + * Remote will timeout. + */ + return 0; + } + + ble_hs_lock(); + + memset(rsp, 0, len); + + /* Initial dummy values in case of error, just to satisfy PTS */ + rsp->credits = htole16(1); + rsp->mps = htole16(BLE_L2CAP_ECOC_MIN_MTU); + rsp->mtu = htole16(BLE_L2CAP_ECOC_MIN_MTU); + + if (hdr->length <= sizeof(*req)) { + rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_PARAMETERS); + goto failed; + } + + req = (struct ble_l2cap_sig_credit_base_connect_req *)(*om)->om_data; + + num_of_scids = (hdr->length - sizeof(*req)) / sizeof(uint16_t); + if (num_of_scids > 5) { + rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_PARAMETERS); + goto failed; + } + + if ((req->mtu < BLE_L2CAP_ECOC_MIN_MTU) || (req->mps < BLE_L2CAP_ECOC_MIN_MTU)) { + rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_PARAMETERS); + goto failed; + } + + conn = ble_hs_conn_find_assert(conn_handle); + + /* First verify that provided SCIDs are good */ + for (i = 0; i < num_of_scids; i++) { + scid = le16toh(req->scids[i]); + if (scid < BLE_L2CAP_COC_CID_START || scid > BLE_L2CAP_COC_CID_END) { + rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID); + goto failed; + } + } + + /* Let us try to connect channels */ + for (i = 0; i < num_of_scids; i++) { + /* Verify CID. Note, scid in the request is dcid for out local channel */ + scid = le16toh(req->scids[i]); + chans[i] = ble_hs_conn_chan_find_by_dcid(conn, scid); + if (chans[i]) { + rsp->result = htole16(BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED); + rsp->dcids[i] = htole16(chans[i]->scid); + continue; + } + + rc = ble_l2cap_coc_create_srv_chan(conn, le16toh(req->psm), &chans[i]); + if (rc != 0) { + if (i == 0) { + /* In case it is very first channel we cannot create it means PSM is incorrect + * or we are out of resources. Just send a response now. + */ + rsp->result = htole16(ble_l2cap_sig_ble_hs_err2coc_err(rc)); + goto failed; + } else { + /* We cannot create number of channels req by peer due to limited resources. */ + rsp->result = htole16(BLE_L2CAP_COC_ERR_NO_RESOURCES); + goto done; + } + } + + /* Fill up remote configuration. Note MPS is the L2CAP MTU*/ + chans[i]->dcid = scid; + chans[i]->peer_coc_mps = le16toh(req->mps); + chans[i]->coc_tx.credits = le16toh(req->credits); + chans[i]->coc_tx.mtu = le16toh(req->mtu); + + ble_hs_conn_chan_insert(conn, chans[i]); + /* Sending event to the app. Unlock hs */ + ble_hs_unlock(); + + rc = ble_l2cap_event_coc_accept(chans[i], le16toh(req->mtu)); + if (rc == 0) { + rsp->dcids[i] = htole16(chans[i]->scid); + chan_created++; + if (chan_created == 1) { + /* We need to set it once as there are same initial parameters + * for all the channels + */ + rsp->credits = htole16(chans[i]->coc_rx.credits); + rsp->mps = htole16(chans[i]->my_mtu); + rsp->mtu = htole16(chans[i]->coc_rx.mtu); + } + } else { + /* Make sure we do not send disconnect event when removing channel */ + chans[i]->cb = NULL; + + ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); + ble_hs_conn_delete_chan(conn, chans[i]); + chans[i] = NULL; + rsp->result = htole16(ble_l2cap_sig_ble_hs_err2coc_err(rc)); + rc = 0; + ble_hs_unlock(); + } + + ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); + } + +done: + ble_hs_unlock(); + rc = ble_l2cap_sig_tx(conn_handle, txom); + if (rc != 0) { + ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); + for (i = 0; i < num_of_scids; i++) { + if (chans[i]) { + ble_hs_conn_delete_chan(conn, chans[i]); + } + } + ble_hs_unlock(); + return 0; + } + + /* Notify user about connection status */ + for (i = 0; i < num_of_scids; i++) { + if (chans[i]) { + ble_l2cap_event_coc_connected(chans[i], rc); + } + } + + return 0; + +failed: + ble_hs_unlock(); + ble_l2cap_sig_tx(conn_handle, txom); + return 0; +} + +static int +ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, + struct ble_l2cap_sig_hdr *hdr, + struct os_mbuf **om) +{ + struct ble_l2cap_sig_proc *proc; + struct ble_l2cap_sig_credit_base_connect_rsp *rsp; + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; + int rc; + int i; + +#if !BLE_MONITOR + BLE_HS_LOG(DEBUG, "L2CAP LE COC connection response received\n"); +#endif + + proc = ble_l2cap_sig_proc_extract(conn_handle, + BLE_L2CAP_SIG_PROC_OP_CONNECT, + hdr->identifier); + if (!proc) { + return 0; + } + + rc = ble_hs_mbuf_pullup_base(om, hdr->length); + if (rc != 0) { + goto done; + } + + rsp = (struct ble_l2cap_sig_credit_base_connect_rsp *)(*om)->om_data; + + if (rsp->result) { + rc = ble_l2cap_sig_coc_err2ble_hs_err(le16toh(rsp->result)); + goto done; + } + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + assert(conn != NULL); + + for (i = 0; i < proc->connect.chan_cnt; i++) { + chan = proc->connect.chan[i]; + if (rsp->dcids[i] == 0) { + /* Channel rejected, dont put it on the list. + * User will get notified later in that function + */ + chan->dcid = 0; + continue; + } + chan->peer_coc_mps = le16toh(rsp->mps); + chan->dcid = le16toh(rsp->dcids[i]); + chan->coc_tx.mtu = le16toh(rsp->mtu); + chan->coc_tx.credits = le16toh(rsp->credits); + + ble_hs_conn_chan_insert(conn, chan); + } + + ble_hs_unlock(); + +done: + ble_l2cap_sig_coc_connect_cb(proc, rc); + ble_l2cap_sig_proc_free(proc); + + /* Silently ignore errors as this is response signal */ + return 0; +} +#endif + static int ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct os_mbuf **om) @@ -651,7 +1118,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return rc; } - rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP, + rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP, hdr->identifier, sizeof(*rsp), &txom); if (!rsp) { /* Well, nothing smart we can do if there is no memory for response. @@ -682,7 +1149,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto failed; } - rc = ble_l2cap_coc_create_srv_chan(conn_handle, le16toh(req->psm), &chan); + rc = ble_l2cap_coc_create_srv_chan(conn, le16toh(req->psm), &chan); if (rc != 0) { uint16_t coc_err = ble_l2cap_sig_ble_hs_err2coc_err(rc); rsp->result = htole16(coc_err); @@ -692,7 +1159,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, /* Fill up remote configuration. Note MPS is the L2CAP MTU*/ chan->dcid = scid; - chan->peer_mtu = le16toh(req->mps); + chan->peer_coc_mps = le16toh(req->mps); chan->coc_tx.credits = le16toh(req->credits); chan->coc_tx.mtu = le16toh(req->mtu); @@ -707,6 +1174,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, chan->cb = NULL; ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); ble_hs_conn_delete_chan(conn, chan); ble_hs_unlock(); rsp->result = htole16(coc_err); @@ -715,13 +1183,14 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, rsp->dcid = htole16(chan->scid); rsp->credits = htole16(chan->coc_rx.credits); - rsp->mps = htole16(chan->my_mtu); + rsp->mps = htole16(chan->my_coc_mps); rsp->mtu = htole16(chan->coc_rx.mtu); rsp->result = htole16(BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS); rc = ble_l2cap_sig_tx(conn_handle, txom); if (rc != 0) { ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); ble_hs_conn_delete_chan(conn, chan); ble_hs_unlock(); return 0; @@ -765,7 +1234,7 @@ ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, rsp = (struct ble_l2cap_sig_le_con_rsp *)(*om)->om_data; - chan = proc->connect.chan; + chan = proc->connect.chan[0]; if (rsp->result) { rc = ble_l2cap_sig_coc_err2ble_hs_err(le16toh(rsp->result)); @@ -775,7 +1244,7 @@ ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, /* Fill up remote configuration * Note MPS is the L2CAP MTU */ - chan->peer_mtu = le16toh(rsp->mps); + chan->peer_coc_mps = le16toh(rsp->mps); chan->dcid = le16toh(rsp->dcid); chan->coc_tx.mtu = le16toh(rsp->mtu); chan->coc_tx.credits = le16toh(rsp->credits); @@ -820,7 +1289,7 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, return BLE_HS_ENOTCONN; } - chan = ble_l2cap_coc_chan_alloc(conn_handle, psm, mtu, sdu_rx, cb, cb_arg); + chan = ble_l2cap_coc_chan_alloc(conn, psm, mtu, sdu_rx, cb, cb_arg); if (!chan) { ble_hs_unlock(); return BLE_HS_ENOMEM; @@ -828,7 +1297,7 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, proc = ble_l2cap_sig_proc_alloc(); if (!proc) { - ble_l2cap_chan_free(chan); + ble_l2cap_chan_free(conn, chan); ble_hs_unlock(); return BLE_HS_ENOMEM; } @@ -836,34 +1305,193 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, proc->op = BLE_L2CAP_SIG_PROC_OP_CONNECT; proc->id = ble_l2cap_sig_next_id(); proc->conn_handle = conn_handle; - proc->connect.chan = chan; + proc->connect.chan[0] = chan; + proc->connect.chan_cnt = 1; - req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ, proc->id, + req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_REQ, proc->id, sizeof(*req), &txom); if (!req) { - ble_l2cap_chan_free(chan); + ble_l2cap_chan_free(conn, chan); ble_hs_unlock(); - return BLE_HS_ENOMEM; + rc = BLE_HS_ENOMEM; + /* Goto done to clear proc */ + goto done; } req->psm = htole16(psm); req->scid = htole16(chan->scid); req->mtu = htole16(chan->coc_rx.mtu); - req->mps = htole16(chan->my_mtu); + req->mps = htole16(chan->my_coc_mps); req->credits = htole16(chan->coc_rx.credits); ble_hs_unlock(); rc = ble_l2cap_sig_tx(proc->conn_handle, txom); if (rc != 0) { - ble_l2cap_chan_free(chan); + ble_hs_lock(); + conn = ble_hs_conn_find_assert(conn_handle); + ble_l2cap_chan_free(conn, chan); + ble_hs_unlock(); } +done: ble_l2cap_sig_process_status(proc, rc); return rc; } +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +int +ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg) +{ + struct ble_hs_conn *conn; + struct ble_l2cap_sig_proc *proc; + struct ble_l2cap_chan *chan = NULL; + struct os_mbuf *txom; + struct ble_l2cap_sig_credit_base_connect_req *req; + int rc; + int i; + int j; + + if (!sdu_rx || !cb) { + return BLE_HS_EINVAL; + } + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + + if (!conn) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + proc = ble_l2cap_sig_proc_alloc(); + if (!proc) { + ble_hs_unlock(); + return BLE_HS_ENOMEM; + } + + proc->op = BLE_L2CAP_SIG_PROC_OP_CONNECT; + proc->id = ble_l2cap_sig_next_id(); + proc->conn_handle = conn_handle; + + req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ, proc->id, + sizeof(*req) + num * sizeof(uint16_t), &txom); + if (!req) { + ble_hs_unlock(); + rc = BLE_HS_ENOMEM; + /* Goto done to clear proc */ + goto done; + } + + for (i = 0; i < num; i++) { + chan = ble_l2cap_coc_chan_alloc(conn, psm, mtu, sdu_rx[i], cb, cb_arg); + if (!chan) { + /* Clear request buffer */ + os_mbuf_free_chain(txom); + + for (j = 0; j < i; j++) { + /* Clear callback to make sure "Disconnected event" to the user */ + chan[j].cb = NULL; + ble_l2cap_chan_free(conn, proc->connect.chan[j]); + } + ble_hs_unlock(); + rc = BLE_HS_ENOMEM; + goto done; + } + proc->connect.chan[i] = chan; + } + proc->connect.chan_cnt = num; + + req->psm = htole16(psm); + req->mtu = htole16(chan->coc_rx.mtu); + req->mps = htole16(chan->my_mtu); + req->credits = htole16(chan->coc_rx.credits); + for (i = 0; i < num; i++) { + req->scids[i] = htole16(proc->connect.chan[i]->scid); + } + + ble_hs_unlock(); + + rc = ble_l2cap_sig_tx(proc->conn_handle, txom); + +done: + ble_l2cap_sig_process_status(proc, rc); + + return rc; +} + +int +ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], + uint8_t num, uint16_t new_mtu) +{ + struct ble_hs_conn *conn; + struct ble_l2cap_sig_proc *proc; + struct os_mbuf *txom; + struct ble_l2cap_sig_credit_base_reconfig_req *req; + int rc; + int i; + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + + if (!conn) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + proc = ble_l2cap_sig_proc_alloc(); + if (!proc) { + ble_hs_unlock(); + return BLE_HS_ENOMEM; + } + + for (i = 0; i < num; i++) { + if (ble_hs_conn_chan_exist(conn, chans[i])) { + proc->reconfig.cids[i] = chans[i]->scid; + } else { + ble_hs_unlock(); + rc = BLE_HS_ENOMEM; + goto done; + } + } + + proc->op = BLE_L2CAP_SIG_PROC_OP_RECONFIG; + proc->reconfig.cid_cnt = num; + proc->reconfig.new_mtu = new_mtu; + proc->reconfig.new_mps = MYNEWT_VAL(BLE_L2CAP_COC_MPS); + proc->id = ble_l2cap_sig_next_id(); + proc->conn_handle = conn_handle; + + req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_REQ, proc->id, + sizeof(*req) + num * sizeof(uint16_t), &txom); + if (!req) { + ble_hs_unlock(); + rc = BLE_HS_ENOMEM; + goto done; + } + + /* For now we allow to change CoC MTU only.*/ + req->mtu = htole16(proc->reconfig.new_mtu); + req->mps = htole16(proc->reconfig.new_mps); + + for (i = 0; i < num; i++) { + req->dcids[i] = htole16(proc->reconfig.cids[i]); + } + + ble_hs_unlock(); + + rc = ble_l2cap_sig_tx(proc->conn_handle, txom); + +done: + ble_l2cap_sig_process_status(proc, rc); + + return rc; +} +#endif + /***************************************************************************** * $disconnect * *****************************************************************************/ @@ -945,11 +1573,11 @@ ble_l2cap_sig_coc_disconnect_cb(struct ble_l2cap_sig_proc *proc, int status) done: ble_hs_lock(); - conn = ble_hs_conn_find(chan->conn_handle); + conn = ble_hs_conn_find_assert(chan->conn_handle); if (conn) { ble_hs_conn_delete_chan(conn, chan); } else { - ble_l2cap_chan_free(chan); + ble_l2cap_chan_free(NULL, chan); } ble_hs_unlock(); } @@ -1241,6 +1869,11 @@ ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason) case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: ble_l2cap_sig_coc_disconnect_cb(proc, reason); break; +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) + case BLE_L2CAP_SIG_PROC_OP_RECONFIG: + ble_l2cap_sig_coc_reconfig_cb(proc, reason); + break; +#endif #endif } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_priv.h index 1a6fb8293..a698cd0d8 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_priv.h @@ -74,6 +74,32 @@ struct ble_l2cap_sig_le_con_rsp { uint16_t result; } __attribute__((packed)); +struct ble_l2cap_sig_credit_base_connect_req { + uint16_t psm; + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t scids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_connect_rsp { + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t result; + uint16_t dcids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_reconfig_req { + uint16_t mtu; + uint16_t mps; + uint16_t dcids[0]; +} __attribute__((packed)); + +struct ble_l2cap_sig_credit_base_reconfig_rsp { + uint16_t result; +} __attribute__((packed)); + struct ble_l2cap_sig_disc_req { uint16_t dcid; uint16_t scid; @@ -107,9 +133,43 @@ int ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan); int ble_l2cap_sig_le_credits(uint16_t conn_handle, uint16_t scid, uint16_t credits); #else -#define ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg) \ - BLE_HS_ENOTSUP -#define ble_l2cap_sig_disconnect(chan) BLE_HS_ENOTSUP +static inline int +ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, void *cb_arg) +{ + return BLE_HS_ENOTSUP; +} + +static inline int +ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan) +{ + return BLE_HS_ENOTSUP; +} +#endif + +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) +int ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], + uint8_t num, uint16_t new_mtu); +#else +static inline int +ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + uint8_t num, struct os_mbuf *sdu_rx[], + ble_l2cap_event_fn *cb, void *cb_arg) +{ + return BLE_HS_ENOTSUP; +} +static inline int +ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], + uint8_t num, uint16_t new_mtu) +{ + return BLE_HS_ENOTSUP; +} #endif void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm.c index 6fa6f00c4..8422c044f 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm.c @@ -95,6 +95,14 @@ static ble_sm_rx_fn * const ble_sm_dispatch[] = { #endif }; +struct hci_start_encrypt +{ + uint16_t connection_handle; + uint16_t encrypted_diversifier; + uint64_t random_number; + uint8_t long_term_key[16]; +}; + typedef void ble_sm_state_fn(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg); @@ -575,7 +583,8 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) } } else { peer_addr = conn->bhc_peer_addr; - peer_addr.type = ble_hs_misc_addr_type_to_id(conn->bhc_peer_addr.type); + peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); } ble_hs_unlock(); @@ -758,6 +767,9 @@ ble_sm_ioact_state(uint8_t action) case BLE_SM_IOACT_NUMCMP: return BLE_SM_PROC_STATE_DHKEY_CHECK; + case BLE_SM_IOACT_OOB_SC: + return BLE_SM_PROC_STATE_RANDOM; + case BLE_SM_IOACT_OOB: case BLE_SM_IOACT_INPUT: case BLE_SM_IOACT_DISP: @@ -815,13 +827,17 @@ ble_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason) { struct ble_sm_pair_fail *cmd; struct os_mbuf *txom; + int rc; BLE_HS_DBG_ASSERT(reason > 0 && reason < BLE_SM_ERR_MAX_PLUS_1); cmd = ble_sm_cmd_get(BLE_SM_OP_PAIR_FAIL, sizeof(*cmd), &txom); if (cmd) { cmd->reason = reason; - ble_sm_tx(conn_handle, txom); + rc = ble_sm_tx(conn_handle, txom); + if (rc) { + BLE_HS_LOG(ERROR, "ble_sm_pair_fail_tx failed, rc = %d\n", rc); + } } } @@ -1059,20 +1075,18 @@ ble_sm_chk_store_overflow(uint16_t conn_handle) *****************************************************************************/ static int -ble_sm_start_encrypt_tx(struct hci_start_encrypt *cmd) +ble_sm_start_encrypt_tx(struct hci_start_encrypt *params) { - uint8_t buf[BLE_HCI_LE_START_ENCRYPT_LEN]; - int rc; + struct ble_hci_le_start_encrypt_cp cmd; - ble_hs_hci_cmd_build_le_start_encrypt(cmd, buf, sizeof buf); - rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_START_ENCRYPT), - buf, sizeof(buf)); - if (rc != 0) { - return rc; - } + cmd.conn_handle = htole16(params->connection_handle); + cmd.div = htole16(params->encrypted_diversifier); + cmd.rand = htole64(params->random_number); + memcpy(cmd.ltk, params->long_term_key, sizeof(cmd.ltk)); - return 0; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_START_ENCRYPT), + &cmd, sizeof(cmd), NULL, 0); } static void @@ -1208,19 +1222,19 @@ ble_sm_enc_event_rx(uint16_t conn_handle, uint8_t evt_status, int encrypted) } void -ble_sm_enc_change_rx(struct hci_encrypt_change *evt) +ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev) { /* For encrypted state: read LE-encryption bit; ignore BR/EDR and reserved * bits. */ - ble_sm_enc_event_rx(evt->connection_handle, evt->status, - evt->encryption_enabled & 0x01); + ble_sm_enc_event_rx(le16toh(ev->connection_handle), ev->status, + ev->enabled & 0x01); } void -ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt) +ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev) { - ble_sm_enc_event_rx(evt->connection_handle, evt->status, 1); + ble_sm_enc_event_rx(le16toh(ev->conn_handle), ev->status, 1); } /***************************************************************************** @@ -1228,7 +1242,7 @@ ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt) *****************************************************************************/ static int -ble_sm_retrieve_ltk(struct hci_le_lt_key_req *evt, uint8_t peer_addr_type, +ble_sm_retrieve_ltk(uint16_t ediv, uint64_t rand, uint8_t peer_addr_type, uint8_t *peer_addr, struct ble_store_value_sec *value_sec) { struct ble_store_key_sec key_sec; @@ -1238,8 +1252,8 @@ ble_sm_retrieve_ltk(struct hci_le_lt_key_req *evt, uint8_t peer_addr_type, memset(&key_sec, 0, sizeof key_sec); key_sec.peer_addr.type = peer_addr_type; memcpy(key_sec.peer_addr.val, peer_addr, 6); - key_sec.ediv = evt->encrypted_diversifier; - key_sec.rand_num = evt->random_number; + key_sec.ediv = ediv; + key_sec.rand_num = rand; key_sec.ediv_rand_present = 1; rc = ble_store_read_our_sec(&key_sec, value_sec); @@ -1247,30 +1261,23 @@ ble_sm_retrieve_ltk(struct hci_le_lt_key_req *evt, uint8_t peer_addr_type, } static int -ble_sm_ltk_req_reply_tx(uint16_t conn_handle, uint8_t *ltk) +ble_sm_ltk_req_reply_tx(uint16_t conn_handle, const uint8_t *ltk) { - struct hci_lt_key_req_reply cmd; - uint16_t ack_conn_handle; - uint8_t buf[BLE_HCI_LT_KEY_REQ_REPLY_LEN]; - uint8_t ack_params_len; + struct ble_hci_le_lt_key_req_reply_cp cmd; + struct ble_hci_le_lt_key_req_reply_rp rsp; int rc; - cmd.conn_handle = conn_handle; - memcpy(cmd.long_term_key, ltk, 16); + cmd.conn_handle = htole16(conn_handle); + memcpy(cmd.ltk, ltk, 16); - ble_hs_hci_cmd_build_le_lt_key_req_reply(&cmd, buf, sizeof buf); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY), - buf, sizeof(buf), &ack_conn_handle, - sizeof(ack_conn_handle), &ack_params_len); + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN) { - return BLE_HS_ECONTROLLER; - } - if (le16toh(ack_conn_handle) != conn_handle) { + if (le16toh(rsp.conn_handle) != conn_handle) { return BLE_HS_ECONTROLLER; } @@ -1280,24 +1287,19 @@ ble_sm_ltk_req_reply_tx(uint16_t conn_handle, uint8_t *ltk) static int ble_sm_ltk_req_neg_reply_tx(uint16_t conn_handle) { - uint16_t ack_conn_handle; - uint8_t buf[BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN]; - uint8_t ack_params_len; + struct ble_hci_le_lt_key_req_neg_reply_cp cmd; + struct ble_hci_le_lt_key_req_neg_reply_cp rsp; int rc; - ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(conn_handle, buf, sizeof buf); + cmd.conn_handle = htole16(conn_handle); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY), - buf, sizeof(buf), &ack_conn_handle, - sizeof(ack_conn_handle), &ack_params_len); + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { return rc; } - if (ack_params_len != BLE_HCI_LT_KEY_REQ_NEG_REPLY_ACK_PARAM_LEN) { - return BLE_HS_ECONTROLLER; - } - if (le16toh(ack_conn_handle) != conn_handle) { + if (le16toh(rsp.conn_handle) != conn_handle) { return BLE_HS_ECONTROLLER; } @@ -1356,7 +1358,7 @@ ble_sm_ltk_restore_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, } int -ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) +ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev) { struct ble_store_value_sec value_sec; struct ble_hs_conn_addrs addrs; @@ -1367,11 +1369,12 @@ ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) int store_rc; int restore; + uint16_t conn_handle = le16toh(ev->conn_handle); + memset(&res, 0, sizeof res); ble_hs_lock(); - proc = ble_sm_proc_find(evt->connection_handle, BLE_SM_PROC_STATE_NONE, - 0, NULL); + proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, 0, NULL); if (proc == NULL) { /* The peer is attempting to restore a encrypted connection via the * encryption procedure. Create a proc entry to indicate that security @@ -1383,7 +1386,7 @@ ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) if (proc == NULL) { res.app_status = BLE_HS_ENOMEM; } else { - proc->conn_handle = evt->connection_handle; + proc->conn_handle = conn_handle; proc->state = BLE_SM_PROC_STATE_LTK_RESTORE; ble_sm_insert(proc); @@ -1405,12 +1408,12 @@ ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) } else { /* The request is unexpected; nack and forget. */ restore = 0; - ble_sm_ltk_req_neg_reply_tx(evt->connection_handle); + ble_sm_ltk_req_neg_reply_tx(conn_handle); proc = NULL; } if (restore) { - conn = ble_hs_conn_find_assert(evt->connection_handle); + conn = ble_hs_conn_find_assert(conn_handle); ble_hs_conn_addrs(conn, &addrs); memcpy(peer_id_addr, addrs.peer_id_addr.val, 6); } @@ -1423,7 +1426,8 @@ ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) if (res.app_status == 0) { if (restore) { - store_rc = ble_sm_retrieve_ltk(evt, addrs.peer_id_addr.type, + store_rc = ble_sm_retrieve_ltk(le16toh(ev->div), le64toh(ev->rand), + addrs.peer_id_addr.type, peer_id_addr, &value_sec); if (store_rc == 0) { /* Send the key to the controller. */ @@ -1435,7 +1439,7 @@ ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt) } } - ble_sm_process_result(evt->connection_handle, &res); + ble_sm_process_result(conn_handle, &res); return 0; } @@ -1491,8 +1495,6 @@ ble_sm_random_rx(uint16_t conn_handle, struct os_mbuf **om, cmd = (struct ble_sm_pair_random *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "random", conn_handle, ble_sm_pair_random_log, cmd); - ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_RANDOM, -1, NULL); if (proc == NULL) { @@ -1541,8 +1543,6 @@ ble_sm_confirm_rx(uint16_t conn_handle, struct os_mbuf **om, cmd = (struct ble_sm_pair_confirm *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "confirm", conn_handle, ble_sm_pair_confirm_log, cmd); - ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_CONFIRM, -1, NULL); if (proc == NULL) { @@ -1789,8 +1789,6 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, req = (struct ble_sm_pair_cmd *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "pair req", conn_handle, ble_sm_pair_cmd_log, req); - ble_hs_lock(); /* XXX: Check connection state; reject if not appropriate. */ @@ -1902,8 +1900,6 @@ ble_sm_pair_rsp_rx(uint16_t conn_handle, struct os_mbuf **om, rsp = (struct ble_sm_pair_cmd *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "pair rsp", conn_handle, ble_sm_pair_cmd_log, rsp); - ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PAIR, 1, NULL); if (proc != NULL) { @@ -1982,7 +1978,6 @@ ble_sm_sec_req_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_sec_req *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "sec req", conn_handle, ble_sm_sec_req_log, cmd); /* XXX: Reject if: * o authreq-reserved flags set? @@ -2266,7 +2261,6 @@ ble_sm_enc_info_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_enc_info *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "enc info", conn_handle, ble_sm_enc_info_log, cmd); ble_hs_lock(); @@ -2301,7 +2295,6 @@ ble_sm_master_id_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_master_id *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "master id", conn_handle, ble_sm_master_id_log, cmd); ble_hs_lock(); @@ -2337,7 +2330,6 @@ ble_sm_id_info_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_id_info *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "id info", conn_handle, ble_sm_id_info_log, cmd); ble_hs_lock(); @@ -2372,8 +2364,6 @@ ble_sm_id_addr_info_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_id_addr_info *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "id addr info", conn_handle, ble_sm_id_addr_info_log, - cmd); ble_hs_lock(); @@ -2408,7 +2398,6 @@ ble_sm_sign_info_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_sign_info *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "sign info", conn_handle, ble_sm_sign_info_log, cmd); ble_hs_lock(); @@ -2443,7 +2432,6 @@ ble_sm_fail_rx(uint16_t conn_handle, struct os_mbuf **om, res->app_status = ble_hs_mbuf_pullup_base(om, sizeof(*cmd)); if (res->app_status == 0) { cmd = (struct ble_sm_pair_fail *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "fail", conn_handle, ble_sm_pair_fail_log, cmd); res->app_status = BLE_HS_SM_PEER_ERR(cmd->reason); } @@ -2744,6 +2732,24 @@ ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey) } break; +#if MYNEWT_VAL(BLE_SM_SC) + case BLE_SM_IOACT_OOB_SC: + if (!ble_sm_sc_oob_data_check(proc, + (pkey->oob_sc_data.local != NULL), + (pkey->oob_sc_data.remote != NULL))) { + res.app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_OOB); + res.sm_err = BLE_SM_ERR_OOB; + } else { + proc->flags |= BLE_SM_PROC_F_IO_INJECTED; + proc->oob_data_local = pkey->oob_sc_data.local; + proc->oob_data_remote = pkey->oob_sc_data.remote; + + /* Execute Confirm step */ + ble_sm_sc_oob_confirm(proc, &res); + } + break; +#endif + default: BLE_HS_DBG_ASSERT(0); rc = BLE_HS_EINVAL; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_alg.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_alg.c index 93453c603..ee8b937c5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_alg.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_alg.c @@ -66,7 +66,7 @@ static struct trng_dev *g_trng; #endif static void -ble_sm_alg_xor_128(uint8_t *p, uint8_t *q, uint8_t *r) +ble_sm_alg_xor_128(const uint8_t *p, const uint8_t *q, uint8_t *r) { int i; @@ -76,7 +76,8 @@ ble_sm_alg_xor_128(uint8_t *p, uint8_t *q, uint8_t *r) } int -ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data) +ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, + uint8_t *enc_data) { uint8_t tmp[16]; @@ -87,14 +88,18 @@ ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data) mbedtls_aes_init(&s); if (mbedtls_aes_setkey_enc(&s, tmp, 128) != 0) { + mbedtls_aes_free(&s); return BLE_HS_EUNKNOWN; } swap_buf(tmp, plaintext, 16); if (mbedtls_aes_crypt_ecb(&s, MBEDTLS_AES_ENCRYPT, tmp, enc_data) != 0) { + mbedtls_aes_free(&s); return BLE_HS_EUNKNOWN; } + + mbedtls_aes_free(&s); #else struct tc_aes_key_sched_struct s; @@ -115,7 +120,8 @@ ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data) } int -ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out) +ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2, + uint8_t *out) { int rc; @@ -150,10 +156,10 @@ ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out) } int -ble_sm_alg_c1(uint8_t *k, uint8_t *r, - uint8_t *preq, uint8_t *pres, +ble_sm_alg_c1(const uint8_t *k, const uint8_t *r, + const uint8_t *preq, const uint8_t *pres, uint8_t iat, uint8_t rat, - uint8_t *ia, uint8_t *ra, + const uint8_t *ia, const uint8_t *ra, uint8_t *out_enc_data) { uint8_t p1[16], p2[16]; @@ -301,8 +307,8 @@ ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, #endif int -ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z, - uint8_t *out_enc_data) +ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, + uint8_t z, uint8_t *out_enc_data) { uint8_t xs[16]; uint8_t m[65]; @@ -346,9 +352,9 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z, } int -ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t, - uint8_t *a1, uint8_t a2t, uint8_t *a2, uint8_t *mackey, - uint8_t *ltk) +ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + uint8_t a1t, const uint8_t *a1, uint8_t a2t, const uint8_t *a2, + uint8_t *mackey, uint8_t *ltk) { static const uint8_t salt[16] = { 0x6c, 0x88, 0x83, 0x91, 0xaa, 0xf5, 0xa5, 0x38, 0x60, 0x37, 0x0b, 0xdb, @@ -462,8 +468,8 @@ ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, } int -ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, - uint32_t *passkey) +ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, + const uint8_t *y, uint32_t *passkey) { uint8_t m[80], xs[16]; int rc; @@ -495,8 +501,8 @@ ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, } int -ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, - uint8_t *our_priv_key, uint8_t *out_dhkey) +ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, + const uint8_t *our_priv_key, uint8_t *out_dhkey) { uint8_t dh[32]; uint8_t pk[64]; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c index e12e109d5..01651f1df 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c @@ -66,97 +66,3 @@ ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) return rc; } - -#if NIMBLE_BLE_SM -void -ble_sm_pair_cmd_log(struct ble_sm_pair_cmd *cmd) -{ - BLE_HS_LOG(DEBUG, "io_cap=%d oob_data_flag=%d authreq=0x%02x " - "mac_enc_key_size=%d init_key_dist=%d " - "resp_key_dist=%d", - cmd->io_cap, cmd->oob_data_flag, cmd->authreq, - cmd->max_enc_key_size, cmd->init_key_dist, - cmd->resp_key_dist); -} - -void -ble_sm_pair_confirm_log(struct ble_sm_pair_confirm *cmd) -{ - BLE_HS_LOG(DEBUG, "value="); - ble_hs_log_flat_buf(cmd->value, sizeof cmd->value); -} - -void -ble_sm_pair_random_log(struct ble_sm_pair_random *cmd) -{ - BLE_HS_LOG(DEBUG, "value="); - ble_hs_log_flat_buf(cmd->value, sizeof cmd->value); -} - -void -ble_sm_pair_fail_log(struct ble_sm_pair_fail *cmd) -{ - BLE_HS_LOG(DEBUG, "reason=%d", cmd->reason); -} - -void -ble_sm_enc_info_log(struct ble_sm_enc_info *cmd) -{ - BLE_HS_LOG(DEBUG, "ltk="); - ble_hs_log_flat_buf(cmd->ltk, sizeof cmd->ltk); -} - -void -ble_sm_master_id_log(struct ble_sm_master_id *cmd) -{ - /* These get logged separately to accommodate a bug in the va_args - * implementation related to 64-bit integers. - */ - BLE_HS_LOG(DEBUG, "ediv=0x%04x ", cmd->ediv); - BLE_HS_LOG(DEBUG, "rand=0x%016llx", cmd->rand_val); -} - -void -ble_sm_id_info_log(struct ble_sm_id_info *cmd) -{ - BLE_HS_LOG(DEBUG, "irk="); - ble_hs_log_flat_buf(cmd->irk, sizeof cmd->irk); -} - -void -ble_sm_id_addr_info_log(struct ble_sm_id_addr_info *cmd) -{ - BLE_HS_LOG(DEBUG, "addr_type=%d addr=", cmd->addr_type); - BLE_HS_LOG_ADDR(DEBUG, cmd->bd_addr); -} - -void -ble_sm_sign_info_log(struct ble_sm_sign_info *cmd) -{ - BLE_HS_LOG(DEBUG, "sig_key="); - ble_hs_log_flat_buf(cmd->sig_key, sizeof cmd->sig_key); -} - -void -ble_sm_sec_req_log(struct ble_sm_sec_req *cmd) -{ - BLE_HS_LOG(DEBUG, "authreq=0x%02x", cmd->authreq); -} - -void -ble_sm_public_key_log(struct ble_sm_public_key *cmd) -{ - BLE_HS_LOG(DEBUG, "x="); - ble_hs_log_flat_buf(cmd->x, sizeof cmd->x); - BLE_HS_LOG(DEBUG, "y="); - ble_hs_log_flat_buf(cmd->y, sizeof cmd->y); -} - -void -ble_sm_dhkey_check_log(struct ble_sm_dhkey_check *cmd) -{ - BLE_HS_LOG(DEBUG, "value="); - ble_hs_log_flat_buf(cmd->value, sizeof cmd->value); -} - -#endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h index bbb4b03ae..def0a32f5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h @@ -269,6 +269,8 @@ struct ble_sm_proc { struct ble_sm_public_key pub_key_peer; uint8_t mackey[16]; uint8_t dhkey[32]; + const struct ble_sm_sc_oob_data *oob_data_local; + const struct ble_sm_sc_oob_data *oob_data_remote; #endif }; @@ -294,44 +296,33 @@ void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey); int ble_sm_num_procs(void); -void ble_sm_pair_cmd_log(struct ble_sm_pair_cmd *cmd); -void ble_sm_pair_confirm_log(struct ble_sm_pair_confirm *cmd); -void ble_sm_pair_random_log(struct ble_sm_pair_random *cmd); -void ble_sm_pair_fail_log(struct ble_sm_pair_fail *cmd); -void ble_sm_enc_info_log(struct ble_sm_enc_info *cmd); -void ble_sm_master_id_log(struct ble_sm_master_id *cmd); -void ble_sm_id_info_log(struct ble_sm_id_info *cmd); -void ble_sm_id_addr_info_log(struct ble_sm_id_addr_info *cmd); -void ble_sm_sign_info_log(struct ble_sm_sign_info *cmd); -void ble_sm_sec_req_log(struct ble_sm_sec_req *cmd); -void ble_sm_public_key_log(struct ble_sm_public_key *cmd); -void ble_sm_dhkey_check_log(struct ble_sm_dhkey_check *cmd); - -int ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out); -int ble_sm_alg_c1(uint8_t *k, uint8_t *r, - uint8_t *preq, uint8_t *pres, +int ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2, + uint8_t *out); +int ble_sm_alg_c1(const uint8_t *k, const uint8_t *r, + const uint8_t *preq, const uint8_t *pres, uint8_t iat, uint8_t rat, - uint8_t *ia, uint8_t *ra, + const uint8_t *ia, const uint8_t *ra, uint8_t *out_enc_data); -int ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z, - uint8_t *out_enc_data); -int ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, - uint32_t *passkey); -int ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t, - uint8_t *a1, uint8_t a2t, uint8_t *a2, - uint8_t *mackey, uint8_t *ltk); +int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, + uint8_t z, uint8_t *out_enc_data); +int ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, + const uint8_t *y, uint32_t *passkey); +int ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + uint8_t a1t, const uint8_t *a1, uint8_t a2t, + const uint8_t *a2, uint8_t *mackey, uint8_t *ltk); int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r, const uint8_t *iocap, uint8_t a1t, const uint8_t *a1, uint8_t a2t, const uint8_t *a2, uint8_t *check); -int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, - uint8_t *our_priv_key, uint8_t *out_dhkey); +int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, + const uint8_t *peer_pub_key_y, + const uint8_t *our_priv_key, uint8_t *out_dhkey); int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); void ble_sm_alg_ecc_init(void); -void ble_sm_enc_change_rx(struct hci_encrypt_change *evt); -void ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt); -int ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt); +void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev); +void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev); +int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev); #if MYNEWT_VAL(BLE_SM_LEGACY) int ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action); @@ -364,6 +355,10 @@ void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg); void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **rxom, struct ble_sm_result *res); +bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, + bool oob_data_local_present, + bool oob_data_remote_present); +void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res); void ble_sm_sc_init(void); #else #define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP) @@ -399,12 +394,9 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); -int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); +int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, + uint8_t *enc_data); int ble_sm_init(void); - -#define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ - BLE_HS_LOG_CMD((is_tx), "sm", (cmd_name), (conn_handle), (log_cb), (cmd)) - #else #define ble_sm_enc_change_rx(evt) ((void)(evt)) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_sc.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_sc.c index 1293de3a4..333310702 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_sc.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/src/ble_sm_sc.c @@ -106,7 +106,7 @@ ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action) if (pair_req->oob_data_flag == BLE_SM_PAIR_OOB_YES || pair_rsp->oob_data_flag == BLE_SM_PAIR_OOB_YES) { - *action = BLE_SM_IOACT_OOB; + *action = BLE_SM_IOACT_OOB_SC; } else if (!(pair_req->authreq & BLE_SM_PAIR_AUTHREQ_MITM) && !(pair_rsp->authreq & BLE_SM_PAIR_AUTHREQ_MITM)) { @@ -125,7 +125,7 @@ ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action) proc->pair_alg = BLE_SM_PAIR_ALG_JW; break; - case BLE_SM_IOACT_OOB: + case BLE_SM_IOACT_OOB_SC: proc->pair_alg = BLE_SM_PAIR_ALG_OOB; proc->flags |= BLE_SM_PROC_F_AUTHENTICATED; break; @@ -233,11 +233,11 @@ ble_sm_sc_gen_ri(struct ble_sm_proc *proc) { int byte; int bit; - int rc; switch (proc->pair_alg) { case BLE_SM_PAIR_ALG_JW: case BLE_SM_PAIR_ALG_NUMCMP: + case BLE_SM_PAIR_ALG_OOB: proc->ri = 0; return 0; @@ -253,16 +253,49 @@ ble_sm_sc_gen_ri(struct ble_sm_proc *proc) return 0; - case BLE_SM_PAIR_ALG_OOB: - rc = ble_hs_hci_util_rand(&proc->ri, 1); - return rc; - default: BLE_HS_DBG_ASSERT(0); return BLE_HS_EUNKNOWN; } } +void +ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res) +{ + int err; + bool match; + uint8_t c[16]; + + /* Authentication stage 1: Step 5 */ + if (proc->oob_data_remote) { + err = ble_sm_alg_f4(proc->pub_key_peer.x, proc->pub_key_peer.x, + proc->oob_data_remote->r, 0, c); + if (err) { + res->sm_err = BLE_SM_ERR_UNSPECIFIED; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED); + res->enc_cb = 1; + return; + } + + match = (memcmp(c, proc->oob_data_remote->c, sizeof(c)) == 0); + if (!match) { + /* Random number mismatch. */ + res->sm_err = BLE_SM_ERR_CONFIRM_MISMATCH; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CONFIRM_MISMATCH); + res->enc_cb = 1; + return; + } + } + + if ((proc->flags & BLE_SM_PROC_F_INITIATOR) || + (proc->flags & BLE_SM_PROC_F_ADVANCE_ON_IO)) { + /* If is initiator or was waiting on + * IO then execute step 6: send Random + */ + res->execute = 1; + } +} + void ble_sm_sc_confirm_exec(struct ble_sm_proc *proc, struct ble_sm_result *res) { @@ -414,8 +447,9 @@ ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) uint8_t rat; int rc; - if (proc->flags & BLE_SM_PROC_F_INITIATOR || - ble_sm_sc_responder_verifies_random(proc)) { + if (proc->pair_alg != BLE_SM_PAIR_ALG_OOB && ( + proc->flags & BLE_SM_PROC_F_INITIATOR || + ble_sm_sc_responder_verifies_random(proc))) { BLE_HS_LOG(DEBUG, "tk="); ble_hs_log_flat_buf(proc->tk, 16); @@ -487,7 +521,12 @@ ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) res->execute = 1; } } else { - res->execute = 1; + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB && + !(proc->flags & BLE_SM_PROC_F_IO_INJECTED)) { + proc->flags |= BLE_SM_PROC_F_ADVANCE_ON_IO; + } else { + res->execute = 1; + } } } @@ -526,7 +565,11 @@ ble_sm_sc_public_key_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, } if (!(proc->flags & BLE_SM_PROC_F_INITIATOR)) { - proc->state = BLE_SM_PROC_STATE_CONFIRM; + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB) { + proc->state = BLE_SM_PROC_STATE_RANDOM; + } else { + proc->state = BLE_SM_PROC_STATE_CONFIRM; + } rc = ble_sm_sc_io_action(proc, &ioact); if (rc != 0) { @@ -568,7 +611,13 @@ ble_sm_sc_public_key_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_public_key *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "public key", conn_handle, ble_sm_public_key_log, cmd); + /* Check if the peer public key is same as our generated public key. + * Return fail if the public keys match. */ + if (memcmp(cmd, ble_sm_sc_pub_key, 64) == 0) { + res->enc_cb = 1; + res->sm_err = BLE_SM_ERR_AUTHREQ; + return; + } ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PUBLIC_KEY, -1, @@ -588,8 +637,11 @@ ble_sm_sc_public_key_rx(uint16_t conn_handle, struct os_mbuf **om, res->enc_cb = 1; } else { if (proc->flags & BLE_SM_PROC_F_INITIATOR) { - - proc->state = BLE_SM_PROC_STATE_CONFIRM; + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB) { + proc->state = BLE_SM_PROC_STATE_RANDOM; + } else { + proc->state = BLE_SM_PROC_STATE_CONFIRM; + } rc = ble_sm_sc_io_action(proc, &ioact); if (rc != 0) { @@ -651,6 +703,14 @@ ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, iocap = &pair_rsp->io_cap; } + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB) { + if (proc->oob_data_remote) { + memcpy(proc->tk, proc->oob_data_remote->r, 16); + } else { + memset(proc->tk, 0, 16); + } + } + ble_sm_sc_dhkey_addrs(proc, &our_addr, &peer_addr); cmd = ble_sm_cmd_get(BLE_SM_OP_PAIR_DHKEY_CHECK, sizeof(*cmd), &txom); @@ -702,11 +762,27 @@ ble_sm_dhkey_check_process(struct ble_sm_proc *proc, pair_rsp = (struct ble_sm_pair_cmd *) &proc->pair_rsp[1]; iocap = &pair_rsp->io_cap; + + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB) { + if (pair_rsp->oob_data_flag) { + memcpy(proc->tk, proc->oob_data_local->r, 16); + } else { + memset(proc->tk, 0, 16); + } + } } else { struct ble_sm_pair_cmd *pair_req; pair_req = (struct ble_sm_pair_cmd *) &proc->pair_req[1]; iocap = &pair_req->io_cap; + + if (proc->pair_alg == BLE_SM_PAIR_ALG_OOB) { + if (pair_req->oob_data_flag) { + memcpy(proc->tk, proc->oob_data_local->r, 16); + } else { + memset(proc->tk, 0, 16); + } + } } ble_sm_sc_dhkey_addrs(proc, &our_addr, &peer_addr); @@ -768,7 +844,6 @@ ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **om, } cmd = (struct ble_sm_dhkey_check *)(*om)->om_data; - BLE_SM_LOG_CMD(0, "dhkey check", conn_handle, ble_sm_dhkey_check_log, cmd); ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_DHKEY_CHECK, -1, @@ -781,6 +856,56 @@ ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **om, ble_hs_unlock(); } +bool +ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, + bool oob_data_local_present, + bool oob_data_remote_present) +{ + struct ble_sm_pair_cmd *pair_req; + struct ble_sm_pair_cmd *pair_rsp; + bool req_oob_present; + bool rsp_oob_present; + + pair_req = (struct ble_sm_pair_cmd *) &proc->pair_req[1]; + pair_rsp = (struct ble_sm_pair_cmd *) &proc->pair_rsp[1]; + req_oob_present = pair_req->oob_data_flag == BLE_SM_PAIR_OOB_YES; + rsp_oob_present = pair_rsp->oob_data_flag == BLE_SM_PAIR_OOB_YES; + + if (proc->flags & BLE_SM_PROC_F_INITIATOR) { + return req_oob_present == oob_data_remote_present; + } else { + return rsp_oob_present == oob_data_remote_present; + } +} + +int +ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data) +{ + int rc; + +#if !MYNEWT_VAL(BLE_SM_SC) + return BLE_HS_ENOTSUP; +#endif + + rc = ble_sm_sc_ensure_keys_generated(); + if (rc) { + return rc; + } + + rc = ble_hs_hci_util_rand(oob_data->r, 16); + if (rc) { + return rc; + } + + rc = ble_sm_alg_f4(ble_sm_sc_pub_key, ble_sm_sc_pub_key, oob_data->r, 0, + oob_data->c); + if (rc) { + return rc; + } + + return 0; +} + void ble_sm_sc_init(void) { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c index 13dae8d2b..49ca6ed73 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c @@ -214,8 +214,10 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) if (value) { #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) if (obj_type == BLE_STORE_OBJ_TYPE_PEER_DEV_REC) { - err = get_nvs_matching_index(&p_dev_rec, value, num_value, - sizeof(struct ble_hs_dev_records)); + err = get_nvs_matching_index(&p_dev_rec.peer_sec, + &((struct ble_hs_dev_records *)value)->peer_sec, + num_value, + sizeof(struct ble_hs_peer_sec)); } else #endif { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h index 5ad95ddb9..cf7711c08 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h @@ -186,6 +186,8 @@ #define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH 2 #define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT 1 +#define CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS 2000 + #ifndef CONFIG_BT_ENABLED #define CONFIG_BT_ENABLED #endif @@ -194,6 +196,11 @@ #define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY #endif + +#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#define CONFIG_IDF_TARGET_ESP32 1 +#endif + /* Cannot use client without scan */ #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #define CONFIG_BT_NIMBLE_ROLE_OBSERVER diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig_rename.h b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig_rename.h index 3b96c1fec..c45aa8bf6 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig_rename.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig_rename.h @@ -41,13 +41,21 @@ #endif #if defined(CONFIG_SCAN_DUPLICATE_TYPE) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE) -#define CONFIG_BTDM_SCAN_DUPL_TYPE CONFIG_SCAN_DUPLICATE_TYPE +#define CONFIG_BTDM_SCAN_DUPL_TYPE CONFIG_SCAN_DUPLICATE_TYPE +#endif + +#if defined(CONFIG_BT_CTRL_SCAN_DUPL_TYPE) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE) +#define CONFIG_BTDM_SCAN_DUPL_TYPE CONFIG_BT_CTRL_SCAN_DUPL_TYPE #endif #if defined(CONFIG_DUPLICATE_SCAN_CACHE_SIZE) && !defined(CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE) -#define CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE +#define CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE +#endif + +#if defined(CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE) && !defined(CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE) +#define CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE #endif #if defined(CONFIG_NIMBLE_MAX_CONNECTIONS ) && !defined(CONFIG_BT_NIMBLE_MAX_CONNECTIONS) -#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS +#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/os/endian.h b/lib/libesp32_div/NimBLE-Arduino/src/os/endian.h index e80ca8697..152727225 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/os/endian.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/os/endian.h @@ -207,15 +207,19 @@ extern "C" { #endif void put_le16(void *buf, uint16_t x); +void put_le24(void *buf, uint32_t x); void put_le32(void *buf, uint32_t x); void put_le64(void *buf, uint64_t x); uint16_t get_le16(const void *buf); +uint32_t get_le24(const void *buf); uint32_t get_le32(const void *buf); uint64_t get_le64(const void *buf); void put_be16(void *buf, uint16_t x); +void put_be24(void *buf, uint32_t x); void put_be32(void *buf, uint32_t x); void put_be64(void *buf, uint64_t x); uint16_t get_be16(const void *buf); +uint32_t get_be24(const void *buf); uint32_t get_be32(const void *buf); uint64_t get_be64(const void *buf); void swap_in_place(void *buf, int len); diff --git a/lib/libesp32_div/NimBLE-Arduino/src/os/os_mbuf.h b/lib/libesp32_div/NimBLE-Arduino/src/os/os_mbuf.h index b1e234039..f3857fe46 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/os/os_mbuf.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/os/os_mbuf.h @@ -614,6 +614,25 @@ struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len); */ struct os_mbuf *os_mbuf_trim_front(struct os_mbuf *om); +/** + * Creates a single chained mbuf from m1 and m2 utilizing all + * the available buffer space in all mbufs in the resulting + * chain. In other words, ensures there is no leading space in + * any mbuf in the resulting chain and trailing space only in + * the last mbuf in the chain. Mbufs from either chain may be + * freed if not needed. No mbufs are allocated. Note that mbufs + * from m2 are added to the end of m1. If m1 has a packet + * header, it is retained and length updated. If m2 has a packet + * header it is discarded. If m1 is NULL, NULL is returned and + * m2 is left untouched. + * + * @param m1 Pointer to first mbuf chain to pack + * @param m2 Pointer to second mbuf chain to pack + * + * @return struct os_mbuf* Pointer to resulting mbuf chain + */ +struct os_mbuf *os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2); + #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_dbg_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/os/util.h similarity index 56% rename from lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_dbg_priv.h rename to lib/libesp32_div/NimBLE-Arduino/src/os/util.h index 4d4390f92..3e59670c4 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_dbg_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/os/util.h @@ -17,18 +17,22 @@ * under the License. */ -#ifndef H_BLE_HS_DBG_PRIV_ -#define H_BLE_HS_DBG_PRIV_ +#ifndef H_OS_UTIL_ +#define H_OS_UTIL_ -#ifdef __cplusplus -extern "C" { +/* Helpers to pass integers as pointers and vice-versa */ +#define POINTER_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) +#define UINT_TO_POINTER(u) ((void *) ((uintptr_t) (u))) +#define POINTER_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_POINTER(u) ((void *) ((intptr_t) (u))) + +/* Helper to retrieve pointer to "parent" object in structure */ +#define CONTAINER_OF(ptr, type, field) \ + ((type *)(((char *)(ptr)) - offsetof(type, field))) + +/* Helper to calculate number of elements in array */ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) \ + (sizeof(array) / sizeof((array)[0])) #endif - -void ble_hs_dbg_event_disp(uint8_t *evbuf); -void ble_hs_dbg_set_sync_state(uint8_t sync_state); - -#ifdef __cplusplus -} #endif - -#endif /* H_HOST_DBG_ */ diff --git a/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/endian.c b/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/endian.c index 1311f43ef..2afd6a22e 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/endian.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/endian.c @@ -29,6 +29,17 @@ put_le16(void *buf, uint16_t x) u8ptr[1] = (uint8_t)(x >> 8); } +void +put_le24(void *buf, uint32_t x) +{ + uint8_t *u8ptr; + + u8ptr = buf; + u8ptr[0] = (uint8_t)x; + u8ptr[1] = (uint8_t)(x >> 8); + u8ptr[2] = (uint8_t)(x >> 16); +} + void put_le32(void *buf, uint32_t x) { @@ -70,6 +81,20 @@ get_le16(const void *buf) return x; } +uint32_t +get_le24(const void *buf) +{ + const uint8_t *u8ptr; + uint32_t x; + + u8ptr = buf; + x = u8ptr[0]; + x |= (uint32_t)u8ptr[1] << 8; + x |= (uint32_t)u8ptr[2] << 16; + + return x; +} + uint32_t get_le32(const void *buf) { @@ -114,6 +139,17 @@ put_be16(void *buf, uint16_t x) u8ptr[1] = (uint8_t)x; } +void +put_be24(void *buf, uint32_t x) +{ + uint8_t *u8ptr; + + u8ptr = buf; + u8ptr[0] = (uint8_t)(x >> 24); + u8ptr[1] = (uint8_t)(x >> 16); + u8ptr[2] = (uint8_t)(x >> 8); +} + void put_be32(void *buf, uint32_t x) { @@ -155,6 +191,20 @@ get_be16(const void *buf) return x; } +uint32_t +get_be24(const void *buf) +{ + const uint8_t *u8ptr; + uint32_t x; + + u8ptr = buf; + x = (uint32_t)u8ptr[0] << 24; + x |= (uint32_t)u8ptr[1] << 16; + x |= (uint32_t)u8ptr[2] << 8; + + return x; +} + uint32_t get_be32(const void *buf) { diff --git a/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c b/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c index 4da8b9625..ed18405b8 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c +++ b/lib/libesp32_div/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c @@ -660,10 +660,10 @@ os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpointer-arith" rc = memcmp(om->om_data + om_off, data + data_off, chunk_sz); -#pragma GCC diagnostic pop if (rc != 0) { return rc; } +#pragma GCC diagnostic pop } data_off += chunk_sz; @@ -1046,3 +1046,89 @@ os_mbuf_trim_front(struct os_mbuf *om) return om; } +struct os_mbuf * +os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2) +{ + uint16_t rem_len; + uint16_t copylen; + uint8_t *dptr; + struct os_mbuf *cur; + struct os_mbuf *next; + + /* If m1 is NULL, return NULL */ + if (m1 == NULL) { + return NULL; + } + + /* + * Concatenate the two chains to start. This will discard packet header in + * m2 and adjust packet length in m1 if m1 has a packet header. + */ + if (m2 != NULL) { + os_mbuf_concat(m1, m2); + } + + cur = m1; + while (1) { + /* If there is leading space in the mbuf, move data up */ + if (OS_MBUF_LEADINGSPACE(cur)) { + dptr = &cur->om_databuf[0]; + if (OS_MBUF_IS_PKTHDR(cur)) { + dptr += cur->om_pkthdr_len; + } + memmove(dptr, cur->om_data, cur->om_len); + cur->om_data = dptr; + } + + /* Set pointer to where we will begin copying data in current mbuf */ + dptr = cur->om_data + cur->om_len; + + /* Get a pointer to the next buf we want to absorb */ + next = SLIST_NEXT(cur, om_next); + + /* + * Is there trailing space in the mbuf? If so, copy data from + * following mbufs into the current mbuf + */ + rem_len = OS_MBUF_TRAILINGSPACE(cur); + while (rem_len && next) { + copylen = min(rem_len, next->om_len); + memcpy(dptr, next->om_data, copylen); + cur->om_len += copylen; + dptr += copylen; + rem_len -= copylen; + + /* + * We copied bytes from the next mbuf. Move the data pointer + * and subtract from its length + */ + next->om_data += copylen; + next->om_len -= copylen; + + /* + * Keep removing and freeing consecutive zero length mbufs, + * stopping when we find one with data in it or we have + * reached the end. This will prevent any zero length mbufs + * from remaining in the chain. + */ + while (next->om_len == 0) { + SLIST_NEXT(cur, om_next) = SLIST_NEXT(next, om_next); + os_mbuf_free(next); + next = SLIST_NEXT(cur, om_next); + if (next == NULL) { + break; + } + } + } + + /* If no mbufs are left, we are done */ + if (next == NULL) { + break; + } + + /* Move cur to next as we filled up current */ + cur = next; + } + + return m1; +} diff --git a/lib/libesp32_div/NimBLE-Arduino/src/src/ble_hs_hci_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/src/ble_hs_hci_priv.h index ff3604727..362f12cbd 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/src/ble_hs_hci_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/src/ble_hs_hci_priv.h @@ -48,7 +48,7 @@ struct os_mbuf; struct ble_hs_hci_ack { int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */ - uint8_t *bha_params; + const uint8_t *bha_params; int bha_params_len; uint16_t bha_opcode; uint8_t bha_hci_handle; @@ -81,11 +81,8 @@ struct hci_periodic_adv_params extern uint16_t ble_hs_hci_avail_pkts; -int ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, - void *evt_buf, uint8_t evt_buf_len, - uint8_t *out_evt_buf_len); -int ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len); -void ble_hs_hci_rx_ack(uint8_t *ack_ev); +int ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, + void *rsp, uint8_t rsp_len); void ble_hs_hci_init(void); void ble_hs_hci_deinit(void); @@ -103,78 +100,11 @@ int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_pwr); int ble_hs_hci_util_rand(void *dst, int len); int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); -int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, - uint16_t tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); -int ble_hs_hci_evt_process(uint8_t *data); +int ble_hs_hci_evt_process(const struct ble_hci_ev *ev); -void ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, - void *buf); -int ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len); -void ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, - int dst_len); -void ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_read_buffer_size(void); -void ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst, - int dst_len); -int ble_hs_hci_cmd_le_set_adv_enable(uint8_t enable); -int ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type, - uint16_t scan_itvl, - uint16_t scan_window, - uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint8_t *dst, uint8_t dst_len); -int ble_hs_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups); -int ble_hs_hci_cmd_build_le_create_connection( - const struct hci_create_conn *hcc, uint8_t *cmd, int cmd_len); -int ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr, - uint8_t addr_type, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_reset(void); -int ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable); -int ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd); -int ble_hs_hci_cmd_build_host_num_comp_pkts_entry( - const struct hci_host_num_comp_pkts_entry *entry, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_read_adv_pwr(void); -int ble_hs_hci_cmd_le_create_conn_cancel(void); -int ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu); -void ble_hs_hci_cmd_build_le_lt_key_req_reply( - const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle, - uint8_t *dst, int dst_len); -void ble_hs_hci_cmd_build_le_conn_param_reply( - const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr); -void ble_hs_hci_cmd_build_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_le_conn_param_neg_reply( - const struct hci_conn_param_neg_reply *hcn); -void ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd, - uint8_t *dst, int dst_len); +int ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len); int ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts); void ble_hs_hci_add_avail_pkts(uint16_t delta); @@ -184,145 +114,9 @@ uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, int ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om); int ble_hs_hci_acl_tx(struct ble_hs_conn *conn, struct os_mbuf **om); -int ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle, - uint16_t tx_octets, uint16_t tx_time, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_add_to_resolv_list( - const struct hci_add_dev_to_resolving_list *padd, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_remove_from_resolv_list( - uint8_t addr_type, const uint8_t *addr, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_peer_resolv_addr( - uint8_t peer_identity_addr_type, const uint8_t *peer_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_read_lcl_resolv_addr( - uint8_t local_identity_addr_type, const uint8_t *local_identity_addr, - uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_addr_res_en( - uint8_t enable, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout( - uint16_t timeout, uint8_t *dst, int dst_len); -int ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr, - uint8_t *dst, int dst_len); - -#if MYNEWT_VAL(BLE_EXT_ADV) -int ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type, - uint8_t filter_policy, - uint8_t phy_mask, - uint8_t phy_count, - struct ble_hs_hci_ext_scan_param *params[], - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable, - uint8_t filter_dups, - uint16_t duration, - uint16_t period, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle, - const uint8_t *addr, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation, - uint8_t frag_pref, struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num, - const struct hci_ext_adv_set *sets, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle, - const struct hci_ext_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle, - uint8_t *cmd, int cmd_len); - -#if MYNEWT_VAL(BLE_PERIODIC_ADV) -int -ble_hs_hci_cmd_build_le_periodic_adv_params(uint8_t handle, - const struct hci_periodic_adv_params *params, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_enable(uint8_t enable, - uint8_t handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_data(uint8_t handle, uint8_t operation, - struct os_mbuf *data, - uint8_t data_len, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_periodic_adv_create_sync(uint8_t filter_policy, - uint8_t adv_sid, - uint8_t adv_add_type, - const uint8_t *adv_addr, - uint16_t skip, - uint16_t sync_timeout, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_periodic_adv_terminate_sync(uint16_t sync_handle, - uint8_t *cmd, int cmd_len); - -int -ble_hs_hci_cmd_build_le_add_dev_to_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -int -ble_hs_hci_cmd_build_le_rem_dev_from_periodic_adv_list(uint8_t adv_add_type, - const uint8_t *adv_addr, - uint8_t adv_sid, - uint8_t *cmd, int cmd_len); -#endif - -#endif - -int ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy, - uint8_t mod_idx, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, - uint8_t test_data_len, - uint8_t packet_payload_idx, - uint8_t phy, - uint8_t *dst, uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type, - uint8_t priv_mode, uint8_t *dst, - uint16_t dst_len); - -int ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, - int dst_len); - -int ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, - uint8_t rx_phys_mask, - uint8_t *dst, int dst_len); - -int ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask, - uint8_t rx_phys_mask, uint16_t phy_opts, - uint8_t *dst, int dst_len); - int ble_hs_hci_frag_num_mbufs(void); int ble_hs_hci_frag_num_mbufs_free(void); -#if MYNEWT_VAL(BLE_EXT_ADV) -#endif - -int ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst, - int dst_len); #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/src/ble_sm_priv.h b/lib/libesp32_div/NimBLE-Arduino/src/src/ble_sm_priv.h index bbb4b03ae..def0a32f5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/src/ble_sm_priv.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/src/ble_sm_priv.h @@ -269,6 +269,8 @@ struct ble_sm_proc { struct ble_sm_public_key pub_key_peer; uint8_t mackey[16]; uint8_t dhkey[32]; + const struct ble_sm_sc_oob_data *oob_data_local; + const struct ble_sm_sc_oob_data *oob_data_remote; #endif }; @@ -294,44 +296,33 @@ void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey); int ble_sm_num_procs(void); -void ble_sm_pair_cmd_log(struct ble_sm_pair_cmd *cmd); -void ble_sm_pair_confirm_log(struct ble_sm_pair_confirm *cmd); -void ble_sm_pair_random_log(struct ble_sm_pair_random *cmd); -void ble_sm_pair_fail_log(struct ble_sm_pair_fail *cmd); -void ble_sm_enc_info_log(struct ble_sm_enc_info *cmd); -void ble_sm_master_id_log(struct ble_sm_master_id *cmd); -void ble_sm_id_info_log(struct ble_sm_id_info *cmd); -void ble_sm_id_addr_info_log(struct ble_sm_id_addr_info *cmd); -void ble_sm_sign_info_log(struct ble_sm_sign_info *cmd); -void ble_sm_sec_req_log(struct ble_sm_sec_req *cmd); -void ble_sm_public_key_log(struct ble_sm_public_key *cmd); -void ble_sm_dhkey_check_log(struct ble_sm_dhkey_check *cmd); - -int ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out); -int ble_sm_alg_c1(uint8_t *k, uint8_t *r, - uint8_t *preq, uint8_t *pres, +int ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2, + uint8_t *out); +int ble_sm_alg_c1(const uint8_t *k, const uint8_t *r, + const uint8_t *preq, const uint8_t *pres, uint8_t iat, uint8_t rat, - uint8_t *ia, uint8_t *ra, + const uint8_t *ia, const uint8_t *ra, uint8_t *out_enc_data); -int ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z, - uint8_t *out_enc_data); -int ble_sm_alg_g2(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t *y, - uint32_t *passkey); -int ble_sm_alg_f5(uint8_t *w, uint8_t *n1, uint8_t *n2, uint8_t a1t, - uint8_t *a1, uint8_t a2t, uint8_t *a2, - uint8_t *mackey, uint8_t *ltk); +int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, + uint8_t z, uint8_t *out_enc_data); +int ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, + const uint8_t *y, uint32_t *passkey); +int ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + uint8_t a1t, const uint8_t *a1, uint8_t a2t, + const uint8_t *a2, uint8_t *mackey, uint8_t *ltk); int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r, const uint8_t *iocap, uint8_t a1t, const uint8_t *a1, uint8_t a2t, const uint8_t *a2, uint8_t *check); -int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, - uint8_t *our_priv_key, uint8_t *out_dhkey); +int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, + const uint8_t *peer_pub_key_y, + const uint8_t *our_priv_key, uint8_t *out_dhkey); int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); void ble_sm_alg_ecc_init(void); -void ble_sm_enc_change_rx(struct hci_encrypt_change *evt); -void ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt); -int ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt); +void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev); +void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev); +int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev); #if MYNEWT_VAL(BLE_SM_LEGACY) int ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action); @@ -364,6 +355,10 @@ void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg); void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **rxom, struct ble_sm_result *res); +bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, + bool oob_data_local_present, + bool oob_data_remote_present); +void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res); void ble_sm_sc_init(void); #else #define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP) @@ -399,12 +394,9 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); -int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); +int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, + uint8_t *enc_data); int ble_sm_init(void); - -#define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ - BLE_HS_LOG_CMD((is_tx), "sm", (cmd_name), (conn_handle), (log_cb), (cmd)) - #else #define ble_sm_enc_change_rx(evt) ((void)(evt)) diff --git a/lib/libesp32_div/NimBLE-Arduino/src/store/config/ble_store_config.h b/lib/libesp32_div/NimBLE-Arduino/src/store/config/ble_store_config.h index 2cc411c30..1b3f8e6ce 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/store/config/ble_store_config.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/store/config/ble_store_config.h @@ -32,8 +32,6 @@ int ble_store_config_read(int obj_type, const union ble_store_key *key, int ble_store_config_write(int obj_type, const union ble_store_value *val); int ble_store_config_delete(int obj_type, const union ble_store_key *key); -void ble_store_config_init(void); - #ifdef __cplusplus } #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/syscfg/syscfg.h b/lib/libesp32_div/NimBLE-Arduino/src/syscfg/syscfg.h index ce2832876..8dccca5eb 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/syscfg/syscfg.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache Newt version: 1.4.1 + * This file was generated by Apache newt version: 1.8.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -16,285 +16,46 @@ * attempt to use these macros without including this header will result in a * compiler error. */ -#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** compiler/arm-none-eabi-m4 */ -#ifndef MYNEWT_VAL_HARDFLOAT -#define MYNEWT_VAL_HARDFLOAT (0) +/*** @apache-mynewt-core/crypto/tinycrypt */ +#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE +#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif -/*** hw/bsp/nrf52840pdk */ -#ifndef MYNEWT_VAL_BSP_NRF52840 -#define MYNEWT_VAL_BSP_NRF52840 (1) +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") #endif -#ifndef MYNEWT_VAL_I2C_0_FREQ_KHZ -#define MYNEWT_VAL_I2C_0_FREQ_KHZ (100) +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -#ifndef MYNEWT_VAL_I2C_0_PIN_SCL -#define MYNEWT_VAL_I2C_0_PIN_SCL (27) +/*** @apache-mynewt-core/hw/hal */ +#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS +#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif -#ifndef MYNEWT_VAL_I2C_0_PIN_SDA -#define MYNEWT_VAL_I2C_0_PIN_SDA (26) +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ +#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif -#ifndef MYNEWT_VAL_PWM_3 -#define MYNEWT_VAL_PWM_3 (0) +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0) #endif -#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MISO -#define MYNEWT_VAL_SPI_0_MASTER_PIN_MISO (47) +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif -#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI -#define MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI (46) +#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB +#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_SCK -#define MYNEWT_VAL_SPI_0_MASTER_PIN_SCK (45) -#endif - -#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO (47) -#endif - -#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI (46) -#endif - -#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK (45) -#endif - -#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SS -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SS (44) -#endif - -#ifndef MYNEWT_VAL_TIMER_0 -#define MYNEWT_VAL_TIMER_0 (1) -#endif - -#ifndef MYNEWT_VAL_TIMER_1 -#define MYNEWT_VAL_TIMER_1 (0) -#endif - -#ifndef MYNEWT_VAL_TIMER_2 -#define MYNEWT_VAL_TIMER_2 (0) -#endif - -#ifndef MYNEWT_VAL_TIMER_3 -#define MYNEWT_VAL_TIMER_3 (0) -#endif - -#ifndef MYNEWT_VAL_TIMER_4 -#define MYNEWT_VAL_TIMER_4 (0) -#endif - -#ifndef MYNEWT_VAL_TIMER_5 -#define MYNEWT_VAL_TIMER_5 (0) -#endif - -#ifndef MYNEWT_VAL_UART_0 -#define MYNEWT_VAL_UART_0 (1) -#endif - -#ifndef MYNEWT_VAL_UART_0_PIN_CTS -#define MYNEWT_VAL_UART_0_PIN_CTS (7) -#endif - -#ifndef MYNEWT_VAL_UART_0_PIN_RTS -#define MYNEWT_VAL_UART_0_PIN_RTS (5) -#endif - -#ifndef MYNEWT_VAL_UART_0_PIN_RX -#define MYNEWT_VAL_UART_0_PIN_RX (8) -#endif - -#ifndef MYNEWT_VAL_UART_0_PIN_TX -#define MYNEWT_VAL_UART_0_PIN_TX (6) -#endif - -#ifndef MYNEWT_VAL_UART_1 -#define MYNEWT_VAL_UART_1 (0) -#endif - -#ifndef MYNEWT_VAL_UART_1_PIN_CTS -#define MYNEWT_VAL_UART_1_PIN_CTS (-1) -#endif - -#ifndef MYNEWT_VAL_UART_1_PIN_RTS -#define MYNEWT_VAL_UART_1_PIN_RTS (-1) -#endif - -#ifndef MYNEWT_VAL_UART_1_PIN_RX -#define MYNEWT_VAL_UART_1_PIN_RX (-1) -#endif - -#ifndef MYNEWT_VAL_UART_1_PIN_TX -#define MYNEWT_VAL_UART_1_PIN_TX (-1) -#endif - -/*** hw/mcu/nordic/nrf52xxx */ -#ifndef MYNEWT_VAL_ADC_0 -#define MYNEWT_VAL_ADC_0 (0) -#endif - -#ifndef MYNEWT_VAL_ADC_0_REFMV_0 -#define MYNEWT_VAL_ADC_0_REFMV_0 (0) -#endif - -#ifndef MYNEWT_VAL_I2C_0 -#define MYNEWT_VAL_I2C_0 (0) -#endif - -#ifndef MYNEWT_VAL_I2C_1 -#define MYNEWT_VAL_I2C_1 (0) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_MCU_DCDC_ENABLED -#define MYNEWT_VAL_MCU_DCDC_ENABLED (1) -#endif - -#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE -#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) -#endif - -#ifndef MYNEWT_VAL_PWM_0 -#define MYNEWT_VAL_PWM_0 (0) -#endif - -#ifndef MYNEWT_VAL_PWM_1 -#define MYNEWT_VAL_PWM_1 (0) -#endif - -#ifndef MYNEWT_VAL_PWM_2 -#define MYNEWT_VAL_PWM_2 (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_ADDRMODE -#define MYNEWT_VAL_QSPI_ADDRMODE (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_DPMCONFIG -#define MYNEWT_VAL_QSPI_DPMCONFIG (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_ENABLE -#define MYNEWT_VAL_QSPI_ENABLE (0) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE -#define MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE (256) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT -#define MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT (4096) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE -#define MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE (4096) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_CS -#define MYNEWT_VAL_QSPI_PIN_CS (17) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_DIO0 -#define MYNEWT_VAL_QSPI_PIN_DIO0 (20) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_DIO1 -#define MYNEWT_VAL_QSPI_PIN_DIO1 (21) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_DIO2 -#define MYNEWT_VAL_QSPI_PIN_DIO2 (22) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_DIO3 -#define MYNEWT_VAL_QSPI_PIN_DIO3 (23) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_QSPI_PIN_SCK -#define MYNEWT_VAL_QSPI_PIN_SCK (19) -#endif - -#ifndef MYNEWT_VAL_QSPI_READOC -#define MYNEWT_VAL_QSPI_READOC (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_SCK_DELAY -#define MYNEWT_VAL_QSPI_SCK_DELAY (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_SCK_FREQ -#define MYNEWT_VAL_QSPI_SCK_FREQ (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_SPI_MODE -#define MYNEWT_VAL_QSPI_SPI_MODE (0) -#endif - -#ifndef MYNEWT_VAL_QSPI_WRITEOC -#define MYNEWT_VAL_QSPI_WRITEOC (0) -#endif - -#ifndef MYNEWT_VAL_SOFT_PWM -#define MYNEWT_VAL_SOFT_PWM (0) -#endif - -#ifndef MYNEWT_VAL_SPI_0_MASTER -#define MYNEWT_VAL_SPI_0_MASTER (0) -#endif - -#ifndef MYNEWT_VAL_SPI_0_SLAVE -#define MYNEWT_VAL_SPI_0_SLAVE (0) -#endif - -#ifndef MYNEWT_VAL_SPI_1_MASTER -#define MYNEWT_VAL_SPI_1_MASTER (0) -#endif - -#ifndef MYNEWT_VAL_SPI_1_SLAVE -#define MYNEWT_VAL_SPI_1_SLAVE (0) -#endif - -#ifndef MYNEWT_VAL_SPI_2_MASTER -#define MYNEWT_VAL_SPI_2_MASTER (0) -#endif - -#ifndef MYNEWT_VAL_SPI_2_SLAVE -#define MYNEWT_VAL_SPI_2_SLAVE (0) -#endif - -/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */ -#ifndef MYNEWT_VAL_XTAL_32768 -#define MYNEWT_VAL_XTAL_32768 (1) -#endif - -#ifndef MYNEWT_VAL_XTAL_32768_SYNTH -#define MYNEWT_VAL_XTAL_32768_SYNTH (0) -#endif - -#ifndef MYNEWT_VAL_XTAL_RC -#define MYNEWT_VAL_XTAL_RC (0) -#endif - -/*** kernel/os */ +/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif @@ -307,6 +68,10 @@ #define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292) #endif +#ifndef MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT (0) +#endif + #ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT #define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0) #endif @@ -315,6 +80,18 @@ #define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0) #endif +#ifndef MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_SANITY_TIMEOUT +#define MYNEWT_VAL_MSYS_SANITY_TIMEOUT (60000) +#endif + +#ifndef MYNEWT_VAL_OS_ASSERT_CB +#define MYNEWT_VAL_OS_ASSERT_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_CLI #define MYNEWT_VAL_OS_CLI (0) #endif @@ -331,6 +108,22 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif +#ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_LOG +#define MYNEWT_VAL_OS_CRASH_LOG (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_RESTORE_REGS +#define MYNEWT_VAL_OS_CRASH_RESTORE_REGS (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_STACKTRACE +#define MYNEWT_VAL_OS_CRASH_STACKTRACE (0) +#endif + #ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK #define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0) #endif @@ -339,6 +132,26 @@ #define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4) #endif +#ifndef MYNEWT_VAL_OS_DEBUG_MODE +#define MYNEWT_VAL_OS_DEBUG_MODE (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG +#define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_MONITOR +#define MYNEWT_VAL_OS_EVENTQ_MONITOR (0) +#endif + +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) +#endif + +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#endif + #ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE #define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024) #endif @@ -347,10 +160,18 @@ #define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127) #endif +#ifndef MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS +#define MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS (0) +#endif + #ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK #define MYNEWT_VAL_OS_MEMPOOL_CHECK (0) #endif +#ifndef MYNEWT_VAL_OS_MEMPOOL_GUARD +#define MYNEWT_VAL_OS_MEMPOOL_GUARD (0) +#endif + #ifndef MYNEWT_VAL_OS_MEMPOOL_POISON #define MYNEWT_VAL_OS_MEMPOOL_POISON (0) #endif @@ -359,10 +180,50 @@ #define MYNEWT_VAL_OS_SCHEDULING (1) #endif +#ifndef MYNEWT_VAL_OS_SYSINIT_STAGE +#define MYNEWT_VAL_OS_SYSINIT_STAGE (0) +#endif + #ifndef MYNEWT_VAL_OS_SYSVIEW #define MYNEWT_VAL_OS_SYSVIEW (0) #endif +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM (1) +#endif + +#ifndef MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME +#define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) +#endif + +#ifndef MYNEWT_VAL_OS_TIME_DEBUG +#define MYNEWT_VAL_OS_TIME_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_WATCHDOG_MONITOR +#define MYNEWT_VAL_OS_WATCHDOG_MONITOR (0) +#endif + #ifndef MYNEWT_VAL_SANITY_INTERVAL #define MYNEWT_VAL_SANITY_INTERVAL (15000) #endif @@ -371,16 +232,137 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** libc/baselibc */ -#ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE -#define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) +/*** @apache-mynewt-core/sys/console/stub */ +#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD +#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif -#ifndef MYNEWT_VAL_BASELIBC_PRESENT -#define MYNEWT_VAL_BASELIBC_PRESENT (1) +#ifndef MYNEWT_VAL_CONSOLE_UART_DEV +#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") #endif -/*** nimble */ +#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL +#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) +#endif + +/*** @apache-mynewt-core/sys/flash_map */ +#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS +#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) +#endif + +#ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#endif + +/*** @apache-mynewt-core/sys/log/common */ +#ifndef MYNEWT_VAL_DFLT_LOG_LVL +#define MYNEWT_VAL_DFLT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_DFLT_LOG_MOD +#define MYNEWT_VAL_DFLT_LOG_MOD (0) +#endif + +#ifndef MYNEWT_VAL_LOG_GLOBAL_IDX +#define MYNEWT_VAL_LOG_GLOBAL_IDX (1) +#endif + +/*** @apache-mynewt-core/sys/log/modlog */ +#ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT +#define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) +#endif + +#ifndef MYNEWT_VAL_MODLOG_LOG_MACROS +#define MYNEWT_VAL_MODLOG_LOG_MACROS (0) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_MAPPINGS +#define MYNEWT_VAL_MODLOG_MAX_MAPPINGS (16) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN +#define MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN (128) +#endif + +#ifndef MYNEWT_VAL_MODLOG_SYSINIT_STAGE +#define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) +#endif + +/*** @apache-mynewt-core/sys/log/stub */ +#ifndef MYNEWT_VAL_LOG_CONSOLE +#define MYNEWT_VAL_LOG_CONSOLE (1) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB +#define MYNEWT_VAL_LOG_FCB (0) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB_SLOT1 +#define MYNEWT_VAL_LOG_FCB_SLOT1 (0) +#endif + +#ifndef MYNEWT_VAL_LOG_LEVEL +#define MYNEWT_VAL_LOG_LEVEL (255) +#endif + +/*** @apache-mynewt-core/sys/mfg */ +#ifndef MYNEWT_VAL_MFG_LOG_LVL +#define MYNEWT_VAL_MFG_LOG_LVL (15) +#endif + +#ifndef MYNEWT_VAL_MFG_LOG_MODULE +#define MYNEWT_VAL_MFG_LOG_MODULE (128) +#endif + +#ifndef MYNEWT_VAL_MFG_MAX_MMRS +#define MYNEWT_VAL_MFG_MAX_MMRS (2) +#endif + +#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE +#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) +#endif + +/*** @apache-mynewt-core/sys/sys */ +#ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED +#define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) +#endif + +/*** @apache-mynewt-core/sys/sysdown */ +#ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN +#define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE +#define MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_TIMEOUT_MS +#define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) +#endif + +/*** @apache-mynewt-core/sys/sysinit */ +#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT +#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) +#endif + +#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#endif + +/*** @apache-mynewt-core/util/rwlock */ +#ifndef MYNEWT_VAL_RWLOCK_DEBUG +#define MYNEWT_VAL_RWLOCK_DEBUG (0) +#endif + +/*** @apache-mynewt-nimble/nimble */ #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -394,13 +376,21 @@ #endif #ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS -#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (1) #endif #ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES #define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV +#define MYNEWT_VAL_BLE_PERIODIC_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -417,6 +407,10 @@ #define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1) #endif +#ifndef MYNEWT_VAL_BLE_VERSION +#define MYNEWT_VAL_BLE_VERSION (50) +#endif + #ifndef MYNEWT_VAL_BLE_WHITELIST #define MYNEWT_VAL_BLE_WHITELIST (1) #endif @@ -590,11 +584,6 @@ #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif - -#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV -#define MYNEWT_VAL_BLE_PERIODIC_ADV (0) -#endif - #ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO #define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) #endif @@ -771,6 +760,14 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_LOG_LVL +#define MYNEWT_VAL_BLE_HS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_LOG_MOD +#define MYNEWT_VAL_BLE_HS_LOG_MOD (4) +#endif + #ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS #define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0) #endif @@ -779,10 +776,30 @@ #define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1) #endif +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT (2000) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS +#define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -816,7 +833,7 @@ #endif #ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("monitor") +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") #endif #ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE @@ -879,6 +896,10 @@ #define MYNEWT_VAL_BLE_SM_SC (1) #endif +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST #define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) #endif @@ -891,17 +912,20 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** nimble/host/services/ans */ +/*** @apache-mynewt-nimble/nimble/host/services/ans */ #ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) #endif +#ifndef MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE (303) +#endif #ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) #endif -/*** nimble/host/services/bas */ +/*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) #endif @@ -1222,6 +1246,81 @@ #define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4) #endif +#ifndef MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/dis */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("Apache Mynewt NimBLE") +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE (303) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) +#endif + /*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) @@ -1263,32 +1362,38 @@ #define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0) #endif -/*** nimble/transport */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#ifndef MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/* Overridden by targets/porting-nimble (defined by nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +/*** @apache-mynewt-nimble/nimble/host/services/gatt */ +#ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +/*** @apache-mynewt-nimble/nimble/host/services/ias */ +#ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +/*** @apache-mynewt-nimble/nimble/host/services/ipss */ +#ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) #endif -/* Overridden by targets/porting-nimble (defined by nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (1) +/*** @apache-mynewt-nimble/nimble/host/services/lls */ +#ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) #endif -/*** nimble/transport/uart */ +/*** @apache-mynewt-nimble/nimble/host/services/tps */ +#ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (12) +#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1311,74 +1416,73 @@ #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif -/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */ -#ifndef MYNEWT_VAL_BLE_HCI_UART_BAUD -#define MYNEWT_VAL_BLE_HCI_UART_BAUD (115200) +#ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif -#ifndef MYNEWT_VAL_BLE_HCI_UART_DATA_BITS -#define MYNEWT_VAL_BLE_HCI_UART_DATA_BITS (8) +#ifndef MYNEWT_VAL_BLE_SOCK_LINUX_DEV +#define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0) #endif -/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */ -#ifndef MYNEWT_VAL_BLE_HCI_UART_FLOW_CTRL -#define MYNEWT_VAL_BLE_HCI_UART_FLOW_CTRL (0) +#ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE +#define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (80) #endif -#ifndef MYNEWT_VAL_BLE_HCI_UART_PARITY -#define MYNEWT_VAL_BLE_HCI_UART_PARITY (HAL_UART_PARITY_NONE) +#ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO +#define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (9) #endif -#ifndef MYNEWT_VAL_BLE_HCI_UART_PORT -#define MYNEWT_VAL_BLE_HCI_UART_PORT (0) +#ifndef MYNEWT_VAL_BLE_SOCK_TCP_PORT +#define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif -#ifndef MYNEWT_VAL_BLE_HCI_UART_STOP_BITS -#define MYNEWT_VAL_BLE_HCI_UART_STOP_BITS (1) +#ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE +#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (0) #endif -/*** sys/console/stub */ -#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD -#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) +#ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP +#define MYNEWT_VAL_BLE_SOCK_USE_TCP (1) #endif -#ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +/*** newt */ +#ifndef MYNEWT_VAL_APP_NAME +#define MYNEWT_VAL_APP_NAME ("dummy_app") #endif -#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL -#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) +#ifndef MYNEWT_VAL_APP_dummy_app +#define MYNEWT_VAL_APP_dummy_app (1) #endif -/*** sys/flash_map */ -#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS -#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) +#ifndef MYNEWT_VAL_ARCH_NAME +#define MYNEWT_VAL_ARCH_NAME ("dummy") #endif -/*** sys/log/stub */ -#ifndef MYNEWT_VAL_LOG_CONSOLE -#define MYNEWT_VAL_LOG_CONSOLE (1) +#ifndef MYNEWT_VAL_ARCH_dummy +#define MYNEWT_VAL_ARCH_dummy (1) #endif -#ifndef MYNEWT_VAL_LOG_FCB -#define MYNEWT_VAL_LOG_FCB (0) +#ifndef MYNEWT_VAL_BSP_NAME +#define MYNEWT_VAL_BSP_NAME ("dummy_bsp") #endif -#ifndef MYNEWT_VAL_LOG_LEVEL -#define MYNEWT_VAL_LOG_LEVEL (255) +#ifndef MYNEWT_VAL_BSP_dummy_bsp +#define MYNEWT_VAL_BSP_dummy_bsp (1) #endif -/*** sys/sysinit */ -#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT -#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) +#ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG +#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1) #endif -#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE -#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#ifndef MYNEWT_VAL_NEWT_FEATURE_SYSDOWN +#define MYNEWT_VAL_NEWT_FEATURE_SYSDOWN (1) #endif -#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE -#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#ifndef MYNEWT_VAL_TARGET_NAME +#define MYNEWT_VAL_TARGET_NAME ("porting_default") +#endif + +#ifndef MYNEWT_VAL_TARGET_porting_default +#define MYNEWT_VAL_TARGET_porting_default (1) #endif #endif #endif diff --git a/lib/libesp32_div/NimBLE-Arduino/src/sysflash/sysflash.h b/lib/libesp32_div/NimBLE-Arduino/src/sysflash/sysflash.h new file mode 100644 index 000000000..413cb2679 --- /dev/null +++ b/lib/libesp32_div/NimBLE-Arduino/src/sysflash/sysflash.h @@ -0,0 +1,24 @@ +/** + * This file was generated by Apache newt version: 1.8.0-dev + */ + +#ifndef H_MYNEWT_SYSFLASH_ +#define H_MYNEWT_SYSFLASH_ + +#include "flash_map/flash_map.h" + +/** + * This flash map definition is used for two purposes: + * 1. To locate the meta area, which contains the true flash map definition. + * 2. As a fallback in case the meta area cannot be read from flash. + */ +extern const struct flash_area sysflash_map_dflt[6]; + +#define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_NFFS 17 + +#endif diff --git a/pio-tools/cxx_flags.py b/pio-tools/cxx_flags.py new file mode 100644 index 000000000..74cf99e7c --- /dev/null +++ b/pio-tools/cxx_flags.py @@ -0,0 +1,4 @@ +Import("env") + +# General options that are passed to the C++ compiler +env.Append(CXXFLAGS=["-fpermissive"]) \ No newline at end of file diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index 05f221c56..1d1da267c 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -49,31 +49,14 @@ build_flags = ${env:tasmota32_base.build_flags} extends = env:tasmota32_base board = esp32s2 platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/385/framework-arduinoespressif32-master-cd287c4d6.tar.gz - platformio/tool-mklittlefs @ ~1.203.200522 -build_unflags = ${env:tasmota32_base.build_unflags} -build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_LITE -lib_extra_dirs = lib/libesp32 - lib/lib_basic -lib_ignore = - NimBLE-Arduino - Micro-RTSP - ESP32-HomeKit - -; *** EXPERIMENTAL Tasmota version for ESP32-C3 -[env:tasmota32c3] -extends = env:tasmota32_base -board = esp32c3 -platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/385/framework-arduinoespressif32-master-cd287c4d6.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/408/framework-arduinoespressif32-master-54caa4c74.tar.gz platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} -Wswitch-unreachable - -mtarget-align - -DNDEBUG + -Wstringop-overflow build_flags = ${env:tasmota32_base.build_flags} -Wno-switch-unreachable - ;-DESP32_STAGE=true + -Wno-stringop-overflow lib_extra_dirs = lib/libesp32 lib/libesp32_lvgl lib/lib_basic @@ -82,24 +65,71 @@ lib_extra_dirs = lib/libesp32 lib/lib_display lib_ignore = NimBLE-Arduino + TTGO TWatch Library + ESP32-HomeKit + Micro-RTSP + +; *** EXPERIMENTAL Tasmota version for ESP32-C3 +[env:tasmota32c3] +extends = env:tasmota32_base +board = esp32c3 +platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/408/framework-arduinoespressif32-master-54caa4c74.tar.gz + platformio/tool-mklittlefs @ ~1.203.200522 +build_unflags = ${env:tasmota32_base.build_unflags} + -Wswitch-unreachable + -mtarget-align + -DNDEBUG +build_flags = ${env:tasmota32_base.build_flags} + -Wno-switch-unreachable +; *** Comment next two lines to disable BLE + -DUSE_BLE_ESP32 + -DUSE_MI_ESP32 + ;-DESP32_STAGE=true +extra_scripts = ${common.extra_scripts} + pre:pio-tools/cxx_flags.py +lib_extra_dirs = lib/libesp32 + lib/libesp32_div + lib/libesp32_lvgl + lib/lib_basic + lib/lib_i2c + lib/lib_ssl + lib/lib_display +lib_ignore = +lib_ignore = + TTGO TWatch Library + ESP32-HomeKit Micro-RTSP ; *** EXPERIMENTAL Tasmota version for ESP32 IDF4.4. [env:tasmota32idf4] extends = env:tasmota32_base platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/385/framework-arduinoespressif32-master-cd287c4d6.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/408/framework-arduinoespressif32-master-54caa4c74.tar.gz platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} -Wswitch-unreachable -Wincompatible-pointer-types build_flags = ${env:tasmota32_base.build_flags} -Wno-switch-unreachable + -Wdiscarded-qualifiers +; ***Uncomment next two lines to enable BLE + ;-DUSE_BLE_ESP32 + ;-DUSE_MI_ESP32 ;-DESP32_STAGE=true +extra_scripts = ${common.extra_scripts} + pre:pio-tools/cxx_flags.py +lib_extra_dirs = lib/libesp32 + lib/libesp32_div + lib/libesp32_lvgl + lib/lib_basic + lib/lib_i2c + lib/lib_ssl + lib/lib_display [env:tasmota32-rangeextender] extends = env:tasmota32idf4 -build_flags = ${env:tasmota32idf4.build_flags} +build_flags = ${env:tasmota32idf4.build_flags} -D FIRMWARE_TASMOTA32 -D USE_WIFI_RANGE_EXTENDER -D USE_WIFI_RANGE_EXTENDER_NAPT diff --git a/tasmota/xdrv_79_esp32_ble.ino b/tasmota/xdrv_79_esp32_ble.ino index 9f4ed2e9c..c96f5f8e2 100644 --- a/tasmota/xdrv_79_esp32_ble.ino +++ b/tasmota/xdrv_79_esp32_ble.ino @@ -31,8 +31,8 @@ #define USE_BLE_ESP32 #endif -#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support -#if CONFIG_IDF_TARGET_ESP32 +#ifdef ESP32 // ESP32 family only. Use define USE_HM10 for ESP8266 support +#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3 #ifdef USE_BLE_ESP32 /* @@ -3723,7 +3723,7 @@ void sendExample(){ #endif -#endif // CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_IDF_TARGET_ESP32 or CONFIG_IDF_TARGET_ESP32C3 #endif // ESP32 diff --git a/tasmota/xsns_62_esp32_mi.ino b/tasmota/xsns_62_esp32_mi.ino index ce9ac10ca..ecc9d228c 100644 --- a/tasmota/xsns_62_esp32_mi.ino +++ b/tasmota/xsns_62_esp32_mi.ino @@ -49,7 +49,7 @@ */ #ifndef USE_BLE_ESP32 #ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support -#if CONFIG_IDF_TARGET_ESP32 +#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3 #ifdef USE_MI_ESP32 @@ -2334,6 +2334,6 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_IDF_TARGET_ESP32 or CONFIG_IDF_TARGET_ESP32C3 #endif // ESP32 #endif // USE_BLE_ESP32 diff --git a/tasmota/xsns_62_esp32_mi_ble.ino b/tasmota/xsns_62_esp32_mi_ble.ino index f8011351f..635204cb0 100644 --- a/tasmota/xsns_62_esp32_mi_ble.ino +++ b/tasmota/xsns_62_esp32_mi_ble.ino @@ -70,8 +70,8 @@ // for testing of BLE_ESP32, we remove xsns_62_MI_ESP32.ino completely, and instead add this modified xsns_52_ibeacon_BLE_ESP32.ino #ifdef USE_BLE_ESP32 -#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support -#if CONFIG_IDF_TARGET_ESP32 +#ifdef ESP32 // ESP32 family only. Use define USE_HM10 for ESP8266 support +#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3 #ifdef USE_MI_ESP32 @@ -3269,7 +3269,7 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_IDF_TARGET_ESP32 or CONFIG_IDF_TARGET_ESP32C3 #endif // ESP32 #endif \ No newline at end of file