Google Fast Pair Service (GFPS) Service

The GfpsService implements the Google Fast Pair Service, allowing first-party fast-pair experience on Android devices using the google nearby framework. This also supports app matching / launching, as well as Google’s Find My Device service. Finally, GFPS supports sharing device pairing info across that account’s google devices and personalizing the name of the device.

API Reference

Header File

Classes

class GfpsService : public espp::BaseComponent

Google Fast Pair Service This class is responsible for creating and managing the Google Fast Pair Service.

The service is created with the following characteristics:

  • Model ID (read, unencrypted)

  • KB Pairing (write and notify, unencrypted)

  • Passkey (write and notify, unencrypted)

  • Account Key (write, unencrypted)

Google fast pair service also requires the fast pair provider (device) to support the Device Information Service (DIS, 0x180A) including the Firmware Revision characteristic (0x2A26).

For more information see https://developers.google.com/nearby/fast-pair/specifications/characteristics

If you need the DeviceInfoService and BatteryService, you can access them through espp::BleGattServer.

See also

BleGattServer

GFPS Service 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 = "ESP++ GFPS";
  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"); },
      .get_passkey_callback = [&]() { return NimBLEDevice::getSecurityPasskey(); },
      .confirm_passkey_callback =
          [&](const NimBLEConnInfo &conn_info, uint32_t passkey) {
            // set the passkey here, so that GFPS can later compare against it
            // and inject confirmation/rejection
            NimBLEDevice::setSecurityPasskey(passkey);
          },
  });
  ble_gatt_server.init(device_name);
#if CONFIG_BT_NIMBLE_EXT_ADV
#error                                                                                             \
    "This example does not support extended advertising, as GFPS does not recognize ext advertisements"
#endif
#if !CONFIG_BT_NIMBLE_EXT_ADV
  ble_gatt_server.set_advertise_on_disconnect(true);
#endif

  // NOTE: we don't have to set security, since GFPS internally will set it to
  // what is required by the spec.

  // let's create a GFPS service
  espp::GfpsService gfps_service;
  gfps_service.set_log_level(espp::Logger::Verbosity::DEBUG);
  gfps_service.init(ble_gatt_server.server());

  // now that we've made the input characteristic, we can start the service
  gfps_service.start();
  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 = 0x02; // USB
  uint16_t vid = 0xCafe;
  uint16_t pid = 0xBabe;
  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");
  // NOTE: this is NOT required to be the same as the GFPS SKU Name
  device_info_service.set_model_number("espp-gfps-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");

  // now lets start advertising
  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_DISPLAY);
  adv_data.setServiceData(gfps_service.uuid(), gfps_service.get_service_data());
  adv_data.addTxPower();
  ble_gatt_server.set_advertisement_data(adv_data);
  ble_gatt_server.start_advertising();

  // now lets update the battery level every second
  uint8_t battery_level = 99;
  while (true) {
    auto start = std::chrono::steady_clock::now();

    // 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);
  }

Public Functions

inline explicit GfpsService(espp::Logger::Verbosity log_level = espp::Logger::Verbosity::WARN)

Constructor

Parameters

log_level – The log level for the service

inline explicit GfpsService(NimBLEServer *server, espp::Logger::Verbosity log_level = espp::Logger::Verbosity::WARN)

Constructor

Note

This constructor will initialize the service with the given server

Note

This constructor will also initialize the nearby framework

Parameters
  • server – The BLE server to attach the service to

  • log_level – The log level for the service

inline void set_passkey(uint32_t passkey)

Set the passkey

Note

This function will set the passkey for the service

Note

This function should be called in the ESP_GAP_BLE_NC_REQ_EVT GAP event handler

Parameters

passkey – The passkey to set

inline uint32_t get_passkey() const

Get the passkey

Returns

The passkey for the service

inline void on_pairing_request(NimBLEConnInfo &conn_info)

On pairing request This function is called when a pairing request is received

Note

This function will call the GFPS/nearby on_pairing_request function

Note

This function should be called in the ESP_GAP_BLE_SEC_REQ_EVT GAP event handler

Parameters

conn_info – The connection information for the device

inline NimBLEService *service() const

Get the Service

Returns

The BLE service for the Google Fast Pair Service

inline NimBLEUUID uuid() const

Get the Service UUID

Returns

The UUID for the Google Fast Pair Service

inline std::string get_service_data() const

Get the Service Data

Note

The service data is the 3 byte model ID

Note

This is the service data that is advertised

Returns

The service data for the Google Fast Pair Service

