summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Matt Colyer2008-08-03 17:27:44 -0700
committerGravatar Matt Colyer2008-08-03 17:27:44 -0700
commit4750a54def486d7c2fb6a8de1a287fdad086a92d (patch)
tree6ad707b74a2ad5c474b94b38dbafa57d99afd0ec /src
parent579ca1bda0fbb3d6b8af7275ebec2d64cadad176 (diff)
downloadlibimobiledevice-4750a54def486d7c2fb6a8de1a287fdad086a92d.tar.gz
libimobiledevice-4750a54def486d7c2fb6a8de1a287fdad086a92d.tar.bz2
Added ability to get files larger than a single USB packet size.
Diffstat (limited to 'src')
-rw-r--r--src/AFC.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/AFC.c b/src/AFC.c
index 7030a9e..052213f 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -21,6 +21,9 @@
#include "AFC.h"
+// This is the maximum size an AFC data packet can be
+const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32;
+
extern int debug;
AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
@@ -121,7 +124,8 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
int receive_AFC_data(AFClient *client, char **dump_here) {
AFCPacket *r_packet;
char *buffer = (char*)malloc(sizeof(AFCPacket) * 4);
- int bytes = 0, recv_len = 0;
+ char *final_buffer = NULL;
+ int bytes = 0, recv_len = 0, current_count=0;
int retval = 0;
bytes = mux_recv(client->phone, client->connection, buffer, sizeof(AFCPacket) * 4);
@@ -164,17 +168,27 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
recv_len = r_packet->entire_length - r_packet->this_length;
free(r_packet);
if (!recv_len) return bytes;
- buffer = (char*)malloc(sizeof(char) * recv_len);
- bytes = mux_recv(client->phone, client->connection, buffer, recv_len);
- if (bytes <= 0) {
- free(buffer);
+
+ // Keep collecting packets until we have received the entire file.
+ buffer = (char*)malloc(sizeof(char) * (recv_len < MAXIMUM_PACKET_SIZE) ? recv_len : MAXIMUM_PACKET_SIZE);
+ final_buffer = (char*)malloc(sizeof(char) * recv_len);
+ while(current_count < recv_len){
+ bytes = mux_recv(client->phone, client->connection, buffer, recv_len);
+ if (bytes < 0) break;
+ memcpy(final_buffer+current_count, buffer, bytes);
+ current_count += bytes;
+ }
+ free(buffer);
+
+ /*if (bytes <= 0) {
+ free(final_buffer);
printf("Didn't get it at the second pass.\n");
*dump_here = NULL;
return 0;
- }
+ }*/
- *dump_here = buffer; // what they do beyond this point = not my problem
- return bytes;
+ *dump_here = final_buffer; // what they do beyond this point = not my problem
+ return current_count;
}
char **afc_get_dir_list(AFClient *client, char *dir) {