Files
MAG160C/.superpowers/sdd/task-4-brief.md
T

177 lines
5.5 KiB
Markdown

# 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