BT CLASSIC INITIATOR strange behavior after connect / reconnect

TomasCZ
Posts: 39
Joined: Tue Apr 25, 2023 5:19 am

BT CLASSIC INITIATOR strange behavior after connect / reconnect

Postby TomasCZ » Fri Dec 22, 2023 9:33 pm

Hi guys, could someone help me. changed the BR_CALSSIC- INITIATOR and ACCEPTOR code based on my futore needs. I just changed the code when MASTER sends a hello message to SLAVE and SLAVE to MASTER. I also add some code make reconnect if the connection is lost for some reason. If the reconnect is successful within ca 20 sec it works OK. But if it takes more then 20 sec there is some kind of timeout and it is needed to start discovery again. Everything seemst to work both board send and receive the message, the BT status LEDs work well but I recever errors and 3-4x ESP_BT_GAP_DISC_STATE_CHANGED_EVT consecutively and I can't figure out why.

My MASTER terminal:

Code: Select all

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6940
ho 0 tail 12 room 4
load:0x40078000,len:15500
load:0x40080400,len:3844
0x40080400: _init at ??:?

entry 0x4008064c
I (29) boot: ESP-IDF v5.0.2 2nd stage bootloader
I (29) boot: compile time 11:29:06
I (29) boot: chip revision: v3.0
I (32) boot.esp32: SPI Speed      : 40MHz
I (37) boot.esp32: SPI Mode       : DIO
I (41) boot.esp32: SPI Flash Size : 2MB
I (46) boot: Enabling RNG early entropy source...
I (51) boot: Partition Table:
I (55) boot: ## Label            Usage          Type ST Offset   Length
I (62) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (70) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (77) boot:  2 factory          factory app      00 00 00010000 00100000
I (85) boot: End of partition table
I (89) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=1b8b0h (112816) map
I (138) esp_image: segment 1: paddr=0002b8d8 vaddr=3ffbdb60 size=04214h ( 16916) load
I (145) esp_image: segment 2: paddr=0002faf4 vaddr=40080000 size=00524h (  1316) load
I (146) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=6dc54h (449620) map
I (315) esp_image: segment 4: paddr=0009dc7c vaddr=40080524 size=18b18h (101144) load
I (369) boot: Loaded app from partition at offset 0x10000
I (369) boot: Disabling RNG early entropy source...
I (381) cpu_start: Pro cpu up.
I (381) cpu_start: Starting app cpu, entry point is 0x40081454
0x40081454: call_start_cpu1 at C:/Users/konec/esp/esp-idf/components/esp_system/port/cpu_start.c:141

I (367) cpu_start: App cpu up.
I (397) cpu_start: Pro cpu start user code
I (397) cpu_start: cpu freq: 160000000 Hz
I (397) cpu_start: Application information:
I (402) cpu_start: Project name:     BT_SPP_MASTER_v00-01
I (408) cpu_start: App version:      1
I (413) cpu_start: Compile time:     Dec 22 2023 11:28:30
I (419) cpu_start: ELF file SHA256:  afc26a0c4e5e045a...
Warning: checksum mismatch between flashed and built applications. Checksum of built application is dc5b3c2a9f640360416dbcbbff7a9388eecf3be72d708db51fa34cafb11d45d1
I (425) cpu_start: ESP-IDF:          v5.0.2
I (430) cpu_start: Min chip rev:     v0.0
I (434) cpu_start: Max chip rev:     v3.99 
I (439) cpu_start: Chip rev:         v3.0
I (444) heap_init: Initializing. RAM available for dynamic allocation:
I (451) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (457) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (463) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (469) heap_init: At 3FFC7D68 len 00018298 (96 KiB): DRAM
I (475) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (482) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (488) heap_init: At 4009903C len 00006FC4 (27 KiB): IRAM
I (496) spi_flash: detected chip: generic
I (499) spi_flash: flash io: dio
W (503) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (518) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (528) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (538) SPP_INITIATOR_DEMO: Init DATA LED completed
I (538) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (548) SPP_INITIATOR_DEMO: Init BT LED completed
I (568) BTDM_INIT: BT controller compile version [2c56073]
I (578) system_api: Base MAC address is not set
I (578) system_api: read default base MAC address from EFUSE
I (578) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (1238) SPP_INITIATOR_DEMO: ESP_SPP_INIT_EVT
I (1238) SPP_INITIATOR_DEMO: Own address:[70:b8:f6:5b:90:d6]
I (1248) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (1478) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (1478) SPP_INITIATOR_DEMO: 48 e7 29 c8 9c 8a
I (1478) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (1488) SPP_INITIATOR_DEMO: Peer device name: ESP_SPP_ACCEPTOR
I (1498) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (1498) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (1508) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (1518) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
W (1768) BT_HCI: hcif conn complete: hdl 0x81, st 0x0
I (1948) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT scn_num:1
I (1948) SPP_INITIATOR_DEMO: -- [0] scn:1 service_name:SPP_SERVER
I (1958) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT handle:129 sec_id:55
I (2058) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2058) SPP_INITIATOR_DEMO: 48 e7 29 c8 9c 8a
I (2058) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (2068) SPP_INITIATOR_DEMO: Peer device name: ESP_SPP_ACCEPTOR
I (2078) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2078) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2088) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2098) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2238) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT scn_num:1
I (2238) SPP_INITIATOR_DEMO: -- [0] scn:1 service_name:SPP_SERVER
E (2238) BT_RFCOMM: RFCOMM_CreateConnection - already opened state:1, RFC state:1, MCB state:5
E (2248) BT_APPL: bta_jv_rfcomm_connect, RFCOMM_CreateConnection failed
E (2258) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT status:1
I (2268) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2268) SPP_INITIATOR_DEMO: 48 e7 29 c8 9c 8a
I (2278) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (2278) SPP_INITIATOR_DEMO: Peer device name: ESP_SPP_ACCEPTOR
W (2298) BT_APPL: new conn_srvc id:26, app_id:1
W (2298) BT_APPL: bta_dm_pm_ssr conn_srvc id:26, app_id:1
W (2298) BT_APPL: bta_dm_pm_ssr:2, lat:1200
I (2308) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2308) SPP_INITIATOR_DEMO: ESP_SPP_OPEN_EVT handle:129 rem_bda:[48:e7:29:c8:9c:8a]
I (2318) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2328) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2338) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (2338) SPP_INITIATOR_DEMO: ESP_SPP_WRITE_EVT
I (2388) SPP_INITIATOR_DEMO: ESP_SPP_DATA_IND_EVT
I (2388) SPP_INITIATOR_DEMO: DATA LED ON
I (2388) SPP_INITIATOR_DEMO: ************************************Received data START***************************************************
I (2398) Received data (HEX): : 41 68 6f 6a 20 74 61 64 79 20 53 4c 41 56 45 
I (2408) SPP_INITIATOR_DEMO: Received data (TEXT): Ahoj tady SLAVE
I (2418) SPP_INITIATOR_DEMO: ************************************Received data END*****************************************************
I (2488) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT scn_num:1
I (2488) SPP_INITIATOR_DEMO: -- [0] scn:1 service_name:SPP_SERVER
E (2488) BT_RFCOMM: RFCOMM_CreateConnection - already opened state:2, RFC state:4, MCB state:5
E (2498) BT_APPL: bta_jv_rfcomm_connect, RFCOMM_CreateConnection failed
E (2508) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT status:1
I (2658) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2668) SPP_INITIATOR_DEMO: 48 e7 29 c8 9c 8a
I (2668) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (2668) SPP_INITIATOR_DEMO: Peer device name: ESP_SPP_ACCEPTOR
I (2678) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
W (7588) BT_HCI: hci cmd send: sniff: hdl 0x81, intv(400 800)
W (7588) BT_HCI: hcif mode change: hdl 0x81, mode 2, intv 800, status 0x0
W (9168) BT_HCI: hcif ssr evt: st 0x0, hdl 0x81, tx_lat 800 rx_lat 800
My SLAVE terminal:

