Skip to content

Commit

Permalink
Update and fix tests, minor Packet class tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
microstrain-sam committed Nov 6, 2024
1 parent 1b89fe7 commit 188dd2d
Show file tree
Hide file tree
Showing 14 changed files with 420 additions and 81 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,10 @@ set(MIP_LIBRARIES ${MIP_LIBRARIES_TMP} CACHE STRING "List of all requested MIP l
# TESTING
#

include(CTest)

if(MICROSTRAIN_BUILD_TESTS)
include(CTest)
enable_testing()
add_subdirectory("test")
endif()

Expand Down
4 changes: 2 additions & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ macro(add_mip_example name sources)

endmacro()

add_mip_example(MipPacketC "${EXAMPLE_DIR}/mip_packet_example.c")
add_mip_example(MipPacketExampleC "${EXAMPLE_DIR}/mip_packet_example.c")

if(MICROSTRAIN_ENABLE_CPP)

add_mip_example(MipPacket "${EXAMPLE_DIR}/mip_packet_example.cpp")
add_mip_example(MipPacketExample "${EXAMPLE_DIR}/mip_packet_example.cpp")

# C++ examples that need either serial or TCP support
if(MICROSTRAIN_ENABLE_SERIAL OR MICROSTRAIN_ENABLE_TCP)
Expand Down
67 changes: 50 additions & 17 deletions src/cpp/mip/mip_packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ class PacketView : public C::mip_packet_view
//int finishLastField(uint8_t* payloadPtr, uint8_t newPayloadLength) { return C::mip_packet_realloc_last_field(this, payloadPtr, newPayloadLength); } ///<@copydoc mip::C::mip_packet_realloc_last_field
//int cancelLastField(uint8_t* payloadPtr) { return C::mip_packet_cancel_last_field(this, payloadPtr); } ///<@copydoc mip::C::mip_packet_cancel_last_field

void finalize() { C::mip_packet_finalize(this); } ///<@copydoc mip::C::mip_packet_finalize

void reset(uint8_t descSet) { C::mip_packet_reset(this, descSet); } ///<@copydoc mip::C::mip_packet_reset
void reset() { reset(descriptorSet()); } ///<@brief Resets the packet using the same descriptor set.

//
// C++ additions
//

///@brief Gets a span over the whole packet.
///
microstrain::Span<const uint8_t> totalSpan() const { return {pointer(), totalLength()}; }

///@brief Gets a span over just the payload.
///
microstrain::Span<const uint8_t> payloadSpan() const { return {payload(), payloadLength()}; }


class AllocatedField : public Serializer
{
public:
Expand All @@ -112,17 +130,14 @@ class PacketView : public C::mip_packet_view
return ok;
}

void cancel() { if(basePointer()) C::mip_packet_cancel_last_field(&m_packet, basePointer()); }

private:
PacketView& m_packet;
};

AllocatedField createField(uint8_t fieldDescriptor) { uint8_t* ptr; size_t max_size = std::max<int>(0, C::mip_packet_create_field(this, fieldDescriptor, 0, &ptr)); return {*this, ptr, max_size}; }

void finalize() { C::mip_packet_finalize(this); } ///<@copydoc mip::C::mip_packet_finalize

void reset(uint8_t descSet) { C::mip_packet_reset(this, descSet); } ///<@copydoc mip::C::mip_packet_reset
void reset() { reset(descriptorSet()); } ///<@brief Resets the packet using the same descriptor set.

uint8_t operator[](unsigned int index) const { return pointer()[index]; }

//
Expand Down Expand Up @@ -243,6 +258,28 @@ class PacketView : public C::mip_packet_view
FieldView mField;
};

///@brief Copies this packet to an external buffer.
///
/// This packet must be sane (see isSane()). Undefined behavior otherwise due to lookup of totalLength().
///
///@param buffer Data is copied into this location.
///@param maxLength Maximum number of bytes to copy.
///
///@returns true if successful.
///@returns false if maxLength is too short.
///
bool copyPacketTo(uint8_t* buffer, size_t maxLength) { assert(isSane()); size_t copyLength = this->totalLength(); if(copyLength > maxLength) return false; std::memcpy(buffer, pointer(), copyLength); return true; }

