# Migrating from 1.x to 2.x

Nearly all of the codebase has been updated and changed under the surface, which has greatly reduced the resource use of the library and improved it's performance. To be able to support these changes it required various API changes and additions.

This guide will help you migrate your application code to use the new API.

The changes listed here are only the required changes that must be made, and a short overview of options for migrating existing applications.

* [General changes](#general-changes)
* [Bond migration](#bond-migration)
* [BLE Device](#ble-device)
* [BLE Addresses](#ble-addresses)
* [BLE UUID's](#ble-uuids)
* [Server](#server)
    * [Services](#services)
    * [Characteristics](#characteristics)
    * [Characteristic Callbacks](#characteristic-callbacks)
    * [Security](#server)
* [Client](#client)
    * [Client Callbacks](#client-callbacks)
    * [Remote Services](#remote-services)
    * [Remote characteristics](#remote-characteristics)
* [Scanning](#scan)
    * [Advertise device](#advertised-device)
* [Advertising](#advertising)
* [Beacons](#beacons)
* [Utilities](#utilities)  
<br/>

## General changes
- All functions that take a time parameter now require the time in milliseconds instead of seconds, i.e. `NimBLEScan::start(10000); // 10 seconds`
- `NimBLESecurity` class has been removed it's functionality has been merged into the `NimBLEServer` and `NimBLEClient` classes.
- All connection oriented callbacks now receive a reference to `NimBLEConnInfo` and the `ble_gap_conn_desc` parameter has been replaced with `NimBLEConnInfo` in the functions that received it.  
    For instance `onAuthenticationComplete(ble_gap_conn_desc* desc)` signature is now `onAuthenticationComplete(NimBLEConnInfo& connInfo)` and  
    `NimBLEServerCallbacks::onConnect(NimBLEServer* pServer)` signature is now `NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo)`.  
<br/>

## Bond migration
If your 1.x application stores bonds and you want paired devices to continue working after upgrading to 2.x, the library provides helper functions to migrate the bond data stored in NVS.

The helpers are declared in `NimBLEBondMigration.h`:

- `NimBLEBondMigration::migrateBondStoreToCurrent()` converts 1.x bond data to the current 2.x format.
- `NimBLEBondMigration::migrateBondStoreToV1()` converts current bond data back to the 1.x format.
- `NimBLEBondMigration::dumpBondData()` returns a human-readable dump of the stored bond records for debugging.

These functions must be called **before** `NimBLEDevice::init()` so the bond store can be updated before the stack starts using it.

Typical migration flow:

1. Build and flash a temporary migration firmware that includes `NimBLEBondMigration.h`.
2. Call `migrateBondStoreToCurrent()` once during startup before BLE initialization.
3. If the function returns `true`, stop there and then flash the final 2.x application firmware.
4. After the migration is complete, do not run the migration again in normal application startup.

Example:

    #include <NimBLEDevice.h>
    #include <NimBLEBondMigration.h>

    void setup() {
        bool success = NimBLEBondMigration::migrateBondStoreToCurrent();
        if (success) {
            // Flash the normal 2.x firmware after this one-time step.
            while (true) {
                delay(1000);
            }
        }

        NimBLEDevice::init("NimBLE");
    }

Notes:

- These helpers currently require `ESP_PLATFORM` because they operate directly on the ESP NVS bond storage.
- `dumpBondData()` is useful before and after migration to verify what records are present.
- If you need to temporarily return to a 1.x firmware image while preserving bonds, run `migrateBondStoreToV1()` first, then flash the 1.x application.
- See the `examples/NimBLE_Bond_Migration` example for a complete one-time migration sketch.
<br/>

## BLE Device
- Ignore list functions and vector have been removed, the application should implement this if desired. It was no longer used by the library.
- `NimBLEDevice::startSecurity` now returns a `bool`, true on success, instead of an int to be consistent with the rest of the library.
- `NimBLEDevice::getInitialized` renamed to `NimBLEDevice::isInitialized`.
- `NimBLEDevice::setPower` no longer takes the `esp_power_level_t` and `esp_ble_power_type_t`, instead only an integer value in dbm units is accepted, so instead of `ESP_PWR_LVL_P9` an `int8_t` value of `9` would be used for the same result.
- `NimBLEDevice::setOwnAddrType` no longer takes a `bool nrpa` parameter, the random address type will be determined by the bits the in the address instead.  
    Note: If setting a custom address, it should be set with `NimBLEDevice::setOwnAddr` first before calling  `NimBLEDevice::setOwnAddrType`.
- `NimBLEDevice::getClientListSize` replaced with `NimBLEDevice::getCreatedClientCount`.
- `NimBLEDevice::getClientList` was removed and `NimBLEDevice::getConnectedClients` can be used instead which returns a `std::vector` of pointers to the connected client instances. This was done because internally the clients are managed in a `std::array` which replaced the 'std::list`.  
- `NimBLEDevice::getClientByID(uint16_t conn_id);` has been changed to `NimBLEDevice::getClientByHandle(uint16_t connHandle)`
<br/>

## BLE Addresses
NimBLEAddress comparisons have changed to now consider the address type. If 2 address values are the same but the type is different then they are no longer considered equal. This is a correction to the 1.x version which did not consider the type, whereas the BLE specification states:
> Whenever two device addresses are compared, the comparison shall include the device address type (i.e. if the two addresses have different types, they are different even if the two 48-bit addresses are the same).

This means that if in your application you create a NimBLEAddress instance and are comparing a scan result or some other address created by the library and you did not define the address type then the comparison may fail.
The default address type is public `0`, whereas many devices use a random `1` address type.
If you experience this issue please create your address instances with the address type specified, i.e. `NimBLEAddress address("11:22:33:44:55:66", TYPE_HERE)`

`NimBLEAddress::getNative` has been removed and replaced with `NimBLEAddress::getBase`.
This returns a pointer to `const ble_addr_t` instead of a pointer to the address value that `getNative` did. The value can be accessed through this struct via `ble_addr_t.val` and type is in `ble_addr_t.type`.  
<br/>

## BLE UUID's
- `NimBLEUUID::getNative` method replaced with `NimBLEUUID::getBase` which returns a read-only pointer to the underlying `ble_uuid_t` struct.
- `NimBLEUUID`; `msbFirst` parameter has been removed from constructor, caller should reverse the data first or call the new `NimBLEUUID::reverseByteOrder` method after.  
<br/>

## Server
- `NimBLEServer::disconnect` now returns `bool`, true = success,  instead of `int` to be consistent with the rest of the library.
- `NimBLEServerCallbacks::onMTUChanged` renamed to `NimBLEServerCallbacks::onMTUChange` to be consistent with the client callback.
- `NimBLEServer::getPeerIDInfo` renamed to `NimBLEServer::getPeerInfoByHandle` to better describe it's use.
- Advertising is no longer automatically restarted when a peer disconnects, to re-enable this feature either call `NimBLEServer::advertiseOnDisconnect(true);` after creating the server or manually restart advertising in the `onDisconnect` callback.   
<br/>

### Services
- `NimBLEService::getCharacteristics` now returns a `const std::vector<NimBLECharacteristic*>&` instead of a copy of the vector.  
<br/>

### Characteristics
- `NimBLECharacteristic::notify` no longer takes a `bool is_notification` parameter, instead `NimBLECharacteristic::indicate` should be called to send indications.  
<br/>

#### Characteristic callbacks
- `NimBLECharacteristicCallbacks::onNotify` removed as unnecessary, the library does not call notify without app input.
- `NimBLECharacteristicCallbacks::onStatus` No longer takes a `status` parameter, refer to the return code parameter for success/failure.  
<br/>

### Server Security
- `NimBLEServerCallbacks::onPassKeyRequest` has been renamed to `NimBLEServerCallbacks::onPassKeyDisplay` as it is intended that the device should display the passkey for the client to enter.
- `NimBLEServerCallbacks::onAuthenticationComplete` now takes a `NimBLEConnInfo&` parameter.  
<br/>

## Client
- `NimBLEClient::getServices` now returns a const reference to std::vector<NimBLERemoteService*> instead of a pointer to the internal vector.
- `NimBLEClient::getConnId` has been renamed to `getConnHandle` to be consistent with bluetooth terminology.
- `NimBLEClient::disconnect` now returns a `bool`, true on success, instead of an `int` to be consistent with the rest of the library.  
<br/>

### Client callbacks
- `NimBLEClientCallbacks::onConfirmPIN` renamed to `NimBLEClientCallbacks::onConfirmPasskey`,  takes a `NimBLEConnInfo&` parameter and no longer returns a value. This should be used to prompt a user to confirm the pin on the display (YES/NO) after which the response should be sent with `NimBLEDevice::injectConfirmPasskey`.
- `NimBLEClientCallbacks::onPassKeyRequest` has been changed to `NimBLEClientCallbacks::onPassKeyEntry` which takes a `NimBLEConnInfo&` parameter and no longer returns a value. Instead of returning a value this callback should prompt a user to enter a passkey number which is sent later via `NimBLEDevice::injectPassKey`.  
<br/>

### Remote Services
- `NimBLERemoteService::getCharacteristics` now returns a `const std::vector<NimBLERemoteCharacteristic*>&` instead of non-const `std::vector<NimBLERemoteCharacteristic*>*`.  
<br/>

### Remote Characteristics
- `NimBLERemoteCharacteristic::getRemoteService` now returns a `const NimBLERemoteService*` instead of non-const.
- `NimBLERemoteCharacteristic::registerForNotify`, has been removed, the application should use `NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::unSubscribe`.

        `NimBLERemoteCharacteristic::readUInt32`
        `NimBLERemoteCharacteristic::readUInt16`
        `NimBLERemoteCharacteristic::readUInt8`
        `NimBLERemoteCharacteristic::readFloat`

Have been removed, instead the application should use `NimBLERemoteCharacteristic::readValue<type\>`.  
<br/>

## Scan
- `NimBLEScan::stop` will no longer call the `onScanEnd` callback as the caller should know it has been stopped either by initiating a connection or calling this function itself.
- `NimBLEScan::clearDuplicateCache` has been removed as it was problematic and only for the original esp32. The application should stop and start the scanner for the same effect or call `NimBLEScan::start` with the new `bool restart` parameter set to true.
- `NimBLEScanResults::getDevice` methods now return `const NimBLEAdvertisedDevice*` instead of a non-const pointer.
- `NimBLEScanResults` iterators are now `const_iterator`.
- The callback parameter for `NimBLEScan::start` has been removed and the blocking overload of `NimBLEScan::start` has been replaced by an overload of `NimBLEScan::getResults` with the same parameters.

    So if your code prior was this:

        NimBLEScanResults results = pScan->start(10, false);

    It should now be:

        NimBLEScanResults results = pScan->getResults(10000, false); // note the time is now in milliseconds

- `NimBLEAdvertisedDeviceCallbacks` Has been replaced by `NimBLEScanCallbacks` which contains the following methods:
- - `NimBLEScanCallbacks::onResult`, functions the same as the old `NimBLEAdvertisedDeviceCallbacks::onResult` but now takes aa `const NimBLEAdvertisedDevice*` instead of non-const.
- - `NimBLEScanCallbacks::onScanEnd`, replaces the scanEnded callback passed to `NimBLEScan::start` and now takes a `const NimBLEScanResults&` and `int reason` parameter.
- - `NimBLEScanCallbacks::onDiscovered`, This is called immediately when a device is first scanned, before any scan response data is available and takes a `const NimBLEAdvertisedDevice*` parameter.  
- `NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* callbacks, bool wantDuplicates)` has been changed to `NimBLEScan::setScanCallbacks(NimBLEScanCallbacks* callbacks, bool wantDuplicates);`
<br/>

### Advertised Device
- `NimBLEAdvertisedDevice::hasRSSI` removed as redundant, RSSI is always available.
- `NimBLEAdvertisedDevice::getPayload` now returns `const std::vector<uint8_t>&` instead of a pointer to internal memory.
- `NimBLEAdvertisedDevice` Timestamp removed, if needed then the app should track the time from the callback.  
<br/>

## Advertising
- `NimBLEAdvertising::setMinPreferred` and `NimBLEAdvertising::setMaxPreferred` have been removed and replaced by `NimBLEAdvertising::setPreferredParams` which takes both the min and max parameters.
- Advertising the name and TX power of the device will no longer happen by default and should be set manually by the application using `NimBLEAdvertising::setName` and `NimBLEAdvertising::addTxPower`.
- `NimBLEAdvertising::setAdvertisementType` has been renamed to `NimBLEAdvertising::setConnectableMode` to better reflect it's function.
- `NimBLEAdvertising::setScanResponse` has been renamed to `NimBLEAdvertising::enableScanResponse` to better reflect it's function.
- `NimBLEAdvertising`; Scan response is no longer enabled by default.
- `NimBLEAdvertising::start` No longer takes a callback pointer parameter, instead the new method `NimBLEAdvertising::setAdvertisingCompleteCallback` should be used to set the callback function.  
<br/>

## Beacons
- Removed Eddystone URL as it has been shutdown by google since 2021.
- `NimBLEEddystoneTLM::setTemp` now takes an `int16_t` parameter instead of float to be friendly to devices without floating point support.
- `NimBLEEddystoneTLM::getTemp` now returns `int16_t` to work with devices that don't have floating point support.
- `NimBLEEddystoneTLM::setData` now takes a reference to * `NimBLEEddystoneTLM::BeaconData` instead of `std::string`.
- `NimBLEEddystoneTLM::getData` now returns a reference to * `NimBLEEddystoneTLM::BeaconData` instead of `std::string`.
- `NimBLEBeacon::setData` now takes `const NimBLEBeacon::BeaconData&` instead of `std::string`.
- `NimBLEBeacon::getData` now returns `const NimBLEBeacon::BeaconData&` instead of `std::string`.  
<br/>

## Utilities
- `NimBLEUtils::dumpGapEvent` function removed.
- `NimBLEUtils::buildHexData` replaced with `NimBLEUtils::dataToHexString`, which returns a `std::string` containing the hex string.  
<br/>
