# Bluetooth® SPP API

## Overview

SPP (Serial Port Profile) enables serial communication between Bluetooth devices, allowing them to exchange data over a virtual serial link. SPP API provides functionality to create both SPP initiators (clients) and acceptors (servers), enabling operation under different security requirements.

## Application Example

Check bluetooth/bluedroid/classic_bt folder in ESP-IDF examples, which contains the following application:

- This is a SPP demo. This demo can discover the service, connect, send and receive SPP data bluetooth/bluedroid/classic_bt/bt_spp_acceptor, bluetooth/bluedroid/classic_bt/bt_spp_initiator

## API Reference

### Header File

- components/bt/host/bluedroid/api/include/api/esp_spp_api.h

- This header file can be included with:

  >     #include "esp_spp_api.h"

- This header file is a part of the API provided by the `bt` component. To declare that your component depends on `bt`, add the following to your CMakeLists.txt:

  >     REQUIRES bt

  > or

  >     PRIV_REQUIRES bt

### Functions

esp_err_t esp_spp_register_callback(esp_spp_cb_t callback)

  This function is called to init callbacks with SPP module.

  Parameters:

    callback -- [in] pointer to the init callback function.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_init(esp_spp_mode_t mode)

  This function is called to init SPP module. When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. This function should be called after esp_bluedroid_enable() completes successfully.

  Parameters:

    mode -- [in] Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg)

  This function is called to init SPP module. When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. This function should be called after esp_bluedroid_enable() completes successfully.

  Note

  The member variable enable_l2cap_etrm in esp_spp_cfg_t can affect all L2CAP channel configurations of the upper layer RFCOMM protocol.

  Parameters:

    cfg -- [in] SPP configuration.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_deinit(void)

  This function is called to uninit SPP module. The operation will close all active SPP connection first, then the callback function will be called with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT. This function should be called after esp_spp_init()/esp_spp_enhanced_init() completes successfully.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr)

  Perform service discovery for the services provided by the given peer device. When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Parameters:

    bd_addr -- [in] Remote device bluetooth device address.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr)

  This function makes an SPP connection to a remote BD Address. When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT. When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Parameters:

    - sec_mask -- [in] Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.

    - role -- [in] Master or slave.

    - remote_scn -- [in] Remote device bluetooth device SCN.

    - peer_bd_addr -- [in] Remote device bluetooth device address.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_disconnect(uint32_t handle)

  This function closes an SPP connection. When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Parameters:

    handle -- [in] The connection handle.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name)

  This function create a SPP server and starts listening for an SPP connection request from a remote Bluetooth device. When the server is started successfully, the callback is called with ESP_SPP_START_EVT. When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Parameters:

    - sec_mask -- [in] Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.

    - role -- [in] Master or slave.

    - local_scn -- [in] The specific channel you want to get. If channel is 0, means get any channel.

    - name -- [in] Server's name.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg)

  This function is similar to `esp_spp_start_srv`. The only difference is that it adds a parameter to specify whether to create the SPP record.

  Note

  If the SPP record is not created, it is suggested to use it together with the SDP API.

  Parameters:

    cfg -- [in] Configuration parameters for starting the server.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_stop_srv(void)

  This function stops all SPP servers. The operation will close all active SPP connection first, then the callback function will be called with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_stop_srv_scn(uint8_t scn)

  This function stops a specific SPP server. The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Parameters:

    scn -- [in] Server channel number.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data)

  This function is used to write data, only for ESP_SPP_MODE_CB. When this function need to be called repeatedly, it is strongly recommended to call this function again after the previous event ESP_SPP_WRITE_EVT is received and the parameter 'cong' is equal to false. If the previous event ESP_SPP_WRITE_EVT with parameter 'cong' is equal to true, the function can only be called again when the event ESP_SPP_CONG_EVT with parameter 'cong' equal to false is received. This function must be called after an connection between initiator and acceptor has been established.

  Parameters:

    - handle -- [in] The connection handle.

    - len -- [in] The length of the data written.

    - p_data -- [in] The data written.

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_vfs_register(void)

  This function is used to register VFS. For now, SPP only supports write, read and close. When the operation is completed, the callback function will be called with ESP_SPP_VFS_REGISTER_EVT. This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_vfs_unregister(void)

  This function is used to unregister VFS. When the operation is completed, the callback function will be called with ESP_SPP_VFS_UNREGISTER_EVT. This function must be called after esp_spp_vfs_register() successful and before esp_spp_deinit().

  Returns:

    - ESP_OK: success

    - other: failed

esp_err_t esp_spp_get_profile_status(esp_spp_profile_status_t *profile_status)

  This function is used to get the status of SPP.

  Parameters:

    profile_status -- [out] - SPP status

  Returns:

    - ESP_OK: success

    - other: failed

### Unions

