implemented get

This commit is contained in:
john30
2014-12-06 13:02:16 +01:00
parent 38f0ddbe78
commit 73b74f1602
3 changed files with 266 additions and 161 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ ebusd_SOURCES = bushandler.cpp \
ebusd_LDADD = $(top_srcdir)/src/lib/utils/libutils.a \ ebusd_LDADD = $(top_srcdir)/src/lib/utils/libutils.a \
$(top_srcdir)/src/lib/ebus/libebus.a \ $(top_srcdir)/src/lib/ebus/libebus.a \
-lpthread -lpthread -lrt
distclean-local: distclean-local:
-rm -f Makefile.in -rm -f Makefile.in
+223 -134
View File
@@ -35,28 +35,31 @@ extern Logger& L;
extern Appl& A; extern Appl& A;
/** /**
* @brief Return the string corresponding to the @a BusState and send position. * @brief Return the string corresponding to the @a BusState.
* @param state the @a BusState. * @param state the @a BusState.
* @param sendPos >=0 while sending data, -1 while receiving data.
* @return the string corresponding to the @a BusState. * @return the string corresponding to the @a BusState.
*/ */
const char* getStateCode(BusState state, int sendPos) { const char* getStateCode(BusState state) {
switch (state) switch (state)
{ {
case bs_skip: return "skip"; case bs_skip: return "skip";
case bs_ready: return "ready"; case bs_ready: return "ready";
case bs_command: return sendPos < 0 ? "receive command" : "send command"; case bs_sendCmd: return "send command";
case bs_commandAck: return sendPos < 0 ? "receive command ACK" : "send command ACK"; case bs_recvCmdAck: return "receive command ACK";
case bs_response: return sendPos < 0 ? "receive response" : "send response"; case bs_recvRes: return "receive response";
case bs_responseAck: return sendPos < 0 ? "receive response ACK" : "send response ACK"; case bs_sendResAck: return "send response ACK";
//case bs_validTransfer: return sendPos < 0 ? "after complete receive" : "after complete send"; case bs_recvCmd: return "receive command";
default: return "unknown state"; case bs_recvResAck: return "receive response ACK";
// case bs_sendRes: return "send response";
// case bs_sendCmdAck: return "send command ACK";
case bs_sendSyn: return "send SYN";
default: return "unknown";
} }
} }
BusRequest::BusRequest(SymbolString& master, SymbolString& slave) BusRequest::BusRequest(SymbolString& master, SymbolString& slave)
: m_master(master), m_slave(slave), m_finished(false) : m_master(master), m_slave(slave), 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);
@@ -88,11 +91,12 @@ bool BusRequest::wait(int timeout)
return result == 0; return result == 0;
} }
void BusRequest::notify(bool finished) void BusRequest::notify(result_t result)
{ {
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
m_finished = finished; m_result = result;
m_finished = true;
pthread_mutex_unlock(&m_mutex); pthread_mutex_unlock(&m_mutex);
} }
@@ -103,29 +107,24 @@ result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave)
BusRequest* request = new BusRequest(master, slave); BusRequest* request = new BusRequest(master, slave);
m_requests.add(request); m_requests.add(request);
bool result = request->wait(5); bool success = request->wait(5);
if (result == false) if (success == false)
m_requests.remove(request); m_requests.remove(request);
result_t result = request->m_result;
delete request; delete request;
return result == true ? RESULT_OK : RESULT_ERR_TIMEOUT; return success == true ? result : RESULT_ERR_TIMEOUT;
} }
void BusHandler::run() void BusHandler::run()
{ {
result_t result = RESULT_OK;
do { do {
if (m_port->isOpen() == true) { if (m_port->isOpen() == true)
result = receiveSymbol(); handleSymbol();
if (result != RESULT_OK)
L.log(bus, error, " %s", getResultCode(result));
}
else { else {
// TODO: define max reopen // TODO: define max reopen
sleep(10); sleep(10);
result = m_port->open(); result_t result = m_port->open();
if (result != RESULT_OK) if (result != RESULT_OK)
L.log(bus, error, "can't open %s", A.getOptVal<const char*>("device")); L.log(bus, error, "can't open %s", A.getOptVal<const char*>("device"));
@@ -135,46 +134,72 @@ void BusHandler::run()
} while (isRunning() == true); } while (isRunning() == true);
} }
result_t BusHandler::receiveSymbol() #define RECV_TIMEOUT 4500
result_t BusHandler::handleSymbol()
{ {
long timeout; long timeout = SYN_TIMEOUT;
ssize_t count; unsigned char sendSymbol = ESC;
unsigned char sentSymbol = SYN; bool sending = false;
BusRequest* startRequest = NULL;
if (m_state == bs_skip) // check if another symbol has to be sent and determine timeout for receive
timeout = 0; switch (m_state)
else if (m_sendPos >= 0) { {
timeout = SLAVE_RECV_TIMEOUT; case bs_skip:
if (m_sendPos+1 < m_request->m_master.size()) { timeout = 0; // endless
m_sendPos++; break;
sentSymbol = m_request->m_master[m_sendPos];
if (m_port->send(&sentSymbol) != 1) { case bs_ready:
sentSymbol = SYN; // try again later // TODO error: send failed, abort send m_request = m_requests.next(false);
m_request->notify(false); if (m_request != NULL) { // initiate arbitration
m_request = NULL; sendSymbol = m_request->m_master[0];
m_sendPos = -1; sending = true;
}
} }
break;
case bs_recvCmd:
case bs_recvCmdAck:
case bs_recvRes:
case bs_recvResAck:
timeout = SLAVE_RECV_TIMEOUT;
break;
case bs_sendCmd:
if (m_request != NULL) {
sendSymbol = m_request->m_master[m_nextSendPos];
sending = true;
}
break;
case bs_sendResAck:
if (m_request != NULL) {
sendSymbol = m_responseCrcValid ? ACK : NAK;
sending = true;
}
break;
case bs_sendSyn:
sendSymbol = SYN;
sending = true;
break;
} }
else {
timeout = SYN_TIMEOUT; // send symbol if necessary
if (m_state == bs_ready && m_request == NULL) { if (sending == true) {
startRequest = m_requests.next(false); if (m_port->send(&sendSymbol, 1) == 1)
if (startRequest != NULL) { timeout = RECV_TIMEOUT;
// initiate arbitration else {
sentSymbol = startRequest->m_master[0]; sending = false;
if (m_port->send(&sentSymbol) != 1) { timeout = 0;
sentSymbol = SYN; // try again later // TODO error: send failed setState(bs_skip, RESULT_ERR_SEND);
startRequest = NULL;
}
}
} }
} }
count = m_port->recv(timeout, 1); // receive next symbol (optionally check reception of sent symbol)
ssize_t count = m_port->recv(timeout, 1);
if (count < 0) if (count < 0)
return setState(bs_skip, RESULT_ERR_DEVICE); return setState(bs_skip, count);
if (count == 0) { if (count == 0) {
if (m_state == bs_ready) if (m_state == bs_ready)
@@ -182,11 +207,9 @@ result_t BusHandler::receiveSymbol()
return setState(bs_skip, RESULT_ERR_TIMEOUT); return setState(bs_skip, RESULT_ERR_TIMEOUT);
} }
unsigned char symbol = m_port->byte(); unsigned char recvSymbol = m_port->byte();
if (symbol == SYN) { if (recvSymbol == SYN)
m_repeat = false; return setState(bs_ready, RESULT_SYN);
return setState(bs_ready, RESULT_OK);
}
unsigned char headerLen, crcPos; unsigned char headerLen, crcPos;
result_t result; result_t result;
@@ -197,128 +220,185 @@ result_t BusHandler::receiveSymbol()
return RESULT_OK; return RESULT_OK;
case bs_ready: case bs_ready:
if (symbol == ESC) if (m_request != NULL && sending == true) {
return setState(bs_skip, RESULT_ERR_ESC);
if (m_sendPos < 0 && sentSymbol != SYN) {
// check arbitration // check arbitration
if (symbol == sentSymbol) { // arbitration successful if (recvSymbol == sendSymbol) { // arbitration successful
if (m_requests.remove(startRequest) == false) { if (m_requests.remove(m_request) == false) {
sentSymbol = SYN; // try again later // TODO error: send failed, abort send // request already timed out
} else { m_request = NULL;
m_request = startRequest; return setState(bs_sendSyn, RESULT_ERR_TIMEOUT);
m_sendPos = 0;
} }
} else { // arbitration lost m_nextSendPos = 1;
sentSymbol = SYN; // try again later // TODO error: lost arbitration m_repeat = false;
return setState(bs_sendCmd, RESULT_OK);
} }
// arbitration lost
setState(m_state, RESULT_ERR_BUS_LOST); // try again later
} }
result = m_command.push_back(symbol); result = m_command.push_back(recvSymbol, false); // expect no escaping for master address
if (result < RESULT_OK) if (result < RESULT_OK)
return setState(bs_skip, result); return setState(bs_skip, result);
return setState(bs_command, RESULT_OK); m_repeat = false;
return setState(bs_recvCmd, RESULT_OK);
case bs_command: case bs_recvCmd:
headerLen = 4; headerLen = 4;
crcPos = m_command.size() > headerLen ? headerLen + 1 + m_command[headerLen] : 0xff; crcPos = m_command.size() > headerLen ? headerLen + 1 + m_command[headerLen] : 0xff;
result = m_command.push_back(symbol, true, m_command.size() < crcPos); result = m_command.push_back(recvSymbol, true, m_command.size() < crcPos);
if (result < RESULT_OK) if (result < RESULT_OK)
return setState(bs_skip, result); return setState(bs_skip, result);
if (result == RESULT_OK && m_command.size() == crcPos + 1) { // CRC received if (result == RESULT_OK && crcPos != 0xff && m_command.size() == crcPos + 1) { // CRC received
unsigned char dstAddress = m_command[1];
//if (isValidAddress(dstAddress) == false || isMaster(m_command[0]) == false)
// return setState(bs_skip, RESULT_ERR_INVALID_ADDR);
m_commandCrcValid = m_command[headerLen + 1 + m_command[headerLen]] == m_command.getCRC(); m_commandCrcValid = m_command[headerLen + 1 + m_command[headerLen]] == m_command.getCRC();
if (m_command[1] == BROADCAST) { if (m_commandCrcValid) {
if (m_commandCrcValid) { if (dstAddress == BROADCAST) {
transferCompleted(tt_broadcast); transferCompleted(tt_broadcast);
return setState(bs_skip, RESULT_OK); return setState(bs_skip, RESULT_OK);
} }
//if (dstAddress == m_ownMasterAddress || dstAddress == m_ownSlaveAddress)
// return setState(bs_sendCmdAck, RESULT_OK);
return setState(bs_skip, RESULT_ERR_CRC); return setState(bs_recvCmdAck, RESULT_OK);
} }
/*if (m_command[1] == m_ownSlaveAddress || m_command[1] == m_ownMasterAddress) { if (dstAddress == BROADCAST)
setState(bs_commandAck, RESULT_OK); return setState(bs_skip, RESULT_OK);
m_sendPos = 0;
symbol = m_commandCrcValid ? ACK : NAK; //if (dstAddress == m_ownMasterAddress || dstAddress == m_ownSlaveAddress)
if (m_port->send(&symbol) <= 0) // return setState(bs_sendCmdAck, RESULT_ERR_CRC);
return setState(bs_skip, RESULT_ERR_SEND); if (m_repeat == true)
}*/ return setState(bs_skip, RESULT_ERR_CRC);
return setState(bs_commandAck, RESULT_OK); return setState(bs_recvCmdAck, RESULT_ERR_CRC);
} }
return RESULT_OK; return RESULT_OK;
case bs_commandAck: case bs_recvCmdAck:
if (symbol == ESC) if (recvSymbol == ACK) {
return setState(bs_skip, RESULT_ERR_ESC);
/*if (m_sendPos >= 0) {
if (symbol == ACK && m_commandCrcValid == true)
return setState();
return setState()
}*/
if (symbol == ACK) {
if (m_commandCrcValid == false) if (m_commandCrcValid == false)
return setState(bs_skip, RESULT_ERR_ACK); return setState(bs_skip, RESULT_ERR_ACK);
if (isMaster(m_command[1]) == true) { if (m_request != NULL) {
if (isMaster(m_request->m_master[1]) == true) {
transferCompleted(tt_masterMaster);
return setState(bs_sendSyn, RESULT_OK);
}
} else if (isMaster(m_command[1]) == true) {
transferCompleted(tt_masterMaster); transferCompleted(tt_masterMaster);
return setState(bs_skip, RESULT_OK); return setState(bs_skip, RESULT_OK);
} }
return setState(bs_response, RESULT_OK); m_repeat = false;
return setState(bs_recvRes, RESULT_OK);
} }
if (symbol == NAK) { if (recvSymbol == NAK) {
if (m_repeat == false) { if (m_repeat == false) {
m_repeat = true; m_repeat = true;
return setState(bs_ready, RESULT_ERR_NAK); m_nextSendPos = 0;
m_command.clear();
if (m_request != NULL)
return setState(bs_sendCmd, RESULT_ERR_NAK);
return setState(bs_recvCmd, RESULT_ERR_NAK);
} }
if (m_request != NULL)
return setState(bs_sendSyn, RESULT_ERR_NAK);
return setState(bs_skip, RESULT_ERR_NAK); return setState(bs_skip, RESULT_ERR_NAK);
} }
if (m_request != NULL)
return setState(bs_sendSyn, RESULT_ERR_ACK);
return setState(bs_skip, RESULT_ERR_ACK); return setState(bs_skip, RESULT_ERR_ACK);
case bs_response: case bs_recvRes:
headerLen = 0; headerLen = 0;
crcPos = m_response.size() > headerLen ? headerLen + 1 + m_response[headerLen] : 0xff; crcPos = m_response.size() > headerLen ? headerLen + 1 + m_response[headerLen] : 0xff;
result = m_response.push_back(symbol, true, m_response.size() < crcPos); result = m_response.push_back(recvSymbol, true, m_response.size() < crcPos);
if (result < RESULT_OK) if (result < RESULT_OK) {
return setState(bs_skip, result); if (m_request != NULL)
return setState(bs_sendSyn, result);
if (result == RESULT_OK && m_response.size() == crcPos + 1) { // CRC received return setState(bs_skip, result);
}
if (result == RESULT_OK && crcPos != 0xff && m_response.size() == crcPos + 1) { // CRC received
m_responseCrcValid = m_response[headerLen + 1 + m_response[headerLen]] == m_response.getCRC(); m_responseCrcValid = m_response[headerLen + 1 + m_response[headerLen]] == m_response.getCRC();
/*if (m_command[1] == m_ownSlaveAddress || m_command[1] == m_ownMasterAddress) { if (m_responseCrcValid) {
setState(bs_responseAck, RESULT_OK); if (m_request != NULL)
m_sendPos = 0; return setState(bs_sendResAck, RESULT_OK);
symbol = m_responseCrcValid ? ACK : NAK;
if (m_port->send(&symbol) <= 0) return setState(bs_recvResAck, RESULT_OK);
return setState(bs_skip, RESULT_ERR_SEND); }
}*/ if (m_repeat == true) {
return setState(bs_responseAck, RESULT_OK); if (m_request != NULL)
return setState(bs_sendSyn, RESULT_ERR_CRC);
return setState(bs_skip, RESULT_ERR_CRC);
}
if (m_request != NULL)
return setState(bs_sendResAck, RESULT_ERR_CRC);
return setState(bs_recvResAck, RESULT_ERR_CRC);
} }
return RESULT_OK; return RESULT_OK;
case bs_responseAck: case bs_recvResAck:
if (symbol == ESC) if (recvSymbol == ACK) {
return setState(bs_skip, RESULT_ERR_ESC);
/*if (m_sendPos >= 0) {
if (symbol == ACK && m_responseCrcValid == true)
return setState();
return setState()
}*/
if (symbol == ACK) {
if (m_responseCrcValid == false) if (m_responseCrcValid == false)
return setState(bs_skip, RESULT_ERR_ACK); return setState(bs_skip, RESULT_ERR_ACK);
transferCompleted(tt_masterSlave); transferCompleted(tt_masterSlave);
return setState(bs_skip, RESULT_OK); return setState(bs_skip, RESULT_OK);
} }
if (symbol == NAK) { if (recvSymbol == NAK) {
if (m_repeat == false) { if (m_repeat == false) {
m_repeat = true; m_repeat = true;
return setState(bs_response, RESULT_ERR_NAK); m_response.clear();
return setState(bs_recvRes, RESULT_ERR_NAK);
} }
return setState(bs_skip, RESULT_ERR_NAK); return setState(bs_skip, RESULT_ERR_NAK);
} }
return setState(bs_skip, RESULT_ERR_ACK); return setState(bs_skip, RESULT_ERR_ACK);
case bs_sendCmd:
if (m_request != NULL && sending == true) {
if (recvSymbol == sendSymbol) {
// successfully sent
m_nextSendPos++;
if (m_nextSendPos >= m_request->m_master.size()) {
// master data completely sent
if (m_request->m_master[1] == BROADCAST)
return setState(bs_sendSyn, RESULT_OK);
m_commandCrcValid = true;
return setState(bs_recvCmdAck, RESULT_OK);
}
return RESULT_OK;
}
}
return setState(bs_sendSyn, RESULT_ERR_INVALID_ARG);
case bs_sendResAck:
if (m_request != NULL && sending == true) {
if (recvSymbol == sendSymbol) {
// successfully sent
return setState(bs_sendSyn, RESULT_OK);
}
}
return setState(bs_sendSyn, RESULT_ERR_INVALID_ARG);
case bs_sendSyn:
if (sending == true) {
if (recvSymbol == sendSymbol) {
// successfully sent
return setState(bs_skip, RESULT_OK);
}
}
return setState(bs_skip, RESULT_ERR_INVALID_ARG);
} }
return RESULT_OK; return RESULT_OK;
@@ -330,18 +410,27 @@ result_t BusHandler::setState(BusState state, result_t result)
return result; return result;
if (result < RESULT_OK || (result != RESULT_OK && state == bs_skip)) if (result < RESULT_OK || (result != RESULT_OK && state == bs_skip))
L.log(bus, error, " %s during %s, switching to %s", getResultCode(result), getStateCode(m_state, m_sendPos), getStateCode(state, m_sendPos)); L.log(bus, error, " %s during %s, switching to %s", getResultCode(result), getStateCode(m_state), getStateCode(state));
m_state = state; m_state = state;
if (m_request != NULL) {
if (state == bs_sendSyn) {
m_request->m_slave = m_response; // TODO nicer
m_request->notify(result);
m_request = NULL;
} else if (result != RESULT_OK) {
m_request->notify(result);
m_request = NULL;
}
}
if (state == bs_ready || state == bs_skip) { if (state == bs_ready || state == bs_skip) {
m_command.clear(); m_command.clear();
m_commandCrcValid = false; m_commandCrcValid = false;
m_response.clear(); m_response.clear();
m_responseCrcValid = false; m_responseCrcValid = false;
m_sendPos = -1; m_nextSendPos = 0;
} }
if (state == bs_skip)
m_repeat = false;
return result; return result;
} }
@@ -367,7 +456,7 @@ void BusHandler::transferCompleted(TransferType type)
ostringstream output; ostringstream output;
result_t result = msg->decode(m_command, m_response, output); result_t result = msg->decode(m_command, m_response, output);
if (result != RESULT_OK) if (result != RESULT_OK)
L.log(bus, error, "unable to parse %s %s: %s", msg->getClass().c_str(), msg->getName().c_str(), getResultCode(result)); L.log(bus, error, "unable to parse %s %s from %s / %s: %s", msg->getClass().c_str(), msg->getName().c_str(), m_command.getDataStr().c_str(), m_response.getDataStr().c_str(), getResultCode(result));
else else
L.log(bus, trace, "%s %s: %s", msg->getClass().c_str(), msg->getName().c_str(), output.str().c_str()); L.log(bus, trace, "%s %s: %s", msg->getClass().c_str(), msg->getName().c_str(), output.str().c_str());
} }
+42 -26
View File
@@ -36,18 +36,22 @@ using namespace std;
/** the maximum allowed time [us] for retrieval of a single symbol from an addressed slave. */ /** the maximum allowed time [us] for retrieval of a single symbol from an addressed slave. */
#define SLAVE_RECV_TIMEOUT 10000 #define SLAVE_RECV_TIMEOUT 10000
/** the maximum allowed time [us] for retrieval of an AUTO-SYN symbol. */ /** the maximum allowed time [us] for retrieval of an AUTO-SYN symbol (should be generated in <45ms). */
#define SYN_TIMEOUT 50000 #define SYN_TIMEOUT 50000
/** the possible bus states. */ /** the possible bus states. */
enum BusState { enum BusState {
bs_skip, // skip all symbols until next @a SYN bs_skip, // skip all symbols until next @a SYN
bs_ready, // ready for next master (after @a SYN symbol, send/receive QQ) bs_ready, // ready for next master (after @a SYN symbol, send/receive QQ)
bs_command, // receive/send command (ZZ, PBSB, master data) bs_recvCmd, // receive command (ZZ, PBSB, master data) [passive set]
bs_commandAck, // receive/send command ACK/NACK bs_recvCmdAck, // receive command ACK/NACK [passive set + active set+get]
bs_response, // receive/send response (slave data) bs_recvRes, // receive response (slave data) [passive set + active get]
bs_responseAck, // receive/send response ACK/NACK bs_recvResAck, // receive response ACK/NACK [passive set]
//bs_validTransfer,// completed a valid message transfer bs_sendCmd, // send command (ZZ, PBSB, master data) [active set+get]
bs_sendResAck, // send response ACK/NACK [active get]
// bs_sendRes, // send response (slave data) [passive get] // TODO implement
// bs_sendCmdAck, // send command ACK/NACK [passive get] // TODO implement
bs_sendSyn, // send SYN for completed transfer [active set+get]
}; };
/** the possible message transfer types. */ /** the possible message transfer types. */
@@ -62,9 +66,9 @@ enum MessageDirection {
md_thisToAll, // message from us to all (broadcast) md_thisToAll, // message from us to all (broadcast)
md_thisToMaster, // message from us to another master md_thisToMaster, // message from us to another master
md_thisToSlave, // message from us to another slave md_thisToSlave, // message from us to another slave
md_otherToAll, // message from a master (other than us) to all (broadcast): @a bs_ready, @a bs_recvCmd 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): @a bs_ready, @a bs_recvCmd, @a bs_recvAck 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): @a bs_ready, @a bs_recvCmd, @a bs_recvAck, @a bs_recvResp, @a bs_recvAck 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_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_otherToThisSlave, // message from a master (other than us) to us (as slave)
md_undefined, md_undefined,
@@ -72,6 +76,9 @@ enum MessageDirection {
class BusHandler; class BusHandler;
/**
* @brief Handles input from and output to the bus with respect to the ebus protocol.
*/
class BusRequest class BusRequest
{ {
friend class BusHandler; friend class BusHandler;
@@ -79,6 +86,8 @@ public:
/** /**
* @brief Constructor. * @brief Constructor.
* @param master the master data @a SymbolString to send.
* @param slave the slave data @a SymbolString received.
*/ */
BusRequest(SymbolString& master, SymbolString& slave); BusRequest(SymbolString& master, SymbolString& slave);
@@ -96,16 +105,22 @@ public:
/** /**
* @brief Notify all waiting threads. * @brief Notify all waiting threads.
*/ */
void notify(bool finished); void notify(result_t result);
private: private:
/** the master data @a SymbolString to send. */
SymbolString& m_master; SymbolString& m_master;
/** the slave data @a SymbolString received. */
SymbolString& m_slave; SymbolString& m_slave;
/** true once the request is finished. */
bool m_finished; bool m_finished;
/** the result of handling the request. */
result_t m_result;
/** a mutex for wait/notify. */ /** a mutex for wait/notify. */
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
@@ -132,8 +147,9 @@ public:
BusHandler(Port* port, MessageMap* messages, unsigned char ownMasterAddress, BusHandler(Port* port, MessageMap* messages, unsigned char ownMasterAddress,
unsigned char ownSlaveAddress) unsigned char ownSlaveAddress)
: m_port(port), m_messages(messages), m_ownMasterAddress(ownMasterAddress), : m_port(port), m_messages(messages), m_ownMasterAddress(ownMasterAddress),
m_ownSlaveAddress(ownSlaveAddress), m_state(bs_skip), m_repeat(false), m_ownSlaveAddress(ownSlaveAddress), m_request(NULL), m_nextSendPos(0),
m_sendPos(-1), m_commandCrcValid(false), m_responseCrcValid(false), m_request(NULL) {} m_state(bs_skip), m_repeat(false),
m_commandCrcValid(false), m_responseCrcValid(false) {}
/** /**
* @brief Destructor. * @brief Destructor.
@@ -155,10 +171,10 @@ public:
private: private:
/** /**
* @brief Receive another symbol from the bus. * @brief Handle the next symbol on the bus.
* @return RESULT_OK on success, or an error code. * @return RESULT_OK on success, or an error code.
*/ */
result_t receiveSymbol(); result_t handleSymbol();
/** /**
* @brief Set a new @a BusState and add a log message if necessary. * @brief Set a new @a BusState and add a log message if necessary.
@@ -186,18 +202,22 @@ private:
/** the own slave address to react on master-slave messages, or @a SYN to ignore. */ /** the own slave address to react on master-slave messages, or @a SYN to ignore. */
unsigned char m_ownSlaveAddress; unsigned char m_ownSlaveAddress;
/** the queue of @a BusRequests that shall be handled. */
WQueue<BusRequest*> m_requests;
/** the currently handled BusRequest, or NULL. */
BusRequest* m_request;
/** the offset of the next symbol that needs to be sent from the command or response,
* (only relevant if m_request is set and state is bs_command or bs_response). */
unsigned char m_nextSendPos;
/** the current @a BusState. */ /** the current @a BusState. */
BusState m_state; BusState m_state;
/** whether the current message part is being repeated. */ /** whether the current message part is being repeated. */
bool m_repeat; bool m_repeat;
/*
* the offset of the last sent symbol while sending command/response,
* or 0 while sending ACK/NACK, or -1 if not sending.
*/
int m_sendPos;
/** the received/sent command. */ /** the received/sent command. */
SymbolString m_command; SymbolString m_command;
@@ -210,10 +230,6 @@ private:
/** whether the response CRC is valid. */ /** whether the response CRC is valid. */
bool m_responseCrcValid; bool m_responseCrcValid;
WQueue<BusRequest*> m_requests;
BusRequest* m_request;
}; };