ajout d'un exemple de systeme d'autoconfiguration via http
[ipphone-tools.git] / ipphone5-upload.c
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 */
8
9 #define FILE_FULL_PAGE_SIZE 65536
10
11 #define FIRMWARE_SIZE (FILE_FULL_PAGE_SIZE*15)
12 #define MAX_PCMRING_SIZE 15360
13 #define SDRAM_MAX_LENGTH 640000
14 #define TOTAL_SETTINGS_SIZE 4096
15
16 #define TCP_UPLOAD_SIZE 128
17 #define TCP_UPLOAD_PORT 0x2223 // 8739
18
19 #define OPTIONS_UPLOAD_PAGE 128
20 #define PROGRAM_UPLOAD_PAGE 129
21 #define RING_UPLOAD_PAGE 130
22 #define MAP_UPLOAD_PAGE 132
23 #define ALTERNATE_SETTING_UPLOAD_PAGE 133
24
25 /*
26 * Upload protocol (from PalmToolDlg.cpp):
27 * Step1. PC make a TCP connection to Palm1's page0 program
28 * Step2. PC sends 128 bytes package data to Palm1
29 * Palm1 send back 1 byte of "0xff"
30 * Repeat step2 until the whole data has been sent
31 * Step3. PC sends 1 byte data indicate which page to write to
32 * Palm1 send back 1 byte of "0xff"
33 * Step4. PC close the TCP connection indicate the update progress is over
34 */
35 int upload(int sd, const char *buffer, size_t length, int upload_page) {
36 unsigned char result;
37 fprintf(stdout, "Uploading... ");
38 // sending data
39 while (length > 0) {
40 write(sd, buffer, TCP_UPLOAD_SIZE);
41 read(sd, &result, 1);
42 if (result != 0xff) {
43 fprintf(stderr, "Warning: unexpected read result (%02X) !\n", result);
44 fprintf(stdout, "Aborting.\n");
45 return 1;
46 }
47 fprintf(stdout, "%10d\b\b\b\b\b\b\b\b\b\b", length);
48 buffer += TCP_UPLOAD_SIZE;
49 length -= TCP_UPLOAD_SIZE;
50 }
51 // sending page number
52 result = upload_page;
53 write(sd, &result, 1);
54 read(sd, &result, 1);
55 if (result != 0xff) {
56 fprintf(stderr, "Warning: unexpected read result (%02X) !\n", result);
57 fprintf(stdout, "Aborting.\n");
58 return 1;
59 }
60 fprintf(stdout, "Done. \n");
61 return 0;
62 }
63
64 int main(int argc, const char *argv[]) {
65 const char *progname, *filename, *extension, *ipaddr;
66 FILE *filehandle;
67 int upload_page;
68 size_t length, length_padded;
69 char *buffer;
70 struct in_addr sin_addr;
71 int sd;
72 struct sockaddr_in sin;
73
74 // check arguments count
75 progname = argv[0];
76 if (argc != 3) {
77 fprintf(stderr, "Syntax: %s <filename> <IPv4-address>\n", progname);
78 fprintf(stderr, " where <filename> is one of:\n");
79 fprintf(stderr, " <name>.bin : firmware\n");
80 fprintf(stderr, " <name>.dat : ring\n");
81 fprintf(stderr, " <name>.sh : options\n");
82 fprintf(stderr, " map.txt : digit map\n");
83 fprintf(stderr, " stdram.dat : \n");
84 return 1;
85 }
86 filename = argv[1];
87 ipaddr = argv[2];
88
89 // check first argument (filename)
90 filehandle = fopen(filename, "rb");
91 if (filehandle == NULL) {
92 fprintf(stderr, "Unable to open '%s' !\n", filename);
93 return 2;
94 }
95 fprintf(stdout, "File name: %s\n", filename);
96
97 // check file type (by extension, for now...)
98 extension = strrchr(filename, '.');
99 if (!strcasecmp(filename, "sdram.dat")) {
100 // FIXME: upload_page = ;
101 fprintf(stderr, "Not implemented yet!\n");
102 return 2;
103 } else if (!strcasecmp(filename, "map.txt")) {
104 upload_page = MAP_UPLOAD_PAGE;
105 } else if (extension && !strcasecmp(extension, ".sh")) {
106 upload_page = OPTIONS_UPLOAD_PAGE;
107 } else if (extension && !strcasecmp(extension, ".bin")) {
108 upload_page = PROGRAM_UPLOAD_PAGE;
109 } else if (extension && !strcasecmp(extension, ".dat")) {
110 upload_page = RING_UPLOAD_PAGE;
111 } else {
112 fprintf(stderr, "Unknown file type!\n");
113 return 2;
114 }
115
116 // get file size
117 fseek(filehandle, 0L, SEEK_END);
118 length = ftell(filehandle);
119 length_padded = length + TCP_UPLOAD_SIZE*2 - 1;
120 length_padded /= TCP_UPLOAD_SIZE*2;
121 length_padded *= TCP_UPLOAD_SIZE*2;
122
123 // check file size
124 if ((upload_page == PROGRAM_UPLOAD_PAGE) && (length_padded != FIRMWARE_SIZE)) {
125 fprintf(stderr, "Invalid file size (%d != %d) !\n", length_padded, FIRMWARE_SIZE);
126 return 3;
127 } else if ((upload_page == RING_UPLOAD_PAGE) && (length_padded > MAX_PCMRING_SIZE)) {
128 fprintf(stderr, "Invalid file size (%d > %d) !\n", length_padded, MAX_PCMRING_SIZE);
129 return 3;
130 } else if ((upload_page == OPTIONS_UPLOAD_PAGE) && (length_padded != TOTAL_SETTINGS_SIZE)) {
131 fprintf(stderr, "Invalid file size (%d > %d) !\n", length_padded, MAX_PCMRING_SIZE);
132 return 3;
133 }
134
135 // load data into memory
136 fprintf(stdout, "File length: %d bytes", length);
137 if (length_padded > length) {
138 fprintf(stdout, " (padding to %d bytes)", length_padded);
139 }
140 fprintf(stdout, "\n");
141 buffer = malloc(length_padded);
142 if (buffer == NULL) {
143 fprintf(stderr, "Unable to allocate enough (%d bytes) memory!\n", length_padded);
144 return 4;
145 }
146 fseek(filehandle, 0L, SEEK_SET);
147 if (fread(buffer, length, 1, filehandle) != 1) {
148 fprintf(stderr, "Unable to read the whole file content!\n");
149 return 5;
150 }
151 fclose(filehandle);
152 if (length < length_padded) {
153 memset(buffer + length, 0, length_padded - length);
154 }
155
156 // check second argument (IPv4 address)
157 if (!inet_aton(ipaddr, &sin_addr)) {
158 fprintf(stderr, "'%s' is an invalid IPv4 address!\n", ipaddr);
159 return 6;
160 }
161 fprintf(stdout, "IPv4 address: %s\n", inet_ntoa(sin_addr));
162
163 // connect to the host
164 sd = socket(PF_INET, SOCK_STREAM, 0);
165 if (sd < 0) {
166 fprintf(stderr, "Unable to create a socket!\n");
167 return 7;
168 }
169 memset(&sin, 0, sizeof(sin));
170 sin.sin_family = AF_INET;
171 sin.sin_port = htons(TCP_UPLOAD_PORT);
172 memcpy(&sin.sin_addr, &sin_addr, sizeof(sin.sin_addr));
173 if (connect(sd, (struct sockaddr *)&sin, sizeof(sin))) {
174 fprintf(stderr, "Unable to connect to host!\n");
175 return 8;
176 }
177
178 // do the upgrade process
179 setbuf(stdout, NULL);
180 if (upload(sd, buffer, length_padded, upload_page)) return 9;
181
182 // cleaning
183 close(sd);
184 return 0;
185 }