2014-08-29 07:52:33 -07:00
|
|
|
/**
|
2015-01-13 19:04:02 -08:00
|
|
|
* @file cli_registry.cpp
|
2014-08-29 07:52:33 -07:00
|
|
|
* @brief Command-line interface commands registry
|
|
|
|
*
|
|
|
|
* Here we have a data structure which holds all the dynamically-registered
|
|
|
|
* command line interface action names & callback. This logic is invoked in
|
|
|
|
* user context by the console thread - see consoleThreadThreadEntryPoint
|
|
|
|
*
|
|
|
|
* TODO: there is too much copy-paste here, this class needs some refactoring :)
|
|
|
|
*
|
2014-10-11 01:03:02 -07:00
|
|
|
* see testConsoleLogic()
|
|
|
|
*
|
2014-08-29 07:52:33 -07:00
|
|
|
* @date Nov 15, 2012
|
2015-01-12 15:04:10 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2015
|
2014-08-29 07:52:33 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "main.h"
|
|
|
|
#include "cli_registry.h"
|
|
|
|
#include "efilib.h"
|
|
|
|
|
|
|
|
#if EFI_PROD_CODE
|
|
|
|
#include "board_test.h"
|
|
|
|
#endif
|
|
|
|
|
2014-12-31 16:03:30 -08:00
|
|
|
#if ! EFI_UNIT_TEST
|
2014-08-29 07:52:33 -07:00
|
|
|
#include "eficonsole.h"
|
2014-12-31 16:03:30 -08:00
|
|
|
#endif /* ! EFI_UNIT_TEST */
|
2014-08-29 07:52:33 -07:00
|
|
|
|
2015-01-15 13:03:51 -08:00
|
|
|
static Logging * logging;
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
static int consoleActionCount = 0;
|
|
|
|
static TokenCallback consoleActions[CONSOLE_MAX_ACTIONS];
|
|
|
|
|
|
|
|
#define SECURE_LINE_PREFIX "sec!"
|
2015-02-23 17:07:48 -08:00
|
|
|
#define SECURE_LINE_PREFIX_LENGTH 4
|
2014-08-29 07:52:33 -07:00
|
|
|
|
|
|
|
void resetConsoleActions(void) {
|
|
|
|
consoleActionCount = 0;
|
|
|
|
}
|
|
|
|
|
2015-01-13 18:06:35 -08:00
|
|
|
static void doAddAction(const char *token, action_type_e type, Void callback, void *param) {
|
2014-08-29 07:52:33 -07:00
|
|
|
efiAssertVoid(consoleActionCount < CONSOLE_MAX_ACTIONS, "Too many console actions");
|
|
|
|
TokenCallback *current = &consoleActions[consoleActionCount++];
|
|
|
|
current->token = token;
|
|
|
|
current->parameterType = type;
|
|
|
|
current->callback = callback;
|
2014-09-17 13:03:04 -07:00
|
|
|
current->param = param;
|
|
|
|
}
|
|
|
|
|
|
|
|
void addConsoleActionP(const char *token, VoidPtr callback, void *param) {
|
|
|
|
doAddAction(token, NO_PARAMETER_P, (Void) callback, param);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
2014-09-20 12:03:00 -07:00
|
|
|
void addConsoleActionSSP(const char *token, VoidCharPtrCharPtrVoidPtr callback, void *param) {
|
|
|
|
doAddAction(token, STRING2_PARAMETER_P, (Void) callback, param);
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
/**
|
|
|
|
* @brief Register console action without parameters
|
|
|
|
*/
|
|
|
|
void addConsoleAction(const char *token, Void callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, NO_PARAMETER, callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Register a console command with one Integer parameter
|
|
|
|
*/
|
|
|
|
void addConsoleActionI(const char *token, VoidInt callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, ONE_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
2014-10-21 13:03:04 -07:00
|
|
|
void addConsoleActionIP(const char *token, VoidIntVoidPtr callback, void *param) {
|
|
|
|
doAddAction(token, ONE_PARAMETER_P, (Void) callback, param);
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
/**
|
|
|
|
* @brief Register a console command with two Integer parameters
|
|
|
|
*/
|
|
|
|
void addConsoleActionII(const char *token, VoidIntInt callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, TWO_INTS_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
2014-10-21 13:03:04 -07:00
|
|
|
void addConsoleActionIIP(const char *token, VoidIntIntVoidPtr callback, void *param) {
|
|
|
|
doAddAction(token, TWO_INTS_PARAMETER_P, (Void) callback, param);
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
void addConsoleActionS(const char *token, VoidCharPtr callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, STRING_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
2014-11-18 12:03:13 -08:00
|
|
|
void addConsoleActionSP(const char *token, VoidCharPtrVoidPtr callback, void *param) {
|
2014-11-18 19:03:12 -08:00
|
|
|
doAddAction(token, STRING_PARAMETER_P, (Void) callback, param);
|
2014-11-18 12:03:13 -08:00
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
void addConsoleActionSS(const char *token, VoidCharPtrCharPtr callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, STRING2_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void addConsoleActionSSS(const char *token, VoidCharPtrCharPtrCharPtr callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, STRING3_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void addConsoleActionSSSSS(const char *token, VoidCharPtrCharPtrCharPtrCharPtrCharPtr callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, STRING5_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void addConsoleActionF(const char *token, VoidFloat callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, FLOAT_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void addConsoleActionFF(const char *token, VoidFloatFloat callback) {
|
2014-09-17 10:02:56 -07:00
|
|
|
doAddAction(token, FLOAT_FLOAT_PARAMETER, (Void) callback, NULL);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
2014-10-21 09:04:13 -07:00
|
|
|
void addConsoleActionFFP(const char *token, VoidFloatFloatVoidPtr callback, void *param) {
|
|
|
|
doAddAction(token, FLOAT_FLOAT_PARAMETER_P, (Void) callback, param);
|
|
|
|
}
|
|
|
|
|
2014-09-15 09:03:05 -07:00
|
|
|
static int getParameterCount(action_type_e parameterType) {
|
|
|
|
switch (parameterType) {
|
|
|
|
case NO_PARAMETER:
|
2014-09-17 13:03:04 -07:00
|
|
|
case NO_PARAMETER_P:
|
2014-09-15 09:03:05 -07:00
|
|
|
return 0;
|
|
|
|
case ONE_PARAMETER:
|
2014-10-22 14:03:06 -07:00
|
|
|
case ONE_PARAMETER_P:
|
2014-09-15 09:03:05 -07:00
|
|
|
case FLOAT_PARAMETER:
|
|
|
|
case STRING_PARAMETER:
|
|
|
|
return 1;
|
|
|
|
case FLOAT_FLOAT_PARAMETER:
|
2014-09-20 12:03:00 -07:00
|
|
|
case FLOAT_FLOAT_PARAMETER_P:
|
2014-09-15 09:03:05 -07:00
|
|
|
case STRING2_PARAMETER:
|
2014-09-20 12:03:00 -07:00
|
|
|
case STRING2_PARAMETER_P:
|
2014-09-15 09:03:05 -07:00
|
|
|
case TWO_INTS_PARAMETER:
|
2014-09-20 12:03:00 -07:00
|
|
|
case TWO_INTS_PARAMETER_P:
|
2014-09-15 09:03:05 -07:00
|
|
|
return 2;
|
|
|
|
case STRING3_PARAMETER:
|
|
|
|
return 3;
|
|
|
|
case STRING5_PARAMETER:
|
|
|
|
return 5;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
/**
|
|
|
|
* @brief This function prints out a list of all available commands
|
|
|
|
*/
|
|
|
|
void helpCommand(void) {
|
|
|
|
#if EFI_PROD_CODE
|
|
|
|
if (isBoardTestMode()) {
|
|
|
|
printBoardTestState();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif /* EFI_PROD_CODE */
|
|
|
|
|
|
|
|
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
2015-01-15 13:03:51 -08:00
|
|
|
scheduleMsg(logging, "%d actions available", consoleActionCount);
|
2014-08-29 07:52:33 -07:00
|
|
|
for (int i = 0; i < consoleActionCount; i++) {
|
|
|
|
TokenCallback *current = &consoleActions[i];
|
2015-01-15 13:03:51 -08:00
|
|
|
scheduleMsg(logging, " %s: %d parameters", current->token, getParameterCount(current->parameterType));
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
#endif
|
2015-02-15 09:04:39 -08:00
|
|
|
scheduleMsg(logging, "For more visit http://rusefi.com/wiki/index.php?title=Manual:Software:dev_console_commands");
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This is just a test function
|
|
|
|
*/
|
|
|
|
static void echo(int value) {
|
|
|
|
print("got value: %d\r\n", value);
|
|
|
|
}
|
|
|
|
|
2014-10-12 14:06:19 -07:00
|
|
|
char *unquote(char *line) {
|
|
|
|
if (line[0] == '"') {
|
|
|
|
int len = strlen(line);
|
|
|
|
if (line[len - 1] == '"') {
|
|
|
|
line[len - 1] = 0;
|
|
|
|
return line + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
2014-10-11 01:03:02 -07:00
|
|
|
int findEndOfToken(const char *line) {
|
2014-10-12 12:02:57 -07:00
|
|
|
if (line[0] == '"') {
|
|
|
|
/**
|
|
|
|
* Looks like this is a quoted token
|
|
|
|
*/
|
|
|
|
int v = indexOf(line + 1, '"');
|
|
|
|
if (v == -1) {
|
|
|
|
/**
|
|
|
|
* Matching closing quote not found
|
|
|
|
*/
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Skipping first quote and the symbol after closing quote
|
|
|
|
*/
|
|
|
|
return v + 2;
|
|
|
|
}
|
2014-10-11 01:03:02 -07:00
|
|
|
return indexOf(line, ' ');
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
void handleActionWithParameter(TokenCallback *current, char *parameter) {
|
|
|
|
if (current->parameterType == STRING_PARAMETER) {
|
|
|
|
VoidCharPtr callbackS = (VoidCharPtr) current->callback;
|
|
|
|
(*callbackS)(parameter);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-11-18 12:03:13 -08:00
|
|
|
if (current->parameterType == STRING_PARAMETER_P) {
|
|
|
|
VoidCharPtrVoidPtr callbackS = (VoidCharPtrVoidPtr) current->callback;
|
|
|
|
(*callbackS)(parameter, current->param);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-29 07:52:33 -07:00
|
|
|
// todo: refactor this hell!
|
2014-09-20 12:03:00 -07:00
|
|
|
if (current->parameterType == STRING2_PARAMETER || current->parameterType == STRING2_PARAMETER_P) {
|
2014-10-11 01:03:02 -07:00
|
|
|
int spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param0 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
|
|
|
char * param1 = parameter;
|
|
|
|
|
2014-09-20 12:03:00 -07:00
|
|
|
if (current->parameterType == STRING2_PARAMETER) {
|
|
|
|
VoidCharPtrCharPtr callbackS = (VoidCharPtrCharPtr) current->callback;
|
|
|
|
(*callbackS)(param0, param1);
|
|
|
|
} else {
|
|
|
|
VoidCharPtrCharPtrVoidPtr callbackS = (VoidCharPtrCharPtrVoidPtr) current->callback;
|
|
|
|
(*callbackS)(param0, param1, current->param);
|
|
|
|
}
|
2014-08-29 07:52:33 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current->parameterType == STRING3_PARAMETER) {
|
2014-10-11 01:03:02 -07:00
|
|
|
int spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param0 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
2014-10-11 01:03:02 -07:00
|
|
|
spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param1 = parameter;
|
|
|
|
parameter += spaceIndex + 1;
|
|
|
|
char * param2 = parameter;
|
|
|
|
|
|
|
|
VoidCharPtrCharPtrCharPtr callbackS = (VoidCharPtrCharPtrCharPtr) current->callback;
|
|
|
|
(*callbackS)(param0, param1, param2);
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: refactor this hell!
|
|
|
|
if (current->parameterType == STRING5_PARAMETER) {
|
2014-10-11 01:03:02 -07:00
|
|
|
int spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param0 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
2014-10-11 01:03:02 -07:00
|
|
|
spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param1 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
2014-10-11 01:03:02 -07:00
|
|
|
spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param2 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
2014-10-11 01:03:02 -07:00
|
|
|
spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
char * param3 = parameter;
|
|
|
|
|
|
|
|
parameter += spaceIndex + 1;
|
|
|
|
char * param4 = parameter;
|
|
|
|
|
|
|
|
VoidCharPtrCharPtrCharPtrCharPtrCharPtr callbackS = (VoidCharPtrCharPtrCharPtrCharPtrCharPtr) current->callback;
|
|
|
|
(*callbackS)(param0, param1, param2, param3, param4);
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current->parameterType == TWO_INTS_PARAMETER) {
|
2014-10-11 01:03:02 -07:00
|
|
|
int spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
int value1 = atoi(parameter);
|
2014-12-03 08:03:52 -08:00
|
|
|
if (absI(value1) == ERROR_CODE) {
|
2014-08-29 07:52:33 -07:00
|
|
|
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
2015-01-15 13:03:51 -08:00
|
|
|
scheduleMsg(logging, "not an integer [%s]", parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
parameter += spaceIndex + 1;
|
|
|
|
int value2 = atoi(parameter);
|
2014-12-03 08:03:52 -08:00
|
|
|
if (absI(value2) == ERROR_CODE) {
|
2014-08-29 07:52:33 -07:00
|
|
|
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
2015-01-15 13:03:51 -08:00
|
|
|
scheduleMsg(logging, "not an integer [%s]", parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
VoidIntInt callbackS = (VoidIntInt) current->callback;
|
|
|
|
(*callbackS)(value1, value2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current->parameterType == FLOAT_PARAMETER) {
|
|
|
|
float value = atoff(parameter);
|
|
|
|
VoidFloat callbackF = (VoidFloat) current->callback;
|
|
|
|
|
|
|
|
// invoke callback function by reference
|
|
|
|
(*callbackF)(value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-21 10:03:09 -07:00
|
|
|
if (current->parameterType == FLOAT_FLOAT_PARAMETER || current->parameterType == FLOAT_FLOAT_PARAMETER_P) {
|
2014-10-11 01:03:02 -07:00
|
|
|
int spaceIndex = findEndOfToken(parameter);
|
2014-08-29 07:52:33 -07:00
|
|
|
if (spaceIndex == -1)
|
|
|
|
return;
|
|
|
|
parameter[spaceIndex] = 0;
|
|
|
|
float value1 = atoff(parameter);
|
|
|
|
parameter += spaceIndex + 1;
|
|
|
|
float value2 = atoff(parameter);
|
2014-10-21 10:03:09 -07:00
|
|
|
if (current->parameterType == FLOAT_FLOAT_PARAMETER) {
|
|
|
|
VoidFloatFloat callbackS = (VoidFloatFloat) current->callback;
|
|
|
|
(*callbackS)(value1, value2);
|
|
|
|
} else {
|
|
|
|
VoidFloatFloatVoidPtr callbackS = (VoidFloatFloatVoidPtr) current->callback;
|
|
|
|
(*callbackS)(value1, value2, current->param);
|
|
|
|
}
|
2014-08-29 07:52:33 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int value = atoi(parameter);
|
2014-12-03 08:03:52 -08:00
|
|
|
if (absI(value) == ERROR_CODE) {
|
2014-08-29 07:52:33 -07:00
|
|
|
print("invalid integer [%s]\r\n", parameter);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-22 14:03:06 -07:00
|
|
|
if (current->parameterType == ONE_PARAMETER_P) {
|
|
|
|
VoidIntVoidPtr callback1 = (VoidIntVoidPtr) current->callback;
|
|
|
|
// invoke callback function by reference
|
|
|
|
(*callback1)(value, current->param);
|
2014-08-29 07:52:33 -07:00
|
|
|
|
2014-10-22 14:03:06 -07:00
|
|
|
} else {
|
|
|
|
VoidInt callback1 = (VoidInt) current->callback;
|
|
|
|
// invoke callback function by reference
|
|
|
|
(*callback1)(value);
|
|
|
|
}
|
2014-08-29 07:52:33 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Number of space-separated tokens in the string
|
|
|
|
*/
|
|
|
|
int tokenLength(const char *msgp) {
|
|
|
|
int result = 0;
|
|
|
|
while (*msgp) {
|
|
|
|
char ch = *msgp++;
|
|
|
|
if (ch == ' ') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
result++;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-01-15 13:03:51 -08:00
|
|
|
void initConsoleLogic(Logging *sharedLogger) {
|
|
|
|
logging = sharedLogger;
|
2015-04-03 20:10:08 -07:00
|
|
|
// resetConsoleActions();
|
2014-08-29 07:52:33 -07:00
|
|
|
addConsoleAction("help", helpCommand);
|
|
|
|
addConsoleActionI("echo", echo);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return NULL if input line validation failed, reference to line payload if validation succeeded.
|
|
|
|
* @see sendOutConfirmation() for command confirmation processing.
|
|
|
|
*/
|
|
|
|
char *validateSecureLine(char *line) {
|
|
|
|
if (line == NULL)
|
|
|
|
return NULL;
|
2015-02-23 17:07:48 -08:00
|
|
|
if (strncmp(SECURE_LINE_PREFIX, line, SECURE_LINE_PREFIX_LENGTH) == 0) {
|
2014-08-29 07:52:33 -07:00
|
|
|
// COM protocol looses bytes, this is a super-naive error detection
|
|
|
|
|
|
|
|
// print("Got secure mode request header [%s]\r\n", line);
|
2015-02-23 17:07:48 -08:00
|
|
|
line += SECURE_LINE_PREFIX_LENGTH;
|
2014-08-29 07:52:33 -07:00
|
|
|
// print("Got secure mode request command [%s]\r\n", line);
|
|
|
|
|
|
|
|
char *divider = line;
|
|
|
|
while (*divider != '!') {
|
|
|
|
if (*divider == '\0') {
|
|
|
|
print("Divider not found [%s]\r\n", line);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
divider++;
|
|
|
|
}
|
|
|
|
*divider++ = 0; // replacing divider symbol with zero
|
|
|
|
int expectedLength = atoi(line);
|
|
|
|
line = divider;
|
|
|
|
int actualLength = strlen(line);
|
|
|
|
if (expectedLength != actualLength) {
|
|
|
|
print("Error detected: expected %d but got %d in [%s]\r\n", expectedLength, actualLength, line);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char confirmation[200];
|
2015-03-21 21:04:52 -07:00
|
|
|
static char handleBuffer[200];
|
2014-08-29 07:52:33 -07:00
|
|
|
|
2015-03-21 21:04:52 -07:00
|
|
|
static bool handleConsoleLineInternal(const char *commandLine, int lineLength) {
|
|
|
|
strncpy(handleBuffer, commandLine, sizeof(handleBuffer));
|
|
|
|
char *line = handleBuffer;
|
2014-08-29 07:52:33 -07:00
|
|
|
int firstTokenLength = tokenLength(line);
|
|
|
|
|
|
|
|
// print("processing [%s] with %d actions\r\n", line, consoleActionCount);
|
|
|
|
|
|
|
|
if (firstTokenLength == lineLength) {
|
|
|
|
// no-param actions are processed here
|
|
|
|
for (int i = 0; i < consoleActionCount; i++) {
|
|
|
|
TokenCallback *current = &consoleActions[i];
|
|
|
|
if (strEqual(line, current->token)) {
|
2014-09-17 13:03:04 -07:00
|
|
|
if (current->parameterType == NO_PARAMETER) {
|
|
|
|
(*current->callback)();
|
|
|
|
} else if (current->parameterType == NO_PARAMETER_P) {
|
|
|
|
VoidPtr cb = (VoidPtr) current->callback;
|
|
|
|
(*cb)(current->param);
|
|
|
|
}
|
2014-08-29 07:52:33 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char *ptr = line + firstTokenLength;
|
|
|
|
ptr[0] = 0; // change space into line end
|
|
|
|
ptr++; // start from next symbol
|
|
|
|
|
|
|
|
for (int i = 0; i < consoleActionCount; i++) {
|
|
|
|
TokenCallback *current = &consoleActions[i];
|
|
|
|
if (strEqual(line, current->token)) {
|
|
|
|
handleActionWithParameter(current, ptr);
|
2014-10-11 01:03:02 -07:00
|
|
|
return true;
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
|
|
|
static void sendOutConfirmation(const char *command, int length) {
|
2015-01-15 13:03:51 -08:00
|
|
|
scheduleMsg(logging, "%s%d", command, length);
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function takes care of one command line once we have it
|
|
|
|
*/
|
|
|
|
void handleConsoleLine(char *line) {
|
|
|
|
line = validateSecureLine(line);
|
|
|
|
if (line == NULL)
|
|
|
|
return; // error detected
|
|
|
|
|
|
|
|
int lineLength = strlen(line);
|
|
|
|
if (lineLength > 100) {
|
|
|
|
// todo: better max size logic
|
|
|
|
// todo: better reaction to excessive line
|
|
|
|
print("Long line?\r\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(confirmation, "confirmation_");
|
|
|
|
strcat(confirmation, line);
|
|
|
|
strcat(confirmation, ":");
|
|
|
|
|
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
|
|
|
sendOutConfirmation(confirmation, lineLength);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool isKnownComman = handleConsoleLineInternal(line, lineLength);
|
|
|
|
|
2015-03-21 21:04:52 -07:00
|
|
|
if (!isKnownComman) {
|
|
|
|
scheduleMsg(logging, "unknown [%s]", line);
|
2014-08-29 07:52:33 -07:00
|
|
|
helpCommand();
|
2015-03-21 21:04:52 -07:00
|
|
|
}
|
2014-08-29 07:52:33 -07:00
|
|
|
}
|