///@brief Copies this packet to an external buffer (span version).
///
/// This packet must be sane (see isSane()). Undefined behavior otherwise due to lookup of totalLength().
///
///@param buffer Data is copied to this buffer.
///
///@returns true if successful.
///@returns false if maxLength is too short.
///
bool copyPacketTo(microstrain::Span<uint8_t> buffer) { return copyPacketTo(buffer.data(), buffer.size()); }
};


Expand All @@ -262,9 +299,13 @@ class SizedPacketBuf : public PacketView
explicit SizedPacketBuf(const uint8_t* data, size_t length) : PacketView(mData, sizeof(mData)) { copyFrom(data, length); }
explicit SizedPacketBuf(const PacketView& packet) : PacketView(mData, sizeof(mData)) { copyFrom(packet); }

///@brief Construct from a span.
explicit SizedPacketBuf(microstrain::Span<const uint8_t> data) : SizedPacketBuf(data.data(), data.size()) {}

///@brief Copy constructor
SizedPacketBuf(const SizedPacketBuf& other) : PacketView(mData, sizeof(mData)) { copyFrom(other); }


///@brief Copy constructor (required to insert packets into std::vector in some cases).
template<size_t OtherSize>
explicit SizedPacketBuf(const SizedPacketBuf<OtherSize>& other) : PacketView(mData, sizeof(mData)) { copyFrom(other); };
Expand Down Expand Up @@ -306,6 +347,10 @@ class SizedPacketBuf : public PacketView
/// This is technically the same as PacketRef::pointer but is writable.
uint8_t* buffer() { return mData; }

///@brief Returns a Span covering the entire buffer.
///
microstrain::Span<uint8_t, BufferSize> bufferSpan() { return microstrain::Span<uint8_t, BufferSize>{buffer(), BufferSize}; }

///@brief Copies the data from the pointer to this buffer. The data is not inspected.
///
///@param data Pointer to the start of the packet.
Expand All @@ -319,18 +364,6 @@ class SizedPacketBuf : public PacketView
///
void copyFrom(const PacketView& packet) { assert(packet.isSane()); copyFrom(packet.pointer(), packet.totalLength()); }

///@brief Copies this packet to an external buffer.
///
/// This packet must be sane (see isSane()). Undefined behavior otherwise due to lookup of totalLength().
///
///@param buffer Data is copied into this location.
///@param maxLength Maximum number of bytes to copy.
///
///@returns true if successful.
///@returns false if maxLength is too short.
///
bool copyTo(uint8_t* buffer, size_t maxLength) { assert(isSane()); size_t copyLength = this->totalLength(); if(copyLength > maxLength) return false; std::memcpy(buffer, mData, copyLength); return true; }

private:
uint8_t mData[BufferSize];
};
Expand Down
27 changes: 19 additions & 8 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
set(TEST_DIR "${CMAKE_CURRENT_LIST_DIR}")

add_library(MicrostrainTest "${TEST_DIR}/test.h" "${TEST_DIR}/test.c")

#
# MIP
#

macro(add_mip_test name sources command)
add_executable(${name} ${sources})

target_include_directories(${name} PRIVATE ${MICROSTRAIN_SRC_DIR})
target_link_libraries(${name} ${MIP_LIBRARY})
target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${MICROSTRAIN_SRC_DIR})
target_link_libraries(${name} MicrostrainTest ${MIP_LIBRARY})

add_test(${name} ${command} ${ARGN})
endmacro()

add_mip_test(TestMipPacketBuilding "${TEST_DIR}/mip/test_mip_packet_builder.c" TestMipPacketBuilding)
add_mip_test(TestMipParsing "${TEST_DIR}/mip/test_mip_parser.c" TestMipParsing "${TEST_DIR}/data/mip_data.bin")
add_mip_test(TestMipRandom "${TEST_DIR}/mip/test_mip_random.c" TestMipRandom)
add_mip_test(TestMipFields "${TEST_DIR}/mip/test_mip_fields.c" TestMipFields)
add_mip_test(TestMipCpp "${TEST_DIR}/mip/test_mip.cpp" TestMipCpp)
add_mip_test(TestMipPerf "${TEST_DIR}/mip/mip_parser_performance.cpp" TestMipPerf)
add_mip_test(TestMipPacketBuilding "${TEST_DIR}/c/mip/test_mip_packet_builder.c" TestMipPacketBuilding)
add_mip_test(TestMipParsing "${TEST_DIR}/c/mip/test_mip_parser.c" TestMipParsing "${TEST_DIR}/data/mip_data.bin")
add_mip_test(TestMipRandom "${TEST_DIR}/c/mip/test_mip_random.c" TestMipRandom)
add_mip_test(TestMipFields "${TEST_DIR}/c/mip/test_mip_fields.c" TestMipFields)
add_mip_test(TestMipCpp "${TEST_DIR}/cpp/mip/test_mip.cpp" TestMipCpp)
add_mip_test(TestMipPerf "${TEST_DIR}/cpp/mip/mip_parser_performance.cpp" TestMipPerf)
add_mip_test(TestMipPacket "${TEST_DIR}/cpp/mip/test_packet_interface.cpp" TestMipPacket)

