diff options
Diffstat (limited to 'src/property_list_service.c')
-rw-r--r-- | src/property_list_service.c | 301 |
1 files changed, 123 insertions, 178 deletions
diff --git a/src/property_list_service.c b/src/property_list_service.c index 8af958e..2fca4e7 100644 --- a/src/property_list_service.c +++ b/src/property_list_service.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * property_list_service.c | 2 | * property_list_service.c |
3 | * PropertyList service implementation. | 3 | * PropertyList service implementation. |
4 | * | 4 | * |
@@ -8,97 +8,86 @@ | |||
8 | * modify it under the terms of the GNU Lesser General Public | 8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. | 10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * This library is distributed in the hope that it will be useful, | 12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. | 15 | * Lesser General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU Lesser General Public | 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 | 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 | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ | 20 | */ |
21 | #ifdef HAVE_CONFIG_H | ||
22 | #include <config.h> | ||
23 | #endif | ||
21 | #include <stdlib.h> | 24 | #include <stdlib.h> |
22 | #include <string.h> | 25 | #include <string.h> |
23 | #include <glib.h> | ||
24 | 26 | ||
25 | #include "property_list_service.h" | 27 | #include "property_list_service.h" |
26 | #include "idevice.h" | 28 | #include "common/debug.h" |
27 | #include "debug.h" | 29 | #include "endianness.h" |
28 | 30 | ||
29 | /** | 31 | /** |
30 | * Convert an idevice_error_t value to an property_list_service_error_t value. | 32 | * Convert a service_error_t value to a property_list_service_error_t value. |
31 | * Used internally to get correct error codes. | 33 | * Used internally to get correct error codes. |
32 | * | 34 | * |
33 | * @param err An idevice_error_t error code | 35 | * @param err A service_error_t error code |
34 | * | 36 | * |
35 | * @return A matching property_list_service_error_t error code, | 37 | * @return A matching property_list_service_error_t error code, |
36 | * PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. | 38 | * PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. |
37 | */ | 39 | */ |
38 | static property_list_service_error_t idevice_to_property_list_service_error(idevice_error_t err) | 40 | static property_list_service_error_t service_to_property_list_service_error(service_error_t err) |
39 | { | 41 | { |
40 | switch (err) { | 42 | switch (err) { |
41 | case IDEVICE_E_SUCCESS: | 43 | case SERVICE_E_SUCCESS: |
42 | return PROPERTY_LIST_SERVICE_E_SUCCESS; | 44 | return PROPERTY_LIST_SERVICE_E_SUCCESS; |
43 | case IDEVICE_E_INVALID_ARG: | 45 | case SERVICE_E_INVALID_ARG: |
44 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 46 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
45 | case IDEVICE_E_SSL_ERROR: | 47 | case SERVICE_E_MUX_ERROR: |
48 | return PROPERTY_LIST_SERVICE_E_MUX_ERROR; | ||
49 | case SERVICE_E_SSL_ERROR: | ||
46 | return PROPERTY_LIST_SERVICE_E_SSL_ERROR; | 50 | return PROPERTY_LIST_SERVICE_E_SSL_ERROR; |
51 | case SERVICE_E_NOT_ENOUGH_DATA: | ||
52 | return PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA; | ||
53 | case SERVICE_E_TIMEOUT: | ||
54 | return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; | ||
47 | default: | 55 | default: |
48 | break; | 56 | break; |
49 | } | 57 | } |
50 | return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; | 58 | return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; |
51 | } | 59 | } |
52 | 60 | ||
53 | /** | 61 | property_list_service_error_t property_list_service_client_new(idevice_t device, lockdownd_service_descriptor_t service, property_list_service_client_t *client) |
54 | * Creates a new property list service for the specified port. | ||
55 | * | ||
56 | * @param device The device to connect to. | ||
57 | * @param port The port on the device to connect to, usually opened by a call to | ||
58 | * lockdownd_start_service. | ||
59 | * @param client Pointer that will be set to a newly allocated | ||
60 | * property_list_service_client_t upon successful return. | ||
61 | * | ||
62 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
63 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one of the arguments is invalid, | ||
64 | * or PROPERTY_LIST_SERVICE_E_MUX_ERROR when connecting to the device failed. | ||
65 | */ | ||
66 | property_list_service_error_t property_list_service_client_new(idevice_t device, uint16_t port, property_list_service_client_t *client) | ||
67 | { | 62 | { |
68 | if (!device || port == 0 || !client || *client) | 63 | if (!device || !service || service->port == 0 || !client || *client) |
69 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 64 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
70 | 65 | ||
71 | /* Attempt connection */ | 66 | service_client_t parent = NULL; |
72 | idevice_connection_t connection = NULL; | 67 | service_error_t rerr = service_client_new(device, service, &parent); |
73 | if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { | 68 | if (rerr != SERVICE_E_SUCCESS) { |
74 | return PROPERTY_LIST_SERVICE_E_MUX_ERROR; | 69 | return service_to_property_list_service_error(rerr); |
75 | } | 70 | } |
76 | 71 | ||
77 | /* create client object */ | 72 | /* create client object */ |
78 | property_list_service_client_t client_loc = (property_list_service_client_t)malloc(sizeof(struct property_list_service_client_private)); | 73 | property_list_service_client_t client_loc = (property_list_service_client_t)malloc(sizeof(struct property_list_service_client_private)); |
79 | client_loc->connection = connection; | 74 | client_loc->parent = parent; |
80 | 75 | ||
76 | /* all done, return success */ | ||
81 | *client = client_loc; | 77 | *client = client_loc; |
82 | |||
83 | return PROPERTY_LIST_SERVICE_E_SUCCESS; | 78 | return PROPERTY_LIST_SERVICE_E_SUCCESS; |
84 | } | 79 | } |
85 | 80 | ||
86 | /** | ||
87 | * Frees a PropertyList service. | ||
88 | * | ||
89 | * @param client The property list service to free. | ||
90 | * | ||
91 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
92 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client is invalid, or a | ||
93 | * PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when another error occured. | ||
94 | */ | ||
95 | property_list_service_error_t property_list_service_client_free(property_list_service_client_t client) | 81 | property_list_service_error_t property_list_service_client_free(property_list_service_client_t client) |
96 | { | 82 | { |
97 | if (!client) | 83 | if (!client) |
98 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 84 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
99 | 85 | ||
100 | property_list_service_error_t err = idevice_to_property_list_service_error(idevice_disconnect(client->connection)); | 86 | property_list_service_error_t err = service_to_property_list_service_error(service_client_free(client->parent)); |
87 | |||
101 | free(client); | 88 | free(client); |
89 | client = NULL; | ||
90 | |||
102 | return err; | 91 | return err; |
103 | } | 92 | } |
104 | 93 | ||
@@ -113,7 +102,8 @@ property_list_service_error_t property_list_service_client_free(property_list_se | |||
113 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | 102 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
114 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are | 103 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are |
115 | * invalid, PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid | 104 | * invalid, PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid |
116 | * plist, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified | 105 | * plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a communication error |
106 | * occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified | ||
117 | * error occurs. | 107 | * error occurs. |
118 | */ | 108 | */ |
119 | static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary) | 109 | static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary) |
@@ -122,9 +112,9 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
122 | char *content = NULL; | 112 | char *content = NULL; |
123 | uint32_t length = 0; | 113 | uint32_t length = 0; |
124 | uint32_t nlen = 0; | 114 | uint32_t nlen = 0; |
125 | int bytes = 0; | 115 | uint32_t bytes = 0; |
126 | 116 | ||
127 | if (!client || (client && !client->connection) || !plist) { | 117 | if (!client || (client && !client->parent) || !plist) { |
128 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 118 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
129 | } | 119 | } |
130 | 120 | ||
@@ -138,15 +128,15 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
138 | return PROPERTY_LIST_SERVICE_E_PLIST_ERROR; | 128 | return PROPERTY_LIST_SERVICE_E_PLIST_ERROR; |
139 | } | 129 | } |
140 | 130 | ||
141 | nlen = GUINT32_TO_BE(length); | 131 | nlen = htobe32(length); |
142 | debug_info("sending %d bytes", length); | 132 | debug_info("sending %d bytes", length); |
143 | idevice_connection_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); | 133 | service_send(client->parent, (const char*)&nlen, sizeof(nlen), &bytes); |
144 | if (bytes == sizeof(nlen)) { | 134 | if (bytes == sizeof(nlen)) { |
145 | idevice_connection_send(client->connection, content, length, (uint32_t*)&bytes); | 135 | service_send(client->parent, content, length, &bytes); |
146 | if (bytes > 0) { | 136 | if (bytes > 0) { |
147 | debug_info("sent %d bytes", bytes); | 137 | debug_info("sent %d bytes", bytes); |
148 | debug_plist(plist); | 138 | debug_plist(plist); |
149 | if ((uint32_t)bytes == length) { | 139 | if (bytes == length) { |
150 | res = PROPERTY_LIST_SERVICE_E_SUCCESS; | 140 | res = PROPERTY_LIST_SERVICE_E_SUCCESS; |
151 | } else { | 141 | } else { |
152 | debug_info("ERROR: Could not send all data (%d of %d)!", bytes, length); | 142 | debug_info("ERROR: Could not send all data (%d of %d)!", bytes, length); |
@@ -155,40 +145,18 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
155 | } | 145 | } |
156 | if (bytes <= 0) { | 146 | if (bytes <= 0) { |
157 | debug_info("ERROR: sending to device failed."); | 147 | debug_info("ERROR: sending to device failed."); |
148 | res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; | ||
158 | } | 149 | } |
159 | 150 | ||
160 | free(content); | 151 | free(content); |
161 | |||
162 | return res; | 152 | return res; |
163 | } | 153 | } |
164 | 154 | ||
165 | /** | ||
166 | * Sends an XML plist. | ||
167 | * | ||
168 | * @param client The property list service client to use for sending. | ||
169 | * @param plist plist to send | ||
170 | * | ||
171 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
172 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or plist is NULL, | ||
173 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, | ||
174 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
175 | */ | ||
176 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist) | 155 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist) |
177 | { | 156 | { |
178 | return internal_plist_send(client, plist, 0); | 157 | return internal_plist_send(client, plist, 0); |
179 | } | 158 | } |
180 | 159 | ||
181 | /** | ||
182 | * Sends a binary plist. | ||
183 | * | ||
184 | * @param client The property list service client to use for sending. | ||
185 | * @param plist plist to send | ||
186 | * | ||
187 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
188 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or plist is NULL, | ||
189 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, | ||
190 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
191 | */ | ||
192 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist) | 160 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist) |
193 | { | 161 | { |
194 | return internal_plist_send(client, plist, 1); | 162 | return internal_plist_send(client, plist, 1); |
@@ -205,6 +173,8 @@ property_list_service_error_t property_list_service_send_binary_plist(property_l | |||
205 | * | 173 | * |
206 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | 174 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
207 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, | 175 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, |
176 | * PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA when not enough data | ||
177 | * received, PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT when the connection times out, | ||
208 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be | 178 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be |
209 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a | 179 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a |
210 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR | 180 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR |
@@ -216,135 +186,110 @@ static property_list_service_error_t internal_plist_receive_timeout(property_lis | |||
216 | uint32_t pktlen = 0; | 186 | uint32_t pktlen = 0; |
217 | uint32_t bytes = 0; | 187 | uint32_t bytes = 0; |
218 | 188 | ||
219 | if (!client || (client && !client->connection) || !plist) { | 189 | if (!client || (client && !client->parent) || !plist) { |
220 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 190 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
221 | } | 191 | } |
222 | 192 | ||
223 | idevice_connection_receive_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); | 193 | *plist = NULL; |
224 | debug_info("initial read=%i", bytes); | 194 | service_error_t serr = service_receive_with_timeout(client->parent, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); |
225 | if (bytes < 4) { | 195 | if (serr != SERVICE_E_SUCCESS) { |
226 | debug_info("initial read failed!"); | 196 | debug_info("initial read failed!"); |
227 | return PROPERTY_LIST_SERVICE_E_MUX_ERROR; | 197 | return service_to_property_list_service_error(serr); |
228 | } else { | 198 | } |
229 | pktlen = GUINT32_FROM_BE(pktlen); | 199 | |
230 | if (pktlen < (1 << 24)) { /* prevent huge buffers */ | 200 | if (bytes == 0) { |
231 | uint32_t curlen = 0; | 201 | /* success but 0 bytes length, assume timeout */ |
232 | char *content = NULL; | 202 | return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; |
233 | debug_info("%d bytes following", pktlen); | 203 | } |
234 | content = (char*)malloc(pktlen); | 204 | |
235 | 205 | debug_info("initial read=%i", bytes); | |
236 | while (curlen < pktlen) { | 206 | |
237 | idevice_connection_receive(client->connection, content+curlen, pktlen-curlen, &bytes); | 207 | uint32_t curlen = 0; |
238 | if (bytes <= 0) { | 208 | char *content = NULL; |
239 | res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; | 209 | |
240 | break; | 210 | pktlen = be32toh(pktlen); |
241 | } | 211 | debug_info("%d bytes following", pktlen); |
242 | debug_info("received %d bytes", bytes); | 212 | content = (char*)malloc(pktlen); |
243 | curlen += bytes; | 213 | if (!content) { |
244 | } | 214 | debug_info("out of memory when allocating %d bytes", pktlen); |
245 | if (!memcmp(content, "bplist00", 8)) { | 215 | return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; |
246 | plist_from_bin(content, pktlen, plist); | 216 | } |
247 | } else { | 217 | |
248 | /* iOS 4.3 hack: plist data might contain invalid null characters, thus we convert those to spaces */ | 218 | while (curlen < pktlen) { |
249 | for (bytes = 0; bytes < pktlen-1; bytes++) { | 219 | serr = service_receive(client->parent, content+curlen, pktlen-curlen, &bytes); |
250 | if (content[bytes] == 0x0) | 220 | if (serr != SERVICE_E_SUCCESS) { |
251 | content[bytes] = 0x20; | 221 | res = service_to_property_list_service_error(serr); |
252 | } | 222 | break; |
253 | plist_from_xml(content, pktlen, plist); | ||
254 | } | ||
255 | if (*plist) { | ||
256 | debug_plist(*plist); | ||
257 | res = PROPERTY_LIST_SERVICE_E_SUCCESS; | ||
258 | } else { | ||
259 | res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; | ||
260 | } | ||
261 | free(content); | ||
262 | content = NULL; | ||
263 | } else { | ||
264 | res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; | ||
265 | } | 223 | } |
224 | debug_info("received %d bytes", bytes); | ||
225 | curlen += bytes; | ||
266 | } | 226 | } |
227 | |||
228 | if (curlen < pktlen) { | ||
229 | debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen); | ||
230 | if (curlen > 0) { | ||
231 | debug_info("incomplete packet following:"); | ||
232 | debug_buffer(content, curlen); | ||
233 | } | ||
234 | free(content); | ||
235 | return res; | ||
236 | } | ||
237 | |||
238 | if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) { | ||
239 | plist_from_bin(content, pktlen, plist); | ||
240 | } else if ((pktlen > 5) && !memcmp(content, "<?xml", 5)) { | ||
241 | /* iOS 4.3+ hack: plist data might contain invalid characters, thus we convert those to spaces */ | ||
242 | for (bytes = 0; bytes < pktlen-1; bytes++) { | ||
243 | if ((content[bytes] >= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d)) | ||
244 | content[bytes] = 0x20; | ||
245 | } | ||
246 | plist_from_xml(content, pktlen, plist); | ||
247 | } else { | ||
248 | debug_info("WARNING: received unexpected non-plist content"); | ||
249 | debug_buffer(content, pktlen); | ||
250 | } | ||
251 | |||
252 | if (*plist) { | ||
253 | debug_plist(*plist); | ||
254 | res = PROPERTY_LIST_SERVICE_E_SUCCESS; | ||
255 | } else { | ||
256 | res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; | ||
257 | } | ||
258 | |||
259 | free(content); | ||
260 | content = NULL; | ||
261 | |||
267 | return res; | 262 | return res; |
268 | } | 263 | } |
269 | 264 | ||
270 | /** | ||
271 | * Receives a plist using the given property list service client with specified | ||
272 | * timeout. | ||
273 | * Binary or XML plists are automatically handled. | ||
274 | * | ||
275 | * @param client The property list service client to use for receiving | ||
276 | * @param plist pointer to a plist_t that will point to the received plist | ||
277 | * upon successful return | ||
278 | * @param timeout Maximum time in milliseconds to wait for data. | ||
279 | * | ||
280 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
281 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when connection or *plist is NULL, | ||
282 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be | ||
283 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a | ||
284 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when | ||
285 | * an unspecified error occurs. | ||
286 | */ | ||
287 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) | 265 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) |
288 | { | 266 | { |
289 | return internal_plist_receive_timeout(client, plist, timeout); | 267 | return internal_plist_receive_timeout(client, plist, timeout); |
290 | } | 268 | } |
291 | 269 | ||
292 | /** | ||
293 | * Receives a plist using the given property list service client. | ||
294 | * Binary or XML plists are automatically handled. | ||
295 | * | ||
296 | * This function is like property_list_service_receive_plist_with_timeout | ||
297 | * using a timeout of 10 seconds. | ||
298 | * @see property_list_service_receive_plist_with_timeout | ||
299 | * | ||
300 | * @param client The property list service client to use for receiving | ||
301 | * @param plist pointer to a plist_t that will point to the received plist | ||
302 | * upon successful return | ||
303 | * | ||
304 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
305 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, | ||
306 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be | ||
307 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a | ||
308 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when | ||
309 | * an unspecified error occurs. | ||
310 | */ | ||
311 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist) | 270 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist) |
312 | { | 271 | { |
313 | return internal_plist_receive_timeout(client, plist, 10000); | 272 | return internal_plist_receive_timeout(client, plist, 30000); |
314 | } | 273 | } |
315 | 274 | ||
316 | /** | ||
317 | * Enable SSL for the given property list service client. | ||
318 | * | ||
319 | * @param client The connected property list service client for which SSL | ||
320 | * should be enabled. | ||
321 | * | ||
322 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
323 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG if client or client->connection is | ||
324 | * NULL, PROPERTY_LIST_SERVICE_E_SSL_ERROR when SSL could not be enabled, | ||
325 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. | ||
326 | */ | ||
327 | property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client) | 275 | property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client) |
328 | { | 276 | { |
329 | if (!client || !client->connection) | 277 | if (!client || !client->parent) |
330 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 278 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
331 | return idevice_to_property_list_service_error(idevice_connection_enable_ssl(client->connection)); | 279 | return service_to_property_list_service_error(service_enable_ssl(client->parent)); |
332 | } | 280 | } |
333 | 281 | ||
334 | /** | ||
335 | * Disable SSL for the given property list service client. | ||
336 | * | ||
337 | * @param client The connected property list service client for which SSL | ||
338 | * should be disabled. | ||
339 | * | ||
340 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
341 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG if client or client->connection is | ||
342 | * NULL, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. | ||
343 | */ | ||
344 | property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client) | 282 | property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client) |
345 | { | 283 | { |
346 | if (!client || !client->connection) | 284 | if (!client || !client->parent) |
347 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 285 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
348 | return idevice_to_property_list_service_error(idevice_connection_disable_ssl(client->connection)); | 286 | return service_to_property_list_service_error(service_disable_ssl(client->parent)); |
349 | } | 287 | } |
350 | 288 | ||
289 | property_list_service_error_t property_list_service_get_service_client(property_list_service_client_t client, service_client_t *service_client) | ||
290 | { | ||
291 | if (!client || !client->parent || !service_client) | ||
292 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | ||
293 | *service_client = client->parent; | ||
294 | return PROPERTY_LIST_SERVICE_E_SUCCESS; | ||
295 | } | ||