Code: Select all

PS C:\Users\konec\ESP-IDF\BR_SPP_SLAVE_v00-01> set IDF_PATH=C:\Users\konec\esp\esp-idf
PS C:\Users\konec\ESP-IDF\BR_SPP_SLAVE_v00-01> c:\Espressif\python_env\idf5.0_py3.8_env\Scripts\python.exe C:\Users\konec\esp\esp-idf\tools\idf_monitor.py -p COM11 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 c:\Users\konec\ESP-IDF\BR_SPP_SLAVE_v00-01\build\BR_SPP_SLAVE_v00-01.elf
--- WARNING: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM11 instead...
--- idf_monitor on \\.\COM11 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6940
ho 0 tail 12 room 4
load:0x40078000,len:15500
load:0x40080400,len:3844
0x40080400: _init at ??:?

entry 0x4008064c
I (29) boot: ESP-IDF v5.0.2 2nd stage bootloader
I (29) boot: compile time 11:35:21
I (29) boot: chip revision: v3.0
I (32) boot.esp32: SPI Speed      : 40MHz
I (37) boot.esp32: SPI Mode       : DIO
I (41) boot.esp32: SPI Flash Size : 2MB
I (46) boot: Enabling RNG early entropy source...
I (51) boot: Partition Table:
I (55) boot: ## Label            Usage          Type ST Offset   Length
I (62) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (70) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (77) boot:  2 factory          factory app      00 00 00010000 00100000
I (85) boot: End of partition table
I (89) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=1b700h (112384) map
I (138) esp_image: segment 1: paddr=0002b728 vaddr=3ffbdb60 size=04214h ( 16916) load
I (145) esp_image: segment 2: paddr=0002f944 vaddr=40080000 size=006d4h (  1748) load
I (146) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=6d72ch (448300) map
I (314) esp_image: segment 4: paddr=0009d754 vaddr=400806d4 size=18968h (100712) load
I (368) boot: Loaded app from partition at offset 0x10000
I (368) boot: Disabling RNG early entropy source...
I (380) cpu_start: Pro cpu up.
I (380) cpu_start: Starting app cpu, entry point is 0x40081454
0x40081454: call_start_cpu1 at C:/Users/konec/esp/esp-idf/components/esp_system/port/cpu_start.c:141

