Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion components/example_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
set(component_requires esp_netif nvs_flash esp_wifi)

if("${IDF_TARGET}" STREQUAL "esp32p4")
list(APPEND component_requires ethernet_init esp_eth)
endif()

idf_component_register(
SRC_DIRS ./src
INCLUDE_DIRS ./include
PRIV_REQUIRES esp_netif esp_wifi nvs_flash
PRIV_REQUIRES ${component_requires}
)
4 changes: 4 additions & 0 deletions components/example_utils/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ menu "LiveKit Example Utilities"
bool "WiFi"
help
Connect to the internet using WiFi.
config LK_EXAMPLE_USE_ETHERNET
bool "Ethernet"
help
Connect to the internet using Ethernet (supported boards only).
endchoice
config LK_EXAMPLE_WIFI_SSID
depends on LK_EXAMPLE_USE_WIFI
Expand Down
2 changes: 1 addition & 1 deletion components/example_utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Establish a network connection with a single function call, configured via _Kcon
### Supported Interfaces

- [x] WiFi
- [ ] Ethernet (*TODO*)
- [x] Ethernet (ESP32-P4 only)

### Usage

Expand Down
7 changes: 6 additions & 1 deletion components/example_utils/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ discussion: https://livekit.io/join-slack/
license: Apache-2.0
dependencies:
idf: ">=5.4"
espressif/ethernet_init:
version: "1.2.0"
rules:
- if: "idf_version >=5.4.3,!=5.5.0,!=5.5.1 && target in [esp32p4]"
# IDF version restriction comes from the ethernet_init component
files:
use_gitignore: true
use_gitignore: true
223 changes: 164 additions & 59 deletions components/example_utils/src/livekit_example_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@
* limitations under the License.
*/

#include <string.h>
#include <nvs_flash.h>
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "freertos/FreeRTOS.h"
#include <nvs_flash.h>
#include <string.h>

#if CONFIG_LK_EXAMPLE_USE_WIFI
#include "esp_wifi.h"
#elif CONFIG_LK_EXAMPLE_USE_ETHERNET
#include "esp_eth.h"
#include "ethernet_init.h"
#endif

#include "livekit_example_net.h"

Expand All @@ -38,56 +46,78 @@ typedef struct {

static network_connect_t state = {};

// MARK: - Event handler

static void event_handler(void* arg,
esp_event_base_t event_base,
int32_t event_id,
void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES < 0 || state.retry_attempt < CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES) {
ESP_LOGI(TAG, "Retry: attempt=%d", state.retry_attempt + 1);
esp_wifi_connect();
state.retry_attempt++;
return;
}
ESP_LOGE(TAG, "Unable to establish connection");
xEventGroupSetBits(state.event_group, NETWORK_EVENT_FAILED);
} else if (event_base == IP_EVENT &&
event_id == IP_EVENT_STA_GOT_IP) {
// MARK: - Common

ip_event_got_ip_t* event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "Connected: ip=" IPSTR ", gateway=" IPSTR,
IP2STR(&event->ip_info.ip), IP2STR(&event->ip_info.gw));
static void ip_event_handler(
void* arg,
esp_event_base_t event_base,
int32_t event_id,
void* event_data
) {
ip_event_got_ip_t* event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "Connected: ip=" IPSTR ", gateway=" IPSTR,
IP2STR(&event->ip_info.ip), IP2STR(&event->ip_info.gw));

state.retry_attempt = 0;
xEventGroupSetBits(state.event_group, NETWORK_EVENT_CONNECTED);
}
state.retry_attempt = 0;
xEventGroupSetBits(state.event_group, NETWORK_EVENT_CONNECTED);
}

// MARK: - Initialization & connection

static inline void init_common(void)
{
if (!state.event_group) {
state.event_group = xEventGroupCreate();
}

ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
}

esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip
));
static inline bool wait_for_connection_or_failure(void)
{
EventBits_t bits;
do {
bits = xEventGroupWaitBits(
state.event_group,
NETWORK_EVENT_CONNECTED | NETWORK_EVENT_FAILED,
pdFALSE,
pdFALSE,
portMAX_DELAY
);
if (bits & NETWORK_EVENT_CONNECTED) {
return true;
}
} while (!(bits & NETWORK_EVENT_FAILED));
return false;
}


// MARK: - WiFi
#if CONFIG_LK_EXAMPLE_USE_WIFI

static void wifi_event_handler(
void* arg,
esp_event_base_t event_base,
int32_t event_id,
void* event_data
) {
switch (event_id) {
case WIFI_EVENT_STA_START:
esp_wifi_connect();
break;
case WIFI_EVENT_STA_DISCONNECTED:
if (CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES < 0 ||
state.retry_attempt < CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES) {
ESP_LOGI(TAG, "Retry: attempt=%d", state.retry_attempt + 1);
esp_wifi_connect();
state.retry_attempt++;
return;
}
ESP_LOGE(TAG, "Unable to establish connection");
xEventGroupSetBits(state.event_group, NETWORK_EVENT_FAILED);
break;
default:
break;
}
}

static inline bool connect_wifi(void)
Expand All @@ -107,13 +137,17 @@ static inline bool connect_wifi(void)
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));

