1 /* 2 * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __ESP_SPP_API_H__ 8 #define __ESP_SPP_API_H__ 9 10 #include "esp_err.h" 11 #include "esp_bt_defs.h" 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 #define ESP_SPP_MAX_MTU (3*330) /*!< SPP max MTU */ 18 #define ESP_SPP_MAX_SCN 31 /*!< SPP max SCN */ 19 #define ESP_SPP_MIN_TX_BUFFER_SIZE 100 /*!< SPP min tx buffer */ 20 #define ESP_SPP_MAX_TX_BUFFER_SIZE (ESP_SPP_MAX_MTU * 10) /*!< SPP max tx buffer size */ 21 22 /** 23 * @brief SPP default configuration 24 */ 25 #define BT_SPP_DEFAULT_CONFIG() { \ 26 .mode = ESP_SPP_MODE_VFS, \ 27 .enable_l2cap_ertm = true, \ 28 .tx_buffer_size = ESP_SPP_MAX_TX_BUFFER_SIZE, \ 29 } 30 31 /* Security Setting Mask 32 Use these three mask modes on both sides: 33 1. ESP_SPP_SEC_NONE 34 2. ESP_SPP_SEC_AUTHENTICATE 35 3. (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) 36 Use these three mask modes only on acceptor side: 37 1. ESP_SPP_SEC_IN_16_DIGITS 38 2. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) 39 3. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) 40 Due to certain limitations, do not use these mask modes: 41 1. ESP_SPP_SEC_AUTHORIZE 42 2. ESP_SPP_SEC_MODE4_LEVEL4 43 3. ESP_SPP_SEC_MITM 44 */ 45 #define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */ 46 #define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/ 47 #define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/ 48 #define ESP_SPP_SEC_ENCRYPT 0x0024 /*!< Encryption required. relate to BTA_SEC_ENCRYPT in bta/bta_api.h*/ 49 #define ESP_SPP_SEC_MODE4_LEVEL4 0x0040 /*!< Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption relate to BTA_SEC_MODE4_LEVEL4 in bta/bta_api.h*/ 50 #define ESP_SPP_SEC_MITM 0x3000 /*!< Man-In-The_Middle protection relate to BTA_SEC_MITM in bta/bta_api.h*/ 51 #define ESP_SPP_SEC_IN_16_DIGITS 0x4000 /*!< Min 16 digit for pin code relate to BTA_SEC_IN_16_DIGITS in bta/bta_api.h*/ 52 typedef uint16_t esp_spp_sec_t; 53 54 typedef enum { 55 ESP_SPP_SUCCESS = 0, /*!< Successful operation. */ 56 ESP_SPP_FAILURE, /*!< Generic failure. */ 57 ESP_SPP_BUSY, /*!< Temporarily can not handle this request. */ 58 ESP_SPP_NO_DATA, /*!< No data */ 59 ESP_SPP_NO_RESOURCE, /*!< No more resource */ 60 ESP_SPP_NEED_INIT, /*!< SPP module shall init first */ 61 ESP_SPP_NEED_DEINIT, /*!< SPP module shall deinit first */ 62 ESP_SPP_NO_CONNECTION, /*!< Connection may have been closed */ 63 ESP_SPP_NO_SERVER, /*!< No SPP server */ 64 } esp_spp_status_t; 65 66 typedef enum { 67 ESP_SPP_ROLE_MASTER = 0, /*!< Role: master */ 68 ESP_SPP_ROLE_SLAVE = 1, /*!< Role: slave */ 69 } esp_spp_role_t; 70 71 typedef enum { 72 ESP_SPP_MODE_CB = 0, /*!< When data is coming, a callback will come with data */ 73 ESP_SPP_MODE_VFS = 1, /*!< Use VFS to write/read data */ 74 } esp_spp_mode_t; 75 76 /** 77 * @brief SPP configuration parameters 78 */ 79 typedef struct { 80 esp_spp_mode_t mode; /*!< Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. */ 81 bool enable_l2cap_ertm; /*!< Enable/disable Logical Link Control and Adaptation Layer Protocol enhanced retransmission mode. */ 82 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. */ 83 } esp_spp_cfg_t; 84 85 /** 86 * @brief SPP callback function events 87 */ 88 typedef enum { 89 ESP_SPP_INIT_EVT = 0, /*!< When SPP is initialized, the event comes */ 90 ESP_SPP_UNINIT_EVT = 1, /*!< When SPP is deinitialized, the event comes */ 91 ESP_SPP_DISCOVERY_COMP_EVT = 8, /*!< When SDP discovery complete, the event comes */ 92 ESP_SPP_OPEN_EVT = 26, /*!< When SPP Client connection open, the event comes */ 93 ESP_SPP_CLOSE_EVT = 27, /*!< When SPP connection closed, the event comes */ 94 ESP_SPP_START_EVT = 28, /*!< When SPP server started, the event comes */ 95 ESP_SPP_CL_INIT_EVT = 29, /*!< When SPP client initiated a connection, the event comes */ 96 ESP_SPP_DATA_IND_EVT = 30, /*!< When SPP connection received data, the event comes, only for ESP_SPP_MODE_CB */ 97 ESP_SPP_CONG_EVT = 31, /*!< When SPP connection congestion status changed, the event comes, only for ESP_SPP_MODE_CB */ 98 ESP_SPP_WRITE_EVT = 33, /*!< When SPP write operation completes, the event comes, only for ESP_SPP_MODE_CB */ 99 ESP_SPP_SRV_OPEN_EVT = 34, /*!< When SPP Server connection open, the event comes */ 100 ESP_SPP_SRV_STOP_EVT = 35, /*!< When SPP server stopped, the event comes */ 101 ESP_SPP_VFS_REGISTER_EVT = 36, /*!< When SPP VFS register, the event comes */ 102 ESP_SPP_VFS_UNREGISTER_EVT = 37, /*!< When SPP VFS unregister, the event comes */ 103 } esp_spp_cb_event_t; 104 105 106 /** 107 * @brief SPP callback parameters union 108 */ 109 typedef union { 110 /** 111 * @brief SPP_INIT_EVT 112 */ 113 struct spp_init_evt_param { 114 esp_spp_status_t status; /*!< status */ 115 } init; /*!< SPP callback param of SPP_INIT_EVT */ 116 117 /** 118 * @brief SPP_UNINIT_EVT 119 */ 120 struct spp_uninit_evt_param { 121 esp_spp_status_t status; /*!< status */ 122 } uninit; /*!< SPP callback param of SPP_UNINIT_EVT */ 123 124 /** 125 * @brief SPP_DISCOVERY_COMP_EVT 126 */ 127 struct spp_discovery_comp_evt_param { 128 esp_spp_status_t status; /*!< status */ 129 uint8_t scn_num; /*!< The num of scn_num */ 130 uint8_t scn[ESP_SPP_MAX_SCN]; /*!< channel # */ 131 const char *service_name[ESP_SPP_MAX_SCN]; /*!< service_name */ 132 } disc_comp; /*!< SPP callback param of SPP_DISCOVERY_COMP_EVT */ 133 134 /** 135 * @brief ESP_SPP_OPEN_EVT 136 */ 137 struct spp_open_evt_param { 138 esp_spp_status_t status; /*!< status */ 139 uint32_t handle; /*!< The connection handle */ 140 int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */ 141 esp_bd_addr_t rem_bda; /*!< The peer address */ 142 } open; /*!< SPP callback param of ESP_SPP_OPEN_EVT */ 143 144 /** 145 * @brief ESP_SPP_SRV_OPEN_EVT 146 */ 147 struct spp_srv_open_evt_param { 148 esp_spp_status_t status; /*!< status */ 149 uint32_t handle; /*!< The connection handle */ 150 uint32_t new_listen_handle; /*!< The new listen handle */ 151 int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */ 152 esp_bd_addr_t rem_bda; /*!< The peer address */ 153 } srv_open; /*!< SPP callback param of ESP_SPP_SRV_OPEN_EVT */ 154 /** 155 * @brief ESP_SPP_CLOSE_EVT 156 */ 157 struct spp_close_evt_param { 158 esp_spp_status_t status; /*!< status */ 159 uint32_t port_status; /*!< PORT status */ 160 uint32_t handle; /*!< The connection handle */ 161 bool async; /*!< FALSE, if local initiates disconnect */ 162 } close; /*!< SPP callback param of ESP_SPP_CLOSE_EVT */ 163 164 /** 165 * @brief ESP_SPP_START_EVT 166 */ 167 struct spp_start_evt_param { 168 esp_spp_status_t status; /*!< status */ 169 uint32_t handle; /*!< The connection handle */ 170 uint8_t sec_id; /*!< security ID used by this server */ 171 uint8_t scn; /*!< Server channel number */ 172 bool use_co; /*!< TRUE to use co_rfc_data */ 173 } start; /*!< SPP callback param of ESP_SPP_START_EVT */ 174 175 /** 176 * @brief ESP_SPP_SRV_STOP_EVT 177 */ 178 struct spp_srv_stop_evt_param { 179 esp_spp_status_t status; /*!< status */ 180 uint8_t scn; /*!< Server channel number */ 181 } srv_stop; /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */ 182 183 /** 184 * @brief ESP_SPP_CL_INIT_EVT 185 */ 186 struct spp_cl_init_evt_param { 187 esp_spp_status_t status; /*!< status */ 188 uint32_t handle; /*!< The connection handle */ 189 uint8_t sec_id; /*!< security ID used by this server */ 190 bool use_co; /*!< TRUE to use co_rfc_data */ 191 } cl_init; /*!< SPP callback param of ESP_SPP_CL_INIT_EVT */ 192 193 /** 194 * @brief ESP_SPP_WRITE_EVT 195 */ 196 struct spp_write_evt_param { 197 esp_spp_status_t status; /*!< status */ 198 uint32_t handle; /*!< The connection handle */ 199 int len; /*!< The length of the data written. */ 200 bool cong; /*!< congestion status */ 201 } write; /*!< SPP callback param of ESP_SPP_WRITE_EVT */ 202 203 /** 204 * @brief ESP_SPP_DATA_IND_EVT 205 */ 206 struct spp_data_ind_evt_param { 207 esp_spp_status_t status; /*!< status */ 208 uint32_t handle; /*!< The connection handle */ 209 uint16_t len; /*!< The length of data */ 210 uint8_t *data; /*!< The data received */ 211 } data_ind; /*!< SPP callback param of ESP_SPP_DATA_IND_EVT */ 212 213 /** 214 * @brief ESP_SPP_CONG_EVT 215 */ 216 struct spp_cong_evt_param { 217 esp_spp_status_t status; /*!< status */ 218 uint32_t handle; /*!< The connection handle */ 219 bool cong; /*!< TRUE, congested. FALSE, uncongested */ 220 } cong; /*!< SPP callback param of ESP_SPP_CONG_EVT */ 221 222 /** 223 * @brief ESP_SPP_VFS_REGISTER_EVT 224 */ 225 struct spp_vfs_register_evt_param { 226 esp_spp_status_t status; /*!< status */ 227 } vfs_register; /*!< SPP callback param of ESP_SPP_VFS_REGISTER_EVT */ 228 229 /** 230 * @brief ESP_SPP_VFS_UNREGISTER_EVT 231 */ 232 struct spp_vfs_unregister_evt_param { 233 esp_spp_status_t status; /*!< status */ 234 } vfs_unregister; /*!< SPP callback param of ESP_SPP_VFS_UNREGISTER_EVT */ 235 } esp_spp_cb_param_t; /*!< SPP callback parameter union type */ 236 237 /** 238 * @brief SPP callback function type. 239 * When handle ESP_SPP_DATA_IND_EVT, it is strongly recommended to cache incoming data, and process them in 240 * other lower priority application task rather than in this callback directly. 241 * 242 * @param event: Event type 243 * @param param: Point to callback parameter, currently is union type 244 */ 245 typedef void (*esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param); 246 247 /** 248 * @brief This function is called to init callbacks with SPP module. 249 * 250 * @param[in] callback: pointer to the init callback function. 251 * 252 * @return 253 * - ESP_OK: success 254 * - other: failed 255 */ 256 esp_err_t esp_spp_register_callback(esp_spp_cb_t callback); 257 258 /** 259 * @brief This function is called to init SPP module. 260 * When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. 261 * This function should be called after esp_bluedroid_enable() completes successfully. 262 * 263 * @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. 264 * 265 * @return 266 * - ESP_OK: success 267 * - other: failed 268 */ 269 esp_err_t esp_spp_init(esp_spp_mode_t mode) __attribute__((deprecated("Please use esp_spp_enhanced_init"))); 270 271 272 /** 273 * @brief This function is called to init SPP module. 274 * When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. 275 * This function should be called after esp_bluedroid_enable() completes successfully. 276 * 277 * @param[in] cfg: SPP configuration. 278 * 279 * @note The member variable enable_l2cap_etrm in esp_spp_cfg_t can affect all L2CAP channel 280 * configurations of the upper layer RFCOMM protocol. 281 * 282 * @return 283 * - ESP_OK: success 284 * - other: failed 285 */ 286 esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg); 287 288 /** 289 * @brief This function is called to uninit SPP module. 290 * The operation will close all active SPP connection first, then the callback function will be called 291 * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. 292 * When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT. 293 * This function should be called after esp_spp_init()/esp_spp_enhanced_init() completes successfully. 294 * 295 * @return 296 * - ESP_OK: success 297 * - other: failed 298 */ 299 esp_err_t esp_spp_deinit(void); 300 301 302 /** 303 * @brief This function is called to performs service discovery for the services provided by the given peer device. 304 * When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT. 305 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 306 * 307 * @param[in] bd_addr: Remote device bluetooth device address. 308 * 309 * @return 310 * - ESP_OK: success 311 * - other: failed 312 */ 313 esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr); 314 315 /** 316 * @brief This function makes an SPP connection to a remote BD Address. 317 * When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT. 318 * When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT. 319 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 320 * 321 * @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only. 322 * @param[in] role: Master or slave. 323 * @param[in] remote_scn: Remote device bluetooth device SCN. 324 * @param[in] peer_bd_addr: Remote device bluetooth device address. 325 * 326 * @return 327 * - ESP_OK: success 328 * - other: failed 329 */ 330 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); 331 332 /** 333 * @brief This function closes an SPP connection. 334 * When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT. 335 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 336 * 337 * @param[in] handle: The connection handle. 338 * 339 * @return 340 * - ESP_OK: success 341 * - other: failed 342 */ 343 esp_err_t esp_spp_disconnect(uint32_t handle); 344 345 /** 346 * @brief This function create a SPP server and starts listening for an 347 * SPP connection request from a remote Bluetooth device. 348 * When the server is started successfully, the callback is called with ESP_SPP_START_EVT. 349 * When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT. 350 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 351 * 352 * @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only. 353 * @param[in] role: Master or slave. 354 * @param[in] local_scn: The specific channel you want to get. 355 * If channel is 0, means get any channel. 356 * @param[in] name: Server's name. 357 * 358 * @return 359 * - ESP_OK: success 360 * - other: failed 361 */ 362 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); 363 364 /** 365 * @brief This function stops all SPP servers. 366 * The operation will close all active SPP connection first, then the callback function will be called 367 * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. 368 * When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. 369 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 370 * 371 * @return 372 * - ESP_OK: success 373 * - other: failed 374 */ 375 376 esp_err_t esp_spp_stop_srv(void); 377 378 /** 379 * @brief This function stops a specific SPP server. 380 * The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called 381 * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. 382 * When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. 383 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 384 * 385 * @param[in] scn: Server channel number. 386 * 387 * @return 388 * - ESP_OK: success 389 * - other: failed 390 */ 391 esp_err_t esp_spp_stop_srv_scn(uint8_t scn); 392 393 /** 394 * @brief This function is used to write data, only for ESP_SPP_MODE_CB. 395 * When this function need to be called repeatedly, it is strongly recommended to call this function again after 396 * the previous event ESP_SPP_WRITE_EVT is received and the parameter 'cong' is equal to false. If the previous event 397 * ESP_SPP_WRITE_EVT with parameter 'cong' is equal to true, the function can only be called again when the event 398 * ESP_SPP_CONG_EVT with parameter 'cong' equal to false is received. 399 * This function must be called after an connection between initiator and acceptor has been established. 400 * 401 * @param[in] handle: The connection handle. 402 * @param[in] len: The length of the data written. 403 * @param[in] p_data: The data written. 404 * 405 * @return 406 * - ESP_OK: success 407 * - other: failed 408 */ 409 esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data); 410 411 412 /** 413 * @brief This function is used to register VFS. 414 * For now, SPP only supports write, read and close. 415 * When the operation is completed, the callback function will be called with ESP_SPP_VFS_REGISTER_EVT. 416 * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). 417 * 418 * @return 419 * - ESP_OK: success 420 * - other: failed 421 */ 422 esp_err_t esp_spp_vfs_register(void); 423 424 /** 425 * @brief This function is used to unregister VFS. 426 * When the operation is completed, the callback function will be called with ESP_SPP_VFS_UNREGISTER_EVT. 427 * This function must be called after esp_spp_vfs_register() successful and before esp_spp_deinit(). 428 * 429 * @return 430 * - ESP_OK: success 431 * - other: failed 432 */ 433 esp_err_t esp_spp_vfs_unregister(void); 434 435 #ifdef __cplusplus 436 } 437 #endif 438 439 #endif ///__ESP_SPP_API_H__ 440