I (0) cpu_start: App cpu up.
I (396) cpu_start: Pro cpu start user code
I (396) cpu_start: cpu freq: 160000000 Hz
I (396) cpu_start: Application information:
I (401) cpu_start: Project name:     BR_SPP_SLAVE_v00-01
I (407) cpu_start: App version:      1
I (412) cpu_start: Compile time:     Dec 22 2023 11:34:44
I (418) cpu_start: ELF file SHA256:  4df698889dac1c5c...
I (424) cpu_start: ESP-IDF:          v5.0.2
I (429) cpu_start: Min chip rev:     v0.0
I (433) cpu_start: Max chip rev:     v3.99
I (438) cpu_start: Chip rev:         v3.0
I (443) heap_init: Initializing. RAM available for dynamic allocation:
I (450) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (456) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (462) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (468) heap_init: At 3FFC7C58 len 000183A8 (96 KiB): DRAM
I (474) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (481) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (487) heap_init: At 4009903C len 00006FC4 (27 KiB): IRAM
I (495) spi_flash: detected chip: generic
I (498) spi_flash: flash io: dio
W (502) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (516) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (527) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (537) SPP_ACCEPTOR_DEMO: Init DATA LED completed
I (537) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (547) SPP_ACCEPTOR_DEMO: Init BT LED completed
I (577) BTDM_INIT: BT controller compile version [2c56073]
I (577) system_api: Base MAC address is not set
I (577) system_api: read default base MAC address from EFUSE
I (587) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (1237) SPP_ACCEPTOR_DEMO: ESP_SPP_INIT_EVT
I (1247) SPP_ACCEPTOR_DEMO: ESP_SPP_START_EVT handle:129 sec_id:55 scn:1
W (14947) BT_HCI: hcif conn complete: hdl 0x80, st 0x0
W (14957) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (15317) BT_APPL: new conn_srvc id:26, app_id:255
W (15317) BT_APPL: bta_dm_pm_ssr conn_srvc id:26, app_id:255
W (15317) BT_APPL: bta_dm_pm_ssr:2, lat:1200
I (15327) SPP_ACCEPTOR_DEMO: ESP_SPP_SRV_OPEN_EVT
I (15327) SPP_ACCEPTOR_DEMO: Remote device address: 70:b8:f6:5b:90:d6
I (15337) SPP_ACCEPTOR_DEMO: ESP_SPP_WRITE_EVT
I (15387) SPP_ACCEPTOR_DEMO: DATA LED ON
I (15387) SPP_ACCEPTOR_DEMO: ************************************Received data START***************************************************
I (15397) Received data (HEX): : 41 68 6f 6a 20 74 61 64 79 20 4d 41 53 54 45 52
I (15407) SPP_ACCEPTOR_DEMO: Received data (TEXT): Ahoj tady MASTER
I (15407) SPP_ACCEPTOR_DEMO: ************************************Received data END*****************************************************
W (20627) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
W (22237) BT_HCI: hcif ssr evt: st 0x0, hdl 0x80, tx_lat 800 rx_lat 800
W (135227) BT_RFCOMM: port_rfc_closed RFCOMM connection in server:1 state 2 closed: Peer connection failed (res: 16)
W (135237) BT_HCI: hcif disc complete: hdl 0x80, rsn 0x8
I (135237) SPP_ACCEPTOR_DEMO: ESP_SPP_CLOSE_EVT status:0 handle:129 close_by_remote:1
W (135907) BT_HCI: hcif conn complete: hdl 0x81, st 0x0
W (135907) BT_HCI: hcif link supv_to changed: hdl 0x81, supv_to 8000
W (136447) BT_APPL: new conn_srvc id:26, app_id:255
W (136447) BT_APPL: bta_dm_pm_ssr conn_srvc id:26, app_id:255
W (136447) BT_APPL: bta_dm_pm_ssr:2, lat:1200
I (136457) SPP_ACCEPTOR_DEMO: ESP_SPP_SRV_OPEN_EVT
I (136457) SPP_ACCEPTOR_DEMO: Remote device address: 70:b8:f6:5b:90:d6
I (136467) SPP_ACCEPTOR_DEMO: ESP_SPP_WRITE_EVT
I (136517) SPP_ACCEPTOR_DEMO: DATA LED ON
I (136517) SPP_ACCEPTOR_DEMO: ************************************Received data START***************************************************
I (136527) Received data (HEX): : 41 68 6f 6a 20 74 61 64 79 20 4d 41 53 54 45 52 
I (136537) SPP_ACCEPTOR_DEMO: Received data (TEXT): Ahoj tady MASTER
I (136547) SPP_ACCEPTOR_DEMO: ************************************Received data END*****************************************************
W (141767) BT_HCI: hcif mode change: hdl 0x81, mode 2, intv 800, status 0x0
W (143357) BT_HCI: hcif ssr evt: st 0x0, hdl 0x81, tx_lat 800 rx_lat 800
W (162357) BT_RFCOMM: port_rfc_closed RFCOMM connection in server:1 state 2 closed: Peer connection failed (res: 16)
W (162357) BT_HCI: hcif disc complete: hdl 0x81, rsn 0x8
I (162357) SPP_ACCEPTOR_DEMO: ESP_SPP_CLOSE_EVT status:0 handle:385 close_by_remote:1
W (164477) BT_HCI: hcif conn complete: hdl 0x80, st 0x0
W (164487) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (164957) BT_APPL: new conn_srvc id:26, app_id:255
W (164957) BT_APPL: bta_dm_pm_ssr conn_srvc id:26, app_id:255
W (164957) BT_APPL: bta_dm_pm_ssr:2, lat:1200
I (164957) SPP_ACCEPTOR_DEMO: ESP_SPP_SRV_OPEN_EVT
I (164967) SPP_ACCEPTOR_DEMO: Remote device address: 70:b8:f6:5b:90:d6
I (164977) SPP_ACCEPTOR_DEMO: ESP_SPP_WRITE_EVT
I (165087) SPP_ACCEPTOR_DEMO: DATA LED ON
I (165087) SPP_ACCEPTOR_DEMO: ************************************Received data START***************************************************
I (165097) Received data (HEX): : 41 68 6f 6a 20 74 61 64 79 20 4d 41 53 54 45 52 
I (165097) SPP_ACCEPTOR_DEMO: Received data (TEXT): Ahoj tady MASTER
I (165107) SPP_ACCEPTOR_DEMO: ************************************Received data END*****************************************************
W (170307) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
W (171887) BT_HCI: hcif ssr evt: st 0x0, hdl 0x80, tx_lat 800 rx_lat 800
My MASTER code:

Code: Select all

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <inttypes.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"                // přidáno pro blikající BT_LED
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"

#include "time.h"
#include "sys/time.h"

#include "driver/gpio.h"

#define SPP_TAG "SPP_INITIATOR_DEMO"
#define EXAMPLE_DEVICE_NAME "ESP_SPP_INITIATOR"

#define SPP_SHOW_MODE SPP_SHOW_DATA     /*Choose show mode: show data SPP_SHOW_DATA or speed SPP_SHOW_SPEED*/

#define LED_BT_PIN 2                                                  // GPIO2  LED BT
#define LED_DATA_PIN 27                                               // GPIO27 LED DATA

static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
static const bool esp_spp_enable_l2cap_ertm = true;

static struct timeval time_new, time_old;
//? static long data_num = 0;

static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;

