Merge pull request #19 from john30/master

-lrt needed
This commit is contained in:
Roland Jax
2014-12-07 18:46:16 +01:00
12 changed files with 301 additions and 85 deletions
Regular → Executable
View File
+16 -17
View File
@@ -47,9 +47,9 @@ BaseLoop::BaseLoop()
else else
L.log(bas, error, "error reading config files: %s", getResultCode(result)); L.log(bas, error, "error reading config files: %s", getResultCode(result));
/*L.log(bas, event, "commands DB: %d ", m_commands->sizeCmdDB()); L.log(bas, event, "commands DB: %d ", m_messages->size());
L.log(bas, event, " cycle DB: %d ", m_commands->sizeCycDB()); L.log(bas, event, " cycle DB: %d ", m_messages->size(true));
L.log(bas, event, " polling DB: %d ", m_commands->sizePollDB());*/ L.log(bas, event, " polling DB: %d ", m_messages->sizePoll());
m_ownAddress = A.getOptVal<int>("address") & 0xff; m_ownAddress = A.getOptVal<int>("address") & 0xff;
const bool answer = A.getOptVal<bool>("answer"); const bool answer = A.getOptVal<bool>("answer");
@@ -65,6 +65,12 @@ BaseLoop::BaseLoop()
const unsigned int busAcquireWaitTime = A.getOptVal<unsigned int>("acquiretimeout"); const unsigned int busAcquireWaitTime = A.getOptVal<unsigned int>("acquiretimeout");
const unsigned int slaveRecvTimeout = A.getOptVal<unsigned int>("recvtimeout"); const unsigned int slaveRecvTimeout = A.getOptVal<unsigned int>("recvtimeout");
const unsigned int lockCount = A.getOptVal<unsigned int>("lockcounter"); const unsigned int lockCount = A.getOptVal<unsigned int>("lockcounter");
int pollInterval = A.getOptVal<unsigned int>("pollinterval");
if (pollInterval <= 0) {
m_pollActive = false;
pollInterval = 0;
} else
m_pollActive = true;
// create Port // create Port
m_port = new Port(A.getOptVal<const char*>("device"), A.getOptVal<bool>("nodevicecheck"), logRaw, &BaseLoop::logRaw, dumpRaw, dumpRawFile, dumpRawMaxSize); m_port = new Port(A.getOptVal<const char*>("device"), A.getOptVal<bool>("nodevicecheck"), logRaw, &BaseLoop::logRaw, dumpRaw, dumpRawFile, dumpRawMaxSize);
@@ -75,10 +81,10 @@ BaseLoop::BaseLoop()
// create BusHandler // create BusHandler
m_busHandler = new BusHandler(m_port, m_messages, m_busHandler = new BusHandler(m_port, m_messages,
answer ? m_ownAddress : SYN, answer ? (m_ownAddress+5)&0xff : SYN, m_ownAddress, answer,
busLostRetries, failedSendRetries, busLostRetries, failedSendRetries,
busAcquireWaitTime, slaveRecvTimeout, busAcquireWaitTime, slaveRecvTimeout,
lockCount); lockCount, pollInterval);
m_busHandler->start("bushandler"); m_busHandler->start("bushandler");
// create network // create network
@@ -221,23 +227,16 @@ string BaseLoop::decodeMessage(const string& data)
if (message != NULL) { if (message != NULL) {
/*if (message->getPollPriority() > 0) if (m_pollActive == true && message->getPollPriority() > 0) {
// get polldata // get polldata
polldata = m_commands->getPollData(index); token = message->getLastValue();
if (polldata != "") { if (token.empty() == false) {
// decode data result << token;
Command* command = new Command(index, (*m_commands)[index], polldata);
// return result
result << command->calcResult(cmd);
delete command;
} else { } else {
result << "no data stored"; result << "no data stored";
} }
break; break;
}*/ }
SymbolString master; SymbolString master;
istringstream input; istringstream input;
+3
View File
@@ -96,6 +96,9 @@ private:
/** the own master address for sending on the bus. */ /** the own master address for sending on the bus. */
unsigned char m_ownAddress; unsigned char m_ownAddress;
/** whether polling the messages is active. */
bool m_pollActive;
/** the @a Port instance. */ /** the @a Port instance. */
Port* m_port; Port* m_port;
+50 -7
View File
@@ -58,20 +58,41 @@ const char* getStateCode(BusState state) {
} }
BusRequest::BusRequest(SymbolString& master, SymbolString& slave) result_t PollRequest::prepare(unsigned char ownMasterAddress)
: m_master(master), m_slave(slave), m_finished(false), m_result(RESULT_SYN) {
istringstream input;
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input);
if (result == RESULT_OK)
L.log(bus, event, " poll msg: %s", m_master.getDataStr().c_str());
return result;
}
void PollRequest::notify(result_t result)
{
ostringstream output;
if (result == RESULT_OK) {
result = m_message->decode(pt_slaveData, m_slave, output); // decode data
}
if (result != RESULT_OK)
L.log(bus, error, "poll %s failed: %s", m_message->getName().c_str(), getResultCode(result));
else
L.log(bus, event, "poll %s: %s", m_message->getName().c_str(), output.str().c_str());
}
ActiveBusRequest::ActiveBusRequest(SymbolString& master, SymbolString& slave)
: BusRequest(master, slave, false), m_finished(false), m_result(RESULT_SYN)
{ {
pthread_mutex_init(&m_mutex, NULL); pthread_mutex_init(&m_mutex, NULL);
pthread_cond_init(&m_cond, NULL); pthread_cond_init(&m_cond, NULL);
} }
BusRequest::~BusRequest() ActiveBusRequest::~ActiveBusRequest()
{ {
pthread_mutex_destroy(&m_mutex); pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_cond); pthread_cond_destroy(&m_cond);
} }
bool BusRequest::wait(int timeout) bool ActiveBusRequest::wait(int timeout)
{ {
m_finished = false; m_finished = false;
m_result = RESULT_SYN; m_result = RESULT_SYN;
@@ -93,7 +114,7 @@ bool BusRequest::wait(int timeout)
return result == 0; return result == 0;
} }
void BusRequest::notify(result_t result) void ActiveBusRequest::notify(result_t result)
{ {
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
@@ -108,7 +129,7 @@ void BusRequest::notify(result_t result)
result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave) result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave)
{ {
result_t result = RESULT_SYN; result_t result = RESULT_SYN;
BusRequest* request = new BusRequest(master, slave); ActiveBusRequest* request = new ActiveBusRequest(master, slave);
for (int sendRetries=m_failedSendRetries+1, lostRetries=m_busLostRetries+1; sendRetries>=0; sendRetries--) { for (int sendRetries=m_failedSendRetries+1, lostRetries=m_busLostRetries+1; sendRetries>=0; sendRetries--) {
m_requests.add(request); m_requests.add(request);
@@ -172,6 +193,26 @@ result_t BusHandler::handleSymbol()
setState(bs_ready, RESULT_ERR_TIMEOUT); // just to be sure an old BusRequest is cleaned up setState(bs_ready, RESULT_ERR_TIMEOUT); // just to be sure an old BusRequest is cleaned up
if (m_remainLockCount == 0) { if (m_remainLockCount == 0) {
m_request = m_requests.next(false); m_request = m_requests.next(false);
if (m_request == NULL && m_pollInterval > 0) { // check for poll/scan
time_t now;
time(&now);
if (m_lastPoll == 0 || difftime(now, m_lastPoll) > m_pollInterval) {
Message* message = m_messages->getNextPoll();
if (message != NULL) {
m_lastPoll = now;
PollRequest* request = new PollRequest(m_response, message);
result_t ret = request->prepare(m_ownMasterAddress);
if (ret != RESULT_OK) {
L.log(bus, error, " prepare poll message: %s", getResultCode(ret));
delete request;
}
else {
m_request = request;
m_requests.add(request);
}
}
}
}
if (m_request != NULL) { // initiate arbitration if (m_request != NULL) { // initiate arbitration
sendSymbol = m_request->m_master[0]; sendSymbol = m_request->m_master[0];
sending = true; sending = true;
@@ -435,8 +476,10 @@ result_t BusHandler::setState(BusState state, result_t result, bool firstRepetit
if (m_request != NULL) { if (m_request != NULL) {
if (state == bs_sendSyn || (result != RESULT_OK && firstRepetition == false)) { if (state == bs_sendSyn || (result != RESULT_OK && firstRepetition == false)) {
L.log(bus, debug, "notify request: %s", getResultCode(result)); L.log(bus, debug, "notify request: %s", getResultCode(result));
m_request->m_slave = m_response; // TODO nicer m_request->m_slave = SymbolString(m_response, false, false);
m_request->notify(result); m_request->notify(result);
if (m_request->m_isPoll == true)
delete m_request;
m_request = NULL; m_request = NULL;
} }
} }
+107 -33
View File
@@ -58,23 +58,10 @@ enum BusState {
bs_sendSyn, // send SYN for completed transfer [active set+get] bs_sendSyn, // send SYN for completed transfer [active set+get]
}; };
/** the possible combinations of participants in a single message exchange. */
enum MessageDirection {
md_thisToAll, // message from us to all (broadcast)
md_thisToMaster, // message from us to another master
md_thisToSlave, // message from us to another slave
md_otherToAll, // message from a master (other than us) to all (broadcast)
md_otherToMaster, // message from a master (other than us) to another master (other than us)
md_otherToSlave, // message from a master (other than us) to another slave (other than us)
md_otherToThisMaster, // message from a master (other than us) to us (as master)
md_otherToThisSlave, // message from a master (other than us) to us (as slave)
md_undefined,
};
class BusHandler; class BusHandler;
/** /**
* @brief Handles input from and output to the bus with respect to the ebus protocol. * @brief Generic request for sending to and receiving from the bus.
*/ */
class BusRequest class BusRequest
{ {
@@ -85,13 +72,97 @@ public:
* @brief Constructor. * @brief Constructor.
* @param master the master data @a SymbolString to send. * @param master the master data @a SymbolString to send.
* @param slave the slave data @a SymbolString received. * @param slave the slave data @a SymbolString received.
* @param isPoll whether this is a poll request.
*/ */
BusRequest(SymbolString& master, SymbolString& slave); BusRequest(SymbolString& master, SymbolString& slave, bool isPoll)
: m_master(master), m_slave(slave), m_isPoll(isPoll) {}
/** /**
* @brief Destructor. * @brief Destructor.
*/ */
virtual ~BusRequest(); virtual ~BusRequest() {}
/**
* @brief Notify the request of the specified result.
* @param result the result of the request.
*/
virtual void notify(result_t result) = 0;
protected:
/** the master data @a SymbolString to send. */
SymbolString& m_master;
/** the slave data @a SymbolString received. */
SymbolString& m_slave;
/** whether this is a poll request. */
bool m_isPoll;
};
/**
* @brief A poll @a BusRequest handled by @a BusHandler itself.
*/
class PollRequest : public BusRequest
{
friend class BusHandler;
public:
/**
* @brief Constructor.
* @param slave the slave data @a SymbolString received.
* @param message the associated @a Message.
*/
PollRequest(SymbolString& slave, Message* message)
: BusRequest(m_master, slave, true), m_message(message) {}
/**
* @brief Destructor.
*/
virtual ~PollRequest() {}
/**
* @brief Prepare the master data.
* @param masterAddress the master bus address to use.
* @return the result code.
*/
result_t prepare(unsigned char masterAddress);
// @copydoc
virtual void notify(result_t result);
private:
/** the master data @a SymbolString. */
SymbolString m_master;
/** the associated @a Message. */
Message* m_message;
};
/**
* @brief An active @a BusRequest that can be waited for.
*/
class ActiveBusRequest : public BusRequest
{
friend class BusHandler;
public:
/**
* @brief Constructor.
* @param master the master data @a SymbolString to send.
* @param slave the slave data @a SymbolString received.
*/
ActiveBusRequest(SymbolString& master, SymbolString& slave);
/**
* @brief Destructor.
*/
virtual ~ActiveBusRequest();
/** /**
* @brief Wait for notification. * @brief Wait for notification.
@@ -100,19 +171,11 @@ public:
*/ */
bool wait(int timeout); bool wait(int timeout);
/** // @copydoc
* @brief Notify all waiting threads. virtual void notify(result_t result);
*/
void notify(result_t result);
private: private:
/** the master data @a SymbolString to send. */
SymbolString& m_master;
/** the slave data @a SymbolString received. */
SymbolString& m_slave;
/** true once the request is finished. */ /** true once the request is finished. */
bool m_finished; bool m_finished;
@@ -139,24 +202,26 @@ public:
* @brief Construct a new instance. * @brief Construct a new instance.
* @param port the @a Port instance for accessing the bus. * @param port the @a Port instance for accessing the bus.
* @param messages the @a MessageMap instance with all known @a Message instances. * @param messages the @a MessageMap instance with all known @a Message instances.
* @param ownMasterAddress the own master address to react on master-master messages, or @a SYN to ignore. * @param ownAddress the own master address.
* @param ownSlaveAddress the own slave address to react on master-slave messages, or @a SYN to ignore. * @param answer whether to answer queries for the own master/slave address.
* @param busLostRetries the number of times a send is repeated due to lost arbitration. * @param busLostRetries the number of times a send is repeated due to lost arbitration.
* @param failedSendRetries the number of times a failed send is repeated (other than lost arbitration). * @param failedSendRetries the number of times a failed send is repeated (other than lost arbitration).
* @param slaveRecvTimeout the maximum time in microseconds an addressed slave is expected to acknowledge. * @param slaveRecvTimeout the maximum time in microseconds an addressed slave is expected to acknowledge.
* @param busAcquireTimeout the maximum time in microseconds for bus acquisition. * @param busAcquireTimeout the maximum time in microseconds for bus acquisition.
* @param lockCount the number of AUTO-SYN symbols before sending is allowed after lost arbitration. * @param lockCount the number of AUTO-SYN symbols before sending is allowed after lost arbitration.
* @param pollInterval the interval in seconds in which poll messages are cycled, or 0 if disabled.
*/ */
BusHandler(Port* port, MessageMap* messages, BusHandler(Port* port, MessageMap* messages,
const unsigned char ownMasterAddress, const unsigned char ownSlaveAddress, const unsigned char ownAddress, const bool answer,
const unsigned int busLostRetries, const unsigned int failedSendRetries, const unsigned int busLostRetries, const unsigned int failedSendRetries,
const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout, const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout,
const unsigned int lockCount) const unsigned int lockCount, const unsigned int pollInterval)
: m_port(port), m_messages(messages), : m_port(port), m_messages(messages),
m_ownMasterAddress(ownMasterAddress), m_ownSlaveAddress(ownSlaveAddress), m_ownMasterAddress(ownAddress), m_ownSlaveAddress((ownAddress+5)&0xff), m_answer(answer),
m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries), m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries),
m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout), m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout),
m_lockCount(lockCount), m_remainLockCount(lockCount), m_lockCount(lockCount), m_remainLockCount(lockCount),
m_pollInterval(pollInterval), m_lastPoll(0),
m_request(NULL), m_nextSendPos(0), m_request(NULL), m_nextSendPos(0),
m_state(bs_skip), m_repeat(false), m_state(bs_skip), m_repeat(false),
m_commandCrcValid(false), m_responseCrcValid(false) {} m_commandCrcValid(false), m_responseCrcValid(false) {}
@@ -213,12 +278,15 @@ private:
/** the @a MessageMap instance with all known @a Message instances. */ /** the @a MessageMap instance with all known @a Message instances. */
MessageMap* m_messages; MessageMap* m_messages;
/** the own master address to react on master-master messages, or @a SYN to ignore. */ /** the own master address. */
const unsigned char m_ownMasterAddress; const unsigned char m_ownMasterAddress;
/** the own slave address to react on master-slave messages, or @a SYN to ignore. */ /** the own slave address. */
const unsigned char m_ownSlaveAddress; const unsigned char m_ownSlaveAddress;
/** whether to answer queries for the own master/slave address. */
const bool m_answer;
/** the number of times a send is repeated due to lost arbitration. */ /** the number of times a send is repeated due to lost arbitration. */
const unsigned int m_busLostRetries; const unsigned int m_busLostRetries;
@@ -237,6 +305,12 @@ private:
/** the remaining number of AUTO-SYN symbols before sending is allowed again. */ /** the remaining number of AUTO-SYN symbols before sending is allowed again. */
unsigned int m_remainLockCount; unsigned int m_remainLockCount;
/** the interval in seconds in which poll messages are cycled, or 0 if disabled. */
const unsigned int m_pollInterval;
/** the time of the last poll, or 0 for never. */
time_t m_lastPoll;
/** the queue of @a BusRequests that shall be handled. */ /** the queue of @a BusRequests that shall be handled. */
WQueue<BusRequest*> m_requests; WQueue<BusRequest*> m_requests;
+39 -3
View File
@@ -36,7 +36,7 @@ Message::Message(const string clazz, const string name, const bool isSet,
m_isPassive(isPassive), m_comment(comment), m_isPassive(isPassive), m_comment(comment),
m_srcAddress(srcAddress), m_dstAddress(dstAddress), m_srcAddress(srcAddress), m_dstAddress(dstAddress),
m_id(id), m_data(data), m_pollPriority(pollPriority), m_id(id), m_data(data), m_pollPriority(pollPriority),
m_lastUpdateTime(0) m_lastUpdateTime(0), m_pollCount(0), m_lastPollTime(0)
{ {
int exp = 7; int exp = 7;
unsigned long long key = (unsigned long long)(id.size()-2) << (8 * exp + 5); unsigned long long key = (unsigned long long)(id.size()-2) << (8 * exp + 5);
@@ -269,7 +269,7 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma
result = m_data->write(input, pt_masterData, master, m_id.size() - 2, separator); result = m_data->write(input, pt_masterData, master, m_id.size() - 2, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
masterData = SymbolString(master); masterData = SymbolString(master, true);
return result; return result;
} }
@@ -298,6 +298,18 @@ result_t Message::decode(const PartType partType, SymbolString& data,
return RESULT_OK; return RESULT_OK;
} }
bool Message::isLessPollWeight(Message* other) {
if (m_pollPriority * m_pollCount < other->m_pollPriority * other->m_pollCount)
return true;
if (m_pollPriority < other->m_pollPriority)
return true;
if (m_lastPollTime < other->m_lastPollTime)
return true;
return false;
}
result_t MessageMap::add(Message* message) result_t MessageMap::add(Message* message)
{ {
unsigned long long pkey = message->getKey(); unsigned long long pkey = message->getKey();
@@ -318,6 +330,7 @@ result_t MessageMap::add(Message* message)
} }
m_messagesByName[key] = message; m_messagesByName[key] = message;
m_messageCount++;
key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class
m_messagesByName[key] = message; // last key without class overrides previous m_messagesByName[key] = message; // last key without class overrides previous
@@ -331,7 +344,8 @@ result_t MessageMap::add(Message* message)
m_passiveMessagesByKey[pkey] = message; m_passiveMessagesByKey[pkey] = message;
} }
//m_pollMessages.push() if (message->getPollPriority() > 0)
m_pollMessages.push(message);
return RESULT_OK; return RESULT_OK;
} }
@@ -418,12 +432,34 @@ Message* MessageMap::find(SymbolString& master)
void MessageMap::clear() void MessageMap::clear()
{ {
// clear poll messages
while (m_pollMessages.empty() == false) {
m_pollMessages.top();
m_pollMessages.pop();
}
// free message instances
for (map<string, Message*>::iterator it=m_messagesByName.begin(); it!=m_messagesByName.end(); it++) { for (map<string, Message*>::iterator it=m_messagesByName.begin(); it!=m_messagesByName.end(); it++) {
if (it->first[0] != '-') // avoid double free if (it->first[0] != '-') // avoid double free
delete it->second; delete it->second;
it->second = NULL; it->second = NULL;
} }
// clear messages by name
m_messageCount = 0;
m_messagesByName.clear(); m_messagesByName.clear();
// clear messages by key
m_passiveMessagesByKey.clear(); m_passiveMessagesByKey.clear();
m_minIdLength = 4;
m_maxIdLength = 0; m_maxIdLength = 0;
} }
Message* MessageMap::getNextPoll()
{
if (m_pollMessages.empty() == true)
return NULL;
Message* ret = m_pollMessages.top();
m_pollMessages.pop();
ret->m_pollCount++;
time(&(ret->m_lastPollTime));
m_pollMessages.push(ret); // re-insert at new position
return ret;
}
+57 -4
View File
@@ -29,11 +29,14 @@
using namespace std; using namespace std;
class MessageMap;
/** /**
* @brief Defines parameters of a message sent or received on the bus. * @brief Defines parameters of a message sent or received on the bus.
*/ */
class Message class Message
{ {
friend class MessageMap;
public: public:
/** /**
@@ -151,11 +154,24 @@ public:
string getLastValue() { return m_lastValue; } string getLastValue() { return m_lastValue; }
/** /**
* @brief Get the system time when @a m_lastValue was updated. * @brief Get the time when @a m_lastValue was updated.
* @return the system time when @a m_lastValue was updated, or 0 if this message was not decoded yet. * @return the time when @a m_lastValue was updated, or 0 if this message was not decoded yet.
*/ */
time_t getLastUpdateTime() { return m_lastUpdateTime; } time_t getLastUpdateTime() { return m_lastUpdateTime; }
/**
* @brief Get the time when this message was last polled for.
* @return the time when this message was last polled for, or 0 for never.
*/
time_t getLastPollTime() { return m_lastPollTime; }
/**
* @brief Return whether this @a Message needs to be polled before the other one.
* @param other the other @a Message to compare with.
* @return true if this @a Message needs to be polled before the other one.
*/
bool isLessPollWeight(Message* other);
private: private:
/** the optional device class. */ /** the optional device class. */
@@ -183,10 +199,24 @@ private:
const unsigned char m_pollPriority; const unsigned char m_pollPriority;
/** the last decoded value. */ /** the last decoded value. */
string m_lastValue; string m_lastValue;
/** the system time when @a m_lastValue was updated. */ /** the system time when @a m_lastValue was updated, 0 for never. */
time_t m_lastUpdateTime; time_t m_lastUpdateTime;
/** the number of times this messages was already polled for. */
unsigned int m_pollCount;
/** the system time when this message was last polled for, 0 for never. */
time_t m_lastPollTime;
}; };
/**
* @brief A function that compares the poll priority of two @a Message instances.
*/
struct compareMessagePriority : binary_function <Message*,Message*,bool> {
bool operator() (Message* x, Message* y) const { return x->isLessPollWeight(y) == false; };
};
/** /**
* @brief Holds a map of all known @a Message instances. * @brief Holds a map of all known @a Message instances.
*/ */
@@ -197,7 +227,7 @@ public:
/** /**
* @brief Construct a new instance. * @brief Construct a new instance.
*/ */
MessageMap() : FileReader(true), m_minIdLength(4), m_maxIdLength(0) {} MessageMap() : FileReader(true), m_minIdLength(4), m_maxIdLength(0), m_messageCount(0) {}
/** /**
* @brief Destructor. * @brief Destructor.
*/ */
@@ -232,6 +262,23 @@ public:
* @brief Removes all @a Message instances. * @brief Removes all @a Message instances.
*/ */
void clear(); void clear();
/**
* @brief Get the number of stored @a Message instances.
* @param passiveOnly true to count only passive messages, false to count all messages.
* @return the the number of stored @a Message instances.
*/
int size(const bool passiveOnly=false) { return passiveOnly ? m_passiveMessagesByKey.size() : m_messageCount; }
/**
* @brief Get the number of stored @a Message instances with a poll priority.
* @return the the number of stored @a Message instances with a poll priority.
*/
int sizePoll() { return m_pollMessages.size(); }
/**
* @brief Get the next @a Message to poll.
* @return the next @a Message to poll, or NULL.
* Note: the caller may not free the returned instance.
*/
Message* getNextPoll();
private: private:
@@ -241,12 +288,18 @@ private:
/** the maximum ID length used by any of the known @a Message instances. */ /** the maximum ID length used by any of the known @a Message instances. */
unsigned char m_maxIdLength; unsigned char m_maxIdLength;
/** the number of distinct @a Message instances stored in @a m_messagesByName. */
int m_messageCount;
/** the known @a Message instances by class and name. */ /** the known @a Message instances by class and name. */
map<string, Message*> m_messagesByName; map<string, Message*> m_messagesByName;
/** the known passive @a Message instances by key. */ /** the known passive @a Message instances by key. */
map<unsigned long long, Message*> m_passiveMessagesByKey; map<unsigned long long, Message*> m_passiveMessagesByKey;
/** the known @a Message instances to poll, by priority. */
priority_queue<Message*, vector<Message*>, compareMessagePriority> m_pollMessages;
}; };
#endif // LIBEBUS_MESSAGE_H_ #endif // LIBEBUS_MESSAGE_H_
+6 -6
View File
@@ -60,15 +60,15 @@ SymbolString::SymbolString(const string& str) //TODO use a factory method instea
push_back(m_crc, false, false); push_back(m_crc, false, false);
} }
SymbolString::SymbolString(const SymbolString& str) SymbolString::SymbolString(const SymbolString& str, const bool escape, const bool addCrc)
: m_unescapeState(0), m_crc(0) : m_unescapeState(escape == true ? 0 : 1), m_crc(0)
{ {
// escape
for (size_t i = 0; i < str.size(); i++) { for (size_t i = 0; i < str.size(); i++) {
push_back(str[i], false, true); push_back(str[i], str.m_unescapeState == 0, true);
} }
// add CRC + escape if (addCrc == true)
push_back(m_crc, false, false); // add CRC
push_back(m_crc, false, false);
} }
SymbolString::SymbolString(const string& str, bool isEscaped) SymbolString::SymbolString(const string& str, bool isEscaped)
+11 -3
View File
@@ -52,10 +52,10 @@ public:
*/ */
SymbolString(const string& str); SymbolString(const string& str);
/** /**
* @brief Creates a new escaped instance from an unescaped @a SymbolString and adds the calculated CRC. * @brief Creates a new escaped or unescaped instance from another @a SymbolString and adds the calculated CRC.
* @param str the unescaped SymbolString. * @param str the @a SymbolString top copy from.
*/ */
SymbolString(const SymbolString& str); SymbolString(const SymbolString& str, const bool escape, const bool addCrc=true);
/** /**
* @brief Creates a new unescaped instance from a hex string. * @brief Creates a new unescaped instance from a hex string.
* @param isEscaped whether the hex string is escaped and shall be unescaped. * @param isEscaped whether the hex string is escaped and shall be unescaped.
@@ -125,6 +125,14 @@ public:
void clear() { m_data.clear(); m_unescapeState = m_unescapeState==0 ? 0 : 1; m_crc = 0; } void clear() { m_data.clear(); m_unescapeState = m_unescapeState==0 ? 0 : 1; m_crc = 0; }
private: private:
/**
* @brief Hidden copy constructor.
* @param str the @a SymbolString to copy from.
*/
SymbolString(const SymbolString& str)
: m_data(str.m_data), m_unescapeState(str.m_unescapeState), m_crc(str.m_crc) {}
/** /**
* @brief Updates the calculated CRC in @a m_crc by adding a value. * @brief Updates the calculated CRC in @a m_crc by adding a value.
* @param value the (escaped) value to add to the calculated CRC in @a m_crc. * @param value the (escaped) value to add to the calculated CRC in @a m_crc.
+4 -4
View File
@@ -190,8 +190,8 @@ int main()
string check[5] = checks[i]; string check[5] = checks[i];
istringstream isstr(check[0]); istringstream isstr(check[0]);
string expectStr = check[1]; string expectStr = check[1];
SymbolString mstr = SymbolString(check[2], false); SymbolString mstr(check[2], false);
SymbolString sstr = SymbolString(check[3], false); SymbolString sstr(check[3], false);
string flags = check[4]; string flags = check[4];
bool isSet = flags.find('s') != string::npos; bool isSet = flags.find('s') != string::npos;
bool failedCreate = flags.find('c') != string::npos; bool failedCreate = flags.find('c') != string::npos;
@@ -247,8 +247,8 @@ int main()
} }
ostringstream output; ostringstream output;
SymbolString writeMstr = SymbolString(mstr.getDataStr().substr(0, 10), false); SymbolString writeMstr(mstr.getDataStr().substr(0, 10), false);
SymbolString writeSstr = SymbolString(sstr.getDataStr().substr(0, 2), false); SymbolString writeSstr(sstr.getDataStr().substr(0, 2), false);
result = fields->read(pt_masterData, mstr, 0, output, false, verbose); result = fields->read(pt_masterData, mstr, 0, output, false, verbose);
if (result == RESULT_OK) { if (result == RESULT_OK) {
result = fields->read(pt_slaveData, sstr, 0, output, output.str().empty() == false, verbose); result = fields->read(pt_slaveData, sstr, 0, output, output.str().empty() == false, verbose);
+7 -7
View File
@@ -47,10 +47,10 @@ int main()
// field= name;[pos];type[;[divisor|values][;[unit][;[comment]]]] // field= name;[pos];type[;[divisor|values][;[unit][;[comment]]]]
string checks[][5] = { string checks[][5] = {
// "message", "flags" // "message", "flags"
{"u;;first;;;fe;0700;;x;;bda", "26.10.2014", "fffe0700042610061451", "00", "p"}, {"u;;first;;;fe;0700;;x;;bda", "26.10.2014", "fffe07000426100614", "00", "p"},
{"w;;first;;;15;b509;0400;date;;bda", "26.10.2014", "ff15b5090604002610061445", "00", "m"}, {"w;;first;;;15;b509;0400;date;;bda", "26.10.2014", "ff15b50906040026100614", "00", "m"},
{"r;ehp;time;;;08;b509;0d2800;;;time", "15:00:17", "ff08b509030d2800ea", "0311000f00", "m"}, {"r;ehp;time;;;08;b509;0d2800;;;time", "15:00:17", "ff08b509030d2800", "0311000f", "m"},
{"r;ehp;date;;;08;b509;0d2900;;;hda:3", "23.11.2014", "ff08b509030d290071", "03170b0e5a", "m"}, {"r;ehp;date;;;08;b509;0d2900;;;hda:3", "23.11.2014", "ff08b509030d2900", "03170b0e", "m"},
{"u;ehp;ActualEnvironmentPower;Energiebezug;;08;B509;29BA00;;s;IGN:2;;;;;s;power", "8", "1008b5090329ba00", "03ba0008", "pm"}, {"u;ehp;ActualEnvironmentPower;Energiebezug;;08;B509;29BA00;;s;IGN:2;;;;;s;power", "8", "1008b5090329ba00", "03ba0008", "pm"},
{"uw;ehp;test;Test;;08;B5de;ab;;;power;;;;;s;hex:1", "8;39", "1008b5de02ab08", "0139", "pm"}, {"uw;ehp;test;Test;;08;B5de;ab;;;power;;;;;s;hex:1", "8;39", "1008b5de02ab08", "0139", "pm"},
{"","55.50;ok","1025b50903290000","050000780300",""}, {"","55.50;ok","1025b50903290000","050000780300",""},
@@ -76,8 +76,8 @@ int main()
string check[5] = checks[i]; string check[5] = checks[i];
istringstream isstr(check[0]); istringstream isstr(check[0]);
string inputStr = check[1]; string inputStr = check[1];
SymbolString mstr = SymbolString(check[2], false); SymbolString mstr(check[2]);
SymbolString sstr = SymbolString(check[3], false); SymbolString sstr(check[3]);
string flags = check[4]; string flags = check[4];
bool dontMap = flags.find('m') != string::npos; bool dontMap = flags.find('m') != string::npos;
bool failedCreate = flags.find('c') != string::npos; bool failedCreate = flags.find('c') != string::npos;
@@ -147,7 +147,7 @@ int main()
message = deleteMessage; message = deleteMessage;
} }
istringstream input(inputStr); istringstream input(inputStr);
SymbolString writeMstr = SymbolString(); SymbolString writeMstr;
if (message->isPassive() == true) { if (message->isPassive() == true) {
ostringstream output; ostringstream output;
result = message->decode(pt_masterData, mstr, output); result = message->decode(pt_masterData, mstr, output);
+1 -1
View File
@@ -25,7 +25,7 @@ using namespace std;
int main () int main ()
{ {
SymbolString sstr = SymbolString("10feb5050427a915aa"); SymbolString sstr("10feb5050427a915aa");
std::string gotStr = sstr.getDataStr(false), expectStr = "10feb5050427a90015a90177"; std::string gotStr = sstr.getDataStr(false), expectStr = "10feb5050427a90015a90177";