esp-adf icon indicating copy to clipboard operation
esp-adf copied to clipboard

The Coze platform uses the wss protocol, but I couldn’t find where to configure the certificate. No server verification option set in esp_tls_cfg_t structure (AUD-6456)

Open skipify opened this issue 6 months ago • 1 comments

The Coze platform uses the wss protocol, but I couldn’t find where to configure the certificate. The URL I’m using is: wss://ws.coze.cn/v1/chat?bot_id=7480067804642050059

I also noticed that in the esp_coze component, the libcoze_websocket.a library is not open source, so currently I have no way of knowing where or how to configure the certificate.

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_log.h"
#include "esp_flash.h"
#include "esp_system.h"

#include "nvs_flash.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "protocol_examples_utils.h"
#include "esp_opus_dec.h"

#include "driver/i2s_std.h"
#include "driver/i2s_tdm.h"
#include "soc/soc_caps.h"

#include "esp_codec_dev.h"
#include "esp_codec_dev_defaults.h"

#include "esp_coze_chat.h"
#include "driver/i2c_master.h"

// I2C
#define ESP_GMF_I2C_SDA_IO_NUM      (GPIO_NUM_0)
#define ESP_GMF_I2C_SCL_IO_NUM      (GPIO_NUM_1)

// I2S
#define ESP_GMF_I2S_DAC_MCLK_IO_NUM (GPIO_NUM_10)
#define ESP_GMF_I2S_DAC_BCLK_IO_NUM (GPIO_NUM_8)
#define ESP_GMF_I2S_DAC_WS_IO_NUM   (GPIO_NUM_12)
#define ESP_GMF_I2S_DAC_DO_IO_NUM   (GPIO_NUM_11)
#define ESP_GMF_I2S_DAC_DI_IO_NUM   (GPIO_NUM_7)

// #define ESP_GMF_I2S_ADC_MCLK_IO_NUM (GPIO_NUM_10)
// #define ESP_GMF_I2S_ADC_BCLK_IO_NUM (GPIO_NUM_8)
// #define ESP_GMF_I2S_ADC_WS_IO_NUM   (GPIO_NUM_12)
// #define ESP_GMF_I2S_ADC_DO_IO_NUM   (GPIO_NUM_7)
// #define ESP_GMF_I2S_ADC_DI_IO_NUM   (GPIO_NUM_11)
// PA
#define ESP_GMF_AMP_IO_NUM          (GPIO_NUM_13)

static const char *TAG = "COZE_TEST";

typedef struct {
    i2s_chan_handle_t tx_handle;
    i2s_chan_handle_t rx_handle;
} i2s_keep_t;
static i2s_keep_t i2s_keep;
static i2c_master_bus_handle_t i2c_bus_handle;
static void *ops_dec_handle;



static esp_codec_dev_handle_t codec_dev;
static esp_codec_dev_handle_t codec_dev_ply;
static uint8_t *opus_data = NULL;
static uint32_t opus_data_len = 0;

static int ut_i2c_init()
{
    i2c_master_bus_config_t i2c_bus_config = {0};
    i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
    i2c_bus_config.i2c_port = 0;
    i2c_bus_config.scl_io_num = ESP_GMF_I2C_SCL_IO_NUM;
    i2c_bus_config.sda_io_num = ESP_GMF_I2C_SDA_IO_NUM;
    i2c_bus_config.glitch_ignore_cnt = 7;
    i2c_bus_config.flags.enable_internal_pullup = true;
    return i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
}


static int ut_i2s_init(uint8_t port)
{

    // Already installed
    i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
    i2s_std_config_t std_cfg = {
        .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
        .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(16, I2S_SLOT_MODE_MONO),
        .gpio_cfg ={
            .mclk = ESP_GMF_I2S_DAC_MCLK_IO_NUM,
            .bclk = ESP_GMF_I2S_DAC_BCLK_IO_NUM,
            .ws = ESP_GMF_I2S_DAC_WS_IO_NUM,
            .dout = ESP_GMF_I2S_DAC_DO_IO_NUM,
            .din = ESP_GMF_I2S_DAC_DI_IO_NUM,
        },
    };
    int ret = i2s_new_channel(&chan_cfg, &i2s_keep.tx_handle, &i2s_keep.rx_handle);
    ret = i2s_channel_init_std_mode(i2s_keep.tx_handle, &std_cfg);
    ret = i2s_channel_init_std_mode(i2s_keep.rx_handle, &std_cfg);
 
    i2s_channel_enable(i2s_keep.tx_handle);

    return ret;
}


