espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.51k stars 7.26k forks source link

esp_bt_gap_set_cod (IDFGH-8668) #10113

Closed sueng66 closed 1 year ago

sueng66 commented 1 year ago

Answers checklist.

General issue report

I failed setting bluetooth class device on major device class (always 0x1f) and minor device class (always0x00) , the only work is setting service class, here are my code :

    siscod.major   = esp_bt_gap_get_cod_major_dev(0x040680);
    siscod.minor   = esp_bt_gap_get_cod_minor_dev(0x040680);
    siscod.service = esp_bt_gap_get_cod_srvc(0x040680);

    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 -1;
    }

    if ((ret = esp_bt_gap_set_cod(siscod, ESP_BT_INIT_COD)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s gap set cod failed: %s\n", __func__, esp_err_to_name(ret));
    }
BetterJincheng commented 1 year ago

@sueng66 Please make sure the calling for esp_bt_gap_set_cod is before setting the device to discoverable mode.

sueng66 commented 1 year ago

yes I have, I do that just after esp_bt_gap_register_callback , and call esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE) after got ESP_SPP_INIT_EVT that definitly after calling esp_bt_gap_set_cod

BetterJincheng commented 1 year ago

@sueng66 but I just tested on the example bt_hid_mouse_device with your code and it worked fine. Could you please describe the procedure to reproduce the issue? Thanks!

sueng66 commented 1 year ago

you are right I try with esp_hid_device example , it's could set the cod. My code is base on bt_spp_initiator here are my complete code :

/*
   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.
*/

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include "driver/uart.h"
#include "driver/gpio.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 "console_uart.h"

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

#define GPIO_OUTPUT_IO_0    2
#define GPIO_OUTPUT_PIN_SEL  ((1ULL<<GPIO_OUTPUT_IO_0))

#define SPP_TAG "BT_STOREFORWARD"
#define SPP_SERVER_NAME "SPP_SISTEK_SERVER"
#define DEVICE_NAME "RPP02N"
#define NOCONNECT_PERIODE 100
#define CONNECT_PERIODE 750

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

unsigned blinkperiode = NOCONNECT_PERIODE;

void ledblink( void *param)
{
    printf("LED blink Task Started\r\n");
    while(1) {
        gpio_set_level(GPIO_OUTPUT_IO_0, 0);
        vTaskDelay(blinkperiode / portTICK_PERIOD_MS);
        gpio_set_level(GPIO_OUTPUT_IO_0, 1);
        vTaskDelay(blinkperiode / portTICK_PERIOD_MS);
    }
}

static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;

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

const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY;
static const uint8_t inq_len = 30;
static const uint8_t inq_num_rsps = 0;
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;

esp_bd_addr_t peer_bd_addr = {0xdc, 0x0d, 0x51, 0xd6, 0x91, 0x63};
//esp_bd_addr_t peer_bd_addr = {0x02, 0x14, 0x53, 0x41, 0x2e, 0x42};
//esp_bd_addr_t peer_bd_addr = {0x02, 0x2F, 0xA6, 0x38, 0x05, 0x3E};
static uint8_t peer_bdname_len;
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
char remote_device_name[128] = "RPP02N";
char dev_name[128] = DEVICE_NAME;

#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
#define SPP_DATA_LEN 20
#else
#define SPP_DATA_LEN ESP_SPP_MAX_MTU
#endif
static uint8_t spp_data[SPP_DATA_LEN];

static void print_speed(void)
{
    float time_old_s = time_old.tv_sec + time_old.tv_usec / 1000000.0;
    float time_new_s = time_new.tv_sec + time_new.tv_usec / 1000000.0;
    float time_interval = time_new_s - time_old_s;
    float speed = data_num * 8 / time_interval / 1000.0;
    ESP_LOGI(SPP_TAG, "speed(%fs ~ %fs): %f kbit/s" , time_old_s, time_new_s, speed);
    data_num = 0;
    time_old.tv_sec = time_new.tv_sec;
    time_old.tv_usec = time_new.tv_usec;
}

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;
}

uint32_t poshandle;
uint32_t prnhandle;

uint8_t prnch;

uint8_t pos2prn[32][ESP_SPP_MAX_MTU];
uint8_t prn2pos[16][ESP_SPP_MAX_MTU];

uint8_t pos2head=0,pos2tail=0;
uint8_t prn2head=0,prn2tail=0;

