diff --git a/cpp/include/idevice++/core_device_proxy.hpp b/cpp/include/idevice++/core_device_proxy.hpp index 730fca4..3f84ba8 100644 --- a/cpp/include/idevice++/core_device_proxy.hpp +++ b/cpp/include/idevice++/core_device_proxy.hpp @@ -53,6 +53,14 @@ class Adapter { return Ok(ReadWrite::adopt(s)); } + Result close() { + FfiError e(::adapter_close(handle_.get())); + if (e) { + return Err(e); + } + return Ok(); + } + private: explicit Adapter(AdapterHandle* h) noexcept : handle_(h) {} AdapterPtr handle_{}; diff --git a/cpp/src/adapter_stream.cpp b/cpp/src/adapter_stream.cpp index 2c2df76..498c562 100644 --- a/cpp/src/adapter_stream.cpp +++ b/cpp/src/adapter_stream.cpp @@ -6,45 +6,49 @@ namespace IdeviceFFI { Result AdapterStream::close() { - if (!h_) + if (!h_) { + return Ok(); + } + + FfiError e(::adapter_stream_close(h_)); + if (e) { + return Err(e); + } + + h_ = nullptr; return Ok(); - - FfiError e(::adapter_close(h_)); - if (e) { - return Err(e); - } - - h_ = nullptr; - return Ok(); } -Result AdapterStream::send(const uint8_t *data, size_t len) { - if (!h_) - return Err(FfiError::NotConnected()); - FfiError e(::adapter_send(h_, data, len)); - if (e) { - return Err(e); - } - return Ok(); +Result AdapterStream::send(const uint8_t* data, size_t len) { + if (!h_) { + return Err(FfiError::NotConnected()); + } + FfiError e(::adapter_send(h_, data, len)); + if (e) { + return Err(e); + } + return Ok(); } Result, FfiError> AdapterStream::recv(size_t max_hint) { - if (!h_) - return Err(FfiError::NotConnected()); + if (!h_) { + return Err(FfiError::NotConnected()); + } - if (max_hint == 0) - max_hint = 2048; + if (max_hint == 0) { + max_hint = 2048; + } - std::vector out(max_hint); - size_t actual = 0; + std::vector out(max_hint); + size_t actual = 0; - FfiError e(::adapter_recv(h_, out.data(), &actual, out.size())); - if (e) { - return Err(e); - } + FfiError e(::adapter_recv(h_, out.data(), &actual, out.size())); + if (e) { + return Err(e); + } - out.resize(actual); - return Ok(std::move(out)); + out.resize(actual); + return Ok(std::move(out)); } } // namespace IdeviceFFI diff --git a/ffi/src/adapter.rs b/ffi/src/adapter.rs index 6c466b4..cc82f89 100644 --- a/ffi/src/adapter.rs +++ b/ffi/src/adapter.rs @@ -103,7 +103,9 @@ pub unsafe extern "C" fn adapter_pcap( /// # Safety /// `handle` must be a valid pointer to a handle allocated by this library #[unsafe(no_mangle)] -pub unsafe extern "C" fn adapter_close(handle: *mut AdapterStreamHandle) -> *mut IdeviceFfiError { +pub unsafe extern "C" fn adapter_stream_close( + handle: *mut AdapterStreamHandle, +) -> *mut IdeviceFfiError { if handle.is_null() { return ffi_err!(IdeviceError::FfiInvalidArg); } @@ -114,6 +116,28 @@ pub unsafe extern "C" fn adapter_close(handle: *mut AdapterStreamHandle) -> *mut null_mut() } +/// Stops the entire adapter TCP stack +/// +/// # Arguments +/// * [`handle`] - The adapter handle +/// +/// # Returns +/// Null on success, an IdeviceFfiError otherwise +/// +/// # Safety +/// `handle` must be a valid pointer to a handle allocated by this library +#[unsafe(no_mangle)] +pub unsafe extern "C" fn adapter_close(handle: *mut AdapterHandle) -> *mut IdeviceFfiError { + if handle.is_null() { + return ffi_err!(IdeviceError::FfiInvalidArg); + } + + let adapter = unsafe { &mut (*handle).0 }; + RUNTIME.block_on(async move { adapter.close().await.ok() }); + + null_mut() +} + /// Sends data through the adapter stream /// /// # Arguments diff --git a/idevice/src/tcp/handle.rs b/idevice/src/tcp/handle.rs index 183704b..f4e3718 100644 --- a/idevice/src/tcp/handle.rs +++ b/idevice/src/tcp/handle.rs @@ -38,6 +38,7 @@ enum HandleMessage { path: PathBuf, res: oneshot::Sender>, }, + Die, } #[derive(Debug)] @@ -90,6 +91,9 @@ impl AdapterHandle { res } => { res.send(adapter.pcap(path).await).ok(); + }, + HandleMessage::Die => { + break; } }, Err(_) => { @@ -218,6 +222,16 @@ impl AdapterHandle { )), } } + + pub async fn close(&mut self) -> Result<(), std::io::Error> { + if self.sender.send(HandleMessage::Die).is_err() { + return Err(std::io::Error::new( + std::io::ErrorKind::NetworkUnreachable, + "adapter closed", + )); + } + Ok(()) + } } #[derive(Debug)]