diff options
| author | 2008-08-19 23:58:20 +0200 | |
|---|---|---|
| committer | 2008-08-31 19:27:20 +0200 | |
| commit | ad65cefa1c041bbd4792e3dc4f4afc7b07026930 (patch) | |
| tree | 76c73d5372cc7152ec20fb809b6da71f3dd896df | |
| parent | 21d5d4ac4b4bd419e0d8752147464984497c98ec (diff) | |
| download | libimobiledevice-ad65cefa1c041bbd4792e3dc4f4afc7b07026930.tar.gz libimobiledevice-ad65cefa1c041bbd4792e3dc4f4afc7b07026930.tar.bz2 | |
migrate usbmux.c.
| -rw-r--r-- | include/libiphone/libiphone.h | 17 | ||||
| -rw-r--r-- | src/iphone.c | 3 | ||||
| -rw-r--r-- | src/lockdown.c | 6 | ||||
| -rw-r--r-- | src/lockdown.h | 2 | ||||
| -rw-r--r-- | src/usbmux.c | 170 | ||||
| -rw-r--r-- | src/usbmux.h | 9 |
6 files changed, 105 insertions, 102 deletions
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h index 241c6fa..89b8529 100644 --- a/include/libiphone/libiphone.h +++ b/include/libiphone/libiphone.h | |||
| @@ -32,18 +32,19 @@ extern "C" { | |||
| 32 | //general errors | 32 | //general errors |
| 33 | #define IPHONE_E_SUCCESS 0 | 33 | #define IPHONE_E_SUCCESS 0 |
| 34 | #define IPHONE_E_INVALID_ARG -1 | 34 | #define IPHONE_E_INVALID_ARG -1 |
| 35 | #define IPHONE_E_NO_DEVICE -2 | 35 | #define IPHONE_E_UNKNOWN_ERROR -2 |
| 36 | #define IPHONE_E_TIMEOUT -3 | 36 | #define IPHONE_E_NO_DEVICE -3 |
| 37 | #define IPHONE_E_NOT_ENOUGH_DATA -4 | 37 | #define IPHONE_E_TIMEOUT -4 |
| 38 | #define IPHONE_E_BAD_HEADER -5 | 38 | #define IPHONE_E_NOT_ENOUGH_DATA -5 |
| 39 | #define IPHONE_E_BAD_HEADER -6 | ||
| 39 | 40 | ||
| 40 | //lockdownd specific error | 41 | //lockdownd specific error |
| 41 | #define IPHONE_E_INVALID_CONF -6 | 42 | #define IPHONE_E_INVALID_CONF -7 |
| 42 | #define IPHONE_E_PAIRING_FAILED -7 | 43 | #define IPHONE_E_PAIRING_FAILED -8 |
| 43 | #define IPHONE_E_SSL_ERROR -8 | 44 | #define IPHONE_E_SSL_ERROR -9 |
| 44 | 45 | ||
| 45 | //afc specific error | 46 | //afc specific error |
| 46 | #define IPHONE_E_NO_SUCH_FILE -9 | 47 | #define IPHONE_E_NO_SUCH_FILE -10 |
| 47 | 48 | ||
| 48 | struct iphone_device_int; | 49 | struct iphone_device_int; |
| 49 | typedef struct iphone_device_int *iphone_device_t; | 50 | typedef struct iphone_device_int *iphone_device_t; |
diff --git a/src/iphone.c b/src/iphone.c index f3b7202..9027e35 100644 --- a/src/iphone.c +++ b/src/iphone.c | |||
| @@ -42,7 +42,6 @@ int iphone_get_device ( iphone_device_t *device ){ | |||
| 42 | struct usb_bus *bus, *busses; | 42 | struct usb_bus *bus, *busses; |
| 43 | struct usb_device *dev; | 43 | struct usb_device *dev; |
| 44 | iphone_device_t phone = (iphone_device_t)malloc(sizeof(struct iphone_device_int)); | 44 | iphone_device_t phone = (iphone_device_t)malloc(sizeof(struct iphone_device_int)); |
| 45 | usbmux_version_header *version = version_header(); | ||
| 46 | 45 | ||
| 47 | // Initialize the struct | 46 | // Initialize the struct |
| 48 | phone->device = NULL; | 47 | phone->device = NULL; |
| @@ -126,7 +125,7 @@ int iphone_get_device ( iphone_device_t *device ){ | |||
| 126 | if (debug) fprintf(stderr, "get_iPhone(): Unknown error.\n"); | 125 | if (debug) fprintf(stderr, "get_iPhone(): Unknown error.\n"); |
| 127 | free_iPhone(phone); | 126 | free_iPhone(phone); |
| 128 | free(version); | 127 | free(version); |
| 129 | return IPHONE_E_NO_DEVICE; // if it got to this point it's gotta be bad | 128 | return IPHONE_E_UNKNOWN_ERROR; // if it got to this point it's gotta be bad |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | /** Cleans up an iPhone structure, then frees the structure itself. | 131 | /** Cleans up an iPhone structure, then frees the structure itself. |
diff --git a/src/lockdown.c b/src/lockdown.c index bc70d53..e8626bc 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -77,8 +77,8 @@ char *lockdownd_generate_hostid() { | |||
| 77 | iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) { | 77 | iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) { |
| 78 | if (!phone) return NULL; | 78 | if (!phone) return NULL; |
| 79 | iphone_lckd_client_t control = (iphone_lckd_client_t)malloc(sizeof(struct iphone_lckd_client_int)); | 79 | iphone_lckd_client_t control = (iphone_lckd_client_t)malloc(sizeof(struct iphone_lckd_client_int)); |
| 80 | control->connection = mux_connect(phone, 0x0a00, 0xf27e); | 80 | |
| 81 | if (!control->connection) { | 81 | if (IPHONE_E_SUCCESS != iphone_mux_new_client ( phone, 0x0a00, 0xf27e, &control->connection)) { |
| 82 | free(control); | 82 | free(control); |
| 83 | return NULL; | 83 | return NULL; |
| 84 | } | 84 | } |
| @@ -100,7 +100,7 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) { | |||
| 100 | mux_close_connection(client->connection); | 100 | mux_close_connection(client->connection); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | if (client->ssl_session) gnutls_deinit(*control->ssl_session); | 103 | if (client->ssl_session) gnutls_deinit(*client->ssl_session); |
| 104 | free(client->ssl_session); | 104 | free(client->ssl_session); |
| 105 | free(client); | 105 | free(client); |
| 106 | } | 106 | } |
diff --git a/src/lockdown.h b/src/lockdown.h index 1c83ab3..f22d7db 100644 --- a/src/lockdown.h +++ b/src/lockdown.h | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | struct iphone_lckd_client_int { | 35 | struct iphone_lckd_client_int { |
| 36 | usbmux_connection *connection; | 36 | iphone_umux_client_t connection; |
| 37 | gnutls_session_t *ssl_session; | 37 | gnutls_session_t *ssl_session; |
| 38 | int in_SSL; | 38 | int in_SSL; |
| 39 | char *gtls_buffer_hack; | 39 | char *gtls_buffer_hack; |
diff --git a/src/usbmux.c b/src/usbmux.c index a4a859a..48cb963 100644 --- a/src/usbmux.c +++ b/src/usbmux.c | |||
| @@ -29,8 +29,8 @@ | |||
| 29 | 29 | ||
| 30 | extern int debug; | 30 | extern int debug; |
| 31 | 31 | ||
| 32 | static usbmux_connection **connlist = NULL; | 32 | static iphone_umux_client_t *connlist = NULL; |
| 33 | static int connections = 0; | 33 | static int clients = 0; |
| 34 | 34 | ||
| 35 | /** Creates a USBMux packet for the given set of ports. | 35 | /** Creates a USBMux packet for the given set of ports. |
| 36 | * | 36 | * |
| @@ -76,10 +76,10 @@ usbmux_version_header *version_header() { | |||
| 76 | * | 76 | * |
| 77 | * @param connection The connection to delete from the tracking list. | 77 | * @param connection The connection to delete from the tracking list. |
| 78 | */ | 78 | */ |
| 79 | void delete_connection(usbmux_connection *connection) { | 79 | void delete_connection(iphone_umux_client_t connection) { |
| 80 | usbmux_connection **newlist = (usbmux_connection**)malloc(sizeof(usbmux_connection*) * (connections - 1)); | 80 | iphone_umux_client_t *newlist = (iphone_umux_client_t*)malloc(sizeof(iphone_umux_client_t) * (clients - 1)); |
| 81 | int i = 0, j = 0; | 81 | int i = 0, j = 0; |
| 82 | for (i = 0; i < connections; i++) { | 82 | for (i = 0; i < clients; i++) { |
| 83 | if (connlist[i] == connection) continue; | 83 | if (connlist[i] == connection) continue; |
| 84 | else { | 84 | else { |
| 85 | newlist[j] = connlist[i]; | 85 | newlist[j] = connlist[i]; |
| @@ -88,7 +88,7 @@ void delete_connection(usbmux_connection *connection) { | |||
| 88 | } | 88 | } |
| 89 | free(connlist); | 89 | free(connlist); |
| 90 | connlist = newlist; | 90 | connlist = newlist; |
| 91 | connections--; | 91 | clients--; |
| 92 | if (connection->recv_buffer) free(connection->recv_buffer); | 92 | if (connection->recv_buffer) free(connection->recv_buffer); |
| 93 | if (connection->header) free(connection->header); | 93 | if (connection->header) free(connection->header); |
| 94 | connection->r_len = 0; | 94 | connection->r_len = 0; |
| @@ -101,59 +101,64 @@ void delete_connection(usbmux_connection *connection) { | |||
| 101 | * @param connection The connection to add to the global list of connections. | 101 | * @param connection The connection to add to the global list of connections. |
| 102 | */ | 102 | */ |
| 103 | 103 | ||
| 104 | void add_connection(usbmux_connection *connection) { | 104 | void add_connection(iphone_umux_client_t connection) { |
| 105 | usbmux_connection **newlist = (usbmux_connection**)realloc(connlist, sizeof(usbmux_connection*) * (connections+1)); | 105 | iphone_umux_client_t* newlist = (iphone_umux_client_t*)realloc(connlist, sizeof(iphone_umux_client_t) * (clients+1)); |
| 106 | newlist[connections] = connection; | 106 | newlist[clients] = connection; |
| 107 | connlist = newlist; | 107 | connlist = newlist; |
| 108 | connections++; | 108 | clients++; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /** Initializes a connection on phone, with source port s_port and destination port d_port | 111 | /** Initializes a connection on phone, with source port s_port and destination port d_port |
| 112 | * | 112 | * |
| 113 | * @param phone The iPhone to initialize a connection on. | 113 | * @param device The iPhone to initialize a connection on. |
| 114 | * @param s_port The source port | 114 | * @param src_port The source port |
| 115 | * @param d_port The destination port -- 0xf27e for lockdownd. | 115 | * @param dst_port The destination port -- 0xf27e for lockdownd. |
| 116 | * | 116 | * @param client A mux TCP header for the connection which is used for tracking and data transfer. |
| 117 | * @return A mux TCP header for the connection which is used for tracking and data transfer. | 117 | * @return IPHONE_E_SUCCESS on success, an error code otherwise. |
| 118 | */ | 118 | */ |
| 119 | usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_port) { | 119 | int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ){ |
| 120 | if (!phone || !s_port || !d_port) return NULL; | 120 | if (!device || !src_port || !dst_port) |
| 121 | return IPHONE_E_INVALID_ARG; | ||
| 122 | |||
| 121 | int bytes = 0; | 123 | int bytes = 0; |
| 122 | // Initialize connection stuff | 124 | // Initialize connection stuff |
| 123 | usbmux_connection *new_connection = (usbmux_connection*)malloc(sizeof(usbmux_connection)); | 125 | iphone_umux_client_t new_connection = (iphone_umux_client_t)malloc(sizeof(struct iphone_umux_client_int)); |
| 124 | new_connection->header = new_mux_packet(s_port, d_port); | 126 | new_connection->header = new_mux_packet(src_port, dst_port); |
| 127 | |||
| 125 | // blargg | 128 | // blargg |
| 126 | if (new_connection && new_connection->header) { | 129 | if (new_connection && new_connection->header) { |
| 127 | new_connection->header->tcp_flags = 0x02; | 130 | new_connection->header->tcp_flags = 0x02; |
| 128 | new_connection->header->length = htonl(new_connection->header->length); | 131 | new_connection->header->length = htonl(new_connection->header->length); |
| 129 | new_connection->header->length16 = htons(new_connection->header->length16); | 132 | new_connection->header->length16 = htons(new_connection->header->length16); |
| 130 | 133 | ||
| 131 | if (send_to_phone(phone, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { | 134 | if (send_to_phone(device, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { |
| 132 | usbmux_tcp_header *response; | 135 | usbmux_tcp_header *response; |
| 133 | response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); | 136 | response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); |
| 134 | bytes = recv_from_phone(phone, (char*)response, sizeof(*response)); | 137 | bytes = recv_from_phone(device, (char*)response, sizeof(*response)); |
| 135 | if (response->tcp_flags != 0x12) { | 138 | if (response->tcp_flags != 0x12) { |
| 136 | free(response); | 139 | free(response); |
| 137 | return NULL; | 140 | return IPHONE_E_UNKNOWN_ERROR; |
| 138 | } else { | 141 | } else { |
| 139 | free(response); | 142 | free(response); |
| 143 | |||
| 140 | if (debug) printf("mux_connect: connection success\n"); | 144 | if (debug) printf("mux_connect: connection success\n"); |
| 141 | new_connection->header->tcp_flags = 0x10; | 145 | new_connection->header->tcp_flags = 0x10; |
| 142 | new_connection->header->scnt = 1; | 146 | new_connection->header->scnt = 1; |
| 143 | new_connection->header->ocnt = 1; | 147 | new_connection->header->ocnt = 1; |
| 144 | new_connection->phone = phone; | 148 | new_connection->phone = device; |
| 145 | new_connection->recv_buffer = NULL; | 149 | new_connection->recv_buffer = NULL; |
| 146 | new_connection->r_len = 0; | 150 | new_connection->r_len = 0; |
| 147 | add_connection(new_connection); | 151 | add_connection(new_connection); |
| 148 | return new_connection; | 152 | *client = new_connection; |
| 153 | return IPHONE_E_SUCCESS; | ||
| 149 | } | 154 | } |
| 150 | } else { | 155 | } else { |
| 151 | return NULL; | 156 | return IPHONE_E_NOT_ENOUGH_DATA; |
| 152 | } | 157 | } |
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | // if we get to this point it's probably bad | 160 | // if we get to this point it's probably bad |
| 156 | return NULL; | 161 | return IPHONE_E_UNKNOWN_ERROR; |
| 157 | } | 162 | } |
| 158 | 163 | ||
| 159 | /** Cleans up the given USBMux connection. | 164 | /** Cleans up the given USBMux connection. |
| @@ -161,56 +166,59 @@ usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_po | |||
| 161 | * | 166 | * |
| 162 | * @param connection The connection to close. | 167 | * @param connection The connection to close. |
| 163 | */ | 168 | */ |
| 164 | void mux_close_connection(usbmux_connection *connection) { | 169 | void iphone_mux_free_client ( iphone_umux_client_t client ) { |
| 165 | if (!connection || !connection->phone) return; | 170 | if (!client || !client->phone) return; |
| 166 | 171 | ||
| 167 | connection->header->tcp_flags = 0x04; | 172 | client->header->tcp_flags = 0x04; |
| 168 | connection->header->scnt = htonl(connection->header->scnt); | 173 | client->header->scnt = htonl(client->header->scnt); |
| 169 | connection->header->ocnt = htonl(connection->header->ocnt); | 174 | client->header->ocnt = htonl(client->header->ocnt); |
| 170 | int bytes = 0; | 175 | int bytes = 0; |
| 171 | 176 | ||
| 172 | bytes = usb_bulk_write(connection->phone->device, BULKOUT, (char*)connection->header, sizeof(usbmux_tcp_header), 800); | 177 | bytes = usb_bulk_write(client->phone->device, BULKOUT, (char*)client->header, sizeof(usbmux_tcp_header), 800); |
| 173 | if(debug && bytes < 0) | 178 | if(debug && bytes < 0) |
| 174 | printf("mux_close_connection(): when writing, libusb gave me the error: %s\n", usb_strerror()); | 179 | printf("mux_close_connection(): when writing, libusb gave me the error: %s\n", usb_strerror()); |
| 175 | 180 | ||
| 176 | bytes = usb_bulk_read(connection->phone->device, BULKIN, (char*)connection->header, sizeof(usbmux_tcp_header), 800); | 181 | bytes = usb_bulk_read(client->phone->device, BULKIN, (char*)client->header, sizeof(usbmux_tcp_header), 800); |
| 177 | if(debug && bytes < 0) | 182 | if(debug && bytes < 0) |
| 178 | printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); | 183 | printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); |
| 179 | 184 | ||
| 180 | delete_connection(connection); | 185 | delete_connection(client); |
| 181 | } | 186 | } |
| 182 | 187 | ||
| 188 | |||
| 183 | /** Sends the given data over the selected connection. | 189 | /** Sends the given data over the selected connection. |
| 184 | * | 190 | * |
| 185 | * @param connection The connection we're sending data on. | 191 | * @param phone The iPhone to send to. |
| 192 | * @param client The client we're sending data on. | ||
| 186 | * @param data A pointer to the data to send. | 193 | * @param data A pointer to the data to send. |
| 187 | * @param datalen How much data we're sending. | 194 | * @param datalen How much data we're sending. |
| 188 | * | 195 | * |
| 189 | * @return The number of bytes sent, minus the header (28), or -1 on error. | 196 | * @return The number of bytes sent, minus the header (28), or -1 on error. |
| 190 | */ | 197 | */ |
| 191 | int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) { | 198 | |
| 192 | if (!connection->phone || !connection || !data || datalen == 0) return -1; | 199 | int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen ) { |
| 193 | // connection->scnt and connection->ocnt should already be in host notation... | 200 | if (!client->phone || !client || !data || datalen == 0) return -1; |
| 201 | // client->scnt and client->ocnt should already be in host notation... | ||
| 194 | // we don't need to change them juuuust yet. | 202 | // we don't need to change them juuuust yet. |
| 195 | int bytes = 0; | 203 | int bytes = 0; |
| 196 | if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen); | 204 | if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen); |
| 197 | char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding | 205 | char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding |
| 198 | // Set the length and pre-emptively htonl/htons it | 206 | // Set the length and pre-emptively htonl/htons it |
| 199 | connection->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); | 207 | client->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); |
| 200 | connection->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); | 208 | client->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); |
| 201 | 209 | ||
| 202 | // Put scnt and ocnt into big-endian notation | 210 | // Put scnt and ocnt into big-endian notation |
| 203 | connection->header->scnt = htonl(connection->header->scnt); | 211 | client->header->scnt = htonl(client->header->scnt); |
| 204 | connection->header->ocnt = htonl(connection->header->ocnt); | 212 | client->header->ocnt = htonl(client->header->ocnt); |
| 205 | // Concatenation of stuff in the buffer. | 213 | // Concatenation of stuff in the buffer. |
| 206 | memcpy(buffer, connection->header, sizeof(usbmux_tcp_header)); | 214 | memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); |
| 207 | memcpy(buffer+sizeof(usbmux_tcp_header), data, datalen); | 215 | memcpy(buffer+sizeof(usbmux_tcp_header), data, datalen); |
| 208 | 216 | ||
| 209 | // We have a buffer full of data, we should now send it to the phone. | 217 | // We have a buffer full of data, we should now send it to the phone. |
| 210 | if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer); | 218 | if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer); |
| 211 | 219 | ||
| 212 | 220 | ||
| 213 | bytes = send_to_phone(connection->phone, buffer, sizeof(usbmux_tcp_header)+datalen); | 221 | bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header)+datalen); |
| 214 | if (debug) printf("mux_send: sent %i bytes!\n", bytes); | 222 | if (debug) printf("mux_send: sent %i bytes!\n", bytes); |
| 215 | // Now that we've sent it off, we can clean up after our sloppy selves. | 223 | // Now that we've sent it off, we can clean up after our sloppy selves. |
| 216 | if (debug) { | 224 | if (debug) { |
| @@ -222,12 +230,12 @@ int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) { | |||
| 222 | 230 | ||
| 223 | if (buffer) free(buffer); | 231 | if (buffer) free(buffer); |
| 224 | // Re-calculate scnt and ocnt | 232 | // Re-calculate scnt and ocnt |
| 225 | connection->header->scnt = ntohl(connection->header->scnt) + datalen; | 233 | client->header->scnt = ntohl(client->header->scnt) + datalen; |
| 226 | connection->header->ocnt = ntohl(connection->header->ocnt); | 234 | client->header->ocnt = ntohl(client->header->ocnt); |
| 227 | 235 | ||
| 228 | // Revert lengths | 236 | // Revert lengths |
| 229 | connection->header->length = ntohl(connection->header->length); | 237 | client->header->length = ntohl(client->header->length); |
| 230 | connection->header->length16 = ntohs(connection->header->length16); | 238 | client->header->length16 = ntohs(client->header->length16); |
| 231 | 239 | ||
| 232 | // Now return the bytes. | 240 | // Now return the bytes. |
| 233 | if (bytes < sizeof(usbmux_tcp_header)+datalen) { | 241 | if (bytes < sizeof(usbmux_tcp_header)+datalen) { |
| @@ -247,52 +255,52 @@ int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) { | |||
| 247 | * | 255 | * |
| 248 | * @return How many bytes were read, or -1 if something bad happens. | 256 | * @return How many bytes were read, or -1 if something bad happens. |
| 249 | */ | 257 | */ |
| 250 | int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { | 258 | int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ) { |
| 251 | /* | 259 | /* |
| 252 | * Order of operation: | 260 | * Order of operation: |
| 253 | * 1.) Check if the connection has a pre-received buffer. | 261 | * 1.) Check if the client has a pre-received buffer. |
| 254 | * 2.) If so, fill data with the buffer, as much as needed. | 262 | * 2.) If so, fill data with the buffer, as much as needed. |
| 255 | * a.) Return quickly if the buffer has enough | 263 | * a.) Return quickly if the buffer has enough |
| 256 | * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) | 264 | * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) |
| 257 | * 3.) If not, receive directly from the phone. | 265 | * 3.) If not, receive directly from the phone. |
| 258 | * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. | 266 | * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. |
| 259 | * b.) If not, find the connection the ports belong to and fill that connection's buffer, then return mux_recv with the same args to try again. | 267 | * b.) If not, find the client the ports belong to and fill that client's buffer, then return mux_recv with the same args to try again. |
| 260 | */ | 268 | */ |
| 261 | if (debug) printf("mux_recv: datalen == %i\n", datalen); | 269 | if (debug) printf("mux_recv: datalen == %i\n", datalen); |
| 262 | int bytes = 0, i = 0, complex = 0, offset = 0; | 270 | int bytes = 0, i = 0, complex = 0, offset = 0; |
| 263 | char *buffer = NULL; | 271 | char *buffer = NULL; |
| 264 | usbmux_tcp_header *header = NULL; | 272 | usbmux_tcp_header *header = NULL; |
| 265 | 273 | ||
| 266 | if (connection->recv_buffer) { | 274 | if (client->recv_buffer) { |
| 267 | if (connection->r_len >= datalen) { | 275 | if (client->r_len >= datalen) { |
| 268 | memcpy(data, connection->recv_buffer, datalen); | 276 | memcpy(data, client->recv_buffer, datalen); |
| 269 | if (connection->r_len == datalen) { | 277 | if (client->r_len == datalen) { |
| 270 | // reset everything | 278 | // reset everything |
| 271 | free(connection->recv_buffer); | 279 | free(client->recv_buffer); |
| 272 | connection->r_len = 0; | 280 | client->r_len = 0; |
| 273 | connection->recv_buffer = NULL; | 281 | client->recv_buffer = NULL; |
| 274 | } else { | 282 | } else { |
| 275 | buffer = (char*)malloc(sizeof(char) * (connection->r_len - datalen)); | 283 | buffer = (char*)malloc(sizeof(char) * (client->r_len - datalen)); |
| 276 | memcpy(buffer, connection->recv_buffer+datalen, (connection->r_len - datalen)); | 284 | memcpy(buffer, client->recv_buffer+datalen, (client->r_len - datalen)); |
| 277 | connection->r_len -= datalen; | 285 | client->r_len -= datalen; |
| 278 | free(connection->recv_buffer); | 286 | free(client->recv_buffer); |
| 279 | connection->recv_buffer = buffer; | 287 | client->recv_buffer = buffer; |
| 280 | } | 288 | } |
| 281 | 289 | ||
| 282 | // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. | 290 | // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. |
| 283 | return datalen; | 291 | return datalen; |
| 284 | } else { | 292 | } else { |
| 285 | memcpy(data, connection->recv_buffer, connection->r_len); | 293 | memcpy(data, client->recv_buffer, client->r_len); |
| 286 | free(connection->recv_buffer); // don't need to deal with anymore, but... | 294 | free(client->recv_buffer); // don't need to deal with anymore, but... |
| 287 | offset = connection->r_len; // see #2b, above | 295 | offset = client->r_len; // see #2b, above |
| 288 | connection->r_len = 0; | 296 | client->r_len = 0; |
| 289 | } | 297 | } |
| 290 | } // End of what to do if we have a pre-buffer. See #1 and #2 above. | 298 | } // End of what to do if we have a pre-buffer. See #1 and #2 above. |
| 291 | 299 | ||
| 292 | buffer = (char*)malloc(sizeof(char) * 131072); // make sure we get enough ;) | 300 | buffer = (char*)malloc(sizeof(char) * 131072); // make sure we get enough ;) |
| 293 | 301 | ||
| 294 | // See #3. | 302 | // See #3. |
| 295 | bytes = recv_from_phone(connection->phone, buffer, 131072); | 303 | bytes = recv_from_phone(client->phone, buffer, 131072); |
| 296 | if (bytes < 28) { | 304 | if (bytes < 28) { |
| 297 | free(buffer); | 305 | free(buffer); |
| 298 | if (debug) printf("mux_recv: Did not even get the header.\n"); | 306 | if (debug) printf("mux_recv: Did not even get the header.\n"); |
| @@ -300,10 +308,10 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { | |||
| 300 | } | 308 | } |
| 301 | 309 | ||
| 302 | header = (usbmux_tcp_header*)buffer; | 310 | header = (usbmux_tcp_header*)buffer; |
| 303 | if (header->sport != connection->header->dport || header->dport != connection->header->sport) { | 311 | if (header->sport != client->header->dport || header->dport != client->header->sport) { |
| 304 | // Ooooops -- we got someone else's packet. | 312 | // Ooooops -- we got someone else's packet. |
| 305 | // We gotta stick it in their buffer. (Take that any old way you want ;) ) | 313 | // We gotta stick it in their buffer. (Take that any old way you want ;) ) |
| 306 | for (i = 0; i < connections; i++) { | 314 | for (i = 0; i < clients; i++) { |
| 307 | if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { | 315 | if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { |
| 308 | // we have a winner. | 316 | // we have a winner. |
| 309 | char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); | 317 | char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); |
| @@ -312,7 +320,7 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { | |||
| 312 | free(connlist[i]->recv_buffer); | 320 | free(connlist[i]->recv_buffer); |
| 313 | } | 321 | } |
| 314 | connlist[i]->r_len += bytes - 28; | 322 | connlist[i]->r_len += bytes - 28; |
| 315 | //connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer | 323 | //connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * client->r_len); // grow their buffer |
| 316 | connlist[i]->recv_buffer = nfb; | 324 | connlist[i]->recv_buffer = nfb; |
| 317 | nfb = NULL; // A cookie for you if you can guess what "nfb" means. | 325 | nfb = NULL; // A cookie for you if you can guess what "nfb" means. |
| 318 | complex = connlist[i]->r_len - (bytes - 28); | 326 | complex = connlist[i]->r_len - (bytes - 28); |
| @@ -324,7 +332,7 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { | |||
| 324 | // Free our buffer and continue. | 332 | // Free our buffer and continue. |
| 325 | free(buffer); | 333 | free(buffer); |
| 326 | buffer = NULL; | 334 | buffer = NULL; |
| 327 | return mux_recv(connection, data, datalen); // recurse back in to try again | 335 | return mux_recv(client, data, datalen); // recurse back in to try again |
| 328 | } | 336 | } |
| 329 | 337 | ||
| 330 | // The packet was absolutely meant for us if it hits this point. | 338 | // The packet was absolutely meant for us if it hits this point. |
| @@ -333,18 +341,18 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { | |||
| 333 | if ((bytes-28) > datalen) { | 341 | if ((bytes-28) > datalen) { |
| 334 | // Copy what we need into the data, buffer the rest because we can. | 342 | // Copy what we need into the data, buffer the rest because we can. |
| 335 | memcpy(data+offset, buffer+28, datalen); // data+offset: see #2b, above | 343 | memcpy(data+offset, buffer+28, datalen); // data+offset: see #2b, above |
| 336 | complex = connection->r_len + (bytes-28) - datalen; | 344 | complex = client->r_len + (bytes-28) - datalen; |
| 337 | connection->recv_buffer = (char*)realloc(connection->recv_buffer, (sizeof(char) * complex)); | 345 | client->recv_buffer = (char*)realloc(client->recv_buffer, (sizeof(char) * complex)); |
| 338 | connection->r_len = complex; | 346 | client->r_len = complex; |
| 339 | complex = connection->r_len - (bytes-28) - datalen; | 347 | complex = client->r_len - (bytes-28) - datalen; |
| 340 | memcpy(connection->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen); | 348 | memcpy(client->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen); |
| 341 | free(buffer); | 349 | free(buffer); |
| 342 | connection->header->ocnt += bytes-28; | 350 | client->header->ocnt += bytes-28; |
| 343 | return datalen; | 351 | return datalen; |
| 344 | } else { | 352 | } else { |
| 345 | // Fill the data with what we have, and just return. | 353 | // Fill the data with what we have, and just return. |
| 346 | memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above | 354 | memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above |
| 347 | connection->header->ocnt += bytes-28; | 355 | client->header->ocnt += bytes-28; |
| 348 | free(buffer); | 356 | free(buffer); |
| 349 | return (bytes-28); | 357 | return (bytes-28); |
| 350 | } | 358 | } |
diff --git a/src/usbmux.h b/src/usbmux.h index 831f0fd..da8a361 100644 --- a/src/usbmux.h +++ b/src/usbmux.h | |||
| @@ -43,12 +43,12 @@ typedef struct { | |||
| 43 | uint16 window, nullnull, length16; | 43 | uint16 window, nullnull, length16; |
| 44 | } usbmux_tcp_header; | 44 | } usbmux_tcp_header; |
| 45 | 45 | ||
| 46 | typedef struct { | 46 | struct iphone_umux_client_int { |
| 47 | usbmux_tcp_header *header; | 47 | usbmux_tcp_header *header; |
| 48 | iphone_device_t phone; | 48 | iphone_device_t phone; |
| 49 | char *recv_buffer; | 49 | char *recv_buffer; |
| 50 | int r_len; | 50 | int r_len; |
| 51 | } usbmux_connection; | 51 | }; |
| 52 | 52 | ||
| 53 | usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); | 53 | usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); |
| 54 | 54 | ||
| @@ -58,10 +58,5 @@ typedef struct { | |||
| 58 | 58 | ||
| 59 | usbmux_version_header *version_header(); | 59 | usbmux_version_header *version_header(); |
| 60 | 60 | ||
| 61 | usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_port); | ||
| 62 | void mux_close_connection(usbmux_connection *connection); | ||
| 63 | int mux_send(usbmux_connection *connection, const char *data, uint32 datalen); | ||
| 64 | int mux_recv(usbmux_connection *connection, char *data, uint32 datalen); | ||
| 65 | |||
| 66 | 61 | ||
| 67 | #endif | 62 | #endif |
