diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/webinspector.c | 165 | ||||
| -rw-r--r-- | src/webinspector.h | 2 |
2 files changed, 125 insertions, 42 deletions
diff --git a/src/webinspector.c b/src/webinspector.c index d7c86d0..c042df9 100644 --- a/src/webinspector.c +++ b/src/webinspector.c | |||
| @@ -149,27 +149,56 @@ webinspector_error_t webinspector_client_free(webinspector_client_t client) | |||
| 149 | webinspector_error_t webinspector_send(webinspector_client_t client, plist_t plist) | 149 | webinspector_error_t webinspector_send(webinspector_client_t client, plist_t plist) |
| 150 | { | 150 | { |
| 151 | webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR; | 151 | webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR; |
| 152 | char * buf = NULL; | ||
| 153 | uint32_t length = 0; | ||
| 154 | 152 | ||
| 155 | plist_to_bin(plist, &buf, &length); | 153 | uint32_t offset = 0; |
| 156 | if (!buf || length == 0) { | 154 | int is_final_message = 0; |
| 155 | |||
| 156 | char *packet = NULL; | ||
| 157 | uint32_t packet_length = 0; | ||
| 158 | |||
| 159 | debug_info("Sending webinspector message..."); | ||
| 160 | debug_plist(plist); | ||
| 161 | |||
| 162 | /* convert plist to packet */ | ||
| 163 | plist_to_bin(plist, &packet, &packet_length); | ||
| 164 | if (!packet || packet_length == 0) { | ||
| 157 | debug_info("Error converting plist to binary."); | 165 | debug_info("Error converting plist to binary."); |
| 158 | return res; | 166 | return res; |
| 159 | } | 167 | } |
| 160 | 168 | ||
| 161 | plist_t outplist = plist_new_dict(); | 169 | do { |
| 162 | plist_dict_insert_item(outplist, "WIRFinalMessageKey", plist_new_data(buf, length)); | 170 | /* determine if we need to send partial messages */ |
| 163 | free(buf); | 171 | if (packet_length < WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE) { |
| 172 | is_final_message = 1; | ||
| 173 | } else { | ||
| 174 | /* send partial packet */ | ||
| 175 | is_final_message = 0; | ||
| 176 | } | ||
| 164 | 177 | ||
| 165 | debug_plist(outplist); | 178 | plist_t outplist = plist_new_dict(); |
| 179 | if (!is_final_message) { | ||
| 180 | /* split packet into partial chunks */ | ||
| 181 | plist_dict_insert_item(outplist, "WIRPartialMessageKey", plist_new_data(packet + offset, WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE)); | ||
| 182 | offset += WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE; | ||
| 183 | packet_length -= WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE; | ||
| 184 | } else { | ||
| 185 | /* send final chunk */ | ||
| 186 | plist_dict_insert_item(outplist, "WIRFinalMessageKey", plist_new_data(packet + offset, packet_length)); | ||
| 187 | offset += packet_length; | ||
| 188 | packet_length -= packet_length; | ||
| 189 | } | ||
| 166 | 190 | ||
| 167 | res = webinspector_error(property_list_service_send_binary_plist(client->parent, outplist)); | 191 | res = webinspector_error(property_list_service_send_binary_plist(client->parent, outplist)); |
| 168 | plist_free(outplist); | 192 | plist_free(outplist); |
| 169 | if (res != WEBINSPECTOR_E_SUCCESS) { | 193 | outplist = NULL; |
| 170 | debug_info("Sending plist failed with error %d", res); | 194 | if (res != WEBINSPECTOR_E_SUCCESS) { |
| 171 | return res; | 195 | debug_info("Sending plist failed with error %d", res); |
| 172 | } | 196 | return res; |
| 197 | } | ||
| 198 | } while(packet_length > 0); | ||
| 199 | |||
| 200 | free(packet); | ||
| 201 | packet = NULL; | ||
| 173 | 202 | ||
| 174 | return res; | 203 | return res; |
| 175 | } | 204 | } |
| @@ -206,40 +235,92 @@ webinspector_error_t webinspector_receive(webinspector_client_t client, plist_t | |||
| 206 | webinspector_error_t webinspector_receive_with_timeout(webinspector_client_t client, plist_t * plist, uint32_t timeout_ms) | 235 | webinspector_error_t webinspector_receive_with_timeout(webinspector_client_t client, plist_t * plist, uint32_t timeout_ms) |
| 207 | { | 236 | { |
| 208 | webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR; | 237 | webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR; |
| 209 | plist_t outplist = NULL; | 238 | plist_t message = NULL; |
| 239 | plist_t key = NULL; | ||
| 210 | 240 | ||
| 211 | res = webinspector_error(property_list_service_receive_plist_with_timeout(client->parent, &outplist, timeout_ms)); | 241 | int is_final_message = 1; |
| 212 | if (res != WEBINSPECTOR_E_SUCCESS || !outplist) { | ||
| 213 | debug_info("Could not receive plist, error %d", res); | ||
| 214 | plist_free(outplist); | ||
| 215 | return WEBINSPECTOR_E_MUX_ERROR; | ||
| 216 | } | ||
| 217 | 242 | ||
| 218 | plist_t inplistdata = plist_dict_get_item(outplist, "WIRFinalMessageKey"); | 243 | char* buffer = NULL; |
| 219 | if (!inplistdata) { | 244 | uint64_t length = 0; |
| 220 | debug_info("Could not find the internal message plist."); | ||
| 221 | plist_free(outplist); | ||
| 222 | return WEBINSPECTOR_E_PLIST_ERROR; | ||
| 223 | } | ||
| 224 | 245 | ||
| 225 | char * buf; | 246 | char* packet = NULL; |
| 226 | uint64_t length64; | 247 | char* newpacket = NULL; |
| 227 | plist_get_data_val(inplistdata, &buf, &length64); | 248 | uint64_t packet_length = 0; |
| 228 | plist_free(outplist); | 249 | |
| 229 | if (!buf || length64 == 0 || length64 > 0xFFFFFFFF) { | 250 | debug_info("Receiving webinspector message..."); |
| 230 | debug_info("Error getting the inner plist binary data."); | ||
| 231 | free(buf); | ||
| 232 | return WEBINSPECTOR_E_PLIST_ERROR; | ||
| 233 | } | ||
| 234 | 251 | ||
| 235 | plist_from_bin(buf, (uint32_t) length64, plist); | 252 | do { |
| 236 | free(buf); | 253 | /* receive message */ |
| 237 | if (!*plist) { | 254 | res = webinspector_error(property_list_service_receive_plist_with_timeout(client->parent, &message, timeout_ms)); |
| 238 | debug_info("Error restoring the inner plist."); | 255 | if (res != WEBINSPECTOR_E_SUCCESS || !message) { |
| 239 | return WEBINSPECTOR_E_PLIST_ERROR; | 256 | debug_info("Could not receive message, error %d", res); |
| 257 | plist_free(message); | ||
| 258 | return WEBINSPECTOR_E_MUX_ERROR; | ||
| 259 | } | ||
| 260 | |||
| 261 | /* get message key */ | ||
| 262 | key = plist_dict_get_item(message, "WIRFinalMessageKey"); | ||
| 263 | if (!key) { | ||
| 264 | key = plist_dict_get_item(message, "WIRPartialMessageKey"); | ||
| 265 | if (!key) { | ||
| 266 | debug_info("ERROR: Unable to read message key."); | ||
| 267 | plist_free(message); | ||
| 268 | return WEBINSPECTOR_E_PLIST_ERROR; | ||
| 269 | } | ||
| 270 | is_final_message = 0; | ||
| 271 | } else { | ||
| 272 | is_final_message = 1; | ||
| 273 | } | ||
| 274 | |||
| 275 | /* read partial data */ | ||
| 276 | plist_get_data_val(key, &buffer, &length); | ||
| 277 | if (!buffer || length == 0 || length > 0xFFFFFFFF) { | ||
| 278 | debug_info("ERROR: Unable to get the inner plist binary data."); | ||
| 279 | free(packet); | ||
| 280 | free(buffer); | ||
| 281 | return WEBINSPECTOR_E_PLIST_ERROR; | ||
| 282 | } | ||
| 283 | |||
| 284 | /* (re)allocate packet data */ | ||
| 285 | if (!packet) { | ||
| 286 | packet = (char*)malloc(length * sizeof(char)); | ||
| 287 | } else { | ||
| 288 | newpacket = (char*)realloc(packet, (packet_length + length) * sizeof(char)); | ||
| 289 | packet = newpacket; | ||
| 290 | } | ||
| 291 | |||
| 292 | /* copy partial data into final packet data */ | ||
| 293 | memcpy(packet + packet_length, buffer, length); | ||
| 294 | |||
| 295 | /* cleanup buffer */ | ||
| 296 | free(buffer); | ||
| 297 | buffer = NULL; | ||
| 298 | |||
| 299 | if (message) { | ||
| 300 | plist_free(message); | ||
| 301 | message = NULL; | ||
| 302 | } | ||
| 303 | |||
| 304 | /* adjust packet length */ | ||
| 305 | packet_length += length; | ||
| 306 | length = 0; | ||
| 307 | } while(!is_final_message); | ||
| 308 | |||
| 309 | /* read final message */ | ||
| 310 | if (packet_length) { | ||
| 311 | plist_from_bin(packet, (uint32_t)packet_length, plist); | ||
| 312 | if (!*plist) { | ||
| 313 | debug_info("Error restoring the final plist."); | ||
| 314 | free(packet); | ||
| 315 | return WEBINSPECTOR_E_PLIST_ERROR; | ||
| 316 | } | ||
| 317 | |||
| 318 | debug_plist(*plist); | ||
| 240 | } | 319 | } |
| 241 | 320 | ||
| 242 | debug_plist(*plist); | 321 | if (packet) { |
| 322 | free(packet); | ||
| 323 | } | ||
| 243 | 324 | ||
| 244 | return res; | 325 | return res; |
| 245 | } | 326 | } |
diff --git a/src/webinspector.h b/src/webinspector.h index ab04a70..3c8e695 100644 --- a/src/webinspector.h +++ b/src/webinspector.h | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include "libimobiledevice/webinspector.h" | 25 | #include "libimobiledevice/webinspector.h" |
| 26 | #include "property_list_service.h" | 26 | #include "property_list_service.h" |
| 27 | 27 | ||
| 28 | #define WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE 8096 | ||
| 29 | |||
| 28 | struct webinspector_client_private { | 30 | struct webinspector_client_private { |
| 29 | property_list_service_client_t parent; | 31 | property_list_service_client_t parent; |
| 30 | }; | 32 | }; |
