Skip to content

Commit 5770ffd

Browse files
committed
Merge branch 'feature/update_esp_coze_2_v0.6' into 'master'
esp_coze: update esp_coze to version v0.6.0 See merge request adf/esp-adf-internal!1407
2 parents 87aa596 + 88ba408 commit 5770ffd

File tree

15 files changed

+562
-60
lines changed

15 files changed

+562
-60
lines changed

.github/workflows/upload_component.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@ jobs:
1818
directories: >
1919
components/esp_codec_dev;
2020
components/esp_coze;
21-
examples/ai_agent/coze_ws_app;
2221
namespace: "espressif"
2322
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

components/esp_coze/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
# Changelog
2+
3+
## v0.6.0
4+
5+
### Added
6+
7+
- Support for Opus encoding, and G711A/U encoding and decoding.
8+
- JWT authentication support for secure communication.
9+
- API to set custom user parameters.
10+
- Optional `wss` URL and `conversition id URL` connection configuration in the project settings.
11+
- Support websocket event callback.
12+
- New API to configure voice ID.
13+
- APIs to set and retrieve the conversation ID.
14+
15+
### Changed
16+
17+
- Renamed `http_client_request.h` to `esp_coze_utils.h` for better clarity and consistency.
18+
- Added `http_client_post.c` file.
19+
120
## v0.5.1~1
221

322
- Enhanced coze_ws_app example

