added FIELD.N to 'read' command for retrieving N'th FIELD, fixed getMasterNumber(), check maximum NN in message, use more constants, check all type conversions, added --nodevicecheck to ebusfeed help
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
AM_CXXFLAGS = -fpic \
|
AM_CXXFLAGS = -fpic \
|
||||||
-Wall \
|
-Wall \
|
||||||
-Wextra \
|
-Wextra \
|
||||||
|
-Wconversion \
|
||||||
-isystem$(top_srcdir)/src/lib/utils \
|
-isystem$(top_srcdir)/src/lib/utils \
|
||||||
-isystem$(top_srcdir)/src/lib/ebus \
|
-isystem$(top_srcdir)/src/lib/ebus \
|
||||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ void BusHandler::run()
|
|||||||
symCount++;
|
symCount++;
|
||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
if (now != lastTime) {
|
if (now > lastTime) {
|
||||||
m_symPerSec = symCount / (now-lastTime);
|
m_symPerSec = symCount / (unsigned int)(now-lastTime);
|
||||||
if (m_symPerSec > m_maxSymPerSec) {
|
if (m_symPerSec > m_maxSymPerSec) {
|
||||||
m_maxSymPerSec = m_symPerSec;
|
m_maxSymPerSec = m_symPerSec;
|
||||||
if (m_maxSymPerSec > 100)
|
if (m_maxSymPerSec > 100)
|
||||||
@@ -344,7 +344,7 @@ result_t BusHandler::handleSymbol()
|
|||||||
return setState(bs_ready, RESULT_ERR_SYN);
|
return setState(bs_ready, RESULT_ERR_SYN);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char headerLen, crcPos;
|
unsigned int headerLen, crcPos;
|
||||||
|
|
||||||
switch (m_state)
|
switch (m_state)
|
||||||
{
|
{
|
||||||
@@ -732,11 +732,11 @@ result_t BusHandler::startScan(bool full)
|
|||||||
|
|
||||||
m_scanResults.clear();
|
m_scanResults.clear();
|
||||||
|
|
||||||
for (unsigned int slave=0; slave<=255; slave++) {
|
for (unsigned char slave=1; slave != 0; slave++) { // 0 is known to be a master
|
||||||
if (!isValidAddress(slave, false) || isMaster(slave))
|
if (!isValidAddress(slave, false) || isMaster(slave))
|
||||||
continue;
|
continue;
|
||||||
if (!full && !m_seenAddresses[slave]) {
|
if (!full && !m_seenAddresses[slave]) {
|
||||||
unsigned int master = slave+(256-5); // check if we saw the corresponding master already
|
unsigned char master = (unsigned char)(slave+256-5); // check if we saw the corresponding master already
|
||||||
if (!isMaster(master) || !m_seenAddresses[slave])
|
if (!isMaster(master) || !m_seenAddresses[slave])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -755,7 +755,7 @@ result_t BusHandler::startScan(bool full)
|
|||||||
void BusHandler::formatScanResult(ostringstream& output)
|
void BusHandler::formatScanResult(ostringstream& output)
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (unsigned int slave=0; slave<=255; slave++) {
|
for (unsigned char slave=1; slave != 0; slave++) { // 0 is known to be a master
|
||||||
map<unsigned char, string>::iterator it = m_scanResults.find(slave);
|
map<unsigned char, string>::iterator it = m_scanResults.find(slave);
|
||||||
if (it != m_scanResults.end()) {
|
if (it != m_scanResults.end()) {
|
||||||
if (first)
|
if (first)
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ public:
|
|||||||
const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout,
|
const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout,
|
||||||
const unsigned int lockCount, const unsigned int pollInterval)
|
const unsigned int lockCount, const unsigned int pollInterval)
|
||||||
: m_device(device), m_messages(messages),
|
: m_device(device), m_messages(messages),
|
||||||
m_ownMasterAddress(ownAddress), m_ownSlaveAddress((ownAddress+5)&0xff), m_answer(answer),
|
m_ownMasterAddress(ownAddress), m_ownSlaveAddress((unsigned char)(ownAddress+5)), m_answer(answer),
|
||||||
m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries),
|
m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries),
|
||||||
m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout),
|
m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout),
|
||||||
m_lockCount(lockCount), m_remainLockCount(lockCount),
|
m_lockCount(lockCount), m_remainLockCount(lockCount),
|
||||||
|
|||||||
+1
-1
@@ -201,7 +201,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|||||||
|
|
||||||
// eBUS options:
|
// eBUS options:
|
||||||
case 'a': // --address=FF
|
case 'a': // --address=FF
|
||||||
opt->address = parseInt(arg, 16, 0, 0xff, result);
|
opt->address = (unsigned char)parseInt(arg, 16, 0, 0xff, result);
|
||||||
if (result != RESULT_OK || !isMaster(opt->address)) {
|
if (result != RESULT_OK || !isMaster(opt->address)) {
|
||||||
argp_error(state, "invalid address");
|
argp_error(state, "invalid address");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|||||||
+20
-10
@@ -229,14 +229,15 @@ string MainLoop::executeRead(vector<string> &args)
|
|||||||
argPos++;
|
argPos++;
|
||||||
}
|
}
|
||||||
if (argPos == 0 || args.size() < argPos + 1 || args.size() > argPos + 2)
|
if (argPos == 0 || args.size() < argPos + 1 || args.size() > argPos + 2)
|
||||||
return "usage: read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]\n"
|
return "usage: read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD[.N]]\n"
|
||||||
" Read value(s).\n"
|
" Read value(s).\n"
|
||||||
" -v be verbose (include field names, units, and comments)\n"
|
" -v be verbose (include field names, units, and comments)\n"
|
||||||
" -f force reading from the bus (same as '-m 0')\n"
|
" -f force reading from the bus (same as '-m 0')\n"
|
||||||
" -m SECONDS only return cached value if age is less than SECONDS [300]\n"
|
" -m SECONDS only return cached value if age is less than SECONDS [300]\n"
|
||||||
" -c CLASS limit to messages of CLASS\n"
|
" -c CLASS limit to messages of CLASS\n"
|
||||||
" NAME the NAME of the message to send\n"
|
" NAME the NAME of the message to send\n"
|
||||||
" FIELD only retrieve the single FIELD";
|
" FIELD only retrieve the field named FIELD\n"
|
||||||
|
" N only retrieve the N'th field named FIELD (0-based)";
|
||||||
|
|
||||||
if (args.size() == argPos + 2)
|
if (args.size() == argPos + 2)
|
||||||
maxAge = 0; // force refresh to filter single field
|
maxAge = 0; // force refresh to filter single field
|
||||||
@@ -282,9 +283,18 @@ string MainLoop::executeRead(vector<string> &args)
|
|||||||
|
|
||||||
ostringstream result;
|
ostringstream result;
|
||||||
if (ret == RESULT_OK) {
|
if (ret == RESULT_OK) {
|
||||||
if (args.size() == argPos + 2)
|
if (args.size() == argPos + 2) {
|
||||||
ret = message->decode(pt_slaveData, slave, result, false, verbose, args[argPos + 1].c_str());
|
string fieldName = args[argPos + 1];
|
||||||
else
|
size_t pos = fieldName.find_last_of('.');
|
||||||
|
char fieldIndex = -1;
|
||||||
|
if (pos != string::npos) {
|
||||||
|
result_t result = RESULT_OK;
|
||||||
|
fieldIndex = (char)parseInt(fieldName.substr(pos+1).c_str(), 10, 0, MAX_POS, result);
|
||||||
|
if (result == RESULT_OK)
|
||||||
|
fieldName = fieldName.substr(0, pos);
|
||||||
|
}
|
||||||
|
ret = message->decode(pt_slaveData, slave, result, false, verbose, fieldName.c_str(), fieldIndex);
|
||||||
|
} else
|
||||||
ret = message->decode(pt_slaveData, slave, result, false, verbose); // decode data
|
ret = message->decode(pt_slaveData, slave, result, false, verbose); // decode data
|
||||||
}
|
}
|
||||||
if (ret != RESULT_OK) {
|
if (ret != RESULT_OK) {
|
||||||
@@ -314,7 +324,7 @@ string MainLoop::executeWrite(vector<string> &args)
|
|||||||
if (msg.str().size() < 4*2) // at least ZZ, PB, SB, NN
|
if (msg.str().size() < 4*2) // at least ZZ, PB, SB, NN
|
||||||
return getResultCode(RESULT_ERR_INVALID_ARG);
|
return getResultCode(RESULT_ERR_INVALID_ARG);
|
||||||
result_t ret;
|
result_t ret;
|
||||||
unsigned int length = parseInt(msg.str().substr(3*2, 2).c_str(), 16, 0, 16, ret);
|
unsigned int length = parseInt(msg.str().substr(3*2, 2).c_str(), 16, 0, MAX_POS, ret);
|
||||||
if (ret == RESULT_OK && (4+length)*2 != msg.str().size())
|
if (ret == RESULT_OK && (4+length)*2 != msg.str().size())
|
||||||
return getResultCode(RESULT_ERR_INVALID_ARG);
|
return getResultCode(RESULT_ERR_INVALID_ARG);
|
||||||
|
|
||||||
@@ -397,7 +407,7 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
size_t argPos = 1;
|
size_t argPos = 1;
|
||||||
bool verbose = false, configFormat = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
|
bool verbose = false, configFormat = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
|
||||||
string clazz;
|
string clazz;
|
||||||
int pb = -1;
|
short pb = -1;
|
||||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||||
if (args[argPos] == "-v")
|
if (args[argPos] == "-v")
|
||||||
verbose = true;
|
verbose = true;
|
||||||
@@ -435,9 +445,9 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
const char* str = args[argPos].c_str();
|
const char* str = args[argPos].c_str();
|
||||||
result_t result = RESULT_OK;
|
result_t result = RESULT_OK;
|
||||||
if (strncasecmp(str, "0x", 2) == 0)
|
if (strncasecmp(str, "0x", 2) == 0)
|
||||||
pb = parseInt(str+2, 16, 0, 0xff, result); // hexadecimal
|
pb = (short)parseInt(str+2, 16, 0, 0xff, result); // hexadecimal
|
||||||
else
|
else
|
||||||
pb = parseInt(str, 10, 0, 0xff, result); // decimal
|
pb = (short)parseInt(str, 10, 0, 0xff, result); // decimal
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
return getResultCode(result);
|
return getResultCode(result);
|
||||||
}
|
}
|
||||||
@@ -670,7 +680,7 @@ string MainLoop::executeQuit(vector<string> &args, bool& connected)
|
|||||||
string MainLoop::executeHelp()
|
string MainLoop::executeHelp()
|
||||||
{
|
{
|
||||||
return "usage:\n"
|
return "usage:\n"
|
||||||
" read|r Read value(s): read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]\n"
|
" read|r Read value(s): read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD[.N]]\n"
|
||||||
" write|w Write value(s): write [-c] CLASS NAME VALUE[;VALUE]*\n"
|
" write|w Write value(s): write [-c] CLASS NAME VALUE[;VALUE]*\n"
|
||||||
" Write hex message: write -h ZZPBSBNNDx'\n"
|
" Write hex message: write -h ZZPBSBNNDx'\n"
|
||||||
" find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CLASS] [NAME]\n"
|
" find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CLASS] [NAME]\n"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
AM_CXXFLAGS = -fpic \
|
AM_CXXFLAGS = -fpic \
|
||||||
-Wall \
|
-Wall \
|
||||||
-Wextra \
|
-Wextra \
|
||||||
-Wno-unused-parameter
|
-Wno-unused-parameter \
|
||||||
|
-Wconversion
|
||||||
|
|
||||||
noinst_LIBRARIES = libebus.a
|
noinst_LIBRARIES = libebus.a
|
||||||
|
|
||||||
|
|||||||
+77
-56
@@ -29,22 +29,22 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const dataType_t stringDataType = {
|
static const dataType_t stringDataType = {
|
||||||
"STR",16*8,bt_str, ADJ, ' ', 1, 16, 0 // >= 1 byte character string filled up with space
|
"STR",MAX_POS*8,bt_str, ADJ, ' ', 1, MAX_POS, 0 // >= 1 byte character string filled up with space
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dataType_t pinDataType = {
|
static const dataType_t pinDataType = {
|
||||||
"PIN", 16, bt_num, FIX|BCD|REV, 0xffff, 0, 0x9999, 1 // unsigned decimal in BCD, 0000 - 9999 (fixed length)
|
"PIN", 16, bt_num, FIX|BCD|REV, 0xffff, 0, 0x9999, 1 // unsigned decimal in BCD, 0000 - 9999 (fixed length)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dataType_t uchDataType = {
|
static const dataType_t uchDataType = {
|
||||||
"UCH", 8, bt_num, LST, 0xff, 0, 0xfe, 1 // unsigned integer, 0 - 254
|
"UCH", 8, bt_num, LST, 0xff, 0, 0xfe, 1 // unsigned integer, 0 - 254
|
||||||
};
|
};
|
||||||
|
|
||||||
/** the known data field types. */
|
/** the known data field types. */
|
||||||
static const dataType_t dataTypes[] = {
|
static const dataType_t dataTypes[] = {
|
||||||
{"IGN",16*8,bt_str, IGN|ADJ, 0, 1, 16, 0}, // >= 1 byte ignored data
|
{"IGN",MAX_POS*8,bt_str, IGN|ADJ, 0, 1, MAX_POS, 0}, // >= 1 byte ignored data
|
||||||
stringDataType,
|
stringDataType,
|
||||||
{"HEX",16*8,bt_hexstr, ADJ, 0, 2, 47, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d
|
{"HEX",MAX_POS*8,bt_hexstr, ADJ, 0, 2, 47, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d
|
||||||
{"BDA", 32, bt_dat, BCD, 0, 10, 10, 0}, // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday Mon=0x00 - Sun=0x06)
|
{"BDA", 32, bt_dat, BCD, 0, 10, 10, 0}, // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday Mon=0x00 - Sun=0x06)
|
||||||
{"BDA", 24, bt_dat, BCD, 0, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99)
|
{"BDA", 24, bt_dat, BCD, 0, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99)
|
||||||
{"HDA", 32, bt_dat, 0, 0, 10, 10, 0}, // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63, WW is weekday Mon=0x01 - Sun=0x07))
|
{"HDA", 32, bt_dat, 0, 0, 10, 10, 0}, // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63, WW is weekday Mon=0x01 - Sun=0x07))
|
||||||
@@ -82,17 +82,19 @@ static const dataType_t dataTypes[] = {
|
|||||||
{"BI7", 1, bt_num, ADJ|LST|REQ, 0, 0, 0x01, 7}, // bit 7
|
{"BI7", 1, bt_num, ADJ|LST|REQ, 0, 0, 0x01, 7}, // bit 7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** the maximum divisor value. */
|
||||||
|
#define MAX_DIVISOR 1000000000
|
||||||
|
|
||||||
|
/** the maximum value for value lists. */
|
||||||
|
#define MAX_VALUE (1<<24)
|
||||||
|
|
||||||
/** the week day names. */
|
/** the week day names. */
|
||||||
static const char* dayNames[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
static const char* dayNames[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||||
|
|
||||||
/** the maximum position within master or slave data. */
|
|
||||||
#define MAX_POS 16
|
|
||||||
|
|
||||||
unsigned int parseInt(const char* str, int base, const unsigned int minValue, const unsigned int maxValue, result_t& result, unsigned int* length) {
|
unsigned int parseInt(const char* str, int base, const unsigned int minValue, const unsigned int maxValue, result_t& result, unsigned int* length) {
|
||||||
char* strEnd = NULL;
|
char* strEnd = NULL;
|
||||||
|
|
||||||
unsigned int ret = strtoul(str, &strEnd, base);
|
unsigned long int ret = strtoul(str, &strEnd, base);
|
||||||
|
|
||||||
if (strEnd == NULL || *strEnd != 0) {
|
if (strEnd == NULL || *strEnd != 0) {
|
||||||
result = RESULT_ERR_INVALID_NUM; // invalid value
|
result = RESULT_ERR_INVALID_NUM; // invalid value
|
||||||
@@ -104,10 +106,10 @@ unsigned int parseInt(const char* str, int base, const unsigned int minValue, co
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (length != NULL)
|
if (length != NULL)
|
||||||
*length = strEnd - str;
|
*length = (unsigned int)(strEnd - str);
|
||||||
|
|
||||||
result = RESULT_OK;
|
result = RESULT_OK;
|
||||||
return ret;
|
return (unsigned int)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printErrorPos(vector<string>::iterator begin, const vector<string>::iterator end, vector<string>::iterator pos, string filename, size_t lineNo, result_t result)
|
void printErrorPos(vector<string>::iterator begin, const vector<string>::iterator end, vector<string>::iterator pos, string filename, size_t lineNo, result_t result)
|
||||||
@@ -128,7 +130,7 @@ void printErrorPos(vector<string>::iterator begin, const vector<string>::iterato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (begin < pos)
|
if (begin < pos)
|
||||||
cnt += 1+(*begin).length()+1;
|
cnt += 1+(unsigned int)(*begin).length()+1;
|
||||||
else if (begin == pos)
|
else if (begin == pos)
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
@@ -208,23 +210,23 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
const string divisorStr = *it++;
|
const string divisorStr = *it++;
|
||||||
if (!divisorStr.empty()) {
|
if (!divisorStr.empty()) {
|
||||||
if (divisorStr.find('=') == string::npos)
|
if (divisorStr.find('=') == string::npos)
|
||||||
divisor = parseInt(divisorStr.c_str(), 10, 1, 10000, result);
|
divisor = parseInt(divisorStr.c_str(), 10, 1, MAX_DIVISOR, result);
|
||||||
else {
|
else {
|
||||||
istringstream stream(divisorStr);
|
istringstream stream(divisorStr);
|
||||||
while (getline(stream, token, VALUE_SEPARATOR) != 0) {
|
while (getline(stream, token, VALUE_SEPARATOR) != 0) {
|
||||||
const char* str = token.c_str();
|
const char* str = token.c_str();
|
||||||
char* strEnd = NULL;
|
char* strEnd = NULL;
|
||||||
unsigned int id;
|
unsigned long int id;
|
||||||
if (strncasecmp(str, "0x", 2) == 0)
|
if (strncasecmp(str, "0x", 2) == 0)
|
||||||
id = strtoul(str+2, &strEnd, 16); // hexadecimal
|
id = strtoul(str+2, &strEnd, 16); // hexadecimal
|
||||||
else
|
else
|
||||||
id = strtoul(str, &strEnd, 10); // decimal
|
id = strtoul(str, &strEnd, 10); // decimal
|
||||||
if (strEnd == NULL || strEnd == str || *strEnd != '=') {
|
if (strEnd == NULL || strEnd == str || *strEnd != '=' || id > MAX_VALUE) {
|
||||||
result = RESULT_ERR_INVALID_LIST;
|
result = RESULT_ERR_INVALID_LIST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
values[id] = string(strEnd + 1);
|
values[(unsigned int)id] = string(strEnd + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
@@ -261,7 +263,6 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
if (templates != NULL) {
|
if (templates != NULL) {
|
||||||
istringstream stream(typeStr);
|
istringstream stream(typeStr);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
string lengthStr;
|
|
||||||
while (result == RESULT_OK && getline(stream, token, VALUE_SEPARATOR) != 0) {
|
while (result == RESULT_OK && getline(stream, token, VALUE_SEPARATOR) != 0) {
|
||||||
DataField* templ = templates->get(token);
|
DataField* templ = templates->get(token);
|
||||||
if (templ == NULL) {
|
if (templ == NULL) {
|
||||||
@@ -282,7 +283,7 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
typeName = typeStr;
|
typeName = typeStr;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
length = parseInt(typeStr.substr(pos+1).c_str(), 10, 1, MAX_POS, result);
|
length = (unsigned char)parseInt(typeStr.substr(pos+1).c_str(), 10, 1, MAX_POS, result);
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
break;
|
break;
|
||||||
typeName = typeStr.substr(0, pos);
|
typeName = typeStr.substr(0, pos);
|
||||||
@@ -294,7 +295,7 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
const dataType_t* dataType = &dataTypes[i];
|
const dataType_t* dataType = &dataTypes[i];
|
||||||
if (strcasecmp(typeNameStr, dataType->name) == 0) {
|
if (strcasecmp(typeNameStr, dataType->name) == 0) {
|
||||||
unsigned char bitCount = dataType->bitCount;
|
unsigned char bitCount = dataType->bitCount;
|
||||||
unsigned char byteCount = (bitCount + 7) / 8;
|
unsigned char byteCount = (unsigned char)((bitCount + 7) / 8);
|
||||||
if ((dataType->flags & ADJ) != 0) { // adjustable length
|
if ((dataType->flags & ADJ) != 0) { // adjustable length
|
||||||
if ((bitCount % 8) != 0) {
|
if ((bitCount % 8) != 0) {
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
@@ -306,7 +307,7 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
byteCount = (bitCount + 7) / 8;
|
byteCount = (unsigned char)((bitCount + 7) / 8);
|
||||||
}
|
}
|
||||||
else if (length == 0)
|
else if (length == 0)
|
||||||
byteCount = 1; //default byte count: 1 byte
|
byteCount = 1; //default byte count: 1 byte
|
||||||
@@ -336,8 +337,13 @@ result_t DataField::create(vector<string>::iterator& it,
|
|||||||
if (values.empty() || (dataType->flags & LST) == 0) {
|
if (values.empty() || (dataType->flags & LST) == 0) {
|
||||||
if (divisor == 0)
|
if (divisor == 0)
|
||||||
divisor = 1;
|
divisor = 1;
|
||||||
if ((dataType->bitCount % 8) == 0)
|
if ((dataType->bitCount % 8) == 0) {
|
||||||
divisor *= dataType->divisorOrFirstBit;
|
divisor *= dataType->divisorOrFirstBit;
|
||||||
|
if (divisor > MAX_DIVISOR) {
|
||||||
|
result = RESULT_ERR_OUT_OF_RANGE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add = new NumberDataField(name, comment, unit, *dataType, partType, byteCount, bitCount, divisor);
|
add = new NumberDataField(name, comment, unit, *dataType, partType, byteCount, bitCount, divisor);
|
||||||
break;
|
break;
|
||||||
@@ -403,7 +409,7 @@ void SingleDataField::dump(ostream& output)
|
|||||||
result_t SingleDataField::read(const PartType partType,
|
result_t SingleDataField::read(const PartType partType,
|
||||||
SymbolString& data, unsigned char offset,
|
SymbolString& data, unsigned char offset,
|
||||||
ostringstream& output, bool leadingSeparator,
|
ostringstream& output, bool leadingSeparator,
|
||||||
bool verbose, const char* filterName,
|
bool verbose, const char* fieldName, char fieldIndex,
|
||||||
char separator)
|
char separator)
|
||||||
{
|
{
|
||||||
if (partType != m_partType)
|
if (partType != m_partType)
|
||||||
@@ -412,15 +418,15 @@ result_t SingleDataField::read(const PartType partType,
|
|||||||
switch (m_partType)
|
switch (m_partType)
|
||||||
{
|
{
|
||||||
case pt_masterData:
|
case pt_masterData:
|
||||||
offset += 5; // skip QQ ZZ PB SB NN
|
offset = (unsigned char)(offset + 5); // skip QQ ZZ PB SB NN
|
||||||
break;
|
break;
|
||||||
case pt_slaveData:
|
case pt_slaveData:
|
||||||
offset += 1; // skip NN
|
offset++; // skip NN
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return RESULT_ERR_INVALID_PART;
|
return RESULT_ERR_INVALID_PART;
|
||||||
}
|
}
|
||||||
if (isIgnored() || (filterName != NULL && m_name != filterName)) {
|
if (isIgnored() || (fieldName != NULL && (m_name != fieldName || fieldIndex > 0))) {
|
||||||
if (offset + m_length > data.size()) {
|
if (offset + m_length > data.size()) {
|
||||||
return RESULT_ERR_INVALID_POS;
|
return RESULT_ERR_INVALID_POS;
|
||||||
}
|
}
|
||||||
@@ -455,10 +461,10 @@ result_t SingleDataField::write(istringstream& input,
|
|||||||
switch (m_partType)
|
switch (m_partType)
|
||||||
{
|
{
|
||||||
case pt_masterData:
|
case pt_masterData:
|
||||||
offset += 5; // skip QQ ZZ PB SB NN
|
offset = (unsigned char)(offset + 5); // skip QQ ZZ PB SB NN
|
||||||
break;
|
break;
|
||||||
case pt_slaveData:
|
case pt_slaveData:
|
||||||
offset += 1; // skip NN
|
offset++; // skip NN
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return RESULT_ERR_INVALID_PART;
|
return RESULT_ERR_INVALID_PART;
|
||||||
@@ -521,7 +527,7 @@ result_t StringDataField::readSymbols(SymbolString& input,
|
|||||||
if ((m_dataType.flags & BCD) != 0) {
|
if ((m_dataType.flags & BCD) != 0) {
|
||||||
if ((ch & 0xf0) > 0x90 || (ch & 0x0f) > 0x09)
|
if ((ch & 0xf0) > 0x90 || (ch & 0x0f) > 0x09)
|
||||||
return RESULT_ERR_OUT_OF_RANGE; // invalid BCD
|
return RESULT_ERR_OUT_OF_RANGE; // invalid BCD
|
||||||
ch = (ch >> 4) * 10 + (ch & 0x0f);
|
ch = (unsigned char)((ch >> 4) * 10 + (ch & 0x0f));
|
||||||
}
|
}
|
||||||
switch (m_dataType.type)
|
switch (m_dataType.type)
|
||||||
{
|
{
|
||||||
@@ -566,7 +572,7 @@ result_t StringDataField::readSymbols(SymbolString& input,
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ch = (ch % 6) * 10; // minutes
|
ch = (unsigned char)((ch % 6) * 10); // minutes
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (ch > 24)
|
if (ch > 24)
|
||||||
@@ -581,7 +587,7 @@ result_t StringDataField::readSymbols(SymbolString& input,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ch < 0x20)
|
if (ch < 0x20)
|
||||||
ch = m_dataType.replacement;
|
ch = (unsigned char)m_dataType.replacement;
|
||||||
output << setw(0) << dec << static_cast<char>(ch);
|
output << setw(0) << dec << static_cast<char>(ch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -596,7 +602,7 @@ result_t StringDataField::writeSymbols(istringstream& input,
|
|||||||
{
|
{
|
||||||
size_t start = 0, count = m_length;
|
size_t start = 0, count = m_length;
|
||||||
int incr = 1;
|
int incr = 1;
|
||||||
unsigned long int value = 0, last = 0, lastLast = 0;
|
unsigned int value = 0, last = 0, lastLast = 0;
|
||||||
string token;
|
string token;
|
||||||
|
|
||||||
if ((m_dataType.flags & REV) != 0) { // reverted binary representation (most significant byte first)
|
if ((m_dataType.flags & REV) != 0) { // reverted binary representation (most significant byte first)
|
||||||
@@ -606,7 +612,7 @@ result_t StringDataField::writeSymbols(istringstream& input,
|
|||||||
|
|
||||||
if (isIgnored() && (m_dataType.flags & REQ) == 0) {
|
if (isIgnored() && (m_dataType.flags & REQ) == 0) {
|
||||||
for (size_t offset = start, i = 0; i < count; offset += incr, i++) {
|
for (size_t offset = start, i = 0; i < count; offset += incr, i++) {
|
||||||
output[baseOffset + offset] = m_dataType.replacement; // fill up with replacement
|
output[baseOffset + offset] = (unsigned char)m_dataType.replacement; // fill up with replacement
|
||||||
}
|
}
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -622,10 +628,10 @@ result_t StringDataField::writeSymbols(istringstream& input,
|
|||||||
value = m_dataType.replacement; // fill up with replacement
|
value = m_dataType.replacement; // fill up with replacement
|
||||||
else {
|
else {
|
||||||
token.clear();
|
token.clear();
|
||||||
token.push_back(input.get());
|
token.push_back((unsigned char)input.get());
|
||||||
if (input.eof())
|
if (input.eof())
|
||||||
return RESULT_ERR_INVALID_NUM; // too short hex value
|
return RESULT_ERR_INVALID_NUM; // too short hex value
|
||||||
token.push_back(input.get());
|
token.push_back((unsigned char)input.get());
|
||||||
if (input.eof())
|
if (input.eof())
|
||||||
return RESULT_ERR_INVALID_NUM; // too short hex value
|
return RESULT_ERR_INVALID_NUM; // too short hex value
|
||||||
|
|
||||||
@@ -660,7 +666,7 @@ result_t StringDataField::writeSymbols(istringstream& input,
|
|||||||
return RESULT_ERR_INVALID_NUM; // invalid date
|
return RESULT_ERR_INVALID_NUM; // invalid date
|
||||||
unsigned char daysSinceSunday = (unsigned char)t.tm_wday; // Sun=0
|
unsigned char daysSinceSunday = (unsigned char)t.tm_wday; // Sun=0
|
||||||
if ((m_dataType.flags & BCD) != 0)
|
if ((m_dataType.flags & BCD) != 0)
|
||||||
output[baseOffset + offset - incr] = (6+daysSinceSunday) % 7; // Sun=0x06
|
output[baseOffset + offset - incr] = (unsigned char)((6+daysSinceSunday) % 7); // Sun=0x06
|
||||||
else
|
else
|
||||||
output[baseOffset + offset - incr] = (daysSinceSunday==0 ? 7 : daysSinceSunday); // Sun=0x07
|
output[baseOffset + offset - incr] = (daysSinceSunday==0 ? 7 : daysSinceSunday); // Sun=0x07
|
||||||
}
|
}
|
||||||
@@ -771,7 +777,8 @@ result_t NumericDataField::readRawValue(SymbolString& input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
value = 0;
|
value = 0;
|
||||||
for (size_t offset = start, i = 0, exp = 1; i < count; offset += incr, i++) {
|
unsigned int exp = 1;
|
||||||
|
for (size_t offset = start, i = 0; i < count; offset += incr, i++) {
|
||||||
ch = input[baseOffset + offset];
|
ch = input[baseOffset + offset];
|
||||||
if ((m_dataType.flags & BCD) != 0) {
|
if ((m_dataType.flags & BCD) != 0) {
|
||||||
if ((m_dataType.flags & REQ) == 0 && ch == (m_dataType.replacement & 0xff)) {
|
if ((m_dataType.flags & REQ) == 0 && ch == (m_dataType.replacement & 0xff)) {
|
||||||
@@ -781,7 +788,7 @@ result_t NumericDataField::readRawValue(SymbolString& input,
|
|||||||
if ((ch & 0xf0) > 0x90 || (ch & 0x0f) > 0x09)
|
if ((ch & 0xf0) > 0x90 || (ch & 0x0f) > 0x09)
|
||||||
return RESULT_ERR_OUT_OF_RANGE; // invalid BCD
|
return RESULT_ERR_OUT_OF_RANGE; // invalid BCD
|
||||||
|
|
||||||
ch = (ch >> 4) * 10 + (ch & 0x0f);
|
ch = (unsigned char)((ch >> 4) * 10 + (ch & 0x0f));
|
||||||
value += ch * exp;
|
value += ch * exp;
|
||||||
exp *= 100;
|
exp *= 100;
|
||||||
}
|
}
|
||||||
@@ -823,8 +830,8 @@ result_t NumericDataField::writeRawValue(unsigned int value,
|
|||||||
if ((m_dataType.flags & REQ) == 0 && value == m_dataType.replacement)
|
if ((m_dataType.flags & REQ) == 0 && value == m_dataType.replacement)
|
||||||
ch = m_dataType.replacement & 0xff;
|
ch = m_dataType.replacement & 0xff;
|
||||||
else {
|
else {
|
||||||
ch = (value / exp) % 100;
|
ch = (unsigned char)((value / exp) % 100);
|
||||||
ch = ((ch / 10) << 4) | (ch % 10);
|
ch = (unsigned char)(((ch / 10) << 4) | (ch % 10));
|
||||||
}
|
}
|
||||||
exp = exp * 100;
|
exp = exp * 100;
|
||||||
}
|
}
|
||||||
@@ -847,10 +854,10 @@ NumberDataField::NumberDataField(const string name, const string comment,
|
|||||||
const unsigned char length, const unsigned char bitCount,
|
const unsigned char length, const unsigned char bitCount,
|
||||||
const unsigned int divisor)
|
const unsigned int divisor)
|
||||||
: NumericDataField(name, comment, unit, dataType, partType, length, bitCount,
|
: NumericDataField(name, comment, unit, dataType, partType, length, bitCount,
|
||||||
(dataType.bitCount % 8) == 0 ? 0 : dataType.divisorOrFirstBit),
|
(dataType.bitCount % 8) == 0 ? 0 : (unsigned char)dataType.divisorOrFirstBit),
|
||||||
m_divisor(divisor), m_precision(0)
|
m_divisor(divisor), m_precision(0)
|
||||||
{
|
{
|
||||||
for (unsigned int exp = 1; exp < 1000000000; exp *= 10, m_precision++)
|
for (unsigned int exp = 1; exp < MAX_DIVISOR; exp *= 10, m_precision++)
|
||||||
if (exp >= divisor)
|
if (exp >= divisor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -870,8 +877,12 @@ result_t NumberDataField::derive(string name, string comment,
|
|||||||
unit = m_unit;
|
unit = m_unit;
|
||||||
if (divisor == 0)
|
if (divisor == 0)
|
||||||
divisor = m_divisor;
|
divisor = m_divisor;
|
||||||
else if ((m_dataType.bitCount % 8) == 0)
|
else if ((m_dataType.bitCount % 8) == 0) {
|
||||||
divisor *= m_dataType.divisorOrFirstBit;
|
divisor *= m_dataType.divisorOrFirstBit;
|
||||||
|
if (divisor > MAX_DIVISOR) {
|
||||||
|
return RESULT_ERR_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!values.empty()) {
|
if (!values.empty()) {
|
||||||
if (divisor != 1)
|
if (divisor != 1)
|
||||||
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
|
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
|
||||||
@@ -917,7 +928,7 @@ result_t NumberDataField::readSymbols(SymbolString& input,
|
|||||||
output << static_cast<unsigned>(value);
|
output << static_cast<unsigned>(value);
|
||||||
else
|
else
|
||||||
output << setprecision(m_precision)
|
output << setprecision(m_precision)
|
||||||
<< fixed << static_cast<float>(value / (float) m_divisor);
|
<< fixed << static_cast<float>((float)value / (float)m_divisor);
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
signedValue = (int) value; // negative signed value
|
signedValue = (int) value; // negative signed value
|
||||||
@@ -934,7 +945,7 @@ result_t NumberDataField::readSymbols(SymbolString& input,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
output << setprecision(m_precision)
|
output << setprecision(m_precision)
|
||||||
<< fixed << static_cast<float>(signedValue / (float) m_divisor);
|
<< fixed << static_cast<float>((float)signedValue / (float)m_divisor);
|
||||||
|
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -953,14 +964,14 @@ result_t NumberDataField::writeSymbols(istringstream& input,
|
|||||||
char* strEnd = NULL;
|
char* strEnd = NULL;
|
||||||
if (m_divisor <= 1) {
|
if (m_divisor <= 1) {
|
||||||
if ((m_dataType.flags & SIG) != 0) {
|
if ((m_dataType.flags & SIG) != 0) {
|
||||||
int signedValue = strtol(str, &strEnd, 10);
|
long int signedValue = strtol(str, &strEnd, 10);
|
||||||
if (signedValue < 0 && m_bitCount != 32)
|
if (signedValue < 0 && m_bitCount != 32)
|
||||||
value = (unsigned int) (signedValue + (1 << m_bitCount));
|
value = (unsigned int)(signedValue + (1 << m_bitCount));
|
||||||
else
|
else
|
||||||
value = (unsigned int) signedValue;
|
value = (unsigned int)signedValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = strtoul(str, &strEnd, 10);
|
value = (unsigned int)strtoul(str, &strEnd, 10);
|
||||||
if (strEnd == NULL || *strEnd != 0)
|
if (strEnd == NULL || *strEnd != 0)
|
||||||
return RESULT_ERR_INVALID_NUM; // invalid value
|
return RESULT_ERR_INVALID_NUM; // invalid value
|
||||||
}
|
}
|
||||||
@@ -974,9 +985,9 @@ result_t NumberDataField::writeSymbols(istringstream& input,
|
|||||||
if (dvalue < -(1LL << (8 * m_length)) || dvalue >= (1LL << (8 * m_length)))
|
if (dvalue < -(1LL << (8 * m_length)) || dvalue >= (1LL << (8 * m_length)))
|
||||||
return RESULT_ERR_OUT_OF_RANGE; // value out of range
|
return RESULT_ERR_OUT_OF_RANGE; // value out of range
|
||||||
if (dvalue < 0 && m_bitCount != 32)
|
if (dvalue < 0 && m_bitCount != 32)
|
||||||
value = (unsigned int) (dvalue + (1 << m_bitCount));
|
value = (unsigned int)(dvalue + (1 << m_bitCount));
|
||||||
else
|
else
|
||||||
value = (unsigned int) dvalue;
|
value = (unsigned int)dvalue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dvalue < 0.0 || dvalue >= (1LL << (8 * m_length)))
|
if (dvalue < 0.0 || dvalue >= (1LL << (8 * m_length)))
|
||||||
@@ -1144,7 +1155,7 @@ unsigned char DataFieldSet::getLength(PartType partType)
|
|||||||
if (!previousFullByteOffset[partType] && !field->hasFullByteOffset(false))
|
if (!previousFullByteOffset[partType] && !field->hasFullByteOffset(false))
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
length += field->getLength(partType);
|
length = (unsigned char)(length + field->getLength(partType));
|
||||||
|
|
||||||
previousFullByteOffset[partType] = field->hasFullByteOffset(true);
|
previousFullByteOffset[partType] = field->hasFullByteOffset(true);
|
||||||
}
|
}
|
||||||
@@ -1185,10 +1196,10 @@ void DataFieldSet::dump(ostream& output)
|
|||||||
result_t DataFieldSet::read(const PartType partType,
|
result_t DataFieldSet::read(const PartType partType,
|
||||||
SymbolString& data, unsigned char offset,
|
SymbolString& data, unsigned char offset,
|
||||||
ostringstream& output, bool leadingSeparator,
|
ostringstream& output, bool leadingSeparator,
|
||||||
bool verbose, const char* filterName,
|
bool verbose, const char* fieldName, char fieldIndex,
|
||||||
char separator)
|
char separator)
|
||||||
{
|
{
|
||||||
bool previousFullByteOffset = true, found = false;
|
bool previousFullByteOffset = true, found = false, findFieldIndex = fieldName != NULL && fieldIndex >= 0;
|
||||||
for (vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
|
for (vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
|
||||||
SingleDataField* field = *it;
|
SingleDataField* field = *it;
|
||||||
if (partType != pt_any && field->getPartType() != partType)
|
if (partType != pt_any && field->getPartType() != partType)
|
||||||
@@ -1197,19 +1208,29 @@ result_t DataFieldSet::read(const PartType partType,
|
|||||||
if (!previousFullByteOffset && !field->hasFullByteOffset(false))
|
if (!previousFullByteOffset && !field->hasFullByteOffset(false))
|
||||||
offset--;
|
offset--;
|
||||||
|
|
||||||
result_t result = field->read(partType, data, offset, output, leadingSeparator, verbose, filterName, separator);
|
result_t result = field->read(partType, data, offset, output, leadingSeparator, verbose, fieldName, fieldIndex, separator);
|
||||||
|
|
||||||
if (result < RESULT_OK)
|
if (result < RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
offset += field->getLength(partType);
|
offset = (unsigned char)(offset + field->getLength(partType));
|
||||||
previousFullByteOffset = field->hasFullByteOffset(true);
|
previousFullByteOffset = field->hasFullByteOffset(true);
|
||||||
if (result != RESULT_EMPTY) {
|
if (result != RESULT_EMPTY) {
|
||||||
found = true;
|
found = true;
|
||||||
leadingSeparator = true;
|
leadingSeparator = true;
|
||||||
}
|
}
|
||||||
|
if (findFieldIndex && fieldName == field->getName()) {
|
||||||
|
if (fieldIndex == 0) {
|
||||||
|
if (!found)
|
||||||
|
return RESULT_ERR_NOTFOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fieldIndex--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (findFieldIndex && !found)
|
||||||
|
return RESULT_ERR_NOTFOUND;
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
if (m_comment.length() > 0)
|
if (m_comment.length() > 0)
|
||||||
output << " [" << m_comment << "]";
|
output << " [" << m_comment << "]";
|
||||||
@@ -1249,7 +1270,7 @@ result_t DataFieldSet::write(istringstream& input,
|
|||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
offset += field->getLength(partType);
|
offset = (unsigned char)(offset + field->getLength(partType));
|
||||||
previousFullByteOffset = field->hasFullByteOffset(true);
|
previousFullByteOffset = field->hasFullByteOffset(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-7
@@ -76,15 +76,18 @@ static const unsigned int REQ = 0x100;//!< value may not be NULL
|
|||||||
/** The structure for defining field types with their properties. */
|
/** The structure for defining field types with their properties. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* name; //!< field identifier
|
const char* name; //!< field identifier
|
||||||
const unsigned int bitCount; //!< number of bits (maximum length if @a ADJ flag is set, must be multiple of 8 with flag @a BCD)
|
const unsigned char bitCount; //!< number of bits (maximum length if @a ADJ flag is set, must be multiple of 8 with flag @a BCD)
|
||||||
const BaseType type; //!< base data type
|
const BaseType type; //!< base data type
|
||||||
const unsigned int flags; //!< flags (e.g. @a BCD)
|
const unsigned short flags; //!< flags (e.g. @a BCD)
|
||||||
const unsigned int replacement; //!< replacement value (fill-up value for @a bt_str / @a bt_hexstr, no replacement if equal to @a minValueOrLength for @a bt_num)
|
const unsigned int replacement; //!< replacement value (fill-up value for @a bt_str / @a bt_hexstr, no replacement if equal to @a minValueOrLength for @a bt_num)
|
||||||
const unsigned int minValueOrLength; //!< minimum binary value (minimum length of string for @a StringDataField)
|
const unsigned int minValueOrLength; //!< minimum binary value (minimum length of string for @a StringDataField)
|
||||||
const unsigned int maxValueOrLength; //!< maximum binary value (maximum length of string for @a StringDataField)
|
const unsigned int maxValueOrLength; //!< maximum binary value (maximum length of string for @a StringDataField)
|
||||||
const unsigned int divisorOrFirstBit; //!< @a bt_number: divisor or offset to first bit (if (@a bitCount%8)!=0)
|
const unsigned short divisorOrFirstBit; //!< @a bt_number: divisor or offset to first bit (if (@a bitCount%8)!=0)
|
||||||
} dataType_t;
|
} dataType_t;
|
||||||
|
|
||||||
|
/** the maximum position within master or slave data. */
|
||||||
|
#define MAX_POS 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an unsigned int value.
|
* Parse an unsigned int value.
|
||||||
* @param str the string to parse.
|
* @param str the string to parse.
|
||||||
@@ -214,7 +217,7 @@ public:
|
|||||||
virtual result_t read(const PartType partType,
|
virtual result_t read(const PartType partType,
|
||||||
SymbolString& data, unsigned char offset,
|
SymbolString& data, unsigned char offset,
|
||||||
ostringstream& output, bool leadingSeparator=false,
|
ostringstream& output, bool leadingSeparator=false,
|
||||||
bool verbose=false, const char* filterName=NULL,
|
bool verbose=false, const char* fieldName=NULL, char fieldIndex=-1,
|
||||||
char separator=UI_FIELD_SEPARATOR) = 0;
|
char separator=UI_FIELD_SEPARATOR) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,7 +309,7 @@ public:
|
|||||||
virtual result_t read(const PartType partType,
|
virtual result_t read(const PartType partType,
|
||||||
SymbolString& data, unsigned char offset,
|
SymbolString& data, unsigned char offset,
|
||||||
ostringstream& output, bool leadingSeparator=false,
|
ostringstream& output, bool leadingSeparator=false,
|
||||||
bool verbose=false, const char* filterName=NULL,
|
bool verbose=false, const char* fieldName=NULL, char fieldIndex=-1,
|
||||||
char separator=UI_FIELD_SEPARATOR);
|
char separator=UI_FIELD_SEPARATOR);
|
||||||
|
|
||||||
// @copydoc
|
// @copydoc
|
||||||
@@ -540,7 +543,7 @@ public:
|
|||||||
const unsigned char length, const unsigned char bitCount,
|
const unsigned char length, const unsigned char bitCount,
|
||||||
const map<unsigned int, string> values)
|
const map<unsigned int, string> values)
|
||||||
: NumericDataField(name, comment, unit, dataType, partType, length, bitCount,
|
: NumericDataField(name, comment, unit, dataType, partType, length, bitCount,
|
||||||
(dataType.bitCount < 8) ? dataType.divisorOrFirstBit : 0),
|
(dataType.bitCount < 8) ? (unsigned char)dataType.divisorOrFirstBit : 0),
|
||||||
m_values(values) {}
|
m_values(values) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -638,7 +641,7 @@ public:
|
|||||||
virtual result_t read(const PartType partType,
|
virtual result_t read(const PartType partType,
|
||||||
SymbolString& data, unsigned char offset,
|
SymbolString& data, unsigned char offset,
|
||||||
ostringstream& output, bool leadingSeparator=false,
|
ostringstream& output, bool leadingSeparator=false,
|
||||||
bool verbose=false, const char* filterName=NULL,
|
bool verbose=false, const char* fieldName=NULL, char fieldIndex=-1,
|
||||||
char separator=UI_FIELD_SEPARATOR);
|
char separator=UI_FIELD_SEPARATOR);
|
||||||
|
|
||||||
// @copydoc
|
// @copydoc
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ Device* Device::create(const char* name, const bool checkDevice,
|
|||||||
char* pos = strchr((char*)name, ':');
|
char* pos = strchr((char*)name, ':');
|
||||||
if (pos != NULL) {
|
if (pos != NULL) {
|
||||||
char* end = NULL;
|
char* end = NULL;
|
||||||
unsigned int port = strtoul(pos+1, &end, 10);
|
unsigned long int port = strtoul(pos+1, &end, 10);
|
||||||
if (end == NULL || *end != 0 || port < 1 || port > 65535) {
|
if (end == NULL || *end != 0 || port < 1 || port > 65535) {
|
||||||
return NULL; // invalid port
|
return NULL; // invalid port
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-19
@@ -37,7 +37,7 @@ Message::Message(const string clazz, const string name, const bool isWrite,
|
|||||||
const bool isPassive, const string comment,
|
const bool isPassive, const string comment,
|
||||||
const unsigned char srcAddress, const unsigned char dstAddress,
|
const unsigned char srcAddress, const unsigned char dstAddress,
|
||||||
const vector<unsigned char> id, DataField* data,
|
const vector<unsigned char> id, DataField* data,
|
||||||
const unsigned int pollPriority)
|
const unsigned char pollPriority)
|
||||||
: m_class(clazz), m_name(name), m_isWrite(isWrite),
|
: m_class(clazz), m_name(name), m_isWrite(isWrite),
|
||||||
m_isPassive(isPassive), m_comment(comment),
|
m_isPassive(isPassive), m_comment(comment),
|
||||||
m_srcAddress(srcAddress), m_dstAddress(dstAddress),
|
m_srcAddress(srcAddress), m_dstAddress(dstAddress),
|
||||||
@@ -94,7 +94,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
result_t result;
|
result_t result;
|
||||||
bool isWrite = false, isPassive = false;
|
bool isWrite = false, isPassive = false;
|
||||||
string defaultName;
|
string defaultName;
|
||||||
unsigned int pollPriority = 0;
|
unsigned char pollPriority = 0;
|
||||||
size_t defaultPos = 1;
|
size_t defaultPos = 1;
|
||||||
if (it == end)
|
if (it == end)
|
||||||
return RESULT_ERR_EOF;
|
return RESULT_ERR_EOF;
|
||||||
@@ -108,7 +108,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
} else if (strncasecmp(str, "R", 1) == 0) { // active get
|
} else if (strncasecmp(str, "R", 1) == 0) { // active get
|
||||||
char last = str[len-1];
|
char last = str[len-1];
|
||||||
if (last >= '0' && last <= '9') { // poll priority (=active get)
|
if (last >= '0' && last <= '9') { // poll priority (=active get)
|
||||||
pollPriority = last - '0';
|
pollPriority = (unsigned char)(last - '0');
|
||||||
defaultName = string(str).substr(0, len - 1); // cut off priority digit
|
defaultName = string(str).substr(0, len - 1); // cut off priority digit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -157,7 +157,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
if (*str == 0)
|
if (*str == 0)
|
||||||
srcAddress = SYN; // no specific source
|
srcAddress = SYN; // no specific source
|
||||||
else {
|
else {
|
||||||
srcAddress = parseInt(str, 16, 0, 0xff, result);
|
srcAddress = (unsigned char)parseInt(str, 16, 0, 0xff, result);
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
if (!isMaster(srcAddress))
|
if (!isMaster(srcAddress))
|
||||||
@@ -171,7 +171,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
if (*str == 0)
|
if (*str == 0)
|
||||||
dstAddress = SYN; // no specific destination
|
dstAddress = SYN; // no specific destination
|
||||||
else {
|
else {
|
||||||
dstAddress = parseInt(str, 16, 0, 0xff, result);
|
dstAddress = (unsigned char)parseInt(str, 16, 0, 0xff, result);
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
if (!isValidAddress(dstAddress))
|
if (!isValidAddress(dstAddress))
|
||||||
@@ -197,13 +197,13 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
if (input.eof()) // no more digits
|
if (input.eof()) // no more digits
|
||||||
break;
|
break;
|
||||||
token.clear();
|
token.clear();
|
||||||
token.push_back(input.get());
|
token.push_back((char)input.get());
|
||||||
if (input.eof()) {
|
if (input.eof()) {
|
||||||
return RESULT_ERR_INVALID_ARG; // too short hex
|
return RESULT_ERR_INVALID_ARG; // too short hex
|
||||||
}
|
}
|
||||||
token.push_back(input.get());
|
token.push_back((char)input.get());
|
||||||
|
|
||||||
unsigned char value = parseInt(token.c_str(), 16, 0, 0xff, result);
|
unsigned char value = (unsigned char)parseInt(token.c_str(), 16, 0, 0xff, result);
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
return result; // invalid hex value
|
return result; // invalid hex value
|
||||||
}
|
}
|
||||||
@@ -244,6 +244,11 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
|||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (id.size() + data->getLength(pt_masterData) > 2 + MAX_POS || data->getLength(pt_slaveData) > MAX_POS) {
|
||||||
|
// max NN exceeded
|
||||||
|
delete data;
|
||||||
|
return RESULT_ERR_INVALID_POS;
|
||||||
|
}
|
||||||
returnValue = new Message(clazz, name, isWrite, isPassive, comment, srcAddress, dstAddress, id, data, pollPriority);
|
returnValue = new Message(clazz, name, isWrite, isPassive, comment, srcAddress, dstAddress, id, data, pollPriority);
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -273,7 +278,7 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma
|
|||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
unsigned char addData = m_data->getLength(pt_masterData);
|
unsigned char addData = m_data->getLength(pt_masterData);
|
||||||
result = master.push_back(m_id.size() - 2 + addData, false, false);
|
result = master.push_back((unsigned char)(m_id.size() - 2 + addData), false, false);
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
for (size_t i=2; i<m_id.size(); i++) {
|
for (size_t i=2; i<m_id.size(); i++) {
|
||||||
@@ -281,7 +286,7 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma
|
|||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = m_data->write(input, pt_masterData, master, m_id.size() - 2, separator);
|
result = m_data->write(input, pt_masterData, master, (unsigned char)(m_id.size() - 2), separator);
|
||||||
if (result != RESULT_OK)
|
if (result != RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
masterData.addAll(master);
|
masterData.addAll(master);
|
||||||
@@ -308,16 +313,16 @@ result_t Message::prepareSlave(SymbolString& slaveData)
|
|||||||
|
|
||||||
result_t Message::decode(const PartType partType, SymbolString& data,
|
result_t Message::decode(const PartType partType, SymbolString& data,
|
||||||
ostringstream& output, bool leadingSeparator,
|
ostringstream& output, bool leadingSeparator,
|
||||||
bool verbose, const char* filterName,
|
bool verbose, const char* fieldName, char fieldIndex,
|
||||||
char separator)
|
char separator)
|
||||||
{
|
{
|
||||||
unsigned char offset;
|
unsigned char offset;
|
||||||
if (partType == pt_masterData)
|
if (partType == pt_masterData)
|
||||||
offset = m_id.size() - 2;
|
offset = (unsigned char)(m_id.size() - 2);
|
||||||
else
|
else
|
||||||
offset = 0;
|
offset = 0;
|
||||||
size_t startPos = output.str().length();
|
size_t startPos = output.str().length();
|
||||||
result_t result = m_data->read(partType, data, offset, output, leadingSeparator, verbose, filterName, separator);
|
result_t result = m_data->read(partType, data, offset, output, leadingSeparator, verbose, fieldName, fieldIndex, separator);
|
||||||
if (result < RESULT_OK) {
|
if (result < RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -331,18 +336,17 @@ result_t Message::decode(const PartType partType, SymbolString& data,
|
|||||||
|
|
||||||
result_t Message::decode(SymbolString& masterData, SymbolString& slaveData,
|
result_t Message::decode(SymbolString& masterData, SymbolString& slaveData,
|
||||||
ostringstream& output, bool leadingSeparator,
|
ostringstream& output, bool leadingSeparator,
|
||||||
bool verbose, const char* filterName,
|
bool verbose, char separator)
|
||||||
char separator)
|
|
||||||
{
|
{
|
||||||
unsigned char offset = m_id.size() - 2;
|
unsigned char offset = (unsigned char)(m_id.size() - 2);
|
||||||
size_t startPos = output.str().length();
|
size_t startPos = output.str().length();
|
||||||
result_t result = m_data->read(pt_masterData, masterData, offset, output, leadingSeparator, verbose, filterName, separator);
|
result_t result = m_data->read(pt_masterData, masterData, offset, output, leadingSeparator, verbose, NULL, -1, separator);
|
||||||
if (result < RESULT_OK) {
|
if (result < RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
offset = 0;
|
offset = 0;
|
||||||
leadingSeparator = output.str().length() > startPos;
|
leadingSeparator = output.str().length() > startPos;
|
||||||
result = m_data->read(pt_slaveData, slaveData, offset, output, leadingSeparator, verbose, filterName, separator);
|
result = m_data->read(pt_slaveData, slaveData, offset, output, leadingSeparator, verbose, NULL, -1, separator);
|
||||||
if (result < RESULT_OK) {
|
if (result < RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -443,7 +447,7 @@ result_t MessageMap::add(Message* message)
|
|||||||
m_messagesByName[nameKey] = message; // only store first key without class
|
m_messagesByName[nameKey] = message; // only store first key without class
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char idLength = message->getId().size() - 2;
|
unsigned char idLength = (unsigned char)(message->getId().size() - 2);
|
||||||
if (idLength < m_minIdLength)
|
if (idLength < m_minIdLength)
|
||||||
m_minIdLength = idLength;
|
m_minIdLength = idLength;
|
||||||
if (idLength > m_maxIdLength)
|
if (idLength > m_maxIdLength)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
const bool isPassive, const string comment,
|
const bool isPassive, const string comment,
|
||||||
const unsigned char srcAddress, const unsigned char dstAddress,
|
const unsigned char srcAddress, const unsigned char dstAddress,
|
||||||
const vector<unsigned char> id, DataField* data,
|
const vector<unsigned char> id, DataField* data,
|
||||||
const unsigned int pollPriority);
|
const unsigned char pollPriority);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new temporary instance.
|
* Construct a new temporary instance.
|
||||||
@@ -183,13 +183,14 @@ public:
|
|||||||
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
||||||
* @param verbose whether to prepend the name, append the unit (if present), and append
|
* @param verbose whether to prepend the name, append the unit (if present), and append
|
||||||
* the comment in square brackets (if present).
|
* the comment in square brackets (if present).
|
||||||
* @param filterName the optional name of a field to limit the output to.
|
* @param fieldName the optional name of a field to limit the output to.
|
||||||
|
* @param fieldIndex the optional index of the named field to limit the output to, or -1.
|
||||||
* @param separator the separator character between multiple fields.
|
* @param separator the separator character between multiple fields.
|
||||||
* @return @a RESULT_OK on success, or an error code.
|
* @return @a RESULT_OK on success, or an error code.
|
||||||
*/
|
*/
|
||||||
result_t decode(const PartType partType, SymbolString& data,
|
result_t decode(const PartType partType, SymbolString& data,
|
||||||
ostringstream& output, bool leadingSeparator=false,
|
ostringstream& output, bool leadingSeparator=false,
|
||||||
bool verbose=false, const char* filterName=NULL,
|
bool verbose=false, const char* fieldName=NULL, char fieldIndex=-1,
|
||||||
char separator=UI_FIELD_SEPARATOR);
|
char separator=UI_FIELD_SEPARATOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,14 +201,12 @@ public:
|
|||||||
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
||||||
* @param verbose whether to prepend the name, append the unit (if present), and append
|
* @param verbose whether to prepend the name, append the unit (if present), and append
|
||||||
* the comment in square brackets (if present).
|
* the comment in square brackets (if present).
|
||||||
* @param filterName the optional name of a field to limit the output to.
|
|
||||||
* @param separator the separator character between multiple fields.
|
* @param separator the separator character between multiple fields.
|
||||||
* @return @a RESULT_OK on success, or an error code.
|
* @return @a RESULT_OK on success, or an error code.
|
||||||
*/
|
*/
|
||||||
result_t decode(SymbolString& masterData, SymbolString& slaveData,
|
result_t decode(SymbolString& masterData, SymbolString& slaveData,
|
||||||
ostringstream& output, bool leadingSeparator=false,
|
ostringstream& output, bool leadingSeparator=false,
|
||||||
bool verbose=false, const char* filterName=NULL,
|
bool verbose=false, char separator=UI_FIELD_SEPARATOR);
|
||||||
char separator=UI_FIELD_SEPARATOR);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the last decoded value.
|
* Get the last decoded value.
|
||||||
|
|||||||
+12
-12
@@ -66,7 +66,7 @@ result_t SymbolString::parseHex(const string& str, const bool isEscaped)
|
|||||||
for (size_t i = 0; i < str.size(); i += 2) {
|
for (size_t i = 0; i < str.size(); i += 2) {
|
||||||
char* strEnd = NULL;
|
char* strEnd = NULL;
|
||||||
const char* strBegin = str.substr(i, 2).c_str();
|
const char* strBegin = str.substr(i, 2).c_str();
|
||||||
unsigned int value = strtoul(strBegin, &strEnd, 16);
|
unsigned long int value = strtoul(strBegin, &strEnd, 16);
|
||||||
|
|
||||||
if (strEnd == NULL || *strEnd != 0 || strEnd != strBegin+2 || value > 0xff)
|
if (strEnd == NULL || *strEnd != 0 || strEnd != strBegin+2 || value > 0xff)
|
||||||
return RESULT_ERR_INVALID_NUM; // invalid value
|
return RESULT_ERR_INVALID_NUM; // invalid value
|
||||||
@@ -206,20 +206,20 @@ unsigned char getMasterNumber(unsigned char addr) {
|
|||||||
switch (addrLo)
|
switch (addrLo)
|
||||||
{
|
{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
priority = 0;
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
priority = 1;
|
priority = 1;
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x1:
|
||||||
priority = 2;
|
priority = 2;
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x3:
|
||||||
priority = 3;
|
priority = 3;
|
||||||
break;
|
break;
|
||||||
case 0xF:
|
case 0x7:
|
||||||
priority = 4;
|
priority = 4;
|
||||||
break;
|
break;
|
||||||
|
case 0xF:
|
||||||
|
priority = 5;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -227,15 +227,15 @@ unsigned char getMasterNumber(unsigned char addr) {
|
|||||||
switch (addrHi)
|
switch (addrHi)
|
||||||
{
|
{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
return 5*0 + priority + 1;
|
return (unsigned char)(5*0 + priority);
|
||||||
case 0x1:
|
case 0x1:
|
||||||
return 5*1 + priority + 2;
|
return (unsigned char)(5*1 + priority);
|
||||||
case 0x3:
|
case 0x3:
|
||||||
return 5*2 + priority + 3;
|
return (unsigned char)(5*2 + priority);
|
||||||
case 0x7:
|
case 0x7:
|
||||||
return 5*3 + priority + 4;
|
return (unsigned char)(5*3 + priority);
|
||||||
case 0xF:
|
case 0xF:
|
||||||
return 5*4 + priority + 5;
|
return (unsigned char)(5*4 + priority);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ int main()
|
|||||||
{"u,ehp,hwTankTemp,Speichertemperatur IST,,25,B509,290000,,,IGN:2,,,,,,tempsensor", "","","","M"},
|
{"u,ehp,hwTankTemp,Speichertemperatur IST,,25,B509,290000,,,IGN:2,,,,,,tempsensor", "","","","M"},
|
||||||
{"", "55.50;ok","1025b50903290000","050000780300","d"},
|
{"", "55.50;ok","1025b50903290000","050000780300","d"},
|
||||||
{"r,ehp,datetime,Datum Uhrzeit,,50,B504,00,,,dcfstate,,,,time,,BTI,,,,date,,BDA,,,,temp,,temp2", "valid;08:24:51;31.12.2014;-0.875", "1050b5040100", "0a035124083112031420ff", "md" },
|
{"r,ehp,datetime,Datum Uhrzeit,,50,B504,00,,,dcfstate,,,,time,,BTI,,,,date,,BDA,,,,temp,,temp2", "valid;08:24:51;31.12.2014;-0.875", "1050b5040100", "0a035124083112031420ff", "md" },
|
||||||
|
{"r,ehp,bad,invalid pos,,50,B5ff,000102,,m,tempsensor;tempsensor;tempsensor;tempsensor;power;power,,,", "", "", "", "c" },
|
||||||
|
{"r,ehp,bad,invalid pos,,50,B5ff,,,s,tempsensor;tempsensor;tempsensor;tempsensor;tempsensor;power;power,,,", "", "", "", "c" },
|
||||||
};
|
};
|
||||||
DataFieldTemplates* templates = new DataFieldTemplates();
|
DataFieldTemplates* templates = new DataFieldTemplates();
|
||||||
MessageMap* messages = new MessageMap();
|
MessageMap* messages = new MessageMap();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
AM_CXXFLAGS = -fpic \
|
AM_CXXFLAGS = -fpic \
|
||||||
-Wall \
|
-Wall \
|
||||||
-Wextra
|
-Wextra \
|
||||||
|
-Wconversion
|
||||||
|
|
||||||
noinst_LIBRARIES = libutils.a
|
noinst_LIBRARIES = libutils.a
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ using namespace std;
|
|||||||
TCPSocket::TCPSocket(int sfd, struct sockaddr_in* address) : m_sfd(sfd)
|
TCPSocket::TCPSocket(int sfd, struct sockaddr_in* address) : m_sfd(sfd)
|
||||||
{
|
{
|
||||||
char ip[17];
|
char ip[17];
|
||||||
inet_ntop(AF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, sizeof(ip)-1);
|
inet_ntop(AF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, (socklen_t)sizeof(ip)-1);
|
||||||
m_ip = ip;
|
m_ip = ip;
|
||||||
m_port = ntohs(address->sin_port);
|
m_port = ntohs(address->sin_port);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ using namespace std;
|
|||||||
struct options
|
struct options
|
||||||
{
|
{
|
||||||
const char* server; //!< ebusd server host (name or ip) [localhost]
|
const char* server; //!< ebusd server host (name or ip) [localhost]
|
||||||
int port; //!< ebusd server port [8888]
|
unsigned int port; //!< ebusd server port [8888]
|
||||||
|
|
||||||
char* const *args; //!< arguments to pass to ebusd
|
char* const *args; //!< arguments to pass to ebusd
|
||||||
int argCount; //!< number of arguments to pass to ebusd
|
unsigned int argCount; //!< number of arguments to pass to ebusd
|
||||||
};
|
};
|
||||||
|
|
||||||
/** the program options. */
|
/** the program options. */
|
||||||
@@ -100,7 +100,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|||||||
opt->server = arg;
|
opt->server = arg;
|
||||||
break;
|
break;
|
||||||
case 'p': // --port=8888
|
case 'p': // --port=8888
|
||||||
opt->port = strtol(arg, &strEnd, 10);
|
opt->port = (unsigned int)strtoul(arg, &strEnd, 10);
|
||||||
if (strEnd == NULL || *strEnd != 0 || opt->port < 1 || opt->port > 65535) {
|
if (strEnd == NULL || *strEnd != 0 || opt->port < 1 || opt->port > 65535) {
|
||||||
argp_error(state, "invalid port");
|
argp_error(state, "invalid port");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ using namespace std;
|
|||||||
struct options
|
struct options
|
||||||
{
|
{
|
||||||
const char* device; //!< device to write to [/dev/ttyUSB60]
|
const char* device; //!< device to write to [/dev/ttyUSB60]
|
||||||
int time; //!< delay between bytes in us [10000]
|
unsigned int time; //!< delay between bytes in us [10000]
|
||||||
|
|
||||||
const char* dumpFile; //!< dump file to read
|
const char* dumpFile; //!< dump file to read
|
||||||
};
|
};
|
||||||
@@ -67,7 +67,7 @@ static const char argpdoc[] =
|
|||||||
" 2. create symbol links to appropriate devices, e.g.\n"
|
" 2. create symbol links to appropriate devices, e.g.\n"
|
||||||
" 'ln -s /dev/pts/2 /dev/ttyUSB60'\n"
|
" 'ln -s /dev/pts/2 /dev/ttyUSB60'\n"
|
||||||
" 'ln -s /dev/pts/3 /dev/ttyUSB20'\n"
|
" 'ln -s /dev/pts/3 /dev/ttyUSB20'\n"
|
||||||
" 3. start "PACKAGE": '"PACKAGE" -f -d /dev/ttyUSB20'\n"
|
" 3. start "PACKAGE": '"PACKAGE" -f -d /dev/ttyUSB20 --nodevicecheck'\n"
|
||||||
" 4. start ebusfeed: 'ebusfeed /path/to/ebus_dump.bin'\n";
|
" 4. start ebusfeed: 'ebusfeed /path/to/ebus_dump.bin'\n";
|
||||||
|
|
||||||
/** the description of the accepted arguments. */
|
/** the description of the accepted arguments. */
|
||||||
@@ -101,7 +101,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|||||||
opt->device = arg;
|
opt->device = arg;
|
||||||
break;
|
break;
|
||||||
case 't': // --time=10000
|
case 't': // --time=10000
|
||||||
opt->time = strtol(arg, &strEnd, 10);
|
opt->time = (unsigned int)strtoul(arg, &strEnd, 10);
|
||||||
if (strEnd == NULL || *strEnd != 0 || opt->time < 1000 || opt->time > 100000000) {
|
if (strEnd == NULL || *strEnd != 0 || opt->time < 1000 || opt->time > 100000000) {
|
||||||
argp_error(state, "invalid time");
|
argp_error(state, "invalid time");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@@ -131,7 +131,7 @@ int main(int argc, char* argv[])
|
|||||||
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &opt) != 0)
|
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &opt) != 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
Device* device = Device::create(opt.device, true, NULL);
|
Device* device = Device::create(opt.device, false, NULL);
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
cout << "unable to create device " << opt.device << endl;
|
cout << "unable to create device " << opt.device << endl;
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@@ -150,7 +150,7 @@ int main(int argc, char* argv[])
|
|||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned char byte = file.get();
|
unsigned char byte = (unsigned char)file.get();
|
||||||
if (file.eof())
|
if (file.eof())
|
||||||
break;
|
break;
|
||||||
cout << hex << setw(2) << setfill('0')
|
cout << hex << setw(2) << setfill('0')
|
||||||
|
|||||||
Reference in New Issue
Block a user