esp_bd_addr_t peer_bd_addr = {0};                                               // Proměnná pro uchování BDA vzdáleného zařízení
static uint8_t peer_bdname_len;                                                 // Proměnná pro uchování délky vzdáleného zařizení
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];                         // Proměnná pro uchování jména vzdáleného zařízení; velikost pole = max. délka jména +1 znak
static const char remote_device_name[] = "ESP_SPP_ACCEPTOR";                    // Proměnná pro uchování jména zařízení ke kterému se snažíme připojit
static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY;      // Proměnná určuje režim vyhledávání Bluetoth. "General Inquiry" je standardní režim pro vyhledávání zařízení v dosahu
static const uint8_t inq_len = 30;                                              // Proměnná pro určenídélky vyhldávání v jednotkách 1.28 sec. Určuje, jak dlouho se budou vyhledávat ostatní zařízení 
static const uint8_t inq_num_rsps = 0;                                          // Proměnná určuje maximální počet odpovědí, které se mají zpracovat během jednoho vyhledávacího cyklu- 0 = bez limitu

//DEL #define SPP_DATA_LEN 85                                                         // Délka odesílaných dat
//DEL static uint8_t spp_data[SPP_DATA_LEN];
//DEL static uint8_t *s_p_data = NULL;                                        /* data pointer of spp_data */

// Proměnné pro obsluhu BT_LED
static TimerHandle_t blink_timer = NULL;
static bool is_connected = false;

// Proměnná pro reconnect timer
static TimerHandle_t reconnect_timer = NULL;

/*Převod Bluetooth Device Address (BDA) do četelného formátu*/
static char *bda2str(uint8_t * bda, char *str, size_t size)
{
    if (bda == NULL || str == NULL || size < 18) {
        return NULL;
    }

    uint8_t *p = bda;
    sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
            p[0], p[1], p[2], p[3], p[4], p[5]);
    return str;
}
/* Funkce pro extrakci jména Bluetooth zařízení z Extended Inquiry Response (EIR) dat, která jsou obdržena během procesu vyhledávání */
static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len)
{
    uint8_t *rmt_bdname = NULL;
    uint8_t rmt_bdname_len = 0;

    if (!eir) {
        return false;
    }

    rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
    if (!rmt_bdname) {
        rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
    }

    if (rmt_bdname) {
        if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) {
            rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN;
        }

        if (bdname) {
            memcpy(bdname, rmt_bdname, rmt_bdname_len);
            bdname[rmt_bdname_len] = '\0';
        }
        if (bdname_len) {
            *bdname_len = rmt_bdname_len;
        }
        return true;
    }

    return false;
}

// Zapnutí DATA_LED na daném pinu (1) nebo vypnutí (0)
void toggle_data_led(bool state_data_led) {
    gpio_set_level(LED_DATA_PIN, state_data_led ? 1 : 0); 
}
// Prototypy funkcí pro BT_LED
void toggle_led_bt(bool state_bt_led);
void blink_timer_callback(TimerHandle_t xTimer);

// Funkce pro blikání BT_LED
void blink_timer_callback(TimerHandle_t xTimer) {
    if (!is_connected) {
        // Přepínání stavu LED
        static bool led_state = false;
        toggle_led_bt(led_state);
        led_state = !led_state;
    }
}

// Upravená funkce pro zapnutí/vypnutí BT_LED
void toggle_led_bt(bool state_bt_led) {
    gpio_set_level(LED_BT_PIN, state_bt_led ? 1 : 0);
}

// Inicializace LED
static void init_led(void) {
    gpio_reset_pin(LED_DATA_PIN);
    gpio_set_direction(LED_DATA_PIN, GPIO_MODE_OUTPUT);
    ESP_LOGI(SPP_TAG, "Init DATA LED completed");
    gpio_reset_pin(LED_BT_PIN);
    gpio_set_direction(LED_BT_PIN, GPIO_MODE_OUTPUT);
    ESP_LOGI(SPP_TAG, "Init BT LED completed");
}

// Funkce pro pokus o opětovné připojení
void reconnect_timer_callback(TimerHandle_t xTimer) {
    // Pokus o opětovné připojení
    if (!is_connected)
    {
        esp_spp_start_discovery(peer_bd_addr);
    }
}

static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    uint8_t i = 0;
    char bda_str[18] = {0};

    switch (event) {
    case ESP_SPP_INIT_EVT:
        if (param->init.status == ESP_SPP_SUCCESS) {
            ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
            esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME);
            esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
            esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps);
        } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status);
        }
        break;
    case ESP_SPP_DISCOVERY_COMP_EVT:
        if (param->disc_comp.status == ESP_SPP_SUCCESS) {                                               // Bylo vyhledávání zařízení úspěšné ?
            ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT scn_num:%d", param->disc_comp.scn_num);       // Logování počtu nalezených služeb
            for (i = 0; i < param->disc_comp.scn_num; i++) {                                            // Cyklus prochází všechny nalezené služby, loguje jejich SCN a jméno služby
                ESP_LOGI(SPP_TAG, "-- [%d] scn:%d service_name:%s", i, param->disc_comp.scn[i],
                         param->disc_comp.service_name[i]);
            }
            /* We only connect to the first found server on the remote SPP acceptor here */
            esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr);              // Pokus o navázání spojení s prvním nalezeným serverem
        } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d", param->disc_comp.status);         // Pokud pokus o spojení selže, loguje se chyba
            // Pokud není zařízení připojeno, restartovat proces vyhledávání
            esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps);
        }
        break;
    case ESP_SPP_OPEN_EVT:
        if (param->open.status == ESP_SPP_SUCCESS) {
            ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT handle:%"PRIu32" rem_bda:[%s]", param->open.handle,
                     bda2str(param->open.rem_bda, bda_str, sizeof(bda_str)));
            
            // Když je spojení navázáno
            is_connected = true;
            toggle_led_bt(true); // Trvale zapnout LED
            xTimerStop(blink_timer, 0); // Zastavit blikání


            /* Start to write the first data packet */
            //DEL ESP_LOGI(SPP_TAG, "*****************************Sent first data: SESP_SPP_OPEN_EVT**********************************************************");
            //DEL esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
            //DEL esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data);
            //DEL s_p_data = spp_data;
            //DEL gettimeofday(&time_old, NULL);
            //DEL ESP_LOGI(SPP_TAG, "*************************************************************************************************************************");

            // Odeslání textové zprávy "Ahoj tady MASTER"
            const char *message = "Ahoj tady MASTER";
            esp_spp_write(param->open.handle, strlen(message), (uint8_t *)message);


            } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_OPEN_EVT status:%d", param->open.status);
            }
            break;
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%"PRIu32" close_by_remote:%d", param->close.status,
                 param->close.handle, param->close.async);
        
        // Když je spojení ukončeno
        is_connected = false;
        xTimerStart(blink_timer, 0); // Začít blikat
        xTimerStart(reconnect_timer, 0); // Spustit timer pro opětovné připojení

        break;
    case ESP_SPP_START_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
        break;
    case ESP_SPP_CL_INIT_EVT:
        if (param->cl_init.status == ESP_SPP_SUCCESS) {
            ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT handle:%"PRIu32" sec_id:%d", param->cl_init.handle, param->cl_init.sec_id);
        } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status);
        }
        break;
    case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT");
        /*
         * We only show the data in which the data length is less than 128 here. If you want to print the data and
         * the data rate is high, 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, it may stuck the Bluetooth
         * stack and also have a effect on the throughput!
         */

        if (param->data_ind.len > 0) {                                          // From S
        // Pokud byla přijata nějaká data, rozsvítí se LED                      // From S
        toggle_data_led(true);                                                  // From S
        ESP_LOGI(SPP_TAG, "DATA LED ON");                                       // From S    
        toggle_data_led(false);                                                 // From S
        
        ESP_LOGI(SPP_TAG, "************************************Received data START***************************************************");
        // Vypisuje data v HEX
        esp_log_buffer_hex("Received data (HEX): ", param->data_ind.data, param->data_ind.len);

        // Vypisuje data v textové podobě
        char received_text[param->data_ind.len + 1];
        memcpy(received_text, param->data_ind.data, param->data_ind.len);
        received_text[param->data_ind.len] = '\0'; // Přidání nulového ukončovacího znaku
        ESP_LOGI(SPP_TAG, "Received data (TEXT): %s", received_text);
        
        ESP_LOGI(SPP_TAG, "************************************Received data END*****************************************************");
        
        
        
        
        
         } else {                                                               // From S
        // Pokud nebyla přijata žádná data, LED se zhasne                       // From S
        toggle_data_led(false);                                                 // From S
        ESP_LOGI(SPP_TAG, "DATA LED OFF");                                      // From S
        }                                                                       // From S
                                                                                // From S
        //DEL   ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len:%d handle:%d",              // From S
        //DEL            param->data_ind.len, param->data_ind.handle);                  // From S
        //DEL   if (param->data_ind.len < 128) {                                        // From S
        //DEL       ESP_LOGI(SPP_TAG, "************************************Received data START***************************************************");
        //DEL       esp_log_buffer_hex("Received data: ", param->data_ind.data, param->data_ind.len);                              // Vypisuje data v HEX
        //DEL       // ESP_LOGI(SPP_TAG, "Received data: %.*s", param->data_ind.len, (char *)param->data_ind.data);    // Vypisuje data v ASCII napři při použítí s Serial BT Terminalem na mobilu
        //DEL       ESP_LOGI(SPP_TAG, "************************************Received data END*****************************************************");      // Vypisuje data v ASCII napři při použítí s Serial BT Terminalem na mobilu
        //DEL   }                                                                        // From S
        break; 
    case ESP_SPP_WRITE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT");
        //DEL if (param->write.status == ESP_SPP_SUCCESS) {
        //DEL     if (s_p_data + param->write.len == spp_data + SPP_DATA_LEN) {
        //DEL         /* Means the previous data packet be sent completely, send a new data packet */
        //DEL         s_p_data = spp_data;
        //DEL     } else {
        //DEL         /*
        //DEL          * Means the previous data packet only be sent partially due to the lower layer congestion, resend the
        //DEL          * remainning data.
        //DEL          */
        //DEL         s_p_data += param->write.len;
        //DEL     }
        //DEL     /*
        //DEL      * We only show the data in which the data length is less than 128 here. If you want to print the data and
        //DEL      * the data rate is high, it is strongly recommended to process them in other lower priority application task
        //DEL      * rather than in this callback directly. Since the printing takes too much time, it may stuck the Bluetooth
        //DEL      * stack and also have a effect on the throughput!
        //DEL      */
        //DEL     ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len:%d handle:%d cong:%d", param->write.len, param->write.handle,
        //DEL              param->write.cong);
        //DEL     if (param->write.len < 128) {
        //DEL         // esp_log_buffer_hex("", spp_data, param->write.len);          // původní vyýpis dat k odeslání
        //DEL         /* Delay a little to avoid the task watch dog */
        //DEL         vTaskDelay(pdMS_TO_TICKS(10));
        //DEL     }
        //DEL } else {
        //DEL     /* Means the prevous data packet is not sent at all, need to send the whole data packet again. */
        //DEL     ESP_LOGE(SPP_TAG, "ESP_SPP_WRITE_EVT status:%d", param->write.status);
        //DEL }

        //DEL if (!param->write.cong) {
        //DEL     /* The lower layer is not congested, you can send the next data packet now. */
        //DEL     ESP_LOGI(SPP_TAG, "*****************************Sent Next data packet: ESP_SPP_WRITE_EVT**********************************************************");
        //DEL     esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
        //DEL     esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data);
        //DEL     ESP_LOGI(SPP_TAG, "*******************************************************************************************************************************");
        //DEL } else {
        //DEL     /*
        //DEL      * The lower layer is congested now, don't send the next data packet until receiving the
        //DEL      * ESP_SPP_CONG_EVT with param->cong.cong == 0.
        //DEL      */
        //DEL     ;
        //DEL }
        //DEL 
        //DEL /*
        //DEL  * If you don't want to manage this complicated process, we also provide the SPP VFS mode that hides the
        //DEL  * implementation details. However, it is less efficient and will block the caller until all data has been sent.
        //DEL  */
        break;
    case ESP_SPP_CONG_EVT:
        //DEL ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong:%d", param->cong.cong);
        //DEL if (param->cong.cong == 0) {
        //DEL     /* Send the privous (partial) data packet or the next data packet. */
        //DEL     ESP_LOGI(SPP_TAG, "*****************************Sent Previous partial data: ESP_SPP_WRITE_EVT**********************************************************");
        //DEL     esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
        //DEL     esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data);
        //DEL     ESP_LOGI(SPP_TAG, "************************************************************************************************************************************");
        //DEL }
        break;

    case ESP_SPP_SRV_OPEN_EVT:
        break;
    case ESP_SPP_UNINIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_UNINIT_EVT");
        break;
    default:
        break;
    }
}

