BLE GATT Server
The BleGattServer implements the standard BLE GATT server which has various APIs for controlling the server and adding services. It automatically builds and adds standard battery service and device information service.
API Reference
Header File
Header File
Classes
-
class BleGattServer : public espp::BaseComponent
BLE GATT Server This class is responsible for creating and managing the BLE GATT server. It is responsible for handling the connection and disconnection of clients. It is also responsible for handling the pairing process. It also manages the different services that are part of the GATT server.
BLE GATT Server Example
// NOTE: esp-nimble-cpp already depends on nvs_flash and initializes // nvs_flash in the NimBLEDevice::init(), so we don't have to do that // to store bonding info // create the GATT server espp::BleGattServer ble_gatt_server; std::string device_name = "Espp BLE GATT Server"; ble_gatt_server.set_log_level(espp::Logger::Verbosity::INFO); ble_gatt_server.set_callbacks({ .connect_callback = [&](NimBLEConnInfo &conn_info) { logger.info("Device connected"); }, .disconnect_callback = [&](auto &conn_info, auto reason) { logger.info("Device disconnected: {}", reason); }, .authentication_complete_callback = [&](const NimBLEConnInfo &conn_info) { logger.info("Device authenticated"); }, // NOTE: this is optional, if you don't provide this callback, it will // perform the exactly function as below: .get_passkey_callback = [&]() { logger.info("Getting passkey"); return NimBLEDevice::getSecurityPasskey(); }, // NOTE: this is optional, if you don't provide this callback, it will // perform the exactly function as below: .confirm_passkey_callback = [&](const NimBLEConnInfo &conn_info, uint32_t passkey) { logger.info("Confirming passkey: {}", passkey); NimBLEDevice::injectConfirmPIN(conn_info, passkey == NimBLEDevice::getSecurityPasskey()); }, }); ble_gatt_server.init(device_name); #if !CONFIG_BT_NIMBLE_EXT_ADV // extended advertisement does not support automatically advertising on // disconnect ble_gatt_server.set_advertise_on_disconnect(true); #endif // let's configure the security bool bonding = true; bool mitm = false; bool secure_connections = true; ble_gatt_server.set_security(bonding, mitm, secure_connections); // and some i/o and key config NimBLEDevice::setSecurityPasskey(123456); ble_gatt_server.set_io_capabilities(BLE_HS_IO_NO_INPUT_OUTPUT); ble_gatt_server.set_init_key_distribution(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); ble_gatt_server.set_resp_key_distribution(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); // you can create a service and add it to the server using // ble_gatt_server.server().addService() // now start the services ble_gatt_server.start_services(); // starts the device info service and battery service // NOTE: we could also directly start them ourselves if we wanted to // control the order of starting the services // e.g.: // ble_gatt_server.battery_service().start(); // ble_gatt_server.device_info_service().start(); // now start the gatt server ble_gatt_server.start(); // let's set some of the service data auto &battery_service = ble_gatt_server.battery_service(); battery_service.set_battery_level(99); auto &device_info_service = ble_gatt_server.device_info_service(); uint8_t vendor_source = 0x01; uint16_t vid = 0xCafe; uint16_t pid = 0xFace; uint16_t product_version = 0x0100; device_info_service.set_pnp_id(vendor_source, vid, pid, product_version); device_info_service.set_manufacturer_name("ESP-CPP"); device_info_service.set_model_number("esp-ble-01"); device_info_service.set_serial_number("1234567890"); device_info_service.set_software_version("1.0.0"); device_info_service.set_firmware_version("1.0.0"); device_info_service.set_hardware_version("1.0.0"); // set the advertising data espp::BleGattServer::AdvertisedData adv_data; // uint8_t flags = BLE_HS_ADV_F_DISC_LTD; uint8_t flags = BLE_HS_ADV_F_DISC_GEN; adv_data.setFlags(flags); adv_data.setName(device_name); adv_data.setAppearance((uint16_t)espp::BleAppearance::GENERIC_COMPUTER); adv_data.addTxPower(); ble_gatt_server.set_advertisement_data(adv_data); #if CONFIG_COMPILER_CXX_EXCEPTIONS // let's test and use the BLE menu (CLI) // turn off some of the logs so that it doesn't clutter up the CLI ble_gatt_server.set_log_level(espp::Logger::Verbosity::WARN); // and make the CLI auto ble_menu = espp::BleGattServerMenu(ble_gatt_server); cli::SetColor(); cli::Cli cli(ble_menu.get()); cli.ExitAction([](auto &out) { out << "Goodbye and thanks for all the fish.\n"; }); espp::Cli input(cli); input.SetInputHistorySize(10); input.Start(); // this will not return until the user enters the `exit` command. #endif logger.info("Menu has finished, starting advertising"); // The menu has finished, so let's go into a loop to keep the device running // now lets start advertising ble_gatt_server.start_advertising(); logger.info("Waiting for connection..."); // now lets update the battery level every second for a little while uint8_t battery_level = 99; bool was_connected = false; bool can_exit = false; int num_seconds_to_wait = 30; while (true) { auto start = std::chrono::steady_clock::now(); // if we are now connected, but were not, then get the services if (ble_gatt_server.is_connected() && !was_connected) { was_connected = true; can_exit = true; auto connected_device_infos = ble_gatt_server.get_connected_device_infos(); logger.info("Connected devices: {}", connected_device_infos.size()); std::vector<std::string> connected_device_names; std::transform(connected_device_infos.begin(), connected_device_infos.end(), std::back_inserter(connected_device_names), [&](auto &info) { return ble_gatt_server.get_connected_device_name(info); }); logger.info(" Names: {}", connected_device_names); } else if (!ble_gatt_server.is_connected()) { was_connected = false; if (can_exit) { logger.info("No longer connected, exiting"); break; } } if (!ble_gatt_server.is_connected()) { logger.move_up(); logger.clear_line(); logger.info("Waiting for connection... {}s", --num_seconds_to_wait); if (num_seconds_to_wait == 0) { logger.info("No connection, exiting"); break; } // sleep std::this_thread::sleep_until(start + 1s); continue; } // update the battery level battery_service.set_battery_level(battery_level); battery_level = (battery_level % 100) + 1; // sleep std::this_thread::sleep_until(start + 1s); } // we are done, so stop the server and deinit the BLE stack. NOTE: this will // automatically be called by ~BleGattServer(), but we call it here to show // manual control and to test calling it multiple times since the destructor // will be called immediately after this block ends ble_gatt_server.deinit();
Public Types
-
enum class DisconnectReason : uint8_t
Disconnect reasons for the GATT server. This enum represents the different reasons for disconnection that will be passed to the disconnect callback.
This enum is a simplification of the NimBLE disconnect reasons, and is meant to provide a more user-friendly way to handle disconnections. For more information about the possible reasons for disconnection, see https://mynewt.apache.org/latest/network/ble_hs/ble_hs_return_codes.html.
Values:
-
enumerator UNKNOWN
Unknown reason for disconnection.
-
enumerator TIMEOUT
Disconnected due to timeout.
-
enumerator CONNECTION_TERMINATED
Disconnected due to the connection being terminated.
-
enumerator REMOTE_USER_TERMINATED
Disconnected due to the remote user terminating the connection.
-
enumerator REMOTE_DEVICE_TERMINATED
Disconnected due to the remote device terminating the connection (low resources or power off)
-
enumerator LOCAL_USER_TERMINATED
Disconnected due to the local user terminating the connection.
-
enumerator AUTHENTICATION_FAILURE
Disconnected due to an authentication failure.
-
enumerator UNKNOWN
-
typedef std::function<void(NimBLEConnInfo&)> connect_callback_t
Callback for when a device connects to the GATT server.
- Param conn_info
The connection information for the device.
-
typedef std::function<void(NimBLEConnInfo&, DisconnectReason reason)> disconnect_callback_t
Callback for when a device disconnects from the GATT server.
- Param conn_info
The connection information for the device.
- Param reason
The reason for the disconnection.
-
typedef std::function<void(const NimBLEConnInfo&)> authentication_complete_callback_t
Callback for when a device completes authentication.
- Param conn_info
The connection information for the device.
-
typedef std::function<uint32_t(void)> get_passkey_callback_t
Callback to retrieve the passkey for the device.
- Return
The passkey for the device.
-
typedef std::function<void(const NimBLEConnInfo &conn_info, uint32_t)> confirm_passkey_callback_t
Callback for confirming the passkey.
- Param conn_info
The connection information for the device.
- Param passkey
The passkey for the device.
-
typedef std::function<void(NimBLEExtAdvertising*, int, uint8_t)> advertisement_stopped_callback_t
Callback for when advertising is stopped. This callback is called when advertising is stopped.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Param advertising
Pointer to the advertising object.
- Param reason
The reason for stopping advertising.
- Param instance
The advertising instance that was stopped.
-
typedef std::function<void(NimBLEExtAdvertising*, uint8_t, NimBLEAddress)> scan_request_callback_t
Callback for when a scan request is received. This callback is called when a scan request is received.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Param advertising
Pointer to the advertising object.
- Param instance
The advertising instance that received the scan request.
- Param address
The address of the device that sent the scan request.
-
typedef std::function<void(NimBLEAdvertising*)> advertisement_complete_callback_t
Callback for when advertising is complete. This callback is called when advertising is complete.
Note
This is called when advertising is complete, not when the device is actually advertising. It will not be called if the advertisement duration is 0 (i.e. no timeout).
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is not enabled.
- Param advertising
Pointer to the advertising object.
Public Functions
-
inline BleGattServer()
Constructor for the GATT server.
-
inline explicit BleGattServer(const Config &config)
Constructor
- Parameters
config – The configuration for the GATT server.
-
inline ~BleGattServer()
Destructor.
-
inline bool is_connected() const
Get whether the GATT server is connected to any clients.
- Returns
Whether the GATT server is connected to any clients.
-
inline void set_callbacks(const Callbacks &callbacks)
Set the callbacks for the GATT server.
- Parameters
callbacks – The callbacks for the GATT server.
-
inline bool init(const std::string &device_name)
Initialize the GATT server This method creates the GATT server and sets the callbacks to this class. It also initializes the device info and battery services.
Note
This method must be called before creating any other services or characteristics.
Note
This method must be called before starting the server.
- Parameters
device_name – The name of the device.
- Returns
Whether the GATT server was initialized successfully.
-
inline void deinit()
Deinitialize the GATT server This method deletes the server and all associated objects. It also invalidates any references/pointers to the server.
Note
After calling this method, any references/pointers to the server and any created services/characteristics will be invalid.
Note
This method should only be called after NimBLEDevice::deinit(true) has been called, since that will free the memory used by the server.
Note
This method will also deinitialize the device info and battery services.
-
inline void start_services()
Start the services This method starts the device info and battery services.
-
inline bool start()
Start the server This method starts the GATT server. This method must be called after the server has been initialized, and after any services / characteristics have been added to the server.
- Returns
Whether the server was started successfully.
-
inline void set_advertise_on_disconnect(bool advertise_on_disconnect)
Set whether to advertise on disconnect
Note
This method is only available when CONFIG_BT_NIMBLE_EXT_ADV is not enabled, ane legacy advertising is used. Otherwise, you will have to manually start advertising after disconnecting.
- Parameters
advertise_on_disconnect – Whether to advertise on disconnect
-
void set_advertisement_data(const AdvertisedData &advertising_data, uint8_t instance = 0)
Set the advertisement data for the device.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Parameters
advertising_data – The advertising data for the device.
instance – The advertising instance to set the data for.
-
void set_scan_response_data(const AdvertisedData &scan_response_data, uint8_t instance = 0)
Set the scan response data for the device.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Parameters
scan_response_data – The scan response data for the device.
instance – The advertising instance to set the data for.
-
void set_advertisement_data(const AdvertisedData &advertising_data)
Set the advertisement data for the device.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is disabled.
- Parameters
advertising_data – The advertising data for the device.
-
void set_scan_response_data(const AdvertisedData &scan_response_data)
Set the scan response data for the device.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is disabled.
- Parameters
scan_response_data – The scan response data for the device.
-
inline void stop_advertising()
Stop advertising This method stops advertising.
-
void stop_advertising(uint8_t instance)
Stop advertising This method stops advertising.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Parameters
instance – The advertising instance to stop.
-
bool start_advertising(uint32_t duration_ms = 0, uint8_t instance = 0)
Start Advertising using the previously set advertising data This method simply starts advertising using the previously set advertising data.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
- Parameters
duration_ms – The duration of the advertising in milliseconds. If 0, the advertising will not timeout. If non-zero, the advertising will stop after the specified duration.
instance – The advertising instance to start.
- Returns
Whether advertising was started successfully.
-
bool start_advertising(const AdvertisingParameters ¶ms)
Start Advertising using the previously set advertising data This method simply starts advertising using the previously set advertising data.
Note
This method is only used when CONFIG_BT_NIMBLE_EXT_ADV is not enabled, ane legacy advertising is used. Otherwise, use the NimBLEExtAdvertisement class for advertising and setting the advertising parameters.
- Parameters
params – The advertising parameters for the device.
- Returns
Whether advertising was started successfully.
-
bool start_advertising(uint32_t duration_ms = 0, NimBLEAddress *directed_address = nullptr)
Start Advertising using the previously set advertising data This method simply starts advertising using the previously set advertising data.
Note
This method is only used when CONFIG_BT_NIMBLE_EXT_ADV is not enabled, ane legacy advertising is used.
- Parameters
duration_ms – The duration of the advertising in milliseconds. If 0, the advertising will not timeout. If non-zero, the advertising will stop after the specified duration.
directed_address – The address to direct advertising to, if any.
- Returns
Whether advertising was started successfully.
-
inline NimBLEServer *server() const
Get the GATT server.
- Returns
The GATT server.
-
inline DeviceInfoService &device_info_service()
Get the device info service.
-
inline BatteryService &battery_service()
Get the battery service.
-
inline void set_device_name(const std::string &device_name)
Set the name of the device.
- Parameters
device_name – The name of the device.
-
inline void set_passkey(uint32_t passkey)
Set the passkey for the device.
- Parameters
passkey – The passkey for the device.
-
inline void set_security(bool bonding, bool mitm, bool secure)
Set the security settings for the device.
- Parameters
bonding – Whether to use bonding.
mitm – Man-in-the-middle protection.
secure – Whether to use secure connections.
-
inline void set_io_capabilities(uint8_t io_capabilities)
Set the IO capabilities for the device.
See also
BLE_HS_IO_NO_INPUT_OUTPUT
See also
BLE_HS_IO_DISPLAY_ONLY
See also
BLE_HS_IO_DISPLAY_YESNO
See also
BLE_HS_IO_KEYBOARD_ONLY
See also
BLE_HS_IO_NO_INPUT_OUTPUT
See also
BLE_HS_IO_KEYBOARD_DISPLAY
- Parameters
io_capabilities – The IO capabilities for the device.
-
inline void set_init_key_distribution(uint8_t key_distribution)
Set the initial key distribution for the device.
See also
BLE_SM_PAIR_KEY_DIST_ENC
See also
BLE_SM_PAIR_KEY_DIST_ID
- Parameters
key_distribution – The initial key distribution for the device.
-
inline void set_resp_key_distribution(uint8_t key_distribution)
Set the response key distribution for the device.
See also
BLE_SM_PAIR_KEY_DIST_ENC
See also
BLE_SM_PAIR_KEY_DIST_ID
- Parameters
key_distribution – The response key distribution for the device.
-
inline std::vector<NimBLEAddress> get_paired_devices()
Get the paired devices
- Returns
The paired devices as a vector of Addresses.
-
inline std::vector<NimBLEAddress> get_connected_device_addresses()
Get the connected device addresses
- Returns
The addresses for the connected devices as a vector.
-
inline std::vector<NimBLEConnInfo> get_connected_device_infos()
Get the NimBLEConnInfo objects for the connected devices
- Returns
The connected devices info as a vector of NimBLEConnInfo.
-
inline std::string get_connected_device_name(NimBLEConnInfo &conn_info)
Get the connected device name
- Parameters
conn_info – The connection information for the device.
- Returns
The connected device name.
-
inline std::vector<std::string> get_connected_device_names()
Get the connected device names
Note
This method will connect to each device to get the device name. This may take some time if there are many devices connected.
- Returns
The connected device names as a vector of strings.
-
inline int get_connected_device_rssi(NimBLEConnInfo &conn_info)
Get the RSSI of the connected device
- Parameters
conn_info – The connection information for the device.
- Returns
The RSSI of the connected device.
-
inline std::vector<int> get_connected_devices_rssi_values()
Get the RSSI of the connected devices
Note
This method will connect to each device to get the RSSI. This may take some time if there are many devices connected.
- Returns
The RSSI of the connected devices as a vector.
-
inline std::vector<NimBLEAddress> disconnect_all()
Disconnect from all devices This method disconnects from all devices that are currently connected.
- Returns
The Addresses of the devices that were disconnected from.
-
inline std::vector<NimBLEAddress> unpair_all()
Unpair all devices This method unpairs all devices that are currently paired.
- Returns
The Addresses of the devices that were unpaired.
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static inline constexpr uint16_t interval_ms_to_units(uint16_t interval_ms)
Convert an interval in milliseconds to units of 0.625 ms.
- Parameters
interval_ms – The interval in milliseconds.
- Returns
The interval in units of 0.625 ms.
-
static inline constexpr uint16_t interval_units_to_ms(uint16_t interval_units)
Convert an interval in units of 0.625 ms to milliseconds.
- Parameters
interval_units – The interval in units of 0.625 ms.
- Returns
The interval in milliseconds.
-
struct AdvertisingParameters
Advertising parameters for the device. This struct contains the advertising parameters for the device.
See also
Note
This struct is only available when CONFIG_BT_NIMBLE_EXT_ADV is not enabled, ane legacy advertising is used. Otherwise, use the NimBLEExtAdvertisement class.
Public Members
-
bool connectable = true
Whether the device should be connectable.
-
uint16_t min_interval_ms = 20
Minimum advertising interval. NOTE: this is in milliseconds, but will be converted to units of 0.625 ms. If the value is not a multiple of 0.625 ms, it will be rounded to the nearest multiple and a log message will be printed.
-
uint16_t max_interval_ms = 40
Maximum advertising interval. NOTE: this is in milliseconds, but will be converted to units of 0.625 ms. If the value is not a multiple of 0.625 ms, it will be rounded to the nearest multiple and a log message will be printed.
-
bool include_tx_power = false
Whether to include the TX power level.
-
bool scan_response = false
Whether the device should include scan response data.
-
bool scan_request_whitelist = false
Whether the device should use the white list when scanning
-
bool connect_whitelist = false
Whether the device should use the white list when connecting
-
uint32_t duration_ms = 0
Advertising duration (in ms, 0 for no timeout)
-
NimBLEAddress *directed_address = nullptr
Address to direct advertising to, if any.
-
bool connectable = true
-
struct Callbacks
Callbacks for the GATT server.
Public Members
-
connect_callback_t connect_callback = nullptr
Callback for when a device connects to the GATT server.
-
disconnect_callback_t disconnect_callback = nullptr
Callback for when a device disconnects from the GATT server.
-
authentication_complete_callback_t authentication_complete_callback = nullptr
Callback for when a device completes authentication.
-
get_passkey_callback_t get_passkey_callback = nullptr
Callback for getting the passkey.
Note
If not provided, will simply return NimBLEDevice::getSecurityPasskey().
-
confirm_passkey_callback_t confirm_passkey_callback = nullptr
Callback for confirming the passkey.
Note
Within this function or some point after this call, the user should call NimBLEDevice::injectConfirmPIN(conn_info, true/false) to confirm or reject the passkey.
Note
If not provided, will simply call NimBLEDevice::injectConfirmPIN(conn_info, passkey == NimBLEDevice::getSecurityPasskey()).
-
advertisement_complete_callback_t advertisement_complete_callback = nullptr
Callback for when advertising is complete.
Note
This is called when advertising is complete, not when the device is actually advertising. It will not be called if the advertisement duration is 0 (i.e. no timeout)
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is not enabled.
-
advertisement_stopped_callback_t advertisement_stopped_callback = nullptr
Callback for when advertising is stopped.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
-
scan_request_callback_t scan_request_callback = nullptr
Callback for when a scan request is received.
Note
This is only available when CONFIG_BT_NIMBLE_EXT_ADV is enabled.
-
connect_callback_t connect_callback = nullptr
-
struct Config
Configuration for the GATT server.
-
enum class DisconnectReason : uint8_t
Header File
Classes
-
class BleGattServerCallbacks : public NimBLEServerCallbacks
Class for handling GATT server callbacks, as required by NimBLE
Note
This class is not intended to be used directly by the user
-
class BleGattServerAdvertisingCallbacks : public NimBLEExtAdvertisingCallbacks
Class for handling GATT server advertising callbacks, as required by NimBLE
Note
This class is not intended to be used directly by the user
Note
This class is only available if CONFIG_BT_NIMBLE_EXT_ADV is enabled
Header File
Classes
-
class BleGattServerMenu
A CLI menu for interacting with BleGattServer.
This class provides a CLI menu for interacting with a BleGattServer. It provides options for setting the log verbosity, viewing the paired devices, viewing the connected devices, disconnecting devices, and more.
Example
// NOTE: esp-nimble-cpp already depends on nvs_flash and initializes // nvs_flash in the NimBLEDevice::init(), so we don't have to do that // to store bonding info // create the GATT server espp::BleGattServer ble_gatt_server; std::string device_name = "Espp BLE GATT Server"; ble_gatt_server.set_log_level(espp::Logger::Verbosity::INFO); ble_gatt_server.set_callbacks({ .connect_callback = [&](NimBLEConnInfo &conn_info) { logger.info("Device connected"); }, .disconnect_callback = [&](auto &conn_info, auto reason) { logger.info("Device disconnected: {}", reason); }, .authentication_complete_callback = [&](const NimBLEConnInfo &conn_info) { logger.info("Device authenticated"); }, // NOTE: this is optional, if you don't provide this callback, it will // perform the exactly function as below: .get_passkey_callback = [&]() { logger.info("Getting passkey"); return NimBLEDevice::getSecurityPasskey(); }, // NOTE: this is optional, if you don't provide this callback, it will // perform the exactly function as below: .confirm_passkey_callback = [&](const NimBLEConnInfo &conn_info, uint32_t passkey) { logger.info("Confirming passkey: {}", passkey); NimBLEDevice::injectConfirmPIN(conn_info, passkey == NimBLEDevice::getSecurityPasskey()); }, }); ble_gatt_server.init(device_name); #if !CONFIG_BT_NIMBLE_EXT_ADV // extended advertisement does not support automatically advertising on // disconnect ble_gatt_server.set_advertise_on_disconnect(true); #endif // let's configure the security bool bonding = true; bool mitm = false; bool secure_connections = true; ble_gatt_server.set_security(bonding, mitm, secure_connections); // and some i/o and key config NimBLEDevice::setSecurityPasskey(123456); ble_gatt_server.set_io_capabilities(BLE_HS_IO_NO_INPUT_OUTPUT); ble_gatt_server.set_init_key_distribution(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); ble_gatt_server.set_resp_key_distribution(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); // you can create a service and add it to the server using // ble_gatt_server.server().addService() // now start the services ble_gatt_server.start_services(); // starts the device info service and battery service // NOTE: we could also directly start them ourselves if we wanted to // control the order of starting the services // e.g.: // ble_gatt_server.battery_service().start(); // ble_gatt_server.device_info_service().start(); // now start the gatt server ble_gatt_server.start(); // let's set some of the service data auto &battery_service = ble_gatt_server.battery_service(); battery_service.set_battery_level(99); auto &device_info_service = ble_gatt_server.device_info_service(); uint8_t vendor_source = 0x01; uint16_t vid = 0xCafe; uint16_t pid = 0xFace; uint16_t product_version = 0x0100; device_info_service.set_pnp_id(vendor_source, vid, pid, product_version); device_info_service.set_manufacturer_name("ESP-CPP"); device_info_service.set_model_number("esp-ble-01"); device_info_service.set_serial_number("1234567890"); device_info_service.set_software_version("1.0.0"); device_info_service.set_firmware_version("1.0.0"); device_info_service.set_hardware_version("1.0.0"); // set the advertising data espp::BleGattServer::AdvertisedData adv_data; // uint8_t flags = BLE_HS_ADV_F_DISC_LTD; uint8_t flags = BLE_HS_ADV_F_DISC_GEN; adv_data.setFlags(flags); adv_data.setName(device_name); adv_data.setAppearance((uint16_t)espp::BleAppearance::GENERIC_COMPUTER); adv_data.addTxPower(); ble_gatt_server.set_advertisement_data(adv_data); #if CONFIG_COMPILER_CXX_EXCEPTIONS // let's test and use the BLE menu (CLI) // turn off some of the logs so that it doesn't clutter up the CLI ble_gatt_server.set_log_level(espp::Logger::Verbosity::WARN); // and make the CLI auto ble_menu = espp::BleGattServerMenu(ble_gatt_server); cli::SetColor(); cli::Cli cli(ble_menu.get()); cli.ExitAction([](auto &out) { out << "Goodbye and thanks for all the fish.\n"; }); espp::Cli input(cli); input.SetInputHistorySize(10); input.Start(); // this will not return until the user enters the `exit` command. #endif logger.info("Menu has finished, starting advertising"); // The menu has finished, so let's go into a loop to keep the device running // now lets start advertising ble_gatt_server.start_advertising(); logger.info("Waiting for connection..."); // now lets update the battery level every second for a little while uint8_t battery_level = 99; bool was_connected = false; bool can_exit = false; int num_seconds_to_wait = 30; while (true) { auto start = std::chrono::steady_clock::now(); // if we are now connected, but were not, then get the services if (ble_gatt_server.is_connected() && !was_connected) { was_connected = true; can_exit = true; auto connected_device_infos = ble_gatt_server.get_connected_device_infos(); logger.info("Connected devices: {}", connected_device_infos.size()); std::vector<std::string> connected_device_names; std::transform(connected_device_infos.begin(), connected_device_infos.end(), std::back_inserter(connected_device_names), [&](auto &info) { return ble_gatt_server.get_connected_device_name(info); }); logger.info(" Names: {}", connected_device_names); } else if (!ble_gatt_server.is_connected()) { was_connected = false; if (can_exit) { logger.info("No longer connected, exiting"); break; } } if (!ble_gatt_server.is_connected()) { logger.move_up(); logger.clear_line(); logger.info("Waiting for connection... {}s", --num_seconds_to_wait); if (num_seconds_to_wait == 0) { logger.info("No connection, exiting"); break; } // sleep std::this_thread::sleep_until(start + 1s); continue; } // update the battery level battery_service.set_battery_level(battery_level); battery_level = (battery_level % 100) + 1; // sleep std::this_thread::sleep_until(start + 1s); } // we are done, so stop the server and deinit the BLE stack. NOTE: this will // automatically be called by ~BleGattServer(), but we call it here to show // manual control and to test calling it multiple times since the destructor // will be called immediately after this block ends ble_gatt_server.deinit();
Public Functions
-
inline explicit BleGattServerMenu(std::reference_wrapper<espp::BleGattServer> server)
Construct a new I2cMenu object.
- Parameters
i2c – A reference to the I2c bus to interact with.
-
inline std::unique_ptr<cli::Menu> get(std::string_view name = "ble", std::string_view description = "BLE GATT Server menu")
Get the BleGattServer menu.
- Parameters
name – The name of the menu.
description – The description of the menu.
- Returns
A unique pointer to the BleGattServer menu that you can use to add to a CLI.
-
inline explicit BleGattServerMenu(std::reference_wrapper<espp::BleGattServer> server)