fixed at least 1 bug in the uart handling code and cleaned it up a lot
diff --git a/aos/build/aos_all.gyp b/aos/build/aos_all.gyp
index 1aa6063..0629be5 100644
--- a/aos/build/aos_all.gyp
+++ b/aos/build/aos_all.gyp
@@ -21,6 +21,8 @@
'../common/common.gyp:die_test',
'../common/util/util.gyp:trapezoid_profile_test',
'../common/util/util.gyp:wrapping_counter_test',
+ '<(DEPTH)/bbb_cape/src/bbb/bbb.gyp:cows_test',
+ '<(DEPTH)/bbb_cape/src/bbb/bbb.gyp:packet_finder_test',
'Common',
],
},
diff --git a/bbb_cape/src/bbb/bbb.gyp b/bbb_cape/src/bbb/bbb.gyp
index 82f328a..9ea4bb3 100644
--- a/bbb_cape/src/bbb/bbb.gyp
+++ b/bbb_cape/src/bbb/bbb.gyp
@@ -19,20 +19,53 @@
'target_name': 'uart_reader',
'type': 'static_library',
'dependencies': [
- 'crc',
- '<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
'<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
'<(AOS)/build/aos.gyp:logging',
+ 'packet_finder',
],
'export_dependent_settings': [
'<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
],
'sources': [
'uart_reader.cc',
- 'packet_finder.cc',
'uart_reader_termios2.c',
],
},
+ {
+ 'target_name': 'cows_test',
+ 'type': 'executable',
+ 'dependencies': [
+ '<(EXTERNALS):gtest',
+ '<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
+ ],
+ 'sources': [
+ 'cows_test.cc',
+ ],
+ },
+ {
+ 'target_name': 'packet_finder_test',
+ 'type': 'executable',
+ 'dependencies': [
+ '<(EXTERNALS):gtest',
+ 'packet_finder',
+ '<(AOS)/common/common.gyp:queue_testutils',
+ ],
+ 'sources': [
+ 'packet_finder_test.cc',
+ ],
+ },
+ {
+ 'target_name': 'packet_finder',
+ 'type': 'static_library',
+ 'sources': [
+ 'packet_finder.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
+ '<(AOS)/build/aos.gyp:logging',
+ 'crc',
+ ],
+ },
#{
# 'target_name': 'uart_reader_test',
# 'type': 'executable',
diff --git a/bbb_cape/src/bbb/byte_reader.h b/bbb_cape/src/bbb/byte_reader.h
new file mode 100644
index 0000000..8319ccb
--- /dev/null
+++ b/bbb_cape/src/bbb/byte_reader.h
@@ -0,0 +1,21 @@
+#ifndef BBB_BYTE_READER_H_
+#define BBB_BYTE_READER_H_
+
+#include <sys/types.h>
+
+namespace bbb {
+
+class ByteReader {
+ public:
+ // We have 64-bit ints in some of our data.
+ typedef char __attribute__((aligned(8))) AlignedChar;
+
+ // Implemented by subclasses to provide a data source
+ // for these algorithms.
+ // Returns the number of bytes read or -1 if there is an error in errno.
+ virtual ssize_t ReadBytes(AlignedChar *dest, size_t max_bytes) = 0;
+};
+
+} // namespace bbb
+
+#endif // BBB_BYTE_READER_H_
diff --git a/bbb_cape/src/bbb/cows_test.cc b/bbb_cape/src/bbb/cows_test.cc
new file mode 100644
index 0000000..06eba5b
--- /dev/null
+++ b/bbb_cape/src/bbb/cows_test.cc
@@ -0,0 +1,17 @@
+#include "cape/cows.h"
+
+#include <gtest/gtest.h>
+
+namespace testing {
+
+TEST(CowsTest, StupidZeros) {
+ static const uint8_t kTestInput[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01,
+ 0x00};
+ uint32_t input[3];
+ memcpy(input, kTestInput, 12);
+ uint32_t output[2];
+ EXPECT_EQ(
+ 1u, cows_unstuff(input, sizeof(kTestInput), output, sizeof(output) * 4));
+}
+
+} // namespace testing
diff --git a/bbb_cape/src/bbb/packet_finder.cc b/bbb_cape/src/bbb/packet_finder.cc
index dfc5784..298edc7 100644
--- a/bbb_cape/src/bbb/packet_finder.cc
+++ b/bbb_cape/src/bbb/packet_finder.cc
@@ -2,6 +2,7 @@
#include <errno.h>
#include <inttypes.h>
+#include <assert.h>
#include <algorithm>
@@ -9,15 +10,14 @@
#include "bbb_cape/src/cape/cows.h"
#include "bbb/crc.h"
-#define PACKET_SIZE (DATA_STRUCT_SEND_SIZE - 4)
-
namespace bbb {
-PacketFinder::PacketFinder()
- : buf_(new AlignedChar[PACKET_SIZE]),
- unstuffed_data_(new AlignedChar[PACKET_SIZE - 4]) {
- static_assert((PACKET_SIZE % 4) == 0,
- "We can't do checksums of lengths that aren't multiples of 4.");
+PacketFinder::PacketFinder(ByteReader *reader, size_t packet_size)
+ : reader_(reader),
+ packet_size_(packet_size),
+ buf_(new AlignedChar[packet_size_]),
+ unstuffed_data_(new AlignedChar[packet_size_ - 4]) {
+ assert((packet_size_ % 4) == 0);
}
PacketFinder::~PacketFinder() {
@@ -33,11 +33,10 @@
while (true) {
size_t already_read = ::std::max(0, packet_bytes_);
ssize_t new_bytes =
- ReadBytes(buf_ + already_read, PACKET_SIZE - already_read);
+ reader_->ReadBytes(buf_ + already_read, packet_size_ - already_read);
if (new_bytes < 0) {
- if (errno == EINTR) continue;
LOG(ERROR, "ReadBytes(%p, %zd) failed with %d: %s\n",
- buf_ + already_read, PACKET_SIZE - already_read,
+ buf_ + already_read, packet_size_ - already_read,
errno, strerror(errno));
return false;
}
@@ -53,6 +52,7 @@
new_bytes -= to_check + 1;
memmove(buf_, buf_ + to_check + 1, new_bytes);
to_check = 0;
+ break;
}
} else {
zeros_found = 0;
@@ -61,29 +61,29 @@
}
if (packet_bytes_ != -1) { // if we decided that these are good bytes
packet_bytes_ += new_bytes;
- if (packet_bytes_ == PACKET_SIZE) return true;
+ if (packet_bytes_ == static_cast<ssize_t>(packet_size_)) return true;
}
}
}
bool PacketFinder::ProcessPacket() {
uint32_t unstuffed = cows_unstuff(
- reinterpret_cast<uint32_t *>(buf_), PACKET_SIZE,
- reinterpret_cast<uint32_t *>(unstuffed_data_), PACKET_SIZE - 4);
+ reinterpret_cast<uint32_t *>(buf_), packet_size_,
+ reinterpret_cast<uint32_t *>(unstuffed_data_), packet_size_ - 4);
if (unstuffed == 0) {
LOG(WARNING, "invalid packet\n");
return false;
- } else if (unstuffed != (PACKET_SIZE - 4) / 4) {
+ } else if (unstuffed != (packet_size_ - 4) / 4) {
LOG(WARNING, "packet is %" PRIu32 " words instead of %" PRIu32 "\n",
- unstuffed, (PACKET_SIZE - 4) / 4);
+ unstuffed, (packet_size_ - 4) / 4);
return false;
}
// Make sure the checksum checks out.
uint32_t sent_checksum;
- memcpy(&sent_checksum, unstuffed_data_ + PACKET_SIZE - 8, 4);
+ memcpy(&sent_checksum, unstuffed_data_ + packet_size_ - 8, 4);
uint32_t calculated_checksum = cape::CalculateChecksum(
- reinterpret_cast<uint8_t *>(unstuffed_data_), PACKET_SIZE - 8);
+ reinterpret_cast<uint8_t *>(unstuffed_data_), packet_size_ - 8);
if (sent_checksum != calculated_checksum) {
LOG(WARNING, "sent checksum: %" PRIx32 " vs calculated: %" PRIx32"\n",
sent_checksum, calculated_checksum);
@@ -99,12 +99,12 @@
if (!ProcessPacket()) {
packet_bytes_ = -1;
int zeros = 0;
- for (int i = 0; i < PACKET_SIZE; ++i) {
+ for (size_t i = 0; i < packet_size_; ++i) {
if (buf_[i] == 0) {
++zeros;
if (zeros == 4) {
LOG(INFO, "found another packet start at %d\n", i);
- packet_bytes_ = PACKET_SIZE - (i + 1);
+ packet_bytes_ = packet_size_ - (i + 1);
memmove(buf_, buf_ + i + 1, packet_bytes_);
return false;
}
diff --git a/bbb_cape/src/bbb/packet_finder.h b/bbb_cape/src/bbb/packet_finder.h
index ee2e133..8d02caf 100644
--- a/bbb_cape/src/bbb/packet_finder.h
+++ b/bbb_cape/src/bbb/packet_finder.h
@@ -4,6 +4,10 @@
#include <stdint.h>
#include <string.h>
+#include "aos/common/logging/logging.h"
+
+#include "bbb/byte_reader.h"
+
#define DATA_STRUCT_NAME DataStruct
#include "cape/data_struct.h"
#undef DATA_STRUCT_NAME
@@ -12,8 +16,10 @@
class PacketFinder {
public:
- PacketFinder();
- virtual ~PacketFinder();
+ // *reader has to stay alive for the entire lifetime of this object but this
+ // object does not take ownership.
+ explicit PacketFinder(ByteReader *reader, size_t packet_size);
+ ~PacketFinder();
// Returns true if it succeeds or false if it gets an I/O error first.
bool ReadPacket();
@@ -25,19 +31,12 @@
const T *get_packet() {
static_assert(alignof(T) <= alignof(*unstuffed_data_),
"We need to align our data better.");
- /*static_assert(sizeof(T) <= PACKET_SIZE - 8,
- "We aren't getting that much data.");*/
+ CHECK(sizeof(T) <= packet_size_ - 8);
return reinterpret_cast<const T *>(unstuffed_data_);
}
- protected:
- typedef char __attribute__((aligned(8))) AlignedChar;
-
private:
- // Implemented by subclasses to provide a data source
- // for these algorithms.
- // Returns the number of bytes read or -1 if there is an error in errno.
- virtual int ReadBytes(AlignedChar *dest, size_t max_bytes) = 0;
+ typedef ByteReader::AlignedChar AlignedChar;
// Reads bytes until there are 4 zeros and then fills up buf_.
// Returns true if it finds one or false if it gets an I/O error first or the
@@ -50,6 +49,9 @@
// data.
bool ProcessPacket();
+ ByteReader *const reader_;
+ const size_t packet_size_;
+
AlignedChar *const buf_;
AlignedChar *const unstuffed_data_;
diff --git a/bbb_cape/src/bbb/packet_finder_test.cc b/bbb_cape/src/bbb/packet_finder_test.cc
new file mode 100644
index 0000000..e2e820a
--- /dev/null
+++ b/bbb_cape/src/bbb/packet_finder_test.cc
@@ -0,0 +1,122 @@
+#include "bbb/packet_finder.h"
+
+#include "gtest/gtest.h"
+
+#include "aos/common/queue_testutils.h"
+
+#include "bbb/byte_reader.h"
+
+namespace bbb {
+namespace testing {
+
+class PacketFinderTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ ::aos::common::testing::EnableTestLogging();
+ }
+};
+
+class TestByteReader : public ByteReader {
+ public:
+ TestByteReader(const void *data, size_t data_size)
+ : data_(data), data_size_(data_size), bytes_left_(data_size) {}
+
+ virtual ssize_t ReadBytes(AlignedChar *dest, size_t max_bytes) {
+ size_t to_transfer = ::std::min(max_bytes, bytes_left_);
+ memcpy(dest, static_cast<const uint8_t *>(data_) + data_size_ - bytes_left_,
+ to_transfer);
+ bytes_left_ -= to_transfer;
+ return to_transfer;
+ }
+
+ private:
+ const void *const data_;
+ const size_t data_size_;
+ size_t bytes_left_;
+};
+
+TEST_F(PacketFinderTest, StupidZeros) {
+ static const uint8_t kTestData[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x69, 0x3D, 0xE0, 0x03, 0x02, 0x00, 0x00, 0x00,
+ 0x43, 0x5E, 0x12, 0x16, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x2A, 0x00, 0x1B, 0x00, 0x4E, 0x01, 0x72, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF, 0x90, 0x01, 0x00, 0x20,
+ 0x00, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0xED, 0x00, 0xE0,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0xFF, 0x8E, 0xFE, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0xD0, 0x07, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xA1, 0x79, 0xE0, 0x03,
+ 0x02, 0x00, 0x00, 0x00, 0x43, 0x5E, 0x12, 0x16, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2A, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x29, 0x00, 0x1B, 0x00, 0x50, 0x01, 0x72, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF,
+ 0x90, 0x01, 0x00, 0x20, 0x00, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0xB0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0xF1, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x00, 0x40, 0x00, 0x38, 0x00, 0x40,
+ 0x82, 0x00, 0x00, 0x00, 0xE6, 0x6F, 0x7E, 0xC7, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0xDA, 0xB5, 0xE0, 0x03, 0x02, 0x00, 0x00, 0x00, 0x43, 0x5E, 0x12, 0x16,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x2A, 0x00, 0x1B, 0x00,
+ 0x50, 0x01, 0x72, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0xF1, 0xFF, 0xFF, 0xFF, 0x90, 0x01, 0x00, 0x20, 0x00, 0xED, 0x00, 0xE0,
+ 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x00, 0x40,
+ 0x00, 0x38, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0xDD, 0xD1, 0x5D, 0x8E,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x13, 0xF2, 0xE0, 0x03, 0x02, 0x00, 0x00, 0x00,
+ 0x43, 0x5E, 0x12, 0x16, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x29, 0x00, 0x1B, 0x00, 0x50, 0x01, 0x72, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF, 0x90, 0x01, 0x00, 0x20,
+ 0x00, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xED, 0x00, 0xE0,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x68, 0x26, 0xC4, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4B, 0x2E, 0xE1, 0x03,
+ 0x02, 0x00, 0x00, 0x00, 0x43, 0x5E, 0x12, 0x16, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2A, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x2A, 0x00, 0x1C, 0x00, 0x50, 0x01, 0x72, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF,
+ 0x90, 0x01, 0x00, 0x20, 0x00, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0xF1, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x00, 0x40, 0x00, 0x38, 0x00, 0x40,
+ 0x00, 0x38, 0x00, 0x40, 0xAD, 0x8B, 0x6A, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x10, 0x08, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x84, 0x6A, 0xE1, 0x03, 0x02, 0x00, 0x00, 0x00, 0x43, 0x5E, 0x12, 0x16,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x29, 0x00, 0x1B, 0x00,
+ 0x4E, 0x01, 0x72, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0xF1, 0xFF, 0xFF, 0xFF, 0x90, 0x01, 0x00, 0x20, 0x00, 0xED, 0x00, 0xE0,
+ 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x39, 0x00, 0x00, 0x00, 0x00, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xFC, 0x94, 0x39, 0xF5,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
+ };
+ TestByteReader reader(kTestData, sizeof(kTestData));
+ PacketFinder packet_finder(&reader, 144);
+ EXPECT_TRUE(packet_finder.ReadPacket());
+}
+
+} // namespace testing
+} // namespace bbb
diff --git a/bbb_cape/src/bbb/uart_reader.cc b/bbb_cape/src/bbb/uart_reader.cc
index 7b00c00..03cd248 100644
--- a/bbb_cape/src/bbb/uart_reader.cc
+++ b/bbb_cape/src/bbb/uart_reader.cc
@@ -52,8 +52,12 @@
if (fd_ > 0) close(fd_);
}
-int UartReader::ReadBytes(AlignedChar *dest, size_t max_bytes) {
- return read(fd_, dest, max_bytes);
+ssize_t UartReader::ReadBytes(AlignedChar *dest, size_t max_bytes) {
+ do {
+ ssize_t r = read(fd_, dest, max_bytes);
+ if (r != -1) return r;
+ } while (errno == EINTR);
+ return -1;
}
} // namespace bbb
diff --git a/bbb_cape/src/bbb/uart_reader.h b/bbb_cape/src/bbb/uart_reader.h
index bd022b0..f87af1b 100644
--- a/bbb_cape/src/bbb/uart_reader.h
+++ b/bbb_cape/src/bbb/uart_reader.h
@@ -4,16 +4,16 @@
#include <stdint.h>
#include <string.h>
-#include "bbb/packet_finder.h"
+#include "bbb/byte_reader.h"
namespace bbb {
-class UartReader : public PacketFinder {
+class UartReader : public ByteReader {
public:
UartReader(int32_t baud_rate);
virtual ~UartReader();
- int ReadBytes(AlignedChar *dest, size_t max_bytes);
+ virtual ssize_t ReadBytes(AlignedChar *dest, size_t max_bytes);
private:
const int fd_;
diff --git a/bbb_cape/src/bbb/uart_reader_test.cc b/bbb_cape/src/bbb/uart_reader_test.cc
index 80f634a..53be07e 100644
--- a/bbb_cape/src/bbb/uart_reader_test.cc
+++ b/bbb_cape/src/bbb/uart_reader_test.cc
@@ -1,7 +1,5 @@
#include "bbb/uart_reader.h"
-#include <termios.h>
-
#include "gtest/gtest.h"
namespace bbb {
diff --git a/bbb_cape/src/cape/cows.c b/bbb_cape/src/cape/cows.c
index b896fd7..bcf6308 100644
--- a/bbb_cape/src/cape/cows.c
+++ b/bbb_cape/src/cape/cows.c
@@ -2,11 +2,18 @@
#include <limits.h>
+#if __STDC_HOSTED__
+#include <assert.h>
+#else
+#define assert(...)
+#endif
+
// This implementation is based on
// <http://www.jacquesf.com/2011/03/consistent-overhead-byte-stuffing/>.
uint32_t cows_stuff(const void *__restrict__ source_in, size_t source_length,
void *__restrict__ destination_in) {
+ assert((source_length % 4) == 0);
const uint32_t *restrict source = (const uint32_t *)source_in;
uint32_t *restrict destination = (uint32_t *)destination_in;
size_t source_index = 0;
@@ -14,7 +21,7 @@
size_t code_index = 0;
uint32_t code = 1;
- while (source_index < ((source_length - 1) / 4) + 1) {
+ while (source_index < source_length / 4) {
if (source[source_index] == 0) {
destination[code_index] = code;
code = 1;
@@ -37,11 +44,13 @@
uint32_t cows_unstuff(const uint32_t *__restrict__ source, size_t source_length,
uint32_t *__restrict__ destination,
size_t destination_length) {
+ assert((source_length % 4) == 0);
+ assert((destination_length % 4) == 0);
size_t source_index = 0;
size_t destination_index = 0;
uint32_t code;
- while (source_index < ((source_length - 1) / 4) + 1) {
+ while (1) {
code = source[source_index];
if (source_index + code > source_length / 4 && code != 1) {
return 0;
@@ -50,13 +59,19 @@
++source_index;
for (uint32_t i = 1; i < code; ++i) {
+ if (destination_index >= destination_length / 4) {
+ return 0;
+ }
destination[destination_index++] = source[source_index++];
- if (destination_index > destination_length / 4) return 0;
}
- if (code != UINT32_MAX && source_index != source_length / 4) {
+ if (source_index == source_length / 4) {
+ return destination_index;
+ }
+ if (code != UINT32_MAX) {
+ if (destination_index >= destination_length / 4) {
+ return 0;
+ }
destination[destination_index++] = 0;
- if (destination_index > destination_length / 4) return 0;
}
}
- return destination_index;
}
diff --git a/bbb_cape/src/cape/cows.h b/bbb_cape/src/cape/cows.h
index 442c368..9c47827 100644
--- a/bbb_cape/src/cape/cows.h
+++ b/bbb_cape/src/cape/cows.h
@@ -14,10 +14,10 @@
// because that's more efficient on 32-bit processors. I'm calling it Consistent
// Overhead Word Stuffing.
-// source_length will be rounded up a multiple of 4. That many bytes of source
+// source_length must be a multiple of 4. That many bytes of source
// will be read.
// destination must have at least
-// ([source_length rounded up to a multiple of 4] / (2^32 - 1) rounded up) * 4
+// ((source_length / (2^32 - 1)) rounded up) * 4
// more bytes than source_length available.
// source and destination both have to be 4-byte aligned.
// Returns the total number of words written (not necessarily the maximum given
@@ -25,7 +25,7 @@
uint32_t cows_stuff(const void *__restrict__ source, size_t source_length,
void *__restrict__ destination);
-// source_length will be rounded up a multiple of 4. That many bytes of source
+// source_length must be a multiple of 4. That many bytes of source
// will be read.
// source and destination both have to be 4-byte aligned.
// Returns the total number of words written to destination or 0 for error.
diff --git a/bbb_cape/src/cape/data_struct.h b/bbb_cape/src/cape/data_struct.h
index 68491eb..367c359 100644
--- a/bbb_cape/src/cape/data_struct.h
+++ b/bbb_cape/src/cape/data_struct.h
@@ -61,7 +61,7 @@
// The number of bytes that we actually send (so it stays consistent) (including
// the byte-stuffing overhead and the CRC on the end).
// This will always be a multiple of 4.
-#define DATA_STRUCT_SEND_SIZE 200
+#define DATA_STRUCT_SEND_SIZE 148
#ifdef __cplusplus
#define STATIC_ASSERT(cond, msg) static_assert(cond, #msg)