// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include "esp_system.h" #include "esp_log.h" #include "esp_vfs_dev.h" #include "driver/uart.h" #include "nvs.h" #include "nvs_flash.h" #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_console.h" #include "linenoise/linenoise.h" #include "argtable3/argtable3.h" #include "ble_mesh_console_decl.h" #if CONFIG_STORE_HISTORY #define MOUNT_PATH "/data" #define HISTORY_PATH MOUNT_PATH "/history.txt" static void initialize_filesystem(void) { static wl_handle_t wl_handle; const esp_vfs_fat_mount_config_t mount_config = { .max_files = 4, .format_if_mount_failed = true }; esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH, "storage", &mount_config, &wl_handle); if (err != ESP_OK) { printf("Failed to mount FATFS (0x%x)", err); return; } } #endif // CONFIG_STORE_HISTORY static void initialize_console(void) { /* Disable buffering on stdin and stdout */ setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); /* Move the caret to the beginning of the next line on '\n' */ esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); /* Install UART driver for interrupt-driven reads and writes */ ESP_ERROR_CHECK( uart_driver_install(CONFIG_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0) ); /* Tell VFS to use UART driver */ esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); /* Initialize the console */ esp_console_config_t console_config = { .max_cmdline_args = 20, .max_cmdline_length = 256, #if CONFIG_LOG_COLORS .hint_color = atoi(LOG_COLOR_CYAN) #endif }; ESP_ERROR_CHECK( esp_console_init(&console_config) ); /* Configure linenoise line completion library */ /* Enable multiline editing. If not set, long commands will scroll within * single line. */ linenoiseSetMultiLine(1); /* Tell linenoise where to get command completions and hints */ linenoiseSetCompletionCallback(&esp_console_get_completion); linenoiseSetHintsCallback((linenoiseHintsCallback *) &esp_console_get_hint); /* Set command history size */ linenoiseHistorySetMaxLen(100); #if CONFIG_STORE_HISTORY /* Load command history from filesystem */ linenoiseHistoryLoad(HISTORY_PATH); #endif } esp_err_t bluetooth_init(void) { esp_err_t ret; esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { printf("%s initialize controller failed\n", __func__); return ret; } ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); if (ret) { printf("%s enable controller failed\n", __func__); return ret; } ret = esp_bluedroid_init(); if (ret) { printf("%s init bluetooth failed\n", __func__); return ret; } ret = esp_bluedroid_enable(); if (ret) { printf("%s enable bluetooth failed\n", __func__); return ret; } return ret; } void app_main(void) { esp_err_t res; nvs_flash_init(); // init and enable bluetooth res = bluetooth_init(); if (res) { printf("esp32_bluetooth_init failed (ret %d)", res); } #if CONFIG_STORE_HISTORY initialize_filesystem(); #endif initialize_console(); /* Register commands */ esp_console_register_help_command(); register_system(); register_bluetooth(); ble_mesh_register_mesh_node(); ble_mesh_register_server(); /* Prompt to be printed before each line. * This can be customized, made dynamic, etc. */ const char *prompt = LOG_COLOR_I "esp32> " LOG_RESET_COLOR; printf("\n" "This is an example of ESP-IDF console component.\n" "Type 'help' to get the list of commands.\n" "Use UP/DOWN arrows to navigate through command history.\n" "Press TAB when typing command name to auto-complete.\n"); /* Figure out if the terminal supports escape sequences */ int probe_status = linenoiseProbe(); if (probe_status) { /* zero indicates success */ printf("\n" "Your terminal application does not support escape sequences.\n" "Line editing and history features are disabled.\n" "On Windows, try using Putty instead.\n"); linenoiseSetDumbMode(1); #if CONFIG_LOG_COLORS /* Since the terminal doesn't support escape sequences, * don't use color codes in the prompt. */ prompt = "esp32> "; #endif //CONFIG_LOG_COLORS } /* Main loop */ while (true) { /* Get a line using linenoise. * The line is returned when ENTER is pressed. */ char *line = linenoise(prompt); if (line == NULL) { /* Ignore empty lines */ continue; } /* Add the command to the history */ linenoiseHistoryAdd(line); #if CONFIG_STORE_HISTORY /* Save command history to filesystem */ linenoiseHistorySave(HISTORY_PATH); #endif /* Try to run the command */ int ret; esp_err_t err = esp_console_run(line, &ret); if (err == ESP_ERR_NOT_FOUND) { printf("Unrecognized command\n"); } else if (err == ESP_ERR_INVALID_ARG) { // command was empty } else if (err == ESP_OK && ret != ESP_OK) { printf("\nCommand returned non-zero error code: 0x%x\n", ret); } else if (err != ESP_OK) { printf("Internal error: 0x%x\n", err); } /* linenoise allocates line buffer on the heap, so need to free it */ linenoiseFree(line); } }