Skip to content

Commit

Permalink
feat(common): Added fully operational ifconfig and ping command
Browse files Browse the repository at this point in the history
  • Loading branch information
espressif-abhikroy committed Aug 21, 2023
1 parent d5fec78 commit 967f6ad
Show file tree
Hide file tree
Showing 13 changed files with 404 additions and 68 deletions.
2 changes: 1 addition & 1 deletion components/console_cmd_ifconfig/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS "console_connect.c" "console_ifconfig.c"
idf_component_register(SRCS "console_ifconfig.c"
INCLUDE_DIRS "include"
REQUIRES "ethernet_init"
PRIV_REQUIRES esp_netif console nvs_flash esp_eth)
14 changes: 4 additions & 10 deletions components/console_cmd_ifconfig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,9 @@ The component offers a console that enables runtime network interface configurat
```
4. In your app_main() function, add the following line as the last line:
```c
example_start_networking_console(NULL, NULL);
```
5. Optionally, you can add a user-defined command:
```c
example_start_networking_console("user_cmd", usr_cmd_hndl);
```
In the above line, "user_cmd" is a string representing the user-defined command name, and usr_cmd_hndl is the command callback function with the prototype.
```c
int usr_cmd_hndl(int argc, char **argv)
console_cmd_init(); // Initialize console
register_ifconfig();
console_cmd_start(); // Start console
```


Expand All @@ -36,7 +30,7 @@ The component offers a console that enables runtime network interface configurat
### Ifconfig:
* **ifconfig help:** Prints the help text for all ifconfig commands
* **ifconfig netif create/destroy \<ethernet handle id\>/\<iface\>:** Create or destroy a network interface with the specified ethernet handle or interface name
* **ifconfig eth show:** Display a list of available ethernet handle
* **ifconfig eth init/deinit/show:** Initialize, deinitialize and display a list of available ethernet handle
* **ifconfig:** Display a list of all esp_netif interfaces along with their information.
* **ifconfig \<iface>:** Provide the details of the named interface.
* **ifconfig \<iface> default:** Set the specified interface as the default interface.
Expand Down
5 changes: 1 addition & 4 deletions components/console_cmd_ifconfig/console_connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ esp_err_t example_start_networking_console(char *usr_cmd, int (*usr_cmd_hndl)(in

#if CONFIG_EXAMPLE_CMD_IFCONFIG
/* register command `ifconfig` */
command = register_ifconfig();
if (esp_console_cmd_register(&command)) {
ESP_LOGE(TAG, "Unable to register ifconfig");
}
register_ifconfig();
#endif

#if CONFIG_EXAMPLE_CMD_QUIT
Expand Down
167 changes: 123 additions & 44 deletions components/console_cmd_ifconfig/console_ifconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ esp_err_t ifcfg_netif_op(netif_op *self, int argc, char *argv[], esp_netif_t *es
esp_err_t ifcfg_eth_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_netif);

static const char *TAG = "console_ifconfig";
static esp_console_repl_t *s_repl = NULL;

netif_op cmd_list[] = {
{.name = "help", .operation = ifcfg_help_op, .arg_cnt = 2, .start_index = 1, .netif_flag = false, .help = "ifconfig help: Prints the help text for all ifconfig commands"},
{.name = "netif", .operation = ifcfg_netif_op, .arg_cnt = 4, .start_index = 1, .netif_flag = false, .help = "ifconfig netif create/destroy <ethernet handle id>/<iface>: Create or destroy a network interface with the specified ethernet handle or interface name"},
{.name = "eth", .operation = ifcfg_eth_op, .arg_cnt = 3, .start_index = 1, .netif_flag = false, .help = "ifconfig eth show: Display a list of available ethernet handle"},
{.name = "eth", .operation = ifcfg_eth_op, .arg_cnt = 3, .start_index = 1, .netif_flag = false, .help = "ifconfig eth init/deinit/show: Initialize, deinitialize and display a list of available ethernet handle"},
{.name = "ifconfig", .operation = ifcfg_print_op, .arg_cnt = 1, .start_index = 0, .netif_flag = false, .help = "ifconfig: Display a list of all esp_netif interfaces along with their information"},
{.name = "ifconfig", .operation = ifcfg_print_op, .arg_cnt = 2, .start_index = 0, .netif_flag = true, .help = "ifconfig <iface>: Provide the details of the named interface"},
{.name = "default", .operation = ifcfg_basic_op, .arg_cnt = 3, .start_index = 2, .netif_flag = true, .help = "ifconfig <iface> default: Set the specified interface as the default interface"},
Expand Down Expand Up @@ -176,17 +177,13 @@ esp_err_t ifcfg_ip_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_n
inet_aton(argv[self->start_index + 1], &ip_info.ip.addr);
esp_netif_set_ip_info(esp_netif, &ip_info);
return ESP_OK;
}

if (!strcmp("mask", argv[self->start_index])) {
} else if (!strcmp("mask", argv[self->start_index])) {
ESP_LOGI(TAG, "Setting mask: %s", argv[self->start_index + 1]);

inet_aton(argv[self->start_index + 1], &ip_info.netmask.addr);
esp_netif_set_ip_info(esp_netif, &ip_info);
return ESP_OK;
}

if (!strcmp("gw", argv[self->start_index])) {
} else if (!strcmp("gw", argv[self->start_index])) {
ESP_LOGI(TAG, "Setting gw: %s", argv[self->start_index + 1]);

inet_aton(argv[self->start_index + 1], &ip_info.gw.addr);
Expand Down Expand Up @@ -251,8 +248,7 @@ esp_err_t ifcfg_napt_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp

esp_err_t ifcfg_dhcp_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_netif)
{
/* Server */
if (!strcmp("server", argv[self->start_index + 1])) {
if (!strcmp("server", argv[self->start_index + 1])) { // Server
if (!strcmp("enable", argv[self->start_index + 2])) {
ESP_LOGW(TAG, "DHCP Server configuration is not supported yet."); // TBD
//esp_netif_dhcps_start(esp_netif);
Expand All @@ -261,24 +257,22 @@ esp_err_t ifcfg_dhcp_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp
ESP_LOGW(TAG, "DHCP Server configuration is not supported yet."); // TBD
//esp_netif_dhcps_stop(esp_netif);
return ESP_OK;
} else {
ESP_LOGE(TAG, "Invalid argument");
return ESP_FAIL;
}
}

/* Client */
if (!strcmp("client", argv[self->start_index + 1])) {
ESP_LOGE(TAG, "Invalid argument");
return ESP_FAIL;

} else if (!strcmp("client", argv[self->start_index + 1])) { // Client
if (!strcmp("enable", argv[self->start_index + 2])) {
esp_netif_dhcpc_start(esp_netif);
return ESP_OK;
} else if (!strcmp("disable", argv[self->start_index + 2])) {
esp_netif_dhcpc_stop(esp_netif);
return ESP_OK;
} else {
ESP_LOGE(TAG, "Invalid argument");
return ESP_FAIL;
}

ESP_LOGE(TAG, "Invalid argument");
return ESP_FAIL;
}

return ESP_FAIL;
Expand Down Expand Up @@ -318,7 +312,7 @@ void print_iface_details(esp_netif_t *esp_netif)

/* Print DHCP status */
if (ESP_OK == esp_netif_dhcps_get_status(esp_netif, &status)) {
ESP_LOGI(TAG, "DHCP Server Status: %d", status);
ESP_LOGI(TAG, "DHCP Server Status: %s", status ? "enabled" : "disabled");
} else if ((ESP_OK == esp_netif_dhcpc_get_status(esp_netif, &status))) {
if (ESP_NETIF_DHCP_STOPPED == status) {
ESP_LOGI(TAG, "Static IP");
Expand Down Expand Up @@ -370,18 +364,29 @@ esp_err_t ifcfg_print_op(netif_op *self, int argc, char *argv[], esp_netif_t *es
/* Maximum number of interface that can be added */
#define MAX_ETH_NETIF_COUNT (10)

typedef enum {
UNINITIALIZED = 0,
ETH_INITIALIZED = 1,
NETIF_CREATED = 2,
NETIF_DESTROYED = 3,
ETH_DEINITIALIZED = 4
} iface_state;

typedef struct {
esp_netif_t *esp_netif[MAX_ETH_NETIF_COUNT];
uint8_t created_flag[MAX_ETH_NETIF_COUNT];
uint8_t netif_count;
} esp_netif_list;
esp_netif_t *esp_netif;
esp_eth_handle_t *eth_handle;
esp_eth_netif_glue_handle_t eth_glue;
iface_state state;
} iface_desc;

iface_desc iface_list[MAX_ETH_NETIF_COUNT];
uint8_t netif_count;

uint8_t eth_init_flag = false;
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handle = NULL;


esp_err_t get_netif_config(uint16_t id, esp_netif_config_t *eth_cfg_o)
static esp_err_t get_netif_config(uint16_t id, esp_netif_config_t *eth_cfg_o)
{
/* Create new default instance of esp-netif for Ethernet */
char *if_key;
Expand All @@ -404,7 +409,7 @@ esp_err_t get_netif_config(uint16_t id, esp_netif_config_t *eth_cfg_o)
}


void free_config(esp_netif_config_t *eth_cfg)
static void free_config(esp_netif_config_t *eth_cfg)
{
if ((NULL != eth_cfg) && (NULL != eth_cfg->base)) {
free((void *)(eth_cfg->base->if_key));
Expand All @@ -415,7 +420,6 @@ void free_config(esp_netif_config_t *eth_cfg)

esp_err_t ifcfg_netif_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_netif)
{
static esp_netif_list netif_list;
int eth_handle_id = atoi(argv[self->start_index + 2]);

if (!strcmp(argv[self->start_index + 1], "create")) {
Expand All @@ -424,31 +428,33 @@ esp_err_t ifcfg_netif_op(netif_op *self, int argc, char *argv[], esp_netif_t *es
ESP_LOGE(TAG, "Invalid ethernet handle: %s", argv[self->start_index + 2]);
return ESP_FAIL;
}

esp_netif_config_t eth_cfg = ESP_NETIF_DEFAULT_ETH();
ESP_ERROR_CHECK(get_netif_config(eth_handle_id, &eth_cfg));
for (int i = 0; i < MAX_ETH_NETIF_COUNT; i++) {
if (netif_list.created_flag[i] == 0) {
if (iface_list[i].state == ETH_INITIALIZED) {
esp_netif = esp_netif_new(&eth_cfg);
if (esp_netif == NULL) {
ESP_LOGE(TAG, "Interface with key %s already exists", argv[self->start_index + 2]);
return ESP_FAIL;
}
netif_list.esp_netif[i] = esp_netif;
netif_list.created_flag[i] = 1;
netif_list.netif_count++;

esp_eth_netif_glue_handle_t eth_glue = esp_eth_new_netif_glue(eth_handle[eth_handle_id]);
if (eth_glue == NULL) {
iface_list[i].eth_glue = esp_eth_new_netif_glue(iface_list[i].eth_handle);
if (iface_list[i].eth_glue == NULL) {
ESP_LOGE(TAG, "%s: eth_glue is NULL", __func__);
esp_netif_destroy(esp_netif);
return ESP_FAIL;
}
ESP_ERROR_CHECK(esp_netif_attach(netif_list.esp_netif[i], eth_glue));

sleep(10);
iface_list[i].esp_netif = esp_netif;
ESP_ERROR_CHECK(esp_netif_attach(iface_list[i].esp_netif, iface_list[i].eth_glue));

// start Ethernet driver state machine
ESP_ERROR_CHECK(esp_eth_start(eth_handle[eth_handle_id]));
ESP_ERROR_CHECK(esp_eth_start(iface_list[i].eth_handle));

free_config(&eth_cfg);
iface_list[i].state = NETIF_CREATED;
netif_count++;
break;
}
}
Expand All @@ -462,15 +468,24 @@ esp_err_t ifcfg_netif_op(netif_op *self, int argc, char *argv[], esp_netif_t *es
}

for (int i = 0; i < MAX_ETH_NETIF_COUNT; i++) {
if (esp_netif == netif_list.esp_netif[i]) {
netif_list.created_flag[i] = 0;
if (esp_netif == iface_list[i].esp_netif) {
if (iface_list[i].state == NETIF_CREATED) {
esp_eth_stop(iface_list[i].eth_handle);
esp_eth_del_netif_glue(iface_list[i].eth_glue);
esp_netif_destroy(iface_list[i].esp_netif);
iface_list[i].state = NETIF_DESTROYED;
netif_count--;
return ESP_OK;
} else {
ESP_LOGE(TAG, "Netif is not in created state");
return ESP_FAIL;
}
break;
}
}
esp_netif_destroy(esp_netif);
netif_list.netif_count--;

return ESP_OK;
ESP_LOGE(TAG, "Something is very wrong. Unauthorized Interface.");
return ESP_FAIL;
}

return ESP_FAIL;
Expand All @@ -479,7 +494,7 @@ esp_err_t ifcfg_netif_op(netif_op *self, int argc, char *argv[], esp_netif_t *es

esp_err_t ifcfg_eth_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_netif)
{
if (!strcmp(argv[self->start_index + 1], "show")) {
if (!strcmp(argv[self->start_index + 1], "init")) {

/* Check if ethernet is initialized */
if (eth_init_flag == false) {
Expand All @@ -489,13 +504,54 @@ esp_err_t ifcfg_eth_op(netif_op *self, int argc, char *argv[], esp_netif_t *esp_
return ESP_FAIL;
}
eth_init_flag = true;

for (int i = 0; i < eth_port_cnt; i++) {
for (int j = 0; j < MAX_ETH_NETIF_COUNT; j++) {
if (iface_list[j].state == UNINITIALIZED) {
iface_list[j].eth_handle = eth_handle[i];
iface_list[j].state = ETH_INITIALIZED;
break;
}
}
}

if (eth_port_cnt > MAX_ETH_NETIF_COUNT) {
ESP_LOGW(TAG, "Not all ethernet ports can be assigned a network interface.\nPlease reconfigure MAX_ETH_NETIF_COUNT to a higher value.");
}

} else {
ESP_LOGW(TAG, "Ethernet already initialized");
}

/* Display available ethernet handles */
for (int i = 0; i < eth_port_cnt; i++) {
printf("ethernet handle id: %d\n", i);
}
} else if (!strcmp(argv[self->start_index + 1], "show")) {
/* Check if ethernet is initialized */
if (eth_init_flag == false) {
// Initialize Ethernet driver
ESP_LOGE(TAG, "Ethernet is not initialized.");
return ESP_OK;
}

/* Display available ethernet handles */
for (int i = 0; i < eth_port_cnt; i++) {
printf("ethernet handle id: %d\n", i);
}
} else if (!strcmp(argv[self->start_index + 1], "deinit")) {
/* Check if ethernet is initialized */
if (eth_init_flag == false) {
// Initialize Ethernet driver
ESP_LOGE(TAG, "Ethernet is not initialized.");
return ESP_OK;
}

/* Stop and Deinit ethernet here */
ethernet_deinit();
eth_init_flag = false;
} else {
return ESP_FAIL;
}

return ESP_OK;
Expand Down Expand Up @@ -546,13 +602,36 @@ static int do_cmd_ifconfig(int argc, char **argv)
}


esp_console_cmd_t register_ifconfig(void)
esp_err_t register_ifconfig(void)
{
esp_err_t ret;
esp_console_cmd_t command = {
.command = "ifconfig",
.help = "Command for network interface configuration and monitoring\nFor more info run 'ifconfig help'",
.func = &do_cmd_ifconfig
};

return command;
ret = esp_console_cmd_register(&command);
if (ret) {
ESP_LOGE(TAG, "Unable to register ifconfig");
}

return ret;
}

__attribute__((weak)) void console_cmd_init(void)
{
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();

// install console REPL environment
#if CONFIG_ESP_CONSOLE_UART
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
#endif
}

__attribute__((weak)) int console_cmd_start(void)
{
// start console REPL
return esp_console_start_repl(s_repl);
}
7 changes: 0 additions & 7 deletions components/console_cmd_ifconfig/console_ifconfig.h

This file was deleted.

4 changes: 2 additions & 2 deletions components/console_cmd_ifconfig/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: 0.0.4
version: 0.0.6
url: https://github.com/espressif-abhikroy/esp-protocols/tree/components/console_cmd_ifconfig/components/console_cmd_ifconfig
description: The component offers a console that enables runtime network interface configuration and monitoring.
dependencies:
idf:
version: '>=4.1'
ethernet_init:
version: '>=0.0.1'
version: '>=0.0.2'
10 changes: 10 additions & 0 deletions components/console_cmd_ifconfig/include/console_ifconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

__attribute__((weak)) void console_cmd_init(void);
__attribute__((weak)) int console_cmd_start(void);

esp_err_t register_ifconfig(void);
3 changes: 3 additions & 0 deletions components/console_cmd_ping/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
idf_component_register(SRCS "console_ping.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES esp_netif console nvs_flash)
1 change: 1 addition & 0 deletions components/console_cmd_ping/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console_cmd_ping/LICENSE
Loading

0 comments on commit 967f6ad

Please sign in to comment.