убрана блокировка из за пароля, убрана команда Т00 без пароля,

игнорированеи проблелов в конце команд, исправлена проверка границ
памяти, обновлен приветственный вывод, нет избыточной проверке в
cli_register_command.
parent 8df5e7e1
......@@ -10,7 +10,6 @@
//!
//! Расширение протокола: новые команды регистрируются через cli_register_command().
//!
//! Таймаут соединения: 20 секунд бездействия.
//! Максимальный размер поля данных: 64 байта.
//!
//! @note Для работы необходимо наличие LMCAL, ring_buffer, а также tsp_dev_info из модуля tcp.h.
......@@ -127,12 +126,6 @@ void cli_send_string(const char* str)
//-----------------------------------------------------------------------------------------------------------
static void uart_wait_tx_done(void)
{
// Попытка использовать функцию LMCAL, если она доступна
#ifdef LMCAL_UART_TX_COMPLETE
uint32_t timeout = 100000; // ~100 мс при типичной скорости
while (!lmcal_uart_tx_complete(CLI_UART_CHANNEL) && --timeout);
#else
// Резервный вариант с прямым доступом к регистрам (для GD32)
#if CLI_UART_CHANNEL == LMCAL_UART_CHANNEL0
#define CLI_USART USART5
#elif CLI_UART_CHANNEL == LMCAL_UART_CHANNEL1
......@@ -140,9 +133,9 @@ static void uart_wait_tx_done(void)
#else
#define CLI_USART USART0
#endif
volatile uint32_t timeout = 100000;
volatile u32 timeout = 100000;
while (usart_flag_get(CLI_USART, USART_FLAG_TC) == RESET && --timeout);
#endif
}
//-----------------------------------------------------------------------------------------------------------
......@@ -194,26 +187,18 @@ static void handle_cmd_open(const u8* data, u8 len)
{
(void)len;
// Проверяем, не открыто ли уже соединение
if (cli_connected) {
send_error(CLI_CMD_OPEN, CLI_ERR_INTERNAL);
return;
}
// Проверка пароля, если он задан
if (cli_password_len > 0) {
if (len != cli_password_len || memcmp(data, cli_password, len) != 0) {
// Неверный пароль - возвращаем ошибку "неизвестная команда"
send_error(CLI_CMD_OPEN, CLI_ERR_UNKNOWN_CMD);
send_error(CLI_CMD_OPEN, CLI_ERR_INTERNAL);
return;
}
}
// Пароль верен или не требуется
cli_connected = true;
if (cli_get_tick) {
cli_last_activity = cli_get_tick();
}
if (cli_get_tick) cli_last_activity = cli_get_tick();
send_response(CLI_CMD_OPEN, NULL, 0);
}
......@@ -298,21 +283,30 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
send_error(CLI_CMD_READ_MEM, CLI_ERR_INVALID_ARG);
return;
}
u32 addr = 0;
for (u8 i = 0; i < 4; i++) addr = (addr << 8) | data[i];
u8 size = data[4];
if (size == 0 || size > CLI_DATA_MAX_SIZE) {
send_error(CLI_CMD_READ_MEM, CLI_ERR_INVALID_ARG);
return;
}
// Проверка допустимых диапазонов с учётом размера
// Проверка на переполнение адреса
u32 end_addr = addr + size;
if (end_addr < addr) {
send_error(CLI_CMD_READ_MEM, CLI_ERR_INTERNAL);
return;
}
// Проверка допустимых диапазонов (GD32F450: Flash 2MB, SRAM 192KB)
bool valid = false;
// Flash: 1 МБ (0x08000000 - 0x080FFFFF) – типично для GD32F450VG
if ((addr >= 0x08000000) && ((addr + size) <= 0x080FFFFF)) {
valid = true;
} else if ((addr >= 0x20000000) && ((addr + size) <= 0x2001FFFF)) {
valid = true; // SRAM (128 КБ)
if ((addr >= 0x08000000) && (end_addr <= 0x081FFFFF)) {
valid = true; // Flash (банк 0 + банк 1 = 2 МБ)
} else if ((addr >= 0x20000000) && (end_addr <= 0x2002FFFF)) {
valid = true; // SRAM (192 КБ)
}
if (valid) {
......@@ -322,6 +316,7 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
}
send_response(CLI_CMD_READ_MEM, buf, size);
} else {
printf("READ_MEM error: addr=0x%08X, size=%d, end=0x%08X\n", addr, size, end_addr);
send_error(CLI_CMD_READ_MEM, CLI_ERR_INTERNAL);
}
}
......@@ -341,21 +336,31 @@ static void handle_cmd_write_mem(const u8* data, u8 len)
send_error(CLI_CMD_WRITE_MEM, CLI_ERR_INVALID_ARG);
return;
}
u32 addr = 0;
for (u8 i = 0; i < 4; i++) addr = (addr << 8) | data[i];
u8 size = len - 4;
if (size > CLI_DATA_MAX_SIZE) {
send_error(CLI_CMD_WRITE_MEM, CLI_ERR_INVALID_ARG);
return;
}
// Проверка: только SRAM с учётом размера
if ((addr >= 0x20000000) && ((addr + size) <= 0x2001FFFF)) {
// Проверка на переполнение
u32 end_addr = addr + size;
if (end_addr < addr) {
send_error(CLI_CMD_WRITE_MEM, CLI_ERR_INTERNAL);
return;
}
// Запись разрешена только в SRAM
if ((addr >= 0x20000000) && (end_addr <= 0x2002FFFF)) {
for (u8 i = 0; i < size; i++) {
*(volatile u8*)(addr + i) = data[4 + i];
}
send_response(CLI_CMD_WRITE_MEM, NULL, 0);
} else {
printf("WRITE_MEM error: addr=0x%08X, size=%d, end=0x%08X\n", addr, size, end_addr);
send_error(CLI_CMD_WRITE_MEM, CLI_ERR_INTERNAL);
}
}
......@@ -457,16 +462,16 @@ fun_res_t cli_protocol_init(void)
const u8 default_pass[] = CLI_DEFAULT_PASSWORD_BYTES;
cli_protocol_set_password(default_pass, sizeof(default_pass));
cli_send_string("\r\n------ LTA PROTOCOL ENABLED -----\r\n");
cli_send_string("- T0001 - open without password\r\n");
cli_send_string("- T000131333537 - open with password '1357' (hex bytes 0x31,0x33,0x35,0x37)\r\n");
cli_send_string("- T0101 - close connection\r\n");
cli_send_string("- T0201AABB - ping with data 0xAA,0xBB\r\n");
cli_send_string("- T0A01 - get device info\r\n");
cli_send_string("- T14010800000004 - read 4 bytes from 0x08000000\r\n");
cli_send_string("- T150120000000AABB - write 0xAA,0xBB to SRAM 0x20000000\r\n");
cli_send_string("--------------------------------------------------\r\n");
cli_send_string("> ");
cli_send_string("\r\n********** LTA PROTOCOL ENABLED **********\r\n");
cli_send_string("|> T000131333537 - open with password '1357' (hex bytes 0x31,0x33,0x35,0x37)\r\n");
cli_send_string("|> T0101 - close connection\r\n");
cli_send_string("|> T0201AABB - ping with data 0xAA,0xBB\r\n");
cli_send_string("|> T0A01 - get device info\r\n");
cli_send_string("|> T14010800000004 - read 4 bytes from 0x08000000\r\n");
cli_send_string("|> T14012000000004 - read 4 bytes from 0x20000000\r\n");
cli_send_string("|> T150120000000AABB - write 0xAA,0xBB to SRAM 0x20000000\r\n");
cli_send_string("******************************************************\r\n");
cli_send_string("|> ");
return ERR_OK;
}
......@@ -498,14 +503,20 @@ void cli_protocol_process(void)
cli_cmd_buffer[cli_cmd_index++] = ch;
state = RECEIVING;
break;
case RECEIVING:
if (ch == '\r' || ch == '\n') {
while (cli_cmd_index > 0 && (cli_cmd_buffer[cli_cmd_index - 1] == ' '
|| cli_cmd_buffer[cli_cmd_index - 1] == '\t'))
{
cli_cmd_index--;
}
if (cli_cmd_index > 0) {
cli_cmd_buffer[cli_cmd_index] = CLI_MSG_TERMINATOR;
cli_cmd_index++;
parse_and_execute();
cli_send_string("> ");
cli_send_string("|> ");
}
state = EXPECT_NL;
} else {
......@@ -517,7 +528,6 @@ void cli_protocol_process(void)
}
}
break;
case EXPECT_NL:
if (ch == '\n') {
state = WAIT_CMD;
......@@ -530,7 +540,7 @@ void cli_protocol_process(void)
}
}
// Таймаут соединения
// Таймаут соединения (работает только если cli_get_tick != NULL)
if (cli_connected && cli_get_tick) {
if ((cli_get_tick() - cli_last_activity) > CLI_CONNECTION_TIMEOUT_MS) {
cli_connected = false;
......
......@@ -10,9 +10,9 @@
//************************************ Коды команд (по протоколу 1.1) *************************************
typedef enum {
CLI_CMD_OPEN = 0x00U, // T00 - открыть соединение (опционально с паролем)
CLI_CMD_OPEN = 0x00U, // T00 - открыть соединение (с паролем)
CLI_CMD_CLOSE = 0x01U, // T01 - закрыть соединение
CLI_CMD_PING = 0x02U, // T02 - проверка соединения (ping) – эхо переданных данных
CLI_CMD_PING = 0x02U, // T02 - проверка соединения (ping)
CLI_CMD_GET_INFO = 0x0AU, // T0A - получить информацию об устройстве (имя, серийный, версия)
CLI_CMD_READ_MEM = 0x14U, // T14 - чтение памяти (адрес 4 байта + размер 1 байт)
CLI_CMD_WRITE_MEM = 0x15U, // T15 - запись памяти (адрес 4 байта + данные, только SRAM)
......@@ -102,10 +102,6 @@ void cli_protocol_set_password(const u8* pass, u8 len);
//! @return true – пароль верен, false – неверен
bool cli_protocol_verify_password(const u8* pass, u8 len);
//---------------------------------------------------------------------
//! @brief Сброс блокировки после превышения попыток ввода пароля
void cli_protocol_reset_block(void);
//---------------------------------------------------------------------
//! @brief Регистрация новой команды
//! @param cmd Указатель на структуру с кодом и обработчиком
......
......@@ -16,13 +16,8 @@
//************************************ Пароль по умолчанию **************************************************
// Пароль по умолчанию "1357"
#define CLI_DEFAULT_PASSWORD_BYTES {0x31, 0x33, 0x35, 0x37}
#define CLI_DEFAULT_PASSWORD_LEN 4
#define CLI_MAX_COMMANDS 256 // Максимальное количество регистрируемых команд (0x00..0xFF)
#define CLI_PASSWORD_MAX_LEN 15 // Максимальная длина пароля в байтах
#define CLI_ACTIVITY_TIMEOUT_TICKS 20000U // ~20 сек при вызове каждые 1 мс
#endif
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment