Initial commit
This commit is contained in:
247
main/boards/common/rndis_board.cc
Normal file
247
main/boards/common/rndis_board.cc
Normal file
@@ -0,0 +1,247 @@
|
||||
#include "rndis_board.h"
|
||||
#include "display.h"
|
||||
#include "application.h"
|
||||
#include "system_info.h"
|
||||
#include "settings.h"
|
||||
#include "assets/lang_config.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <esp_network.h>
|
||||
#include <esp_log.h>
|
||||
#include <utility>
|
||||
#include <font_awesome.h>
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S3
|
||||
|
||||
static const char *TAG = "RndisBoard";
|
||||
#define EVENT_GOT_IP_BIT (1 << 0)
|
||||
|
||||
RndisBoard::RndisBoard() {
|
||||
}
|
||||
|
||||
RndisBoard::~RndisBoard() {
|
||||
}
|
||||
|
||||
std::string RndisBoard::GetBoardType() {
|
||||
return "rndis";
|
||||
}
|
||||
|
||||
void RndisBoard::StartNetwork() {
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
/* NVS partition was truncated and needs to be erased
|
||||
* Retry nvs_flash_init */
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
}
|
||||
/* Initialize default TCP/IP stack */
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
s_event_group = xEventGroupCreate();
|
||||
esp_event_handler_register(IOT_ETH_EVENT, ESP_EVENT_ANY_ID, iot_event_handle, this);
|
||||
esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, iot_event_handle, this);
|
||||
|
||||
// install usbh cdc driver
|
||||
usbh_cdc_driver_config_t config = {
|
||||
.task_stack_size = 1024 * 4,
|
||||
.task_priority = configMAX_PRIORITIES - 1,
|
||||
.task_coreid = 0,
|
||||
.skip_init_usb_host_driver = false,
|
||||
};
|
||||
ESP_ERROR_CHECK(usbh_cdc_driver_install(&config));
|
||||
|
||||
install_rndis(USB_DEVICE_VENDOR_ANY, USB_DEVICE_PRODUCT_ANY, "USB RNDIS0");
|
||||
xEventGroupWaitBits(s_event_group, EVENT_GOT_IP_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
|
||||
}
|
||||
|
||||
|
||||
void RndisBoard::iot_event_handle(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == IOT_ETH_EVENT) {
|
||||
switch (event_id) {
|
||||
case IOT_ETH_EVENT_START:
|
||||
ESP_LOGI(TAG, "IOT_ETH_EVENT_START");
|
||||
break;
|
||||
case IOT_ETH_EVENT_STOP:
|
||||
ESP_LOGI(TAG, "IOT_ETH_EVENT_STOP");
|
||||
break;
|
||||
case IOT_ETH_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "IOT_ETH_EVENT_CONNECTED");
|
||||
static_cast<RndisBoard*>(arg)->OnNetworkEvent(NetworkEvent::Connected);
|
||||
break;
|
||||
case IOT_ETH_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "IOT_ETH_EVENT_DISCONNECTED");
|
||||
xEventGroupClearBits(static_cast<RndisBoard*>(arg)->s_event_group, EVENT_GOT_IP_BIT);
|
||||
static_cast<RndisBoard*>(arg)->OnNetworkEvent(NetworkEvent::Disconnected);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "IOT_ETH_EVENT_UNKNOWN");
|
||||
break;
|
||||
}
|
||||
} else if (event_base == IP_EVENT) {
|
||||
ESP_LOGI(TAG, "GOT_IP");
|
||||
xEventGroupSetBits(static_cast<RndisBoard*>(arg)->s_event_group, EVENT_GOT_IP_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RndisBoard::OnNetworkEvent(NetworkEvent event, const std::string& data) {
|
||||
switch (event) {
|
||||
case NetworkEvent::Connected:
|
||||
ESP_LOGI(TAG, "Connected to WiFi: %s", data.c_str());
|
||||
break;
|
||||
case NetworkEvent::Scanning:
|
||||
ESP_LOGI(TAG, "WiFi scanning");
|
||||
break;
|
||||
case NetworkEvent::Connecting:
|
||||
ESP_LOGI(TAG, "WiFi connecting to %s", data.c_str());
|
||||
break;
|
||||
case NetworkEvent::Disconnected:
|
||||
ESP_LOGW(TAG, "WiFi disconnected");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Notify external callback if set
|
||||
if (network_event_callback_) {
|
||||
network_event_callback_(event, data);
|
||||
}
|
||||
}
|
||||
|
||||
void RndisBoard::SetNetworkEventCallback(NetworkEventCallback callback) {
|
||||
network_event_callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void RndisBoard::install_rndis(uint16_t idVendor, uint16_t idProduct, const char *netif_name)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
iot_eth_handle_t eth_handle = nullptr;
|
||||
iot_eth_netif_glue_handle_t glue = nullptr;
|
||||
|
||||
usb_device_match_id_t *dev_match_id = (usb_device_match_id_t*)calloc(2, sizeof(usb_device_match_id_t));
|
||||
dev_match_id[0].match_flags = USB_DEVICE_ID_MATCH_VID_PID;
|
||||
dev_match_id[0].idVendor = idVendor;
|
||||
dev_match_id[0].idProduct = idProduct;
|
||||
memset(&dev_match_id[1], 0, sizeof(usb_device_match_id_t)); // end of list
|
||||
iot_usbh_rndis_config_t rndis_cfg = {
|
||||
.match_id_list = dev_match_id,
|
||||
};
|
||||
|
||||
ret = iot_eth_new_usb_rndis(&rndis_cfg, &rndis_eth_driver);
|
||||
if (ret != ESP_OK || rndis_eth_driver == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create USB RNDIS driver");
|
||||
return;
|
||||
}
|
||||
|
||||
iot_eth_config_t eth_cfg = {
|
||||
.driver = rndis_eth_driver,
|
||||
.stack_input = NULL,
|
||||
};
|
||||
ret = iot_eth_install(ð_cfg, ð_handle);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to install USB RNDIS driver");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_netif_inherent_config_t _inherent_eth_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
_inherent_eth_config.if_key = netif_name;
|
||||
_inherent_eth_config.if_desc = netif_name;
|
||||
esp_netif_config_t netif_cfg = {
|
||||
.base = &_inherent_eth_config,
|
||||
.driver = NULL,
|
||||
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH,
|
||||
};
|
||||
s_rndis_netif = esp_netif_new(&netif_cfg);
|
||||
if (s_rndis_netif == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create network interface");
|
||||
return;
|
||||
}
|
||||
|
||||
glue = iot_eth_new_netif_glue(eth_handle);
|
||||
if (glue == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create netif glue");
|
||||
return;
|
||||
}
|
||||
esp_netif_attach(s_rndis_netif, glue);
|
||||
iot_eth_start(eth_handle);
|
||||
}
|
||||
|
||||
|
||||
NetworkInterface* RndisBoard::GetNetwork() {
|
||||
static EspNetwork network;
|
||||
return &network;
|
||||
}
|
||||
|
||||
const char* RndisBoard::GetNetworkStateIcon() {
|
||||
return FONT_AWESOME_SIGNAL_STRONG;
|
||||
}
|
||||
|
||||
std::string RndisBoard::GetBoardJson() {
|
||||
|
||||
std::string json = R"({"type":")" + std::string(BOARD_TYPE) + R"(",)";
|
||||
json += R"("name":")" + std::string(BOARD_NAME) + R"(",)";
|
||||
|
||||
json += R"("mac":")" + SystemInfo::GetMacAddress() + R"("})";
|
||||
return json;
|
||||
}
|
||||
|
||||
void RndisBoard::SetPowerSaveLevel(PowerSaveLevel level) {
|
||||
|
||||
}
|
||||
|
||||
std::string RndisBoard::GetDeviceStatusJson() {
|
||||
auto& board = Board::GetInstance();
|
||||
auto root = cJSON_CreateObject();
|
||||
|
||||
// Audio speaker
|
||||
auto audio_speaker = cJSON_CreateObject();
|
||||
if (auto codec = board.GetAudioCodec()) {
|
||||
cJSON_AddNumberToObject(audio_speaker, "volume", codec->output_volume());
|
||||
}
|
||||
cJSON_AddItemToObject(root, "audio_speaker", audio_speaker);
|
||||
|
||||
// Screen
|
||||
auto screen = cJSON_CreateObject();
|
||||
if (auto backlight = board.GetBacklight()) {
|
||||
cJSON_AddNumberToObject(screen, "brightness", backlight->brightness());
|
||||
}
|
||||
if (auto display = board.GetDisplay(); display && display->height() > 64) {
|
||||
if (auto theme = display->GetTheme()) {
|
||||
cJSON_AddStringToObject(screen, "theme", theme->name().c_str());
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToObject(root, "screen", screen);
|
||||
|
||||
// Battery
|
||||
int level = 0;
|
||||
bool charging = false, discharging = false;
|
||||
if (board.GetBatteryLevel(level, charging, discharging)) {
|
||||
auto battery = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(battery, "level", level);
|
||||
cJSON_AddBoolToObject(battery, "charging", charging);
|
||||
cJSON_AddItemToObject(root, "battery", battery);
|
||||
}
|
||||
|
||||
// Network
|
||||
auto network = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(network, "type", "rndis");
|
||||
cJSON_AddItemToObject(root, "network", network);
|
||||
|
||||
// Chip temperature
|
||||
float temp = 0.0f;
|
||||
if (board.GetTemperature(temp)) {
|
||||
auto chip = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(chip, "temperature", temp);
|
||||
cJSON_AddItemToObject(root, "chip", chip);
|
||||
}
|
||||
|
||||
auto str = cJSON_PrintUnformatted(root);
|
||||
std::string result(str);
|
||||
cJSON_free(str);
|
||||
cJSON_Delete(root);
|
||||
return result;
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S3
|
||||
Reference in New Issue
Block a user