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:
john30
2015-02-22 13:57:37 +01:00
parent 564a602eaf
commit d50b3b6cb2
17 changed files with 172 additions and 130 deletions
+1
View File
@@ -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)\" \
+6 -6
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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"
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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)
+5 -6
View File
@@ -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
View File
@@ -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;
} }
+2
View File
@@ -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();
+2 -1
View File
@@ -1,6 +1,7 @@
AM_CXXFLAGS = -fpic \ AM_CXXFLAGS = -fpic \
-Wall \ -Wall \
-Wextra -Wextra \
-Wconversion
noinst_LIBRARIES = libutils.a noinst_LIBRARIES = libutils.a
+1 -1
View File
@@ -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);
} }
+3 -3
View File
@@ -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;
+5 -5
View File
@@ -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')