esp_err_t audio_codec_init()
{
    int ret = ut_i2c_init();
    ret = ut_i2s_init(0);

    // Do initialize of related interface: data_if, ctrl_if and gpio_if
    audio_codec_i2s_cfg_t i2s_cfg = {
        .rx_handle = i2s_keep.rx_handle,
        .tx_handle = i2s_keep.tx_handle,
    };
    const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg);

    audio_codec_i2c_cfg_t i2c_cfg = {.addr = ES8311_CODEC_DEFAULT_ADDR};
    i2c_cfg.bus_handle = i2c_bus_handle;
    const audio_codec_ctrl_if_t *out_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);


    const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();
    // New output codec interface
    es8311_codec_cfg_t es8311_cfg = {
        .codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH,
        .ctrl_if = out_ctrl_if,
        .gpio_if = gpio_if,
        .pa_pin = ESP_GMF_AMP_IO_NUM,
        .use_mclk = true,
    };
    const audio_codec_if_t *out_codec_if = es8311_codec_new(&es8311_cfg);

    esp_codec_dev_cfg_t codec_dev_cfg = {
        .codec_if = out_codec_if,
        .data_if = data_if,
        .dev_type = ESP_CODEC_DEV_TYPE_IN,
    };

    codec_dev = esp_codec_dev_new(&codec_dev_cfg);
    esp_codec_dev_cfg_t codec_dev_cfg_ply = {
        .codec_if = out_codec_if,
        .data_if = data_if,
        .dev_type = ESP_CODEC_DEV_TYPE_OUT,
    };
    codec_dev_ply = esp_codec_dev_new(&codec_dev_cfg_ply);
    return ret;
}

static void audio_event_callback(esp_coze_chat_event_t event, char *data, void *ctx)
{
    if (event == ESP_COZE_CHAT_EVENT_CHAT_SPEECH_STARTED) {
        ESP_LOGI(TAG, "chat start");
    } else if (event == ESP_COZE_CHAT_EVENT_CHAT_SPEECH_STOPED) {
        ESP_LOGI(TAG, "chat stop");
    } else if (event == ESP_COZE_CHAT_EVENT_CHAT_CUSTOMER_DATA) {
        // cjson format data
        ESP_LOGI(TAG, "Customer data: %s", data);
    } else if (event == ESP_COZE_CHAT_EVENT_CHAT_SUBTITLE_EVENT) {
        ESP_LOGI(TAG, "Subtitle data: %s", data);
    }
}