union esp_spp_cb_param_t
  #include <esp_spp_api.h>

  SPP callback parameters union.

  Public Members

  struct esp_spp_cb_param_t::spp_init_evt_param init

    SPP callback param of SPP_INIT_EVT

  struct esp_spp_cb_param_t::spp_uninit_evt_param uninit

    SPP callback param of SPP_UNINIT_EVT

  struct esp_spp_cb_param_t::spp_discovery_comp_evt_param disc_comp

    SPP callback param of SPP_DISCOVERY_COMP_EVT

  struct esp_spp_cb_param_t::spp_open_evt_param open

    SPP callback param of ESP_SPP_OPEN_EVT

  struct esp_spp_cb_param_t::spp_srv_open_evt_param srv_open

    SPP callback param of ESP_SPP_SRV_OPEN_EVT

  struct esp_spp_cb_param_t::spp_close_evt_param close

    SPP callback param of ESP_SPP_CLOSE_EVT

  struct esp_spp_cb_param_t::spp_start_evt_param start

    SPP callback param of ESP_SPP_START_EVT

  struct esp_spp_cb_param_t::spp_srv_stop_evt_param srv_stop

    SPP callback param of ESP_SPP_SRV_STOP_EVT

  struct esp_spp_cb_param_t::spp_cl_init_evt_param cl_init

    SPP callback param of ESP_SPP_CL_INIT_EVT

  struct esp_spp_cb_param_t::spp_write_evt_param write

    SPP callback param of ESP_SPP_WRITE_EVT

  struct esp_spp_cb_param_t::spp_data_ind_evt_param data_ind

    SPP callback param of ESP_SPP_DATA_IND_EVT

  struct esp_spp_cb_param_t::spp_cong_evt_param cong

    SPP callback param of ESP_SPP_CONG_EVT

  struct esp_spp_cb_param_t::spp_vfs_register_evt_param vfs_register

    SPP callback param of ESP_SPP_VFS_REGISTER_EVT

  struct esp_spp_cb_param_t::spp_vfs_unregister_evt_param vfs_unregister

    SPP callback param of ESP_SPP_VFS_UNREGISTER_EVT

  struct spp_cl_init_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_CL_INIT_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    uint8_t sec_id

      security ID used by this server

    bool use_co

      TRUE to use co_rfc_data

  struct spp_close_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_CLOSE_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t port_status

      PORT status

    uint32_t handle

      The connection handle

    bool async

      FALSE, if local initiates disconnect

  struct spp_cong_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_CONG_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    bool cong

      TRUE, congested. FALSE, uncongested

  struct spp_data_ind_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_DATA_IND_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    uint16_t len

      The length of data

    uint8_t *data

      The data received

  struct spp_discovery_comp_evt_param
    #include <esp_spp_api.h>

    SPP_DISCOVERY_COMP_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint8_t scn_num

      The num of scn_num

    uint8_t scn[ESP_SPP_MAX_SCN]

      channel #

    const char *service_name[ESP_SPP_MAX_SCN]

      service_name

  struct spp_init_evt_param
    #include <esp_spp_api.h>

    SPP_INIT_EVT.

    Public Members

    esp_spp_status_t status

      status

  struct spp_open_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_OPEN_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    int fd

      The file descriptor only for ESP_SPP_MODE_VFS

    esp_bd_addr_t rem_bda

      The peer address

  struct spp_srv_open_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_SRV_OPEN_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    uint32_t new_listen_handle

      The new listen handle

    int fd

      The file descriptor only for ESP_SPP_MODE_VFS

    esp_bd_addr_t rem_bda

      The peer address

  struct spp_srv_stop_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_SRV_STOP_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint8_t scn

      Server channel number

  struct spp_start_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_START_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    uint8_t sec_id

      security ID used by this server

    uint8_t scn

      Server channel number

    bool use_co

      TRUE to use co_rfc_data

  struct spp_uninit_evt_param
    #include <esp_spp_api.h>

    SPP_UNINIT_EVT.

    Public Members

    esp_spp_status_t status

      status

  struct spp_vfs_register_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_VFS_REGISTER_EVT.

    Public Members

    esp_spp_status_t status

      status

  struct spp_vfs_unregister_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_VFS_UNREGISTER_EVT.

    Public Members

    esp_spp_status_t status

      status

  struct spp_write_evt_param
    #include <esp_spp_api.h>

    ESP_SPP_WRITE_EVT.

    Public Members

    esp_spp_status_t status

      status

    uint32_t handle

      The connection handle

    int len

      The length of the data written.

    bool cong

      congestion status

### Structures

struct esp_spp_cfg_t

  SPP initialization configuration parameters.

  Public Members

  esp_spp_mode_t mode

    Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS.

  bool enable_l2cap_ertm

    Enable/disable Logical Link Control and Adaptation Layer Protocol enhanced retransmission mode.

  uint16_t tx_buffer_size

    Tx buffer size for a new SPP channel. A smaller setting can save memory, but may incur a decrease in throughput. Only for ESP_SPP_MODE_VFS mode.