#if(MICROSTRAIN_BUILD_EXAMPLES)
# set(OUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/MipPacketExampleOutput.txt")
# add_test(
# NAME TestMipPacketExample
# COMMAND diff -u "${CMAKE_CURRENT_LIST_DIR}/data/packet_example_cpp_check.txt" <(examples/MipPacketExample)
# )
#endif()
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,64 +1,17 @@

#include "test.h"

#include <mip/mip_packet.h>
#include <mip/mip_offsets.h>


#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#define EXTRA 1
uint8_t buffer[MIP_PACKET_LENGTH_MAX+EXTRA];

int num_errors = 0;

void print_buffer(FILE* file)
{
for(unsigned int i=0; i<sizeof(buffer); i++)
{
fprintf(file, " %02X", buffer[i]);
}

fputc('\n', stderr);
}

bool check(bool condition, const char* fmt, ...)
{
if( condition )
return true;

va_list argptr;
va_start(argptr, fmt);
vfprintf(stderr, fmt, argptr);
va_end(argptr);

fputc('\n', stderr);

print_buffer(stderr);

num_errors++;
return false;
}

bool check_equal(int a, int b, const char* fmt, ...)
{
if( a == b )
return true;

va_list argptr;
va_start(argptr, fmt);
vfprintf(stderr, fmt, argptr);
va_end(argptr);

fprintf(stderr, " (%d != %d)", a, b);

fputc('\n', stderr);

print_buffer(stderr);

num_errors++;
return false;
}


void test_init()
{
Expand Down Expand Up @@ -147,7 +100,7 @@ void test_short_buffer()
uint8_t* p;
check_equal(mip_packet_create_field(&packet, 0x04, 3, &p), -1, "Wrong remaining count after allocating 1 too many bytes" );
check_equal(mip_packet_create_field(&packet, 0x04, MIP_FIELD_PAYLOAD_LENGTH_MAX, &p), 2-MIP_FIELD_PAYLOAD_LENGTH_MAX, "Wrong remaining count after allocating max payload" );
check_equal(mip_packet_create_field(&packet, 0x04, 255, &p), -253, "Wrong remaining count after allocating excessive payload" );
check_equal(mip_packet_create_field(&packet, 0x04, 253, &p), -251, "Wrong remaining count after allocating excessive payload" );
check_equal(mip_packet_create_field(&packet, 0x05, 1, &p), 1, "Wrong remaining size after allocating 3 bytes" );
check_equal(mip_packet_create_field(&packet, 0x06, 1, &p), -2, "Wrong remaining size after allocating 3 more bytes" );
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 5 additions & 2 deletions test/mip/test_mip.cpp → test/cpp/mip/test_mip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ using namespace mip::C;
uint8_t packetBuffer[PACKET_LENGTH_MAX];
uint8_t parseBuffer[1024];

FieldView fields[MIP_PACKET_PAYLOAD_LENGTH_MAX / MIP_FIELD_LENGTH_MIN];
FieldView fields[(unsigned int)MIP_PACKET_PAYLOAD_LENGTH_MAX / (unsigned int)MIP_FIELD_LENGTH_MIN];
unsigned int numFields = 0;

unsigned int numErrors = 0;
Expand Down Expand Up @@ -87,9 +87,12 @@ int main(int argc, const char* argv[])

auto field = packet.createField(fieldDescriptor);

uint8_t* ptr = field.pointer(payloadLength);
uint8_t* ptr = field.getPtrAndAdvance(payloadLength);
if(!ptr)
{
field.cancel();
break;
}

for(unsigned int p=0; p<payloadLength; p++)
ptr[p] = rand() & 0xFF;
Expand Down
Loading

0 comments on commit 188dd2d

Please sign in to comment.