extra layer for device, more abstraction
This commit is contained in:
+5
-4
@@ -1019,13 +1019,14 @@ int main(int argc, char* argv[], char* envp[]) {
|
|||||||
signal(SIGINT, signalHandler);
|
signal(SIGINT, signalHandler);
|
||||||
signal(SIGTERM, signalHandler);
|
signal(SIGTERM, signalHandler);
|
||||||
|
|
||||||
logNotice(lf_main, PACKAGE_STRING "." REVISION " started%s%s on%s device %s",
|
ostringstream ostream;
|
||||||
device->isReadOnly() ? " read only" : "",
|
device->formatInfo(&ostream, false, false, true);
|
||||||
|
string deviceInfoStr = ostream.str();
|
||||||
|
logNotice(lf_main, PACKAGE_STRING "." REVISION " started%s on device: %s",
|
||||||
s_opt.scanConfig ? s_opt.initialScan == ESC ? " with auto scan"
|
s_opt.scanConfig ? s_opt.initialScan == ESC ? " with auto scan"
|
||||||
: s_opt.initialScan == BROADCAST ? " with broadcast scan" : s_opt.initialScan == SYN ? " with full scan"
|
: s_opt.initialScan == BROADCAST ? " with broadcast scan" : s_opt.initialScan == SYN ? " with full scan"
|
||||||
: " with single scan" : "",
|
: " with single scan" : "",
|
||||||
device->isEnhancedProto() ? " enhanced" : "",
|
deviceInfoStr.c_str());
|
||||||
device->getName());
|
|
||||||
|
|
||||||
// load configuration files
|
// load configuration files
|
||||||
s_scanHelper->loadConfigFiles(!s_opt.scanConfig);
|
s_scanHelper->loadConfigFiles(!s_opt.scanConfig);
|
||||||
|
|||||||
+3
-31
@@ -372,12 +372,7 @@ void MainLoop::run() {
|
|||||||
<< ",\"a\":\"other\""
|
<< ",\"a\":\"other\""
|
||||||
#endif
|
#endif
|
||||||
<< ",\"u\":" << (now-start);
|
<< ",\"u\":" << (now-start);
|
||||||
if (m_device->isEnhancedProto()) {
|
m_device->formatInfo(&ostr, false, true, true);
|
||||||
string ver = m_device->getEnhancedVersion();
|
|
||||||
if (!ver.empty()) {
|
|
||||||
ostr << ",\"dv\":\"" << ver << "\"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_reconnectCount) {
|
if (m_reconnectCount) {
|
||||||
ostr << ",\"rc\":" << m_reconnectCount;
|
ostr << ",\"rc\":" << m_reconnectCount;
|
||||||
}
|
}
|
||||||
@@ -1944,31 +1939,8 @@ result_t MainLoop::executeInfo(const vector<string>& args, const string& user, o
|
|||||||
if (!m_updateCheck.empty()) {
|
if (!m_updateCheck.empty()) {
|
||||||
*ostream << "update check: " << m_updateCheck << "\n";
|
*ostream << "update check: " << m_updateCheck << "\n";
|
||||||
}
|
}
|
||||||
*ostream << "device: " << m_device->getName();
|
*ostream << "device: ";
|
||||||
if (m_device->isEnhancedProto()) {
|
m_device->formatInfo(ostream, verbose);
|
||||||
*ostream << ", enhanced";
|
|
||||||
}
|
|
||||||
if (m_device->isReadOnly()) {
|
|
||||||
*ostream << ", readonly";
|
|
||||||
}
|
|
||||||
if (!m_device->isValid()) {
|
|
||||||
*ostream << ", invalid";
|
|
||||||
}
|
|
||||||
bool infoAdded = false;
|
|
||||||
if (verbose) {
|
|
||||||
string info = m_device->getEnhancedInfos();
|
|
||||||
if (!info.empty()) {
|
|
||||||
*ostream << ", " << info;
|
|
||||||
infoAdded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!infoAdded) {
|
|
||||||
string info = m_device->getEnhancedVersion();
|
|
||||||
if (!info.empty()) {
|
|
||||||
*ostream << ", firmware " << info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ostream << "\n";
|
*ostream << "\n";
|
||||||
if (!user.empty()) {
|
if (!user.empty()) {
|
||||||
*ostream << "user: " << user << "\n";
|
*ostream << "user: " << user << "\n";
|
||||||
|
|||||||
@@ -952,7 +952,7 @@ void MqttHandler::run() {
|
|||||||
publishDefinition(m_replacers, "def_global_uptime-", uptimeTopic, "global", "uptime", "def_global-");
|
publishDefinition(m_replacers, "def_global_uptime-", uptimeTopic, "global", "uptime", "def_global-");
|
||||||
publishDefinition(m_replacers, "def_global_updatecheck-", m_globalTopic.get("", "updatecheck"), "global",
|
publishDefinition(m_replacers, "def_global_updatecheck-", m_globalTopic.get("", "updatecheck"), "global",
|
||||||
"updatecheck", "def_global-");
|
"updatecheck", "def_global-");
|
||||||
if (m_busHandler->getDevice()->supportsEnhancedInfos()) {
|
if (m_busHandler->getDevice()->supportsUpdateCheck()) {
|
||||||
publishDefinition(m_replacers, "def_global_updatecheck_device-", m_globalTopic.get("", "updatecheck"),
|
publishDefinition(m_replacers, "def_global_updatecheck_device-", m_globalTopic.get("", "updatecheck"),
|
||||||
"global", "updatecheck_device", "");
|
"global", "updatecheck_device", "");
|
||||||
}
|
}
|
||||||
|
|||||||
+92
-40
@@ -75,25 +75,8 @@ namespace ebusd {
|
|||||||
#define ENH_BYTE2 ((uint8_t)0x80)
|
#define ENH_BYTE2 ((uint8_t)0x80)
|
||||||
#define makeEnhancedSequence(cmd, data) {(uint8_t)(ENH_BYTE1 | ((cmd)<<2) | (((data)&0xc0)>>6)), (uint8_t)(ENH_BYTE2 | ((data)&0x3f))}
|
#define makeEnhancedSequence(cmd, data) {(uint8_t)(ENH_BYTE1 | ((cmd)<<2) | (((data)&0xc0)>>6)), (uint8_t)(ENH_BYTE2 | ((data)&0x3f))}
|
||||||
|
|
||||||
Device::Device(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend,
|
Device::Device(const char* name, bool readOnly, bool initialSend)
|
||||||
bool enhancedProto)
|
: m_name(name), m_readOnly(readOnly), m_initialSend(initialSend), m_listener(nullptr) {
|
||||||
: m_name(name), m_checkDevice(checkDevice),
|
|
||||||
m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency), m_readOnly(readOnly),
|
|
||||||
m_initialSend(initialSend), m_enhancedProto(enhancedProto), m_fd(-1), m_resetRequested(false),
|
|
||||||
m_listener(nullptr), m_arbitrationMaster(SYN),
|
|
||||||
m_arbitrationCheck(0), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0),
|
|
||||||
m_extraFatures(0), m_infoId(0xff), m_infoReqTime(0), m_infoLen(0), m_infoPos(0) {
|
|
||||||
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
|
|
||||||
if (!m_buffer) {
|
|
||||||
m_bufSize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Device::~Device() {
|
|
||||||
close();
|
|
||||||
if (m_buffer) {
|
|
||||||
free(m_buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Device* Device::create(const char* name, unsigned int extraLatency, bool checkDevice, bool readOnly, bool initialSend) {
|
Device* Device::create(const char* name, unsigned int extraLatency, bool checkDevice, bool readOnly, bool initialSend) {
|
||||||
@@ -138,14 +121,82 @@ Device* Device::create(const char* name, unsigned int extraLatency, bool checkDe
|
|||||||
return new SerialDevice(name, checkDevice, extraLatency, readOnly, initialSend, enhanced, highSpeed);
|
return new SerialDevice(name, checkDevice, extraLatency, readOnly, initialSend, enhanced, highSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::open() {
|
result_t Device::afterOpen() {
|
||||||
|
if (m_initialSend && !send(ESC)) {
|
||||||
|
return RESULT_ERR_SEND;
|
||||||
|
}
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FileDevice::FileDevice(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend,
|
||||||
|
bool enhancedProto)
|
||||||
|
: Device(name, readOnly, initialSend),
|
||||||
|
m_checkDevice(checkDevice),
|
||||||
|
m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency),
|
||||||
|
m_enhancedProto(enhancedProto), m_fd(-1), m_resetRequested(false),
|
||||||
|
m_arbitrationMaster(SYN),
|
||||||
|
m_arbitrationCheck(0), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0),
|
||||||
|
m_extraFatures(0), m_infoId(0xff), m_infoReqTime(0), m_infoLen(0), m_infoPos(0) {
|
||||||
|
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
|
||||||
|
if (!m_buffer) {
|
||||||
|
m_bufSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDevice::~FileDevice() {
|
||||||
|
close();
|
||||||
|
if (m_buffer) {
|
||||||
|
free(m_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileDevice::formatInfo(ostringstream* ostream, bool verbose, bool asJson, bool noWait) {
|
||||||
|
if (asJson) {
|
||||||
|
if (m_enhancedProto) {
|
||||||
|
string ver = getEnhancedVersion();
|
||||||
|
if (!ver.empty()) {
|
||||||
|
*ostream << ",\"dv\":\"" << ver << "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*ostream << m_name;
|
||||||
|
string info = getEnhancedProtoInfo();
|
||||||
|
if (!info.empty()) {
|
||||||
|
*ostream << ", " << info;
|
||||||
|
}
|
||||||
|
if (isReadOnly()) {
|
||||||
|
*ostream << ", readonly";
|
||||||
|
}
|
||||||
|
if (noWait) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isValid()) {
|
||||||
|
*ostream << ", invalid";
|
||||||
|
}
|
||||||
|
bool infoAdded = false;
|
||||||
|
if (verbose) {
|
||||||
|
info = getEnhancedInfos();
|
||||||
|
if (!info.empty()) {
|
||||||
|
*ostream << ", " << info;
|
||||||
|
infoAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!infoAdded) {
|
||||||
|
string ver = getEnhancedVersion();
|
||||||
|
if (!ver.empty()) {
|
||||||
|
*ostream << ", firmware " << ver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result_t FileDevice::open() {
|
||||||
close();
|
close();
|
||||||
return m_bufSize == 0 ? RESULT_ERR_DEVICE : RESULT_OK;
|
return m_bufSize == 0 ? RESULT_ERR_DEVICE : RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::afterOpen() {
|
result_t FileDevice::afterOpen() {
|
||||||
m_bufLen = 0;
|
|
||||||
m_extraFatures = 0;
|
|
||||||
if (m_enhancedProto) {
|
if (m_enhancedProto) {
|
||||||
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INIT, 0x01); // extra feature: info
|
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INIT, 0x01); // extra feature: info
|
||||||
#ifdef DEBUG_RAW_TRAFFIC
|
#ifdef DEBUG_RAW_TRAFFIC
|
||||||
@@ -165,15 +216,16 @@ result_t Device::afterOpen() {
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::close() {
|
void FileDevice::close() {
|
||||||
if (m_fd != -1) {
|
if (m_fd != -1) {
|
||||||
::close(m_fd);
|
::close(m_fd);
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
}
|
}
|
||||||
m_bufLen = 0; // flush read buffer
|
m_bufLen = 0; // flush read buffer
|
||||||
|
m_extraFatures = 0; // reset state
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::isValid() {
|
bool FileDevice::isValid() {
|
||||||
if (m_fd == -1) {
|
if (m_fd == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -183,7 +235,7 @@ bool Device::isValid() {
|
|||||||
return m_fd != -1;
|
return m_fd != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::requestEnhancedInfo(symbol_t infoId) {
|
result_t FileDevice::requestEnhancedInfo(symbol_t infoId) {
|
||||||
if (!m_enhancedProto || m_extraFatures == 0) {
|
if (!m_enhancedProto || m_extraFatures == 0) {
|
||||||
return RESULT_ERR_INVALID_ARG;
|
return RESULT_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
@@ -212,7 +264,7 @@ result_t Device::requestEnhancedInfo(symbol_t infoId) {
|
|||||||
return sendEnhancedInfoRequest(infoId);
|
return sendEnhancedInfoRequest(infoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::sendEnhancedInfoRequest(symbol_t infoId) {
|
result_t FileDevice::sendEnhancedInfoRequest(symbol_t infoId) {
|
||||||
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INFO, infoId);
|
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INFO, infoId);
|
||||||
#ifdef DEBUG_RAW_TRAFFIC
|
#ifdef DEBUG_RAW_TRAFFIC
|
||||||
fprintf(stdout, "raw enhanced > %2.2x %2.2x\n", buf[0], buf[1]);
|
fprintf(stdout, "raw enhanced > %2.2x %2.2x\n", buf[0], buf[1]);
|
||||||
@@ -227,7 +279,7 @@ result_t Device::sendEnhancedInfoRequest(symbol_t infoId) {
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Device::getEnhancedInfos() {
|
string FileDevice::getEnhancedInfos() {
|
||||||
if (!m_enhancedProto || m_extraFatures == 0) {
|
if (!m_enhancedProto || m_extraFatures == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -276,7 +328,7 @@ string Device::getEnhancedInfos() {
|
|||||||
+ m_enhInfoBusVoltage;
|
+ m_enhInfoBusVoltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::send(symbol_t value) {
|
result_t FileDevice::send(symbol_t value) {
|
||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
return RESULT_ERR_DEVICE;
|
return RESULT_ERR_DEVICE;
|
||||||
}
|
}
|
||||||
@@ -296,7 +348,7 @@ result_t Device::send(symbol_t value) {
|
|||||||
#define ENHANCED_COMPLETE_WAIT_DURATION 10
|
#define ENHANCED_COMPLETE_WAIT_DURATION 10
|
||||||
|
|
||||||
|
|
||||||
bool Device::cancelRunningArbitration(ArbitrationState* arbitrationState) {
|
bool FileDevice::cancelRunningArbitration(ArbitrationState* arbitrationState) {
|
||||||
if (m_enhancedProto && m_arbitrationMaster != SYN) {
|
if (m_enhancedProto && m_arbitrationMaster != SYN) {
|
||||||
*arbitrationState = as_error;
|
*arbitrationState = as_error;
|
||||||
m_arbitrationMaster = SYN;
|
m_arbitrationMaster = SYN;
|
||||||
@@ -313,7 +365,7 @@ bool Device::cancelRunningArbitration(ArbitrationState* arbitrationState) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) {
|
result_t FileDevice::recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) {
|
||||||
if (m_arbitrationMaster != SYN) {
|
if (m_arbitrationMaster != SYN) {
|
||||||
*arbitrationState = as_running;
|
*arbitrationState = as_running;
|
||||||
}
|
}
|
||||||
@@ -424,7 +476,7 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t Device::startArbitration(symbol_t masterAddress) {
|
result_t FileDevice::startArbitration(symbol_t masterAddress) {
|
||||||
if (m_arbitrationCheck) {
|
if (m_arbitrationCheck) {
|
||||||
if (masterAddress != SYN) {
|
if (masterAddress != SYN) {
|
||||||
return RESULT_ERR_ARB_RUNNING; // should not occur
|
return RESULT_ERR_ARB_RUNNING; // should not occur
|
||||||
@@ -453,7 +505,7 @@ result_t Device::startArbitration(symbol_t masterAddress) {
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::write(symbol_t value, bool startArbitration) {
|
bool FileDevice::write(symbol_t value, bool startArbitration) {
|
||||||
if (m_enhancedProto) {
|
if (m_enhancedProto) {
|
||||||
symbol_t buf[2] = makeEnhancedSequence(startArbitration ? ENH_REQ_START : ENH_REQ_SEND, value);
|
symbol_t buf[2] = makeEnhancedSequence(startArbitration ? ENH_REQ_START : ENH_REQ_SEND, value);
|
||||||
#ifdef DEBUG_RAW_TRAFFIC
|
#ifdef DEBUG_RAW_TRAFFIC
|
||||||
@@ -473,7 +525,7 @@ bool Device::write(symbol_t value, bool startArbitration) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::available() {
|
bool FileDevice::available() {
|
||||||
if (m_bufLen <= 0) {
|
if (m_bufLen <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -542,7 +594,7 @@ bool Device::available() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrationState, bool* incomplete) {
|
bool FileDevice::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrationState, bool* incomplete) {
|
||||||
if (!isAvailable) {
|
if (!isAvailable) {
|
||||||
if (m_bufLen > 0 && m_bufPos != 0) {
|
if (m_bufLen > 0 && m_bufPos != 0) {
|
||||||
if (m_bufLen > m_bufSize / 2) {
|
if (m_bufLen > m_bufSize / 2) {
|
||||||
@@ -609,7 +661,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
|||||||
return handleEnhancedBufferedData(value, arbitrationState);
|
return handleEnhancedBufferedData(value, arbitrationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* arbitrationState) {
|
bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* arbitrationState) {
|
||||||
while (m_bufLen > 0) {
|
while (m_bufLen > 0) {
|
||||||
symbol_t ch = m_buffer[m_bufPos];
|
symbol_t ch = m_buffer[m_bufPos];
|
||||||
if (!(ch&ENH_BYTE_FLAG)) {
|
if (!(ch&ENH_BYTE_FLAG)) {
|
||||||
@@ -840,7 +892,7 @@ bool Device::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* arbit
|
|||||||
|
|
||||||
|
|
||||||
result_t SerialDevice::open() {
|
result_t SerialDevice::open() {
|
||||||
result_t result = Device::open();
|
result_t result = FileDevice::open();
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -857,7 +909,7 @@ result_t SerialDevice::open() {
|
|||||||
return RESULT_ERR_NOTFOUND;
|
return RESULT_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flock(m_fd, LOCK_EX|LOCK_NB)) {
|
if (flock(m_fd, LOCK_EX|LOCK_NB) != 0) {
|
||||||
close();
|
close();
|
||||||
return RESULT_ERR_DEVICE;
|
return RESULT_ERR_DEVICE;
|
||||||
}
|
}
|
||||||
@@ -925,7 +977,7 @@ void SerialDevice::close() {
|
|||||||
// restore previous settings of the device
|
// restore previous settings of the device
|
||||||
tcsetattr(m_fd, TCSANOW, &m_oldSettings);
|
tcsetattr(m_fd, TCSANOW, &m_oldSettings);
|
||||||
}
|
}
|
||||||
Device::close();
|
FileDevice::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialDevice::checkDevice() {
|
void SerialDevice::checkDevice() {
|
||||||
@@ -936,7 +988,7 @@ void SerialDevice::checkDevice() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result_t NetworkDevice::open() {
|
result_t NetworkDevice::open() {
|
||||||
result_t result = Device::open();
|
result_t result = FileDevice::open();
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+127
-50
@@ -99,20 +99,16 @@ class Device {
|
|||||||
/**
|
/**
|
||||||
* Construct a new instance.
|
* Construct a new instance.
|
||||||
* @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network).
|
* @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network).
|
||||||
* @param checkDevice whether to regularly check the device availability.
|
|
||||||
* @param latency the bus transfer latency in milliseconds.
|
|
||||||
* @param readOnly whether to allow read access to the device only.
|
* @param readOnly whether to allow read access to the device only.
|
||||||
* @param initialSend whether to send an initial @a ESC symbol in @a open().
|
* @param initialSend whether to send an initial @a ESC symbol in @a open().
|
||||||
* @param enhancedProto whether to use the ebusd enhanced protocol.
|
|
||||||
*/
|
*/
|
||||||
Device(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend,
|
Device(const char* name, bool readOnly, bool initialSend);
|
||||||
bool enhancedProto = false);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Destructor.
|
* Destructor.
|
||||||
*/
|
*/
|
||||||
virtual ~Device();
|
virtual ~Device() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method for creating a new instance.
|
* Factory method for creating a new instance.
|
||||||
@@ -128,34 +124,61 @@ class Device {
|
|||||||
bool readOnly = false, bool initialSend = false);
|
bool readOnly = false, bool initialSend = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the transfer latency of this device.
|
* Get the device name.
|
||||||
* @return the transfer latency in milliseconds.
|
* @return the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network).
|
||||||
*/
|
*/
|
||||||
virtual unsigned int getLatency() const { return m_latency; }
|
const char* getName() const { return m_name; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether to allow read access to the device only.
|
||||||
|
* @return whether to allow read access to the device only.
|
||||||
|
*/
|
||||||
|
bool isReadOnly() const { return m_readOnly; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the @a DeviceListener.
|
||||||
|
* @param listener the @a DeviceListener.
|
||||||
|
*/
|
||||||
|
void setListener(DeviceListener* listener) { m_listener = listener; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format device infos in plain text or JSON format.
|
||||||
|
* @param output the @a ostringstream to append the infos to.
|
||||||
|
* @param verbose whether to add verbose infos.
|
||||||
|
* @param asJson whether to format as JSON rather than plain text.
|
||||||
|
* @param noWait true to not wait for any response asynchronously and return immediately.
|
||||||
|
*/
|
||||||
|
virtual void formatInfo(ostringstream* output, bool verbose, bool asJson = false, bool noWait = false) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the file descriptor.
|
* Open the file descriptor.
|
||||||
* @return the @a result_t code.
|
* @return the @a result_t code.
|
||||||
*/
|
*/
|
||||||
virtual result_t open();
|
virtual result_t open() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has to be called by subclasses upon successful opening the device as last action in open().
|
* Has to be called by subclasses upon successful opening the device as last action in open().
|
||||||
* @return the @a result_t code.
|
* @return the @a result_t code.
|
||||||
*/
|
*/
|
||||||
result_t afterOpen();
|
virtual result_t afterOpen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the file descriptor if opened.
|
* Close the file descriptor if opened.
|
||||||
*/
|
*/
|
||||||
virtual void close();
|
virtual void close() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the device is opened and available.
|
||||||
|
* @return whether the device is opened and available.
|
||||||
|
*/
|
||||||
|
virtual bool isValid() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a single byte to the device.
|
* Write a single byte to the device.
|
||||||
* @param value the byte value to write.
|
* @param value the byte value to write.
|
||||||
* @return the @a result_t code.
|
* @return the @a result_t code.
|
||||||
*/
|
*/
|
||||||
result_t send(symbol_t value);
|
virtual result_t send(symbol_t value) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a single byte from the device.
|
* Read a single byte from the device.
|
||||||
@@ -165,7 +188,7 @@ class Device {
|
|||||||
* @a as_won, the received byte is the master address that was successfully arbitrated with.
|
* @a as_won, the received byte is the master address that was successfully arbitrated with.
|
||||||
* @return the result_t code.
|
* @return the result_t code.
|
||||||
*/
|
*/
|
||||||
result_t recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState);
|
virtual result_t recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the arbitration with the specified master address. A subsequent request while an arbitration is currently in
|
* Start the arbitration with the specified master address. A subsequent request while an arbitration is currently in
|
||||||
@@ -173,31 +196,89 @@ class Device {
|
|||||||
* @param masterAddress the master address, or @a SYN to cancel a previous arbitration request.
|
* @param masterAddress the master address, or @a SYN to cancel a previous arbitration request.
|
||||||
* @return the result_t code.
|
* @return the result_t code.
|
||||||
*/
|
*/
|
||||||
result_t startArbitration(symbol_t masterAddress);
|
virtual result_t startArbitration(symbol_t masterAddress) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the device is currently in arbitration.
|
* Return whether the device is currently in arbitration.
|
||||||
* @return true when the device is currently in arbitration.
|
* @return true when the device is currently in arbitration.
|
||||||
*/
|
*/
|
||||||
bool isArbitrating() const { return m_arbitrationMaster != SYN; }
|
virtual bool isArbitrating() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the device name.
|
* @return whether the device supports checking for version updates.
|
||||||
* @return the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network).
|
|
||||||
*/
|
*/
|
||||||
const char* getName() { return m_name; }
|
virtual bool supportsUpdateCheck() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). */
|
||||||
|
const char* m_name;
|
||||||
|
|
||||||
|
/** whether to allow read access to the device only. */
|
||||||
|
const bool m_readOnly;
|
||||||
|
|
||||||
|
/** whether to send an initial @a ESC symbol in @a open(). */
|
||||||
|
const bool m_initialSend;
|
||||||
|
|
||||||
|
/** the @a DeviceListener, or nullptr. */
|
||||||
|
DeviceListener* m_listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The common base class for devices using a file descriptor.
|
||||||
|
*/
|
||||||
|
class FileDevice : public Device {
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Construct a new instance.
|
||||||
|
* @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network).
|
||||||
|
* @param checkDevice whether to regularly check the device availability.
|
||||||
|
* @param latency the bus transfer latency in milliseconds.
|
||||||
|
* @param readOnly whether to allow read access to the device only.
|
||||||
|
* @param initialSend whether to send an initial @a ESC symbol in @a open().
|
||||||
|
* @param enhancedProto whether to use the ebusd enhanced protocol.
|
||||||
|
*/
|
||||||
|
FileDevice(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend,
|
||||||
|
bool enhancedProto = false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
virtual ~FileDevice();
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
void formatInfo(ostringstream* output, bool verbose, bool asJson = false, bool noWait = false) override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
result_t open() override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
result_t afterOpen() override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
void close() override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
bool isValid() override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
result_t send(symbol_t value) override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
result_t recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
result_t startArbitration(symbol_t masterAddress) override;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
bool isArbitrating() const override { return m_arbitrationMaster != SYN; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the device is opened and available.
|
* Get the transfer latency of this device.
|
||||||
* @return whether the device is opened and available.
|
* @return the transfer latency in milliseconds.
|
||||||
*/
|
*/
|
||||||
bool isValid();
|
virtual unsigned int getLatency() const { return m_latency; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether to allow read access to the device only.
|
|
||||||
* @return whether to allow read access to the device only.
|
|
||||||
*/
|
|
||||||
bool isReadOnly() const { return m_readOnly; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the device supports the ebusd enhanced protocol.
|
* Return whether the device supports the ebusd enhanced protocol.
|
||||||
@@ -205,17 +286,20 @@ class Device {
|
|||||||
*/
|
*/
|
||||||
bool isEnhancedProto() const { return m_enhancedProto; }
|
bool isEnhancedProto() const { return m_enhancedProto; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info about enhanced protocol support as string.
|
||||||
|
* @return a @a string describing level of enhanced protocol support, or the empty string.
|
||||||
|
*/
|
||||||
|
virtual string getEnhancedProtoInfo() const { return m_enhancedProto ? "enhanced" : ""; }
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
bool supportsUpdateCheck() const override { return m_enhancedProto && m_extraFatures & 0x01; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether the device supports the ebusd enhanced protocol and supports querying extra infos.
|
* @return whether the device supports the ebusd enhanced protocol and supports querying extra infos.
|
||||||
*/
|
*/
|
||||||
bool supportsEnhancedInfos() const { return m_enhancedProto && m_extraFatures & 0x01; }
|
bool supportsEnhancedInfos() const { return m_enhancedProto && m_extraFatures & 0x01; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the @a DeviceListener.
|
|
||||||
* @param listener the @a DeviceListener.
|
|
||||||
*/
|
|
||||||
void setListener(DeviceListener* listener) { m_listener = listener; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for a running extra infos request, wait for it to complete,
|
* Check for a running extra infos request, wait for it to complete,
|
||||||
* and then send a new request for extra infos to enhanced device.
|
* and then send a new request for extra infos to enhanced device.
|
||||||
@@ -281,21 +365,12 @@ class Device {
|
|||||||
virtual bool read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrationState = nullptr,
|
virtual bool read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrationState = nullptr,
|
||||||
bool* incomplete = nullptr);
|
bool* incomplete = nullptr);
|
||||||
|
|
||||||
/** the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). */
|
|
||||||
const char* m_name;
|
|
||||||
|
|
||||||
/** whether to regularly check the device availability. */
|
/** whether to regularly check the device availability. */
|
||||||
const bool m_checkDevice;
|
const bool m_checkDevice;
|
||||||
|
|
||||||
/** the bus transfer latency in milliseconds. */
|
/** the bus transfer latency in milliseconds. */
|
||||||
const unsigned int m_latency;
|
const unsigned int m_latency;
|
||||||
|
|
||||||
/** whether to allow read access to the device only. */
|
|
||||||
const bool m_readOnly;
|
|
||||||
|
|
||||||
/** whether to send an initial @a ESC symbol in @a open(). */
|
|
||||||
const bool m_initialSend;
|
|
||||||
|
|
||||||
/** whether the device supports the ebusd enhanced protocol. */
|
/** whether the device supports the ebusd enhanced protocol. */
|
||||||
const bool m_enhancedProto;
|
const bool m_enhancedProto;
|
||||||
|
|
||||||
@@ -314,9 +389,6 @@ class Device {
|
|||||||
*/
|
*/
|
||||||
bool handleEnhancedBufferedData(symbol_t* value, ArbitrationState* arbitrationState);
|
bool handleEnhancedBufferedData(symbol_t* value, ArbitrationState* arbitrationState);
|
||||||
|
|
||||||
/** the @a DeviceListener, or nullptr. */
|
|
||||||
DeviceListener* m_listener;
|
|
||||||
|
|
||||||
/** the arbitration master address to send when in arbitration, or @a SYN. */
|
/** the arbitration master address to send when in arbitration, or @a SYN. */
|
||||||
symbol_t m_arbitrationMaster;
|
symbol_t m_arbitrationMaster;
|
||||||
|
|
||||||
@@ -371,7 +443,7 @@ class Device {
|
|||||||
/**
|
/**
|
||||||
* The @a Device for directly connected serial interfaces (tty).
|
* The @a Device for directly connected serial interfaces (tty).
|
||||||
*/
|
*/
|
||||||
class SerialDevice : public Device {
|
class SerialDevice : public FileDevice {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Construct a new instance.
|
* Construct a new instance.
|
||||||
@@ -385,10 +457,15 @@ 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),
|
: FileDevice(name, checkDevice, extraLatency, readOnly, initialSend, enhancedProto),
|
||||||
m_enhancedHighSpeed(enhancedHighSpeed) {
|
m_enhancedHighSpeed(enhancedHighSpeed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
string getEnhancedProtoInfo() const override {
|
||||||
|
return m_enhancedProto ? (m_enhancedHighSpeed ? "enhanced high speed" : "enhanced") : "";
|
||||||
|
}
|
||||||
|
|
||||||
// @copydoc
|
// @copydoc
|
||||||
result_t open() override;
|
result_t open() override;
|
||||||
|
|
||||||
@@ -412,7 +489,7 @@ class SerialDevice : public Device {
|
|||||||
/**
|
/**
|
||||||
* The @a Device for remote network interfaces.
|
* The @a Device for remote network interfaces.
|
||||||
*/
|
*/
|
||||||
class NetworkDevice : public Device {
|
class NetworkDevice : public FileDevice {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Construct a new instance.
|
* Construct a new instance.
|
||||||
@@ -428,7 +505,7 @@ class NetworkDevice : public Device {
|
|||||||
*/
|
*/
|
||||||
NetworkDevice(const char* name, const char* hostOrIp, uint16_t port, unsigned int extraLatency, bool readOnly,
|
NetworkDevice(const char* name, const char* hostOrIp, uint16_t port, unsigned int extraLatency, bool readOnly,
|
||||||
bool initialSend, bool udp, bool enhancedProto = false)
|
bool initialSend, bool udp, bool enhancedProto = false)
|
||||||
: Device(name, true, NETWORK_LATENCY_MS+extraLatency, readOnly, initialSend, enhancedProto),
|
: FileDevice(name, true, NETWORK_LATENCY_MS+extraLatency, readOnly, initialSend, enhancedProto),
|
||||||
m_hostOrIp(hostOrIp), m_port(port), m_udp(udp) {}
|
m_hostOrIp(hostOrIp), m_port(port), m_udp(udp) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user