struct esp_spp_start_srv_cfg_t

  SPP start server configuration parameters.

  Public Members

  uint8_t local_scn

    The specific channel you want to get. If channel is 0, means get any channel.

  bool create_spp_record

    Specifies whether to create the SPP record

  esp_spp_sec_t sec_mask

    Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only

  esp_spp_role_t role

    Master or slave.

  const char *name

    Server's name.

struct esp_spp_profile_status_t

  SPP profile status parameters.

  Public Members

  bool spp_inited

    spp initialization

  uint8_t conn_num

    Number of connections

### Macros

ESP_SPP_MAX_MTU

  SPP max MTU

ESP_SPP_MAX_SCN

  SPP max SCN

ESP_SPP_MIN_TX_BUFFER_SIZE

  SPP min tx buffer

ESP_SPP_MAX_TX_BUFFER_SIZE

  SPP max tx buffer size

BT_SPP_DEFAULT_CONFIG()

  SPP default configuration.

ESP_SPP_SEC_NONE

  No security.

ESP_SPP_SEC_AUTHORIZE

  Authorization required (only needed for out going connection )

ESP_SPP_SEC_AUTHENTICATE

  Authentication required.

ESP_SPP_SEC_ENCRYPT

  Encryption required.

ESP_SPP_SEC_MODE4_LEVEL4

  Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption.

ESP_SPP_SEC_MITM

  Man-In-The-Middle protection.

ESP_SPP_SEC_IN_16_DIGITS

  Min 16 digit for pin code.

### Type Definitions

typedef uint16_t esp_spp_sec_t

  SPP security type

typedef void (*esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)

  SPP callback function type. When handle ESP_SPP_DATA_IND_EVT, it is strongly recommended to cache incoming data, and process them in other lower priority application task rather than in this callback directly.

  Param event:

    Event type

  Param param:

    Point to callback parameter, currently is union type

### Enumerations

enum esp_spp_status_t

  SPP status type.

  Values:

  enumerator ESP_SPP_SUCCESS

    Successful operation.

  enumerator ESP_SPP_FAILURE

    Generic failure.

  enumerator ESP_SPP_BUSY

    Temporarily can not handle this request.

  enumerator ESP_SPP_NO_DATA

    No data

  enumerator ESP_SPP_NO_RESOURCE

    No more resource

  enumerator ESP_SPP_NEED_INIT

    SPP module shall init first

  enumerator ESP_SPP_NEED_DEINIT

    SPP module shall deinit first

  enumerator ESP_SPP_NO_CONNECTION

    Connection may have been closed

  enumerator ESP_SPP_NO_SERVER

    No SPP server

enum esp_spp_role_t

  SPP role type.

  Values:

  enumerator ESP_SPP_ROLE_MASTER

    Role: master

  enumerator ESP_SPP_ROLE_SLAVE

    Role: slave

enum esp_spp_mode_t

  SPP mode type.

  Values:

  enumerator ESP_SPP_MODE_CB

    When data is coming, a callback will come with data

  enumerator ESP_SPP_MODE_VFS

    Use VFS to write/read data

enum esp_spp_cb_event_t

  SPP callback function events.

  Values:

  enumerator ESP_SPP_INIT_EVT

    When SPP is initialized, the event comes

  enumerator ESP_SPP_UNINIT_EVT

    When SPP is deinitialized, the event comes

  enumerator ESP_SPP_DISCOVERY_COMP_EVT

    When SDP discovery complete, the event comes

  enumerator ESP_SPP_OPEN_EVT

    When SPP Client connection open, the event comes

  enumerator ESP_SPP_CLOSE_EVT

    When SPP connection closed, the event comes

  enumerator ESP_SPP_START_EVT

    When SPP server started, the event comes

  enumerator ESP_SPP_CL_INIT_EVT

    When SPP client initiated a connection, the event comes

  enumerator ESP_SPP_DATA_IND_EVT

    When SPP connection received data, the event comes, only for ESP_SPP_MODE_CB

  enumerator ESP_SPP_CONG_EVT

    When SPP connection congestion status changed, the event comes, only for ESP_SPP_MODE_CB

  enumerator ESP_SPP_WRITE_EVT

    When SPP write operation completes, the event comes, only for ESP_SPP_MODE_CB

  enumerator ESP_SPP_SRV_OPEN_EVT

    When SPP Server connection open, the event comes

  enumerator ESP_SPP_SRV_STOP_EVT

    When SPP server stopped, the event comes

  enumerator ESP_SPP_VFS_REGISTER_EVT

    When SPP VFS register, the event comes

  enumerator ESP_SPP_VFS_UNREGISTER_EVT

    When SPP VFS unregister, the event comes

Provide feedback about this document