diff options
Diffstat (limited to 'src/usbmux.c')
| -rw-r--r-- | src/usbmux.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/src/usbmux.c b/src/usbmux.c index 1d6497e..2157e05 100644 --- a/src/usbmux.c +++ b/src/usbmux.c | |||
| @@ -822,6 +822,7 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, | |||
| 822 | pthread_mutex_lock(&client->mutex); | 822 | pthread_mutex_lock(&client->mutex); |
| 823 | 823 | ||
| 824 | int sendresult = 0; | 824 | int sendresult = 0; |
| 825 | int fullsendresult = 0; | ||
| 825 | uint32_t blocksize = 0; | 826 | uint32_t blocksize = 0; |
| 826 | if (client->wr_window <= 0) { | 827 | if (client->wr_window <= 0) { |
| 827 | struct timespec ts; | 828 | struct timespec ts; |
| @@ -840,20 +841,67 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, | |||
| 840 | // client->scnt and client->ocnt should already be in host notation... | 841 | // client->scnt and client->ocnt should already be in host notation... |
| 841 | // we don't need to change them juuuust yet. | 842 | // we don't need to change them juuuust yet. |
| 842 | char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding | 843 | char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding |
| 844 | const char *dataptr = data; | ||
| 845 | uint32_t curlen = datalen; | ||
| 846 | uint32_t packetsize = blocksize; | ||
| 847 | |||
| 848 | // BEGIN HACK | ||
| 849 | if ((blocksize % 128) == 0) { | ||
| 850 | int cutoff = 28; | ||
| 851 | // HACK: we need to split up the packet because of an unresolved | ||
| 852 | // usb communication issue aka 'N*128 problem' or 'N*512 problem' | ||
| 853 | log_debug_msg("%s: HACK: splitting packet, two send_to_device calls will follow\n"); | ||
| 854 | packetsize = blocksize - cutoff; | ||
| 855 | curlen = datalen - cutoff; | ||
| 856 | client->header->length = packetsize; | ||
| 857 | client->header->length16 = packetsize; | ||
| 858 | hton_header(client->header); | ||
| 859 | memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); | ||
| 860 | memcpy(buffer + sizeof(usbmux_tcp_header), dataptr, curlen); | ||
| 861 | |||
| 862 | log_debug_msg("%s: send_to_device(%d --> %d) window = %d\n", __func__, | ||
| 863 | ntohs(client->header->sport), | ||
| 864 | ntohs(client->header->dport), | ||
| 865 | ntohs(client->header->window)); | ||
| 866 | sendresult = send_to_device(client->device, buffer, packetsize); | ||
| 867 | fullsendresult = sendresult; | ||
| 868 | |||
| 869 | // revert header fields that have been swapped before trying to send | ||
| 870 | ntoh_header(client->header); | ||
| 871 | |||
| 872 | // update counts ONLY if the send succeeded. | ||
| 873 | if ((uint32_t) sendresult == packetsize) { | ||
| 874 | // Re-calculate scnt | ||
| 875 | client->header->scnt += curlen; | ||
| 876 | client->wr_window -= packetsize; | ||
| 877 | } else { | ||
| 878 | goto err_cond; | ||
| 879 | } | ||
| 880 | |||
| 881 | dataptr += curlen; | ||
| 882 | curlen = cutoff; | ||
| 883 | packetsize = sizeof(usbmux_tcp_header) + curlen; | ||
| 884 | // fix fullsendresult to not include the header length to make | ||
| 885 | // setting *sent_bytes work properly | ||
| 886 | fullsendresult -= sizeof(usbmux_tcp_header); | ||
| 887 | } | ||
| 888 | // END HACK | ||
| 889 | |||
| 843 | // Set the length | 890 | // Set the length |
| 844 | client->header->length = blocksize; | 891 | client->header->length = packetsize; |
| 845 | client->header->length16 = blocksize; | 892 | client->header->length16 = packetsize; |
| 846 | 893 | ||
| 847 | // Put header into big-endian notation | 894 | // Put header into big-endian notation |
| 848 | hton_header(client->header); | 895 | hton_header(client->header); |
| 849 | // Concatenation of stuff in the buffer. | 896 | // Concatenation of stuff in the buffer. |
| 850 | memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); | 897 | memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); |
| 851 | memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); | 898 | memcpy(buffer + sizeof(usbmux_tcp_header), dataptr, curlen); |
| 852 | 899 | ||
| 853 | log_debug_msg("%s: send_to_device(%d --> %d)\n", __func__, | 900 | log_debug_msg("%s: send_to_device(%d --> %d)\n", __func__, |
| 854 | ntohs(client->header->sport), | 901 | ntohs(client->header->sport), |
| 855 | ntohs(client->header->dport)); | 902 | ntohs(client->header->dport)); |
| 856 | sendresult = send_to_device(client->device, buffer, blocksize); | 903 | sendresult = send_to_device(client->device, buffer, packetsize); |
| 904 | fullsendresult += sendresult; | ||
| 857 | // Now that we've sent it off, we can clean up after our sloppy selves. | 905 | // Now that we've sent it off, we can clean up after our sloppy selves. |
| 858 | if (buffer) | 906 | if (buffer) |
| 859 | free(buffer); | 907 | free(buffer); |
| @@ -862,12 +910,13 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, | |||
| 862 | ntoh_header(client->header); | 910 | ntoh_header(client->header); |
| 863 | 911 | ||
| 864 | // update counts ONLY if the send succeeded. | 912 | // update counts ONLY if the send succeeded. |
| 865 | if ((uint32_t) sendresult == blocksize) { | 913 | if ((uint32_t) sendresult == packetsize) { |
| 866 | // Re-calculate scnt | 914 | // Re-calculate scnt |
| 867 | client->header->scnt += datalen; | 915 | client->header->scnt += curlen; |
| 868 | client->wr_window -= blocksize; | 916 | client->wr_window -= packetsize; |
| 869 | } | 917 | } |
| 870 | 918 | ||
| 919 | err_cond: | ||
| 871 | pthread_mutex_unlock(&client->mutex); | 920 | pthread_mutex_unlock(&client->mutex); |
| 872 | 921 | ||
| 873 | if (sendresult == -ETIMEDOUT || sendresult == 0) { | 922 | if (sendresult == -ETIMEDOUT || sendresult == 0) { |
| @@ -876,14 +925,14 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, | |||
| 876 | return -ETIMEDOUT; | 925 | return -ETIMEDOUT; |
| 877 | } else if (sendresult < 0) { | 926 | } else if (sendresult < 0) { |
| 878 | return sendresult; | 927 | return sendresult; |
| 879 | } else if ((uint32_t) sendresult == blocksize) { | 928 | } else if ((uint32_t) fullsendresult == blocksize) { |
| 880 | // actual number of data bytes sent. | 929 | // actual number of data bytes sent. |
| 881 | *sent_bytes = sendresult - sizeof(usbmux_tcp_header); | 930 | *sent_bytes = fullsendresult - sizeof(usbmux_tcp_header); |
| 882 | return 0; | 931 | return 0; |
| 883 | } else { | 932 | } else { |
| 884 | fprintf(stderr, | 933 | fprintf(stderr, |
| 885 | "usbsend managed to dump a packet that is not full size. %d of %d\n", | 934 | "usbsend managed to dump a packet that is not full size. %d of %d\n", |
| 886 | sendresult, blocksize); | 935 | sendresult, packetsize); |
| 887 | return -EBADMSG; | 936 | return -EBADMSG; |
| 888 | } | 937 | } |
| 889 | } | 938 | } |
