added optional initial active scan address to --scanconfig option (including full scan) and set default to sending broadcast ident message, check address argument for validity in scan command
This commit is contained in:
+23
-5
@@ -70,6 +70,7 @@ static struct options opt = {
|
||||
-1, // latency
|
||||
CONFIG_PATH, // configPath
|
||||
false, // scanConfig
|
||||
BROADCAST, // initialScan
|
||||
0, // checkConfig
|
||||
5, // pollInterval
|
||||
0x31, // address
|
||||
@@ -144,7 +145,7 @@ static const struct argp_option argpoptions[] = {
|
||||
|
||||
{NULL, 0, NULL, 0, "Message configuration options:", 2 },
|
||||
{"configpath", 'c', "PATH", 0, "Read CSV config files from PATH [" CONFIG_PATH "]", 0 },
|
||||
{"scanconfig", 's', NULL, 0, "Pick CSV config files matching initial scan. If combined with --checkconfig, you can add scan message data as arguments for checking a particular scan configuration, e.g. \"FF08070400/0AB5454850303003277201\".", 0 },
|
||||
{"scanconfig", 's', "ADDR", OPTION_ARG_OPTIONAL, "Pick CSV config files matching initial scan (ADDR=\"none\" or empty for no initial scan message, \"full\" for full scan, or a single hex address to scan, default is broadcast ident message). If combined with --checkconfig, you can add scan message data as arguments for checking a particular scan configuration, e.g. \"FF08070400/0AB5454850303003277201\".", 0 },
|
||||
{"checkconfig", O_CHKCFG, NULL, 0, "Check CSV config files, then stop", 0 },
|
||||
{"dumpconfig", O_DMPCFG, NULL, 0, "Check and dump CSV config files, then stop", 0 },
|
||||
{"pollinterval", O_POLINT, "SEC", 0, "Poll for data every SEC seconds (0=disable) [5]", 0 },
|
||||
@@ -224,7 +225,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
case O_INISND: // --initsend
|
||||
opt->initialSend = true;
|
||||
break;
|
||||
case O_DEVLAT: // --latency
|
||||
case O_DEVLAT: // --latency=10000
|
||||
opt->latency = parseInt(arg, 10, 0, 200000, result);
|
||||
if (result != RESULT_OK) {
|
||||
argp_error(state, "invalid latency");
|
||||
@@ -240,12 +241,28 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
}
|
||||
opt->configPath = arg;
|
||||
break;
|
||||
case 's': // --scanconfig
|
||||
case 's': // --scanconfig[=ADDR] (ADDR=<empty>|full|<hexaddr>)
|
||||
opt->scanConfig = true;
|
||||
if (opt->readOnly) {
|
||||
argp_error(state, "cannot combine readonly with scanconfig/answer/generatesyn");
|
||||
return EINVAL;
|
||||
}
|
||||
if (arg != NULL) {
|
||||
if (arg[0] == 0 || strcmp("none", arg) == 0) {
|
||||
opt->initialScan = ESC;
|
||||
} else if (strcmp("full", arg) == 0) {
|
||||
opt->initialScan = SYN;
|
||||
} else {
|
||||
opt->initialScan = (unsigned char)parseInt(arg, 16, 0x00, 0xff, result);
|
||||
if (!isValidAddress(opt->initialScan)) {
|
||||
argp_error(state, "invalid initial scan address");
|
||||
return EINVAL;
|
||||
}
|
||||
if (isMaster(opt->initialScan)) {
|
||||
opt->initialScan = (unsigned char)(opt->initialScan+5);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case O_CHKCFG: // --checkconfig
|
||||
if (opt->checkConfig==0)
|
||||
@@ -344,7 +361,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
case O_LOCAL: // --localhost
|
||||
opt->localOnly = true;
|
||||
break;
|
||||
case O_HTTPPT: // --httpport
|
||||
case O_HTTPPT: // --httpport=0
|
||||
opt->httpPort = (uint16_t)parseInt(arg, 10, 1, 65535, result);
|
||||
if (result != RESULT_OK) {
|
||||
argp_error(state, "invalid port");
|
||||
@@ -897,8 +914,9 @@ int main(int argc, char* argv[])
|
||||
struct argp argp = { argpoptions, parse_opt, NULL, argpdoc, NULL, NULL, NULL };
|
||||
int arg_index = -1;
|
||||
setenv("ARGP_HELP_FMT", "no-dup-args-note", 0);
|
||||
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, &arg_index, &opt) != 0)
|
||||
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, &arg_index, &opt) != 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
s_messageMap = new MessageMap(opt.checkConfig && opt.scanConfig && arg_index >= argc);
|
||||
if (opt.checkConfig) {
|
||||
|
||||
@@ -37,6 +37,7 @@ struct options
|
||||
|
||||
const char* configPath; //!< path to CSV configuration files [/etc/ebusd]
|
||||
bool scanConfig; //!< pick configuration files matching initial scan
|
||||
unsigned char initialScan; //!< the initial address to scan for scanconfig (@a ESC=none, 0xfe=broadcast ident, @a SYN=full scan, else: single slave address)
|
||||
int checkConfig; //!< check CSV config files (!=0) and optionally dump (2), then stop
|
||||
int pollInterval; //!< poll interval in seconds, 0 to disable [5]
|
||||
|
||||
|
||||
+35
-6
@@ -42,7 +42,7 @@ static const char* columnNames[] = {
|
||||
static const size_t columnCount = sizeof(columnNames) / sizeof(char*);
|
||||
|
||||
MainLoop::MainLoop(const struct options opt, Device *device, MessageMap* messages)
|
||||
: m_device(device), m_messages(messages), m_address(opt.address), m_scanConfig(opt.scanConfig), m_enableHex(opt.enableHex)
|
||||
: m_device(device), m_messages(messages), m_address(opt.address), m_scanConfig(opt.scanConfig), m_initialScan(opt.initialScan), m_enableHex(opt.enableHex)
|
||||
{
|
||||
// setup Device
|
||||
m_device->setLogRaw(opt.logRaw);
|
||||
@@ -96,7 +96,7 @@ MainLoop::~MainLoop()
|
||||
|
||||
void MainLoop::run()
|
||||
{
|
||||
bool running = true;
|
||||
bool running = true, reload = true;
|
||||
time_t lastTaskRun, now;
|
||||
int taskDelay = 5;
|
||||
unsigned char lastScanAddress = 0; // 0 is known to be a master
|
||||
@@ -115,6 +115,31 @@ void MainLoop::run()
|
||||
} else if (now > lastTaskRun+taskDelay) {
|
||||
logDebug(lf_main, "performing regular tasks");
|
||||
if (m_scanConfig) {
|
||||
if (m_initialScan != ESC && reload && m_busHandler->hasSignal()) {
|
||||
result_t result = RESULT_ERR_NO_SIGNAL;
|
||||
if (m_initialScan == SYN) {
|
||||
logNotice(lf_main, "initiating full scan");
|
||||
result = m_busHandler->startScan(true);
|
||||
} else {
|
||||
logNotice(lf_main, "starting initial scan for %2.2x", m_initialScan);
|
||||
SymbolString slave(false);
|
||||
result = m_busHandler->scanAndWait(m_initialScan, slave);
|
||||
Message* message = m_messages->getScanMessage(m_initialScan);
|
||||
if (result == RESULT_OK && message != NULL) {
|
||||
ostringstream ret;
|
||||
result = message->decodeLastData(ret, 0, true); // decode data
|
||||
if (result == RESULT_OK) {
|
||||
logNotice(lf_main, "initial scan result: %2.2x%s", m_initialScan, ret.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != RESULT_OK) {
|
||||
logError(lf_main, "initial scan failed: %s", getResultCode(result));
|
||||
}
|
||||
if (result != RESULT_ERR_NO_SIGNAL) {
|
||||
reload = false;
|
||||
}
|
||||
}
|
||||
bool scanned = false;
|
||||
lastScanAddress = m_busHandler->getNextScanAddress(lastScanAddress, scanned);
|
||||
if (lastScanAddress==SYN) {
|
||||
@@ -164,7 +189,7 @@ void MainLoop::run()
|
||||
bool connected = true;
|
||||
if (request.length() > 0) {
|
||||
logDebug(lf_main, ">>> %s", request.c_str());
|
||||
result = decodeMessage(request, message->isHttp(), connected, listening, running);
|
||||
result = decodeMessage(request, message->isHttp(), connected, listening, running, reload);
|
||||
|
||||
if (result.length() == 0 && !message->isHttp())
|
||||
result = getResultCode(RESULT_EMPTY);
|
||||
@@ -188,7 +213,7 @@ void MainLoop::run()
|
||||
}
|
||||
}
|
||||
|
||||
string MainLoop::decodeMessage(const string& data, const bool isHttp, bool& connected, bool& listening, bool& running)
|
||||
string MainLoop::decodeMessage(const string& data, const bool isHttp, bool& connected, bool& listening, bool& running, bool& reload)
|
||||
{
|
||||
ostringstream result;
|
||||
|
||||
@@ -272,8 +297,10 @@ string MainLoop::decodeMessage(const string& data, const bool isHttp, bool& conn
|
||||
return executeRaw(args);
|
||||
if (strcasecmp(str, "DUMP") == 0)
|
||||
return executeDump(args);
|
||||
if (strcasecmp(str, "RELOAD") == 0)
|
||||
if (strcasecmp(str, "RELOAD") == 0) {
|
||||
reload = true;
|
||||
return executeReload(args);
|
||||
}
|
||||
if (strcasecmp(str, "STOP") == 0)
|
||||
return executeStop(args, running);
|
||||
if (strcasecmp(str, "Q") == 0 || strcasecmp(str, "QUIT") == 0)
|
||||
@@ -993,6 +1020,8 @@ string MainLoop::executeScan(vector<string> &args)
|
||||
|
||||
result_t result;
|
||||
unsigned char dstAddress = (unsigned char)parseInt(args[1].c_str(), 16, 0, 0xff, result);
|
||||
if (result == RESULT_OK && !isValidAddress(dstAddress, false))
|
||||
result = RESULT_ERR_INVALID_ADDR;
|
||||
if (result != RESULT_OK)
|
||||
return getResultCode(result);
|
||||
|
||||
@@ -1001,7 +1030,7 @@ string MainLoop::executeScan(vector<string> &args)
|
||||
if (result != RESULT_OK)
|
||||
return getResultCode(result);
|
||||
|
||||
Message* message = m_messages->getScanMessage(dstAddress); // never NULL due to scanAndWait() == RESULT_OK
|
||||
Message* message = m_messages->getScanMessage(dstAddress); // never NULL due to scanAndWait() == RESULT_OK && dstAddress != BROADCAST
|
||||
ostringstream ret;
|
||||
ret << hex << setw(2) << setfill('0') << static_cast<unsigned>(dstAddress);
|
||||
result = message->decodeLastData(ret, 0, true); // decode data
|
||||
|
||||
@@ -72,6 +72,9 @@ private:
|
||||
/** whether to pick configuration files matching initial scan. */
|
||||
const bool m_scanConfig;
|
||||
|
||||
/** the initial address to scan for @a m_scanConfig (@a ESC=none, 0xfe=broadcast ident, @a SYN=full scan, else: single slave address). */
|
||||
const unsigned char m_initialScan;
|
||||
|
||||
/** whether to enable the hex command. */
|
||||
const bool m_enableHex;
|
||||
|
||||
@@ -94,9 +97,10 @@ private:
|
||||
* @param isHttp true for HTTP message.
|
||||
* @param listening set to true when the client is in listening mode.
|
||||
* @param running set to false when the server shall be stopped.
|
||||
* @param reload set to true when the configuration files were reloaded.
|
||||
* @return result string to send back to the client.
|
||||
*/
|
||||
string decodeMessage(const string& data, const bool isHttp, bool& connected, bool& listening, bool& running);
|
||||
string decodeMessage(const string& data, const bool isHttp, bool& connected, bool& listening, bool& running, bool& reload);
|
||||
|
||||
/**
|
||||
* Parse the hex master message from the remaining arguments.
|
||||
|
||||
Reference in New Issue
Block a user