uint8_t pos2idx=0,prn2idx=0;
uint8_t pos2cur=0,prn2cur=0;
int pos2len[32],prn2len[16];
int cong[2] = {0,0};
int wait4cong[2] = {0,0};

static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    switch (event) {
    case ESP_SPP_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
        esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
        esp_bt_dev_set_device_name(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);

        break;
    case ESP_SPP_DISCOVERY_COMP_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%lu scn_num=%lu",(unsigned long)param->disc_comp.status, (unsigned long)param->disc_comp.scn_num);
        if (param->disc_comp.status == ESP_SPP_SUCCESS) {
            esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr);
            prnch = param->disc_comp.scn[0];
        } else {
            esp_spp_start_discovery(peer_bd_addr);
        }
        break;
    case ESP_SPP_OPEN_EVT:
        prnhandle = param->open.handle;
        cong[0] = 0;
        blinkperiode = CONNECT_PERIODE;
        ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT %lu-%lu",prnhandle , param->open.handle);
        //esp_spp_write(param->open.handle, SPP_DATA_LEN, spp_data);
        gettimeofday(&time_old, NULL);
        break;
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
        if(param->close.handle == prnhandle) {
            blinkperiode = NOCONNECT_PERIODE;
            prnhandle = 0;
            //esp_spp_connect(sec_mask, role_master, prnch, peer_bd_addr);
            esp_spp_start_discovery(peer_bd_addr);
        } else if(param->close.handle == poshandle) {
            poshandle = 0;
        }
        break;
    case ESP_SPP_START_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
        esp_bt_dev_set_device_name(DEVICE_NAME);
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
        break;
    case ESP_SPP_CL_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
        break;
    case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT handle :  %lu,%lu length : %lu",(unsigned long)param->data_ind.handle,(unsigned long)poshandle,(unsigned long)param->data_ind.len);
        if(param->data_ind.handle == poshandle) {
            //uart_write_bytes(UART_NUM_0, param->data_ind.data, param->data_ind.len);
            if(prnhandle > 0) {
                pos2len[pos2tail] = param->data_ind.len;
                memcpy(pos2prn[pos2tail],param->data_ind.data, pos2len[pos2tail]);
                if((pos2tail == pos2head) && !cong[0])
                {
                    ESP_LOGI(SPP_TAG, "Write to printer %lu,%d,%d",
                        (unsigned long)prnhandle, pos2len[pos2tail], pos2tail);
                    cong[0] = 1;
                    esp_spp_write(prnhandle, pos2len[pos2tail], pos2prn[pos2tail]);
                    uart_write_bytes(UART_NUM_0, pos2prn[pos2tail], pos2len[pos2tail]);
                }
                pos2tail++ ; if(pos2tail>31) pos2tail=0;
            }
        } else if(param->data_ind.handle == prnhandle) {
            if(poshandle > 0) {
                prn2len[prn2tail] = param->data_ind.len;
                memcpy(prn2pos[prn2cur],param->data_ind.data, prn2len[prn2tail]);
                if((prn2tail == prn2head) && !cong[1])
                {
                    cong[1] = 1;
                    esp_spp_write(poshandle, prn2len[prn2tail], prn2pos[prn2tail]);
                }
                prn2tail++ ; if(prn2tail>15) prn2tail=0;
            }
        }
        break;
    case ESP_SPP_CONG_EVT:
//#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
        ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT to %lu  cong=%d", (unsigned long)param->cong.handle,param->cong.cong);
//#endif
        if(param->cong.handle == poshandle) {
            cong[1] = param->cong.cong;
        } else {
            cong[0] = param->cong.cong;
        }
        if (param->cong.cong == 0) {
            if(param->cong.handle == poshandle) {
                if(wait4cong[1])
                {
                    wait4cong[1] = 0;
                    if(prn2head != prn2tail)
                    {
                        prn2head++; if(prn2head>15) prn2head=0;
                    }
                    if(prn2head != prn2tail)
                    {
                        cong[1] = 1;
                        esp_spp_write(param->cong.handle, prn2len[prn2head], prn2pos[prn2head]);
                    }
                }
            } else if(param->cong.handle == prnhandle) {
                if(wait4cong[0])
                {
                    wait4cong[0] = 0;
                    if(pos2head != pos2tail)
                    {
                        pos2head++; if(pos2head>31) pos2head=0;
                    }
                    if(pos2head != pos2tail)
                    {
                        ESP_LOGI(SPP_TAG, "Write to printer %lu,%d,%d",
                            (unsigned long)param->cong.handle, pos2len[pos2head], pos2head);
                        cong[0] =  1;
                        esp_spp_write(param->cong.handle, pos2len[pos2head], pos2prn[pos2head]);
                        uart_write_bytes(UART_NUM_0, pos2prn[pos2head], pos2len[pos2head]);
                    }
                }
            }

        }
        break;
    case ESP_SPP_WRITE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT to %lu len=%lu cong=%lu", 
            (unsigned long)param->write.handle,(unsigned long)param->write.len , (unsigned long)param->write.cong);

        if(param->write.handle == poshandle) {
            cong[1] = param->write.cong;
        } else {
            cong[0] = param->write.cong;
        }
        if (param->write.cong == 0) {
            if(param->write.handle == poshandle) {
                if(prn2head != prn2tail)
                {
                    prn2head++; if(prn2head>15) prn2head=0;
                }
                if(prn2head != prn2tail)
                {
                    cong[1] = 1;
                    esp_spp_write(param->write.handle, prn2len[prn2head], prn2pos[prn2head]);
                }
            } else if(param->write.handle == prnhandle) {
                if(pos2head != pos2tail)
                {
                    pos2head++; if(pos2head>31) pos2head=0;
                }
                if(pos2head != pos2tail)
                {
                    ESP_LOGI(SPP_TAG, "Write to printer %lu,%d,%d",
                        (unsigned long)param->write.handle, pos2len[pos2head], pos2head);
                    cong[0] = 1;
                    esp_spp_write(param->write.handle, pos2len[pos2head], pos2prn[pos2head]);
                    uart_write_bytes(UART_NUM_0, pos2prn[pos2head], pos2len[pos2head]);
                }
            }
        } else {
            if(param->write.handle == poshandle) {
                wait4cong[1] =1;
            } else if(param->write.handle == prnhandle) {
                wait4cong[0] =1;
            }
        }
        break;
    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT handle : %lu,%lu,%lu",(unsigned long)param->srv_open.handle,(unsigned long)param->srv_open.new_listen_handle,(unsigned long)prnhandle);
        poshandle = param->srv_open.handle;
        cong[1] = 0;
        if(prnhandle<=0) {
            esp_spp_connect(sec_mask, role_master, prnch, peer_bd_addr);
        }
        break;
    case ESP_SPP_UNINIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_UNINIT_EVT");
        break;
    default:
        ESP_LOGI(SPP_TAG, "SPP UNKNOWN EVENT %lu",(unsigned long)event);
        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);
        int i;
        for (i=0;i<ESP_BD_ADDR_LEN;i++){
            if(param->disc_res.bda[i] != peer_bd_addr[i])
                break;
        }

        if(i>=ESP_BD_ADDR_LEN) {
            esp_spp_start_discovery(peer_bd_addr);
            esp_bt_gap_cancel_discovery();
            break;
        }

        for (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);
                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);
                    esp_spp_start_discovery(peer_bd_addr);
                    esp_bt_gap_cancel_discovery();
                }
            }
        }
        break;
    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_STATE_CHANGED_EVT");
        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;
    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:%lu", (unsigned long)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:%lu", (unsigned long)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: 0000");
            esp_bt_pin_code_t pin_code;
            pin_code[0] = '0';
            pin_code[1] = '0';
            pin_code[2] = '0';
            pin_code[3] = '0';
            esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
        }
        break;
    }

#if (CONFIG_BT_SSP_ENABLED == true)
    case ESP_BT_GAP_CFM_REQ_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %lu", (unsigned long)param->cfm_req.num_val);
        ESP_LOGW(SPP_TAG, "To confirm the value, type `spp ok;`");
        break;
    case ESP_BT_GAP_KEY_NOTIF_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%lu", (unsigned long)param->key_notif.passkey);
        ESP_LOGW(SPP_TAG, "Waiting responce...");
        break;
    case ESP_BT_GAP_KEY_REQ_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
        ESP_LOGW(SPP_TAG, "To input the key, type `spp key xxxxxx;`");
        break;
#endif

    case ESP_BT_GAP_MODE_CHG_EVT:
        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%lu", (unsigned long)param->mode_chg.mode);
        break;

    default:
        ESP_LOGI(SPP_TAG,"GAP UNKNOWN EVENT: %lu",(unsigned long)event);
        break;
    }
}

int bt_init()
{
    esp_err_t 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 -1;
    }

    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 -1;
    }

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

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

