建立 MAG160C 逆向工程交接仓库
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# Subagent-Driven Development Progress
|
||||
|
||||
- Task 1: complete (review clean of Critical/Important issues; direct g++ verification passed; CMake unavailable in environment)
|
||||
- Task 2: complete (review clean after oversized-payload fix; direct g++ verification passed; CMake unavailable in environment)
|
||||
- Task 3: complete (review clean of Critical/Important issues; direct g++ verification passed; CMake unavailable in environment; minor coverage/internal validation notes recorded)
|
||||
@@ -0,0 +1,127 @@
|
||||
# Task 1 Brief: Build scaffold and public C ABI lifecycle
|
||||
|
||||
## Global constraints
|
||||
|
||||
- Use only original source code; do not link proprietary SDK binaries.
|
||||
- Current workspace is not a git repository; replace commit steps with verification plus updates to progress.md.
|
||||
- Keep public C ABI free of C++ types.
|
||||
- Use C++17.
|
||||
- libusb-1.0 is the only native runtime dependency for the core library.
|
||||
- Firmware update commands are not exposed as an easy accidental CLI action.
|
||||
- IR protocol gaps return MAG160C_ERR_PROTOCOL_UNKNOWN or MAG160C_ERR_UNSUPPORTED.
|
||||
|
||||
## Files
|
||||
|
||||
- Create: CMakeLists.txt
|
||||
- Create: include/mag160c/mag160c.h
|
||||
- Create: src/core/error.hpp
|
||||
- Create: src/core/error.cpp
|
||||
- Create: src/core/context.hpp
|
||||
- Create: src/core/context.cpp
|
||||
- Create: src/c_api.cpp
|
||||
- Create: tests/cpp/test_c_api.cpp
|
||||
- Update: progress.md with the checkpoint at the end.
|
||||
|
||||
## Interfaces to produce
|
||||
|
||||
- mag160c_error_t
|
||||
- opaque mag160c_context_t
|
||||
- opaque mag160c_ir_device_t
|
||||
- opaque mag160c_tcm_device_t
|
||||
- mag160c_error_t mag160c_init(mag160c_context_t** out_ctx)
|
||||
- void mag160c_shutdown(mag160c_context_t* ctx)
|
||||
- const char* mag160c_last_error(void)
|
||||
- const char* mag160c_error_name(mag160c_error_t code)
|
||||
|
||||
## Required public error enum
|
||||
|
||||
```c
|
||||
typedef enum mag160c_error_t {
|
||||
MAG160C_OK = 0,
|
||||
MAG160C_ERR_INVALID_ARGUMENT = 1,
|
||||
MAG160C_ERR_NO_DEVICE = 2,
|
||||
MAG160C_ERR_PERMISSION = 3,
|
||||
MAG160C_ERR_USB = 4,
|
||||
MAG160C_ERR_TIMEOUT = 5,
|
||||
MAG160C_ERR_CHECKSUM = 6,
|
||||
MAG160C_ERR_PROTOCOL_UNKNOWN = 7,
|
||||
MAG160C_ERR_UNSUPPORTED = 8,
|
||||
MAG160C_ERR_INTERNAL = 9
|
||||
} mag160c_error_t;
|
||||
```
|
||||
|
||||
## Required test assertions
|
||||
|
||||
Create tests/cpp/test_c_api.cpp and include assertions equivalent to:
|
||||
|
||||
```cpp
|
||||
assert(std::strcmp(mag160c_error_name(MAG160C_OK), "MAG160C_OK") == 0);
|
||||
assert(std::strcmp(mag160c_error_name(MAG160C_ERR_PROTOCOL_UNKNOWN), "MAG160C_ERR_PROTOCOL_UNKNOWN") == 0);
|
||||
assert(std::strcmp(mag160c_error_name(static_cast<mag160c_error_t>(9999)), "MAG160C_ERR_UNKNOWN_CODE") == 0);
|
||||
assert(mag160c_init(nullptr) == MAG160C_ERR_INVALID_ARGUMENT);
|
||||
mag160c_context_t* ctx = nullptr;
|
||||
assert(mag160c_init(&ctx) == MAG160C_OK);
|
||||
assert(ctx != nullptr);
|
||||
mag160c_shutdown(ctx);
|
||||
```
|
||||
|
||||
## Required CMake behavior
|
||||
|
||||
- Minimum CMake 3.16.
|
||||
- Project name mag160c, C and CXX languages.
|
||||
- Options:
|
||||
- MAG160C_BUILD_TESTS ON by default.
|
||||
- MAG160C_BUILD_CLI ON by default.
|
||||
- C++ standard 17, required, no compiler extensions.
|
||||
- Use PkgConfig to find libusb-1.0 if available.
|
||||
- Build shared library target mag160c_core from:
|
||||
- src/core/error.cpp
|
||||
- src/core/context.cpp
|
||||
- src/c_api.cpp
|
||||
- Public include directory: include.
|
||||
- Private include directory: src.
|
||||
- If libusb is found, define MAG160C_HAS_LIBUSB=1 and link include/library variables.
|
||||
- If libusb is absent, define MAG160C_HAS_LIBUSB=0 and still build.
|
||||
- When tests are enabled, build test_c_api and register it with CTest.
|
||||
|
||||
## Required implementation behavior
|
||||
|
||||
- last error is thread-local.
|
||||
- mag160c_error_name returns stable string names for every enum value and MAG160C_ERR_UNKNOWN_CODE for unknown values.
|
||||
- Context construction succeeds without hardware.
|
||||
- When libusb is absent at build time, Context records has_libusb as false but still constructs.
|
||||
- mag160c_init rejects a null output pointer, sets last_error mentioning out_ctx, and returns MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- mag160c_init allocates a context on success, clears last_error, and returns MAG160C_OK.
|
||||
- mag160c_shutdown accepts null safely through delete behavior.
|
||||
- mag160c_last_error returns the thread-local message.
|
||||
|
||||
## Verification
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
cmake -S . -B build -DMAG160C_BUILD_TESTS=ON
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
Expected: test_c_api passes.
|
||||
|
||||
## Progress checkpoint
|
||||
|
||||
Append this line to progress.md after verification:
|
||||
|
||||
```markdown
|
||||
- Implemented Task 1 scaffold: CMake, public C ABI lifecycle, error names, and lifecycle tests.
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Write a report to .superpowers/sdd/task-1-report.md with:
|
||||
|
||||
- status: DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED
|
||||
- files created/modified
|
||||
- exact commands run
|
||||
- test results
|
||||
- concerns, if any
|
||||
- self-review notes
|
||||
@@ -0,0 +1,48 @@
|
||||
# Task 1 Report
|
||||
|
||||
status: DONE_WITH_CONCERNS
|
||||
|
||||
## Files created/modified
|
||||
|
||||
- CMakeLists.txt
|
||||
- include/mag160c/mag160c.h
|
||||
- src/core/error.hpp
|
||||
- src/core/error.cpp
|
||||
- src/core/context.hpp
|
||||
- src/core/context.cpp
|
||||
- src/c_api.cpp
|
||||
- tests/cpp/test_c_api.cpp
|
||||
- progress.md
|
||||
|
||||
## Commands run
|
||||
|
||||
```powershell
|
||||
cmake -S . -B build -DMAG160C_BUILD_TESTS=ON
|
||||
```
|
||||
|
||||
Result: failed because cmake is not installed or not on PATH.
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task1_test.exe
|
||||
.\build_task1_test.exe
|
||||
```
|
||||
|
||||
Result: passed with exit code 0 and no assertion failures.
|
||||
|
||||
## Test results
|
||||
|
||||
- CMake/CTest verification could not run because `cmake` is unavailable in the environment.
|
||||
- Direct MinGW C++17 compile/run verification passed.
|
||||
|
||||
## Concerns
|
||||
|
||||
- The planned CMake verification remains unverified until CMake is installed or available on PATH.
|
||||
- A generated local executable `build_task1_test.exe` exists from substitute verification.
|
||||
|
||||
## Self-review notes
|
||||
|
||||
- Public C ABI is free of C++ types.
|
||||
- Unknown error codes return MAG160C_ERR_UNKNOWN_CODE.
|
||||
- Null init output pointer returns MAG160C_ERR_INVALID_ARGUMENT and last_error mentions out_ctx.
|
||||
- Successful init clears last_error and returns a non-null context.
|
||||
- Context construction does not require hardware or libusb.
|
||||
@@ -0,0 +1,173 @@
|
||||
# Task 2 Brief: TCM frame codec
|
||||
|
||||
## Context
|
||||
|
||||
Task 1 is complete. Existing files include CMakeLists.txt, include/mag160c/mag160c.h, src/core/error.*, src/core/context.*, src/c_api.cpp, and tests/cpp/test_c_api.cpp.
|
||||
|
||||
CMake is currently unavailable on PATH in this environment. Still keep CMakeLists.txt correct, but if CMake verification cannot run, use direct MinGW g++ verification and record the substitution in the report.
|
||||
|
||||
## Global constraints
|
||||
|
||||
- Use only original source code; do not link proprietary SDK binaries.
|
||||
- Current workspace is not a git repository; replace commit steps with verification plus updates to progress.md.
|
||||
- Keep public C ABI free of C++ types.
|
||||
- Use C++17.
|
||||
- libusb-1.0 is the only native runtime dependency for the core library.
|
||||
- Firmware update commands are not exposed as an easy accidental CLI action.
|
||||
- IR protocol gaps return MAG160C_ERR_PROTOCOL_UNKNOWN or MAG160C_ERR_UNSUPPORTED.
|
||||
|
||||
## Files
|
||||
|
||||
- Create: src/core/tcm_frame.hpp
|
||||
- Create: src/core/tcm_frame.cpp
|
||||
- Create: tests/cpp/test_tcm_frame.cpp
|
||||
- Modify: CMakeLists.txt
|
||||
- Modify: include/mag160c/mag160c.h
|
||||
- Modify: src/c_api.cpp
|
||||
- Update: progress.md with the checkpoint at the end.
|
||||
|
||||
## Interfaces to produce
|
||||
|
||||
- mag160c::core::TcmFrame
|
||||
- mag160c::core::checksum(const uint8_t* data, size_t begin, size_t end)
|
||||
- mag160c::core::encode_tcm_frame(uint8_t main_cmd, uint8_t sub_cmd, uint16_t frame_id, const std::vector<uint8_t>& payload)
|
||||
- mag160c::core::decode_tcm_frame(const uint8_t* data, size_t size, TcmFrame* out)
|
||||
- mag160c_tcm_encode_frame C ABI
|
||||
- mag160c_tcm_decode_header C ABI
|
||||
|
||||
## TCM frame rules
|
||||
|
||||
- Header byte 0 is 0x7e.
|
||||
- Bytes 1..2 are big-endian body length.
|
||||
- Byte 3 is additive checksum over bytes 0..2.
|
||||
- Body is main, sub, frame high, frame low, payload, body checksum.
|
||||
- Body checksum is additive checksum over body bytes before the final checksum byte.
|
||||
- Body length is payload length + 5.
|
||||
- Minimum valid full packet length is 9 bytes.
|
||||
|
||||
## Required exact test vector
|
||||
|
||||
Encoding main 0x02, sub 0x77, frame id 0x0001, payload {0x00, 0x05} must produce:
|
||||
|
||||
```text
|
||||
7e 00 07 85 02 77 00 01 00 05 7f
|
||||
```
|
||||
|
||||
## Required tests
|
||||
|
||||
Create tests/cpp/test_tcm_frame.cpp with:
|
||||
|
||||
- test_rotate_frame_encoding: exact bytes above.
|
||||
- test_decode_rejects_bad_header_checksum: corrupt byte 3 and expect MAG160C_ERR_CHECKSUM.
|
||||
- test_decode_roundtrip: encode then decode and assert main, sub, frame id, payload.
|
||||
|
||||
## Required C++ header
|
||||
|
||||
src/core/tcm_frame.hpp must declare:
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include "mag160c/mag160c.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace mag160c::core {
|
||||
|
||||
struct TcmFrame {
|
||||
uint8_t main_cmd = 0;
|
||||
uint8_t sub_cmd = 0;
|
||||
uint16_t frame_id = 0;
|
||||
std::vector<uint8_t> payload;
|
||||
};
|
||||
|
||||
uint8_t checksum(const uint8_t* data, size_t begin, size_t end);
|
||||
std::vector<uint8_t> encode_tcm_frame(uint8_t main_cmd, uint8_t sub_cmd, uint16_t frame_id, const std::vector<uint8_t>& payload);
|
||||
mag160c_error_t decode_tcm_frame(const uint8_t* data, size_t size, TcmFrame* out);
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Required C ABI declarations
|
||||
|
||||
Add to include/mag160c/mag160c.h inside the extern C block:
|
||||
|
||||
```c
|
||||
MAG160C_API mag160c_error_t mag160c_tcm_encode_frame(
|
||||
uint8_t main_cmd,
|
||||
uint8_t sub_cmd,
|
||||
uint16_t frame_id,
|
||||
const uint8_t* payload,
|
||||
size_t payload_size,
|
||||
uint8_t* out_bytes,
|
||||
size_t out_capacity,
|
||||
size_t* out_size
|
||||
);
|
||||
|
||||
MAG160C_API mag160c_error_t mag160c_tcm_decode_header(
|
||||
const uint8_t* data,
|
||||
size_t size,
|
||||
uint8_t* out_main_cmd,
|
||||
uint8_t* out_sub_cmd,
|
||||
uint16_t* out_frame_id,
|
||||
size_t* out_payload_size
|
||||
);
|
||||
```
|
||||
|
||||
## Required C ABI behavior
|
||||
|
||||
- mag160c_tcm_encode_frame requires out_size.
|
||||
- If output buffer is null or too small, set out_size to the required encoded size and return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- If payload_size is nonzero and payload is null, return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- On success, copy encoded bytes, set out_size, clear last error, return MAG160C_OK.
|
||||
- mag160c_tcm_decode_header requires all output pointers.
|
||||
- It should call decode_tcm_frame and return any error from it.
|
||||
- On success, fill main, sub, frame id, and payload size.
|
||||
|
||||
## CMake update
|
||||
|
||||
- Add src/core/tcm_frame.cpp to mag160c_core sources.
|
||||
- Add test_tcm_frame executable linked to mag160c_core.
|
||||
- Give test_tcm_frame access to src private headers.
|
||||
- Register test_tcm_frame with CTest.
|
||||
|
||||
## Verification
|
||||
|
||||
First try:
|
||||
|
||||
```powershell
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
If CMake is unavailable, run direct verification equivalent to:
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task2_c_api_test.exe
|
||||
.\build_task2_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task2_tcm_frame_test.exe
|
||||
.\build_task2_tcm_frame_test.exe
|
||||
```
|
||||
|
||||
Expected: both executables exit 0.
|
||||
|
||||
## Progress checkpoint
|
||||
|
||||
Append this line to progress.md after verification:
|
||||
|
||||
```markdown
|
||||
- Implemented Task 2 TCM frame codec with byte-exact encode/decode tests and C ABI utility functions.
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Write a report to .superpowers/sdd/task-2-report.md with:
|
||||
|
||||
- status: DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED
|
||||
- files created/modified
|
||||
- exact commands run
|
||||
- test results
|
||||
- concerns, if any
|
||||
- self-review notes
|
||||
@@ -0,0 +1,52 @@
|
||||
# Task 2 Fix Brief: oversized TCM payload safety
|
||||
|
||||
## Finding to fix
|
||||
|
||||
Task 2 reviewer found an Important issue:
|
||||
|
||||
- In src/core/tcm_frame.cpp, payload.size() + 5U is cast to uint16_t. For payloads larger than 65530 bytes, the body length truncates, the vector is allocated too small, and the copy loop writes past the encoded vector.
|
||||
- In src/c_api.cpp, mag160c_tcm_encode_frame encodes before checking output buffer, so even size-query calls with out_bytes == nullptr can trigger the overflow.
|
||||
|
||||
## Required fix
|
||||
|
||||
- Prevent oversized payloads from corrupting memory.
|
||||
- Maximum payload size is 65530 bytes because body length is uint16_t and body length is payload_size + 5.
|
||||
- C++ encode_tcm_frame must reject oversized payloads before allocation/copy.
|
||||
- C ABI mag160c_tcm_encode_frame must return MAG160C_ERR_INVALID_ARGUMENT for oversized payloads and set last_error explaining the payload is too large.
|
||||
- Add tests covering oversized payload handling.
|
||||
|
||||
## Suggested implementation
|
||||
|
||||
- In src/core/tcm_frame.cpp, add a helper constant or check:
|
||||
- constexpr size_t MAX_TCM_PAYLOAD_SIZE = 0xffffU - 5U;
|
||||
- if payload.size() > MAX_TCM_PAYLOAD_SIZE, throw std::length_error("TCM payload is too large");
|
||||
- In src/c_api.cpp, validate payload_size before constructing payload_vec or calling encode_tcm_frame.
|
||||
- Optionally catch std::length_error around encode_tcm_frame and map to MAG160C_ERR_INVALID_ARGUMENT for defense-in-depth.
|
||||
|
||||
## Required tests
|
||||
|
||||
Add at least one no-crash test:
|
||||
|
||||
- In tests/cpp/test_c_api.cpp, allocate a payload of size 65531 and call mag160c_tcm_encode_frame with out_bytes nullptr and capacity 0.
|
||||
- Assert it returns MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- Assert out_size is 0.
|
||||
- Assert mag160c_last_error() contains "too large".
|
||||
|
||||
Also add a core test if convenient:
|
||||
|
||||
- In tests/cpp/test_tcm_frame.cpp, call encode_tcm_frame with payload size 65531 and assert it throws std::length_error.
|
||||
|
||||
## Verification
|
||||
|
||||
Run direct verification:
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task2_c_api_test.exe
|
||||
.\build_task2_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task2_tcm_frame_test.exe
|
||||
.\build_task2_tcm_frame_test.exe
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Append a fix report section to .superpowers/sdd/task-2-report.md and return status plus one-line test summary.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Task 2 Report
|
||||
|
||||
status: DONE_WITH_CONCERNS
|
||||
|
||||
## Files created/modified
|
||||
|
||||
- CMakeLists.txt
|
||||
- include/mag160c/mag160c.h
|
||||
- src/core/tcm_frame.hpp
|
||||
- src/core/tcm_frame.cpp
|
||||
- src/c_api.cpp
|
||||
- tests/cpp/test_c_api.cpp
|
||||
- tests/cpp/test_tcm_frame.cpp
|
||||
- progress.md
|
||||
|
||||
## Commands run
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task2_c_api_test.exe
|
||||
.\build_task2_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task2_tcm_frame_test.exe
|
||||
.\build_task2_tcm_frame_test.exe
|
||||
```
|
||||
|
||||
## Test results
|
||||
|
||||
- Direct MinGW C++17 compile/run verification passed for test_c_api.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_tcm_frame.
|
||||
|
||||
## Concerns
|
||||
|
||||
- CMake/CTest verification remains unavailable because cmake is not installed or not on PATH in this environment.
|
||||
- Generated local executables build_task2_c_api_test.exe and build_task2_tcm_frame_test.exe exist from substitute verification.
|
||||
|
||||
## Self-review notes
|
||||
|
||||
- TCM encode exact vector for rotate +5 is implemented and tested.
|
||||
- Header checksum and body checksum use additive uint8_t wrapping.
|
||||
- C ABI encode reports required size when output buffer is too small.
|
||||
- C ABI decode_header delegates to decode_tcm_frame and returns parsed main/sub/frame/payload size.
|
||||
- Public header now includes stddef.h and stdint.h because Task 2 introduced size_t and fixed-width integer types.
|
||||
|
||||
## Fix report: oversized TCM payload safety
|
||||
|
||||
status: DONE
|
||||
|
||||
### Files modified
|
||||
|
||||
- src/core/tcm_frame.cpp
|
||||
- src/c_api.cpp
|
||||
- tests/cpp/test_c_api.cpp
|
||||
- tests/cpp/test_tcm_frame.cpp
|
||||
|
||||
### Commands run
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task2_c_api_test.exe
|
||||
.\build_task2_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task2_tcm_frame_test.exe
|
||||
.\build_task2_tcm_frame_test.exe
|
||||
```
|
||||
|
||||
### Test results
|
||||
|
||||
- Direct MinGW C++17 compile/run verification passed for test_c_api.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_tcm_frame.
|
||||
|
||||
### Self-review
|
||||
|
||||
- Oversized payloads are rejected before allocation/copy.
|
||||
- C ABI oversized payload path returns MAG160C_ERR_INVALID_ARGUMENT, sets out_size to 0, and sets last_error containing "too large".
|
||||
- Core encode_tcm_frame oversized payload path is covered by a std::length_error test.
|
||||
@@ -0,0 +1,180 @@
|
||||
# Task 3 Brief: TCM command builders
|
||||
|
||||
## Context
|
||||
|
||||
Tasks 1 and 2 are complete. Existing TCM frame codec is in src/core/tcm_frame.* and C ABI frame utilities are in src/c_api.cpp.
|
||||
|
||||
CMake is unavailable on PATH in this environment. Keep CMakeLists.txt correct, but use direct MinGW g++ verification if CMake cannot run.
|
||||
|
||||
## Global constraints
|
||||
|
||||
- Use only original source code; do not link proprietary SDK binaries.
|
||||
- Current workspace is not a git repository; replace commit steps with verification plus updates to progress.md.
|
||||
- Keep public C ABI free of C++ types.
|
||||
- Use C++17.
|
||||
- libusb-1.0 is the only native runtime dependency for the core library.
|
||||
- Firmware update commands are not exposed as an easy accidental CLI action.
|
||||
- IR protocol gaps return MAG160C_ERR_PROTOCOL_UNKNOWN or MAG160C_ERR_UNSUPPORTED.
|
||||
|
||||
## Files
|
||||
|
||||
- Create: src/core/transport.hpp
|
||||
- Create: src/core/tcm_device.hpp
|
||||
- Create: src/core/tcm_device.cpp
|
||||
- Create: tests/cpp/test_tcm_device.cpp
|
||||
- Modify: CMakeLists.txt
|
||||
- Modify: include/mag160c/mag160c.h
|
||||
- Modify: src/c_api.cpp
|
||||
- Update: progress.md with the checkpoint.
|
||||
|
||||
## Interfaces to produce
|
||||
|
||||
- mag160c::core::Transport
|
||||
- mag160c::core::TcmCommandBuilder
|
||||
- mag160c_tcm_build_rotate_frame
|
||||
- mag160c_tcm_build_light_frame
|
||||
|
||||
## Required transport interface
|
||||
|
||||
```cpp
|
||||
class Transport {
|
||||
public:
|
||||
virtual ~Transport() = default;
|
||||
virtual mag160c_error_t write(const std::vector<uint8_t>& bytes) = 0;
|
||||
virtual mag160c_error_t read(std::vector<uint8_t>* out, int timeout_ms) = 0;
|
||||
};
|
||||
```
|
||||
|
||||
## Required TCM command behavior
|
||||
|
||||
- Frame id starts at 1.
|
||||
- Frame id increments after each encoded frame.
|
||||
- Frame id wraps to 1 before reaching 0x8000.
|
||||
- rotate clamps input to [-128, 128].
|
||||
- rotate payload is [direction, magnitude], direction 0 for positive and 1 for negative.
|
||||
- light payload is [on, red, green, blue].
|
||||
- red/green/blue/yellow channel value is 0xff.
|
||||
- off payload is [0, 0, 0, 0].
|
||||
- light steady sub is 0x31, blink is 0x32, breath is 0x33.
|
||||
- all observed TCM main commands here use main 0x02.
|
||||
|
||||
## Required exact test vectors
|
||||
|
||||
- rotate +5 with initial frame id 1:
|
||||
|
||||
```text
|
||||
7e 00 07 85 02 77 00 01 00 05 7f
|
||||
```
|
||||
|
||||
- after one prior command, rotate -3 with frame id 2:
|
||||
|
||||
```text
|
||||
7e 00 07 85 02 77 00 02 01 03 7f
|
||||
```
|
||||
|
||||
- green blink with initial frame id 1:
|
||||
|
||||
```text
|
||||
7e 00 09 87 02 32 00 01 01 00 ff 00 35
|
||||
```
|
||||
|
||||
## Required C ABI declarations
|
||||
|
||||
Add to include/mag160c/mag160c.h:
|
||||
|
||||
```c
|
||||
typedef enum mag160c_tcm_light_color_t {
|
||||
MAG160C_TCM_LIGHT_OFF = 0,
|
||||
MAG160C_TCM_LIGHT_RED = 1,
|
||||
MAG160C_TCM_LIGHT_GREEN = 2,
|
||||
MAG160C_TCM_LIGHT_BLUE = 3,
|
||||
MAG160C_TCM_LIGHT_YELLOW = 4
|
||||
} mag160c_tcm_light_color_t;
|
||||
|
||||
typedef enum mag160c_tcm_light_mode_t {
|
||||
MAG160C_TCM_LIGHT_STEADY = 0,
|
||||
MAG160C_TCM_LIGHT_BLINK = 1,
|
||||
MAG160C_TCM_LIGHT_BREATH = 2
|
||||
} mag160c_tcm_light_mode_t;
|
||||
|
||||
MAG160C_API mag160c_error_t mag160c_tcm_build_rotate_frame(
|
||||
int angle,
|
||||
uint8_t* out_bytes,
|
||||
size_t out_capacity,
|
||||
size_t* out_size
|
||||
);
|
||||
|
||||
MAG160C_API mag160c_error_t mag160c_tcm_build_light_frame(
|
||||
mag160c_tcm_light_color_t color,
|
||||
mag160c_tcm_light_mode_t mode,
|
||||
uint8_t* out_bytes,
|
||||
size_t out_capacity,
|
||||
size_t* out_size
|
||||
);
|
||||
```
|
||||
|
||||
## Required C ABI behavior
|
||||
|
||||
- Build helpers are dry-run byte builders only; they do not talk to USB.
|
||||
- If out_size is null, return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- If output buffer is null or too small, set out_size to the required frame size and return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- On success, copy bytes, set out_size, clear last_error, return MAG160C_OK.
|
||||
- Invalid light color or mode returns MAG160C_ERR_INVALID_ARGUMENT and sets a useful last_error.
|
||||
|
||||
## Required tests
|
||||
|
||||
Create tests/cpp/test_tcm_device.cpp with:
|
||||
|
||||
- test_rotate_positive_payload exact vector.
|
||||
- test_rotate_negative_payload_and_frame_increment exact vector.
|
||||
- test_green_blink_payload exact vector.
|
||||
|
||||
Also extend tests/cpp/test_c_api.cpp if convenient to check the new dry-run C ABI for rotate +5.
|
||||
|
||||
## CMake update
|
||||
|
||||
- Add src/core/tcm_device.cpp to mag160c_core sources.
|
||||
- Add test_tcm_device executable linked to mag160c_core.
|
||||
- Give test_tcm_device access to src private headers.
|
||||
- Register test_tcm_device with CTest.
|
||||
|
||||
## Verification
|
||||
|
||||
First try:
|
||||
|
||||
```powershell
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
If CMake is unavailable, run:
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task3_c_api_test.exe
|
||||
.\build_task3_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task3_tcm_frame_test.exe
|
||||
.\build_task3_tcm_frame_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_tcm_device.cpp -o build_task3_tcm_device_test.exe
|
||||
.\build_task3_tcm_device_test.exe
|
||||
```
|
||||
|
||||
Expected: all executables exit 0.
|
||||
|
||||
## Progress checkpoint
|
||||
|
||||
Append this line to progress.md after verification:
|
||||
|
||||
```markdown
|
||||
- Implemented Task 3 TCM command builder, dry-run C ABI helpers, and command payload tests.
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Write a report to .superpowers/sdd/task-3-report.md with:
|
||||
|
||||
- status: DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED
|
||||
- files created/modified
|
||||
- exact commands run
|
||||
- test results
|
||||
- concerns, if any
|
||||
- self-review notes
|
||||
@@ -0,0 +1,44 @@
|
||||
# Task 3 Report
|
||||
|
||||
status: DONE_WITH_CONCERNS
|
||||
|
||||
## Files created/modified
|
||||
|
||||
- CMakeLists.txt
|
||||
- include/mag160c/mag160c.h
|
||||
- src/core/transport.hpp
|
||||
- src/core/tcm_device.hpp
|
||||
- src/core/tcm_device.cpp
|
||||
- src/c_api.cpp
|
||||
- tests/cpp/test_c_api.cpp
|
||||
- tests/cpp/test_tcm_device.cpp
|
||||
- progress.md
|
||||
|
||||
## Commands run
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task3_c_api_test.exe
|
||||
.\build_task3_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_tcm_frame.cpp -o build_task3_tcm_frame_test.exe
|
||||
.\build_task3_tcm_frame_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\c_api.cpp tests\cpp\test_tcm_device.cpp -o build_task3_tcm_device_test.exe
|
||||
.\build_task3_tcm_device_test.exe
|
||||
```
|
||||
|
||||
## Test results
|
||||
|
||||
- Direct MinGW C++17 compile/run verification passed for test_c_api.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_tcm_frame.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_tcm_device.
|
||||
|
||||
## Concerns
|
||||
|
||||
- CMake/CTest verification remains unavailable because cmake is not installed or not on PATH.
|
||||
- Generated local executables build_task3_c_api_test.exe, build_task3_tcm_frame_test.exe, and build_task3_tcm_device_test.exe exist from substitute verification.
|
||||
|
||||
## Self-review notes
|
||||
|
||||
- TcmCommandBuilder starts frame ids at 1 and increments them.
|
||||
- Rotate frames clamp to [-128, 128] and encode [direction, magnitude].
|
||||
- Light frames encode [on, red, green, blue] with 0xff channel values.
|
||||
- C ABI dry-run builders report required size on too-small buffers and validate invalid light color/mode.
|
||||
@@ -0,0 +1,176 @@
|
||||
# Task 4 Brief: USB discovery and endpoint model
|
||||
|
||||
## Context
|
||||
|
||||
Tasks 1-3 are complete. CMake remains unavailable on PATH; keep CMakeLists.txt correct but use direct MinGW g++ verification if CMake cannot run.
|
||||
|
||||
## Global constraints
|
||||
|
||||
- Use only original source code; do not link proprietary SDK binaries.
|
||||
- Current workspace is not a git repository; replace commit steps with verification plus updates to progress.md.
|
||||
- Keep public C ABI free of C++ types.
|
||||
- Use C++17.
|
||||
- libusb-1.0 is the only native runtime dependency for the core library.
|
||||
- Firmware update commands are not exposed as an easy accidental CLI action.
|
||||
- IR protocol gaps return MAG160C_ERR_PROTOCOL_UNKNOWN or MAG160C_ERR_UNSUPPORTED.
|
||||
|
||||
## Files
|
||||
|
||||
- Create: src/core/device.hpp
|
||||
- Create: src/core/device.cpp
|
||||
- Create: tests/cpp/test_device_model.cpp
|
||||
- Modify: CMakeLists.txt
|
||||
- Modify: include/mag160c/mag160c.h
|
||||
- Modify: src/c_api.cpp
|
||||
- Update: progress.md with the checkpoint.
|
||||
|
||||
## Interfaces to produce
|
||||
|
||||
- mag160c::core::EndpointType
|
||||
- mag160c::core::EndpointDescriptor
|
||||
- mag160c::core::EndpointPair
|
||||
- mag160c::core::DeviceInfo
|
||||
- mag160c::core::is_in_endpoint
|
||||
- mag160c::core::find_bulk_pair
|
||||
- mag160c::core::list_devices
|
||||
- mag160c_list_devices C ABI
|
||||
- mag160c_free_device_list C ABI
|
||||
|
||||
## Required constants and structs
|
||||
|
||||
```cpp
|
||||
constexpr uint16_t MAG_IR_VENDOR_ID = 0x833c;
|
||||
constexpr uint16_t MAG_IR_PRODUCT_ID = 0x0001;
|
||||
|
||||
enum class EndpointType {
|
||||
Other,
|
||||
Bulk,
|
||||
Interrupt,
|
||||
Isochronous
|
||||
};
|
||||
|
||||
struct EndpointDescriptor {
|
||||
uint8_t address = 0;
|
||||
EndpointType type = EndpointType::Other;
|
||||
};
|
||||
|
||||
struct EndpointPair {
|
||||
uint8_t bulk_in = 0;
|
||||
uint8_t bulk_out = 0;
|
||||
};
|
||||
|
||||
struct DeviceInfo {
|
||||
mag160c_device_info_t c_info{};
|
||||
};
|
||||
```
|
||||
|
||||
## Required public C struct and declarations
|
||||
|
||||
Add to include/mag160c/mag160c.h:
|
||||
|
||||
```c
|
||||
typedef struct mag160c_device_info_t {
|
||||
uint16_t vendor_id;
|
||||
uint16_t product_id;
|
||||
uint8_t bus;
|
||||
uint8_t address;
|
||||
uint8_t interface_number;
|
||||
uint8_t bulk_in_endpoint;
|
||||
uint8_t bulk_out_endpoint;
|
||||
char product[128];
|
||||
char manufacturer[128];
|
||||
char serial[128];
|
||||
} mag160c_device_info_t;
|
||||
|
||||
MAG160C_API mag160c_error_t mag160c_list_devices(
|
||||
mag160c_context_t* ctx,
|
||||
mag160c_device_info_t** out_devices,
|
||||
size_t* out_count
|
||||
);
|
||||
|
||||
MAG160C_API void mag160c_free_device_list(mag160c_device_info_t* devices);
|
||||
```
|
||||
|
||||
## Required endpoint behavior
|
||||
|
||||
- is_in_endpoint returns true when endpoint address has bit 0x80 set.
|
||||
- find_bulk_pair scans endpoints and returns the first bulk IN and first bulk OUT.
|
||||
- find_bulk_pair returns false if either direction is absent.
|
||||
- find_bulk_pair returns false for null out pointer.
|
||||
|
||||
## Required list_devices behavior
|
||||
|
||||
- If out is null, return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- If MAG160C_HAS_LIBUSB is 0, return MAG160C_ERR_UNSUPPORTED and set last_error explaining libusb was not available at build time.
|
||||
- If MAG160C_HAS_LIBUSB is 1 and no matching device is present, return MAG160C_OK and an empty vector.
|
||||
- Only match VID 0x833C and PID 0x0001 initially.
|
||||
- If libusb is enabled, inspect config descriptors and report the first interface/altsetting with both bulk IN and bulk OUT.
|
||||
- Avoid including libusb.h unless MAG160C_HAS_LIBUSB is true so direct no-libusb builds compile.
|
||||
|
||||
## Required C ABI behavior
|
||||
|
||||
- mag160c_list_devices requires ctx, out_devices, and out_count.
|
||||
- On invalid arguments, return MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- Initialize *out_devices to null and *out_count to 0 before enumeration.
|
||||
- On empty device list, return MAG160C_OK with null devices and count 0.
|
||||
- On non-empty list, allocate an array with new[] and copy mag160c_device_info_t values.
|
||||
- mag160c_free_device_list deletes the array and accepts null.
|
||||
|
||||
## Required tests
|
||||
|
||||
Create tests/cpp/test_device_model.cpp:
|
||||
|
||||
- endpoints {0x01 interrupt, 0x82 bulk, 0x03 bulk} returns bulk_in 0x82 and bulk_out 0x03.
|
||||
- endpoints {0x82 bulk} returns false because bulk OUT is absent.
|
||||
- optional: null out pointer returns false.
|
||||
|
||||
Extend tests/cpp/test_c_api.cpp if convenient:
|
||||
|
||||
- mag160c_list_devices(nullptr, nullptr, nullptr) returns MAG160C_ERR_INVALID_ARGUMENT.
|
||||
- with a valid context and MAG160C_HAS_LIBUSB=0, mag160c_list_devices returns MAG160C_ERR_UNSUPPORTED, devices remains null, count remains 0.
|
||||
|
||||
## CMake update
|
||||
|
||||
- Add src/core/device.cpp to mag160c_core sources.
|
||||
- Add test_device_model executable linked to mag160c_core.
|
||||
- Give test_device_model access to src private headers.
|
||||
- Register test_device_model with CTest.
|
||||
|
||||
## Verification
|
||||
|
||||
First try:
|
||||
|
||||
```powershell
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
If CMake is unavailable, run:
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task4_c_api_test.exe
|
||||
.\build_task4_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_device_model.cpp -o build_task4_device_model_test.exe
|
||||
.\build_task4_device_model_test.exe
|
||||
```
|
||||
|
||||
Expected: both executables exit 0.
|
||||
|
||||
## Progress checkpoint
|
||||
|
||||
Append this line to progress.md after verification:
|
||||
|
||||
```markdown
|
||||
- Implemented Task 4 USB device model, endpoint-pair selection, and C ABI device listing/freeing.
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Write a report to .superpowers/sdd/task-4-report.md with:
|
||||
|
||||
- status: DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED
|
||||
- files created/modified
|
||||
- exact commands run
|
||||
- test results
|
||||
- concerns, if any
|
||||
- self-review notes
|
||||
@@ -0,0 +1,32 @@
|
||||
# Task 4 Fix Brief: make list_devices test compatible with libusb-enabled builds
|
||||
|
||||
## Finding to fix
|
||||
|
||||
Task 4 reviewer found an Important issue:
|
||||
|
||||
- tests/cpp/test_c_api.cpp unconditionally expects mag160c_list_devices to return MAG160C_ERR_UNSUPPORTED.
|
||||
- That is correct only when MAG160C_HAS_LIBUSB=0.
|
||||
- When CMake finds libusb and builds with MAG160C_HAS_LIBUSB=1, the Task 4 spec requires no matching device to return MAG160C_OK with an empty list, and matching devices may return MAG160C_OK with a non-empty list.
|
||||
- The test target currently does not receive MAG160C_HAS_LIBUSB from CMake, so it cannot conditionalize correctly.
|
||||
|
||||
## Required fix
|
||||
|
||||
- In tests/cpp/test_c_api.cpp, make the list_devices expectation conditional on MAG160C_HAS_LIBUSB.
|
||||
- In no-libusb builds, continue to assert MAG160C_ERR_UNSUPPORTED, null devices, count 0, and last_error contains libusb.
|
||||
- In libusb-enabled builds, assert MAG160C_OK, and always call mag160c_free_device_list(devices). Do not require count to be zero because hardware may be attached.
|
||||
- In CMakeLists.txt, propagate MAG160C_HAS_LIBUSB=1 or 0 to test targets that need it, at least test_c_api.
|
||||
|
||||
## Verification
|
||||
|
||||
Run direct no-libusb verification:
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task4_c_api_test.exe
|
||||
.\build_task4_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_device_model.cpp -o build_task4_device_model_test.exe
|
||||
.\build_task4_device_model_test.exe
|
||||
```
|
||||
|
||||
## Report contract
|
||||
|
||||
Append a fix report section to .superpowers/sdd/task-4-report.md and return status plus one-line test summary.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Task 4 Report
|
||||
|
||||
status: DONE_WITH_CONCERNS
|
||||
|
||||
## Files created/modified
|
||||
|
||||
- CMakeLists.txt
|
||||
- include/mag160c/mag160c.h
|
||||
- src/core/device.hpp
|
||||
- src/core/device.cpp
|
||||
- src/c_api.cpp
|
||||
- tests/cpp/test_c_api.cpp
|
||||
- tests/cpp/test_device_model.cpp
|
||||
- progress.md
|
||||
|
||||
## Commands run
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task4_c_api_test.exe
|
||||
.\build_task4_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_device_model.cpp -o build_task4_device_model_test.exe
|
||||
.\build_task4_device_model_test.exe
|
||||
```
|
||||
|
||||
## Test results
|
||||
|
||||
- Direct MinGW C++17 compile/run verification passed for test_c_api.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_device_model.
|
||||
|
||||
## Concerns
|
||||
|
||||
- CMake/CTest verification remains unavailable because cmake is not installed or not on PATH.
|
||||
- libusb-enabled enumeration path is implemented under conditional compilation but not compiled in this environment because MAG160C_HAS_LIBUSB=0.
|
||||
- Generated local executables build_task4_c_api_test.exe and build_task4_device_model_test.exe exist from substitute verification.
|
||||
|
||||
## Self-review notes
|
||||
|
||||
- Endpoint pair selection returns first bulk IN and first bulk OUT.
|
||||
- No-libusb list_devices path returns MAG160C_ERR_UNSUPPORTED and clears output pointers/count through the C ABI.
|
||||
- C ABI device list allocation uses new[] and free uses delete[].
|
||||
- Public device info struct uses only C-compatible fields.
|
||||
|
||||
## Fix report: libusb-enabled list_devices test compatibility
|
||||
|
||||
status: DONE
|
||||
|
||||
### Files modified
|
||||
|
||||
- CMakeLists.txt
|
||||
- tests/cpp/test_c_api.cpp
|
||||
|
||||
### Commands run
|
||||
|
||||
```powershell
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_c_api.cpp -o build_task4_c_api_test.exe
|
||||
.\build_task4_c_api_test.exe
|
||||
g++ -std=c++17 -DMAG160C_STATIC -DMAG160C_HAS_LIBUSB=0 -Iinclude -Isrc src\core\error.cpp src\core\context.cpp src\core\tcm_frame.cpp src\core\tcm_device.cpp src\core\device.cpp src\c_api.cpp tests\cpp\test_device_model.cpp -o build_task4_device_model_test.exe
|
||||
.\build_task4_device_model_test.exe
|
||||
```
|
||||
|
||||
### Test results
|
||||
|
||||
- Direct MinGW C++17 compile/run verification passed for test_c_api.
|
||||
- Direct MinGW C++17 compile/run verification passed for test_device_model.
|
||||
|
||||
### Self-review
|
||||
|
||||
- test_c_api now expects MAG160C_ERR_UNSUPPORTED only when MAG160C_HAS_LIBUSB is 0.
|
||||
- test_c_api accepts MAG160C_OK and frees any returned device list when MAG160C_HAS_LIBUSB is 1.
|
||||
- CMake now propagates MAG160C_HAS_LIBUSB to test_c_api via MAG160C_HAS_LIBUSB_VALUE.
|
||||
Reference in New Issue
Block a user