components/esp_coze/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
set(public_include_dirs "./include")
2-
idf_component_register(INCLUDE_DIRS "${public_include_dirs}")
2+
idf_component_register(INCLUDE_DIRS "${public_include_dirs}"
3+
SRCS "http_client_request.c"
4+
PRIV_REQUIRES esp_http_client
5+
WHOLE_ARCHIVE)
36
add_prebuilt_library(esp_coze "${CMAKE_CURRENT_LIST_DIR}/libs/${CONFIG_IDF_TARGET}/libcoze_websocket.a"
47
PRIV_REQUIRES mbedtls espressif__esp_websocket_client json)
5-
target_link_libraries(${COMPONENT_LIB} INTERFACE esp_coze)
8+
target_link_libraries(${COMPONENT_LIB} INTERFACE esp_coze)
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Espressif Modified MIT License
3+
*
4+
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., LTD
5+
*
6+
* Permission is hereby granted for use **exclusively** with Espressif Systems products.
7+
* This includes the right to use, copy, modify, merge, publish, distribute, and sublicense
8+
* the Software, subject to the following conditions:
9+
*
10+
* 1. This Software **must be used in conjunction with Espressif Systems products**.
11+
* 2. The above copyright notice and this permission notice shall be included in all copies
12+
* or substantial portions of the Software.
13+
* 3. Redistribution of the Software in source or binary form **for use with non-Espressif products**
14+
* is strictly prohibited.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17+
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
18+
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
19+
* FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
* SPDX-License-Identifier: MIT-ESPRESSIF
24+
*/
25+
26+
#include <stdio.h>
27+
#include <string.h>
28+
#include <stdlib.h>
29+
#include <stdint.h>
30+
#include "freertos/FreeRTOS.h"
31+
#include "freertos/event_groups.h"
32+
#include "esp_log.h"
33+
#include "esp_idf_version.h"
34+
#include "esp_http_client.h"
35+
#include "http_client_post.h"
36+
37+
#define DEFAULT_HTTP_BUFFER_SIZE (1024)
38+
#define HTTP_FINISH_BIT (1 << 0)
39+
#define HTTP_TIMEOUT_MS (10000)
40+
41+
static const char *TAG = "HTTP_CLIENT_POST";
42+
43+
typedef struct {
44+
http_response_t *resp;
45+
EventGroupHandle_t eg;
46+
} http_client_ctx_t;
47+
48+
/* HTTP event handler */
49+
static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
50+
{
51+
http_client_ctx_t *ctx = (http_client_ctx_t *)evt->user_data;
52+
static int output_len = 0;
53+
54+
switch (evt->event_id) {
55+
case HTTP_EVENT_ERROR:
56+
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
57+
break;
58+
59+
case HTTP_EVENT_ON_CONNECTED:
60+
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
61+
break;
62+
63+
case HTTP_EVENT_HEADER_SENT:
64+
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
65+
break;
66+
67+
case HTTP_EVENT_ON_HEADER:
68+
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s",
69+
evt->header_key, evt->header_value);
70+
break;
71+
72+
case HTTP_EVENT_ON_DATA:
73+
if (output_len + evt->data_len > ctx->resp->body_len) {
74+
ctx->resp->body = (char *)realloc(ctx->resp->body,
75+
DEFAULT_HTTP_BUFFER_SIZE + ctx->resp->body_len);
76+
ctx->resp->body_len += DEFAULT_HTTP_BUFFER_SIZE;
77+
}
78+
memcpy(ctx->resp->body + output_len, evt->data, evt->data_len);
79+
output_len += evt->data_len;
80+
break;
81+
82+
case HTTP_EVENT_ON_FINISH:
83+
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
84+
output_len = 0;
85+
xEventGroupSetBits(ctx->eg, HTTP_FINISH_BIT);
86+
break;
87+
88+
case HTTP_EVENT_DISCONNECTED:
89+
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
90+
break;
91+
92+
case HTTP_EVENT_REDIRECT:
93+
break;
94+
}
95+
return ESP_OK;
96+
}
97+
98+
esp_err_t http_client_post(const char *url, http_req_header_t *header,
99+
char *body, http_response_t *response)
100+
{
101+
esp_err_t err = ESP_OK;
102+
esp_http_client_handle_t client = NULL;
103+
http_response_t rsp_data = {0};
104+
http_client_ctx_t ctx = {0};
105+
esp_http_client_config_t config = {0};
106+
107+
/* Initialize response buffer */
108+
rsp_data.body = (char *)calloc(1, DEFAULT_HTTP_BUFFER_SIZE);
109+
if (!rsp_data.body) {
110+
ESP_LOGE(TAG, "Failed to allocate response buffer");
111+
return ESP_ERR_NO_MEM;
112+
}
113+
rsp_data.body_len = DEFAULT_HTTP_BUFFER_SIZE;
114+
ctx.resp = &rsp_data;
115+
ctx.eg = xEventGroupCreate();
116+
if (!ctx.eg) {
117+
ESP_LOGE(TAG, "Failed to create event group");
118+
free(rsp_data.body);
119+
return ESP_ERR_NO_MEM;
120+
}
121+
122+
config.buffer_size_tx = 2048;
123+
config.url = url;
124+
config.query = "esp";
125+
config.event_handler = _http_event_handler;
126+
config.user_data = &ctx;
127+
client = esp_http_client_init(&config);
128+
if (!client) {
129+
ESP_LOGE(TAG, "Failed to initialize HTTP client");
130+
goto cleanup;
131+
}
132+
esp_http_client_set_method(client, HTTP_METHOD_POST);
133+
if (header) {
134+
for (int i = 0; header[i].key && header[i].value; i++) {
135+
ESP_LOGD(TAG, "Setting header: %s: %s",
136+
header[i].key, header[i].value);
137+
esp_http_client_set_header(client, header[i].key, header[i].value);
138+
}
139+
}
140+
if (body) {
141+
esp_http_client_set_post_field(client, body, strlen(body));
142+
}
143+
err = esp_http_client_perform(client);
144+
if (err != ESP_OK) {
145+
ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err));
146+
goto cleanup;
147+
}
148+
149+
EventBits_t bits = xEventGroupWaitBits(ctx.eg, HTTP_FINISH_BIT,
150+
pdTRUE, pdFALSE,
151+
pdMS_TO_TICKS(HTTP_TIMEOUT_MS));
152+
if (!(bits & HTTP_FINISH_BIT)) {
153+
ESP_LOGE(TAG, "HTTP request timeout");
154+
err = ESP_ERR_TIMEOUT;
155+
goto cleanup;
156+
}
157+
158+
*response = rsp_data;
159+
160+
esp_http_client_close(client);
161+
esp_http_client_cleanup(client);
162+
vEventGroupDelete(ctx.eg);
163+
return ESP_OK;
164+
165+
cleanup:
166+
if (client) {
167+
esp_http_client_close(client);
168+
esp_http_client_cleanup(client);
169+
}
170+
vEventGroupDelete(ctx.eg);
171+
free(rsp_data.body);
172+
return err;
173+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Espressif Modified MIT License
3+
*
4+
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., LTD
5+
*
6+
* Permission is hereby granted for use **exclusively** with Espressif Systems products.
7+
* This includes the right to use, copy, modify, merge, publish, distribute, and sublicense
8+
* the Software, subject to the following conditions:
9+
*
10+
* 1. This Software **must be used in conjunction with Espressif Systems products**.
11+
* 2. The above copyright notice and this permission notice shall be included in all copies
12+
* or substantial portions of the Software.
13+
* 3. Redistribution of the Software in source or binary form **for use with non-Espressif products**
14+
* is strictly prohibited.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17+
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
18+
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
19+
* FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
* SPDX-License-Identifier: MIT-ESPRESSIF
24+
*/
25+
26+
#include <stdio.h>
27+
#include <string.h>
28+
#include <stdlib.h>
29+
#include <stdint.h>
30+
#include "freertos/FreeRTOS.h"
31+
#include "freertos/event_groups.h"
32+
#include "esp_log.h"
33+
#include "esp_idf_version.h"
34+
#include "esp_http_client.h"
35+
#include "http_client_request.h"
36+
37+
#define DEFAULT_HTTP_BUFFER_SIZE (1024)
38+
#define HTTP_FINISH_BIT (1 << 0)
39+
#define HTTP_TIMEOUT_MS (10000)
40+
41+
static const char *TAG = "HTTP_CLIENT_POST";
42+
43+
typedef struct {
44+
http_response_t *resp;
45+
EventGroupHandle_t eg;
46+
} http_client_ctx_t;
47+
48+
/* HTTP event handler */
49+
static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
50+
{
51+
http_client_ctx_t *ctx = (http_client_ctx_t *)evt->user_data;
52+
static int output_len = 0;
53+
54+
switch (evt->event_id) {
55+
case HTTP_EVENT_ERROR:
56+
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
57+
break;
58+
59+
case HTTP_EVENT_ON_CONNECTED:
60+
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
61+
break;
62+
63+
case HTTP_EVENT_HEADER_SENT:
64+
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
65+
break;
66+
67+
case HTTP_EVENT_ON_HEADER:
68+
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s",
69+
evt->header_key, evt->header_value);
70+
break;
71+
72+
case HTTP_EVENT_ON_DATA:
73+
if (output_len + evt->data_len > ctx->resp->body_len) {
74+
ctx->resp->body = (char *)realloc(ctx->resp->body,
75+
DEFAULT_HTTP_BUFFER_SIZE + ctx->resp->body_len);
76+
ctx->resp->body_len += DEFAULT_HTTP_BUFFER_SIZE;
77+
}
78+
memcpy(ctx->resp->body + output_len, evt->data, evt->data_len);
79+
output_len += evt->data_len;
80+
break;
81+
82+
case HTTP_EVENT_ON_FINISH:
83+
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
84+
output_len = 0;
85+
xEventGroupSetBits(ctx->eg, HTTP_FINISH_BIT);
86+
break;
87+
88+
case HTTP_EVENT_DISCONNECTED:
89+
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
90+
break;
91+
92+
case HTTP_EVENT_REDIRECT:
93+
break;
94+
}
95+
return ESP_OK;
96+
}
97+
98+
esp_err_t http_client_post(const char *url, http_req_header_t *header,
99+
char *body, http_response_t *response)
100+
{
101+
esp_err_t err = ESP_OK;
102+
esp_http_client_handle_t client = NULL;
103+
http_response_t rsp_data = {0};
104+
http_client_ctx_t ctx = {0};
105+
esp_http_client_config_t config = {0};
106+
107+
/* Initialize response buffer */
108+
rsp_data.body = (char *)calloc(1, DEFAULT_HTTP_BUFFER_SIZE);
109+
if (!rsp_data.body) {
110+
ESP_LOGE(TAG, "Failed to allocate response buffer");
111+
return ESP_ERR_NO_MEM;
112+
}
113+
rsp_data.body_len = DEFAULT_HTTP_BUFFER_SIZE;
114+
ctx.resp = &rsp_data;
115+
ctx.eg = xEventGroupCreate();
116+
if (!ctx.eg) {
117+
ESP_LOGE(TAG, "Failed to create event group");
118+
free(rsp_data.body);
119+
return ESP_ERR_NO_MEM;
120+
}
121+
122+
config.buffer_size_tx = 2048;
123+
config.url = url;
124+
config.query = "esp";
125+
config.event_handler = _http_event_handler;
126+
config.user_data = &ctx;
127+
client = esp_http_client_init(&config);
128+
if (!client) {
129+
ESP_LOGE(TAG, "Failed to initialize HTTP client");
130+
goto cleanup;
131+
}
132+
esp_http_client_set_method(client, HTTP_METHOD_POST);
133+
if (header) {
134+
for (int i = 0; header[i].key && header[i].value; i++) {
135+
ESP_LOGD(TAG, "Setting header: %s: %s",
136+
header[i].key, header[i].value);
137+
esp_http_client_set_header(client, header[i].key, header[i].value);
138+
}
139+
}
140+
if (body) {
141+
esp_http_client_set_post_field(client, body, strlen(body));
142+
}
143+
err = esp_http_client_perform(client);
144+
if (err != ESP_OK) {
145+
ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err));
146+
goto cleanup;
147+
}
148+
149+
EventBits_t bits = xEventGroupWaitBits(ctx.eg, HTTP_FINISH_BIT,
150+
pdTRUE, pdFALSE,
151+
pdMS_TO_TICKS(HTTP_TIMEOUT_MS));
152+
if (!(bits & HTTP_FINISH_BIT)) {
153+
ESP_LOGE(TAG, "HTTP request timeout");
154+
err = ESP_ERR_TIMEOUT;
155+
goto cleanup;
156+
}
157+
158+
*response = rsp_data;
159+
160+
esp_http_client_close(client);
161+
esp_http_client_cleanup(client);
162+
vEventGroupDelete(ctx.eg);
163+
return ESP_OK;
164+
165+
cleanup:
166+
if (client) {
167+
esp_http_client_close(client);
168+
esp_http_client_cleanup(client);
169+
}
170+
vEventGroupDelete(ctx.eg);
171+
free(rsp_data.body);
172+
return err;
173+
}

0 commit comments

Comments
 (0)