Commit 86f61988 authored by Jonathan Beck's avatar Jonathan Beck

make all functions return an error code.

parent dc89741f
...@@ -46,6 +46,8 @@ extern "C" { ...@@ -46,6 +46,8 @@ extern "C" {
//afc specific error //afc specific error
#define IPHONE_E_NO_SUCH_FILE -10 #define IPHONE_E_NO_SUCH_FILE -10
typedef short iphone_error_t;
enum { enum {
AFC_FILE_READ = 0x00000002, // seems to be able to read and write files AFC_FILE_READ = 0x00000002, // seems to be able to read and write files
AFC_FILE_WRITE = 0x00000003, // writes and creates a file, blanks it out, etc. AFC_FILE_WRITE = 0x00000003, // writes and creates a file, blanks it out, etc.
...@@ -73,44 +75,44 @@ struct iphone_afc_file_int; ...@@ -73,44 +75,44 @@ struct iphone_afc_file_int;
typedef struct iphone_afc_file_int *iphone_afc_file_t; typedef struct iphone_afc_file_int *iphone_afc_file_t;
//device related functions //device related functions
int iphone_get_device ( iphone_device_t *device ); iphone_error_t iphone_get_device ( iphone_device_t *device );
void iphone_free_device ( iphone_device_t device ); iphone_error_t iphone_free_device ( iphone_device_t device );
//lockdownd related functions //lockdownd related functions
int iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client ); iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client );
void iphone_lckd_free_client( iphone_lckd_client_t client ); iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client );
int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ); iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port );
int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ); iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes );
int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length ); iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *recv_bytes );
//usbmux related functions //usbmux related functions
int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ); iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client );
void iphone_mux_free_client ( iphone_umux_client_t client ); iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client );
int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen ); iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes );
int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ); iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes );
//afc related functions //afc related functions
int iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client ); iphone_error_t iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_afc_client_t *client );
void iphone_afc_free_client ( iphone_afc_client_t client ); iphone_error_t iphone_afc_free_client ( iphone_afc_client_t client );
char **iphone_afc_get_devinfo ( iphone_afc_client_t client ); iphone_error_t iphone_afc_get_devinfo ( iphone_afc_client_t client, char ***infos );
char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir); iphone_error_t iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir, char ***list);
int iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf ); iphone_error_t iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf );
int iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, uint32_t file_mode, iphone_afc_file_t *file ); iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, uint32_t file_mode, iphone_afc_file_t *file );
void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file); iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file);
int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length); iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t *bytes);
int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length); iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length, uint32_t *bytes);
int iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos); iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos);
int iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize); iphone_error_t iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize);
int iphone_afc_delete_file ( iphone_afc_client_t client, const char *path); iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path);
int iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to); iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to);
int iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir);
#ifdef __cplusplus #ifdef __cplusplus
......
This diff is collapsed.
...@@ -34,7 +34,7 @@ extern int debug; ...@@ -34,7 +34,7 @@ extern int debug;
* @return A structure with data on the first iPhone it finds. (Or NULL, on * @return A structure with data on the first iPhone it finds. (Or NULL, on
* error) * error)
*/ */
int iphone_get_device ( iphone_device_t *device ){ iphone_error_t iphone_get_device ( iphone_device_t *device ){
//check we can actually write in device //check we can actually write in device
if (!device || (device && *device)) if (!device || (device && *device))
return IPHONE_E_INVALID_ARG; return IPHONE_E_INVALID_ARG;
...@@ -134,14 +134,21 @@ int iphone_get_device ( iphone_device_t *device ){ ...@@ -134,14 +134,21 @@ int iphone_get_device ( iphone_device_t *device ){
* *
* @param phone A pointer to an iPhone structure. * @param phone A pointer to an iPhone structure.
*/ */
void iphone_free_device ( iphone_device_t device ) { iphone_error_t iphone_free_device ( iphone_device_t device ) {
if (device->buffer) free(device->buffer); if (!device) return IPHONE_E_INVALID_ARG;
iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
if (device->buffer) {
free(device->buffer);
if (device->device) { if (device->device) {
usb_release_interface(device->device, 1); usb_release_interface(device->device, 1);
usb_reset(device->device); usb_reset(device->device);
usb_close(device->device); usb_close(device->device);
ret = IPHONE_E_SUCCESS;
} }
free(device); free(device);
}
return ret;
} }
/** Sends data to the phone /** Sends data to the phone
......
...@@ -94,15 +94,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) { ...@@ -94,15 +94,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) {
* *
* @param control The lockdown client * @param control The lockdown client
*/ */
void iphone_lckd_free_client( iphone_lckd_client_t client ) { iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ) {
if (!client) return; if (!client) return IPHONE_E_INVALID_ARG;
iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
if (client->connection) { if (client->connection) {
iphone_mux_free_client(client->connection); ret = iphone_mux_free_client(client->connection);
} }
if (client->ssl_session) gnutls_deinit(*client->ssl_session); if (client->ssl_session) gnutls_deinit(*client->ssl_session);
free(client->ssl_session); free(client->ssl_session);
free(client); free(client);
return ret;
} }
/** Polls the iPhone for lockdownd data. /** Polls the iPhone for lockdownd data.
...@@ -113,20 +116,28 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) { ...@@ -113,20 +116,28 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) {
* *
* @return The number of bytes received * @return The number of bytes received
*/ */
int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) { iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ) {
if (!client) return 0; if (!client || dump_data || !recv_bytes) return IPHONE_E_INVALID_ARG;
iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
char *receive; char *receive;
uint32 datalen = 0, bytes = 0; uint32 datalen = 0, bytes = 0;
if (!client->in_SSL) bytes = iphone_mux_recv(client->connection, (char *)&datalen, sizeof(datalen)); if (!client->in_SSL) ret = iphone_mux_recv(client->connection, (char *)&datalen, sizeof(datalen), &bytes);
else bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); else {
bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen));
if (bytes > 0) ret = IPHONE_E_SUCCESS;
}
datalen = ntohl(datalen); datalen = ntohl(datalen);
receive = (char*)malloc(sizeof(char) * datalen); receive = (char*)malloc(sizeof(char) * datalen);
if (!client->in_SSL) bytes = iphone_mux_recv(client->connection, receive, datalen); if (!client->in_SSL) ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
else bytes = gnutls_record_recv(*client->ssl_session, receive, datalen); else {
bytes = gnutls_record_recv(*client->ssl_session, receive, datalen);
if (bytes > 0) ret = IPHONE_E_SUCCESS;
}
*dump_data = receive; *dump_data = receive;
return bytes; *recv_bytes = bytes;
return ret;
} }
/** Sends lockdownd data to the iPhone /** Sends lockdownd data to the iPhone
...@@ -140,10 +151,11 @@ int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) { ...@@ -140,10 +151,11 @@ int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) {
* *
* @return The number of bytes sent * @return The number of bytes sent
*/ */
int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length ) { iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *sent_bytes ) {
if (!client) return 0; if (!client || !raw_data || length == 0 || !sent_bytes) return IPHONE_E_INVALID_ARG;
char *real_query; char *real_query;
int bytes; int bytes;
iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
real_query = (char*)malloc(sizeof(char) * (length+4)); real_query = (char*)malloc(sizeof(char) * (length+4));
length = htonl(length); length = htonl(length);
...@@ -157,11 +169,15 @@ int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t len ...@@ -157,11 +169,15 @@ int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t len
packet = NULL; packet = NULL;
} }
if (!client->in_SSL) bytes = iphone_mux_send(client->connection, real_query, ntohl(length)+sizeof(length)); if (!client->in_SSL) ret = iphone_mux_send(client->connection, real_query, ntohl(length)+sizeof(length), &bytes);
else gnutls_record_send(*client->ssl_session, real_query, ntohl(length)+sizeof(length)); else {
gnutls_record_send(*client->ssl_session, real_query, ntohl(length)+sizeof(length));
ret = IPHONE_E_SUCCESS;
}
if (debug) printf("lockdownd_send(): sent it!\n"); if (debug) printf("lockdownd_send(): sent it!\n");
free(real_query); free(real_query);
return bytes; *sent_bytes = bytes;
return ret;
} }
/** Initiates the handshake for the lockdown session. Part of the lockdownd handshake. /** Initiates the handshake for the lockdown session. Part of the lockdownd handshake.
...@@ -307,11 +323,11 @@ int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_ ...@@ -307,11 +323,11 @@ int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_
* *
* @return 1 on success and 0 on failure * @return 1 on success and 0 on failure
*/ */
int iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client ) iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client )
{ {
if (!device || !client || (client && *client) ) if (!device || !client || (client && *client) )
return IPHONE_E_INVALID_ARG; return IPHONE_E_INVALID_ARG;
int ret = IPHONE_E_SUCCESS; iphone_error_t ret = IPHONE_E_SUCCESS;
char *host_id = NULL; char *host_id = NULL;
iphone_lckd_client_t client_loc = new_lockdownd_client( device ); iphone_lckd_client_t client_loc = new_lockdownd_client( device );
...@@ -815,14 +831,15 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ ...@@ -815,14 +831,15 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
* *
* @return The port number the service was started on or 0 on failure. * @return The port number the service was started on or 0 on failure.
*/ */
int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ) { iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port ) {
if (!client) return 0; if (!client || !service || !port) return IPHONE_E_INVALID_ARG;
char* host_id = get_host_id(); char* host_id = get_host_id();
if (host_id && !client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return 0; if (!host_id) return IPHONE_E_INVALID_CONF;
if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR;
char *XML_query, **dictionary; char *XML_query, **dictionary;
uint32 length, i = 0, port = 0; uint32 length, i = 0, port_loc = 0;
uint8 result = 0; uint8 result = 0;
free(host_id); free(host_id);
...@@ -832,9 +849,9 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ...@@ -832,9 +849,9 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
xmlNode *key; xmlNode *key;
key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1);
if (!key) { xmlFreeDoc(plist); return 0; } if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; }
key = add_key_str_dict_element(plist, dict, "Service", service, 1); key = add_key_str_dict_element(plist, dict, "Service", service, 1);
if (!key) { xmlFreeDoc(plist); return 0; } if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; }
xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length); xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length);
...@@ -845,24 +862,24 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ...@@ -845,24 +862,24 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
xmlFreeDoc(plist); xmlFreeDoc(plist);
if (length <= 0) return 0; if (length <= 0) return IPHONE_E_NOT_ENOUGH_DATA;
else { else {
plist = xmlReadMemory(XML_query, length, NULL, NULL, 0); plist = xmlReadMemory(XML_query, length, NULL, NULL, 0);
if (!plist) return 0; if (!plist) return IPHONE_E_UNKNOWN_ERROR;
dict = xmlDocGetRootElement(plist); dict = xmlDocGetRootElement(plist);
if (!dict) return 0; if (!dict) return IPHONE_E_UNKNOWN_ERROR;
for (dict = dict->children; dict; dict = dict->next) { for (dict = dict->children; dict; dict = dict->next) {
if (!xmlStrcmp(dict->name, "dict")) break; if (!xmlStrcmp(dict->name, "dict")) break;
} }
if (!dict) return 0; if (!dict) return IPHONE_E_UNKNOWN_ERROR;
dictionary = read_dict_element_strings(dict); dictionary = read_dict_element_strings(dict);
for (i = 0; dictionary[i]; i+=2) { for (i = 0; dictionary[i]; i+=2) {
if (debug) printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i+1]); if (debug) printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i+1]);
if (!xmlStrcmp(dictionary[i], "Port")) { if (!xmlStrcmp(dictionary[i], "Port")) {
port = atoi(dictionary[i+1]); port_loc = atoi(dictionary[i+1]);
if (debug) printf("lockdownd_start_service() atoi'd port: %i\n", port); if (debug) printf("lockdownd_start_service() atoi'd port: %i\n", port);
} }
...@@ -882,9 +899,12 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ...@@ -882,9 +899,12 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
free(XML_query); free(XML_query);
xmlFreeDoc(plist); xmlFreeDoc(plist);
free_dictionary(dictionary); free_dictionary(dictionary);
if (port && result) return port; if (port && result) {
else return 0; *port = port_loc;
return IPHONE_E_SUCCESS;
}
else return IPHONE_E_UNKNOWN_ERROR;
} }
return 0; return IPHONE_E_UNKNOWN_ERROR;
} }
...@@ -116,7 +116,7 @@ void add_connection(iphone_umux_client_t connection) { ...@@ -116,7 +116,7 @@ void add_connection(iphone_umux_client_t connection) {
* @param client A mux TCP header for the connection which is used for tracking and data transfer. * @param client A mux TCP header for the connection which is used for tracking and data transfer.
* @return IPHONE_E_SUCCESS on success, an error code otherwise. * @return IPHONE_E_SUCCESS on success, an error code otherwise.
*/ */
int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ){ iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ){
if (!device || !src_port || !dst_port) if (!device || !src_port || !dst_port)
return IPHONE_E_INVALID_ARG; return IPHONE_E_INVALID_ARG;
...@@ -165,8 +165,10 @@ int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t ...@@ -165,8 +165,10 @@ int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t
* @note Once a connection is closed it may not be used again. * @note Once a connection is closed it may not be used again.
* *
* @param connection The connection to close. * @param connection The connection to close.
*
* @return IPHONE_E_SUCCESS on success.
*/ */
void iphone_mux_free_client ( iphone_umux_client_t client ) { iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client ) {
if (!client || !client->phone) return; if (!client || !client->phone) return;
client->header->tcp_flags = 0x04; client->header->tcp_flags = 0x04;
...@@ -183,6 +185,8 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) { ...@@ -183,6 +185,8 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror());
delete_connection(client); delete_connection(client);
return IPHONE_E_SUCCESS;
} }
...@@ -192,15 +196,16 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) { ...@@ -192,15 +196,16 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
* @param client The client we're sending data on. * @param client The client we're sending data on.
* @param data A pointer to the data to send. * @param data A pointer to the data to send.
* @param datalen How much data we're sending. * @param datalen How much data we're sending.
* @param sent_bytes The number of bytes sent, minus the header (28)
* *
* @return The number of bytes sent, minus the header (28), or -1 on error. * @return IPHONE_E_SUCCESS on success.
*/ */
int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen ) { iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes ) {
if (!client->phone || !client || !data || datalen == 0) return -1; if (!client->phone || !client || !data || datalen == 0 || !sent_bytes) return IPHONE_E_INVALID_ARG;
// client->scnt and client->ocnt should already be in host notation... // client->scnt and client->ocnt should already be in host notation...
// we don't need to change them juuuust yet. // we don't need to change them juuuust yet.
int bytes = 0; *sent_bytes = 0;
if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen); if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen);
char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding
// Set the length and pre-emptively htonl/htons it // Set the length and pre-emptively htonl/htons it
...@@ -218,12 +223,12 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da ...@@ -218,12 +223,12 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer); if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer);
bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header)+datalen); *sent_bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header)+datalen);
if (debug) printf("mux_send: sent %i bytes!\n", bytes); if (debug) printf("mux_send: sent %i bytes!\n", *sent_bytes);
// Now that we've sent it off, we can clean up after our sloppy selves. // Now that we've sent it off, we can clean up after our sloppy selves.
if (debug) { if (debug) {
FILE *packet = fopen("packet", "a+"); FILE *packet = fopen("packet", "a+");
fwrite(buffer, 1, bytes, packet); fwrite(buffer, 1, *sent_bytes, packet);
fclose(packet); fclose(packet);
printf("\n"); printf("\n");
} }
...@@ -238,13 +243,14 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da ...@@ -238,13 +243,14 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
client->header->length16 = ntohs(client->header->length16); client->header->length16 = ntohs(client->header->length16);
// Now return the bytes. // Now return the bytes.
if (bytes < sizeof(usbmux_tcp_header)+datalen) { if (*sent_bytes < sizeof(usbmux_tcp_header)+datalen) {
return -1; // blah *sent_bytes = 0;
return IPHONE_E_NOT_ENOUGH_DATA;
} else { } else {
return bytes - 28; // actual length sent. :/ *sent_bytes = *sent_bytes - 28; // actual length sent. :/
} }
return bytes; // or something return IPHONE_E_UNKNOWN_ERROR;
} }
/** This is a higher-level USBMuxTCP-like function /** This is a higher-level USBMuxTCP-like function
...@@ -255,7 +261,10 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da ...@@ -255,7 +261,10 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
* *
* @return How many bytes were read, or -1 if something bad happens. * @return How many bytes were read, or -1 if something bad happens.
*/ */
int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ) { iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes ) {
if (!client || !data || datalen == 0 || !recv_bytes)
return IPHONE_E_INVALID_ARG;
/* /*
* Order of operation: * Order of operation:
* 1.) Check if the client has a pre-received buffer. * 1.) Check if the client has a pre-received buffer.
...@@ -268,6 +277,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ...@@ -268,6 +277,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
*/ */
if (debug) printf("mux_recv: datalen == %i\n", datalen); if (debug) printf("mux_recv: datalen == %i\n", datalen);
int bytes = 0, i = 0, complex = 0, offset = 0; int bytes = 0, i = 0, complex = 0, offset = 0;
*recv_bytes = 0;
char *buffer = NULL; char *buffer = NULL;
usbmux_tcp_header *header = NULL; usbmux_tcp_header *header = NULL;
...@@ -304,7 +314,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ...@@ -304,7 +314,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
if (bytes < 28) { if (bytes < 28) {
free(buffer); free(buffer);
if (debug) printf("mux_recv: Did not even get the header.\n"); if (debug) printf("mux_recv: Did not even get the header.\n");
return -1; return IPHONE_E_NOT_ENOUGH_DATA;
} }
header = (usbmux_tcp_header*)buffer; header = (usbmux_tcp_header*)buffer;
...@@ -332,7 +342,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ...@@ -332,7 +342,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
// Free our buffer and continue. // Free our buffer and continue.
free(buffer); free(buffer);
buffer = NULL; buffer = NULL;
return iphone_mux_recv(client, data, datalen); // recurse back in to try again return iphone_mux_recv(client, data, datalen, recv_bytes); // recurse back in to try again
} }
// The packet was absolutely meant for us if it hits this point. // The packet was absolutely meant for us if it hits this point.
...@@ -348,13 +358,15 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ...@@ -348,13 +358,15 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
memcpy(client->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen); memcpy(client->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen);
free(buffer); free(buffer);
client->header->ocnt += bytes-28; client->header->ocnt += bytes-28;
return datalen; *recv_bytes = datalen;
return IPHONE_E_SUCCESS;
} else { } else {
// Fill the data with what we have, and just return. // Fill the data with what we have, and just return.
memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above
client->header->ocnt += bytes-28; client->header->ocnt += bytes-28;
free(buffer); free(buffer);
return (bytes-28); *recv_bytes = bytes - 28;
return IPHONE_E_SUCCESS;
} }
// If we get to this point, 'tis probably bad. // If we get to this point, 'tis probably bad.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment