From 60d5440dd3514e71b87948ff5ed30ee38445b8a5 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 15 Feb 2015 11:01:46 +0100 Subject: o wip. Test cases! --- Bluetooth.cpp | 25 +++++++++++++------------ Bluetooth.h | 10 ++++++---- ByteBuffer.cpp | 4 +++- ByteBuffer.h | 8 ++++++++ CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++---- LinuxBluetooth.cpp | 20 +++++++++----------- main.cpp | 4 ++-- test/ByteBufferTest.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 124 insertions(+), 34 deletions(-) create mode 100644 test/ByteBufferTest.cpp diff --git a/Bluetooth.cpp b/Bluetooth.cpp index 5dca8fa..dd9e48e 100644 --- a/Bluetooth.cpp +++ b/Bluetooth.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include "Bluetooth.h" namespace trygvis { @@ -15,12 +14,12 @@ namespace trygvis { 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(); } @@ -91,7 +90,7 @@ namespace trygvis { } } - vector* AttPdu::parseReadByGroupType(ByteBuffer &bytes) { + vector AttPdu::parseReadByGroupType(ByteBuffer &bytes) { checkType(bytes, READ_BY_GROUP_TYPE_RES); if (bytes.getSize() < 4) { @@ -104,9 +103,9 @@ namespace trygvis { size_t count = (bytes.getSize() - 2) / length; DF << "count=" << count; - vector *values = new vector; + vector values; for (int i = 0; i < count; i++) { - values->push_back(AttributeData::fromByteBuffer(bytes, length)); + values.push_back(AttributeData::fromByteBuffer(bytes, length)); } return values; @@ -116,13 +115,15 @@ namespace trygvis { // AttributeData // ----------------------------------------------------------------------- - AttributeData* AttributeData::fromByteBuffer(ByteBuffer &bytes, uint8_t length) { + AttributeData AttributeData::fromByteBuffer(ByteBuffer &bytes, uint8_t length) { uint16_t handle = bytes.get16le(); + uint16_t groupEndHandle = bytes.get16le(); - return new AttributeData(handle, bytes.view(length)); + return AttributeData(handle, groupEndHandle, bytes.view(length)); } - AttributeData::AttributeData(uint16_t handle, ByteBuffer bytes) : handle(handle), value(value) { + AttributeData::AttributeData(uint16_t handle, uint16_t groupEndHandle, ByteBuffer value) : + handle(handle), groupEndHandle(groupEndHandle), value(value) { } AttributeData::~AttributeData() { diff --git a/Bluetooth.h b/Bluetooth.h index a0fd2c6..15ef171 100644 --- a/Bluetooth.h +++ b/Bluetooth.h @@ -114,7 +114,7 @@ namespace trygvis { AttPduType getType(); - static vector* parseReadByGroupType(ByteBuffer &bytes); + static vector parseReadByGroupType(ByteBuffer &bytes); static void makeReadByGroupType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, uint16_t uuid); @@ -126,14 +126,16 @@ namespace trygvis { class AttributeData { public: - static AttributeData* fromByteBuffer(ByteBuffer &value, uint8_t length); + ~AttributeData(); + + static AttributeData fromByteBuffer(ByteBuffer &value, uint8_t length); const uint16_t handle; + const uint16_t groupEndHandle; const ByteBuffer value; private: - AttributeData(uint16_t handle, ByteBuffer value); - ~AttributeData(); + AttributeData(uint16_t handle, uint16_t groupEndHandle, ByteBuffer value); }; // BluetoothAdapter &getAdapter(int hciDevice); diff --git a/ByteBuffer.cpp b/ByteBuffer.cpp index 912e697..f27deeb 100644 --- a/ByteBuffer.cpp +++ b/ByteBuffer.cpp @@ -3,11 +3,13 @@ #include #include #include +#include using namespace std; ByteBuffer::ByteBuffer(uint8_t *bytes, size_t capacity, size_t size, size_t zero) : bytes(bytes), capacity(capacity), size(size), cursor(zero), zero(zero) { + assert(zero <= size); } ByteBuffer &ByteBuffer::add8(uint8_t value) { @@ -73,7 +75,7 @@ std::string ByteBuffer::toString() const { stringstream s; for(size_t i = zero; i < size; i++) { - s << hex << setfill('0') << setw(2) << bytes[i] << " "; + s << hex << setfill('0') << setw(2) << (int) bytes[i] << " "; } return string(s.str()); diff --git a/ByteBuffer.h b/ByteBuffer.h index c93b5f1..828ee4b 100644 --- a/ByteBuffer.h +++ b/ByteBuffer.h @@ -20,6 +20,14 @@ public: return size; } + inline size_t getCapacity() { + return capacity; + } + + inline size_t getCursor() { + return cursor; + } + inline void setCursor(size_t newCursor) { cursor = newCursor; } diff --git a/CMakeLists.txt b/CMakeLists.txt index e23e674..1220f20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,13 +9,46 @@ set(Boost_USE_STATIC_RUNTIME OFF) add_definitions(-DBOOST_ALL_DYN_LINK) -find_package(Boost REQUIRED COMPONENTS system log thread) +find_package(Boost COMPONENTS system log thread REQUIRED) -set(SOURCE_FILES "${SOURCE_FILES}" main.cpp Bluetooth.cpp LinuxBluetooth.cpp) -set(SOURCE_FILES "${SOURCE_FILES}" ByteBuffer.cpp) +set(SOURCE_FILES "${SOURCE_FILES}" + Bluetooth.cpp + LinuxBluetooth.cpp + ByteBuffer.cpp) -add_executable(ble_toys ${SOURCE_FILES}) +add_library(ble ${SOURCE_FILES}) + +add_executable(ble_toys main.cpp) target_link_libraries(ble_toys bluetooth) target_link_libraries(ble_toys pthread) target_link_libraries(ble_toys ${Boost_LIBRARIES}) +target_link_libraries(ble_toys ble) + +enable_testing() +find_package(Boost COMPONENTS unit_test_framework REQUIRED) +file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test/*.cpp) + +foreach(testSrc ${TEST_SRCS}) + #Extract the filename without an extension (NAME_WE) + get_filename_component(testName ${testSrc} NAME_WE) + + #Add compile target + add_executable(${testName} ${testSrc}) + + include_directories(${PROJECT_SOURCE_DIR}) + + #link to Boost libraries AND your targets and dependencies + target_link_libraries(${testName} ${Boost_LIBRARIES}) + target_link_libraries(${testName} ble) + + #I like to move testing binaries into a testBin directory + set_target_properties(${testName} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) + + #Finally add it to test execution - + #Notice the WORKING_DIRECTORY and COMMAND + add_test(NAME ${testName} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test + COMMAND ${CMAKE_BINARY_DIR}/test/${testName} ) +endforeach(testSrc) diff --git a/LinuxBluetooth.cpp b/LinuxBluetooth.cpp index a15f350..c30a2b7 100644 --- a/LinuxBluetooth.cpp +++ b/LinuxBluetooth.cpp @@ -129,12 +129,12 @@ namespace trygvis { addr.l2_family = AF_BLUETOOTH; addr.l2_cid = htobs(ATT_CID); addr.l2_bdaddr_type = BDADDR_LE_RANDOM; - _mac.copy(addr.l2_bdaddr.b[0], - addr.l2_bdaddr.b[1], - addr.l2_bdaddr.b[2], - addr.l2_bdaddr.b[3], + _mac.copy(addr.l2_bdaddr.b[5], addr.l2_bdaddr.b[4], - addr.l2_bdaddr.b[5]); + addr.l2_bdaddr.b[3], + addr.l2_bdaddr.b[2], + addr.l2_bdaddr.b[1], + addr.l2_bdaddr.b[0]); if (::connect(l2cap, (struct sockaddr *) &addr, sizeof(addr)) < 0) { close(l2cap); @@ -165,15 +165,13 @@ namespace trygvis { D << "read: " << r << " bytes"; - vector *values = AttPdu::parseReadByGroupType(in); + vector values = AttPdu::parseReadByGroupType(in); - D << "READ_BY_GROUP_TYPE response has " + to_string(values->size()) + " values"; + D << "READ_BY_GROUP_TYPE response has " + to_string(values.size()) + " values"; - for (auto &data: *values) { - D << "handle: " << data->handle << ", value: " << data->value.toString(); + for (auto &data: values) { + D << "handle: " << data.handle << ", value: " << data.value.toString(); } - - delete values; } // ----------------------------------------------------------------------- diff --git a/main.cpp b/main.cpp index 7caa303..0ff7eed 100644 --- a/main.cpp +++ b/main.cpp @@ -44,8 +44,8 @@ int main(int argc, char *argv[]) { // adapter->runScan(scan_callback); e = EXIT_SUCCESS; - } catch (BluetoothException ex) { - W << "BluetoothException: " << ex.what(); + } catch (std::runtime_error ex) { + W << "std::runtime_error: " << ex.what(); e = EXIT_FAILURE; } catch (std::exception ex) { W << "std::exception: " << ex.what(); diff --git a/test/ByteBufferTest.cpp b/test/ByteBufferTest.cpp new file mode 100644 index 0000000..f98a770 --- /dev/null +++ b/test/ByteBufferTest.cpp @@ -0,0 +1,46 @@ +#include "ByteBuffer.h" + +#define BOOST_TEST_DYN_LINK + +//Define our Module name (prints at testing) +#define BOOST_TEST_MODULE "ByteBuffer" + +#include + +void checkBuffer(ByteBuffer& buffer, size_t size, size_t capacity, size_t cursor) { + BOOST_CHECK(buffer.getSize() == size); + BOOST_CHECK(buffer.getCapacity() == capacity); + BOOST_CHECK(buffer.getCursor() == cursor); +} + +BOOST_AUTO_TEST_CASE(empty_buffer) { + uint8_t bytes[1000]; + + for (int i = 0; i < sizeof(bytes); i++) { + bytes[i] = (uint8_t) i; + } + + ByteBuffer buffer(bytes, sizeof(bytes), 0, 0); + + checkBuffer(buffer, 0, 1000, 0); + + try { + buffer.get8(); + BOOST_FAIL("Expected exception"); + } catch (ByteBufferException e) { + } +} + +BOOST_AUTO_TEST_CASE(basic) { + uint8_t bytes[1000]; + + for (int i = 0; i < sizeof(bytes); i++) { + bytes[i] = (uint8_t) i; + } + + ByteBuffer buffer(bytes, sizeof(bytes), 10, 0); + checkBuffer(buffer, 10, 1000, 0); + + buffer.get8(); + checkBuffer(buffer, 10, 1000, 1); +} -- cgit v1.2.3