Merge remote-tracking branch 'origin/master' into enhanced_device
# Conflicts: # src/lib/ebus/device.cpp
This commit is contained in:
@@ -9,12 +9,35 @@ if (substr($agent, 0, 5)==='ebusd') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
readVersions();
|
readVersions();
|
||||||
|
$ref = @file_get_contents('ebusd-configuration/.git/refs/heads/master');
|
||||||
?>
|
?>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>ebusd update check service</title>
|
<title>ebusd update check webservice</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>latest ebusd version: <?=$versions['ebusd'][0]?></p>
|
|
||||||
<p>last update: <?=date('c', @filemtime('versions.txt'))?></p>
|
<p>last update: <?=date('c', @filemtime('versions.txt'))?></p>
|
||||||
|
<?php
|
||||||
|
if ($ref) {
|
||||||
|
echo " <p>git revision: <a href=\"https://github.com/john30/ebusd-configuration/tree/$ref\">".substr($ref, 0, 7).'</a></p>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<p>latest ebusd version: <?=$versions['ebusd'][0]?></p>
|
||||||
|
<p>config files:
|
||||||
|
<?php
|
||||||
|
$func = function($v, $k) {
|
||||||
|
if ($k==='ebusd') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
global $ref;
|
||||||
|
$str = "$k: ".date('d.m.Y H:i:s', $v[2]);
|
||||||
|
if ($ref) {
|
||||||
|
echo " <br><a href=\"https://github.com/john30/ebusd-configuration/blob/$ref/ebusd-2.1.x/de/$k\">$str</a>\n";
|
||||||
|
} else {
|
||||||
|
echo " <br>$str\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
array_walk($versions, $func);
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -328,7 +328,7 @@ result_t BusHandler::sendAndWait(const MasterSymbolString& master, SlaveSymbolSt
|
|||||||
ActiveBusRequest request(master, slave);
|
ActiveBusRequest request(master, slave);
|
||||||
logInfo(lf_bus, "send message: %s", master.getStr().c_str());
|
logInfo(lf_bus, "send message: %s", master.getStr().c_str());
|
||||||
|
|
||||||
for (int sendRetries = m_failedSendRetries + 1; sendRetries >= 0; sendRetries--) {
|
for (int sendRetries = m_failedSendRetries + 1; sendRetries > 0; sendRetries--) {
|
||||||
m_nextRequests.push(&request);
|
m_nextRequests.push(&request);
|
||||||
bool success = m_finishedRequests.remove(&request, true);
|
bool success = m_finishedRequests.remove(&request, true);
|
||||||
result = success ? request.m_result : RESULT_ERR_TIMEOUT;
|
result = success ? request.m_result : RESULT_ERR_TIMEOUT;
|
||||||
@@ -339,7 +339,7 @@ result_t BusHandler::sendAndWait(const MasterSymbolString& master, SlaveSymbolSt
|
|||||||
logError(lf_bus, "send to %2.2x: %s, give up", master[1], getResultCode(result));
|
logError(lf_bus, "send to %2.2x: %s, give up", master[1], getResultCode(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
logError(lf_bus, "send to %2.2x: %s%s", master[1], getResultCode(result), sendRetries > 0 ? ", retry" : "");
|
logError(lf_bus, "send to %2.2x: %s%s", master[1], getResultCode(result), sendRetries > 1 ? ", retry" : "");
|
||||||
request.m_busLostRetries = 0;
|
request.m_busLostRetries = 0;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ static struct options opt = {
|
|||||||
false, // dump
|
false, // dump
|
||||||
"/tmp/" PACKAGE "_dump.bin", // dumpFile
|
"/tmp/" PACKAGE "_dump.bin", // dumpFile
|
||||||
100, // dumpSize
|
100, // dumpSize
|
||||||
|
false, // dumpFlush
|
||||||
};
|
};
|
||||||
|
|
||||||
/** the @a MessageMap instance, or nullptr. */
|
/** the @a MessageMap instance, or nullptr. */
|
||||||
@@ -174,6 +175,7 @@ static const char argpdoc[] =
|
|||||||
#define O_RAWSIZ (O_RAWFIL+1)
|
#define O_RAWSIZ (O_RAWFIL+1)
|
||||||
#define O_DMPFIL (O_RAWSIZ+1)
|
#define O_DMPFIL (O_RAWSIZ+1)
|
||||||
#define O_DMPSIZ (O_DMPFIL+1)
|
#define O_DMPSIZ (O_DMPFIL+1)
|
||||||
|
#define O_DMPFLU (O_DMPSIZ+1)
|
||||||
|
|
||||||
/** the definition of the known program arguments. */
|
/** the definition of the known program arguments. */
|
||||||
static const struct argp_option argpoptions[] = {
|
static const struct argp_option argpoptions[] = {
|
||||||
@@ -242,6 +244,7 @@ static const struct argp_option argpoptions[] = {
|
|||||||
{"dump", 'D', nullptr, 0, "Enable binary dump of received bytes", 0 },
|
{"dump", 'D', nullptr, 0, "Enable binary dump of received bytes", 0 },
|
||||||
{"dumpfile", O_DMPFIL, "FILE", 0, "Dump received bytes to FILE [/tmp/" PACKAGE "_dump.bin]", 0 },
|
{"dumpfile", O_DMPFIL, "FILE", 0, "Dump received bytes to FILE [/tmp/" PACKAGE "_dump.bin]", 0 },
|
||||||
{"dumpsize", O_DMPSIZ, "SIZE", 0, "Make dump file no larger than SIZE kB [100]", 0 },
|
{"dumpsize", O_DMPSIZ, "SIZE", 0, "Make dump file no larger than SIZE kB [100]", 0 },
|
||||||
|
{"dumpflush", O_DMPFLU, nullptr, 0, "Flush each byte", 0 },
|
||||||
|
|
||||||
{nullptr, 0, nullptr, 0, nullptr, 0 },
|
{nullptr, 0, nullptr, 0, nullptr, 0 },
|
||||||
};
|
};
|
||||||
@@ -581,6 +584,9 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case O_DMPFLU: // --dumpflush
|
||||||
|
opt->dumpFlush = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (opt->injectMessages || (opt->checkConfig && opt->scanConfig)) {
|
if (opt->injectMessages || (opt->checkConfig && opt->scanConfig)) {
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ struct options {
|
|||||||
bool dump; //!< binary dump received bytes
|
bool dump; //!< binary dump received bytes
|
||||||
const char* dumpFile; //!< name of dump file [/tmp/ebusd_dump.bin]
|
const char* dumpFile; //!< name of dump file [/tmp/ebusd_dump.bin]
|
||||||
unsigned int dumpSize; //!< maximum size of dump file in kB [100]
|
unsigned int dumpSize; //!< maximum size of dump file in kB [100]
|
||||||
|
bool dumpFlush; //!< flush each byte
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messag
|
|||||||
}
|
}
|
||||||
m_device->setListener(this);
|
m_device->setListener(this);
|
||||||
if (opt.dumpFile[0]) {
|
if (opt.dumpFile[0]) {
|
||||||
m_dumpFile = new RotateFile(opt.dumpFile, opt.dumpSize);
|
m_dumpFile = new RotateFile(opt.dumpFile, opt.dumpSize, false, opt.dumpFlush ? 1 : 16);
|
||||||
m_dumpFile->setEnabled(opt.dump);
|
m_dumpFile->setEnabled(opt.dump);
|
||||||
} else {
|
} else {
|
||||||
m_dumpFile = nullptr;
|
m_dumpFile = nullptr;
|
||||||
@@ -359,12 +359,14 @@ void MainLoop::run() {
|
|||||||
time(&now);
|
time(&now);
|
||||||
if (!dataSinks.empty()) {
|
if (!dataSinks.empty()) {
|
||||||
messages.clear();
|
messages.clear();
|
||||||
|
m_messages->lock();
|
||||||
m_messages->findAll("", "", "*", false, true, true, true, true, true, sinkSince, now, false, &messages);
|
m_messages->findAll("", "", "*", false, true, true, true, true, true, sinkSince, now, false, &messages);
|
||||||
for (const auto message : messages) {
|
for (const auto message : messages) {
|
||||||
for (const auto dataSink : dataSinks) {
|
for (const auto dataSink : dataSinks) {
|
||||||
dataSink->notifyUpdate(message);
|
dataSink->notifyUpdate(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_messages->unlock();
|
||||||
sinkSince = now;
|
sinkSince = now;
|
||||||
}
|
}
|
||||||
if (netMessage == nullptr) {
|
if (netMessage == nullptr) {
|
||||||
@@ -461,11 +463,12 @@ void MainLoop::notifyDeviceData(symbol_t symbol, bool received) {
|
|||||||
m_logRawLastSymbol = symbol;
|
m_logRawLastSymbol = symbol;
|
||||||
}
|
}
|
||||||
if (symbol == SYN && m_logRawBuffer.tellp() > 0) { // flush
|
if (symbol == SYN && m_logRawBuffer.tellp() > 0) { // flush
|
||||||
|
const string bufStr = m_logRawBuffer.str();
|
||||||
|
const char* str = bufStr.c_str();
|
||||||
if (m_logRawFile) {
|
if (m_logRawFile) {
|
||||||
const char* str = m_logRawBuffer.str().c_str();
|
|
||||||
m_logRawFile->write((const unsigned char*)str, strlen(str), received, false);
|
m_logRawFile->write((const unsigned char*)str, strlen(str), received, false);
|
||||||
} else {
|
} else {
|
||||||
logNotice(lf_bus, m_logRawBuffer.str().c_str());
|
logNotice(lf_bus, str);
|
||||||
}
|
}
|
||||||
m_logRawBuffer.str("");
|
m_logRawBuffer.str("");
|
||||||
}
|
}
|
||||||
@@ -2115,7 +2118,7 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
|||||||
<< ",\n \"maxsymbolrate\": " << m_busHandler->getMaxSymbolRate();
|
<< ",\n \"maxsymbolrate\": " << m_busHandler->getMaxSymbolRate();
|
||||||
if (m_busHandler->getMinArbitrationDelay() >= 0) {
|
if (m_busHandler->getMinArbitrationDelay() >= 0) {
|
||||||
*ostream << ",\n \"minarbitrationmicros\": " << m_busHandler->getMinArbitrationDelay()
|
*ostream << ",\n \"minarbitrationmicros\": " << m_busHandler->getMinArbitrationDelay()
|
||||||
<< ",\n \"minarbitrationmicros\": " << m_busHandler->getMaxArbitrationDelay();
|
<< ",\n \"maxarbitrationmicros\": " << m_busHandler->getMaxArbitrationDelay();
|
||||||
}
|
}
|
||||||
if (m_busHandler->getMinSymbolLatency() >= 0) {
|
if (m_busHandler->getMinSymbolLatency() >= 0) {
|
||||||
*ostream << ",\n \"minsymbollatency\": " << m_busHandler->getMinSymbolLatency()
|
*ostream << ",\n \"minsymbollatency\": " << m_busHandler->getMinSymbolLatency()
|
||||||
|
|||||||
@@ -747,8 +747,8 @@ void MqttHandler::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_updatedMessages.empty()) {
|
if (!m_updatedMessages.empty()) {
|
||||||
if (m_connected) {
|
|
||||||
m_messages->lock();
|
m_messages->lock();
|
||||||
|
if (m_connected) {
|
||||||
for (auto it = m_updatedMessages.begin(); it != m_updatedMessages.end(); ) {
|
for (auto it = m_updatedMessages.begin(); it != m_updatedMessages.end(); ) {
|
||||||
const vector<Message*>* messages = m_messages->getByKey(it->first);
|
const vector<Message*>* messages = m_messages->getByKey(it->first);
|
||||||
if (messages) {
|
if (messages) {
|
||||||
@@ -764,11 +764,11 @@ void MqttHandler::run() {
|
|||||||
}
|
}
|
||||||
it = m_updatedMessages.erase(it);
|
it = m_updatedMessages.erase(it);
|
||||||
}
|
}
|
||||||
m_messages->unlock();
|
|
||||||
time(&lastUpdates);
|
time(&lastUpdates);
|
||||||
} else {
|
} else {
|
||||||
m_updatedMessages.clear();
|
m_updatedMessages.clear();
|
||||||
}
|
}
|
||||||
|
m_messages->unlock();
|
||||||
}
|
}
|
||||||
if ((!m_connected && !Wait(5)) || (needsWait && !Wait(1))) {
|
if ((!m_connected && !Wait(5)) || (needsWait && !Wait(1))) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ result_t TemParamDataType::readSymbols(size_t offset, size_t length, const Symbo
|
|||||||
if (outputFormat & OF_JSON) {
|
if (outputFormat & OF_JSON) {
|
||||||
*output << "null";
|
*output << "null";
|
||||||
} else {
|
} else {
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
}
|
}
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ result_t TemParamDataType::writeSymbols(const size_t offset, const size_t length
|
|||||||
unsigned int value;
|
unsigned int value;
|
||||||
unsigned int grp, num;
|
unsigned int grp, num;
|
||||||
|
|
||||||
if (input->str() == nullptr_VALUE) {
|
if (input->str() == NULL_VALUE) {
|
||||||
value = m_replacement; // replacement value
|
value = m_replacement; // replacement value
|
||||||
} else {
|
} else {
|
||||||
string token;
|
string token;
|
||||||
|
|||||||
@@ -752,7 +752,7 @@ result_t ValueListDataField::readSymbols(const SymbolString& input, size_t offse
|
|||||||
if (outputFormat & OF_JSON) {
|
if (outputFormat & OF_JSON) {
|
||||||
*output << "null";
|
*output << "null";
|
||||||
} else if (value == m_dataType->getReplacement()) {
|
} else if (value == m_dataType->getReplacement()) {
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
}
|
}
|
||||||
} else if (outputFormat & OF_NUMERIC) {
|
} else if (outputFormat & OF_NUMERIC) {
|
||||||
*output << setw(0) << dec << value;
|
*output << setw(0) << dec << value;
|
||||||
@@ -775,17 +775,18 @@ result_t ValueListDataField::readSymbols(const SymbolString& input, size_t offse
|
|||||||
result_t ValueListDataField::writeSymbols(size_t offset, istringstream* input,
|
result_t ValueListDataField::writeSymbols(size_t offset, istringstream* input,
|
||||||
SymbolString* output, size_t* usedLength) const {
|
SymbolString* output, size_t* usedLength) const {
|
||||||
const NumberDataType* numType = reinterpret_cast<const NumberDataType*>(m_dataType);
|
const NumberDataType* numType = reinterpret_cast<const NumberDataType*>(m_dataType);
|
||||||
if (isIgnored() || input->str() == nullptr_VALUE) {
|
const string inputStr = input->str();
|
||||||
|
if (isIgnored() || inputStr == NULL_VALUE) {
|
||||||
// replacement value
|
// replacement value
|
||||||
return numType->writeRawValue(numType->getReplacement(), offset, m_length, output, usedLength);
|
return numType->writeRawValue(numType->getReplacement(), offset, m_length, output, usedLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* str = input->str().c_str();
|
|
||||||
for (map<unsigned int, string>::const_iterator it = m_values.begin(); it != m_values.end(); ++it) {
|
for (map<unsigned int, string>::const_iterator it = m_values.begin(); it != m_values.end(); ++it) {
|
||||||
if (it->second.compare(str) == 0) {
|
if (it->second == inputStr) {
|
||||||
return numType->writeRawValue(it->first, offset, m_length, output, usedLength);
|
return numType->writeRawValue(it->first, offset, m_length, output, usedLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const char* str = inputStr.c_str();
|
||||||
char* strEnd = nullptr; // fall back to raw value in input
|
char* strEnd = nullptr; // fall back to raw value in input
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
value = (unsigned int)strtoul(str, &strEnd, 10);
|
value = (unsigned int)strtoul(str, &strEnd, 10);
|
||||||
|
|||||||
+14
-13
@@ -243,13 +243,13 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
|||||||
case 2: // date only
|
case 2: // date only
|
||||||
if (!hasFlag(REQ) && symbol == m_replacement) {
|
if (!hasFlag(REQ) && symbol == m_replacement) {
|
||||||
if (i + 1 != length) {
|
if (i + 1 != length) {
|
||||||
*output << nullptr_VALUE << ".";
|
*output << NULL_VALUE << ".";
|
||||||
break;
|
break;
|
||||||
} else if (last == m_replacement) {
|
} else if (last == m_replacement) {
|
||||||
if (length == 2) { // number of days since 01.01.1900
|
if (length == 2) { // number of days since 01.01.1900
|
||||||
*output << nullptr_VALUE << ".";
|
*output << NULL_VALUE << ".";
|
||||||
}
|
}
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,13 +282,13 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
|||||||
case 1: // time only
|
case 1: // time only
|
||||||
if (!hasFlag(REQ) && symbol == m_replacement) {
|
if (!hasFlag(REQ) && symbol == m_replacement) {
|
||||||
if (length == 1) { // truncated time
|
if (length == 1) { // truncated time
|
||||||
*output << nullptr_VALUE << ":" << nullptr_VALUE;
|
*output << NULL_VALUE << ":" << NULL_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
*output << ":";
|
*output << ":";
|
||||||
}
|
}
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hasFlag(SPE)) { // minutes since midnight
|
if (hasFlag(SPE)) { // minutes since midnight
|
||||||
@@ -378,7 +378,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
if (input->eof() || !getline(*input, token, '.')) {
|
if (input->eof() || !getline(*input, token, '.')) {
|
||||||
return RESULT_ERR_EOF; // incomplete
|
return RESULT_ERR_EOF; // incomplete
|
||||||
}
|
}
|
||||||
if (!hasFlag(REQ) && token == nullptr_VALUE) {
|
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
||||||
value = m_replacement;
|
value = m_replacement;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -431,7 +431,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
if (input->eof() || !getline(*input, token, LENGTH_SEPARATOR)) {
|
if (input->eof() || !getline(*input, token, LENGTH_SEPARATOR)) {
|
||||||
return RESULT_ERR_EOF; // incomplete
|
return RESULT_ERR_EOF; // incomplete
|
||||||
}
|
}
|
||||||
if (!hasFlag(REQ) && token == nullptr_VALUE) {
|
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
||||||
value = m_replacement;
|
value = m_replacement;
|
||||||
if (length == 1) { // truncated time
|
if (length == 1) { // truncated time
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -654,7 +654,7 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS
|
|||||||
if (outputFormat & OF_JSON) {
|
if (outputFormat & OF_JSON) {
|
||||||
*output << "null";
|
*output << "null";
|
||||||
} else {
|
} else {
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
}
|
}
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -700,7 +700,7 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS
|
|||||||
if (outputFormat & OF_JSON) {
|
if (outputFormat & OF_JSON) {
|
||||||
*output << "null";
|
*output << "null";
|
||||||
} else {
|
} else {
|
||||||
*output << nullptr_VALUE;
|
*output << NULL_VALUE;
|
||||||
}
|
}
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -805,12 +805,13 @@ result_t NumberDataType::writeSymbols(size_t offset, size_t length, istringstrea
|
|||||||
SymbolString* output, size_t* usedLength) const {
|
SymbolString* output, size_t* usedLength) const {
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
|
|
||||||
if (!hasFlag(REQ) && (isIgnored() || input->str() == nullptr_VALUE)) {
|
const string inputStr = input->str();
|
||||||
|
if (!hasFlag(REQ) && (isIgnored() || inputStr == NULL_VALUE)) {
|
||||||
value = m_replacement; // replacement value
|
value = m_replacement; // replacement value
|
||||||
} else if (input->str().empty()) {
|
} else if (inputStr.empty()) {
|
||||||
return RESULT_ERR_EOF; // input too short
|
return RESULT_ERR_EOF; // input too short
|
||||||
} else if (hasFlag(EXP)) { // IEEE 754 binary32
|
} else if (hasFlag(EXP)) { // IEEE 754 binary32
|
||||||
const char* str = input->str().c_str();
|
const char* str = inputStr.c_str();
|
||||||
char* strEnd = nullptr;
|
char* strEnd = nullptr;
|
||||||
double dvalue = strtod(str, &strEnd);
|
double dvalue = strtod(str, &strEnd);
|
||||||
if (strEnd == nullptr || strEnd == str || *strEnd != 0) {
|
if (strEnd == nullptr || strEnd == str || *strEnd != 0) {
|
||||||
@@ -849,7 +850,7 @@ result_t NumberDataType::writeSymbols(size_t offset, size_t length, istringstrea
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
const char* str = input->str().c_str();
|
const char* str = inputStr.c_str();
|
||||||
char* strEnd = nullptr;
|
char* strEnd = nullptr;
|
||||||
if (m_divisor == 1) {
|
if (m_divisor == 1) {
|
||||||
if (hasFlag(SIG)) {
|
if (hasFlag(SIG)) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ using std::ostringstream;
|
|||||||
#define LENGTH_SEPARATOR ':'
|
#define LENGTH_SEPARATOR ':'
|
||||||
|
|
||||||
/** the replacement string for undefined values (in UI and CSV). */
|
/** the replacement string for undefined values (in UI and CSV). */
|
||||||
#define nullptr_VALUE "-"
|
#define NULL_VALUE "-"
|
||||||
|
|
||||||
/** the separator character used between fields (in UI only). */
|
/** the separator character used between fields (in UI only). */
|
||||||
#define UI_FIELD_SEPARATOR ';'
|
#define UI_FIELD_SEPARATOR ';'
|
||||||
@@ -134,7 +134,7 @@ enum PartType {
|
|||||||
/** bit flag for @a DataType: fixed width formatting. */
|
/** bit flag for @a DataType: fixed width formatting. */
|
||||||
#define FIX 0x20
|
#define FIX 0x20
|
||||||
|
|
||||||
/** bit flag for @a DataType: value may not be nullptr. */
|
/** bit flag for @a DataType: value may not be NULL. */
|
||||||
#define REQ 0x40
|
#define REQ 0x40
|
||||||
|
|
||||||
/** bit flag for @a DataType: binary representation is hex converted to decimal and interpreted as 2 digits
|
/** bit flag for @a DataType: binary representation is hex converted to decimal and interpreted as 2 digits
|
||||||
|
|||||||
+30
-1
@@ -515,6 +515,17 @@ void SerialDevice::checkDevice() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#ifndef TCP_KEEPCNT
|
||||||
|
#define TCP_KEEPCNT 8
|
||||||
|
#endif
|
||||||
|
#ifndef TCP_KEEPINTVL
|
||||||
|
#define TCP_KEEPINTVL 150
|
||||||
|
#endif
|
||||||
|
#ifndef TCP_KEEPIDLE
|
||||||
|
#define TCP_KEEPIDLE 14400
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
result_t NetworkDevice::open() {
|
result_t NetworkDevice::open() {
|
||||||
result_t result = Device::open();
|
result_t result = Device::open();
|
||||||
@@ -535,6 +546,12 @@ result_t NetworkDevice::open() {
|
|||||||
ret = setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<void*>(&value), sizeof(value));
|
ret = setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<void*>(&value), sizeof(value));
|
||||||
value = 1;
|
value = 1;
|
||||||
setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<void*>(&value), sizeof(value));
|
setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<void*>(&value), sizeof(value));
|
||||||
|
value = 3; // send keepalive after 3 seconds of silence
|
||||||
|
setsockopt(m_fd, IPPROTO_TCP, TCP_KEEPIDLE, reinterpret_cast<void*>(&value), sizeof(value));
|
||||||
|
value = 2; // send keepalive in interval of 2 seconds
|
||||||
|
setsockopt(m_fd, IPPROTO_TCP, TCP_KEEPINTVL, reinterpret_cast<void*>(&value), sizeof(value));
|
||||||
|
value = 2; // drop connection after 2 failed keep alive sends
|
||||||
|
setsockopt(m_fd, IPPROTO_TCP, TCP_KEEPCNT, reinterpret_cast<void*>(&value), sizeof(value));
|
||||||
}
|
}
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
ret = connect(m_fd, (struct sockaddr*)&m_address, sizeof(m_address));
|
ret = connect(m_fd, (struct sockaddr*)&m_address, sizeof(m_address));
|
||||||
@@ -548,13 +565,25 @@ result_t NetworkDevice::open() {
|
|||||||
}
|
}
|
||||||
int cnt;
|
int cnt;
|
||||||
symbol_t buf[MTU];
|
symbol_t buf[MTU];
|
||||||
while (ioctl(m_fd, FIONREAD, &cnt) >= 0 && cnt > 1) {
|
int ioerr;
|
||||||
|
while ((ioerr=ioctl(m_fd, FIONREAD, &cnt)) >= 0 && cnt > 1) {
|
||||||
// skip buffered input
|
// skip buffered input
|
||||||
ssize_t read = ::read(m_fd, &buf, MTU);
|
ssize_t read = ::read(m_fd, &buf, MTU);
|
||||||
if (read <= 0) {
|
if (read <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ioerr < 0) {
|
||||||
|
close();
|
||||||
|
return RESULT_ERR_GENERIC_IO;
|
||||||
|
}
|
||||||
|
if (m_bufSize == 0) {
|
||||||
|
m_bufSize = MAX_LEN+1;
|
||||||
|
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
|
||||||
|
if (!m_buffer) {
|
||||||
|
m_bufSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_bufLen = 0;
|
m_bufLen = 0;
|
||||||
if (m_initialSend && !write(ESC)) {
|
if (m_initialSend && !write(ESC)) {
|
||||||
return RESULT_ERR_SEND;
|
return RESULT_ERR_SEND;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ void RotateFile::write(const unsigned char* value, const size_t size, const bool
|
|||||||
fwrite(value, (streamsize)size, 1, m_stream);
|
fwrite(value, (streamsize)size, 1, m_stream);
|
||||||
m_fileSize += size;
|
m_fileSize += size;
|
||||||
m_flushSize += size;
|
m_flushSize += size;
|
||||||
if (m_flushSize > 16) {
|
if (m_flushSize >= m_flushBuffer) {
|
||||||
fflush(m_stream);
|
fflush(m_stream);
|
||||||
m_flushSize = 0;
|
m_flushSize = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ class RotateFile {
|
|||||||
* @param fileName the name of the file write to.
|
* @param fileName the name of the file write to.
|
||||||
* @param maxSize the maximum size of the file to write to.
|
* @param maxSize the maximum size of the file to write to.
|
||||||
* @param textMode whether to write each byte with prefixed timestamp and direction as text.
|
* @param textMode whether to write each byte with prefixed timestamp and direction as text.
|
||||||
|
* @param flushBuffer the size of the flush buffer.
|
||||||
*/
|
*/
|
||||||
RotateFile(const string fileName, const unsigned int maxSize, const bool textMode = false)
|
RotateFile(const string fileName, const unsigned int maxSize, const bool textMode = false, const unsigned int flushBuffer = 16)
|
||||||
: m_enabled(false), m_fileName(fileName), m_maxSize(maxSize), m_textMode(textMode), m_stream(), m_fileSize(0),
|
: m_enabled(false), m_fileName(fileName), m_maxSize(maxSize), m_textMode(textMode), m_stream(), m_fileSize(0),
|
||||||
m_flushSize(0) {}
|
m_flushSize(0), m_flushBuffer(flushBuffer) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor.
|
* Destructor.
|
||||||
@@ -98,6 +99,9 @@ class RotateFile {
|
|||||||
|
|
||||||
/** the number of bytes written to @a m_file since the last flush. */
|
/** the number of bytes written to @a m_file since the last flush. */
|
||||||
uint64_t m_flushSize;
|
uint64_t m_flushSize;
|
||||||
|
|
||||||
|
/** the size of the flush buffer. */
|
||||||
|
const unsigned int m_flushBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ebusd
|
} // namespace ebusd
|
||||||
|
|||||||
Reference in New Issue
Block a user