static void audio_data_callback(char *data, int len, void *ctx)
{
    // output raw opus data
    esp_audio_dec_in_raw_t in_raw = {
        .buffer = (uint8_t *)data,
        .len = len,
        .consumed = 0,
    };
    esp_audio_dec_info_t dec_info = {0};
_retry:
    esp_audio_dec_out_frame_t out_frame = {
        .buffer = opus_data,
        .len = opus_data_len,
        .needed_size = 0,
        .decoded_size = 0,
    };
    esp_audio_err_t res = esp_opus_dec_decode(ops_dec_handle, &in_raw, &out_frame, &dec_info);
    if (res == ESP_AUDIO_ERR_BUFF_NOT_ENOUGH) {
        ESP_LOGW(TAG, "Memory lack, need re-allocate");
        opus_data = realloc(opus_data, out_frame.needed_size);
        opus_data_len = out_frame.needed_size;
        goto _retry;
    }
    if (res == ESP_AUDIO_ERR_OK) {
        ESP_LOGI(TAG, "Decoded size: %d", (int)out_frame.decoded_size);
    } else {
        ESP_LOGE(TAG, "Decode failed, err: %d", res);
    }
    esp_codec_dev_write(codec_dev_ply, out_frame.buffer, out_frame.decoded_size);
}
#include "driver/gpio.h"
void app_main(void)
{
    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_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
    ESP_ERROR_CHECK(example_connect());
    ESP_LOGI(TAG, "Connected to AP, begin http example");
    audio_codec_init();

    esp_opus_dec_cfg_t ops_dec_cfg = ESP_OPUS_DEC_CONFIG_DEFAULT();
    ops_dec_cfg.sample_rate = 16000;
    ops_dec_cfg.channel = 1;
    ops_dec_cfg.frame_duration = ESP_OPUS_DEC_FRAME_DURATION_60_MS;
    ops_dec_cfg.self_delimited = false;
    esp_opus_dec_open(&ops_dec_cfg, sizeof(ops_dec_cfg), &ops_dec_handle);

    opus_data= malloc(1024);
    opus_data_len = 1024;

    esp_coze_chat_config_t chat_config = ESP_COZE_CHAT_DEFAULT_CONFIG();
    chat_config.bot_id = "7480067804642050059";
    chat_config.pull_task_caps = MALLOC_CAP_INTERNAL;
    chat_config.push_task_caps = MALLOC_CAP_INTERNAL;
    chat_config.push_task_core = 0;
    chat_config.pull_task_core = 0;
    chat_config.pull_task_stack_size = 42 * 1024;
    chat_config.access_token = "pat_FRF6d2kjfa5e74rDweuL5S7GFIv9QS5UUNxYUmLjA6x0DHhIQ9pMERHIdarjAPGO";
    chat_config.audio_callback = audio_data_callback;
    chat_config.event_callback = audio_event_callback;
    esp_coze_chat_handle_t chat = NULL;

    ret = esp_coze_chat_init(&chat_config, &chat);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "esp_coze_chat_init failed, err: %d", ret);
        return;
    }
    esp_coze_chat_start(chat);

    esp_codec_dev_sample_info_t fs = {
        .sample_rate = 16000,
        .channel = 1,
        .bits_per_sample = 16,
    };

    esp_codec_dev_open(codec_dev, &fs);
    esp_codec_dev_open(codec_dev_ply, &fs);

    char *data = (char *) malloc(512);
    while (1) {
        esp_codec_dev_read(codec_dev, data, 512);
        // esp_codec_dev_write(codec_dev_ply, data, 512);
        esp_coze_chat_send_audio_data(chat, data, 512);
        printf("1-> %d\n", gpio_get_level(ESP_GMF_AMP_IO_NUM));
        gpio_set_level(ESP_GMF_AMP_IO_NUM, 1);
        printf("heap: %ld, total: %ld\n", esp_get_minimum_free_heap_size(), esp_get_free_heap_size());
    }
}



output log:

I (10590) ES8311: Work in Slave mode I (10597) ESP_COZE_CHAT: wss_url: wss://ws.coze.cn/v1/chat?bot_id=7480067804642050059 I (10598) ESP_COZE_CHAT: token: Bearer pat_FRF6d2kjfa5e74rDweuL5S7GFIv9QS5UUNxYUmLjA6x0DHhIQ9pMERHIdarjAPGO I (10605) ESP_COZE_CHAT: WEBSOCKET_EVENT_BEGIN I (10609) websocket_client: Started E (10627) esp-tls-mbedtls: No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference E (10628) esp-tls-mbedtls: Failed to set client configurations, returned [0x8017] (ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) E (10640) esp-tls: create_ssl_handle failed E (10644) esp-tls: Failed to open new connection E (10649) transport_base: Failed to open a new connection E (10658) transport_ws: Error connecting to host ws.coze.cn:443 E (10662) websocket_client: esp_transport_connect() failed with -1, transport_error=ESP_ERR_MBEDTLS_SSL_SETUP_FAILED, tls_error_code=0, tls_flags=0, esp_ws_handshake_status_code=0, errno=119 E (10680) ESP_COZE_CHAT: WEBSOCKET_EVENT_ERROR I (10684) websocket_client: Reconnect after 1000 ms I (10689) ESP_COZE_CHAT: WEBSOCKET_EVENT_DISCONNECTED E (10694) ESP_COZE_CHAT: Last error reported from esp-tls: 0x8017

skipify avatar Jun 18 '25 10:06 skipify

Hi @skipify Try this one, it contains HTTP requests esp_coze_v0.6.tar.gz

shootao avatar Jun 20 '25 07:06 shootao

esp coze v0.6 has been released on 5770ffd7e262dca6b682c9692d22b473325c74e2

jason-mao avatar Jul 17 '25 03:07 jason-mao