Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions cpp/include/idevice++/notification_proxy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once
#include <idevice++/bindings.hpp>
#include <idevice++/ffi.hpp>
#include <idevice++/provider.hpp>
#include <memory>
#include <string>
#include <vector>

namespace IdeviceFFI {

using NotificationProxyPtr = std::unique_ptr<NotificationProxyClientHandle,
FnDeleter<NotificationProxyClientHandle, notification_proxy_client_free>>;

class NotificationProxy {
public:
// Factory: connect via Provider
static Result<NotificationProxy, FfiError> connect(Provider& provider);

// Factory: wrap an existing Idevice socket (consumes it on success)
static Result<NotificationProxy, FfiError> from_socket(Idevice&& socket);

// Ops
Result<void, FfiError> post_notification(const std::string& name);
Result<void, FfiError> observe_notification(const std::string& name);
Result<void, FfiError> observe_notifications(const std::vector<std::string>& names);
Result<std::string, FfiError> receive_notification();
Result<std::string, FfiError> receive_notification_with_timeout(u_int64_t interval);

// RAII / moves
~NotificationProxy() noexcept = default;
NotificationProxy(NotificationProxy&&) noexcept = default;
NotificationProxy& operator=(NotificationProxy&&) noexcept = default;
NotificationProxy(const NotificationProxy&) = delete;
NotificationProxy& operator=(const NotificationProxy&) = delete;

NotificationProxyClientHandle* raw() const noexcept { return handle_.get(); }
static NotificationProxy adopt(NotificationProxyClientHandle* h) noexcept {
return NotificationProxy(h);
}

private:
explicit NotificationProxy(NotificationProxyClientHandle* h) noexcept : handle_(h) {}
NotificationProxyPtr handle_{};
};

} // namespace IdeviceFFI
82 changes: 82 additions & 0 deletions cpp/src/notification_proxy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Jackson Coxson

#include <idevice++/bindings.hpp>
#include <idevice++/ffi.hpp>
#include <idevice++/notification_proxy.hpp>
#include <idevice++/provider.hpp>

namespace IdeviceFFI {

Result<NotificationProxy, FfiError> NotificationProxy::connect(Provider& provider) {
NotificationProxyClientHandle* out = nullptr;
FfiError e(::notification_proxy_connect(provider.raw(), &out));
if (e) {
provider.release();
return Err(e);
}
return Ok(NotificationProxy::adopt(out));
}

Result<NotificationProxy, FfiError> NotificationProxy::from_socket(Idevice&& socket) {
NotificationProxyClientHandle* out = nullptr;
FfiError e(::notification_proxy_new(socket.raw(), &out));
if (e) {
return Err(e);
}
socket.release();
return Ok(NotificationProxy::adopt(out));
}

Result<void, FfiError> NotificationProxy::post_notification(const std::string& name) {
FfiError e(::notification_proxy_post(handle_.get(), name.c_str()));
if (e) {
return Err(e);
}
return Ok();
}

Result<void, FfiError> NotificationProxy::observe_notification(const std::string& name) {
FfiError e(::notification_proxy_observe(handle_.get(), name.c_str()));
if (e) {
return Err(e);
}
return Ok();
}

Result<void, FfiError> NotificationProxy::observe_notifications(const std::vector<std::string>& names) {
std::vector<const char*> ptrs;
ptrs.reserve(names.size() + 1);
for (const auto& n : names) {
ptrs.push_back(n.c_str());
}
ptrs.push_back(nullptr);
FfiError e(::notification_proxy_observe_multiple(handle_.get(), ptrs.data()));
if (e) {
return Err(e);
}
return Ok();
}

Result<std::string, FfiError> NotificationProxy::receive_notification() {
char* name_ptr = nullptr;
FfiError e(::notification_proxy_receive(handle_.get(), &name_ptr));
if (e) {
return Err(e);
}
std::string name(name_ptr);
::notification_proxy_free_string(name_ptr);
return Ok(std::move(name));
}

Result<std::string, FfiError> NotificationProxy::receive_notification_with_timeout(u_int64_t interval) {
char* name_ptr = nullptr;
FfiError e(::notification_proxy_receive_with_timeout(handle_.get(), interval, &name_ptr));
if (e) {
return Err(e);
}
std::string name(name_ptr);
::notification_proxy_free_string(name_ptr);
return Ok(std::move(name));
}

} // namespace IdeviceFFI
2 changes: 2 additions & 0 deletions ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ debug_proxy = ["idevice/debug_proxy"]
diagnostics_relay = ["idevice/diagnostics_relay"]
dvt = ["idevice/dvt"]
heartbeat = ["idevice/heartbeat"]
notification_proxy = ["idevice/notification_proxy"]
house_arrest = ["idevice/house_arrest"]
installation_proxy = ["idevice/installation_proxy"]
springboardservices = ["idevice/springboardservices"]
Expand Down Expand Up @@ -61,6 +62,7 @@ full = [
"diagnostics_relay",
"dvt",
"heartbeat",
"notification_proxy",
"house_arrest",
"installation_proxy",
"misagent",
Expand Down
2 changes: 2 additions & 0 deletions ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub mod logging;
pub mod misagent;
#[cfg(feature = "mobile_image_mounter")]
pub mod mobile_image_mounter;
#[cfg(feature = "notification_proxy")]
pub mod notification_proxy;
#[cfg(feature = "syslog_relay")]
pub mod os_trace_relay;
mod pairing_file;
Expand Down
Loading