static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    switch(event){
    case ESP_BT_GAP_DISC_RES_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT");
        esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN);
        /* Find the target peer device name in the EIR data */
        for (int i = 0; i < param->disc_res.num_prop; i++){
            if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR
                && get_name_from_eir(param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){
                esp_log_buffer_char(SPP_TAG, peer_bdname, peer_bdname_len);

                // Print the peer device name
                ESP_LOGI(SPP_TAG, "Peer device name: %.*s", peer_bdname_len, peer_bdname);


                if (strlen(remote_device_name) == peer_bdname_len
                    && strncmp(peer_bdname, remote_device_name, peer_bdname_len) == 0) {
                    memcpy(peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
                    /* Have found the target peer device, cancel the previous GAP discover procedure. And go on
                     * dsicovering the SPP service on the peer device */
                    esp_bt_gap_cancel_discovery();
                    if (!is_connected) {
                        esp_spp_start_discovery(peer_bd_addr);
                    }
                }
            }
        }
        break;
    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_STATE_CHANGED_EVT");
        // Pokud není zařízení připojeno, restartovat proces vyhledávání
        if (!is_connected) {
                esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps);
            }
        break;
    case ESP_BT_GAP_RMT_SRVCS_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVCS_EVT");
        break;
    case ESP_BT_GAP_RMT_SRVC_REC_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT");
        break;
    default:
        break;
    }   
}

void app_main(void)
{
    init_led();                             // inicializace LED diod
        
    esp_err_t ret = ESP_OK;
    char bda_str[18] = {0};

    //DEL // Generování dat k odeslání
    //DEL for (int i = 0; i < SPP_DATA_LEN; ++i) {
    //DEL     spp_data[i] = i;
    //DEL }

    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_init()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_enable()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bt_gap_register_callback(esp_bt_gap_cb)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s gap register failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

#if (CONFIG_BT_SSP_ENABLED == true)
    /* Set default parameters for Secure Simple Pairing */
    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE;                             // ESP_BT_IO_CAP_NONE bez možnosti vstupu a zadání PIN (původní hodnota byla ESP_BT_IO_CAP_IO a vyžadovala PIN)                         
    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
    
#endif

    if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    esp_spp_cfg_t bt_spp_cfg = {
        .mode = esp_spp_mode,
        .enable_l2cap_ertm = esp_spp_enable_l2cap_ertm,
        .tx_buffer_size = 0, /* Only used for ESP_SPP_MODE_VFS mode */
    };
    if ((ret = esp_spp_enhanced_init(&bt_spp_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    } 

    ESP_LOGI(SPP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str)));

    // Inicializace timeru pro blikání
    blink_timer = xTimerCreate("BlinkTimer", pdMS_TO_TICKS(250), pdTRUE, (void *)0, blink_timer_callback);  // pdMS_TO_TICKS(250) nastavuje rychlost blikání v ms
    xTimerStart(blink_timer, 0); // Spustit blikání hned na začátku

    // Inicializace timeru pro opětovné připojení
    reconnect_timer = xTimerCreate("ReconnectTimer", pdMS_TO_TICKS(10000), pdFALSE, (void *)0, reconnect_timer_callback);
}
My SLAVE code:

Code: Select all

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <inttypes.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"                // přidáno pro blikající BT_LED
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"

#include "time.h"
#include "sys/time.h"

#include "driver/gpio.h"                                        

#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define BT_DEVICE_NAME "ESP_SPP_ACCEPTOR"                  // Jmeńo pro párování, k zařízení s tímto jménem se bude chtít připojit INITIATOR

#define LED_BT_PIN 2                                                  // GPIO2  LED BT
#define LED_DATA_PIN 27                                               // GPIO27 LED DATA

static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
static const bool esp_spp_enable_l2cap_ertm = true;

static struct timeval time_new, time_old;
//? static long data_num = 0;

static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;

#define SPP_DATA_LEN 80                             // From M                            // Délka odesílaných dat
static uint8_t spp_data[SPP_DATA_LEN];              // From M
static uint8_t *s_p_data = NULL;                    // From M                    /* data pointer of spp_data */

// Proměnné pro obsluhu BT_LED
static TimerHandle_t blink_timer = NULL;
static bool is_connected = false;

// Zapnutí DATA_LED na daném pinu (1) nebo vypnutí (0)
void toggle_data_led(bool state_data_led) {
    gpio_set_level(LED_DATA_PIN, state_data_led ? 1 : 0); 
}
// Prototypy funkcí pro BT_LED
void toggle_led_bt(bool state_bt_led);
void blink_timer_callback(TimerHandle_t xTimer);

// Funkce pro blikání BT_LED
void blink_timer_callback(TimerHandle_t xTimer) {
    if (!is_connected) {
        // Přepínání stavu LED
        static bool led_state = false;
        toggle_led_bt(led_state);
        led_state = !led_state;
    }
}

