summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2020-05-18 04:31:44 +0200
committerGravatar Nikias Bassen2020-05-18 04:31:44 +0200
commit0268777212847afd7734cb280115aea70dc81c92 (patch)
treeb5847442cf82d9ef2923fb791b8e5e58887df8b9
parent2c83cae88c50217f0fbbff5c3d2eab5f252f164e (diff)
downloadlibimobiledevice-0268777212847afd7734cb280115aea70dc81c92.tar.gz
libimobiledevice-0268777212847afd7734cb280115aea70dc81c92.tar.bz2
Add support for com.apple.companion_proxy
-rw-r--r--include/libimobiledevice/companion_proxy.h208
-rw-r--r--src/Makefile.am1
-rw-r--r--src/companion_proxy.c381
-rw-r--r--src/companion_proxy.h34
4 files changed, 624 insertions, 0 deletions
diff --git a/include/libimobiledevice/companion_proxy.h b/include/libimobiledevice/companion_proxy.h
new file mode 100644
index 0000000..aaf7661
--- /dev/null
+++ b/include/libimobiledevice/companion_proxy.h
@@ -0,0 +1,208 @@
1/**
2 * @file libimobiledevice/companion_proxy.h
3 * @brief Companion proxy support.
4 * \internal
5 *
6 * Copyright (c) 2019-2020 Nikias Bassen, All Rights Reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef ICOMPANION_PROXY_H
24#define ICOMPANION_PROXY_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include <libimobiledevice/libimobiledevice.h>
31#include <libimobiledevice/lockdown.h>
32
33#define COMPPROXY_SERVICE_NAME "com.apple.companion_proxy"
34
35/** Error Codes */
36typedef enum {
37 COMPPROXY_E_SUCCESS = 0,
38 COMPPROXY_E_INVALID_ARG = -1,
39 COMPPROXY_E_PLIST_ERROR = -2,
40 COMPPROXY_E_MUX_ERROR = -3,
41 COMPPROXY_E_SSL_ERROR = -4,
42 COMPPROXY_E_NOT_ENOUGH_DATA = -5,
43 COMPPROXY_E_TIMEOUT = -6,
44 COMPPROXY_E_OP_IN_PROGRESS = -7,
45 COMPPROXY_E_NO_DEVICES = -100,
46 COMPPROXY_E_UNSUPPORTED_KEY = -101,
47 COMPPROXY_E_TIMEOUT_REPLY = -102,
48 COMPPROXY_E_UNKNOWN_ERROR = -256
49} compproxy_error_t;
50
51typedef struct compproxy_client_private compproxy_client_private;
52typedef compproxy_client_private *compproxy_client_t; /**< The client handle. */
53
54typedef void (*compproxy_device_event_cb_t) (plist_t event, void* userdata);
55
56/**
57 * Connects to the compproxy service on the specified device.
58 *
59 * @param device The device to connect to.
60 * @param service The service descriptor returned by lockdownd_start_service.
61 * @param client Pointer that will point to a newly allocated
62 * compproxy_client_t upon successful return. Must be freed using
63 * compproxy_client_free() after use.
64 *
65 * @return COMPPROXY_E_SUCCESS on success, COMPPROXY_E_INVALID_ARG when
66 * the arguments are invalid, or an COMPPROXY_E_* error code otherwise.
67 */
68compproxy_error_t compproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, compproxy_client_t* client);
69
70/**
71 * Starts a new compproxy service on the specified device and connects to it.
72 *
73 * @param device The device to connect to.
74 * @param client Pointer that will point to a newly allocated
75 * compproxy_client_t upon successful return. Must be freed using
76 * compproxy_client_free() after use.
77 * @param label The label to use for communication. Usually the program name.
78 * Pass NULL to disable sending the label in requests to lockdownd.
79 *
80 * @return COMPPROXY_E_SUCCESS on success, or an COMPPROXY_E_* error
81 * code otherwise.
82 */
83compproxy_error_t compproxy_client_start_service(idevice_t device, compproxy_client_t* client, const char* label);
84
85/**
86 * Disconnects a compproxy client from the device and frees up the
87 * compproxy client data.
88 *
89 * @param client The compproxy client to disconnect and free.
90 *
91 * @return COMPPROXY_E_SUCCESS on success, COMPPROXY_E_INVALID_ARG when
92 * client is NULL, or an COMPPROXY_E_* error code otherwise.
93 */
94compproxy_error_t compproxy_client_free(compproxy_client_t client);
95
96/**
97 * Sends a plist to the service.
98 *
99 * @param client The compproxy client
100 * @param plist The plist to send
101 *
102 * @return COMPPROXY_E_SUCCESS on success,
103 * COMPPROXY_E_INVALID_ARG when client or plist is NULL
104 */
105compproxy_error_t compproxy_send(compproxy_client_t client, plist_t plist);
106
107/**
108 * Receives a plist from the service.
109 *
110 * @param client The compproxy client
111 * @param plist The plist to store the received data
112 *
113 * @return COMPPROXY_E_SUCCESS on success,
114 * COMPPROXY_E_INVALID_ARG when client or plist is NULL
115 */
116compproxy_error_t compproxy_receive(compproxy_client_t client, plist_t * plist);
117
118/**
119 * Retrieves a list of paired devices.
120 *
121 * @param client The compproxy client
122 * @param devices Point that will receive a PLIST_ARRAY with paired device UDIDs
123 *
124 * @note The device closes the connection after sending the reply.
125 *
126 * @return COMPPROXY_E_SUCCESS on success,
127 * COMPPROXY_E_NO_DEVICES if no devices are paired,
128 * or a COMPPROXY_E_* error code otherwise.
129 */
130compproxy_error_t compproxy_get_device_registry(compproxy_client_t client, plist_t* paired_devices);
131
132/**
133 * Starts listening for paired devices.
134 *
135 * @param client The compproxy client
136 * @param callback Callback function that will be called when a new device is detected
137 * @param userdata Pointer that that will be passed to the callback function
138 *
139 * @note The event parameter that gets passed to the callback function is
140 * freed internally after returning from the callback. The consumer needs
141 * to make a copy if required.
142 *
143 * @return COMPPROXY_E_SUCCESS on success,
144 * or a COMPPROXY_E_* error code otherwise.
145 */
146compproxy_error_t compproxy_start_listening_for_devices(compproxy_client_t client, compproxy_device_event_cb_t callback, void* userdata);
147
148/**
149 * Stops listening for paired devices
150 *
151 * @param client The compproxy client
152 *
153 * @return COMPPROXY_E_SUCCESS on success,
154 * or a COMPPROXY_E_* error code otherwise.
155 */
156compproxy_error_t compproxy_stop_listening_for_devices(compproxy_client_t client);
157
158/**
159 * Returns a value for the given key.
160 *
161 * @param client The compproxy client
162 * @param companion_udid UDID of the (paired) watch
163 * @param key The key to retrieve the value for
164 *
165 * @note The device closes the connection after sending the reply.
166 *
167 * @return COMPPROXY_E_SUCCESS on success,
168 * COMPPROXY_E_INVALID_ARG when client or paired_devices is invalid,
169 * COMPPROXY_E_UNSUPPORTED_KEY if the watch doesn't support the given key,
170 * or a COMPPROXY_E_* error code otherwise.
171 */
172compproxy_error_t compproxy_get_value_from_registry(compproxy_client_t client, const char* companion_udid, const char* key, plist_t* value);
173
174/**
175 * Start forwarding a service port on the watch to a port on the idevice.
176 *
177 * @see compproxy_stop_forwarding_service_port
178 *
179 * @param client The compproxy client
180 * @param remote_port remote port
181 * @param service_name The name of the service that shall be forwarded
182 * @param forward_port Pointer that will receive the newly-assigned port accessible via USB/Network on the idevice
183 * @param options PLIST_DICT with additional options. Currently known are
184 * IsServiceLowPriority (boolean) and PreferWifi (boolean).
185 *
186 * @return COMPPROXY_E_SUCCESS on success,
187 * or a COMPPROXY_E_* error code otherwise.
188 */
189compproxy_error_t compproxy_start_forwarding_service_port(compproxy_client_t client, uint16_t remote_port, const char* service_name, uint16_t* forward_port, plist_t options);
190
191/**
192 * Stop forwarding a service port between watch and idevice.
193 *
194 * @see compproxy_start_forwarding_service_port
195 *
196 * @param client The compproxy client
197 * @param remote_port remote port
198 *
199 * @return COMPPROXY_E_SUCCESS on success,
200 * or a COMPPROXY_E_* error code otherwise.
201 */
202compproxy_error_t compproxy_stop_forwarding_service_port(compproxy_client_t client, uint16_t remote_port);
203
204#ifdef __cplusplus
205}
206#endif
207
208#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 75c6dfe..feabf40 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,7 @@ libimobiledevice_la_SOURCES = idevice.c idevice.h \
30 webinspector.c webinspector.h\ 30 webinspector.c webinspector.h\
31 mobileactivation.c mobileactivation.h\ 31 mobileactivation.c mobileactivation.h\
32 preboard.c preboard.h \ 32 preboard.c preboard.h \
33 companion_proxy.c companion_proxy.h \
33 syslog_relay.c syslog_relay.h 34 syslog_relay.c syslog_relay.h
34 35
35if WIN32 36if WIN32
diff --git a/src/companion_proxy.c b/src/companion_proxy.c
new file mode 100644
index 0000000..f4fe96c
--- /dev/null
+++ b/src/companion_proxy.c
@@ -0,0 +1,381 @@
1/*
2 * compproxy.c
3 * com.apple.companion_proxy service implementation.
4 *
5 * Copyright (c) 2019-2020 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25#include <string.h>
26#include <stdlib.h>
27#include <plist/plist.h>
28
29#include "companion_proxy.h"
30#include "lockdown.h"
31#include "common/debug.h"
32#include "common/thread.h"
33
34/**
35 * Convert a property_list_service_error_t value to a compproxy_error_t value.
36 * Used internally to get correct error codes.
37 *
38 * @param err An property_list_service_error_t error code
39 *
40 * @return A matching compproxy_error_t error code,
41 * COMPPROXY_E_UNKNOWN_ERROR otherwise.
42 */
43static compproxy_error_t compproxy_error(property_list_service_error_t err)
44{
45 switch (err) {
46 case PROPERTY_LIST_SERVICE_E_SUCCESS:
47 return COMPPROXY_E_SUCCESS;
48 case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
49 return COMPPROXY_E_INVALID_ARG;
50 case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
51 return COMPPROXY_E_PLIST_ERROR;
52 case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
53 return COMPPROXY_E_MUX_ERROR;
54 case PROPERTY_LIST_SERVICE_E_SSL_ERROR:
55 return COMPPROXY_E_SSL_ERROR;
56 case PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA:
57 return COMPPROXY_E_NOT_ENOUGH_DATA;
58 case PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT:
59 return COMPPROXY_E_TIMEOUT;
60 default:
61 break;
62 }
63 return COMPPROXY_E_UNKNOWN_ERROR;
64}
65
66LIBIMOBILEDEVICE_API compproxy_error_t compproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, compproxy_client_t * client)
67{
68 *client = NULL;
69
70 if (!device || !service || service->port == 0 || !client || *client) {
71 debug_info("Incorrect parameter passed to compproxy_client_new.");
72 return COMPPROXY_E_INVALID_ARG;
73 }
74
75 debug_info("Creating compproxy_client, port = %d.", service->port);
76
77 property_list_service_client_t plclient = NULL;
78 compproxy_error_t ret = compproxy_error(property_list_service_client_new(device, service, &plclient));
79 if (ret != COMPPROXY_E_SUCCESS) {
80 debug_info("Creating a property list client failed. Error: %i", ret);
81 return ret;
82 }
83
84 compproxy_client_t client_loc = (compproxy_client_t) malloc(sizeof(struct compproxy_client_private));
85 client_loc->parent = plclient;
86 client_loc->event_thread = THREAD_T_NULL;
87
88 *client = client_loc;
89
90 debug_info("compproxy_client successfully created.");
91 return COMPPROXY_E_SUCCESS;
92}
93
94LIBIMOBILEDEVICE_API compproxy_error_t compproxy_client_start_service(idevice_t device, compproxy_client_t * client, const char* label)
95{
96 compproxy_error_t err = COMPPROXY_E_UNKNOWN_ERROR;
97 service_client_factory_start_service(device, COMPPROXY_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(compproxy_client_new), &err);
98 return err;
99}
100
101LIBIMOBILEDEVICE_API compproxy_error_t compproxy_client_free(compproxy_client_t client)
102{
103 if (!client)
104 return COMPPROXY_E_INVALID_ARG;
105
106 property_list_service_client_t parent = client->parent;
107 client->parent = NULL;
108 if (client->event_thread) {
109 debug_info("joining event thread");
110 thread_join(client->event_thread);
111 thread_free(client->event_thread);
112 client->event_thread = THREAD_T_NULL;
113 }
114 compproxy_error_t err = compproxy_error(property_list_service_client_free(parent));
115 free(client);
116
117 return err;
118}
119
120LIBIMOBILEDEVICE_API compproxy_error_t compproxy_send(compproxy_client_t client, plist_t plist)
121{
122 compproxy_error_t res = COMPPROXY_E_UNKNOWN_ERROR;
123
124 res = compproxy_error(property_list_service_send_binary_plist(client->parent, plist));
125 if (res != COMPPROXY_E_SUCCESS) {
126 debug_info("Sending plist failed with error %d", res);
127 return res;
128 }
129
130 return res;
131}
132
133LIBIMOBILEDEVICE_API compproxy_error_t compproxy_receive(compproxy_client_t client, plist_t * plist)
134{
135 compproxy_error_t res = COMPPROXY_E_UNKNOWN_ERROR;
136 plist_t outplist = NULL;
137 res = compproxy_error(property_list_service_receive_plist_with_timeout(client->parent, &outplist, 10000));
138 if (res != COMPPROXY_E_SUCCESS && res != COMPPROXY_E_TIMEOUT) {
139 debug_info("Could not receive plist, error %d", res);
140 plist_free(outplist);
141 } else if (res == COMPPROXY_E_SUCCESS) {
142 *plist = outplist;
143 }
144 return res;
145}
146
147LIBIMOBILEDEVICE_API compproxy_error_t compproxy_get_device_registry(compproxy_client_t client, plist_t* paired_devices)
148{
149 if (!client || !paired_devices) {
150 return COMPPROXY_E_INVALID_ARG;
151 }
152
153 plist_t dict = plist_new_dict();
154 plist_dict_set_item(dict, "Command", plist_new_string("GetDeviceRegistry"));
155
156 compproxy_error_t res = compproxy_send(client, dict);
157 plist_free(dict);
158 dict = NULL;
159 if (res != COMPPROXY_E_SUCCESS) {
160 return res;
161 }
162
163 res = compproxy_receive(client, &dict);
164 if (res != COMPPROXY_E_SUCCESS) {
165 return res;
166 }
167 if (!dict || !PLIST_IS_DICT(dict)) {
168 return COMPPROXY_E_PLIST_ERROR;
169 }
170 plist_t val = plist_dict_get_item(dict, "PairedDevicesArray");
171 if (val) {
172 *paired_devices = plist_copy(val);
173 res = COMPPROXY_E_SUCCESS;
174 } else {
175 res = COMPPROXY_E_UNKNOWN_ERROR;
176 val = plist_dict_get_item(dict, "Error");
177 if (val) {
178 if (plist_string_val_compare(val, "NoPairedWatches")) {
179 res = COMPPROXY_E_NO_DEVICES;
180 }
181 }
182 }
183 plist_free(dict);
184 return res;
185}
186
187struct compproxy_cb_data {
188 compproxy_client_t client;
189 compproxy_device_event_cb_t cbfunc;
190 void* user_data;
191};
192
193static void* compproxy_event_thread(void* arg)
194{
195 struct compproxy_cb_data* data = (struct compproxy_cb_data*)arg;
196 compproxy_client_t client = data->client;
197 compproxy_error_t res;
198
199 plist_t command = plist_new_dict();
200 plist_dict_set_item(command, "Command", plist_new_string("StartListeningForDevices"));
201 res = compproxy_send(client, command);
202 plist_free(command);
203
204 if (res != COMPPROXY_E_SUCCESS) {
205 free(data);
206 client->event_thread = THREAD_T_NULL;
207 return NULL;
208 }
209
210 while (client && client->parent) {
211 plist_t node = NULL;
212 res = compproxy_error(property_list_service_receive_plist_with_timeout(client->parent, &node, 1000));
213 if (res != COMPPROXY_E_SUCCESS && res != COMPPROXY_E_TIMEOUT) {
214 debug_info("could not receive plist, error %d", res);
215 break;
216 }
217
218 if (node) {
219 data->cbfunc(node, data->user_data);
220 }
221 plist_free(node);
222 }
223
224 client->event_thread = THREAD_T_NULL;
225 free(data);
226
227 return NULL;
228}
229
230LIBIMOBILEDEVICE_API compproxy_error_t compproxy_start_listening_for_devices(compproxy_client_t client, compproxy_device_event_cb_t callback, void* userdata)
231{
232 if (!client || !client->parent || !callback) {
233 return COMPPROXY_E_INVALID_ARG;
234 }
235
236 if (client->event_thread) {
237 return COMPPROXY_E_OP_IN_PROGRESS;
238 }
239
240 compproxy_error_t res = COMPPROXY_E_UNKNOWN_ERROR;
241 struct compproxy_cb_data *data = (struct compproxy_cb_data*)malloc(sizeof(struct compproxy_cb_data));
242 if (data) {
243 data->client = client;
244 data->cbfunc = callback;
245 data->user_data = userdata;
246
247 if (thread_new(&client->event_thread, compproxy_event_thread, data) == 0) {
248 res = COMPPROXY_E_SUCCESS;
249 } else {
250 free(data);
251 }
252 }
253 return res;
254}
255
256LIBIMOBILEDEVICE_API compproxy_error_t compproxy_stop_listening_for_devices(compproxy_client_t client)
257{
258 property_list_service_client_t parent = client->parent;
259 client->parent = NULL;
260 if (client->event_thread) {
261 debug_info("joining event thread");
262 thread_join(client->event_thread);
263 thread_free(client->event_thread);
264 client->event_thread = THREAD_T_NULL;
265 }
266 client->parent = parent;
267 return COMPPROXY_E_SUCCESS;
268}
269
270LIBIMOBILEDEVICE_API compproxy_error_t compproxy_get_value_from_registry(compproxy_client_t client, const char* companion_udid, const char* key, plist_t* value)
271{
272 if (!client || !companion_udid || !key || !value) {
273 return COMPPROXY_E_INVALID_ARG;
274 }
275
276 plist_t dict = plist_new_dict();
277 plist_dict_set_item(dict, "Command", plist_new_string("GetValueFromRegistry"));
278 plist_dict_set_item(dict, "GetValueGizmoUDIDKey", plist_new_string(companion_udid));
279 plist_dict_set_item(dict, "GetValueKeyKey", plist_new_string(key));
280
281 compproxy_error_t res = compproxy_send(client, dict);
282 plist_free(dict);
283 dict = NULL;
284 if (res != COMPPROXY_E_SUCCESS) {
285 return res;
286 }
287
288 res = compproxy_receive(client, &dict);
289 if (res != COMPPROXY_E_SUCCESS) {
290 return res;
291 }
292 if (!dict || !PLIST_IS_DICT(dict)) {
293 return COMPPROXY_E_PLIST_ERROR;
294 }
295 plist_t val = plist_dict_get_item(dict, "RetrievedValueDictionary");
296 if (val) {
297 *value = plist_copy(val);
298 res = COMPPROXY_E_SUCCESS;
299 } else {
300 res = COMPPROXY_E_UNKNOWN_ERROR;
301 val = plist_dict_get_item(dict, "Error");
302 if (val) {
303 if (!plist_string_val_compare(val, "UnsupportedWatchKey")) {
304 res = COMPPROXY_E_UNSUPPORTED_KEY;
305 } else if (plist_string_val_compare(val, "TimeoutReply")) {
306 res = COMPPROXY_E_TIMEOUT_REPLY;
307 }
308 }
309 }
310 plist_free(dict);
311 return res;
312}
313
314LIBIMOBILEDEVICE_API compproxy_error_t compproxy_start_forwarding_service_port(compproxy_client_t client, uint16_t remote_port, const char* service_name, uint16_t* forward_port, plist_t options)
315{
316 if (!client) {
317 return COMPPROXY_E_INVALID_ARG;
318 }
319
320 plist_t dict = plist_new_dict();
321 plist_dict_set_item(dict, "Command", plist_new_string("StartForwardingServicePort"));
322 plist_dict_set_item(dict, "GizmoRemotePortNumber", plist_new_uint(remote_port));
323 if (service_name) {
324 plist_dict_set_item(dict, "ForwardedServiceName", plist_new_string(service_name));
325 }
326 plist_dict_set_item(dict, "IsServiceLowPriority", plist_new_bool(0));
327 plist_dict_set_item(dict, "PreferWifi", plist_new_bool(0));
328 if (options) {
329 plist_dict_merge(dict, options);
330 }
331
332 compproxy_error_t res = compproxy_send(client, dict);
333 plist_free(dict);
334 dict = NULL;
335 if (res != COMPPROXY_E_SUCCESS) {
336 return res;
337 }
338
339 res = compproxy_receive(client, &dict);
340 if (res != COMPPROXY_E_SUCCESS) {
341 return res;
342 }
343 plist_t val = plist_dict_get_item(dict, "CompanionProxyServicePort");
344 if (val) {
345 uint64_t u64val = 0;
346 plist_get_uint_val(val, &u64val);
347 *forward_port = (uint16_t)u64val;
348 res = COMPPROXY_E_SUCCESS;
349 } else {
350 res = COMPPROXY_E_UNKNOWN_ERROR;
351 }
352 plist_free(dict);
353
354 return res;
355}
356
357LIBIMOBILEDEVICE_API compproxy_error_t compproxy_stop_forwarding_service_port(compproxy_client_t client, uint16_t remote_port)
358{
359 if (!client) {
360 return COMPPROXY_E_INVALID_ARG;
361 }
362
363 plist_t dict = plist_new_dict();
364 plist_dict_set_item(dict, "Command", plist_new_string("StopForwardingServicePort"));
365 plist_dict_set_item(dict, "GizmoRemotePortNumber", plist_new_uint(remote_port));
366
367 compproxy_error_t res = compproxy_send(client, dict);
368 plist_free(dict);
369 dict = NULL;
370 if (res != COMPPROXY_E_SUCCESS) {
371 return res;
372 }
373
374 res = compproxy_receive(client, &dict);
375 if (res != COMPPROXY_E_SUCCESS) {
376 return res;
377 }
378 plist_free(dict);
379
380 return res;
381}
diff --git a/src/companion_proxy.h b/src/companion_proxy.h
new file mode 100644
index 0000000..1b520d4
--- /dev/null
+++ b/src/companion_proxy.h
@@ -0,0 +1,34 @@
1/*
2 * compproxy.h
3 * com.apple.companion_proxy service header file.
4 *
5 * Copyright (c) 2019-2020 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#ifndef __COMPANION_PROXY_H
23#define __COMPANION_PROXY_H
24
25#include "libimobiledevice/companion_proxy.h"
26#include "property_list_service.h"
27#include "common/thread.h"
28
29struct compproxy_client_private {
30 property_list_service_client_t parent;
31 THREAD_T event_thread;
32};
33
34#endif