formatting, remove unused

This commit is contained in:
john30
2022-09-17 23:57:24 +02:00
parent bb6a05190e
commit ce6ea68f22
20 changed files with 199 additions and 179 deletions
+2 -2
View File
@@ -784,7 +784,7 @@ result_t BusHandler::handleSymbol() {
// check arbitration // check arbitration
if (recvSymbol == sendSymbol) { // arbitration successful if (recvSymbol == sendSymbol) { // arbitration successful
// measure arbitration delay // measure arbitration delay
long long latencyLong = (sentTime.tv_sec*1000000000 + sentTime.tv_nsec int64_t latencyLong = (sentTime.tv_sec*1000000000 + sentTime.tv_nsec
- m_lastSynReceiveTime.tv_sec*1000000000 - m_lastSynReceiveTime.tv_nsec)/1000; - m_lastSynReceiveTime.tv_sec*1000000000 - m_lastSynReceiveTime.tv_nsec)/1000;
if (latencyLong >= 0 && latencyLong <= 10000) { // skip clock skew or out of reasonable range if (latencyLong >= 0 && latencyLong <= 10000) { // skip clock skew or out of reasonable range
auto latency = static_cast<int>(latencyLong); auto latency = static_cast<int>(latencyLong);
@@ -1113,7 +1113,7 @@ result_t BusHandler::setState(BusState state, result_t result, bool firstRepetit
} }
void BusHandler::measureLatency(struct timespec* sentTime, struct timespec* recvTime) { void BusHandler::measureLatency(struct timespec* sentTime, struct timespec* recvTime) {
long long latencyLong = (recvTime->tv_sec*1000000000 + recvTime->tv_nsec int64_t latencyLong = (recvTime->tv_sec*1000000000 + recvTime->tv_nsec
- sentTime->tv_sec*1000000000 - sentTime->tv_nsec)/1000000; - sentTime->tv_sec*1000000000 - sentTime->tv_nsec)/1000000;
if (latencyLong < 0 || latencyLong > 1000) { if (latencyLong < 0 || latencyLong > 1000) {
return; // clock skew or out of reasonable range return; // clock skew or out of reasonable range
+52 -45
View File
@@ -43,7 +43,7 @@ using std::dec;
// 5 bits magic (to be incremented with incompatible changes, not shown) // 5 bits magic (to be incremented with incompatible changes, not shown)
// 5 bits major, using major directly // 5 bits major, using major directly
// 6 bits minor, using minor multiplied by 10 to have space for micro versioning in future // 6 bits minor, using minor multiplied by 10 to have space for micro versioning in future
#define VERSION_INT ((PACKAGE_VERSION_MAJOR<<6)|(PACKAGE_VERSION_MINOR*10)) #define VERSION_INT ((PACKAGE_VERSION_MAJOR << 6) |(PACKAGE_VERSION_MINOR*10))
#define O_URL -2 #define O_URL -2
#define O_AGR (O_URL-1) #define O_AGR (O_URL-1)
@@ -59,8 +59,10 @@ static const struct argp_option g_knx_argp_options[] = {
" or \"ip:host[:port]\" / \"local:/socketpath\" for knxd" " or \"ip:host[:port]\" / \"local:/socketpath\" for knxd"
#endif #endif
") []", 0 }, ") []", 0 },
{"knxrage", O_AGR, "SEC", 0, "Maximum age in seconds for using the last value of read messages (0=disable) [5]", 0 }, {"knxrage", O_AGR, "SEC", 0, "Maximum age in seconds for using the last value of read messages (0=disable)"
{"knxwage", O_AGW, "SEC", 0, "Maximum age in seconds for using the last value for reads on write messages (0=disable), [99999999]", 0 }, " [5]", 0 },
{"knxwage", O_AGW, "SEC", 0, "Maximum age in seconds for using the last value for reads on write messages"
" (0=disable), [99999999]", 0 },
{"knxint", O_INT, "FILE", 0, "Read KNX integration settings from FILE [/etc/ebusd/knx.cfg]", 0 }, {"knxint", O_INT, "FILE", 0, "Read KNX integration settings from FILE [/etc/ebusd/knx.cfg]", 0 },
{"knxvar", O_VAR, "NAME=VALUE", 0, "Add a variable to the read KNX integration settings", 0 }, {"knxvar", O_VAR, "NAME=VALUE", 0, "Add a variable to the read KNX integration settings", 0 },
@@ -69,7 +71,8 @@ static const struct argp_option g_knx_argp_options[] = {
static const char* g_url = nullptr; //!< URL of KNX daemon static const char* g_url = nullptr; //!< URL of KNX daemon
static unsigned int g_maxReadAge = 5; //!< max age in seconds for using the last value of read messages static unsigned int g_maxReadAge = 5; //!< max age in seconds for using the last value of read messages
static unsigned int g_maxWriteAge = 99999999; //!< max age in seconds for using the last value for reads on write messages // max age in seconds for using the last value for reads on write messages
static unsigned int g_maxWriteAge = 99999999;
static const char* g_integrationFile = nullptr; //!< the integration settings file static const char* g_integrationFile = nullptr; //!< the integration settings file
static vector<string>* g_integrationVars = nullptr; //!< the integration settings variables static vector<string>* g_integrationVars = nullptr; //!< the integration settings variables
@@ -259,7 +262,7 @@ void KnxHandler::startHandler() {
void KnxHandler::notifyUpdateCheckResult(const string& checkResult) { void KnxHandler::notifyUpdateCheckResult(const string& checkResult) {
if (checkResult != m_lastUpdateCheckResult) { if (checkResult != m_lastUpdateCheckResult) {
m_lastUpdateCheckResult = checkResult; m_lastUpdateCheckResult = checkResult;
sendGlobalValue(GLOBAL_UPDATECHECK, checkResult.empty() || checkResult=="OK" ? 0 : 1); sendGlobalValue(GLOBAL_UPDATECHECK, checkResult.empty() || checkResult == "OK" ? 0 : 1);
} }
} }
@@ -269,7 +272,7 @@ void KnxHandler::notifyScanStatus(scanStatus_t scanStatus) {
} }
if (scanStatus != m_lastScanStatus) { if (scanStatus != m_lastScanStatus) {
m_lastScanStatus = scanStatus; m_lastScanStatus = scanStatus;
sendGlobalValue(GLOBAL_SCAN, m_lastScanStatus==SCAN_STATUS_RUNNING ? 1 : 0); sendGlobalValue(GLOBAL_SCAN, m_lastScanStatus == SCAN_STATUS_RUNNING ? 1 : 0);
} }
} }
@@ -288,20 +291,20 @@ result_t getFieldLength(const SingleDataField *field, dtlf_t *length) {
return RESULT_OK; return RESULT_OK;
} }
const auto nt = dynamic_cast<const NumberDataType*>(dt); const auto nt = dynamic_cast<const NumberDataType*>(dt);
if (nt->getDivisor()!=1) { if (nt->getDivisor() != 1) {
// adjust bit count to 2 octet or 4 octet float DPT // adjust bit count to 2 octet or 4 octet float DPT
if (bitCnt>=24 && bitCnt<31) { if (bitCnt >= 24 && bitCnt < 31) {
bitCnt = 32; bitCnt = 32;
} else if (bitCnt<16) { } else if (bitCnt < 16) {
bitCnt = 16; bitCnt = 16;
} }
// TODO uncommon divisor (e.g. >100) may not fit into KNX 2-octet float or truncates precision // TODO uncommon divisor (e.g. >100) may not fit into KNX 2-octet float or truncates precision
} else if (bitCnt>=24 && bitCnt<31) { } else if (bitCnt >= 24 && bitCnt < 31) {
// adjust bit count for non-existent 24 bit KNX type // adjust bit count for non-existent 24 bit KNX type
bitCnt = 32; bitCnt = 32;
} }
*length = {{ *length = {{
.hasDivisor = nt->getDivisor()!=1, .hasDivisor = nt->getDivisor() != 1,
.isFloat = dt->hasFlag(EXP), .isFloat = dt->hasFlag(EXP),
.isSigned = dt->hasFlag(SIG), .isSigned = dt->hasFlag(SIG),
.lastValueSent = false, .lastValueSent = false,
@@ -339,7 +342,7 @@ float int16ToFloat(uint16_t val) {
return 0; return 0;
} }
if (val == 0x7fff) { if (val == 0x7fff) {
return static_cast<float>(0xffffffff); // NaN return static_cast<float>(0xffffffff); // NaN
} }
bool negative = val&0x8000; bool negative = val&0x8000;
int exp = (val>>11)&0xf; int exp = (val>>11)&0xf;
@@ -347,7 +350,8 @@ float int16ToFloat(uint16_t val) {
return static_cast<float>(sig * exp2(exp) * (negative ? -0.01 : 0.01)); return static_cast<float>(sig * exp2(exp) * (negative ? -0.01 : 0.01));
} }
result_t KnxHandler::sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& lengthFlag, unsigned int value, const SingleDataField *field) const { result_t KnxHandler::sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& lengthFlag, unsigned int value,
const SingleDataField *field) const {
if (!m_con || !m_con->isConnected() || !m_con->getAddress()) { if (!m_con || !m_con->isConnected() || !m_con->getAddress()) {
return RESULT_EMPTY; return RESULT_EMPTY;
} }
@@ -365,7 +369,7 @@ result_t KnxHandler::sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& length
result_t ret = nt->getFloatFromRawValue(value, &fval); result_t ret = nt->getFloatFromRawValue(value, &fval);
if (ret == RESULT_EMPTY) { if (ret == RESULT_EMPTY) {
// replacement value: // replacement value:
if (lengthFlag.length==2) { if (lengthFlag.length == 2) {
// shall have 0x7fff for DPT 9 // shall have 0x7fff for DPT 9
value = 0x7fff; value = 0x7fff;
} else { } else {
@@ -384,7 +388,7 @@ result_t KnxHandler::sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& length
} }
} }
// else signed values: fine as long as length is identical // else signed values: fine as long as length is identical
if (apci==APCI_GROUPVALUE_WRITE && lengthFlag.lastValueSent && lengthFlag.lastValue==value) { if (apci == APCI_GROUPVALUE_WRITE && lengthFlag.lastValueSent && lengthFlag.lastValue == value) {
return RESULT_EMPTY; // no need to send the same group value again return RESULT_EMPTY; // no need to send the same group value again
} }
lengthFlag.lastValue = value; lengthFlag.lastValue = value;
@@ -413,12 +417,12 @@ result_t KnxHandler::sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& length
const char* err = m_con->sendGroup(dest, len, data); const char* err = m_con->sendGroup(dest, len, data);
if (err) { if (err) {
logOtherError("knx", "unable to send %s, dest %4.4x, len %d", logOtherError("knx", "unable to send %s, dest %4.4x, len %d",
apci==APCI_GROUPVALUE_WRITE ? "write" : apci==APCI_GROUPVALUE_READ ? "read" : "response", apci == APCI_GROUPVALUE_WRITE ? "write" : apci == APCI_GROUPVALUE_READ ? "read" : "response",
dest, len); dest, len);
return RESULT_ERR_SEND; return RESULT_ERR_SEND;
} }
logOtherDebug("knx", "sent %s, dest %4.4x, len %d", logOtherDebug("knx", "sent %s, dest %4.4x, len %d",
apci==APCI_GROUPVALUE_WRITE ? "write" : apci==APCI_GROUPVALUE_READ ? "read" : "response", apci == APCI_GROUPVALUE_WRITE ? "write" : apci == APCI_GROUPVALUE_READ ? "read" : "response",
dest, len); dest, len);
return RESULT_OK; return RESULT_OK;
} }
@@ -503,24 +507,25 @@ void printResponse(knx_addr_t src, knx_addr_t dest, int len, const uint8_t *data
if ((apci & APCI_GROUPVALUE_READ_MASK) == 0) { if ((apci & APCI_GROUPVALUE_READ_MASK) == 0) {
apci &= ~APCI_GROUPVALUE_READ_MASK; apci &= ~APCI_GROUPVALUE_READ_MASK;
} }
int value = len==2 ? data[1]&0x3f : data[2]; // 6 bits or full octet int value = len == 2 ? data[1]&0x3f : data[2]; // 6 bits or full octet
if (len>3) { if (len>3) {
value = (value<<8) | data[3]; // up to 16 bits value = (value<<8) | data[3]; // up to 16 bits
} }
if (len>4) { if (len>4) {
value = (value<<8) | data[4]; // up to 24 bits value = (value<<8) | data[4]; // up to 24 bits
} }
if (len>5) { if (len>5) {
value = (value<<8) | data[5]; // up to 32 bits value = (value<<8) | data[5]; // up to 32 bits
} }
logOtherDebug("knx", "recv from %4.4x to %4.4x, %s (0x%3.3x, tctrl 0x%2.2x), len %d", src, dest, logOtherDebug("knx", "recv from %4.4x to %4.4x, %s (0x%3.3x, tctrl 0x%2.2x), len %d", src, dest,
apci==APCI_GROUPVALUE_WRITE ? "write" : apci==APCI_GROUPVALUE_READ ? "read" apci == APCI_GROUPVALUE_WRITE ? "write" : apci == APCI_GROUPVALUE_READ ? "read"
: apci==APCI_GROUPVALUE_RESPONSE ? "response" : "other", : apci == APCI_GROUPVALUE_RESPONSE ? "response" : "other",
apci, tctrl, len); apci, tctrl, len);
} }
*/ */
void KnxHandler::handleReceivedTelegram(knx_transfer_t typ, knx_addr_t src, knx_addr_t dest, int len, const uint8_t *data) { void KnxHandler::handleReceivedTelegram(knx_transfer_t typ, knx_addr_t src, knx_addr_t dest, int len,
const uint8_t *data) {
if (typ == KNX_TRANSFER_GROUP) { if (typ == KNX_TRANSFER_GROUP) {
handleGroupTelegram(src, dest, len, data); handleGroupTelegram(src, dest, len, data);
return; return;
@@ -542,7 +547,8 @@ void KnxHandler::sendNonGroupDisconnect(knx_addr_t dest) {
// the connection timeout in millis (6 seconds) // the connection timeout in millis (6 seconds)
#define CONNECTION_TIMEOUT 6000 #define CONNECTION_TIMEOUT 6000
void KnxHandler::handleNonGroupTelegram(knx_transfer_t typ, knx_addr_t src, knx_addr_t dest, int len, const uint8_t *data) { void KnxHandler::handleNonGroupTelegram(knx_transfer_t typ, knx_addr_t src, knx_addr_t dest, int len,
const uint8_t *data) {
if (typ == KNX_TRANSFER_NONE) { if (typ == KNX_TRANSFER_NONE) {
return; return;
} }
@@ -552,24 +558,24 @@ void KnxHandler::handleNonGroupTelegram(knx_transfer_t typ, knx_addr_t src, knx_
void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, const uint8_t *data) { void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, const uint8_t *data) {
time_t now; time_t now;
time(&now); time(&now);
int apci = ((data[0]&0x03)<<8) | data[1]; int apci = ((data[0]&0x03) << 8) | data[1];
int groupReadWriteApci = apci & APCI_GROUPVALUE_READ_WRITE_MASK; int groupReadWriteApci = apci & APCI_GROUPVALUE_READ_WRITE_MASK;
if (groupReadWriteApci == APCI_GROUPVALUE_WRITE || groupReadWriteApci == APCI_GROUPVALUE_READ) { if (groupReadWriteApci == APCI_GROUPVALUE_WRITE || groupReadWriteApci == APCI_GROUPVALUE_READ) {
apci = groupReadWriteApci; apci = groupReadWriteApci;
} }
bool isWrite = apci==APCI_GROUPVALUE_WRITE; bool isWrite = apci == APCI_GROUPVALUE_WRITE;
if (apci!=APCI_GROUPVALUE_READ && !isWrite) { if (apci != APCI_GROUPVALUE_READ && !isWrite) {
if (m_con->isProgrammingMode()) { if (m_con->isProgrammingMode()) {
if (apci == APCI_INDIVIDUALADDRESS_READ && m_lastIndividualAddressResponseTime<now-3) { // timeout 3 seconds if (apci == APCI_INDIVIDUALADDRESS_READ && m_lastIndividualAddressResponseTime < now-3) { // timeout 3 seconds
uint8_t buf[] = {APCI_INDIVIDUALADDRESS_RESPONSE>>8, APCI_INDIVIDUALADDRESS_RESPONSE&0xff}; uint8_t buf[] = {APCI_INDIVIDUALADDRESS_RESPONSE >> 8, APCI_INDIVIDUALADDRESS_RESPONSE&0xff};
logOtherNotice("knx", "answering to A_IndividualAddress_Read"); logOtherNotice("knx", "answering to A_IndividualAddress_Read");
if (m_con->sendGroup(0, 2, buf)) { if (m_con->sendGroup(0, 2, buf)) {
logOtherDebug("knx", "cannot send"); logOtherDebug("knx", "cannot send");
} else { } else {
m_lastIndividualAddressResponseTime = now; m_lastIndividualAddressResponseTime = now;
} }
} else if (apci==APCI_INDIVIDUALADDRESS_WRITE && len==4 && !m_con->getAddress() && (data[2]|data[3])) { } else if (apci == APCI_INDIVIDUALADDRESS_WRITE && len == 4 && !m_con->getAddress() && (data[2]|data[3])) {
m_con->setAddress((data[2]<<8)|data[3]); m_con->setAddress(static_cast<knx_addr_t>((data[2] << 8)|data[3]));
m_lastIndividualAddressResponseTime = 0; m_lastIndividualAddressResponseTime = 0;
logOtherNotice("knx", "received new address %x", m_con->getAddress()); logOtherNotice("knx", "received new address %x", m_con->getAddress());
} }
@@ -581,7 +587,7 @@ void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, c
if (needsLog(lf_other, ll_debug)) { if (needsLog(lf_other, ll_debug)) {
logOtherDebug("knx", "received %ssubscribed %s from %4.4x to %4.4x, len %d", logOtherDebug("knx", "received %ssubscribed %s from %4.4x to %4.4x, len %d",
sit == m_subscribedGroups.end() ? "un" : "", sit == m_subscribedGroups.end() ? "un" : "",
apci==APCI_GROUPVALUE_WRITE ? "write" : apci==APCI_GROUPVALUE_READ ? "read" : "response", apci == APCI_GROUPVALUE_WRITE ? "write" : apci == APCI_GROUPVALUE_READ ? "read" : "response",
src, dest, len); src, dest, len);
} }
if (sit == m_subscribedGroups.end()) { if (sit == m_subscribedGroups.end()) {
@@ -603,10 +609,11 @@ void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, c
sendGlobalValue(GLOBAL_SIGNAL, m_busHandler->hasSignal() ? 1 : 0, true); sendGlobalValue(GLOBAL_SIGNAL, m_busHandler->hasSignal() ? 1 : 0, true);
break; break;
case GLOBAL_SCAN: case GLOBAL_SCAN:
sendGlobalValue(GLOBAL_SCAN, m_lastScanStatus==SCAN_STATUS_RUNNING ? 1 : 0, true); sendGlobalValue(GLOBAL_SCAN, m_lastScanStatus == SCAN_STATUS_RUNNING ? 1 : 0, true);
break; break;
case GLOBAL_UPDATECHECK: case GLOBAL_UPDATECHECK:
sendGlobalValue(GLOBAL_UPDATECHECK, m_lastUpdateCheckResult.empty() || m_lastUpdateCheckResult=="OK" || m_lastUpdateCheckResult=="." ? 0 : 1, true); sendGlobalValue(GLOBAL_UPDATECHECK, m_lastUpdateCheckResult.empty() || m_lastUpdateCheckResult == "OK"
|| m_lastUpdateCheckResult == "." ? 0 : 1, true);
break; break;
default: default:
return; // ignore return; // ignore
@@ -655,15 +662,15 @@ void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, c
result_t res; result_t res;
const string circuit = msg->getCircuit(), name = msg->getName(), fieldName = msg->getFieldName(fieldIndex); const string circuit = msg->getCircuit(), name = msg->getName(), fieldName = msg->getFieldName(fieldIndex);
if (isWrite) { if (isWrite) {
unsigned int value = len==2 ? data[1]&0x3f : data[2]; // <=6 bits or full octet unsigned int value = len == 2 ? data[1]&0x3f : data[2]; // <=6 bits or full octet
if (len>3) { if (len > 3) {
value = (value<<8) | data[3]; // up to 16 bits value = (value << 8) | data[3]; // up to 16 bits
} }
if (len>4) { if (len > 4) {
value = (value<<8) | data[4]; // up to 24 bits value = (value << 8) | data[4]; // up to 24 bits
} }
if (len>5) { if (len > 5) {
value = (value<<8) | data[5]; // up to 32 bits value = (value << 8) | data[5]; // up to 32 bits
} }
// note: a write from KNX updates the message and thus re-sends the write later on again during update check // note: a write from KNX updates the message and thus re-sends the write later on again during update check
logOtherNotice("knx", "received write request from %4.4x to %4.4x for %s/%s/%s, value %d", logOtherNotice("knx", "received write request from %4.4x to %4.4x for %s/%s/%s, value %d",
@@ -691,7 +698,7 @@ void KnxHandler::handleGroupTelegram(knx_addr_t src, knx_addr_t dest, int len, c
} else { } else {
if (lengthFlag.isSigned) { if (lengthFlag.isSigned) {
// signed values: determine sign // signed values: determine sign
uint32_t bit = 1<<(lengthFlag.length*8-1); uint32_t bit = 1 << (lengthFlag.length*8-1);
if (value & bit) { if (value & bit) {
value = -(value&~bit); value = -(value&~bit);
} }
@@ -801,7 +808,7 @@ void KnxHandler::run() {
continue; continue;
} }
ssize_t fieldCount = static_cast<signed>(message->getFieldCount()); ssize_t fieldCount = static_cast<signed>(message->getFieldCount());
if (isWrite && fieldCount>1) { if (isWrite && fieldCount > 1) {
// impossible with more than one field // impossible with more than one field
continue; continue;
} }
@@ -878,7 +885,7 @@ void KnxHandler::run() {
} }
} }
} }
if (addCnt>0) { if (addCnt > 0) {
logOtherInfo("knx", "added %d associations, %d active now", addCnt, m_subscribedGroups.size()); logOtherInfo("knx", "added %d associations, %d active now", addCnt, m_subscribedGroups.size());
} }
definitionsSince = now; definitionsSince = now;
+8 -6
View File
@@ -88,7 +88,7 @@ typedef union {
bool isFloat: 1; bool isFloat: 1;
bool isSigned: 1; bool isSigned: 1;
bool lastValueSent: 1; bool lastValueSent: 1;
uint8_t length; // 0 for 1-6 bits, number of bytes otherwise uint8_t length; // 0 for 1-6 bits, number of bytes otherwise
uint32_t lastValue; uint32_t lastValue;
}; };
uint64_t value; uint64_t value;
@@ -155,7 +155,8 @@ class KnxHandler : public DataSink, public DataSource, public WaitThread {
* @param field the message field or nullptr for non field related. * @param field the message field or nullptr for non field related.
* @return the result code. * @return the result code.
*/ */
result_t sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& lengthFlag, unsigned int value, const SingleDataField *field = nullptr) const; result_t sendGroupValue(knx_addr_t dest, apci_t apci, dtlf_t& lengthFlag, unsigned int value,
const SingleDataField *field = nullptr) const;
/** /**
* Send a global value to the registered group address. * Send a global value to the registered group address.
@@ -175,7 +176,8 @@ class KnxHandler : public DataSink, public DataSource, public WaitThread {
* @return the result code, either RESULT_OK on success, RESULT_ERR_GENERIC_IO on I/O error (e.g. socket closed), * @return the result code, either RESULT_OK on success, RESULT_ERR_GENERIC_IO on I/O error (e.g. socket closed),
* or RESULT_ERR_TIMEOUT if no data is available. * or RESULT_ERR_TIMEOUT if no data is available.
*/ */
result_t receiveTelegram(int maxlen, knx_transfer_t* typ, uint8_t *buf, int *recvlen, knx_addr_t *src, knx_addr_t *dest); result_t receiveTelegram(int maxlen, knx_transfer_t* typ, uint8_t *buf, int *recvlen, knx_addr_t *src,
knx_addr_t *dest);
/** /**
* Handle a received KNX telegram. * Handle a received KNX telegram.
@@ -237,7 +239,7 @@ class KnxHandler : public DataSink, public DataSource, public WaitThread {
map<uint32_t, groupInfo_t>m_subscribedGroups; map<uint32_t, groupInfo_t>m_subscribedGroups;
/** the group address and flags (key of m_subscribedGroups) by subscribed message key. */ /** the group address and flags (key of m_subscribedGroups) by subscribed message key. */
map<uint64_t, list<uint32_t>>m_subscribedMessages; map<uint64_t, list<uint32_t> >m_subscribedMessages;
/** the group address and flags (key of m_subscribedGroups) by subscribed global values. */ /** the group address and flags (key of m_subscribedGroups) by subscribed global values. */
map<global_t, uint32_t>m_subscribedGlobals; map<global_t, uint32_t>m_subscribedGlobals;
@@ -252,7 +254,7 @@ class KnxHandler : public DataSink, public DataSource, public WaitThread {
time_t m_lastIndividualAddressResponseTime = 0; time_t m_lastIndividualAddressResponseTime = 0;
/** the time of the last connection, or 0 if not connected. */ /** the time of the last connection, or 0 if not connected. */
long long m_lastConnectTime = 0; uint64_t m_lastConnectTime = 0;
/** the source address of the last connection, or 0. */ /** the source address of the last connection, or 0. */
knx_addr_t m_lastConnectSource = 0; knx_addr_t m_lastConnectSource = 0;
@@ -276,7 +278,7 @@ class KnxHandler : public DataSink, public DataSource, public WaitThread {
bool m_scanFinishReceived; bool m_scanFinishReceived;
/** the last system time when a communication error was logged. */ /** the last system time when a communication error was logged. */
long long m_lastErrorLogTime; time_t m_lastErrorLogTime;
}; };
} // namespace ebusd } // namespace ebusd
+4 -2
View File
@@ -222,7 +222,8 @@ static const struct argp_option argpoptions[] = {
{"inject", 'i', "stop", OPTION_ARG_OPTIONAL, "Inject remaining arguments as already seen messages (e.g. " {"inject", 'i', "stop", OPTION_ARG_OPTIONAL, "Inject remaining arguments as already seen messages (e.g. "
"\"FF08070400/0AB5454850303003277201\"), optionally stop afterwards", 0 }, "\"FF08070400/0AB5454850303003277201\"), optionally stop afterwards", 0 },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{"cafile", O_CAFILE, "FILE", 0, "Use CA FILE for checking certificates (uses defaults, \"#\" for insecure)", 0 }, {"cafile", O_CAFILE, "FILE", 0, "Use CA FILE for checking certificates (uses defaults,"
" \"#\" for insecure)", 0 },
{"capath", O_CAPATH, "PATH", 0, "Use CA PATH for checking certificates (uses defaults)", 0 }, {"capath", O_CAPATH, "PATH", 0, "Use CA PATH for checking certificates (uses defaults)", 0 },
#endif // HAVE_SSL #endif // HAVE_SSL
@@ -1371,7 +1372,8 @@ int main(int argc, char* argv[]) {
} }
size_t pos = s_configPath.find(PREVIOUS_CONFIG_PATH_SUFFIX); size_t pos = s_configPath.find(PREVIOUS_CONFIG_PATH_SUFFIX);
if (pos != string::npos) { if (pos != string::npos) {
string newPath = s_configPath.substr(0, pos) + CONFIG_PATH_SUFFIX + s_configPath.substr(pos+strlen(PREVIOUS_CONFIG_PATH_SUFFIX)); string newPath = s_configPath.substr(0, pos) + CONFIG_PATH_SUFFIX
+ s_configPath.substr(pos+strlen(PREVIOUS_CONFIG_PATH_SUFFIX));
logNotice(lf_main, "replaced old configPath %s with new one: %s", s_configPath.c_str(), newPath.c_str()); logNotice(lf_main, "replaced old configPath %s with new one: %s", s_configPath.c_str(), newPath.c_str());
s_configPath = newPath; s_configPath = newPath;
} }
+5 -3
View File
@@ -374,7 +374,8 @@ bool mqtthandler_register(UserInfo* userInfo, BusHandler* busHandler, MessageMap
int revision = -1; int revision = -1;
mosquitto_lib_version(&major, &minor, &revision); mosquitto_lib_version(&major, &minor, &revision);
if (major < LIBMOSQUITTO_MAJOR) { if (major < LIBMOSQUITTO_MAJOR) {
logOtherError("mqtt", "invalid mosquitto version %d instead of %d, will try connecting anyway", major, LIBMOSQUITTO_MAJOR); logOtherError("mqtt", "invalid mosquitto version %d instead of %d, will try connecting anyway", major,
LIBMOSQUITTO_MAJOR);
} }
logOtherInfo("mqtt", "mosquitto version %d.%d.%d (compiled with %d.%d.%d)", major, minor, revision, logOtherInfo("mqtt", "mosquitto version %d.%d.%d (compiled with %d.%d.%d)", major, minor, revision,
LIBMOSQUITTO_MAJOR, LIBMOSQUITTO_MINOR, LIBMOSQUITTO_REVISION); LIBMOSQUITTO_MAJOR, LIBMOSQUITTO_MINOR, LIBMOSQUITTO_REVISION);
@@ -482,7 +483,8 @@ string removeTrailingNonTopicPart(const string& str) {
MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap* messages) MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap* messages)
: DataSink(userInfo, "mqtt"), DataSource(busHandler), WaitThread(), m_messages(messages), m_connected(false), : DataSink(userInfo, "mqtt"), DataSource(busHandler), WaitThread(), m_messages(messages), m_connected(false),
m_initialConnectFailed(false), m_lastUpdateCheckResult("."), m_lastScanStatus(SCAN_STATUS_NONE), m_lastErrorLogTime(0) { m_initialConnectFailed(false), m_lastUpdateCheckResult("."), m_lastScanStatus(SCAN_STATUS_NONE),
m_lastErrorLogTime(0) {
m_definitionsSince = 0; m_definitionsSince = 0;
m_mosquitto = nullptr; m_mosquitto = nullptr;
bool hasIntegration = false; bool hasIntegration = false;
@@ -540,7 +542,7 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
m_replacers.set("version", PACKAGE_VERSION); m_replacers.set("version", PACKAGE_VERSION);
if (m_replacers["prefix"].empty()) { if (m_replacers["prefix"].empty()) {
string line = m_replacers.get("topic", true); string line = m_replacers.get("topic", true);
if (line.empty() || line=="/") { if (line.empty() || line == "/") {
line = string(PACKAGE); // ensure prefix if cmdline topic is absent line = string(PACKAGE); // ensure prefix if cmdline topic is absent
} }
m_replacers.set("prefix", line); m_replacers.set("prefix", line);
+4 -2
View File
@@ -20,9 +20,10 @@
#define EBUSD_MQTTHANDLER_H_ #define EBUSD_MQTTHANDLER_H_
#include <mosquitto.h> #include <mosquitto.h>
#include <list>
#include <map> #include <map>
#include <string> #include <string>
#include <list> #include <utility>
#include <vector> #include <vector>
#include "ebusd/datahandler.h" #include "ebusd/datahandler.h"
#include "ebusd/bushandler.h" #include "ebusd/bushandler.h"
@@ -36,6 +37,7 @@ namespace ebusd {
*/ */
using std::map; using std::map;
using std::pair;
using std::string; using std::string;
using std::vector; using std::vector;
@@ -185,7 +187,7 @@ class MqttHandler : public DataSink, public DataSource, public WaitThread {
bool m_hasDefinitionFieldsPayload; bool m_hasDefinitionFieldsPayload;
/** map of type name to a list of pairs of wildcard string and mapped value. */ /** map of type name to a list of pairs of wildcard string and mapped value. */
map<string, vector<std::pair<string, string>>> m_typeSwitches; map<string, vector<pair<string, string>>> m_typeSwitches;
/** the subscribed configuration restart topic, or empty. */ /** the subscribed configuration restart topic, or empty. */
string m_subscribeConfigRestartTopic; string m_subscribeConfigRestartTopic;
+1 -1
View File
@@ -1011,7 +1011,7 @@ result_t NumberDataType::getRawValueFromFloat(float val, unsigned int* output) c
} else { } else {
if (m_divisor == 1) { if (m_divisor == 1) {
if (hasFlag(SIG)) { if (hasFlag(SIG)) {
long signedValue = static_cast<long>(val); // TODO static_c? long signedValue = static_cast<long>(val); // TODO static_c?
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 {
+9 -8
View File
@@ -465,7 +465,8 @@ bool Device::available() {
ch = m_buffer[(pos+m_bufPos+1)%m_bufSize]; ch = m_buffer[(pos+m_bufPos+1)%m_bufSize];
if (!(ch&ENH_BYTE_FLAG) || (ch&ENH_BYTE_MASK) != ENH_BYTE2) { if (!(ch&ENH_BYTE_FLAG) || (ch&ENH_BYTE_MASK) != ENH_BYTE2) {
#ifdef DEBUG_RAW_TRAFFIC #ifdef DEBUG_RAW_TRAFFIC
fprintf(stdout, "raw avail enhanced following bad @%d+%d %2.2x %2.2x\n", m_bufPos, pos, m_buffer[(pos+m_bufPos)%m_bufSize], ch); fprintf(stdout, "raw avail enhanced following bad @%d+%d %2.2x %2.2x\n", m_bufPos, pos,
m_buffer[(pos+m_bufPos)%m_bufSize], ch);
fflush(stdout); fflush(stdout);
#endif #endif
if (m_listener != nullptr) { if (m_listener != nullptr) {
@@ -654,17 +655,17 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
ostringstream stream; ostringstream stream;
switch ((m_infoLen << 8) | m_infoId) { switch ((m_infoLen << 8) | m_infoId) {
case 0x0200: case 0x0200:
case 0x0500: // with firmware version and jumper info case 0x0500: // with firmware version and jumper info
case 0x0800: // with firmware version, jumper info, and bootloader version case 0x0800: // with firmware version, jumper info, and bootloader version
stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." // version minor stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." // version minor
<< std::hex << static_cast<unsigned>(m_infoBuf[1]); // features mask << std::hex << static_cast<unsigned>(m_infoBuf[1]); // features mask
if (m_infoLen>=5) { if (m_infoLen >= 5) {
stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[2]) stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[2])
<< std::setw(2) << static_cast<unsigned>(m_infoBuf[3]) << "]"; << std::setw(2) << static_cast<unsigned>(m_infoBuf[3]) << "]";
stream << ", jumpers 0x" << std::setw(2) << static_cast<unsigned>(m_infoBuf[4]); stream << ", jumpers 0x" << std::setw(2) << static_cast<unsigned>(m_infoBuf[4]);
stream << std::setfill(' '); // reset stream << std::setfill(' '); // reset
} }
if (m_infoLen>=8) { if (m_infoLen >= 8) {
stream << ", bootloader " << std::dec << static_cast<unsigned>(m_infoBuf[5]); stream << ", bootloader " << std::dec << static_cast<unsigned>(m_infoBuf[5]);
stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[6]) stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[6])
<< std::setw(2) << static_cast<unsigned>(m_infoBuf[7]) << "]"; << std::setw(2) << static_cast<unsigned>(m_infoBuf[7]) << "]";
@@ -677,7 +678,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
for (uint8_t pos = 0; pos < m_infoPos; pos++) { for (uint8_t pos = 0; pos < m_infoPos; pos++) {
stream << " " << std::setw(2) << static_cast<unsigned>(m_infoBuf[pos]); stream << " " << std::setw(2) << static_cast<unsigned>(m_infoBuf[pos]);
} }
if (m_infoId == 2 && (m_infoBuf[2]&0x3f)!=0x3f) { if (m_infoId == 2 && (m_infoBuf[2]&0x3f) != 0x3f) {
// non-default arbitration delay // non-default arbitration delay
val = (m_infoBuf[2]&0x3f)*10; // steps of 10us val = (m_infoBuf[2]&0x3f)*10; // steps of 10us
stream << ", arbitration delay " << std::dec << static_cast<unsigned>(val) << " us"; stream << ", arbitration delay " << std::dec << static_cast<unsigned>(val) << " us";
+2 -1
View File
@@ -352,7 +352,8 @@ class SerialDevice : public Device {
*/ */
SerialDevice(const char* name, bool checkDevice, unsigned int extraLatency, bool readOnly, bool initialSend, SerialDevice(const char* name, bool checkDevice, unsigned int extraLatency, bool readOnly, bool initialSend,
bool enhancedProto = false, bool enhancedHighSpeed = false) bool enhancedProto = false, bool enhancedHighSpeed = false)
: Device(name, checkDevice, extraLatency, readOnly, initialSend, enhancedProto), m_enhancedHighSpeed(enhancedHighSpeed) { : Device(name, checkDevice, extraLatency, readOnly, initialSend, enhancedProto),
m_enhancedHighSpeed(enhancedHighSpeed) {
} }
// @copydoc // @copydoc
+5 -2
View File
@@ -22,6 +22,7 @@
#include "lib/ebus/stringhelper.h" #include "lib/ebus/stringhelper.h"
#include <algorithm> #include <algorithm>
#include <stack>
namespace ebusd { namespace ebusd {
@@ -296,7 +297,8 @@ bool StringReplacer::checkMatchability() const {
return true; return true;
} }
ssize_t StringReplacer::match(const string& str, string* circuit, string* name, string* field, const string& separator) const { ssize_t StringReplacer::match(const string& str, string* circuit, string* name, string* field,
const string& separator) const {
size_t last = 0; size_t last = 0;
size_t count = m_parts.size(); size_t count = m_parts.size();
size_t idx; size_t idx;
@@ -442,7 +444,8 @@ StringReplacer StringReplacers::get(const string& key) const {
return StringReplacer(); return StringReplacer();
} }
string StringReplacers::get(const string& key, bool untilFirstEmpty, bool onlyAlphanum, const string& fallbackKey) const { string StringReplacers::get(const string& key, bool untilFirstEmpty, bool onlyAlphanum,
const string& fallbackKey) const {
auto itc = m_constants.find(key); auto itc = m_constants.find(key);
if (itc != m_constants.end()) { if (itc != m_constants.end()) {
return itc->second; return itc->second;
+3 -2
View File
@@ -24,6 +24,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <utility>
#include <vector> #include <vector>
#include "lib/ebus/message.h" #include "lib/ebus/message.h"
@@ -34,6 +35,7 @@ namespace ebusd {
*/ */
using std::map; using std::map;
using std::pair;
using std::ostringstream; using std::ostringstream;
using std::string; using std::string;
using std::vector; using std::vector;
@@ -172,7 +174,7 @@ class StringReplacer {
* @param isField true when it is a field. * @param isField true when it is a field.
* @return the created pair. * @return the created pair.
*/ */
static std::pair<string, int> makeField(const string& name, bool isField); static pair<string, int> makeField(const string& name, bool isField);
/** /**
* Add a part to the list of parts. * Add a part to the list of parts.
@@ -180,7 +182,6 @@ class StringReplacer {
* @param inField 1 after '%', 2 after '%{', 0 otherwise. * @param inField 1 after '%', 2 after '%{', 0 otherwise.
*/ */
void addPart(ostringstream& stack, int inField); void addPart(ostringstream& stack, int inField);
}; };
+2 -2
View File
@@ -20,6 +20,8 @@
# include <config.h> # include <config.h>
#endif #endif
#include <string.h>
#include "lib/knx/knx.h" #include "lib/knx/knx.h"
#ifdef HAVE_KNXD #ifdef HAVE_KNXD
@@ -27,8 +29,6 @@
#endif #endif
#include "lib/knx/knxnet.h" #include "lib/knx/knxnet.h"
#include <string.h>
namespace ebusd { namespace ebusd {
unsigned int parseInt(const char* str, int base, unsigned int minValue, unsigned int maxValue, unsigned int parseInt(const char* str, int base, unsigned int minValue, unsigned int maxValue,
+4 -3
View File
@@ -150,12 +150,12 @@ class KnxConnection {
/** /**
* @return true if connection allows programming via ETS. * @return true if connection allows programming via ETS.
*/ */
virtual bool isProgrammable() const { return false; }; virtual bool isProgrammable() const { return false; }
/** /**
* @return the individual address, or 0 if not programmed yet, or any non-zero value if not programmable. * @return the individual address, or 0 if not programmed yet, or any non-zero value if not programmable.
*/ */
virtual knx_addr_t getAddress() { return DEFAULT_ADDRESS; }; virtual knx_addr_t getAddress() const { return DEFAULT_ADDRESS; }
/** /**
* @param address the individual address to set. * @param address the individual address to set.
@@ -168,7 +168,7 @@ class KnxConnection {
* Get the programming mode. * Get the programming mode.
* @return true when in programming mode, false if not. * @return true when in programming mode, false if not.
*/ */
virtual bool isProgrammingMode() { virtual bool isProgrammingMode() const {
return false; return false;
} }
@@ -184,3 +184,4 @@ class KnxConnection {
} // namespace ebusd } // namespace ebusd
#endif // LIB_KNX_KNX_H_ #endif // LIB_KNX_KNX_H_
+1 -1
View File
@@ -34,7 +34,7 @@ class KnxdConnection : public KnxConnection {
/** /**
* Construct a new instance. * Construct a new instance.
*/ */
KnxdConnection(const char *url) explicit KnxdConnection(const char *url)
: KnxConnection(), m_url(url), m_con(nullptr) {} : KnxConnection(), m_url(url), m_con(nullptr) {}
/** /**
+73 -70
View File
@@ -19,7 +19,6 @@
#ifndef LIB_KNX_KNXNET_H_ #ifndef LIB_KNX_KNXNET_H_
#define LIB_KNX_KNXNET_H_ #define LIB_KNX_KNXNET_H_
#include <string>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -33,6 +32,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <endian.h> #include <endian.h>
#include <string>
#include <cstdio> #include <cstdio>
#include "lib/knx/knx.h" #include "lib/knx/knx.h"
@@ -62,10 +62,10 @@ typedef union __attribute__ ((packed)) {
// KNXnet/IP header // KNXnet/IP header
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t headerLength; // =6 uint8_t headerLength; // =6
uint8_t protocolVersion; // =0x10 uint8_t protocolVersion; // =0x10
uint16be_t serviceTypeIdentifier; uint16be_t serviceTypeIdentifier;
uint16be_t totalLength; // complete length including header uint16be_t totalLength; // complete length including header
} knxnet_header_t; } knxnet_header_t;
/** service types. */ /** service types. */
@@ -92,7 +92,8 @@ typedef enum {
// cEMI frame header (external message interface) // cEMI frame header (external message interface)
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t messageCode; uint8_t messageCode;
uint8_t additionalInfoLength; // optional immediately following additional bytes, usually =0. fixed to 0 in cEMI management messages // optional immediately following additional bytes, usually =0. fixed to 0 in cEMI management messages
uint8_t additionalInfoLength;
} knxnet_cemi_header_t; } knxnet_cemi_header_t;
/* cEMI message codes. */ /* cEMI message codes. */
@@ -128,21 +129,21 @@ typedef struct __attribute__ ((packed)) {
uint8_t raw; uint8_t raw;
struct { struct {
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
bool frameType: 1; // 0=extended, 1=standard bool frameType: 1; // 0=extended, 1=standard
bool reserved: 1; bool reserved: 1;
bool repeat: 1; // 0=repeat, 1=do not repeat bool repeat: 1; // 0=repeat, 1=do not repeat
bool systemBroadcast: 1; // 0=system broadcast, 1=broadcast bool systemBroadcast: 1; // 0=system broadcast, 1=broadcast
uint8_t priority: 2; // 0=system, 1=normal, 2=urgent, 3=low uint8_t priority: 2; // 0=system, 1=normal, 2=urgent, 3=low
bool acknowledgeRequest: 1; // 1=ack requested bool acknowledgeRequest: 1; // 1=ack requested
bool confirm: 1; // 0=no error, 1=error bool confirm: 1; // 0=no error, 1=error
#else #else
bool confirm: 1; // 0=no error, 1=error bool confirm: 1; // 0=no error, 1=error
bool acknowledgeRequest: 1; // 1=ack requested bool acknowledgeRequest: 1; // 1=ack requested
uint8_t priority: 2; // 0=system, 1=normal, 2=urgent, 3=low uint8_t priority: 2; // 0=system, 1=normal, 2=urgent, 3=low
bool systemBroadcast: 1; // 0=system broadcast, 1=broadcast bool systemBroadcast: 1; // 0=system broadcast, 1=broadcast
bool repeat: 1; // 0=repeat, 1=do not repeat bool repeat: 1; // 0=repeat, 1=do not repeat
bool reserved: 1; bool reserved: 1;
bool frameType: 1; // 0=extended, 1=standard bool frameType: 1; // 0=extended, 1=standard
#endif #endif
}; };
} controlField1; } controlField1;
@@ -150,19 +151,19 @@ typedef struct __attribute__ ((packed)) {
uint8_t raw; uint8_t raw;
struct { struct {
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
bool addressType: 1; // 0=individual, 1=group bool addressType: 1; // 0=individual, 1=group
uint8_t hopCount: 3; uint8_t hopCount: 3;
uint8_t extendedFrameFormat: 4; // 0=standard frame, 0xf=escape uint8_t extendedFrameFormat: 4; // 0=standard frame, 0xf=escape
#else #else
uint8_t extendedFrameFormat: 4; // 0=standard frame, 0xf=escape uint8_t extendedFrameFormat: 4; // 0=standard frame, 0xf=escape
uint8_t hopCount: 3; uint8_t hopCount: 3;
bool addressType: 1; // 0=individual, 1=group bool addressType: 1; // 0=individual, 1=group
#endif #endif
}; };
} controlField2; } controlField2;
uint16be_t sourceAddress; uint16be_t sourceAddress;
uint16be_t destinationAddress; uint16be_t destinationAddress;
uint8_t informationLength; // number of NPDU octets (not including the TPCI/APCI octet) uint8_t informationLength; // number of NPDU octets (not including the TPCI/APCI octet)
} knxnet_l_data_header_t; } knxnet_l_data_header_t;
@@ -170,22 +171,22 @@ typedef union __attribute__ ((packed)) {
uint8_t raw; uint8_t raw;
struct { struct {
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
bool controlFlag: 1; // 0=data, 1=control bool controlFlag: 1; // 0=data, 1=control
bool numbered: 1; // 1=has sequence, 0=no sequence bool numbered: 1; // 1=has sequence, 0=no sequence
uint8_t sequence: 4; // optional sequence number uint8_t sequence: 4; // optional sequence number
uint8_t apci: 2; // highest 2 bits of APCI uint8_t apci: 2; // highest 2 bits of APCI
#else #else
uint8_t apci: 2; // highest 2 bits of APCI uint8_t apci: 2; // highest 2 bits of APCI
uint8_t sequence: 4; // optional sequence number uint8_t sequence: 4; // optional sequence number
bool numbered: 1; // 1=has sequence, 0=no sequence bool numbered: 1; // 1=has sequence, 0=no sequence
bool controlFlag: 1; // 0=data, 1=control bool controlFlag: 1; // 0=data, 1=control
#endif #endif
}; };
} knxnet_tpci_apci_t; } knxnet_tpci_apci_t;
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t length; uint8_t length;
uint8_t protocolCode; // 0x01=UDP over IPv4 uint8_t protocolCode; // 0x01=UDP over IPv4
uint32be_t ipAddressV4; uint32be_t ipAddressV4;
uint16be_t port; uint16be_t port;
} knxnet_hpai_t; } knxnet_hpai_t;
@@ -194,9 +195,9 @@ typedef struct __attribute__ ((packed)) {
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t length; uint8_t length;
uint8_t descriptionCode; // 0x01=device info uint8_t descriptionCode; // 0x01=device info
uint8_t medium; // 0x20=IP uint8_t medium; // 0x20=IP
uint8_t status; // bit 0=programming mode uint8_t status; // bit 0=programming mode
uint16be_t individualAddress; uint16be_t individualAddress;
uint16be_t projInstId; uint16be_t projInstId;
uint8_t serial[6]; uint8_t serial[6];
@@ -207,11 +208,11 @@ typedef struct __attribute__ ((packed)) {
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t length; uint8_t length;
uint8_t descriptionCode; // 0x02=services uint8_t descriptionCode; // 0x02=services
struct { struct {
uint8_t familyId; uint8_t familyId;
uint8_t familyVersion; uint8_t familyVersion;
}; // just one for now }; // just one for now
} knxnet_dib_services_t; } knxnet_dib_services_t;
// the default system port // the default system port
@@ -227,7 +228,7 @@ class LastFrame {
public: public:
void set(uint8_t* data, size_t len, size_t lOffset, time_t now) { void set(uint8_t* data, size_t len, size_t lOffset, time_t now) {
if (len>=sizeof(m_data)) { if (len >= sizeof(m_data)) {
return; return;
} }
memcpy(m_data, data, len); memcpy(m_data, data, len);
@@ -237,7 +238,7 @@ class LastFrame {
} }
bool isValid(time_t now) { bool isValid(time_t now) {
return m_len && m_time>=now-LAST_FRAME_TIMEOUT; return m_len && m_time >= now-LAST_FRAME_TIMEOUT;
} }
bool isSameAs(uint8_t* data, size_t len, size_t lOffset, time_t now, bool isSend = false) { bool isSameAs(uint8_t* data, size_t len, size_t lOffset, time_t now, bool isSend = false) {
@@ -250,10 +251,10 @@ class LastFrame {
} }
int oldHopCount = (m_data[lOffset+1]&0x70)>>4; int oldHopCount = (m_data[lOffset+1]&0x70)>>4;
int newHopCount = (data[lOffset+1]&0x70)>>4; int newHopCount = (data[lOffset+1]&0x70)>>4;
if (newHopCount < 6 // top hop count is always tolerated TODO bad idea? if (newHopCount < 6 // top hop count is always tolerated TODO bad idea?
&& memcmp(data, m_data, lOffset+1) == 0 // including first byte of l_data header && memcmp(data, m_data, lOffset+1) == 0 // including first byte of l_data header
&& (data[lOffset+1]&~0x70)==(m_data[lOffset+1]&~0x70) // ignore hop count && (data[lOffset+1]&~0x70) == (m_data[lOffset+1]&~0x70) // ignore hop count
&& (isSend ? newHopCount<=oldHopCount : newHopCount<oldHopCount) // decremented hop count? && (isSend ? newHopCount <= oldHopCount : newHopCount < oldHopCount) // decremented hop count?
&& memcmp(data+lOffset+2, m_data+lOffset+2, len-(lOffset+2)) == 0 && memcmp(data+lOffset+2, m_data+lOffset+2, len-(lOffset+2)) == 0
) { ) {
m_time = now; m_time = now;
@@ -286,7 +287,7 @@ class LastFrame {
class LastFrames { class LastFrames {
public: public:
bool isRepetition(uint8_t* data, size_t len, size_t lOffset, time_t now, bool isSend = false) { bool isRepetition(uint8_t* data, size_t len, size_t lOffset, time_t now, bool isSend = false) {
for (int i=0; i<CHECK_REPETITION_COUNT; i++) { for (int i=0; i < CHECK_REPETITION_COUNT; i++) {
if (m_lastFrames[i].isValid(now) if (m_lastFrames[i].isValid(now)
&& m_lastFrames[i].isSameAs(data, len, lOffset, now, isSend)) { && m_lastFrames[i].isSameAs(data, len, lOffset, now, isSend)) {
return true; return true;
@@ -298,12 +299,12 @@ class LastFrames {
void add(uint8_t* data, size_t len, size_t lOffset, time_t now) { void add(uint8_t* data, size_t len, size_t lOffset, time_t now) {
int oldestPos = -1; int oldestPos = -1;
time_t oldestAge = 0; time_t oldestAge = 0;
for (int i=0; i<CHECK_REPETITION_COUNT; i++) { for (int i=0; i < CHECK_REPETITION_COUNT; i++) {
if (!m_lastFrames[i].isValid(now)) { if (!m_lastFrames[i].isValid(now)) {
m_lastFrames[i].set(data, len, lOffset, now); m_lastFrames[i].set(data, len, lOffset, now);
return; return;
} }
if (oldestPos<0 || m_lastFrames[i].m_time < oldestAge) { if (oldestPos < 0 || m_lastFrames[i].m_time < oldestAge) {
oldestPos = i; oldestPos = i;
oldestAge = m_lastFrames[i].m_time; oldestAge = m_lastFrames[i].m_time;
} }
@@ -312,7 +313,7 @@ class LastFrames {
} }
void reset() { void reset() {
for (int i=0; i<CHECK_REPETITION_COUNT; i++) { for (int i=0; i < CHECK_REPETITION_COUNT; i++) {
m_lastFrames[i].reset(); m_lastFrames[i].reset();
} }
} }
@@ -328,7 +329,8 @@ class LastFrames {
// helper method to log received/sent telegrams // helper method to log received/sent telegrams
void logTelegram(bool sent, knxnet_cemi_header_t* c, knxnet_l_data_header_t* l, uint8_t* d) { void logTelegram(bool sent, knxnet_cemi_header_t* c, knxnet_l_data_header_t* l, uint8_t* d) {
bool isGrp = l->controlField2.addressType; bool isGrp = l->controlField2.addressType;
PRINTF("%s msgcode=%2.2x, %d.%d.%d > %d%c%d%c%d, repeat=%s, ack=%s, hopcnt=%d, prio=%s, frame=%s, %sbroad, confirm=%s, tpci/apci=%2.2x", PRINTF("%s msgcode=%2.2x, %d.%d.%d > %d%c%d%c%d, repeat=%s, ack=%s, hopcnt=%d, prio=%s, frame=%s, %sbroad, "
"confirm=%s, tpci/apci=%2.2x",
sent ? "send" : "recv", sent ? "send" : "recv",
c->messageCode, c->messageCode,
l->sourceAddress.high>>4, l->sourceAddress.high>>4,
@@ -342,15 +344,15 @@ void logTelegram(bool sent, knxnet_cemi_header_t* c, knxnet_l_data_header_t* l,
l->controlField1.repeat ? "yes" : "no", l->controlField1.repeat ? "yes" : "no",
l->controlField1.acknowledgeRequest ? "yes" : "no", l->controlField1.acknowledgeRequest ? "yes" : "no",
l->controlField2.hopCount, l->controlField2.hopCount,
l->controlField1.priority==1 ? "normal" : l->controlField1.priority==2 ? "urgent" : l->controlField1.priority==3 ? "low" : "system", l->controlField1.priority == 1 ? "normal" : l->controlField1.priority == 2 ? "urgent" :
l->controlField1.priority == 3 ? "low" : "system",
l->controlField1.frameType ? "std" : "ext", l->controlField1.frameType ? "std" : "ext",
l->controlField1.systemBroadcast ? "" : "sys ", l->controlField1.systemBroadcast ? "" : "sys ",
l->controlField1.confirm ? "error" : "no err", l->controlField1.confirm ? "error" : "no err",
d[0] d[0]);
);
if (d) { if (d) {
PRINTF(", data="); PRINTF(", data=");
for (int i=0; i<l->informationLength; i++) { for (int i=0; i < l->informationLength; i++) {
PRINTF("%2.2x ", d[1+i]); PRINTF("%2.2x ", d[1+i]);
} }
} }
@@ -371,7 +373,7 @@ class KnxNetConnection : public KnxConnection {
/** /**
* Construct a new instance. * Construct a new instance.
*/ */
KnxNetConnection(const char* url) explicit KnxNetConnection(const char* url)
: KnxConnection(), m_url(url), m_sock(0), m_programmingMode(false), m_addr(0) {} : KnxConnection(), m_url(url), m_sock(0), m_programmingMode(false), m_addr(0) {}
/** /**
@@ -395,7 +397,7 @@ class KnxNetConnection : public KnxConnection {
m_interface.s_addr = INADDR_ANY; m_interface.s_addr = INADDR_ANY;
m_port = SYSTEM_MULTICAST_PORT; m_port = SYSTEM_MULTICAST_PORT;
if (m_url && m_url[0]) { // non-empty if (m_url && m_url[0]) { // non-empty
string urlStr = m_url; // "[mcast][@intf]" for non-default 224.0.23.12:3671) string urlStr = m_url; // "[mcast][@intf]" for non-default 224.0.23.12:3671)
if (!urlStr.empty()) { if (!urlStr.empty()) {
auto pos = urlStr.find('@'); auto pos = urlStr.find('@');
if (pos != string::npos) { if (pos != string::npos) {
@@ -504,11 +506,12 @@ class KnxNetConnection : public KnxConnection {
// @copydoc // @copydoc
knx_transfer_t getPollData(int size, uint8_t* data, int* recvlen, knx_addr_t* src, knx_addr_t* dst) override { knx_transfer_t getPollData(int size, uint8_t* data, int* recvlen, knx_addr_t* src, knx_addr_t* dst) override {
uint8_t buf[128]; uint8_t buf[128];
ssize_t len = recv(m_sock, buf, sizeof(buf), 0); ssize_t slen = recv(m_sock, buf, sizeof(buf), 0);
if (len < sizeof(knxnet_header_t)) { if (slen < 0 || static_cast<unsigned>(slen) < sizeof(knxnet_header_t)) {
PRINTF("#skip recv short hdr len=%d\n", len); PRINTF("#skip recv short hdr len=%d\n", len);
return KNX_TRANSFER_NONE; return KNX_TRANSFER_NONE;
} }
size_t len = static_cast<unsigned>(slen);
auto h = (knxnet_header_t*)buf; auto h = (knxnet_header_t*)buf;
if (h->headerLength != sizeof(knxnet_header_t) || h->protocolVersion != 0x10) { if (h->headerLength != sizeof(knxnet_header_t) || h->protocolVersion != 0x10) {
PRINTF("#skip recv short/proto len=%d\n", len); PRINTF("#skip recv short/proto len=%d\n", len);
@@ -583,16 +586,16 @@ class KnxNetConnection : public KnxConnection {
// all fine // all fine
int ret = d[0]; int ret = d[0];
if (l->controlField2.addressType) { if (l->controlField2.addressType) {
ret |= 0x100; // address type group ret |= 0x100; // address type group
} }
if (!(ret&0x80)) { if (!(ret&0x80)) {
ret &= ~0x03; // remove two apci bits ret &= ~0x03; // remove two apci bits
} }
if (ret&0x40) { if (ret&0x40) {
ret &= ~0x3c; // remove sequence number ret &= ~0x3c; // remove sequence number
} }
*recvlen = size > dataLen ? dataLen : size; *recvlen = size > dataLen ? dataLen : size;
memcpy(data, d, *recvlen); // including the TPCI/APCI octet 6 memcpy(data, d, *recvlen); // including the TPCI/APCI octet 6
if (src) { if (src) {
*src = htons(l->sourceAddress.raw); *src = htons(l->sourceAddress.raw);
} }
@@ -638,27 +641,27 @@ class KnxNetConnection : public KnxConnection {
c->additionalInfoLength = 0; c->additionalInfoLength = 0;
auto lOffset = sizeof(knxnet_header_t)+sizeof(knxnet_cemi_header_t)+c->additionalInfoLength; auto lOffset = sizeof(knxnet_header_t)+sizeof(knxnet_cemi_header_t)+c->additionalInfoLength;
auto l = (knxnet_l_data_header_t*)(((uint8_t*)h)+lOffset); auto l = (knxnet_l_data_header_t*)(((uint8_t*)h)+lOffset);
l->controlField1.raw = 0xbc; // standard frame, no repeat, broadcast, low prio, no ack, no err l->controlField1.raw = 0xbc; // standard frame, no repeat, broadcast, low prio, no ack, no err
l->controlField2.raw = 0xe0; // group address, hop count 6, standard frame l->controlField2.raw = 0xe0; // group address, hop count 6, standard frame
l->controlField2.addressType = (typ&0x100)!=0; l->controlField2.addressType = (typ&0x100) != 0;
l->sourceAddress.raw = htons(m_addr); l->sourceAddress.raw = htons(m_addr);
l->destinationAddress.raw = htons(dst); l->destinationAddress.raw = htons(dst);
if (typ&0x100) { if (typ&0x100) {
// ensure at least default individual address // ensure at least default individual address
if (!m_addr) { if (!m_addr) {
l->sourceAddress.raw = 0xffff; // for "unregistered device" in S-Mode l->sourceAddress.raw = 0xffff; // for "unregistered device" in S-Mode
} }
} }
l->informationLength = len-1; // subtracting the TPCI/APCI l->informationLength = len-1; // subtracting the TPCI/APCI
uint8_t* d = buf+sizeof(knxnet_header_t)+sizeof(knxnet_cemi_header_t)+sizeof(knxnet_l_data_header_t); uint8_t* d = buf+sizeof(knxnet_header_t)+sizeof(knxnet_cemi_header_t)+sizeof(knxnet_l_data_header_t);
// first byte of data is expected to hold the APCI upper byte, copy remainder: // first byte of data is expected to hold the APCI upper byte, copy remainder:
memcpy(d, data, len); memcpy(d, data, len);
int tpci = typ&0xff; // TPCI/APCI int tpci = typ&0xff; // TPCI/APCI
if ((typ&0x080)==0) { if ((typ&0x080) == 0) {
tpci |= (d[0]&0x03); // highest 2 bits of APCI tpci |= (d[0]&0x03); // highest 2 bits of APCI
} }
if (typ&0x040) { if (typ&0x040) {
tpci |= d[0]&((0x0f)<<2); // SeqNo tpci |= d[0]&((0x0f) << 2); // SeqNo
} }
d[0] = tpci; d[0] = tpci;
logTelegram(true, c, l, d); logTelegram(true, c, l, d);
@@ -673,7 +676,7 @@ class KnxNetConnection : public KnxConnection {
} }
// copydoc // copydoc
knx_addr_t getAddress() override { knx_addr_t getAddress() const override {
return m_addr; return m_addr;
} }
@@ -686,7 +689,7 @@ class KnxNetConnection : public KnxConnection {
} }
// copydoc // copydoc
bool isProgrammingMode() override { bool isProgrammingMode() const override {
return m_programmingMode; return m_programmingMode;
} }
+1 -1
View File
@@ -44,7 +44,7 @@ void clockGettime(struct timespec* t) {
#endif #endif
} }
long long clockGetMillis() { uint64_t clockGetMillis() {
struct timespec t; struct timespec t;
clockGettime(&t); clockGettime(&t);
return t.tv_sec*1000LL + t.tv_nsec / 1000000; return t.tv_sec*1000LL + t.tv_nsec / 1000000;
+2 -1
View File
@@ -19,6 +19,7 @@
#ifndef LIB_UTILS_CLOCK_H_ #ifndef LIB_UTILS_CLOCK_H_
#define LIB_UTILS_CLOCK_H_ #define LIB_UTILS_CLOCK_H_
#include <stdint.h>
#include <time.h> #include <time.h>
namespace ebusd { namespace ebusd {
@@ -34,7 +35,7 @@ void clockGettime(struct timespec* t);
/** /**
* Get the current system time in milliseconds since the Epoch. * Get the current system time in milliseconds since the Epoch.
*/ */
long long clockGetMillis(); uint64_t clockGetMillis();
} // namespace ebusd } // namespace ebusd
+1 -1
View File
@@ -170,7 +170,7 @@ SSLSocket* SSLSocket::connect(const string& host, const uint16_t& port, bool htt
if (isError("ctx_new", ctx)) { if (isError("ctx_new", ctx)) {
break; break;
} }
bool verifyPeer = !caFile || strcmp(caFile, "#")!=0; bool verifyPeer = !caFile || strcmp(caFile, "#") != 0;
SSL_CTX_set_verify(ctx, verifyPeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, nullptr); SSL_CTX_set_verify(ctx, verifyPeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, nullptr);
if (verifyPeer) { if (verifyPeer) {
#if OPENSSL_VERSION_NUMBER >= 0x10101000L #if OPENSSL_VERSION_NUMBER >= 0x10101000L
+2 -2
View File
@@ -98,10 +98,10 @@ bool WaitThread::Wait(int seconds, int millis) {
struct timespec t; struct timespec t;
clockGettime(&t); clockGettime(&t);
t.tv_sec += seconds; t.tv_sec += seconds;
long newMillis = t.tv_nsec/1000000 + millis; long int newMillis = t.tv_nsec/1000000 + millis;
if (newMillis >= 1000) { if (newMillis >= 1000) {
t.tv_sec += newMillis / 1000; t.tv_sec += newMillis / 1000;
t.tv_nsec = (newMillis%1000) * 1000000; // rounds down to whole millis t.tv_nsec = (newMillis%1000) * 1000000; // rounds down to whole millis
} else { } else {
t.tv_nsec += millis * 1000000; t.tv_nsec += millis * 1000000;
} }
+16 -22
View File
@@ -45,8 +45,8 @@ const char *argp_program_version = "eBUS adapter PIC firmware loader";
/** the documentation of the program. */ /** the documentation of the program. */
static const char argpdoc[] = static const char argpdoc[] =
"A tool for loading firmware to the eBUS adapter PIC." "A tool for loading firmware to the eBUS adapter PIC."
"\vPORT is either the serial port to use (e.g./dev/ttyUSB0) that also supports a trailing wildcard '*' for testing multiple ports," "\vPORT is either the serial port to use (e.g./dev/ttyUSB0) that also supports a trailing wildcard '*' for testing"
"or a network port as \"ip:port\" for use with e.g. socat."; " multiple ports, or a network port as \"ip:port\" for use with e.g. socat.";
static const char argpargsdoc[] = "PORT"; static const char argpargsdoc[] = "PORT";
@@ -149,7 +149,7 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
} }
setIp = true; setIp = true;
break; break;
case 'm': // --mask=24 case 'm': // --mask=24
if (arg == nullptr || arg[0] == 0) { if (arg == nullptr || arg[0] == 0) {
argp_error(state, "invalid IP mask"); argp_error(state, "invalid IP mask");
return EINVAL; return EINVAL;
@@ -164,10 +164,10 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
} }
setMask = true; setMask = true;
break; break;
case 'M': // --macip case 'M': // --macip
setMacFromIp = true; setMacFromIp = true;
break; break;
case 'a': // --arbdel=1000 case 'a': // --arbdel=1000
if (arg == nullptr || arg[0] == 0) { if (arg == nullptr || arg[0] == 0) {
argp_error(state, "invalid arbitration delay"); argp_error(state, "invalid arbitration delay");
return EINVAL; return EINVAL;
@@ -178,17 +178,17 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
} }
setArbitrationDelay = true; setArbitrationDelay = true;
break; break;
case 'f': // --flash=firmware.hex case 'f': // --flash=firmware.hex
if (arg == nullptr || arg[0] == 0 || stat(arg, &st) != 0 || !S_ISREG(st.st_mode)) { if (arg == nullptr || arg[0] == 0 || stat(arg, &st) != 0 || !S_ISREG(st.st_mode)) {
argp_error(state, "invalid flash file"); argp_error(state, "invalid flash file");
return EINVAL; return EINVAL;
} }
flashFile = arg; flashFile = arg;
break; break;
case 'r': // --reset case 'r': // --reset
reset = true; reset = true;
break; break;
case 's': // --slow case 's': // --slow
lowSpeed = true; lowSpeed = true;
break; break;
default: default:
@@ -265,12 +265,6 @@ static bool isSerial = true;
static int timeoutFactor = 1; static int timeoutFactor = 1;
static int timeoutAddend = 0; static int timeoutAddend = 0;
long long getTime() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec*1000+ts.tv_nsec/1000000;
}
ssize_t waitWrite(int fd, uint8_t *data, size_t len, int timeoutMillis) { ssize_t waitWrite(int fd, uint8_t *data, size_t len, int timeoutMillis) {
int ret; int ret;
struct pollfd pfd; struct pollfd pfd;
@@ -770,7 +764,7 @@ void printFileChecksum() {
} }
std::cout std::cout
<< "New firmware version: " << static_cast<unsigned>(newFirmwareVersion) << "New firmware version: " << static_cast<unsigned>(newFirmwareVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(checkSum) << "]" << std::endl; << " [" << std::hex << std::setw(4) << std::setfill('0') << static_cast<signed>(checkSum) << "]" << std::endl;
} }
bool flashPic(int fd) { bool flashPic(int fd) {
@@ -938,10 +932,10 @@ void readSettings(int fd) {
} }
uint16_t arbitrationDelay = configData[3]&0x3f; uint16_t arbitrationDelay = configData[3]&0x3f;
std::cout << "Arbitration delay: "; std::cout << "Arbitration delay: ";
if (arbitrationDelay==0x3f) { if (arbitrationDelay == 0x3f) {
std::cout << "200 us (default)" << std::endl; std::cout << "200 us (default)" << std::endl;
} else { } else {
arbitrationDelay *= 10; // steps of 10us arbitrationDelay *= 10; // steps of 10us
std::cout << std::dec << static_cast<unsigned>(arbitrationDelay) << " us" << std::endl; std::cout << std::dec << static_cast<unsigned>(arbitrationDelay) << " us" << std::endl;
} }
} }
@@ -996,7 +990,7 @@ int main(int argc, char* argv[]) {
} }
std::string port = argv[arg_index]; std::string port = argv[arg_index];
std::string::size_type pos = port.find('*'); std::string::size_type pos = port.find('*');
if (pos==std::string::npos || pos != port.length()-1) { if (pos == std::string::npos || pos != port.length()-1) {
int fd; int fd;
pos = port.find(':'); pos = port.find(':');
if (pos != std::string::npos) { if (pos != std::string::npos) {
@@ -1019,14 +1013,14 @@ int main(int argc, char* argv[]) {
} }
std::string::size_type sep = port.find_last_of('/'); std::string::size_type sep = port.find_last_of('/');
std::string base = sep==std::string::npos ? "" : port.substr(0, sep); std::string base = sep == std::string::npos ? "" : port.substr(0, sep);
DIR* dir = opendir(base.c_str()); DIR* dir = opendir(base.c_str());
if (!dir) { if (!dir) {
std::cerr << "Unable to open directory " << base << std::endl; std::cerr << "Unable to open directory " << base << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
std::string prefix = sep==std::string::npos ? port.substr(0, pos) : port.substr(sep + 1, pos - 1 - sep); std::string prefix = sep == std::string::npos ? port.substr(0, pos) : port.substr(sep + 1, pos - 1 - sep);
struct dirent* ent; struct dirent* ent;
while ((ent = readdir(dir))) { while ((ent = readdir(dir))) {
if (std::string(ent->d_name).substr(0, prefix.length()) != prefix) { if (std::string(ent->d_name).substr(0, prefix.length()) != prefix) {
@@ -1081,7 +1075,7 @@ int run(int fd) {
int picSum = calcChecksum(fd, 0x0000, END_BOOT_BYTES); int picSum = calcChecksum(fd, 0x0000, END_BOOT_BYTES);
std::cout std::cout
<< "Bootloader version: " << static_cast<unsigned>(bootloaderVersion) << "Bootloader version: " << static_cast<unsigned>(bootloaderVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl; << " [" << std::hex << std::setw(4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl;
} else { } else {
std::cerr << "Bootloader version not found" << std::endl; std::cerr << "Bootloader version not found" << std::endl;
} }
@@ -1092,7 +1086,7 @@ int run(int fd) {
int picSum = calcChecksum(fd, END_BOOT, END_FLASH_BYTES-END_BOOT_BYTES); int picSum = calcChecksum(fd, END_BOOT, END_FLASH_BYTES-END_BOOT_BYTES);
std::cout std::cout
<< "Firmware version: " << static_cast<unsigned>(firmwareVersion) << "Firmware version: " << static_cast<unsigned>(firmwareVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl; << " [" << std::hex << std::setw(4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl;
} else { } else {
std::cout << "Firmware version not found" << std::endl; std::cout << "Firmware version not found" << std::endl;
} }