1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 #include <arpa/inet.h> /* inet_aton,inet_ntoa */
4 #include <unistd.h> /* read,write,close */
5 #include <string.h> /* memset */
6 #include <stdlib.h> /* malloc */
7 #include <stdio.h> /* FILE,fprintf */
9 #define FILE_READ_MAX_SIZE 655000
10 #define FILE_ONE_PAGE_SIZE 64000
12 #define SDRAM_MAX_LENGTH 640000
13 #define TOTAL_SETTINGS_SIZE 4096
15 #define TCP_DOWNLOAD_SIZE 128
16 #define TCP_DOWNLOAD_PORT 0x2223 // 8739
18 #define DATA_HINT "dh"
19 #define SETTINGS_HINT "sh"
22 * Download protocol (from PalmToolDlg.cpp):
23 * Step1. PC make a TCP connection to Palm1's page0 program
24 * Step2. PC sends 2 bytes to Palm1 for data "dh" or settings "sh" hints
25 * Palm1 sends back 128 byte of data
26 * Repeat step2 until the whole data has been received
27 * Step3. PC close the TCP connection indicate the download is over
29 int download(int sd
, char *buffer
, size_t length
, const char *hint
) {
30 fprintf(stdout
, "Downloading... ");
33 write(sd
, hint
, strlen(hint
));
34 read(sd
, buffer
, TCP_DOWNLOAD_SIZE
);
35 // FIXME: should check for errors!
36 fprintf(stdout
, "%10d\b\b\b\b\b\b\b\b\b\b", length
);
37 buffer
+= TCP_DOWNLOAD_SIZE
;
38 length
-= TCP_DOWNLOAD_SIZE
;
40 fprintf(stdout
, "Done. \n");
44 int main(int argc
, const char *argv
[]) {
45 const char *progname
, *filename
, *extension
, *hint
, *ipaddr
;
47 size_t length
, length_padded
;
49 struct in_addr sin_addr
;
51 struct sockaddr_in sin
;
53 // check arguments count
56 fprintf(stderr
, "Syntax: %s <filename> <IPv4-address>\n", progname
);
62 // check first argument (filename)
63 filehandle
= fopen(filename
, "wb");
64 if (filehandle
== NULL
) {
65 fprintf(stderr
, "Unable to open '%s' !\n", filename
);
68 fprintf(stdout
, "File name: %s\n", filename
);
70 // check file type (by extension, for now...)
71 extension
= strrchr(filename
, '.');
72 if (extension
&& !strcasecmp(extension
, ".dh")) {
74 length
= SDRAM_MAX_LENGTH
; // < FILE_READ_MAX_SIZE
75 } else if (extension
&& !strcasecmp(extension
, ".sh")) {
77 length
= TOTAL_SETTINGS_SIZE
; // < FILE_ONE_PAGE_SIZE
79 fprintf(stderr
, "Unknown file type!\n");
83 // normalize file size
84 length_padded
= length
+ TCP_DOWNLOAD_SIZE
*2 - 1;
85 length_padded
/= TCP_DOWNLOAD_SIZE
*2;
86 length_padded
*= TCP_DOWNLOAD_SIZE
*2;
88 // prepare to load data into memory
89 fprintf(stdout
, "File length: %d bytes", length
);
90 if (length_padded
> length
) {
91 fprintf(stdout
, " (padding to %d bytes)", length_padded
);
93 fprintf(stdout
, "\n");
94 buffer
= malloc(length_padded
);
96 fprintf(stderr
, "Unable to allocate enough (%d bytes) memory!\n", length_padded
);
100 // check second argument (IPv4 address)
101 if (!inet_aton(ipaddr
, &sin_addr
)) {
102 fprintf(stderr
, "'%s' is an invalid IPv4 address!\n", ipaddr
);
105 fprintf(stdout
, "IPv4 address: %s\n", inet_ntoa(sin_addr
));
107 // connect to the host
108 sd
= socket(PF_INET
, SOCK_STREAM
, 0);
110 fprintf(stderr
, "Unable to create a socket!\n");
113 memset(&sin
, 0, sizeof(sin
));
114 sin
.sin_family
= AF_INET
;
115 sin
.sin_port
= htons(TCP_DOWNLOAD_PORT
);
116 memcpy(&sin
.sin_addr
, &sin_addr
, sizeof(sin
.sin_addr
));
117 if (connect(sd
, (struct sockaddr
*)&sin
, sizeof(sin
))) {
118 fprintf(stderr
, "Unable to connect to host!\n");
122 // do the upgrade process
123 setbuf(stdout
, NULL
);
124 if (download(sd
, buffer
, length_padded
, hint
)) return 9;
127 //if (length < length_padded) {
128 // memset(buffer + length, 0, length_padded - length);
130 if (fwrite(buffer
, length
, 1, filehandle
) != 1) { // XXX: length_padded?
131 fprintf(stderr
, "Unable to write the whole file content!\n");