From ffa313e80a27005405334db6491075442f6e1abd Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 20 Dec 2018 08:35:51 +0100 Subject: Mac: o Using more natural byte ordering in the code. No external effect. o Using global ==, != and < operators instead of in-class operators for better compatibility with STL. ByteBuffer: o Renaming setPosition() to setCursor(). --- apps/SoilMoisture.cpp | 2 +- apps/ble-scan.cpp | 6 +++++- ble/Bluetooth.cpp | 43 ++++++++++++++++++++++++------------------- ble/LinuxBluetooth.cpp | 13 +++++++------ include/ble/Bluetooth.h | 27 +++++++++++++++++---------- include/ble/ByteBuffer.h | 8 +++++--- test/ByteBufferTest.cpp | 10 +++++----- test/CMakeLists.txt | 19 ++++++++++++++----- test/MacTest.cpp | 30 ++++++++++++++++++++++++++++++ 9 files changed, 108 insertions(+), 50 deletions(-) create mode 100644 test/MacTest.cpp diff --git a/apps/SoilMoisture.cpp b/apps/SoilMoisture.cpp index fcf81bd..3de85d2 100644 --- a/apps/SoilMoisture.cpp +++ b/apps/SoilMoisture.cpp @@ -95,7 +95,7 @@ SoilMoisture::SoilMoisture(const BluetoothGattPtr &gatt, temperatureCharacteristic(temperatureCharacteristic), lightCharacteristic(lightCharacteristic) {} void SoilMoisture::writeAndRead(const BluetoothGattCharacteristicPtr &c, ByteBuffer &buffer) { - buffer.setPosition(0); + buffer.setCursor(0); uint8_t expectedCode = buffer.peek8(0); diff --git a/apps/ble-scan.cpp b/apps/ble-scan.cpp index b148752..6d271da 100644 --- a/apps/ble-scan.cpp +++ b/apps/ble-scan.cpp @@ -64,7 +64,11 @@ public: cout << "Stopped. Found " << seen_devices.size() << " devices." << endl; - for_each(begin(seen_devices), end(seen_devices), [&](auto mac) { cout << mac.str() << endl; }); + vector devices(seen_devices.cbegin(), seen_devices.cend()); + std::sort(devices.begin(), devices.end(), [](const Mac& a, const Mac& b) { + return a < b; + }); + for_each(begin(devices), end(devices), [&](auto mac) { cout << " " << mac.str() << endl; }); return EXIT_SUCCESS; } catch (std::runtime_error &ex) { diff --git a/ble/Bluetooth.cpp b/ble/Bluetooth.cpp index 16f4224..735a29b 100644 --- a/ble/Bluetooth.cpp +++ b/ble/Bluetooth.cpp @@ -20,48 +20,53 @@ string Mac::str() const { std::ostringstream buf; buf - << setw(2) << hex << setfill('0') << (int) bytes[5] << ":" - << setw(2) << hex << setfill('0') << (int) bytes[4] << ":" - << setw(2) << hex << setfill('0') << (int) bytes[3] << ":" - << setw(2) << hex << setfill('0') << (int) bytes[2] << ":" + << setw(2) << hex << setfill('0') << (int) bytes[0] << ":" << setw(2) << hex << setfill('0') << (int) bytes[1] << ":" - << setw(2) << hex << setfill('0') << (int) bytes[0]; + << setw(2) << hex << setfill('0') << (int) bytes[2] << ":" + << setw(2) << hex << setfill('0') << (int) bytes[3] << ":" + << setw(2) << hex << setfill('0') << (int) bytes[4] << ":" + << setw(2) << hex << setfill('0') << (int) bytes[5]; return buf.str(); } -bool Mac::operator==(Mac &other) const { - const uint8_t *b = bytes; - return memcmp(b, other.bytes, sizeof(bytes)) == 0; +bool operator==(const Mac &a, const Mac &b) { + return memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0; } -bool Mac::operator!=(Mac &other) const { - return !operator==(other); +bool operator!=(const Mac &a, const Mac &b) { + return !(a == b); } -bool operator<(const Mac &a, const Mac &b) { +bool operator<(const Mac &a, const Mac &b) +{ return memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0; } -void Mac::copy(uint8_t &_5, uint8_t &_4, uint8_t &_3, uint8_t &_2, uint8_t &_1, uint8_t &_0) const { - _5 = bytes[5]; - _4 = bytes[4]; - _3 = bytes[3]; - _2 = bytes[2]; - _1 = bytes[1]; +std::ostream& operator<<(std::ostream& os, const Mac& mac) { +os << mac.str(); +return os; +} + +void Mac::copy(uint8_t &_0, uint8_t &_1, uint8_t &_2, uint8_t &_3, uint8_t &_4, uint8_t &_5) const { _0 = bytes[0]; + _1 = bytes[1]; + _2 = bytes[2]; + _3 = bytes[3]; + _4 = bytes[4]; + _5 = bytes[5]; } Mac Mac::parseMac(string s) { unsigned int bytes[6]; int count = sscanf(s.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", - &bytes[5], &bytes[4], &bytes[3], &bytes[2], &bytes[1], &bytes[0]); + &bytes[0], &bytes[1], &bytes[2], &bytes[3], &bytes[4], &bytes[5]); if (count != 6) { throw BluetoothException("Unable to parseAttributeData mac: " + s); } - return Mac((uint8_t) bytes[5], (uint8_t) bytes[4], (uint8_t) bytes[3], (uint8_t) bytes[2], (uint8_t) bytes[1], (uint8_t) bytes[0]); + return Mac((uint8_t) bytes[0], (uint8_t) bytes[1], (uint8_t) bytes[2], (uint8_t) bytes[3], (uint8_t) bytes[4], (uint8_t) bytes[5]); } // ----------------------------------------------------------------------- diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp index 9e7193f..3c4925c 100644 --- a/ble/LinuxBluetooth.cpp +++ b/ble/LinuxBluetooth.cpp @@ -307,7 +307,7 @@ void LinuxBluetoothGatt::writeHandle(uint16_t handle, const ByteBuffer &bytes) { writeAndRead(buffer, buffer); auto cursor = buffer.getPosition(); - buffer.setPosition(0); + buffer.setCursor(0); AttPdu::parseWrite(buffer); @@ -319,7 +319,7 @@ void LinuxBluetoothGatt::writeHandle(uint16_t handle, const ByteBuffer &bytes) { } } -ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristicPtr &c, ByteBuffer &response) { +ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristicPtr &c, ByteBuffer& response) { uint8_t b[mtu]; ByteBuffer buffer{b, mtu}; @@ -328,7 +328,7 @@ ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristicPtr &c writeAndRead(buffer, response); auto cursor = response.getPosition(); - response.setPosition(0); + response.setCursor(0); AttPdu::parseRead(response); @@ -428,7 +428,7 @@ void LinuxBluetoothGatt::discoverServices() { } while (startHandle != 0xffff); } -void LinuxBluetoothGatt::writeAndRead(const ByteBuffer &buffer, ByteBuffer &response) { +void LinuxBluetoothGatt::writeAndRead(const ByteBuffer &buffer, ByteBuffer& response) { // LOG_DEBUG("pdu size=" << out.getCursor()); auto to_be_written = buffer.getPosition(); @@ -447,8 +447,9 @@ void LinuxBluetoothGatt::writeAndRead(const ByteBuffer &buffer, ByteBuffer &resp throw BluetoothException(&device, "read(): " + errnoAsString()); } - response.setPosition(static_cast(r)); + response.setCursor(static_cast(r)); LOG_DEBUG("read: " << r << " bytes: " << response.viewBeginningToCursor().toString()); + response.setCursor(static_cast(r)); } void LinuxBluetoothGatt::writeL2cap(ByteBuffer &buffer) { @@ -459,7 +460,7 @@ void LinuxBluetoothGatt::writeL2cap(ByteBuffer &buffer) { throw BluetoothException(&device, "Expected to write " + to_string(to_be_written) + " but wrote only " + to_string(written)); } - buffer.setPosition(0); + buffer.setCursor(0); } AttVariant LinuxBluetoothGatt::processAvailableMessages(ByteBuffer &buffer) { diff --git a/include/ble/Bluetooth.h b/include/ble/Bluetooth.h index 28e2794..80becec 100644 --- a/include/ble/Bluetooth.h +++ b/include/ble/Bluetooth.h @@ -38,31 +38,38 @@ typedef std::shared_ptr BluetoothAdapterPtr; class Mac { public: - explicit Mac(uint8_t _5, uint8_t _4, uint8_t _3, uint8_t _2, uint8_t _1, uint8_t _0) : bytes() { - bytes[5] = _5; - bytes[4] = _4; - bytes[3] = _3; - bytes[2] = _2; - bytes[1] = _1; + explicit Mac(uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5) : bytes() { bytes[0] = _0; + bytes[1] = _1; + bytes[2] = _2; + bytes[3] = _3; + bytes[4] = _4; + bytes[5] = _5; }; string str() const; - bool operator==(Mac &other) const; +// bool operator==(const Mac &other) const; +// bool operator!=(const Mac &other) const; +// bool operator<(const Mac &other) const; - bool operator!=(Mac &other) const; - - void copy(uint8_t &_5, uint8_t &_4, uint8_t &_3, uint8_t &_2, uint8_t &_1, uint8_t &_0) const; + void copy(uint8_t &_0, uint8_t &_1, uint8_t &_2, uint8_t &_3, uint8_t &_4, uint8_t &_5) const; static Mac parseMac(string s); friend bool operator<(const Mac &a, const Mac &b); + friend bool operator==(const Mac &a, const Mac &b); private: uint8_t bytes[6]; }; +std::ostream& operator<<(std::ostream& os, const Mac& mac); + +bool operator==(const Mac &a, const Mac &b); +bool operator!=(const Mac &a, const Mac &b); +bool operator<(const Mac &a, const Mac &b); + class BluetoothCallback { virtual ~BluetoothCallback() = default; diff --git a/include/ble/ByteBuffer.h b/include/ble/ByteBuffer.h index 6b09049..1ba088f 100644 --- a/include/ble/ByteBuffer.h +++ b/include/ble/ByteBuffer.h @@ -42,7 +42,7 @@ public: ByteBuffer(uint8_t *bytes, size_t size) noexcept : zero(bytes), end_(&bytes[size]), cursor(zero) {}; ByteBuffer(uint8_t *bytes, size_t size, size_t position) : zero(bytes), end_(&bytes[size]), cursor(zero) { - setPosition(position); + setCursor(position); }; template @@ -64,8 +64,10 @@ public: return end_ - cursor; } - inline ByteBuffer &setPosition(size_t newCursor) { - cursor = &zero[newCursor]; + inline ByteBuffer &setCursor(size_t newCursor) { + auto tmp = &zero[newCursor]; + assertCanAccessPtr(tmp); + cursor = tmp; return *this; } diff --git a/test/ByteBufferTest.cpp b/test/ByteBufferTest.cpp index 9f26971..7af18ef 100644 --- a/test/ByteBufferTest.cpp +++ b/test/ByteBufferTest.cpp @@ -70,13 +70,13 @@ BOOST_AUTO_TEST_CASE(setCursor) { BOOST_CHECK_EQUAL(buffer.read8(), 0); checkBuffer(buffer, 1000, 1); - buffer.setPosition(0); + buffer.setCursor(0); checkBuffer(buffer, 1000, 0); BOOST_CHECK_EQUAL(buffer.read8(), 0); checkBuffer(buffer, 1000, 1); - buffer.setPosition(9); + buffer.setCursor(9); checkBuffer(buffer, 1000, 9); } @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(ieee_11073_20601_float_1_0d) { ByteBuffer buffer(b.bytes, b.capacity); buffer.writeFLOAT(1.0); - buffer.setPosition(0); + buffer.setCursor(0); BOOST_CHECK_EQUAL(buffer.readFLOAT(), 1.0); } @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(ieee_11073_20601_float_nan) { BOOST_CHECK_EQUAL(std::isnan(stof("NaN")), true); buffer.writeFLOAT(stof("NaN")); - buffer.setPosition(0); + buffer.setCursor(0); BOOST_CHECK_EQUAL(std::isnan(buffer.readFLOAT()), true); } @@ -120,7 +120,7 @@ void c(double input, uint32_t hx, double sigma = 0.00001) { Bytes b(1000); ByteBuffer buffer(b.bytes, b.capacity); buffer.writeFLOAT(input); - buffer.setPosition(0); + buffer.setCursor(0); double output = buffer.readFLOAT(); stringstream str; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4671329..86f2b1b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,11 @@ find_package(Boost COMPONENTS log regex unit_test_framework REQUIRED QUIET) +find_header_and_lib(LOG4CPLUS log4cplus/logger.h log4cplus REQUIRED QUIET) # If we can change directory here add_definition and test-specific stuff could be moved to the test directory -file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *Test.cpp) +set(TEST_SRCS + ByteBufferTest.cpp + MacTest.cpp + UuidTest.cpp) add_definitions(-DBOOST_TEST_DYN_LINK) foreach(testSrc ${TEST_SRCS}) @@ -11,14 +15,19 @@ foreach(testSrc ${TEST_SRCS}) #Add compile target add_executable(${testName} ${testSrc}) - include_directories("${PROJECT_SOURCE_DIR}/ble") - include_directories("${PROJECT_SOURCE_DIR}/include") + target_include_directories(${testName} PUBLIC "${PROJECT_SOURCE_DIR}/ble") + target_include_directories(${testName} PUBLIC "${PROJECT_SOURCE_DIR}/include") + add_dependencies(${testName} ble) target_link_libraries(${testName} ble) + target_link_libraries(${testName} bluetooth) + + target_include_directories(${testName} PUBLIC "${PROJECT_SOURCE_DIR}/apps") + target_link_libraries(${testName} pthread) target_link_libraries(${testName} ${Boost_LIBRARIES}) - - include_directories("${PROJECT_SOURCE_DIR}/apps") + target_include_directories(${testName} PUBLIC "${LOG4CPLUS_INCLUDE_DIRECTORY}") + target_link_libraries(${testName} "${LOG4CPLUS_LIBRARY}") #I like to move testing binaries into a testBin directory set_target_properties(${testName} PROPERTIES diff --git a/test/MacTest.cpp b/test/MacTest.cpp new file mode 100644 index 0000000..7af1624 --- /dev/null +++ b/test/MacTest.cpp @@ -0,0 +1,30 @@ +#include "ble/Bluetooth.h" + +#define BOOST_TEST_MODULE "MacTest" + +#include + +using trygvis::bluetooth::Mac; + +BOOST_AUTO_TEST_CASE(parseMac) { + auto mac = Mac::parseMac("11:22:33:44:55:FF"); + uint8_t b1, b2, b3, b4, b5, b6; + mac.copy(b1, b2, b3, b4, b5, b6); + BOOST_CHECK_EQUAL(0x11, b1); + BOOST_CHECK_EQUAL(0x22, b2); + BOOST_CHECK_EQUAL(0x33, b3); + BOOST_CHECK_EQUAL(0x44, b4); + BOOST_CHECK_EQUAL(0x55, b5); + BOOST_CHECK_EQUAL(0xff, b6); + BOOST_CHECK_EQUAL("11:22:33:44:55:ff", mac.str()); +} + +BOOST_AUTO_TEST_CASE(equal) { + Mac a(0x11, 0x22, 0x33, 0x44, 0x55, 0xFF); + auto a2 = Mac::parseMac("11:22:33:44:55:FF"); + BOOST_CHECK_EQUAL(a, a2); + + Mac b(0x11, 0x22, 0x33, 0xff, 0x10, 0x02); + + BOOST_CHECK_LT(a, b); +} -- cgit v1.2.3