OVMS3-idf/examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c

221 lines
6.9 KiB
C

/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/****************************************************************************
*
* This file is for bt_spp_vfs_acceptor demo. It can create servers, wait for connected and receive data.
* run bt_spp_vfs_acceptor demo, the bt_spp_vfs_initiator demo will automatically connect the bt_spp_vfs_acceptor demo,
* then receive data.
*
****************************************************************************/
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#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 "spp_task.h"
#include "time.h"
#include "sys/time.h"
#include "esp_vfs.h"
#include "sys/unistd.h"
#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR"
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_VFS;
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 100
static uint8_t spp_data[SPP_DATA_LEN];
static void spp_read_handle(void * param)
{
int size = 0;
int fd = (int)param;
do {
size = read (fd, spp_data, SPP_DATA_LEN);
ESP_LOGI(SPP_TAG, "fd = %d data_len = %d", fd, size);
if (size == -1) {
break;
}
esp_log_buffer_hex(SPP_TAG, spp_data, size);
if (size == 0) {
/*read fail due to there is no data, retry after 1s*/
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
} while (1);
spp_wr_task_shut_down();
}
static void esp_spp_cb(uint16_t e, void *p)
{
esp_spp_cb_event_t event = e;
esp_spp_cb_param_t *param = p;
switch (event) {
case ESP_SPP_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
esp_bt_dev_set_device_name(EXCAMPLE_DEVICE_NAME);
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
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");
break;
case ESP_SPP_CLOSE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_START_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
spp_wr_task_start_up(spp_read_handle, param->srv_open.fd);
break;
default:
break;
}
}
static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL);
}
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_AUTH_CMPL_EVT:{
if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
} else {
ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
}
break;
}
case ESP_BT_GAP_PIN_REQ_EVT:{
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
if (param->pin_req.min_16_digit) {
ESP_LOGI(SPP_TAG, "Input pin code: 0000 0000 0000 0000");
esp_bt_pin_code_t pin_code = {0};
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
} else {
ESP_LOGI(SPP_TAG, "Input pin code: 1234");
esp_bt_pin_code_t pin_code;
pin_code[0] = '1';
pin_code[1] = '2';
pin_code[2] = '3';
pin_code[3] = '4';
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
}
break;
}
case ESP_BT_GAP_CFM_REQ_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
break;
case ESP_BT_GAP_KEY_NOTIF_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
break;
case ESP_BT_GAP_KEY_REQ_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
break;
default: {
ESP_LOGI(SPP_TAG, "event: %d", event);
break;
}
}
return;
}
void app_main()
{
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 );
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 (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize controller failed", __func__);
return;
}
if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable controller failed", __func__);
return;
}
if (esp_bluedroid_init() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed", __func__);
return;
}
if (esp_bluedroid_enable() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed", __func__);
return;
}
if (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 (esp_spp_register_callback(esp_spp_stack_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp register failed", __func__);
return;
}
esp_spp_vfs_register();
spp_task_task_start_up();
if (esp_spp_init(esp_spp_mode) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp init failed", __func__);
return;
}
/* 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_IO;
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
/*
* Set default parameters for Legacy Pairing
* Use variable pin, input pin code when pairing
*/
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE;
esp_bt_pin_code_t pin_code;
esp_bt_gap_set_pin(pin_type, 0, pin_code);
}