Skip to content

Commit

Permalink
[Issue #10] Unexpected start of next frame.
Browse files Browse the repository at this point in the history
Fixed byte processing for incomming frames in XBeeNet.
Implemented Logger::putByte.
Fixed compilation warnings in XBeeFrame.
Version: 0.3.1
  • Loading branch information
monstrenyatko committed Sep 26, 2015
1 parent 75dba70 commit c8edf96
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 49 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.0
0.3.1
30 changes: 30 additions & 0 deletions src/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,36 @@ inline __iom__put_array putArray(const std::vector<uint8_t>& data) {
return __iom__put_array(data);
};

/**
* Print byte content in HEX mode (helper class)
*/
class __iom__put_byte {
public:
inline explicit __iom__put_byte(uint8_t data)
: mData(data) {}

inline friend std::ostream& operator<<(std::ostream& os, const __iom__put_byte& data)
{
// save flags
std::ios::fmtflags f(os.flags());
// print
os << std::uppercase << std::hex << std::setw(2) << std::setfill('0')
<< (int)(data.mData);
// revert flags
os.flags(f);
return os;
}
private:
const uint8_t mData;
};

/**
* Print byte content in HEX mode with 'XX' format
*/
inline __iom__put_byte putByte(uint8_t data) {
return __iom__put_byte(data);
};

/**
* Overload operator '<<' for custom manipulators.
* If the 'os' is not an instance of 'LogStream' Do nothing.
Expand Down
2 changes: 1 addition & 1 deletion src/SerialPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct SerialPortContext {
std::unique_ptr<Serial> serial;
std::unique_ptr<SerialPortOpener> portOpener;

SerialPortContext(const std::string& name) : processor(name) {}
SerialPortContext(const std::string& name) : processor(name), portBaud(0) {}
};

///////////////////// SerialPortReader /////////////////////
Expand Down
6 changes: 0 additions & 6 deletions src/XBeeFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,6 @@ class XBeeFrameOptionsRecv: public XBeeFrameOptions {
XBeeFrameOptionsRecv(XBeeBuffer::const_iterator& cursor, const XBeeBuffer& buffer) throw (Utils::Error)
:XBeeFrameOptions(cursor, buffer) {}
private:
type mValue;

void decode(XBeeBuffer::const_iterator& cursor, const XBeeBuffer&) throw (Utils::Error);
};

class XBeeFrameOptionsSend: public XBeeFrameOptions {
Expand All @@ -212,9 +209,6 @@ class XBeeFrameOptionsSend: public XBeeFrameOptions {
XBeeFrameOptionsSend(XBeeBuffer::const_iterator& cursor, const XBeeBuffer& buffer) throw (Utils::Error)
:XBeeFrameOptions(cursor, buffer) {}
private:
type mValue;

void decode(XBeeBuffer::const_iterator& cursor, const XBeeBuffer&) throw (Utils::Error);
};

class XBeeFrameRadius {
Expand Down
101 changes: 60 additions & 41 deletions src/XBeeNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,59 +52,29 @@ class XBeeNetFromBuffer {
*/
void push(const XBeeBuffer& buffer) {
for (uint8_t b: buffer) {
// wait the start of the frame
if (mBuffer->empty()) {
switch (b) {
case API_START_DELIM:
mBuffer->push_back(b);
continue;
default:
// skip
continue;
}
}
// process Escape sequence
if (mIsEscapeSequence) {
switch (b) {
case DO_API_ESCPE(API_START_DELIM):
case DO_API_ESCPE(API_ESCAPE):
case DO_API_ESCPE(API_XON):
case DO_API_ESCPE(API_XOFF):
mIsEscapeSequence = false;
mBuffer->push_back(DO_API_ESCPE(b));
continue;
default:
*mLog.warn() << UTILS_STR_FUNCTION << ", bad Escape";
drop();
continue;
}
}
// other characters
switch (b) {
case API_ESCAPE:
mIsEscapeSequence = true;
continue;
case API_START_DELIM:
*mLog.warn() << UTILS_STR_FUNCTION << ", unexpected start of next frame";
drop();
// no break
default:
mBuffer->push_back(b);
break;
}
push(b);
// get length; length is 16-bit [1:2] bytes
if (!mFrameLength && mBuffer->size()>=3) {
uint8_t b1 = (*mBuffer)[1];
uint8_t b2 = (*mBuffer)[2];
mFrameLength = ((((uint16_t)b1)<<8) & 0xFF00) | (b2 & 0x00FF);
*mLog.debug() << UTILS_STR_FUNCTION << ", frame-length: "<< getFrameSize();
if (getFrameSize() > 200) {
*mLog.warn() << UTILS_STR_FUNCTION << ", frame-length is huge";
}
mBuffer->reserve(getFrameSize());
}
// check length
if (mFrameLength && mBuffer->size() == getFrameSize()) {
if (mFrameLength && mBuffer->size() >= getFrameSize()) {
if (mBuffer->size() != getFrameSize()) {
*mLog.warn() << UTILS_STR_FUNCTION << ", new-frame.size != frame-length"
<< "[" << mBuffer->size() << "!=" << getFrameSize() << "]";
}
// frame is received
pop();
}
}
*mLog.debug() << UTILS_STR_FUNCTION << ", new-frame.current-size: "<< mBuffer->size();
}

private:
Expand All @@ -115,6 +85,55 @@ class XBeeNetFromBuffer {
bool mIsEscapeSequence;
uint16_t mFrameLength;

/**
* Processes one byte
*/
void push(uint8_t b) {
// wait the start of the frame
if (mBuffer->empty()) {
switch (b) {
case API_START_DELIM:
*mLog.debug() << UTILS_STR_FUNCTION << ", new-frame started";
mBuffer->push_back(b);
// no break
default:
// skip
return;
}
}
// process Escape sequence
if (mIsEscapeSequence) {
switch (b) {
case DO_API_ESCPE(API_START_DELIM):
case DO_API_ESCPE(API_ESCAPE):
case DO_API_ESCPE(API_XON):
case DO_API_ESCPE(API_XOFF):
*mLog.trace() << UTILS_STR_FUNCTION << ", escaping "
<< Utils::putByte(b) << " => " << Utils::putByte(DO_API_ESCPE(b));
mIsEscapeSequence = false;
mBuffer->push_back(DO_API_ESCPE(b));
return;
default:
*mLog.warn() << UTILS_STR_FUNCTION << ", bad Escape";
drop();
return;
}
}
// other characters
switch (b) {
case API_ESCAPE:
mIsEscapeSequence = true;
return;
case API_START_DELIM:
*mLog.warn() << UTILS_STR_FUNCTION << ", unexpected start of next frame";
pop();
// no break
default:
mBuffer->push_back(b);
return;
}
}

/**
* Notifies about new received frame and starts assembling of a new one.
*/
Expand Down

0 comments on commit c8edf96

Please sign in to comment.