diff options
| author | 2008-08-03 17:27:44 -0700 | |
|---|---|---|
| committer | 2008-08-03 17:27:44 -0700 | |
| commit | 4750a54def486d7c2fb6a8de1a287fdad086a92d (patch) | |
| tree | 6ad707b74a2ad5c474b94b38dbafa57d99afd0ec /src | |
| parent | 579ca1bda0fbb3d6b8af7275ebec2d64cadad176 (diff) | |
| download | libimobiledevice-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.c | 30 |
1 files changed, 22 insertions, 8 deletions
| @@ -21,6 +21,9 @@ | |||
| 21 | 21 | ||
| 22 | #include "AFC.h" | 22 | #include "AFC.h" |
| 23 | 23 | ||
| 24 | // This is the maximum size an AFC data packet can be | ||
| 25 | const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32; | ||
| 26 | |||
| 24 | extern int debug; | 27 | extern int debug; |
| 25 | 28 | ||
| 26 | AFClient *afc_connect(iPhone *phone, int s_port, int d_port) { | 29 | 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) { | |||
| 121 | int receive_AFC_data(AFClient *client, char **dump_here) { | 124 | int receive_AFC_data(AFClient *client, char **dump_here) { |
| 122 | AFCPacket *r_packet; | 125 | AFCPacket *r_packet; |
| 123 | char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); | 126 | char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); |
| 124 | int bytes = 0, recv_len = 0; | 127 | char *final_buffer = NULL; |
| 128 | int bytes = 0, recv_len = 0, current_count=0; | ||
| 125 | int retval = 0; | 129 | int retval = 0; |
| 126 | 130 | ||
| 127 | bytes = mux_recv(client->phone, client->connection, buffer, sizeof(AFCPacket) * 4); | 131 | bytes = mux_recv(client->phone, client->connection, buffer, sizeof(AFCPacket) * 4); |
| @@ -164,17 +168,27 @@ int receive_AFC_data(AFClient *client, char **dump_here) { | |||
| 164 | recv_len = r_packet->entire_length - r_packet->this_length; | 168 | recv_len = r_packet->entire_length - r_packet->this_length; |
| 165 | free(r_packet); | 169 | free(r_packet); |
| 166 | if (!recv_len) return bytes; | 170 | if (!recv_len) return bytes; |
| 167 | buffer = (char*)malloc(sizeof(char) * recv_len); | 171 | |
| 168 | bytes = mux_recv(client->phone, client->connection, buffer, recv_len); | 172 | // Keep collecting packets until we have received the entire file. |
| 169 | if (bytes <= 0) { | 173 | buffer = (char*)malloc(sizeof(char) * (recv_len < MAXIMUM_PACKET_SIZE) ? recv_len : MAXIMUM_PACKET_SIZE); |
| 170 | free(buffer); | 174 | final_buffer = (char*)malloc(sizeof(char) * recv_len); |
| 175 | while(current_count < recv_len){ | ||
| 176 | bytes = mux_recv(client->phone, client->connection, buffer, recv_len); | ||
| 177 | if (bytes < 0) break; | ||
| 178 | memcpy(final_buffer+current_count, buffer, bytes); | ||
| 179 | current_count += bytes; | ||
| 180 | } | ||
| 181 | free(buffer); | ||
| 182 | |||
| 183 | /*if (bytes <= 0) { | ||
| 184 | free(final_buffer); | ||
| 171 | printf("Didn't get it at the second pass.\n"); | 185 | printf("Didn't get it at the second pass.\n"); |
| 172 | *dump_here = NULL; | 186 | *dump_here = NULL; |
| 173 | return 0; | 187 | return 0; |
| 174 | } | 188 | }*/ |
| 175 | 189 | ||
| 176 | *dump_here = buffer; // what they do beyond this point = not my problem | 190 | *dump_here = final_buffer; // what they do beyond this point = not my problem |
| 177 | return bytes; | 191 | return current_count; |
| 178 | } | 192 | } |
| 179 | 193 | ||
| 180 | char **afc_get_dir_list(AFClient *client, char *dir) { | 194 | char **afc_get_dir_list(AFClient *client, char *dir) { |
