1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef __ESP_SPP_API_H__
16 #define __ESP_SPP_API_H__
17 
18 #include "esp_err.h"
19 #include "esp_bt_defs.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 typedef enum {
26     ESP_SPP_SUCCESS   = 0,          /*!< Successful operation. */
27     ESP_SPP_FAILURE,                /*!< Generic failure. */
28     ESP_SPP_BUSY,                   /*!< Temporarily can not handle this request. */
29     ESP_SPP_NO_DATA,                /*!< No data */
30     ESP_SPP_NO_RESOURCE,            /*!< No more resource */
31     ESP_SPP_NEED_INIT,              /*!< SPP module shall init first */
32     ESP_SPP_NEED_DEINIT,            /*!< SPP module shall deinit first */
33     ESP_SPP_NO_CONNECTION,          /*!< Connection may have been closed */
34     ESP_SPP_NO_SERVER,              /*!< No SPP server */
35 } esp_spp_status_t;
36 
37 /* Security Setting Mask
38 Use these three mask mode:
39 1. ESP_SPP_SEC_NONE
40 2. ESP_SPP_SEC_AUTHENTICATE
41 3. (ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE)
42 */
43 #define ESP_SPP_SEC_NONE            0x0000    /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */
44 #define ESP_SPP_SEC_AUTHORIZE       0x0001    /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/
45 #define ESP_SPP_SEC_AUTHENTICATE    0x0012    /*!< Authentication required.  relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/
46 #define ESP_SPP_SEC_ENCRYPT         0x0024    /*!< Encryption required.  relate to BTA_SEC_ENCRYPT in bta/bta_api.h*/
47 #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*/
48 #define ESP_SPP_SEC_MITM            0x3000    /*!< Man-In-The_Middle protection  relate to BTA_SEC_MITM in bta/bta_api.h*/
49 #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*/
50 typedef uint16_t esp_spp_sec_t;
51 
52 typedef enum {
53     ESP_SPP_ROLE_MASTER     = 0,          /*!< Role: master */
54     ESP_SPP_ROLE_SLAVE      = 1,          /*!< Role: slave */
55 } esp_spp_role_t;
56 
57 typedef enum {
58     ESP_SPP_MODE_CB         = 0,          /*!< When data is coming, a callback will come with data */
59     ESP_SPP_MODE_VFS        = 1,          /*!< Use VFS to write/read data */
60 } esp_spp_mode_t;
61 
62 #define ESP_SPP_MAX_MTU                 (3*330)     /*!< SPP max MTU */
63 #define ESP_SPP_MAX_SCN                 31          /*!< SPP max SCN */
64 /**
65  * @brief SPP callback function events
66  */
67 typedef enum {
68     ESP_SPP_INIT_EVT                    = 0,                /*!< When SPP is inited, the event comes */
69     ESP_SPP_UNINIT_EVT                  = 1,                /*!< When SPP is uninited, the event comes */
70     ESP_SPP_DISCOVERY_COMP_EVT          = 8,                /*!< When SDP discovery complete, the event comes */
71     ESP_SPP_OPEN_EVT                    = 26,               /*!< When SPP Client connection open, the event comes */
72     ESP_SPP_CLOSE_EVT                   = 27,               /*!< When SPP connection closed, the event comes */
73     ESP_SPP_START_EVT                   = 28,               /*!< When SPP server started, the event comes */
74     ESP_SPP_CL_INIT_EVT                 = 29,               /*!< When SPP client initiated a connection, the event comes */
75     ESP_SPP_DATA_IND_EVT                = 30,               /*!< When SPP connection received data, the event comes, only for ESP_SPP_MODE_CB */
76     ESP_SPP_CONG_EVT                    = 31,               /*!< When SPP connection congestion status changed, the event comes, only for ESP_SPP_MODE_CB */
77     ESP_SPP_WRITE_EVT                   = 33,               /*!< When SPP write operation completes, the event comes, only for ESP_SPP_MODE_CB */
78     ESP_SPP_SRV_OPEN_EVT                = 34,               /*!< When SPP Server connection open, the event comes */
79     ESP_SPP_SRV_STOP_EVT                = 35,               /*!< When SPP server stopped, the event comes */
80 } esp_spp_cb_event_t;
81 
82 
83 /**
84  * @brief SPP callback parameters union
85  */
86 typedef union {
87     /**
88      * @brief SPP_INIT_EVT
89      */
90     struct spp_init_evt_param {
91         esp_spp_status_t    status;         /*!< status */
92     } init;                                 /*!< SPP callback param of SPP_INIT_EVT */
93 
94     /**
95      * @brief SPP_UNINIT_EVT
96      */
97     struct spp_uninit_evt_param {
98         esp_spp_status_t    status;         /*!< status */
99     } uninit;                               /*!< SPP callback param of SPP_UNINIT_EVT */
100 
101     /**
102      * @brief SPP_DISCOVERY_COMP_EVT
103      */
104     struct spp_discovery_comp_evt_param {
105         esp_spp_status_t status;                   /*!< status */
106         uint8_t scn_num;                           /*!< The num of scn_num */
107         uint8_t scn[ESP_SPP_MAX_SCN];              /*!< channel # */
108         const char *service_name[ESP_SPP_MAX_SCN]; /*!< service_name */
109     } disc_comp;                            /*!< SPP callback param of SPP_DISCOVERY_COMP_EVT */
110 
111     /**
112      * @brief ESP_SPP_OPEN_EVT
113      */
114     struct spp_open_evt_param {
115         esp_spp_status_t    status;         /*!< status */
116         uint32_t            handle;         /*!< The connection handle */
117         int                 fd;             /*!< The file descriptor only for ESP_SPP_MODE_VFS */
118         esp_bd_addr_t       rem_bda;        /*!< The peer address */
119     } open;                                 /*!< SPP callback param of ESP_SPP_OPEN_EVT */
120 
121     /**
122      * @brief ESP_SPP_SRV_OPEN_EVT
123      */
124     struct spp_srv_open_evt_param {
125         esp_spp_status_t    status;         /*!< status */
126         uint32_t            handle;         /*!< The connection handle */
127         uint32_t            new_listen_handle;  /*!< The new listen handle */
128         int                 fd;             /*!< The file descriptor only for ESP_SPP_MODE_VFS */
129         esp_bd_addr_t       rem_bda;        /*!< The peer address */
130     } srv_open;                             /*!< SPP callback param of ESP_SPP_SRV_OPEN_EVT */
131     /**
132      * @brief ESP_SPP_CLOSE_EVT
133      */
134     struct spp_close_evt_param {
135         esp_spp_status_t    status;         /*!< status */
136         uint32_t            port_status;    /*!< PORT status */
137         uint32_t            handle;         /*!< The connection handle */
138         bool                async;          /*!< FALSE, if local initiates disconnect */
139     } close;                                /*!< SPP callback param of ESP_SPP_CLOSE_EVT */
140 
141     /**
142      * @brief ESP_SPP_START_EVT
143      */
144     struct spp_start_evt_param {
145         esp_spp_status_t    status;         /*!< status */
146         uint32_t            handle;         /*!< The connection handle */
147         uint8_t             sec_id;         /*!< security ID used by this server */
148         uint8_t             scn;            /*!< Server channel number */
149         bool                use_co;         /*!< TRUE to use co_rfc_data */
150     } start;                                /*!< SPP callback param of ESP_SPP_START_EVT */
151 
152     /**
153      * @brief ESP_SPP_SRV_STOP_EVT
154      */
155     struct spp_srv_stop_evt_param {
156         esp_spp_status_t    status;         /*!< status */
157         uint8_t             scn;            /*!< Server channel number */
158     } srv_stop;                             /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */
159 
160     /**
161      * @brief ESP_SPP_CL_INIT_EVT
162      */
163     struct spp_cl_init_evt_param {
164         esp_spp_status_t    status;         /*!< status */
165         uint32_t            handle;         /*!< The connection handle */
166         uint8_t             sec_id;         /*!< security ID used by this server */
167         bool                use_co;         /*!< TRUE to use co_rfc_data */
168     } cl_init;                              /*!< SPP callback param of ESP_SPP_CL_INIT_EVT */
169 
170     /**
171      * @brief ESP_SPP_WRITE_EVT
172      */
173     struct spp_write_evt_param {
174         esp_spp_status_t    status;         /*!< status */
175         uint32_t            handle;         /*!< The connection handle */
176         int                 len;            /*!< The length of the data written. */
177         bool                cong;           /*!< congestion status */
178     } write;                                /*!< SPP callback param of ESP_SPP_WRITE_EVT */
179 
180     /**
181      * @brief ESP_SPP_DATA_IND_EVT
182      */
183     struct spp_data_ind_evt_param {
184         esp_spp_status_t    status;         /*!< status */
185         uint32_t            handle;         /*!< The connection handle */
186         uint16_t            len;            /*!< The length of data */
187         uint8_t             *data;          /*!< The data received */
188     } data_ind;                             /*!< SPP callback param of ESP_SPP_DATA_IND_EVT */
189 
190     /**
191      * @brief ESP_SPP_CONG_EVT
192      */
193     struct spp_cong_evt_param {
194         esp_spp_status_t    status;         /*!< status */
195         uint32_t            handle;         /*!< The connection handle */
196         bool                cong;           /*!< TRUE, congested. FALSE, uncongested */
197     } cong;                                 /*!< SPP callback param of ESP_SPP_CONG_EVT */
198 } esp_spp_cb_param_t;                       /*!< SPP callback parameter union type */
199 
200 /**
201  * @brief       SPP callback function type.
202  *              When handle ESP_SPP_DATA_IND_EVT, it is strongly recommended to cache incoming data, and process them in
203  *              other lower priority application task rather than in this callback directly.
204  *
205  * @param       event:      Event type
206  * @param       param:      Point to callback parameter, currently is union type
207  */
208 typedef void (esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
209 
210 /**
211  * @brief       This function is called to init callbacks with SPP module.
212  *
213  * @param[in]   callback:   pointer to the init callback function.
214  *
215  * @return
216  *              - ESP_OK: success
217  *              - other: failed
218  */
219 esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
220 
221 /**
222  * @brief       This function is called to init SPP module.
223  *              When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT.
224  *              This function should be called after esp_bluedroid_enable() completes successfully.
225  *
226  * @param[in]   mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS.
227  *
228  * @return
229  *              - ESP_OK: success
230  *              - other: failed
231  */
232 esp_err_t esp_spp_init(esp_spp_mode_t mode);
233 
234 /**
235  * @brief       This function is called to uninit SPP module.
236  *              The operation will close all active SPP connection first, then the callback function will be called
237  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
238  *              When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT.
239  *              This function should be called after esp_spp_init() completes successfully.
240  *
241  * @return
242  *              - ESP_OK: success
243  *              - other: failed
244  */
245 esp_err_t esp_spp_deinit(void);
246 
247 
248 /**
249  * @brief       This function is called to performs service discovery for the services provided by the given peer device.
250  *              When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT.
251  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
252  *
253  * @param[in]   bd_addr:   Remote device bluetooth device address.
254  *
255  * @return
256  *              - ESP_OK: success
257  *              - other: failed
258  */
259 esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
260 
261 /**
262  * @brief       This function makes an SPP connection to a remote BD Address.
263  *              When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT.
264  *              When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT.
265  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
266  *
267  * @param[in]   sec_mask:     Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
268  * @param[in]   role:         Master or slave.
269  * @param[in]   remote_scn:   Remote device bluetooth device SCN.
270  * @param[in]   peer_bd_addr: Remote device bluetooth device address.
271  *
272  * @return
273  *              - ESP_OK: success
274  *              - other: failed
275  */
276 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);
277 
278 /**
279  * @brief       This function closes an SPP connection.
280  *              When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT.
281  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
282  *
283  * @param[in]   handle:    The connection handle.
284  *
285  * @return
286  *              - ESP_OK: success
287  *              - other: failed
288  */
289 esp_err_t esp_spp_disconnect(uint32_t handle);
290 
291 /**
292  * @brief       This function create a SPP server and starts listening for an
293  *              SPP connection request from a remote Bluetooth device.
294  *              When the server is started successfully, the callback is called with ESP_SPP_START_EVT.
295  *              When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT.
296  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
297  *
298  * @param[in]   sec_mask:     Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
299  * @param[in]   role:         Master or slave.
300  * @param[in]   local_scn:    The specific channel you want to get.
301  *                            If channel is 0, means get any channel.
302  * @param[in]   name:         Server's name.
303  *
304  * @return
305  *              - ESP_OK: success
306  *              - other: failed
307  */
308 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);
309 
310 /**
311  * @brief       This function stops all SPP servers.
312  *              The operation will close all active SPP connection first, then the callback function will be called
313  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
314  *              When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
315  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
316  *
317  * @return
318  *              - ESP_OK: success
319  *              - other: failed
320  */
321 
322 esp_err_t esp_spp_stop_srv(void);
323 
324 /**
325  * @brief       This function stops a specific SPP server.
326  *              The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called
327  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
328  *              When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
329  *              This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
330  *
331  * @param[in]   scn:         Server channel number.
332  *
333  * @return
334  *              - ESP_OK: success
335  *              - other: failed
336  */
337 esp_err_t esp_spp_stop_srv_scn(uint8_t scn);
338 
339 /**
340  * @brief       This function is used to write data, only for ESP_SPP_MODE_CB.
341  *              When this function need to be called repeatedly, it is strongly recommended to call this function again after
342  *              the previous event ESP_SPP_WRITE_EVT is received and the parameter 'cong' is equal to false. If the previous event
343  *              ESP_SPP_WRITE_EVT with parameter 'cong' is equal to true, the function can only be called again when the event
344  *              ESP_SPP_CONG_EVT with parameter 'cong' equal to false is received.
345  *              This funciton must be called after an connection between initiator and acceptor has been established.
346  *
347  * @param[in]   handle: The connection handle.
348  * @param[in]   len:    The length of the data written.
349  * @param[in]   p_data: The data written.
350  *
351  * @return
352  *              - ESP_OK: success
353  *              - other: failed
354  */
355 esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
356 
357 
358 /**
359  * @brief       This function is used to register VFS.
360  *              For now, SPP only supports write, read and close.
361  *
362  * @return
363  *              - ESP_OK: success
364  *              - other: failed
365  */
366 esp_err_t esp_spp_vfs_register(void);
367 
368 #ifdef __cplusplus
369 }
370 #endif
371 
372 #endif ///__ESP_SPP_API_H__
373