1| Supported Targets | ESP32 |
2| ----------------- | ----- |
3
4# ESP-IDF BT-SPP-INITATOR Example
5
6This example is to show how to use the APIs of **Serial Port Protocol** (**SPP**) to create an SPP initiator which performs as a client. we aggregate **Secure Simple Pair** (**SSP**) into this example to show how to use SPP when creating your own APPs. We also provide the example `bt_spp_acceptor` or the example `bt_spp_vfs_acceptor` to create an SPP acceptor which performs as a server. In fact, you can create SPP acceptors and SPP initiators on a single device at the same time.
7
8## How to use example
9
10### Hardware Required
11
12This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate the example, you should be connect to an SPP acceptor running on a smartphone, a computer or on another ESP32 development board.
13
14### Configure the project
151. Open the project configuration menu:
16```
17idf.py menuconfig
18```
19
202. Enable the SPP functionality by choosing the path as following:
21
22`Component config --> Bluetooth --> Bluedroid Options --> SPP`.
23
243. SSP is enabled as default in this example. If you prefer the legacy pairing, you can disable it in the following path.
25
26`Component config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`.
27
28
29### Build and Flash
30
31Build the project and flash it to the board, then run monitor tool to view serial output:
32
33```
34idf.py -p PORT flash monitor
35```
36
37(Replace PORT with the name of the serial port to use.)
38
39(To exit the serial monitor, type ``Ctrl-]``.)
40
41See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
42
43## Example Description
44
45After the program starts, the example will initiate a Bluetooth discovery procedure and filter out the peer device by the name in the EIR(Extended Inquiry Response). After discovering the SPP service, it will connect to the SPP acceptor and send data. The example will calculate the data rate or print the sent data after the SPP connection is established.
46### Example Output
47
48When you run this example and the IO capability is `ESP_IO_CAP_IO` or `ESP_IO_CAP_IN` , the commands help table prints the following at the very beginning:
49
50```
51########################################################################
52Supported commands are as follows, arguments are embraced with < and >
53spp h;                -- show command manual
54
55Use this cmmand table if the IO Capability of local device set as IO_CAP_IO.
56spp ok;               -- manual Numeric Confirmation.
57
58Use this cmmand table if the IO Capability of local device set as IO_CAP_IN.
59spp key <auth key>;   -- manual Passkey. (e.g. spp key 136245;)
60
61########################################################################
62```
63
64**Note:**
65
66- Only after SPP service is initialized and a service level connection exists between an Initiator and Acceptor device, could other commands be available.
67- This command help table will print out in monitor whenever you type `spp h;` or if you input a command that is not required by the command parse rule.
68
69- Commands should always start with `spp` and end with `;` or the example will not responds.
70
71- The command you typed will not echo in monitor.
72
73### Situation under `ESP_IO_CAP_IN`
74
75The log in terminal will indicate you to input the passkey to initiate the connection of SPP.
76
77```
78I (2244) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
79I (2244) SPP_INITIATOR_DEMO: ......
80I (2394) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
81I (2404) SPP_INITIATOR_DEMO: ......
82I (2404) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
83I (2414) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
84I (3274) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT status=0 scn_num=1
85I (3284) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT
86I (3454) SPP_INITIATOR_DEMO: ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!
87W (3454) SPP_INITIATOR_DEMO: To input the key, type `spp key xxxxxx;`
88```
89
90### Situation under `ESP_IO_CAP_IO`
91
92The log in terminal will indicate you to confirm the number to initiate the connection of SPP.
93
94```
95I (2342) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
96I (2342) SPP_INITIATOR_DEMO: 30 ae a4 80 18 32
97I (2342) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
98I (2352) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
99I (3212) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT status=0 scn_num=1
100I (3222) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT
101I (3392) SPP_INITIATOR_DEMO: ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: 864115
102W (3392) SPP_INITIATOR_DEMO: To confirm the value, type `spp ok;`
103```
104
105**Note:**
106
107Whether you should passkey or confirm the number also depends on the IO capability of the peer device. And whether the two device are already paired before.
108
109## Troubleshouting
110
111- Set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code (should be same with `bt_spp_acceptor`, if the peer device runs it). When setting `SPP_SHOW_MODE` as `SPP_SHOW_DATA`, if the data rate is too high or the data length is too long, it is strongly recommended to process them in other lower priority application task rather than in this callback directly. Since the printing takes too much time, and it may stuck the Bluetooth stack.
112
113- We haven't do the same update to the example `bt_spp_acceptor` for the sake of reducing the size of ESP_IDF, but transplanting of input module is supported.
114
115## Example Breakdown
116
117To clearly show how the SSP aggregate with the SPP , we use the Commands and Effects scheme to illustrate the process of secure paring and connection establishment.
118
119- The example will respond to user command through UART console. Please go to `console_uart.c`  for the configuration details.
120
121- If you want to update the command table, please refer to `app_spp_msg_set.c`.
122
123- If you want to update the command parse rules, please refer to `app_spp_msg_prs.c`.
124
125## FAQ
126Q: How to change the process of SSP?
127A: Users can set the IO Capability and Security Mask for their device (fixed Security Mode, Security Mode 4). In short, the Security Mask sets the security level for authentication stage and the IO Capability determines the way of user interaction during pairing. The default Security Mask of this example is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](../bt_spp_acceptor/ESP32_SSP.md).
128
129Q: How can we reach the maximum throughput when using SPP?
130A: The default MTU size of classic Bluetooth SPP on ESP32 is 990 bytes, and higher throughput can be achieved in the case that data chunck size is close to the MTU size or multiple of MTU size. For example, sending 100 bytes data per second is much better than sending 10 bytes every 100 milliseconds.
131
132Q: What is the difference between the event `ESP_SPP_CONG_EVT` and the parameter `cong` of the event `ESP_SPP_WRITE_EVT`?
133A: The event `ESP_SPP_CONG_EVT` shows the changing status from `congest` to `uncongest`, or form `uncongest` to `congest`. Congestion can have many causes, such as using out of the credit which is sent by peer, reaching the high watermark of the Tx buffer, the congestion at Bluetooth L2CAP layer and so on. The parameter `cong` of the event `ESP_SPP_WRITE_EVT` shows a snapshot of the state of the flow control manager after the write operation is completed. The user needs to carefully consider retransmitting or continuing to write according to these two events. The ESP32 offers an VFS mode of SPP which hides the details of retransmitting, but it will block the caller and is not more efficient than the callback mode.
134
135Q: How many SPP clients does ESP32 support?
136A: The ESP32 supports maximum 8 SPP clients, which including virtual SPP connections. Virtual SPP connection means that SPP clients can connect to the different SPP servers running on the same peer device. However the number of SPP clients (excluding virtual connections) shall not exceed the number of Bluetooth ACL connections.
137