// Upravená funkce pro zapnutí/vypnutí BT_LED
void toggle_led_bt(bool state_bt_led) {
    gpio_set_level(LED_BT_PIN, state_bt_led ? 1 : 0);
}

// Inicializace LED
static void init_led(void) {
    gpio_reset_pin(LED_DATA_PIN);
    gpio_set_direction(LED_DATA_PIN, GPIO_MODE_OUTPUT);
    ESP_LOGI(SPP_TAG, "Init DATA LED completed");
    gpio_reset_pin(LED_BT_PIN);
    gpio_set_direction(LED_BT_PIN, GPIO_MODE_OUTPUT);
    ESP_LOGI(SPP_TAG, "Init BT LED completed");
}

static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    char bda_str[18] = {0};
    
    switch (event) {
    case ESP_SPP_INIT_EVT:
        if (param->init.status == ESP_SPP_SUCCESS) {
            ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
            esp_spp_start_srv(sec_mask, role_slave, 0, SPP_SERVER_NAME);
        } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_INIT_EVT status:%d", param->init.status);
        }
        break;
    case ESP_SPP_DISCOVERY_COMP_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT");      
        break;
    case ESP_SPP_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
        
        //DEL   if (param->open.status == ESP_SPP_SUCCESS) {

            //DEL   /* Start to write the first data packet */                                  // From M
            //DEL   esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data);                  // From M
            //DEL   s_p_data = spp_data;                                                        // From M
            //DEL   gettimeofday(&time_old, NULL);                                              // From M
            //DEL   } else {                                                                    // From M
            //DEL   ESP_LOGE(SPP_TAG, "ESP_SPP_OPEN_EVT status:%d", param->open.status);        // From M
            //DEL   }                                                                           // From M
        break;
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT status:%d handle:%"PRIu32" close_by_remote:%d", param->close.status,
                 param->close.handle, param->close.async);
               
        // Když je spojení ukončeno
        is_connected = false;
        xTimerStart(blink_timer, 0); // Začít blikat
                
        break;
    case ESP_SPP_START_EVT:
        if (param->start.status == ESP_SPP_SUCCESS) {
            ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT handle:%"PRIu32" sec_id:%d scn:%d", param->start.handle, param->start.sec_id,
                     param->start.scn);
            esp_bt_dev_set_device_name(BT_DEVICE_NAME);
            esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
        } else {
            ESP_LOGE(SPP_TAG, "ESP_SPP_START_EVT status:%d", param->start.status);
        }
        break;
    case ESP_SPP_CL_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
        break;
    case ESP_SPP_DATA_IND_EVT:
        /*
         * We only show the data in which the data length is less than 128 here. If you want to print the data and
         * the data rate is high, 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, it may stuck the Bluetooth
         * stack and also have a effect on the throughput!
         */

        if (param->data_ind.len > 0) {
        // Pokud byla přijata nějaká data, rozsvítí se LED
        toggle_data_led(true);
        ESP_LOGI(SPP_TAG, "DATA LED ON");
        toggle_data_led(false);
        
        

        ESP_LOGI(SPP_TAG, "************************************Received data START***************************************************");
        // Vypisuje data v HEX
        esp_log_buffer_hex("Received data (HEX): ", param->data_ind.data, param->data_ind.len);

        // Vypisuje data v textové podobě
        char received_text[param->data_ind.len + 1];
        memcpy(received_text, param->data_ind.data, param->data_ind.len);
        received_text[param->data_ind.len] = '\0'; // Přidání nulového ukončovacího znaku
        ESP_LOGI(SPP_TAG, "Received data (TEXT): %s", received_text);
        
        ESP_LOGI(SPP_TAG, "************************************Received data END*****************************************************");
        
        
        
         } else {
        // Pokud nebyla přijata žádná data, LED se zhasne
        toggle_data_led(false);
        ESP_LOGI(SPP_TAG, "DATA LED OFF");
        }
        //DEL ESP_LOGI(SPP_TAG, "************************************Received data START***************************************************");
        //DEL ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len:%d handle:%d",
        //DEL          param->data_ind.len, param->data_ind.handle);
        //DEL if (param->data_ind.len < 128) {
        //DEL     
        //DEL     esp_log_buffer_hex("Received data: HEX: ", param->data_ind.data, param->data_ind.len);                              // Vypisuje data v HEX
        //DEL     // ESP_LOGI(SPP_TAG, "Received data: %.*s", param->data_ind.len, (char *)param->data_ind.data);    // Vypisuje data v ASCII napři při použítí s Serial BT Terminalem na mobilu
        //DEL     ESP_LOGI(SPP_TAG, "************************************Received data END*****************************************************");
        //DEL }
        break;
    case ESP_SPP_WRITE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT");
        //DEL if (param->write.status == ESP_SPP_SUCCESS) {                                               // From M
        //DEL     if (s_p_data + param->write.len == spp_data + SPP_DATA_LEN) {                           // From M
        //DEL         /* Means the previous data packet be sent completely, send a new data packet */     // From M
        //DEL         s_p_data = spp_data;                                                                // From M
        //DEL     } else {                                                                                // From M
        //DEL         /*  
        //DEL          * Means the previous data packet only be sent partially due to the lower layer congestion, resend the
        //DEL          * remainning data.
        //DEL          */
        //DEL         s_p_data += param->write.len;                                                       // From M
        //DEL     }                                                                                       // From M
        //DEL 
        //DEL     /*
        //DEL      * We only show the data in which the data length is less than 128 here. If you want to print the data and
        //DEL      * the data rate is high, it is strongly recommended to process them in other lower priority application task
        //DEL      * rather than in this callback directly. Since the printing takes too much time, it may stuck the Bluetooth
        //DEL      * stack and also have a effect on the throughput!
        //DEL      */
        //DEL     ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len:%d handle:%d cong:%d", param->write.len, param->write.handle,  // From M
        //DEL              param->write.cong);                                                                // From M
        //DEL     if (param->write.len < 128) {                                                               // From M
        //DEL         // esp_log_buffer_hex("", spp_data, param->write.len);                       // původní vyýpis dat k odeslání              // From M
        //DEL         /* Delay a little to avoid the task watch dog */                                        // From M
        //DEL         vTaskDelay(pdMS_TO_TICKS(10));                                                          // From M
        //DEL     }                                                                                           // From M
        //DEL                                                                                       // From M
        //DEL } else {                                                                                        // From M
        //DEL     /* Means the prevous data packet is not sent at all, need to send the whole data packet again. */
        //DEL     ESP_LOGE(SPP_TAG, "ESP_SPP_WRITE_EVT status:%d", param->write.status);                      // From M
        //DEL }                                                                                               // From M
        //DEL                                                                                                 // From M
        //DEL if (!param->write.cong) {                                                                       // From M
        //DEL     /* The lower layer is not congested, you can send the next data packet now. */              // From M
        //DEL     ESP_LOGI(SPP_TAG, "*****************************Sent Next data packet: ESP_SPP_WRITE_EVT**********************************************************");
        //DEL     esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
        //DEL     esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data);           // From M
        //DEL     ESP_LOGI(SPP_TAG, "*******************************************************************************************************************************");
        //DEL } else {                                                                                        // From M
        //DEL     /*                                                                                          // From M
        //DEL      * The lower layer is congested now, don't send the next data packet until receiving the
        //DEL      * ESP_SPP_CONG_EVT with param->cong.cong == 0.
        //DEL      */
        //DEL     ;                                                                                           // From M
        //DEL }                                                                                               // From M
                                                                                                        // From M
        //DEL /*
        //DEL * If you don't want to manage this complicated process, we also provide the SPP VFS mode that hides the
        //DEL * implementation details. However, it is less efficient and will block the caller until all data has been sent.
        //DEL */                                                                                             // From M
        break;
    case ESP_SPP_CONG_EVT:                                                                      // From M
        //DEL ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT");                                                  // From M
        //DEL ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong:%d", param->cong.cong);                        // From M

        //DEL if (param->cong.cong == 0) {                                                            // From M
        //DEL     /* Send the privous (partial) data packet or the next data packet. */               // From M
        //DEL     ESP_LOGI(SPP_TAG, "*****************************Sent Previous partial data: ESP_SPP_WRITE_EVT**********************************************************");
        //DEL     esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
        //DEL     esp_spp_write(param->write.handle, spp_data + SPP_DATA_LEN - s_p_data, s_p_data);   // From M
        //DEL     ESP_LOGI(SPP_TAG, "************************************************************************************************************************************");
        //DEL }                                                                                       // From M
        break;

    
        case ESP_SPP_SRV_OPEN_EVT:
        
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");

        // Vypsání adresy vzdáleného zařízení
        ESP_LOGI(SPP_TAG, "Remote device address: %02x:%02x:%02x:%02x:%02x:%02x",
             param->srv_open.rem_bda[0], param->srv_open.rem_bda[1], param->srv_open.rem_bda[2],
             param->srv_open.rem_bda[3], param->srv_open.rem_bda[4], param->srv_open.rem_bda[5]);
                 
        gettimeofday(&time_old, NULL);
        
        // Když je spojení navázáno
        is_connected = true;
        toggle_led_bt(true); // Trvale zapnout LED
        xTimerStop(blink_timer, 0); // Zastavit blikání   

        // Odeslání textové zprávy "Ahoj tady SLAVE"
            const char *message = "Ahoj tady SLAVE";
            esp_spp_write(param->open.handle, strlen(message), (uint8_t *)message);


        //DEL /* Start to write the first data packet */                                  // From M
        //DEL     ESP_LOGI(SPP_TAG, "*****************************Sent first data: SESP_SPP_SRV_OPEN_EVT**********************************************************");
        //DEL     // ESP_LOGI(SPP_TAG, "Data k odeslání: %.*s", SPP_DATA_LEN, (char *)spp_data);
        //DEL     esp_log_buffer_hex(SPP_TAG, spp_data, SPP_DATA_LEN);
        //DEL     esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data);                  // From M
        //DEL     s_p_data = spp_data;                                                        // From M
        //DEL     gettimeofday(&time_old, NULL);                                              // From M
        //DEL     ESP_LOGI(SPP_TAG, "*****************************************************************************************************************************");

        break;

    case ESP_SPP_SRV_STOP_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_STOP_EVT");
        break;

    case ESP_SPP_UNINIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_UNINIT_EVT");
        break;
    default:
        break;
    }
}

