summaryrefslogtreecommitdiffstats
path: root/iphone.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-02-25 18:09:19 +0100
committerGravatar Nikias Bassen2009-02-25 18:09:19 +0100
commit6e2946da89ce8c44ac2b78e49c8fc934974d021d (patch)
tree33c63b8b7a008695df606190195b9baf4a59f350 /iphone.c
parent97e6c8b7bb89c7f08ad46050598c15a55ea3f436 (diff)
downloadusbmuxd-6e2946da89ce8c44ac2b78e49c8fc934974d021d.tar.gz
usbmuxd-6e2946da89ce8c44ac2b78e49c8fc934974d021d.tar.bz2
big endian fix and some improvements, now multi-client capable
Diffstat (limited to 'iphone.c')
-rw-r--r--iphone.c162
1 files changed, 133 insertions, 29 deletions
diff --git a/iphone.c b/iphone.c
index 9035be9..bf0d5de 100644
--- a/iphone.c
+++ b/iphone.c
@@ -132,6 +132,61 @@ void log_debug_msg(const char *format, ...)
132#endif 132#endif
133} 133}
134 134
135#ifdef DEBUG
136/**
137 * for debugging purposes.
138 */
139static void print_buffer(const char *data, const int length)
140{
141 int i;
142 int j;
143 unsigned char c;
144
145 for(i=0; i<length; i+=16) {
146 printf("%04x: ", i);
147 for (j=0;j<16;j++) {
148 if (i+j >= length) {
149 printf(" ");
150 continue;
151 }
152 printf("%02hhx ", *(data+i+j));
153 }
154 printf(" | ");
155 for(j=0;j<16;j++) {
156 if (i+j >= length)
157 break;
158 c = *(data+i+j);
159 if ((c < 32) || (c > 127)) {
160 printf(".");
161 continue;
162 }
163 printf("%c", c);
164 }
165 printf("\n");
166 }
167 printf("\n");
168}
169#endif
170
171void hton_header(usbmux_tcp_header *hdr)
172{
173 if (hdr) {
174 hdr->length = htonl(hdr->length);
175 hdr->scnt = htonl(hdr->scnt);
176 hdr->ocnt = htonl(hdr->ocnt);
177 hdr->length16 = htons(hdr->length16);
178 }
179}
180
181void ntoh_header(usbmux_tcp_header *hdr)
182{
183 if (hdr) {
184 hdr->length = ntohl(hdr->length);
185 hdr->scnt = ntohl(hdr->scnt);
186 hdr->ocnt = ntohl(hdr->ocnt);
187 hdr->length16 = ntohs(hdr->length16);
188 }
189}
135 190
136/** Creates a USBMux header containing version information 191/** Creates a USBMux header containing version information
137 * 192 *
@@ -392,6 +447,12 @@ int send_to_phone(iphone_device_t phone, char *data, int datalen)
392 int timeout = 1000; 447 int timeout = 1000;
393 int retrycount = 0; 448 int retrycount = 0;
394 int bytes = 0; 449 int bytes = 0;
450
451#ifdef DEBUG
452 printf("===============================\n%s: trying to send\n", __func__);
453 print_buffer(data, datalen);
454 printf("===============================\n");
455#endif
395 do { 456 do {
396 if (retrycount > 3) { 457 if (retrycount > 3) {
397 fprintf(stderr, "EPIC FAIL! aborting on retry count overload.\n"); 458 fprintf(stderr, "EPIC FAIL! aborting on retry count overload.\n");
@@ -426,6 +487,14 @@ int send_to_phone(iphone_device_t phone, char *data, int datalen)
426 } 487 }
427 while(0); // fall out 488 while(0); // fall out
428 489
490#ifdef DEBUG
491 if (bytes > 0) {
492 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
493 printf("%s: sent to phone\n", __func__);
494 print_buffer(data, bytes);
495 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
496 }
497#endif
429 return bytes; 498 return bytes;
430} 499}
431 500
@@ -459,6 +528,15 @@ int recv_from_phone_timeout(iphone_device_t phone, char *data, int datalen, int
459 return -1; 528 return -1;
460 } 529 }
461 530
531#ifdef DEBUG
532 if (bytes > 0) {
533 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
534 printf("%s: received from phone:\n", __func__);
535 print_buffer(data, bytes);
536 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
537 }
538#endif
539
462 return bytes; 540 return bytes;
463} 541}
464 542
@@ -621,8 +699,8 @@ iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port,
621 // send TCP syn 699 // send TCP syn
622 if (new_connection && new_connection->header) { 700 if (new_connection && new_connection->header) {
623 new_connection->header->tcp_flags = TCP_SYN; 701 new_connection->header->tcp_flags = TCP_SYN;
624 new_connection->header->length = htonl(new_connection->header->length); 702 new_connection->header->length = new_connection->header->length;
625 new_connection->header->length16 = htons(new_connection->header->length16); 703 new_connection->header->length16 = new_connection->header->length16;
626 new_connection->header->scnt = 0; 704 new_connection->header->scnt = 0;
627 new_connection->header->ocnt = 0; 705 new_connection->header->ocnt = 0;
628 new_connection->phone = device; 706 new_connection->phone = device;
@@ -635,6 +713,8 @@ iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port,
635 new_connection->wr_window = 0; 713 new_connection->wr_window = 0;
636 add_connection(new_connection); 714 add_connection(new_connection);
637 new_connection->error = IPHONE_E_SUCCESS; 715 new_connection->error = IPHONE_E_SUCCESS;
716 hton_header(new_connection->header);
717 printf("%s: send_to_phone (%d --> %d)\n", __func__, ntohs(new_connection->header->sport), ntohs(new_connection->header->dport));
638 if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { 718 if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) {
639 *client = new_connection; 719 *client = new_connection;
640 return IPHONE_E_SUCCESS; 720 return IPHONE_E_SUCCESS;
@@ -661,11 +741,10 @@ iphone_error_t iphone_mux_free_client(iphone_umux_client_t client)
661 741
662 pthread_mutex_lock(&client->mutex); 742 pthread_mutex_lock(&client->mutex);
663 client->header->tcp_flags = TCP_FIN; 743 client->header->tcp_flags = TCP_FIN;
664 client->header->length = htonl(0x1C); 744 client->header->length = 0x1C;
665 client->header->scnt = htonl(client->header->scnt);
666 client->header->ocnt = htonl(client->header->ocnt);
667 client->header->window = 0; 745 client->header->window = 0;
668 client->header->length16 = htons(0x1C); 746 client->header->length16 = 0x1C;
747 hton_header(client->header);
669 int bytes = 0; 748 int bytes = 0;
670 749
671 bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800); 750 bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800);
@@ -731,31 +810,29 @@ iphone_error_t iphone_mux_send(iphone_umux_client_t client, const char *data, ui
731 // client->scnt and client->ocnt should already be in host notation... 810 // client->scnt and client->ocnt should already be in host notation...
732 // we don't need to change them juuuust yet. 811 // we don't need to change them juuuust yet.
733 char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding 812 char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding
734 // Set the length and pre-emptively htonl/htons it 813 // Set the length
735 client->header->length = htonl(blocksize); 814 client->header->length = blocksize;
736 client->header->length16 = htons(blocksize); 815 client->header->length16 = blocksize;
737 816
738 // Put scnt and ocnt into big-endian notation 817 // Put header into big-endian notation
739 client->header->scnt = htonl(client->header->scnt); 818 hton_header(client->header);
740 client->header->ocnt = htonl(client->header->ocnt);
741 // Concatenation of stuff in the buffer. 819 // Concatenation of stuff in the buffer.
742 memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); 820 memcpy(buffer, client->header, sizeof(usbmux_tcp_header));
743 memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); 821 memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen);
744 822
823 printf("%s: send_to_phone(%d --> %d)\n", __func__, ntohs(client->header->sport), ntohs(client->header->dport));
745 sendresult = send_to_phone(client->phone, buffer, blocksize); 824 sendresult = send_to_phone(client->phone, buffer, blocksize);
746 // Now that we've sent it off, we can clean up after our sloppy selves. 825 // Now that we've sent it off, we can clean up after our sloppy selves.
747 if (buffer) 826 if (buffer)
748 free(buffer); 827 free(buffer);
749 828
829 // revert header fields that have been swapped before trying to send
830 ntoh_header(client->header);
831
750 // update counts ONLY if the send succeeded. 832 // update counts ONLY if the send succeeded.
751 if (sendresult == blocksize) { 833 if (sendresult == blocksize) {
752 // Re-calculate scnt and ocnt 834 // Re-calculate scnt
753 client->header->scnt = ntohl(client->header->scnt) + datalen; 835 client->header->scnt += datalen;
754 client->header->ocnt = ntohl(client->header->ocnt);
755 // Revert lengths
756 client->header->length = ntohl(client->header->length);
757 client->header->length16 = ntohs(client->header->length16);
758
759 client->wr_window -= blocksize; 836 client->wr_window -= blocksize;
760 } 837 }
761 838
@@ -812,20 +889,19 @@ uint32 append_receive_buffer(iphone_umux_client_t client, char* packet)
812 if (header->tcp_flags == (TCP_SYN | TCP_ACK)) { 889 if (header->tcp_flags == (TCP_SYN | TCP_ACK)) {
813 fprintf(stdout, "yes, got syn+ack ; replying with ack.\n"); 890 fprintf(stdout, "yes, got syn+ack ; replying with ack.\n");
814 client->header->tcp_flags = TCP_ACK; 891 client->header->tcp_flags = TCP_ACK;
815 client->header->length = htonl(sizeof(usbmux_tcp_header)); 892 client->header->length = sizeof(usbmux_tcp_header);
816 client->header->length16 = htons(sizeof(usbmux_tcp_header)); 893 client->header->length16 = sizeof(usbmux_tcp_header);
817 client->header->scnt = htonl(client->header->scnt + 1); 894 client->header->scnt += 1;
818 client->header->ocnt = header->ocnt; 895 client->header->ocnt = header->ocnt;
896 hton_header(client->header);
819 // push it to USB 897 // push it to USB
820 // TODO: need to check for error in the send here.... :( 898 // TODO: need to check for error in the send here.... :(
899 printf("%s: send_to_phone (%d --> %d)\n", __func__, ntohs(client->header->sport), ntohs(client->header->dport));
821 if (send_to_phone(client->phone, (char *)client->header, sizeof(usbmux_tcp_header)) <= 0) { 900 if (send_to_phone(client->phone, (char *)client->header, sizeof(usbmux_tcp_header)) <= 0) {
822 fprintf(stdout, "%s: error when pushing to usb...\n", __func__); 901 fprintf(stdout, "%s: error when pushing to usb...\n", __func__);
823 } 902 }
824 // need to revert some of the fields back to host notation. 903 // need to revert some of the fields back to host notation.
825 client->header->scnt = ntohl(client->header->scnt); 904 ntoh_header(client->header);
826 client->header->ocnt = ntohl(client->header->ocnt);
827 client->header->length = ntohl(client->header->length);
828 client->header->length16 = ntohs(client->header->length16);
829 } 905 }
830 else { 906 else {
831 client->error = IPHONE_E_ECONNABORTED; 907 client->error = IPHONE_E_ECONNABORTED;
@@ -843,7 +919,33 @@ uint32 append_receive_buffer(iphone_umux_client_t client, char* packet)
843 // larger number. 919 // larger number.
844 if (header->tcp_flags & TCP_RST) { 920 if (header->tcp_flags & TCP_RST) {
845 client->error = IPHONE_E_ECONNRESET; 921 client->error = IPHONE_E_ECONNRESET;
846 fprintf(stderr, "peer sent connection reset. setting error: %d\n", client->error); 922
923 if (datalen > 0) {
924 char e_msg[128];
925 e_msg[0] = 0;
926 if (datalen > 1) {
927 memcpy(e_msg, data+1, datalen-1);
928 e_msg[datalen-1] = 0;
929 }
930 // fetch the message
931 switch(data[0]) {
932 case 0:
933 // this is not an error, it's just a status message.
934 fprintf(stdout, "received status message: %s\n", e_msg);
935 datalen = 0;
936 break;
937 case 1:
938 fprintf(stderr, "received error message: %s\n", e_msg);
939 datalen = 0;
940 break;
941 default:
942 fprintf(stderr, "received unknown message (type 0x%02x): %s\n", data[0], e_msg);
943 //datalen = 0; // <-- we let this commented out for testing
944 break;
945 }
946 } else {
947 fprintf(stderr, "peer sent connection reset. setting error: %d\n", client->error);
948 }
847 } 949 }
848 950
849 // the packet's ocnt tells us how much of our data the device has received. 951 // the packet's ocnt tells us how much of our data the device has received.
@@ -954,7 +1056,7 @@ void iphone_mux_pullbulk(iphone_device_t phone)
954 readlen = 0; 1056 readlen = 0;
955 } 1057 }
956 if (readlen > 0) { 1058 if (readlen > 0) {
957 //fprintf(stdout, "recv_from_phone_timeout pulled an extra %d bytes\n", readlen); 1059 //fprintf(stdout, "recv_from_phone_timeout pulled an extra %d bytes\n", readlen);
958 } 1060 }
959 1061
960 // the amount of content we have to work with is the remainder plus 1062 // the amount of content we have to work with is the remainder plus
@@ -968,7 +1070,9 @@ void iphone_mux_pullbulk(iphone_device_t phone)
968 // check if there's even sufficient data to decode a header 1070 // check if there's even sufficient data to decode a header
969 if (usbReceive.leftover < HEADERLEN) break; 1071 if (usbReceive.leftover < HEADERLEN) break;
970 usbmux_tcp_header *header = (usbmux_tcp_header *) cursor; 1072 usbmux_tcp_header *header = (usbmux_tcp_header *) cursor;
971 1073
1074 printf("%s: recv_from_phone_timeout (%d --> %d)\n", __func__, ntohs(header->sport), ntohs(header->dport));
1075
972 // now that we have a header, check if there is sufficient data 1076 // now that we have a header, check if there is sufficient data
973 // to construct a full packet, including its data 1077 // to construct a full packet, including its data
974 uint32 packetlen = ntohl(header->length); 1078 uint32 packetlen = ntohl(header->length);