Skip to content

Commit ffc333f

Browse files
committed
Add libusbp_write_pipe for macOS and get the tests passing.
1 parent 33e1d4d commit ffc333f

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

src/mac/generic_handle_mac.c

+63
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,69 @@ libusbp_error * libusbp_read_pipe(
455455
return error;
456456
}
457457

458+
libusbp_error * libusbp_write_pipe(
459+
libusbp_generic_handle * handle,
460+
uint8_t pipe_id,
461+
const void * buffer,
462+
size_t size,
463+
size_t * transferred)
464+
{
465+
if (transferred != NULL)
466+
{
467+
*transferred = 0;
468+
}
469+
470+
if (handle == NULL)
471+
{
472+
return error_create("Generic handle is null.");
473+
}
474+
475+
libusbp_error * error = NULL;
476+
477+
if (error == NULL && size > UINT32_MAX)
478+
{
479+
error = error_create("Transfer size is too large.");
480+
}
481+
482+
if (error == NULL && buffer == NULL && size)
483+
{
484+
error = error_create("Buffer is null.");
485+
}
486+
487+
if (error == NULL)
488+
{
489+
error = check_pipe_id_out(pipe_id);
490+
}
491+
492+
if (error == NULL)
493+
{
494+
uint8_t endpoint_number = pipe_id & MAX_ENDPOINT_NUMBER;
495+
uint32_t no_data_timeout = 0;
496+
uint32_t completion_timeout = handle->out_timeout[endpoint_number];
497+
uint32_t pipe_index = handle->out_pipe_index[endpoint_number];
498+
kern_return_t kr = (*handle->ioh)->WritePipeTO(handle->ioh, pipe_index,
499+
(void *)buffer, size, no_data_timeout, completion_timeout);
500+
if (kr != KERN_SUCCESS)
501+
{
502+
error = error_create_mach(kr, "");
503+
}
504+
}
505+
506+
if (error == NULL && transferred != NULL)
507+
{
508+
// There was no error, so just assume the entire amount was transferred.
509+
// WritePipeTO does not give us a number.
510+
*transferred = size;
511+
}
512+
513+
if (error != NULL)
514+
{
515+
error = error_add(error, "Failed to write to pipe.");
516+
}
517+
518+
return error;
519+
}
520+
458521
#pragma pack(4)
459522
typedef struct
460523
{

test/CMakeLists.txt

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if (NOT HAVE_CATCH_FRAMEWORK)
1111
return ()
1212
endif ()
1313

14-
use_cxx11()
14+
use_cxx11 ()
1515

1616
set(USE_TEST_DEVICE_A FALSE CACHE BOOL
1717
"Run tests that require Test Device A.")
@@ -21,8 +21,16 @@ set(USE_TEST_DEVICE_B FALSE CACHE BOOL
2121

2222
file(GLOB test_sources *.cpp)
2323

24+
if (APPLE)
25+
set (link_flags "-framework CoreFoundation ${link_flags}")
26+
endif ()
27+
2428
add_executable(run_test ${test_sources})
2529

30+
set_target_properties(run_test PROPERTIES
31+
LINK_FLAGS "${link_flags}"
32+
)
33+
2634
include_directories (
2735
"${CMAKE_CURRENT_SOURCE_DIR}"
2836
"${CMAKE_SOURCE_DIR}/include"

test/write_pipe_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ TEST_CASE("write_pipe (synchronous) on a bulk endpoint ", "[wpi]")
133133

134134
SECTION("can time out")
135135
{
136-
// First packet causes a 150 ms delay, so this transfer will timeout after
136+
// First packet causes a long delay, so this transfer will timeout after
137137
// a partial data transfer. Need three packets because of double
138138
// buffering on the device.
139139
uint8_t buffer[32 * 3] = { 0xDE, 150, 0 };
@@ -145,7 +145,7 @@ TEST_CASE("write_pipe (synchronous) on a bulk endpoint ", "[wpi]")
145145
catch (const libusbp::error & e)
146146
{
147147
REQUIRE(e.has_code(LIBUSBP_ERROR_TIMEOUT));
148-
#ifdef __linux__
148+
#if defined(__linux__) || defined(__APPLE__)
149149
REQUIRE(transferred == 0); // bad
150150
#else
151151
REQUIRE(transferred == 64);

0 commit comments

Comments
 (0)