esp_event_handler_instance_t instance_any_id;
ESP_ERROR_CHECK(esp_event_handler_instance_register(
ESP_ERROR_CHECK(esp_event_handler_register(
WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id
&wifi_event_handler,
NULL
));
ESP_ERROR_CHECK(esp_event_handler_register(
IP_EVENT,
IP_EVENT_STA_GOT_IP,
&ip_event_handler,
NULL
));

wifi_config_t wifi_config = {};
Expand All @@ -130,30 +164,101 @@ static inline bool connect_wifi(void)
return true;
}

static inline bool wait_for_connection_or_failure(void)
// MARK: - Ethernet
#elif CONFIG_LK_EXAMPLE_USE_ETHERNET

static void eth_event_handler(
void* arg,
esp_event_base_t event_base,
int32_t event_id,
void* event_data
) {
uint8_t mac_addr[6] = { 0 };
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;

switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
ESP_LOGD(TAG, "Ethernet Link Up");
break;
case ETHERNET_EVENT_DISCONNECTED:
if (CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES < 0 ||
state.retry_attempt < CONFIG_LK_EXAMPLE_NETWORK_MAX_RETRIES) {
ESP_LOGI(TAG, "Retry: attempt=%d", state.retry_attempt + 1);
state.retry_attempt++;
return;
}
ESP_LOGE(TAG, "Unable to establish connection");
xEventGroupSetBits(state.event_group, NETWORK_EVENT_FAILED);
break;
default:
break;
}
}

static inline bool connect_ethernet(void)
{
EventBits_t bits;
do {
bits = xEventGroupWaitBits(
state.event_group,
NETWORK_EVENT_CONNECTED | NETWORK_EVENT_FAILED,
pdFALSE,
pdFALSE,
portMAX_DELAY
);
if (bits & NETWORK_EVENT_CONNECTED) {
return true;
static esp_eth_handle_t *handles = NULL;

uint8_t port_count = 0;
ESP_ERROR_CHECK(ethernet_init_all(&handles, &port_count));

if (port_count == 1) {
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(handles[0])));
} else {
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config_t cfg_spi = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < port_count; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), num_str);
strcat(strcpy(if_desc_str, "eth"), num_str);
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio -= i * 5;
esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(handles[i])));
}
} while (!(bits & NETWORK_EVENT_FAILED));
return false;
}
ESP_ERROR_CHECK(esp_event_handler_register(
ETH_EVENT,
ESP_EVENT_ANY_ID,
&eth_event_handler,
NULL
));
ESP_ERROR_CHECK(esp_event_handler_register(
IP_EVENT,
IP_EVENT_ETH_GOT_IP,
&ip_event_handler,
NULL
));
for (int i = 0; i < port_count; i++) {
ESP_ERROR_CHECK(esp_eth_start(handles[i]));
}
ESP_LOGI(TAG, "Connecting Ethernet");
return true;
}
#endif

// MARK: - Public API

bool lk_example_network_connect()
{
init_common();
if (!connect_wifi()) {
bool success = false;
#if CONFIG_LK_EXAMPLE_USE_WIFI
success = connect_wifi();
#elif CONFIG_LK_EXAMPLE_USE_ETHERNET
success = connect_ethernet();
#endif
if (!success) {
return false;
}
return wait_for_connection_or_failure();
Expand Down
6 changes: 6 additions & 0 deletions components/livekit/examples/minimal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ CONFIG_LK_EXAMPLE_WIFI_SSID="<your SSID>"
CONFIG_LK_EXAMPLE_WIFI_PASSWORD="<your password>"
```

Or using Ethernet (ESP32-P4 only):

```ini
CONFIG_LK_EXAMPLE_USE_ETHERNET=y
```

### Development Board

This example uses the Espressif [*codec_board*](https://components.espressif.com/components/tempotian/codec_board/) component to access board-specific peripherals for media capture and rendering. Supported boards are [defined here](https://github.com/espressif/esp-webrtc-solution/blob/65d13427dd83c37264b6cff966d60af0f84f649c/components/codec_board/board_cfg.txt). Locate the name of your board, and set it as follows:
Expand Down
6 changes: 6 additions & 0 deletions components/livekit/examples/minimal_video/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ CONFIG_LK_EXAMPLE_WIFI_SSID="<your SSID>"
CONFIG_LK_EXAMPLE_WIFI_PASSWORD="<your password>"
```

Or using Ethernet (ESP32-P4 only):

```ini
CONFIG_LK_EXAMPLE_USE_ETHERNET=y
```

### Development Board

This example uses the Espressif [*codec_board*](https://components.espressif.com/components/tempotian/codec_board/) component to access board-specific peripherals for media capture and rendering. Supported boards are [defined here](https://github.com/espressif/esp-webrtc-solution/blob/65d13427dd83c37264b6cff966d60af0f84f649c/components/codec_board/board_cfg.txt). Locate the name of your board, and set it as follows:
Expand Down
6 changes: 6 additions & 0 deletions components/livekit/examples/voice_agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ CONFIG_LK_EXAMPLE_WIFI_SSID="<your SSID>"
CONFIG_LK_EXAMPLE_WIFI_PASSWORD="<your password>"
```

Or using Ethernet (ESP32-P4 only):

```ini
CONFIG_LK_EXAMPLE_USE_ETHERNET=y
```

### Development Board

By default, this example targets the [ESP32-S3-Korvo-2](https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/dev-boards/user-guide-esp32-s3-korvo-2.html) development board, using its corresponding [board support package](https://components.espressif.com/components/espressif/esp32_s3_korvo_2/) (BSP) to access the LED peripherals for the agent to control. If you wish to target a different board, this dependency can be easily removed or replaced.
Expand Down
Loading