diff options
Diffstat (limited to 'src/afc.c')
-rw-r--r-- | src/afc.c | 49 |
1 files changed, 25 insertions, 24 deletions
@@ -213,7 +213,8 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
213 | uint32_t this_len = 0; | 213 | uint32_t this_len = 0; |
214 | uint32_t current_count = 0; | 214 | uint32_t current_count = 0; |
215 | uint64_t param1 = -1; | 215 | uint64_t param1 = -1; |
216 | char* dump_here = NULL; | 216 | char *buf = NULL; |
217 | uint32_t recv_len = 0; | ||
217 | 218 | ||
218 | if (bytes_recv) { | 219 | if (bytes_recv) { |
219 | *bytes_recv = 0; | 220 | *bytes_recv = 0; |
@@ -223,12 +224,12 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
223 | } | 224 | } |
224 | 225 | ||
225 | /* first, read the AFC header */ | 226 | /* first, read the AFC header */ |
226 | service_receive(client->parent, (char*)&header, sizeof(AFCPacket), bytes_recv); | 227 | service_receive(client->parent, (char*)&header, sizeof(AFCPacket), &recv_len); |
227 | AFCPacket_from_LE(&header); | 228 | AFCPacket_from_LE(&header); |
228 | if (*bytes_recv == 0) { | 229 | if (recv_len == 0) { |
229 | debug_info("Just didn't get enough."); | 230 | debug_info("Just didn't get enough."); |
230 | return AFC_E_MUX_ERROR; | 231 | return AFC_E_MUX_ERROR; |
231 | } else if (*bytes_recv < sizeof(AFCPacket)) { | 232 | } else if (recv_len < sizeof(AFCPacket)) { |
232 | debug_info("Did not even get the AFCPacket header"); | 233 | debug_info("Did not even get the AFCPacket header"); |
233 | return AFC_E_MUX_ERROR; | 234 | return AFC_E_MUX_ERROR; |
234 | } | 235 | } |
@@ -252,7 +253,6 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
252 | } else if ((header.this_length == header.entire_length) | 253 | } else if ((header.this_length == header.entire_length) |
253 | && header.entire_length == sizeof(AFCPacket)) { | 254 | && header.entire_length == sizeof(AFCPacket)) { |
254 | debug_info("Empty AFCPacket received!"); | 255 | debug_info("Empty AFCPacket received!"); |
255 | *bytes_recv = 0; | ||
256 | if (header.operation == AFC_OP_DATA) { | 256 | if (header.operation == AFC_OP_DATA) { |
257 | return AFC_E_SUCCESS; | 257 | return AFC_E_SUCCESS; |
258 | } else { | 258 | } else { |
@@ -265,15 +265,16 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
265 | entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket); | 265 | entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket); |
266 | this_len = (uint32_t)header.this_length - sizeof(AFCPacket); | 266 | this_len = (uint32_t)header.this_length - sizeof(AFCPacket); |
267 | 267 | ||
268 | dump_here = (char*)malloc(entire_len); | 268 | buf = (char*)malloc(entire_len); |
269 | if (this_len > 0) { | 269 | if (this_len > 0) { |
270 | service_receive(client->parent, dump_here, this_len, bytes_recv); | 270 | recv_len = 0; |
271 | if (*bytes_recv <= 0) { | 271 | service_receive(client->parent, buf, this_len, &recv_len); |
272 | free(dump_here); | 272 | if (recv_len <= 0) { |
273 | free(buf); | ||
273 | debug_info("Did not get packet contents!"); | 274 | debug_info("Did not get packet contents!"); |
274 | return AFC_E_NOT_ENOUGH_DATA; | 275 | return AFC_E_NOT_ENOUGH_DATA; |
275 | } else if (*bytes_recv < this_len) { | 276 | } else if (recv_len < this_len) { |
276 | free(dump_here); | 277 | free(buf); |
277 | debug_info("Could not receive this_len=%d bytes", this_len); | 278 | debug_info("Could not receive this_len=%d bytes", this_len); |
278 | return AFC_E_NOT_ENOUGH_DATA; | 279 | return AFC_E_NOT_ENOUGH_DATA; |
279 | } | 280 | } |
@@ -283,12 +284,13 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
283 | 284 | ||
284 | if (entire_len > this_len) { | 285 | if (entire_len > this_len) { |
285 | while (current_count < entire_len) { | 286 | while (current_count < entire_len) { |
286 | service_receive(client->parent, dump_here+current_count, entire_len - current_count, bytes_recv); | 287 | recv_len = 0; |
287 | if (*bytes_recv <= 0) { | 288 | service_receive(client->parent, buf+current_count, entire_len - current_count, &recv_len); |
288 | debug_info("Error receiving data (recv returned %d)", *bytes_recv); | 289 | if (recv_len <= 0) { |
290 | debug_info("Error receiving data (recv returned %d)", recv_len); | ||
289 | break; | 291 | break; |
290 | } | 292 | } |
291 | current_count += *bytes_recv; | 293 | current_count += recv_len; |
292 | } | 294 | } |
293 | if (current_count < entire_len) { | 295 | if (current_count < entire_len) { |
294 | debug_info("WARNING: could not receive full packet (read %s, size %d)", current_count, entire_len); | 296 | debug_info("WARNING: could not receive full packet (read %s, size %d)", current_count, entire_len); |
@@ -296,16 +298,16 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
296 | } | 298 | } |
297 | 299 | ||
298 | if (current_count >= sizeof(uint64_t)) { | 300 | if (current_count >= sizeof(uint64_t)) { |
299 | param1 = le64toh(*(uint64_t*)(dump_here)); | 301 | param1 = le64toh(*(uint64_t*)(buf)); |
300 | } | 302 | } |
301 | 303 | ||
302 | debug_info("packet data size = %i", current_count); | 304 | debug_info("packet data size = %i", current_count); |
303 | if (current_count > 256) { | 305 | if (current_count > 256) { |
304 | debug_info("packet data follows (256/%u)", current_count); | 306 | debug_info("packet data follows (256/%u)", current_count); |
305 | debug_buffer(dump_here, 256); | 307 | debug_buffer(buf, 256); |
306 | } else { | 308 | } else { |
307 | debug_info("packet data follows"); | 309 | debug_info("packet data follows"); |
308 | debug_buffer(dump_here, current_count); | 310 | debug_buffer(buf, current_count); |
309 | } | 311 | } |
310 | 312 | ||
311 | /* check operation types */ | 313 | /* check operation types */ |
@@ -316,7 +318,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
316 | if (param1 != AFC_E_SUCCESS) { | 318 | if (param1 != AFC_E_SUCCESS) { |
317 | /* error status */ | 319 | /* error status */ |
318 | /* free buffer */ | 320 | /* free buffer */ |
319 | free(dump_here); | 321 | free(buf); |
320 | return (afc_error_t)param1; | 322 | return (afc_error_t)param1; |
321 | } | 323 | } |
322 | } else if (header.operation == AFC_OP_DATA) { | 324 | } else if (header.operation == AFC_OP_DATA) { |
@@ -330,8 +332,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
330 | debug_info("got a tell response, position=%lld", param1); | 332 | debug_info("got a tell response, position=%lld", param1); |
331 | } else { | 333 | } else { |
332 | /* unknown operation code received */ | 334 | /* unknown operation code received */ |
333 | free(dump_here); | 335 | free(buf); |
334 | *bytes_recv = 0; | ||
335 | 336 | ||
336 | debug_info("WARNING: Unknown operation code received 0x%llx param1=%lld", header.operation, param1); | 337 | debug_info("WARNING: Unknown operation code received 0x%llx param1=%lld", header.operation, param1); |
337 | #ifndef WIN32 | 338 | #ifndef WIN32 |
@@ -342,9 +343,9 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
342 | } | 343 | } |
343 | 344 | ||
344 | if (bytes) { | 345 | if (bytes) { |
345 | *bytes = dump_here; | 346 | *bytes = buf; |
346 | } else { | 347 | } else { |
347 | free(dump_here); | 348 | free(buf); |
348 | } | 349 | } |
349 | 350 | ||
350 | *bytes_recv = current_count; | 351 | *bytes_recv = current_count; |
@@ -798,7 +799,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_write(afc_client_t client, uint64_t ha | |||
798 | ret = afc_receive_data(client, NULL, &bytes_loc); | 799 | ret = afc_receive_data(client, NULL, &bytes_loc); |
799 | afc_unlock(client); | 800 | afc_unlock(client); |
800 | if (ret != AFC_E_SUCCESS) { | 801 | if (ret != AFC_E_SUCCESS) { |
801 | debug_info("uh oh?"); | 802 | debug_info("Failed to receive reply (%d)", ret); |
802 | } | 803 | } |
803 | *bytes_written = current_count; | 804 | *bytes_written = current_count; |
804 | return ret; | 805 | return ret; |