int gap_init()
{
    esp_err_t ret;

    esp_bt_cod_t siscod;

    siscod.major   = esp_bt_gap_get_cod_major_dev(0x040680);
    siscod.minor   = esp_bt_gap_get_cod_minor_dev(0x040680);
    siscod.service = esp_bt_gap_get_cod_srvc(0x040680);

    ESP_LOGI(SPP_TAG, "COD : %x-%x-%x\n",siscod.major,siscod.minor,siscod.service);

    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 -1;
    }

    //esp_bt_gap_set_cod(siscod, ESP_BT_INIT_COD);
    //esp_bt_gap_set_cod(siscod, ESP_BT_CLR_COD_SERVICE_CLASS);
    if ((ret = esp_bt_gap_set_cod(siscod, ESP_BT_INIT_COD)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s gap set cod failed: %s\n", __func__, esp_err_to_name(ret));
    }

    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 -1;
    }
    return 0;
}

int spp_init()
{
    esp_err_t ret;

    if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
        return -1;
    }

#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_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
    if (iocap == ESP_BT_IO_CAP_IN || iocap == ESP_BT_IO_CAP_IO) {
        console_uart_init();
    }
#endif

    /*
     * 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 = {0,0,0,0};
    esp_bt_gap_set_pin(ESP_BT_PIN_TYPE_FIXED, 4, pin_code);
    return 0;
}

void app_main(void)
{
    //zero-initialize the config structure.
    gpio_config_t io_conf = {};
    //disable interrupt
    io_conf.intr_type = GPIO_INTR_DISABLE;
    //set as output mode
    io_conf.mode = GPIO_MODE_OUTPUT;
    //bit mask of the pins that you want to set,e.g.GPIO18/19
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    //disable pull-down mode
    io_conf.pull_down_en = 0;
    //disable pull-up mode
    io_conf.pull_up_en = 0;
    //configure GPIO with the given settings
    gpio_config(&io_conf);

    /*
    for (int i = 0; i < SPP_DATA_LEN; ++i) {
        spp_data[i] = i;
    }
    */
    memset((void *)spp_data,0,SPP_DATA_LEN);
    sprintf((char *)spp_data,"Testing Printer Tapper\r\nESP32\r\n=============\r\n");

    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 );

    int r = bt_init();
    if(r<0)
        return;

    r = gap_init();
    if(r<0)
        return;

    r = spp_init();
    if(r<0)
        return;

    console_uart_init();

    printf("Tapper START\r\n");
    xTaskCreate(ledblink, "LED bliker", 2048, NULL, 10, NULL);
    while(1) {
        sleep(1);
    }
}
sueng66 commented 1 year ago

Done, I've inserted the esp_bt_gap_set_cod(siscod, ESP_BT_INIT_COD) between :

        esp_bt_dev_set_device_name(DEVICE_NAME);
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
BetterJincheng commented 1 year ago

@sueng66 Thanks for your reporting. Turn to us any time.

sueng66 commented 1 year ago

the question is why setting cod must be done just before setting scan mode, why could not be done way before it (in my case in init state) ? maybe the documentation should be update to clarify it

BetterJincheng commented 1 year ago

@sueng66 In user code spp_init() , some initialization will be done. In function bta_jv_enable() in stack, cod.major and cod_minor will be initialized.

void bta_jv_enable(tBTA_JV_MSG *p_data)
{
    tBTA_UTL_COD   cod;

    tBTA_JV_STATUS status = BTA_JV_SUCCESS;
    bta_jv_cb.p_dm_cback = p_data->enable.p_cback;
    bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, (tBTA_JV *)&status, 0);
    memset(bta_jv_cb.free_psm_list, 0, sizeof(bta_jv_cb.free_psm_list));

    /* Set the Class of Device */
    cod.major = BTM_COD_MAJOR_UNCLASSIFIED;
    cod.minor = BTM_COD_MINOR_UNCLASSIFIED;
    utl_set_device_class(&cod, BTA_UTL_SET_COD_MAJOR_MINOR);
}

So, when you set the cod before spp_init, it will be overwritten to default values.

A suggestion is that setting the cod after spp_init(), which is after the arrival of the event of ESP_SPP_INIT_EVT.

sueng66 commented 1 year ago

thanks for the clarification, I think it's should be put at the documentation

BetterJincheng commented 1 year ago

@sueng66 We will improve the document. Thank!