void app_main(void)
{
    init_led();                             // inicializace LED diod

    //DEL // Generování dat k odeslání
    //DEL for (int i = 0; i < SPP_DATA_LEN; ++i) {
    //DEL spp_data[i] = i;
    //DEL }


    esp_err_t ret = nvs_flash_init();
    
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );                                                     // Ověření, zda předchozí volání funkce bylo úspašné

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));            // Uvolnění paměti přidělené pro Bluetooth Low Energy (BLE) 

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_init()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_enable()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }
    
    esp_spp_cfg_t bt_spp_cfg = {
        .mode = esp_spp_mode,
        .enable_l2cap_ertm = esp_spp_enable_l2cap_ertm,
    };
    
    if ((ret = esp_spp_enhanced_init(&bt_spp_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

#if (CONFIG_BT_SSP_ENABLED == true)
    /* Set default parameters for Secure Simple Pairing */
    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE;                              // ESP_BT_IO_CAP_NONE bez možnosti vstupu a zadání PIN (původní hodnota byla ESP_BT_IO_CAP_IO a vyžadovala PIN)                         
    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
#endif

    // Inicializace timeru pro blikání
    blink_timer = xTimerCreate("BlinkTimer", pdMS_TO_TICKS(250), pdTRUE, (void *)0, blink_timer_callback);  // pdMS_TO_TICKS(250) nastavuje rychlost blikání v ms
    xTimerStart(blink_timer, 0); // Spustit blikání hned na začátku

}

Who is online

Users browsing this forum: tonystuart and 123 guests