inline bool notify(nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Notify the characteristic

Note

This function will notify the given characteristic with the given value

Parameters
  • characteristic – The characteristic to notify

  • value – The value to notify

  • length – The length of the value

Returns

True if the notification was successful, false otherwise

inline void init(NimBLEServer *server)

Initialize the service

Note

This function will initialize the service with the given server

Note

This function will also initialize the nearby framework

Parameters

server – The BLE server to attach the service to

inline void deinit()

Deinitialize the service

Note

This function will deinitialize the service

Note

This function will also deinitialize the nearby framework

Note

This function should only be called after NimBLEDevice::deinit(true) has been called, since that will free the memory used by the service and the nearby framework

inline void start()

Start the service

Note

This function will start the service

Note

This function will also set the advertisement mode for the nearby framework

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

Returns

The verbosity level of the logger

inline void set_log_level(espp::Logger::Verbosity level)

Set the log level for the logger

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

set_log_level

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

get_log_level

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

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

Header File

Classes

class GfpsCharacteristicCallback

Callback base class for the Google Fast Pair Service This class provides the base functionality for the Google Fast Pair Service characteristic callbacks.

Subclassed by espp::GfpsAccountKeyCharacteristicCallbacks, espp::GfpsKbPairingCharacteristicCallbacks, espp::GfpsModelIdCharacteristicCallbacks, espp::GfpsPasskeyCharacteristicCallbacks

Public Functions

inline std::vector<uint8_t> on_gfps_read(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic)

Called when a Google Fast Pair Service characteristic is read

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to read

Returns

The value of the characteristic or an empty vector if the read failed

inline void on_gfps_write(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Called when a Google Fast Pair Service characteristic is written

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to write

  • value – The value to write

  • length – The length of the value

inline void set_log_level(espp::Logger::Verbosity log_level)

Set the log level for the class

Parameters

log_level – The log level

class GfpsModelIdCharacteristicCallbacks : public NimBLECharacteristicCallbacks, public espp::GfpsCharacteristicCallback

Public Functions

inline void onRead(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Model ID Characteristic is read

Parameters
  • characteristic – The characteristic that is being read

  • conn_info – The ConnInfo object for the connection associated with the read

inline std::vector<uint8_t> on_gfps_read(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic)

Called when a Google Fast Pair Service characteristic is read

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to read

Returns

The value of the characteristic or an empty vector if the read failed

inline void on_gfps_write(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Called when a Google Fast Pair Service characteristic is written

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to write

  • value – The value to write

  • length – The length of the value

inline void set_log_level(espp::Logger::Verbosity log_level)

Set the log level for the class

Parameters

log_level – The log level

class GfpsKbPairingCharacteristicCallbacks : public NimBLECharacteristicCallbacks, public espp::GfpsCharacteristicCallback

Public Functions

inline void onWrite(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Key-Based Pairing Characteristic is written

Parameters
  • characteristic – The characteristic that is being written

  • conn_info – The ConnInfo object for the connection associated with the write

inline void onRead(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Key-Based Pairing Characteristic is read

Parameters
  • characteristic – The characteristic that is being read

  • conn_info – The ConnInfo object for the connection associated with the read

inline std::vector<uint8_t> on_gfps_read(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic)

Called when a Google Fast Pair Service characteristic is read

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to read

Returns

The value of the characteristic or an empty vector if the read failed

inline void on_gfps_write(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Called when a Google Fast Pair Service characteristic is written

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to write

  • value – The value to write

  • length – The length of the value

inline void set_log_level(espp::Logger::Verbosity log_level)

Set the log level for the class

Parameters

log_level – The log level

class GfpsPasskeyCharacteristicCallbacks : public NimBLECharacteristicCallbacks, public espp::GfpsCharacteristicCallback

Public Functions

inline void onWrite(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Passkey Pairing Characteristic is written

Parameters
  • characteristic – The characteristic that is being written

  • conn_info – The ConnInfo object for the connection associated with the write

inline void onRead(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Passkey Characteristic is read

Parameters
  • characteristic – The characteristic that is being read

  • conn_info – The ConnInfo object for the connection associated with the read

inline std::vector<uint8_t> on_gfps_read(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic)

Called when a Google Fast Pair Service characteristic is read

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to read

Returns

The value of the characteristic or an empty vector if the read failed

inline void on_gfps_write(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Called when a Google Fast Pair Service characteristic is written

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to write

  • value – The value to write

  • length – The length of the value

inline void set_log_level(espp::Logger::Verbosity log_level)

Set the log level for the class

Parameters

log_level – The log level

class GfpsAccountKeyCharacteristicCallbacks : public NimBLECharacteristicCallbacks, public espp::GfpsCharacteristicCallback

Public Functions

inline void onWrite(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Account Key Characteristic is written

Parameters
  • characteristic – The characteristic that is being written

  • conn_info – The ConnInfo object for the connection associated with the write

inline void onRead(NimBLECharacteristic *characteristic, NimBLEConnInfo &conn_info) override

Called when the Account Key Characteristic is read

Parameters
  • characteristic – The characteristic that is being read

  • conn_info – The ConnInfo object for the connection associated with the read

inline std::vector<uint8_t> on_gfps_read(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic)

Called when a Google Fast Pair Service characteristic is read

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to read

Returns

The value of the characteristic or an empty vector if the read failed

inline void on_gfps_write(NimBLEConnInfo &conn_info, nearby_fp_Characteristic characteristic, const uint8_t *value, size_t length)

Called when a Google Fast Pair Service characteristic is written

Parameters
  • conn_info – The connection information for the device

  • characteristic – The characteristic to write

  • value – The value to write

  • length – The length of the value

inline void set_log_level(espp::Logger::Verbosity log_level)

Set the log level for the class

Parameters

log_level – The log level

Header File