diff options
| -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; |
