024697d76da310f9605c19aa3e24e2229fad3d73
[osmocom-bb.git] / src / host / osmocon / osmocon.c
1 /* osmocon */
2
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
4  * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
5  * (C) 2010 by Steve Markgraf <steve@steve-m.de>
6  *
7  * All Rights Reserved
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  */
24
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <stdint.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <termios.h>
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/stat.h>
38 #include <sys/un.h>
39
40 #include <sercomm.h>
41
42 #include <osmocore/linuxlist.h>
43 #include <osmocore/select.h>
44 #include <osmocore/talloc.h>
45 #include <osmocore/timer.h>
46
47 #include <arpa/inet.h>
48
49 #define MODEM_BAUDRATE          B115200
50 #define MAX_DNLOAD_SIZE         0xFFFF
51 #define MAX_HDR_SIZE            128
52 #define MAGIC_OFFSET            0x3be2
53
54 #define BEACON_INTERVAL         50000
55 #define ROMLOAD_INIT_BAUDRATE   B19200
56 #define ROMLOAD_DL_BAUDRATE     B115200
57 #define ROMLOAD_BLOCK_HDR_LEN   10
58 #define ROMLOAD_ADDRESS         0x820000
59
60 #define MTK_INIT_BAUDRATE       B19200
61 #define MTK_ADDRESS             0x40001400
62 #define MTK_BLOCK_SIZE          1024
63
64 struct tool_server *tool_server_for_dlci[256];
65
66 /**
67  * a connection from some other tool
68  */
69 struct tool_connection {
70         struct tool_server *server;
71         struct llist_head entry;
72         struct bsc_fd fd;
73 };
74
75 /**
76  * server for a tool
77  */
78 struct tool_server {
79         struct bsc_fd bfd;
80         uint8_t dlci;
81         struct llist_head connections;
82 };
83
84
85 enum dnload_state {
86         WAITING_PROMPT1,
87         WAITING_PROMPT2,
88         DOWNLOADING,
89 };
90
91 enum romload_state {
92         WAITING_IDENTIFICATION,
93         WAITING_PARAM_ACK,
94         SENDING_BLOCKS,
95         SENDING_LAST_BLOCK,
96         LAST_BLOCK_SENT,
97         WAITING_BLOCK_ACK,
98         WAITING_CHECKSUM_ACK,
99         WAITING_BRANCH_ACK,
100         FINISHED,
101 };
102
103 enum mtk_state {
104         MTK_INIT_1,
105         MTK_INIT_2,
106         MTK_INIT_3,
107         MTK_INIT_4,
108         MTK_WAIT_WRITE_ACK,
109         MTK_WAIT_ADDR_ACK,
110         MTK_WAIT_SIZE_ACK,
111         MTK_SENDING_BLOCKS,
112         MTK_WAIT_BRANCH_CMD_ACK,
113         MTK_WAIT_BRANCH_ADDR_ACK,
114         MTK_FINISHED,
115 };
116
117 enum dnload_mode {
118         MODE_C123,
119         MODE_C123xor,
120         MODE_C140,
121         MODE_C140xor,
122         MODE_C155,
123         MODE_ROMLOAD,
124         MODE_MTK,
125 };
126
127 struct dnload {
128         enum dnload_state state;
129         enum romload_state romload_state;
130         enum mtk_state mtk_state;
131         enum dnload_mode mode;
132         struct bsc_fd serial_fd;
133         char *filename;
134         char *chainload_filename;
135
136         int expect_hdlc;
137
138         int dump_rx;
139         int dump_tx;
140
141         /* data to be downloaded */
142         uint8_t *data;
143         int data_len;
144
145         uint8_t *write_ptr;
146
147         /* romload: block to be downloaded */
148         uint8_t *block;
149         int block_len;
150         uint8_t block_number;
151         uint16_t block_payload_size;
152         int romload_dl_checksum;
153         uint8_t *block_ptr;
154         uint8_t load_address[4];
155
156         uint8_t mtk_send_size[4];
157         int block_count;
158         int echo_bytecount;
159
160         struct tool_server layer2_server;
161         struct tool_server loader_server;
162 };
163
164
165 static struct dnload dnload;
166 static struct timer_list tick_timer;
167
168 /* Compal ramloader specific */
169 static const uint8_t phone_prompt1[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x01, 0x40 };
170 static const uint8_t dnload_cmd[]    = { 0x1b, 0xf6, 0x02, 0x00, 0x52, 0x01, 0x53 };
171 static const uint8_t phone_prompt2[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x02, 0x43 };
172 static const uint8_t phone_ack[]     = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x42 };
173 static const uint8_t phone_nack_magic[]= { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x57 };
174 static const uint8_t phone_nack[]    = { 0x1b, 0xf6, 0x02, 0x00, 0x45, 0x53, 0x16 };
175 static const uint8_t ftmtool[] = { 0x66, 0x74, 0x6d, 0x74, 0x6f, 0x6f, 0x6c };
176 static const uint8_t phone_magic[] = { 0x31, 0x30, 0x30, 0x33 }; /* "1003" */
177
178 /* The C123 has a hard-coded check inside the ramloader that requires the
179  * following bytes to be always the first four bytes of the image */
180 static const uint8_t data_hdr_c123[]    = { 0xee, 0x4c, 0x9f, 0x63 };
181
182 /* The C155 doesn't have some strange restriction on what the first four bytes
183  *  have to be, but it starts the ramloader in THUMB mode. We use the following
184  * four bytes to switch back to ARM mode:
185   800100:       4778            bx      pc
186   800102:       46c0            nop                     ; (mov r8, r8)
187  */
188 static const uint8_t data_hdr_c155[]    = { 0x78, 0x47, 0xc0, 0x46 };
189
190 /* Calypso romloader specific */
191 static const uint8_t romload_ident_cmd[] =      { 0x3c, 0x69 }; /* <i */
192 static const uint8_t romload_abort_cmd[] =      { 0x3c, 0x61 }; /* <a */
193 static const uint8_t romload_write_cmd[] =      { 0x3c, 0x77 }; /* <w */
194 static const uint8_t romload_checksum_cmd[] =   { 0x3c, 0x63 }; /* <c */
195 static const uint8_t romload_branch_cmd[] =     { 0x3c, 0x62 }; /* <b */
196 static const uint8_t romload_ident_ack[] =      { 0x3e, 0x69 }; /* >i */
197 static const uint8_t romload_param_ack[] =      { 0x3e, 0x70 }; /* >p */
198 static const uint8_t romload_param_nack[] =     { 0x3e, 0x50 }; /* >P */
199 static const uint8_t romload_block_ack[] =      { 0x3e, 0x77 }; /* >w */
200 static const uint8_t romload_block_nack[] =     { 0x3e, 0x57 }; /* >W */
201 static const uint8_t romload_checksum_ack[] =   { 0x3e, 0x63 }; /* >c */
202 static const uint8_t romload_checksum_nack[] =  { 0x3e, 0x43 }; /* >C */
203 static const uint8_t romload_branch_ack[] =     { 0x3e, 0x62 }; /* >b */
204 static const uint8_t romload_branch_nack[] =    { 0x3e, 0x42 }; /* >B */
205
206 /* romload_param: {"<p", uint8_t baudrate, uint8_t dpll, uint16_t memory_config,
207  * uint8_t strobe_af, uint32_t uart_timeout} */
208
209 static const uint8_t romload_param[] = { 0x3c, 0x70, 0x00, 0x00, 0x00, 0x04,
210                                          0x00, 0x00, 0x00, 0x00, 0x00 };
211
212 /* MTK romloader specific */
213 static const uint8_t mtk_init_cmd[] =   { 0xa0, 0x0a, 0x50, 0x05 };
214 static const uint8_t mtk_init_resp[] =  { 0x5f, 0xf5, 0xaf, 0xfa };
215 static const uint8_t mtk_command[] =    { 0xa1, 0xa2, 0xa4, 0xa8 };
216
217 /* FIXME: this routine is more or less what openbsc/src/rs232:rs232_setup()
218  * does, we should move it to libosmocore at some point */
219 static int serial_init(const char *serial_port)
220 {
221         int rc, serial_fd, v24;
222         struct termios tio;
223
224         serial_fd = open(serial_port, O_RDWR | O_NOCTTY | O_NDELAY);
225         if (serial_fd < 0) {
226                 perror("cannot open serial port");
227                 return serial_fd;
228         }
229
230         //fcntl(serial_fd, F_SETFL, 0);
231
232         /* Configure serial interface */
233         rc = tcgetattr(serial_fd, &tio);
234         if (rc < 0) {
235                 perror("tcgetattr()");
236                 return rc;
237         }
238         cfsetispeed(&tio, MODEM_BAUDRATE);
239         cfsetospeed(&tio, MODEM_BAUDRATE);
240         tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
241         tio.c_cflag |=  (CREAD | CLOCAL | CS8);
242         tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
243         tio.c_iflag |=  (INPCK | ISTRIP);
244         tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
245         tio.c_oflag &= ~(OPOST | ONLCR);
246         rc = tcsetattr(serial_fd, TCSANOW, &tio);
247         if (rc < 0) {
248                 perror("tcsetattr()");
249                 return rc;
250         }
251
252         /* set ready to read/write */
253         v24 = TIOCM_DTR | TIOCM_RTS;
254         rc = ioctl(serial_fd, TIOCMBIS, &v24);
255         if (rc < 0) {
256                 perror("ioctl(TIOCMBIS)");
257                 return rc;
258         }
259
260         return serial_fd;
261 }
262
263 static int serial_set_baudrate(speed_t baudrate)
264 {
265         int rc;
266         struct termios tio;
267
268         rc = tcgetattr(dnload.serial_fd.fd, &tio);
269         if (rc < 0) {
270                 perror("tcgetattr()");
271                 return rc;
272         }
273         cfsetispeed(&tio, baudrate);
274         cfsetospeed(&tio, baudrate);
275
276         rc = tcsetattr(dnload.serial_fd.fd, TCSANOW, &tio);
277         return rc;
278 }
279
280 static void beacon_timer_cb(void *p)
281 {
282         int rc;
283
284         if (dnload.romload_state == WAITING_IDENTIFICATION) {
285                 printf("Sending Calypso romloader beacon...\n");
286                 rc = write(dnload.serial_fd.fd, romload_ident_cmd,
287                            sizeof(romload_ident_cmd));
288
289                 if (!(rc == sizeof(romload_ident_cmd)))
290                         printf("Error sending identification beacon\n");
291
292                 bsc_schedule_timer(p, 0, BEACON_INTERVAL);
293         }
294 }
295
296 static void mtk_timer_cb(void *p)
297 {
298         int rc;
299
300         if (dnload.mtk_state == MTK_INIT_1) {
301                 printf("Sending MTK romloader beacon...\n");
302                 rc = write(dnload.serial_fd.fd, &mtk_init_cmd[0], 1);
303
304                 if (!(rc == 1))
305                         printf("Error sending identification beacon\n");
306
307                 bsc_schedule_timer(p, 0, BEACON_INTERVAL);
308         }
309 }
310
311 /* Read the to-be-downloaded file, prepend header and length, append XOR sum */
312 int read_file(const char *filename)
313 {
314         int fd, rc, i;
315         struct stat st;
316         const uint8_t *hdr = NULL;
317         int payload_size;
318         int hdr_len = 0;
319         uint8_t *file_data;
320         uint16_t tot_len;
321         uint8_t nibble;
322         uint8_t running_xor = 0x02;
323
324         fd = open(filename, O_RDONLY);
325         if (fd < 0) {
326                 perror("opening file");
327                 exit(1);
328         }
329
330         rc = fstat(fd, &st);
331         if (st.st_size > MAX_DNLOAD_SIZE) {
332                 fprintf(stderr, "The maximum file size is 64kBytes (%u bytes)\n",
333                         MAX_DNLOAD_SIZE);
334                 return -EFBIG;
335         }
336
337         if (dnload.data) {
338                 free(dnload.data);
339                 dnload.data = NULL;
340         }
341
342         if (dnload.mode == MODE_C140 || dnload.mode == MODE_C140xor) {
343                 if (st.st_size < (MAGIC_OFFSET + sizeof(phone_magic)))
344                         payload_size = MAGIC_OFFSET + sizeof(phone_magic);
345                 else {
346                         printf("\nThe filesize is larger than 15kb, code on "
347                                 "the magic address will be overwritten!\nUse "
348                                 "loader.bin and upload the application with "
349                                 "osmoload instead!\n\n");
350                         payload_size = st.st_size;
351                 }
352         } else
353                 payload_size = st.st_size;
354
355         dnload.data = malloc(MAX_HDR_SIZE + payload_size);
356
357         if (!dnload.data) {
358                 close(fd);
359                 fprintf(stderr, "No memory\n");
360                 return -ENOMEM;
361         }
362
363         /* copy in the header, if any */
364         switch (dnload.mode) {
365         case MODE_C155:
366                 hdr = data_hdr_c155;
367                 hdr_len = sizeof(data_hdr_c155);
368                 break;
369         case MODE_C140:
370         case MODE_C140xor:
371         case MODE_C123:
372         case MODE_C123xor:
373                 hdr = data_hdr_c123;
374                 hdr_len = sizeof(data_hdr_c123);
375                 break;
376         case MODE_ROMLOAD:
377                 break;
378         default:
379                 break;
380         }
381
382         if (hdr && hdr_len)
383                 memcpy(dnload.data, hdr, hdr_len);
384
385         /* 2 bytes for length + header */
386         file_data = dnload.data + 2 + hdr_len;
387
388         /* write the length, keep running XOR */
389         tot_len = hdr_len + payload_size;
390         nibble = tot_len >> 8;
391         dnload.data[0] = nibble;
392         running_xor ^= nibble;
393         nibble = tot_len & 0xff;
394         dnload.data[1] = nibble;
395         running_xor ^= nibble;
396
397         if (hdr_len && hdr) {
398                 memcpy(dnload.data+2, hdr, hdr_len);
399
400                 for (i = 0; i < hdr_len; i++)
401                         running_xor ^= hdr[i];
402         }
403
404         rc = read(fd, file_data, st.st_size);
405         if (rc < 0) {
406                 perror("error reading file\n");
407                 free(dnload.data);
408                 dnload.data = NULL;
409                 close(fd);
410                 return -EIO;
411         }
412         if (rc < st.st_size) {
413                 free(dnload.data);
414                 dnload.data = NULL;
415                 close(fd);
416                 fprintf(stderr, "Short read of file (%d < %d)\n",
417                         rc, (int)st.st_size);
418                 return -EIO;
419         }
420
421         close(fd);
422
423         dnload.data_len = (file_data+payload_size) - dnload.data;
424
425         /* fill memory between data end and magic, add magic */
426         if(dnload.mode == MODE_C140 || dnload.mode == MODE_C140xor) {
427                 if (st.st_size < MAGIC_OFFSET)
428                         memset(file_data + st.st_size, 0x00,
429                                 payload_size - st.st_size);
430                 memcpy(dnload.data + MAGIC_OFFSET, phone_magic,
431                         sizeof(phone_magic));
432         }
433
434         /* calculate XOR sum */
435         for (i = 0; i < payload_size; i++)
436                 running_xor ^= file_data[i];
437
438         dnload.data[dnload.data_len++] = running_xor;
439
440         /* initialize write pointer to start of data */
441         dnload.write_ptr = dnload.data;
442
443         printf("read_file(%s): file_size=%u, hdr_len=%u, dnload_len=%u\n",
444                 filename, (int)st.st_size, hdr_len, dnload.data_len);
445
446         return 0;
447 }
448
449 static void hexdump(const uint8_t *data, unsigned int len)
450 {
451         int n;
452
453         for (n=0; n < len; n++)
454                 printf("%02x ", data[n]);
455         printf(" ");
456         for (n=0; n < len; n++)
457                 if (isprint(data[n]))
458                         putchar(data[n]);
459                 else
460                         putchar('.');
461         printf("\n");
462 }
463
464 static int romload_prepare_block(void)
465 {
466         int i;
467
468         int block_checksum = 5;
469         int remaining_bytes;
470         int fill_bytes;
471         uint8_t *block_data;
472         uint32_t block_address;
473
474         dnload.block_len = ROMLOAD_BLOCK_HDR_LEN + dnload.block_payload_size;
475
476         /* if first block, allocate memory */
477         if (!dnload.block_number) {
478                 dnload.block = malloc(dnload.block_len);
479                 if (!dnload.block) {
480                         fprintf(stderr, "No memory\n");
481                         return -ENOMEM;
482                 }
483                 dnload.romload_dl_checksum = 0;
484                 /* initialize write pointer to start of data */
485                 dnload.write_ptr = dnload.data;
486         }
487
488         block_address = ROMLOAD_ADDRESS +
489                         (dnload.block_number * dnload.block_payload_size);
490
491         /* prepare our block header (10 bytes) */
492         memcpy(dnload.block, romload_write_cmd, sizeof(romload_write_cmd));
493         dnload.block[2] = 0x01; /* block index */
494         /* should normally be the block number, but hangs when sending !0x01 */
495         dnload.block[3] = 0x01; /* dnload.block_number+1 */
496         dnload.block[4] = (dnload.block_payload_size >> 8) & 0xff;
497         dnload.block[5] = dnload.block_payload_size & 0xff;
498         dnload.block[6] = (block_address >> 24) & 0xff;
499         dnload.block[7] = (block_address >> 16) & 0xff;
500         dnload.block[8] = (block_address >> 8) & 0xff;
501         dnload.block[9] = block_address & 0xff;
502
503         block_data = dnload.block + ROMLOAD_BLOCK_HDR_LEN;
504         dnload.write_ptr = dnload.data + 2 +
505                         (dnload.block_payload_size * dnload.block_number);
506
507         remaining_bytes = dnload.data_len - 3 -
508                         (dnload.block_payload_size * dnload.block_number);
509
510         memcpy(block_data, dnload.write_ptr, dnload.block_payload_size);
511
512         if (remaining_bytes <= dnload.block_payload_size) {
513                 fill_bytes = (dnload.block_payload_size - remaining_bytes);
514                 printf("Preparing the last block, filling %i bytes,",
515                         fill_bytes);
516                 memset(block_data + remaining_bytes, 0x00, fill_bytes);
517                 dnload.romload_state = SENDING_LAST_BLOCK;
518         } else {
519                         dnload.romload_state = SENDING_BLOCKS;
520                         printf("Preparing block %i,", dnload.block_number+1);
521         }
522
523         /* block checksum is lsb of ~(5 + block_size_lsb +  all bytes of
524          * block_address + all data bytes) */
525         for (i = 5; i < ROMLOAD_BLOCK_HDR_LEN + dnload.block_payload_size; i++)
526                 block_checksum += dnload.block[i];
527
528         /* checksum is lsb of ~(sum of LSBs of all block checksums) */
529         printf(" block checksum is 0x%02x \n", ~(block_checksum) & 0xff);
530         dnload.romload_dl_checksum += ~(block_checksum) & 0xff;
531
532         /* initialize block pointer to start of block */
533         dnload.block_ptr = dnload.block;
534
535         dnload.block_number++;
536         dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
537         return 0;
538 }
539
540 static int mtk_prepare_block(void)
541 {
542         int rc, i;
543
544         int remaining_bytes;
545         int fill_bytes;
546         uint8_t *block_data;
547         uint8_t tmp_byteswap;
548         uint32_t tmp_size;
549
550         dnload.block_len = MTK_BLOCK_SIZE;
551         dnload.echo_bytecount = 0;
552
553         /* if first block, allocate memory */
554         if (!dnload.block_number) {
555                 dnload.block = malloc(dnload.block_len);
556                 if (!dnload.block) {
557                         fprintf(stderr, "No memory\n");
558                         return -ENOMEM;
559                 }
560
561                 /* calculate the number of blocks we need to send */
562                 dnload.block_count = (dnload.data_len-3) / MTK_BLOCK_SIZE;
563                 /* add one more block if no multiple of blocksize */
564                 if((dnload.data_len-3) % MTK_BLOCK_SIZE)
565                         dnload.block_count++;
566
567                 /* divide by 2, since we have to tell the mtk loader the size
568                  * as count of uint16 (odd transfer sizes are not possible) */
569                 tmp_size = (dnload.block_count * MTK_BLOCK_SIZE)/2;
570                 dnload.mtk_send_size[0] = (tmp_size >> 24) & 0xff;
571                 dnload.mtk_send_size[1] = (tmp_size >> 16) & 0xff;
572                 dnload.mtk_send_size[2] = (tmp_size >> 8) & 0xff;
573                 dnload.mtk_send_size[3] = tmp_size & 0xff;
574
575                 /* initialize write pointer to start of data */
576                 dnload.write_ptr = dnload.data;
577         }
578
579         block_data = dnload.block;
580         dnload.write_ptr = dnload.data + 2 +
581                         (dnload.block_len * dnload.block_number);
582
583         remaining_bytes = dnload.data_len - 3 -
584                         (dnload.block_len * dnload.block_number);
585
586         memcpy(block_data, dnload.write_ptr, MTK_BLOCK_SIZE);
587
588         if (remaining_bytes <= MTK_BLOCK_SIZE) {
589                 fill_bytes = (MTK_BLOCK_SIZE - remaining_bytes);
590                 printf("Preparing the last block, filling %i bytes\n",
591                         fill_bytes);
592                 memset(block_data + remaining_bytes, 0x00, fill_bytes);
593                 dnload.romload_state = SENDING_LAST_BLOCK;
594         } else {
595                 dnload.romload_state = SENDING_BLOCKS;
596                 printf("Preparing block %i\n", dnload.block_number+1);
597         }
598
599         /* for the mtk romloader we need to swap MSB <-> LSB */
600         for (i = 0; i < dnload.block_len; i += 2) {
601                 tmp_byteswap = dnload.block[i];
602                 dnload.block[i] = dnload.block[i+1];
603                 dnload.block[i+1] = tmp_byteswap;
604         }
605
606         /* initialize block pointer to start of block */
607         dnload.block_ptr = dnload.block;
608
609         dnload.block_number++;
610         return rc;
611 }
612
613 static int handle_write_block(void)
614 {
615         int bytes_left, write_len, rc;
616
617         printf("handle_write_block(): ");
618
619         if (dnload.block_ptr >= dnload.block + dnload.block_len) {
620                 printf("Block %i finished\n", dnload.block_number);
621                 dnload.write_ptr = dnload.data;
622                 dnload.serial_fd.when &= ~BSC_FD_WRITE;
623                 if (dnload.romload_state == SENDING_LAST_BLOCK) {
624                         dnload.romload_state = LAST_BLOCK_SENT;
625                         printf("Finished, sent %i blocks in total\n",
626                                 dnload.block_number);
627                 } else {
628                         dnload.romload_state = WAITING_BLOCK_ACK;
629                 }
630
631                 return 0;
632         }
633
634         /* try to write a maximum of block_len bytes */
635         bytes_left = (dnload.block + dnload.block_len) - dnload.block_ptr;
636         write_len = dnload.block_len;
637         if (bytes_left < dnload.block_len)
638                 write_len = bytes_left;
639
640         rc = write(dnload.serial_fd.fd, dnload.block_ptr, write_len);
641         if (rc < 0) {
642                 perror("Error during write");
643                 return rc;
644         }
645
646         dnload.block_ptr += rc;
647
648         printf("%u bytes (%tu/%u)\n", rc, dnload.block_ptr - dnload.block,
649                 dnload.block_len);
650
651         return 0;
652 }
653
654 #define WRITE_BLOCK     4096
655
656 static int handle_write_dnload(void)
657 {
658         int bytes_left, write_len, rc;
659         uint8_t xor_init = 0x02;
660
661         printf("handle_write(): ");
662         if (dnload.write_ptr == dnload.data) {
663                 /* no bytes have been transferred yet */
664                 switch (dnload.mode) {
665                 case MODE_C155:
666                 case MODE_C140xor:
667                 case MODE_C123xor:
668                         rc = write(dnload.serial_fd.fd, &xor_init, 1);
669                         break;
670                 default:
671                         break;
672                 }
673         } else if (dnload.write_ptr >= dnload.data + dnload.data_len) { 
674                 printf("finished\n");
675                 dnload.write_ptr = dnload.data;
676                 dnload.serial_fd.when &= ~BSC_FD_WRITE;
677                 return 1;
678         }
679
680         /* try to write a maximum of WRITE_BLOCK bytes */
681         bytes_left = (dnload.data + dnload.data_len) - dnload.write_ptr;
682         write_len = WRITE_BLOCK;
683         if (bytes_left < WRITE_BLOCK)
684                 write_len = bytes_left;
685
686         rc = write(dnload.serial_fd.fd, dnload.write_ptr, write_len);
687         if (rc < 0) {
688                 perror("Error during write");
689                 return rc;
690         }
691
692         dnload.write_ptr += rc;
693
694         printf("%u bytes (%tu/%u)\n", rc, dnload.write_ptr - dnload.data,
695                 dnload.data_len);
696
697         return 0;
698 }
699
700 static int handle_sercomm_write(void)
701 {
702         uint8_t c;
703
704         if (sercomm_drv_pull(&c) != 0) {
705                 if (write(dnload.serial_fd.fd, &c, 1) != 1)
706                         perror("short write");
707                 } else
708                         dnload.serial_fd.when &= ~BSC_FD_WRITE;
709
710         return 0;
711 }
712
713 static int handle_write(void)
714 {
715         /* TODO: simplify this again (global state: downloading, sercomm) */
716         switch (dnload.mode) {
717         case MODE_ROMLOAD:
718                 switch (dnload.romload_state) {
719                 case SENDING_BLOCKS:
720                 case SENDING_LAST_BLOCK:
721                         return handle_write_block();
722                 default:
723                         return handle_sercomm_write();
724                 }
725                 break;
726         case MODE_MTK:
727                 switch (dnload.mtk_state) {
728                 case MTK_SENDING_BLOCKS:
729                         return handle_write_block();
730                 default:
731                         return handle_sercomm_write();
732                 }
733                 break;
734         default:
735                 switch (dnload.state) {
736                 case DOWNLOADING:
737                         return handle_write_dnload();
738                 default:
739                         return handle_sercomm_write();
740                 }
741         }
742
743         return 0;
744 }
745
746 static uint8_t buffer[sizeof(phone_prompt1)];
747 static uint8_t *bufptr = buffer;
748
749 static void hdlc_send_to_phone(uint8_t dlci, uint8_t *data, int len)
750 {
751         struct msgb *msg;
752         uint8_t *dest;
753
754         if(dnload.dump_tx) {
755                 printf("hdlc_send(dlci=%u): ", dlci);
756                 hexdump(data, len);
757         }
758
759         if (len > 512) {
760                 fprintf(stderr, "Too much data to send. %u\n", len);
761                 return;
762         }
763
764         /* push the message into the stack */
765         msg = sercomm_alloc_msgb(512);
766         if (!msg) {
767                 fprintf(stderr, "Failed to create data for the frame.\n");
768                 return;
769         }
770
771         /* copy the data */
772         dest = msgb_put(msg, len);
773         memcpy(dest, data, len);
774
775         sercomm_sendmsg(dlci, msg);
776
777         dnload.serial_fd.when |= BSC_FD_WRITE;
778 }
779
780 static void hdlc_console_cb(uint8_t dlci, struct msgb *msg)
781 {
782         int rc;
783
784         rc = write(1, msg->data, msg->len);
785         msgb_free(msg);
786 }
787
788 static void hdlc_tool_cb(uint8_t dlci, struct msgb *msg)
789 {
790         struct tool_server *srv = tool_server_for_dlci[dlci];
791
792         if(dnload.dump_rx) {
793                 printf("hdlc_recv(dlci=%u): ", dlci);
794                 hexdump(msg->data, msg->len);
795         }
796
797         if(srv) {
798                 struct tool_connection *con;
799                 uint16_t *len;
800
801                 len = (uint16_t *) msgb_push(msg, 2);
802                 *len = htons(msg->len - sizeof(*len));
803
804                 llist_for_each_entry(con, &srv->connections, entry) {
805                         if (write(con->fd.fd, msg->data, msg->len) != msg->len) {
806                                 fprintf(stderr,
807                                         "Failed to write msg to the socket..\n");
808                                 continue;
809                         }
810                 }
811         }
812
813         msgb_free(msg);
814 }
815
816 static int handle_buffer(int buf_used_len)
817 {
818         int nbytes, buf_left, i;
819
820         buf_left = buf_used_len - (bufptr - buffer);
821         if (buf_left <= 0) {
822                 memmove(buffer, buffer+1, buf_used_len-1);
823                 bufptr -= 1;
824                 buf_left = 1;
825         }
826
827         nbytes = read(dnload.serial_fd.fd, bufptr, buf_left);
828         if (nbytes <= 0)
829                 return nbytes;
830
831         if (!dnload.expect_hdlc) {
832                 printf("got %i bytes from modem, ", nbytes);
833                 printf("data looks like: ");
834                 hexdump(bufptr, nbytes);
835         } else {
836                 for (i = 0; i < nbytes; ++i)
837                         if (sercomm_drv_rx_char(bufptr[i]) == 0)
838                                 printf("Dropping sample '%c'\n", bufptr[i]);
839         }
840
841         return nbytes;
842 }
843
844 /* Compal ramloader */
845 static int handle_read(void)
846 {
847         int rc, nbytes;
848
849         nbytes = handle_buffer(sizeof(buffer));
850         if (nbytes <= 0)
851                 return nbytes;
852
853         if (!memcmp(buffer, phone_prompt1, sizeof(phone_prompt1))) {
854                 printf("Received PROMPT1 from phone, responding with CMD\n");
855                 dnload.expect_hdlc = 0;
856                 dnload.state = WAITING_PROMPT2;
857                 if(dnload.filename) {
858                         rc = write(dnload.serial_fd.fd, dnload_cmd, sizeof(dnload_cmd));
859
860                         /* re-read file */
861                         rc = read_file(dnload.filename);
862                         if (rc < 0) {
863                                 fprintf(stderr, "read_file(%s) failed with %d\n",
864                                                 dnload.filename, rc);
865                                 exit(1);
866                         }
867                 }
868         } else if (!memcmp(buffer, phone_prompt2, sizeof(phone_prompt2))) {
869                 printf("Received PROMPT2 from phone, starting download\n");
870                 dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
871                 dnload.state = DOWNLOADING;
872         } else if (!memcmp(buffer, phone_ack, sizeof(phone_ack))) {
873                 printf("Received DOWNLOAD ACK from phone, your code is"
874                         " running now!\n");
875                 dnload.serial_fd.when = BSC_FD_READ;
876                 dnload.state = WAITING_PROMPT1;
877                 dnload.write_ptr = dnload.data;
878                 dnload.expect_hdlc = 1;
879
880                 /* check for romloader chainloading mode used as a workaround
881                  * for the magic on the C139/C140 and J100i */
882                 if (dnload.chainload_filename != NULL) {
883                         printf("Enabled Compal ramloader -> Calypso romloader"
884                                 " chainloading mode\n");
885                         bufptr = buffer;
886                         dnload.filename = dnload.chainload_filename;
887                         dnload.mode = MODE_ROMLOAD;
888                         serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
889                         tick_timer.cb = &beacon_timer_cb;
890                         tick_timer.data = &tick_timer;
891                         bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
892                 }
893         } else if (!memcmp(buffer, phone_nack, sizeof(phone_nack))) {
894                 printf("Received DOWNLOAD NACK from phone, something went"
895                         " wrong :(\n");
896                 dnload.serial_fd.when = BSC_FD_READ;
897                 dnload.state = WAITING_PROMPT1;
898                 dnload.write_ptr = dnload.data;
899         } else if (!memcmp(buffer, phone_nack_magic, sizeof(phone_nack_magic))) {
900                 printf("Received MAGIC NACK from phone, you need to"
901                         " have \"1003\" at 0x803ce0\n");
902                 dnload.serial_fd.when = BSC_FD_READ;
903                 dnload.state = WAITING_PROMPT1;
904                 dnload.write_ptr = dnload.data;
905         } else if (!memcmp(buffer, ftmtool, sizeof(ftmtool))) {
906                 printf("Received FTMTOOL from phone, ramloader has aborted\n");
907                 dnload.serial_fd.when = BSC_FD_READ;
908                 dnload.state = WAITING_PROMPT1;
909                 dnload.write_ptr = dnload.data;
910         }
911         bufptr += nbytes;
912
913         return nbytes;
914 }
915
916 /* "Calypso non-secure romloader" */
917 static int handle_read_romload(void)
918 {
919         int rc, nbytes, buf_used_len;
920
921         /* virtually limit buffer length for romloader, since responses
922          * are shorter and vary in length */
923
924         switch (dnload.romload_state) {
925         case WAITING_PARAM_ACK:
926                 buf_used_len = 4;       /* ">p" + uint16_t len */
927                 break;
928         case WAITING_CHECKSUM_ACK:
929                 buf_used_len = 3;       /* ">c" + uint8_t checksum */
930                 break;
931         case FINISHED:
932                 buf_used_len = sizeof(buffer);
933                 break;
934         default:
935                 buf_used_len = 2;       /* ">*" */
936         }
937
938         nbytes = handle_buffer(buf_used_len);
939         if (nbytes <= 0)
940                 return nbytes;
941
942         switch (dnload.romload_state) {
943         case WAITING_IDENTIFICATION:
944                 if (memcmp(buffer, romload_ident_ack,
945                             sizeof(romload_ident_ack)))
946                         break;
947
948                 printf("Received ident ack from phone, sending "
949                         "parameter sequence\n");
950                 dnload.expect_hdlc = 1;
951                 dnload.romload_state = WAITING_PARAM_ACK;
952                 rc = write(dnload.serial_fd.fd, romload_param,
953                            sizeof(romload_param));
954                 /* re-read file */
955                 rc = read_file(dnload.filename);
956                 if (rc < 0) {
957                         fprintf(stderr, "read_file(%s) failed with %d\n",
958                                 dnload.filename, rc);
959                         exit(1);
960                 }
961                 break;
962         case WAITING_PARAM_ACK:
963                 if (memcmp(buffer, romload_param_ack,
964                             sizeof(romload_param_ack)))
965                         break;
966
967                 printf("Received parameter ack from phone, "
968                         "starting download\n");
969                 serial_set_baudrate(ROMLOAD_DL_BAUDRATE);
970
971                 /* using the max blocksize the phone tells us */
972                 dnload.block_payload_size = ((buffer[3] << 8) + buffer[2]);
973                 printf("Used blocksize for download is %i bytes\n",
974                         dnload.block_payload_size);
975                 dnload.block_payload_size -= ROMLOAD_BLOCK_HDR_LEN;
976                 dnload.romload_state = SENDING_BLOCKS;
977                 dnload.block_number = 0;
978                 romload_prepare_block();
979                 bufptr -= 2;
980                 break;
981         case WAITING_BLOCK_ACK:
982         case LAST_BLOCK_SENT:
983                 if (!memcmp(buffer, romload_block_ack,
984                             sizeof(romload_block_ack))) {
985                         printf("Received block ack from phone\n");
986                         if (dnload.romload_state == LAST_BLOCK_SENT) {
987                                 /* send the checksum */
988                                 uint8_t final_checksum =
989                                         (~(dnload.romload_dl_checksum) & 0xff);
990                                 printf("Sending checksum: 0x%02x \n",
991                                         final_checksum);
992                                 rc = write(dnload.serial_fd.fd,
993                                            romload_checksum_cmd,
994                                            sizeof(romload_checksum_cmd));
995                                 rc = write(dnload.serial_fd.fd,
996                                            &final_checksum, 1);
997                                 dnload.romload_state = WAITING_CHECKSUM_ACK;
998                         } else
999                                 romload_prepare_block();
1000                 } else if (!memcmp(buffer, romload_block_nack,
1001                                    sizeof(romload_block_nack))) {
1002                         printf("Received block nack from phone, "
1003                                 "something went wrong, aborting\n");
1004                         serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
1005                         dnload.romload_state = WAITING_IDENTIFICATION;
1006                         bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
1007                 }
1008                 break;
1009         case WAITING_CHECKSUM_ACK:
1010                 if (!memcmp(buffer, romload_checksum_ack,
1011                             sizeof(romload_checksum_ack))) {
1012                         printf("Checksum on phone side matches, "
1013                                 "let's branch to your code\n");
1014                         printf("Branching to 0x%08x\n", ROMLOAD_ADDRESS);
1015
1016                         rc = write(dnload.serial_fd.fd, romload_branch_cmd,
1017                                    sizeof(romload_branch_cmd));
1018                         rc = write(dnload.serial_fd.fd, &dnload.load_address,
1019                                    sizeof(dnload.load_address));
1020                         dnload.romload_state = WAITING_BRANCH_ACK;
1021                         bufptr -= 1;
1022                 } else if (!memcmp(buffer, romload_checksum_nack,
1023                                    sizeof(romload_checksum_nack))) {
1024                         printf("Checksum on phone side (0x%02x) doesn't "
1025                                 "match ours, aborting\n", ~buffer[2]);
1026                         serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
1027                         dnload.romload_state = WAITING_IDENTIFICATION;
1028                         bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
1029                         bufptr -= 1;
1030                 }
1031                 break;
1032         case WAITING_BRANCH_ACK:
1033                 if (!memcmp(buffer, romload_branch_ack,
1034                             sizeof(romload_branch_ack))) {
1035                         printf("Received branch ack, your code is running now!\n");
1036                         dnload.serial_fd.when = BSC_FD_READ;
1037                         dnload.romload_state = FINISHED;
1038                         dnload.write_ptr = dnload.data;
1039                         dnload.expect_hdlc = 1;
1040                 } else if (!memcmp(buffer, romload_branch_nack,
1041                            sizeof(romload_branch_nack))) {
1042                         printf("Received branch nack, aborting\n");
1043                         serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
1044                         dnload.romload_state = WAITING_IDENTIFICATION;
1045                         bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
1046                 }
1047                 break;
1048         default:
1049                 break;
1050         }
1051
1052         bufptr += nbytes;
1053         return nbytes;
1054 }
1055
1056 /* MTK romloader */
1057 static int handle_read_mtk(void)
1058 {
1059         int rc, nbytes, buf_used_len;
1060
1061         switch (dnload.mtk_state) {
1062         case MTK_WAIT_ADDR_ACK:
1063         case MTK_WAIT_SIZE_ACK:
1064         case MTK_WAIT_BRANCH_ADDR_ACK:
1065                 buf_used_len = 4;
1066                 break;
1067         case MTK_FINISHED:
1068                 buf_used_len = sizeof(buffer);
1069                 break;
1070         default:
1071                 buf_used_len = 1;
1072         }
1073
1074         nbytes = handle_buffer(buf_used_len);
1075         if (nbytes <= 0)
1076                 return nbytes;
1077
1078         switch (dnload.mtk_state) {
1079         case MTK_INIT_1:
1080                 if (!(buffer[0] == mtk_init_resp[0]))
1081                         break;
1082                 dnload.mtk_state = MTK_INIT_2;
1083                 printf("Received init magic byte 1\n");
1084                 rc = write(dnload.serial_fd.fd, &mtk_init_cmd[1], 1);
1085                 break;
1086         case MTK_INIT_2:
1087                 if (!(buffer[0] == mtk_init_resp[1]))
1088                         break;
1089                 dnload.mtk_state = MTK_INIT_3;
1090                 printf("Received init magic byte 2\n");
1091                 rc = write(dnload.serial_fd.fd, &mtk_init_cmd[2], 1);
1092                 break;
1093         case MTK_INIT_3:
1094                 if (!(buffer[0] == mtk_init_resp[2]))
1095                         break;
1096                 dnload.mtk_state = MTK_INIT_4;
1097                 printf("Received init magic byte 3\n");
1098                 rc = write(dnload.serial_fd.fd, &mtk_init_cmd[3], 1);
1099                 break;
1100         case MTK_INIT_4:
1101                 if (!(buffer[0] == mtk_init_resp[3]))
1102                         break;
1103                 dnload.mtk_state = MTK_WAIT_WRITE_ACK;
1104                 printf("Received init magic byte 4, requesting write\n");
1105                 rc = write(dnload.serial_fd.fd, &mtk_command[0], 1);
1106                 break;
1107         case MTK_WAIT_WRITE_ACK:
1108                 if (!(buffer[0] == mtk_command[0]))
1109                         break;
1110                 dnload.mtk_state = MTK_WAIT_ADDR_ACK;
1111                 printf("Received write ack, sending load address\n");
1112
1113                 rc = write(dnload.serial_fd.fd, &dnload.load_address,
1114                            sizeof(dnload.load_address));
1115                 break;
1116         case MTK_WAIT_ADDR_ACK:
1117                 if (memcmp(buffer, dnload.load_address,
1118                             sizeof(dnload.load_address)))
1119                         break;
1120                 printf("Received address ack from phone, sending loadsize\n");
1121                 /* re-read file */
1122                 rc = read_file(dnload.filename);
1123                 if (rc < 0) {
1124                         fprintf(stderr, "read_file(%s) failed with %d\n",
1125                                 dnload.filename, rc);
1126                         exit(1);
1127                 }
1128                 dnload.block_number = 0;
1129                 mtk_prepare_block();
1130                 dnload.mtk_state = MTK_WAIT_SIZE_ACK;
1131                 rc = write(dnload.serial_fd.fd, &dnload.mtk_send_size,
1132                            sizeof(dnload.mtk_send_size));
1133                 break;
1134         case MTK_WAIT_SIZE_ACK:
1135                 if (memcmp(buffer, dnload.mtk_send_size,
1136                             sizeof(dnload.mtk_send_size)))
1137                         break;
1138                 printf("Received size ack\n");
1139                 dnload.expect_hdlc = 1;
1140                 dnload.mtk_state = MTK_SENDING_BLOCKS;
1141                 dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
1142                 bufptr -= 3;
1143                 break;
1144         case MTK_SENDING_BLOCKS:
1145                 if (!(buffer[0] == dnload.block[dnload.echo_bytecount]))
1146                         printf("Warning: Byte %i of Block %i doesn't match,"
1147                                 " check your serial connection!\n",
1148                                 dnload.echo_bytecount, dnload.block_number);
1149                 dnload.echo_bytecount++;
1150
1151                 if ((dnload.echo_bytecount+1) > MTK_BLOCK_SIZE) {
1152                         if ( dnload.block_number == dnload.block_count) {
1153                                 rc = write(dnload.serial_fd.fd,
1154                                            &mtk_command[3], 1);
1155                                 printf("Sending branch command\n");
1156                                 dnload.expect_hdlc = 0;
1157                                 dnload.mtk_state = MTK_WAIT_BRANCH_CMD_ACK;
1158                                 break;
1159                         }
1160                         printf("Received Block %i preparing next block\n",
1161                                 dnload.block_number);
1162                         mtk_prepare_block();
1163                         dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
1164                 }
1165                 break;
1166         case MTK_WAIT_BRANCH_CMD_ACK:
1167                 if (!(buffer[0] == mtk_command[3]))
1168                         break;
1169                 dnload.mtk_state = MTK_WAIT_BRANCH_ADDR_ACK;
1170                 printf("Received branch command ack, sending address\n");
1171
1172                 rc = write(dnload.serial_fd.fd, &dnload.load_address,
1173                            sizeof(dnload.load_address));
1174                 break;
1175         case MTK_WAIT_BRANCH_ADDR_ACK:
1176                 if (memcmp(buffer, dnload.load_address,
1177                             sizeof(dnload.load_address)))
1178                         break;
1179                 printf("Received branch address ack, code should run now\n");
1180                 serial_set_baudrate(MODEM_BAUDRATE);
1181                 dnload.serial_fd.when = BSC_FD_READ;
1182                 dnload.mtk_state = MTK_FINISHED;
1183                 dnload.write_ptr = dnload.data;
1184                 dnload.expect_hdlc = 1;
1185                 break;
1186         default:
1187                 break;
1188         }
1189
1190         bufptr += nbytes;
1191         return nbytes;
1192 }
1193
1194 static int serial_read(struct bsc_fd *fd, unsigned int flags)
1195 {
1196         int rc;
1197         if (flags & BSC_FD_READ) {
1198                 switch (dnload.mode) {
1199                         case MODE_ROMLOAD:
1200                                 rc = handle_read_romload();
1201                                 break;
1202                         case MODE_MTK:
1203                                 rc = handle_read_mtk();
1204                                 break;
1205                         default:
1206                                 rc = handle_read();
1207                                 break;
1208                 }
1209                 if (rc == 0)
1210                         exit(2);
1211         }
1212
1213         if (flags & BSC_FD_WRITE) {
1214                 rc = handle_write();
1215                 if (rc == 1)
1216                         dnload.state = WAITING_PROMPT1;
1217         }
1218         return 0;
1219 }
1220
1221 static int parse_mode(const char *arg)
1222 {
1223         if (!strcasecmp(arg, "c123"))
1224                 return MODE_C123;
1225         else if (!strcasecmp(arg, "c123xor"))
1226                 return MODE_C123xor;
1227         else if (!strcasecmp(arg, "c140"))
1228                 return MODE_C140;
1229         else if (!strcasecmp(arg, "c140xor"))
1230                 return MODE_C140xor;
1231         else if (!strcasecmp(arg, "c155"))
1232                 return MODE_C155;
1233         else if (!strcasecmp(arg, "romload"))
1234                 return MODE_ROMLOAD;
1235         else if (!strcasecmp(arg, "mtk"))
1236                 return MODE_MTK;
1237
1238         return -1;
1239 }
1240
1241 #define HELP_TEXT \
1242         "[ -v | -h ] [ -d [t][r] ] [ -p /dev/ttyXXXX ]\n" \
1243         "\t\t [ -s /tmp/osmocom_l2 ]\n" \
1244         "\t\t [ -l /tmp/osmocom_loader ]\n" \
1245         "\t\t [ -m {c123,c123xor,c140,c140xor,c155,romload,mtk} ]\n" \
1246         "\t\t [ -c /to-be-chainloaded-file.bin ]\n" \
1247         "\t\t  file.bin\n\n" \
1248         "* Open serial port /dev/ttyXXXX (connected to your phone)\n" \
1249         "* Perform handshaking with the ramloader in the phone\n" \
1250         "* Download file.bin to the attached phone (base address 0x00800100)\n"
1251
1252 static int usage(const char *name)
1253 {
1254         printf("Usage: %s ", name);
1255         printf(HELP_TEXT);
1256         exit(2);
1257 }
1258
1259 static int version(const char *name)
1260 {
1261         printf("%s version %s\n", name, PACKAGE_VERSION);
1262         exit(2);
1263 }
1264
1265 static int un_tool_read(struct bsc_fd *fd, unsigned int flags)
1266 {
1267         int rc, c;
1268         uint16_t length = 0xffff;
1269         uint8_t buf[4096];
1270         struct tool_connection *con = (struct tool_connection *)fd->data;
1271
1272         c = 0;
1273         while(c < 2) {
1274                 rc = read(fd->fd, &buf + c, 2 - c);
1275                 if(rc == 0) {
1276                         // disconnect
1277                         goto close;
1278                 }
1279                 if(rc < 0) {
1280                         if(errno == EAGAIN) {
1281                                 continue;
1282                         }
1283                         fprintf(stderr, "Err from socket: %s\n", strerror(errno));
1284                         goto close;
1285                 }
1286                 c += rc;
1287         }
1288
1289         length = ntohs(*(uint16_t*)buf);
1290
1291         c = 0;
1292         while(c < length) {
1293                 rc = read(fd->fd, &buf + c, length - c);
1294                 if(rc == 0) {
1295                         // disconnect
1296                         goto close;
1297                 }
1298                 if(rc < 0) {
1299                         if(errno == EAGAIN) {
1300                                 continue;
1301                         }
1302                         fprintf(stderr, "Err from socket: %s\n", strerror(errno));
1303                         goto close;
1304                 }
1305                 c += rc;
1306         }
1307
1308         hdlc_send_to_phone(con->server->dlci, buf, length);
1309
1310         return 0;
1311 close:
1312
1313         close(fd->fd);
1314         bsc_unregister_fd(fd);
1315         llist_del(&con->entry);
1316         talloc_free(con);
1317         return -1;
1318 }
1319
1320 /* accept a new connection */
1321 static int tool_accept(struct bsc_fd *fd, unsigned int flags)
1322 {
1323         struct tool_server *srv = (struct tool_server *)fd->data;
1324         struct tool_connection *con;
1325         struct sockaddr_un un_addr;
1326         socklen_t len;
1327         int rc;
1328
1329         len = sizeof(un_addr);
1330         rc = accept(fd->fd, (struct sockaddr *) &un_addr, &len);
1331         if (rc < 0) {
1332                 fprintf(stderr, "Failed to accept a new connection.\n");
1333                 return -1;
1334         }
1335
1336         con = talloc_zero(NULL, struct tool_connection);
1337         if (!con) {
1338                 fprintf(stderr, "Failed to create tool connection.\n");
1339                 return -1;
1340         }
1341
1342         con->server = srv;
1343
1344         con->fd.fd = rc;
1345         con->fd.when = BSC_FD_READ;
1346         con->fd.cb = un_tool_read;
1347         con->fd.data = con;
1348         if (bsc_register_fd(&con->fd) != 0) {
1349                 fprintf(stderr, "Failed to register the fd.\n");
1350                 return -1;
1351         }
1352
1353         llist_add(&con->entry, &srv->connections);
1354         return 0;
1355 }
1356
1357 /*
1358  * Register and start a tool server
1359  */
1360 static int register_tool_server(struct tool_server *ts,
1361                                 const char *path,
1362                                 uint8_t dlci)
1363 {
1364         struct bsc_fd *bfd = &ts->bfd;
1365         struct sockaddr_un local;
1366         unsigned int namelen;
1367         int rc;
1368
1369         bfd->fd = socket(AF_UNIX, SOCK_STREAM, 0);
1370
1371         if (bfd->fd < 0) {
1372                 fprintf(stderr, "Failed to create Unix Domain Socket.\n");
1373                 return -1;
1374         }
1375
1376         local.sun_family = AF_UNIX;
1377         strncpy(local.sun_path, path, sizeof(local.sun_path));
1378         local.sun_path[sizeof(local.sun_path) - 1] = '\0';
1379         unlink(local.sun_path);
1380
1381         /* we use the same magic that X11 uses in Xtranssock.c for
1382          * calculating the proper length of the sockaddr */
1383 #if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
1384         local.sun_len = strlen(local.sun_path);
1385 #endif
1386 #if defined(BSD44SOCKETS) || defined(SUN_LEN)
1387         namelen = SUN_LEN(&local);
1388 #else
1389         namelen = strlen(local.sun_path) +
1390                   offsetof(struct sockaddr_un, sun_path);
1391 #endif
1392
1393         rc = bind(bfd->fd, (struct sockaddr *) &local, namelen);
1394         if (rc != 0) {
1395                 fprintf(stderr, "Failed to bind the unix domain socket. '%s'\n",
1396                         local.sun_path);
1397                 return -1;
1398         }
1399
1400         if (listen(bfd->fd, 0) != 0) {
1401                 fprintf(stderr, "Failed to listen.\n");
1402                 return -1;
1403         }
1404
1405         bfd->when = BSC_FD_READ;
1406         bfd->cb = tool_accept;
1407         bfd->data = ts;
1408
1409         ts->dlci = dlci;
1410         INIT_LLIST_HEAD(&ts->connections);
1411
1412         tool_server_for_dlci[dlci] = ts;
1413
1414         sercomm_register_rx_cb(dlci, hdlc_tool_cb);
1415
1416         if (bsc_register_fd(bfd) != 0) {
1417                 fprintf(stderr, "Failed to register the bfd.\n");
1418                 return -1;
1419         }
1420
1421         return 0;
1422 }
1423
1424 extern void hdlc_tpudbg_cb(uint8_t dlci, struct msgb *msg);
1425
1426 void parse_debug(const char *str)
1427 {
1428         while(*str) {
1429                 switch(*str) {
1430                 case 't':
1431                         dnload.dump_tx = 1;
1432                         break;
1433                 case 'r':
1434                         dnload.dump_rx = 1;
1435                         break;
1436                 default:
1437                         printf("Unknown debug flag %c\n", *str);
1438                         abort();
1439                         break;
1440                 }
1441                 str++;
1442         }
1443 }
1444
1445 int main(int argc, char **argv)
1446 {
1447         int opt, flags;
1448         uint32_t tmp_load_address = ROMLOAD_ADDRESS;
1449         const char *serial_dev = "/dev/ttyUSB1";
1450         const char *layer2_un_path = "/tmp/osmocom_l2";
1451         const char *loader_un_path = "/tmp/osmocom_loader";
1452
1453         dnload.mode = MODE_C123;
1454         dnload.chainload_filename = NULL;
1455
1456         while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:v")) != -1) {
1457                 switch (opt) {
1458                 case 'p':
1459                         serial_dev = optarg;
1460                         break;
1461                 case 'm':
1462                         dnload.mode = parse_mode(optarg);
1463                         if (dnload.mode < 0)
1464                                 usage(argv[0]);
1465                         break;
1466                 case 's':
1467                         layer2_un_path = optarg;
1468                         break;
1469                 case 'l':
1470                         loader_un_path = optarg;
1471                         break;
1472                 case 'v':
1473                         version(argv[0]);
1474                         break;
1475                 case 'd':
1476                         parse_debug(optarg);
1477                         break;
1478                 case 'c':
1479                         dnload.chainload_filename = optarg;
1480                         break;
1481                 case 'h':
1482                 default:
1483                         usage(argv[0]);
1484                         break;
1485                 }
1486         }
1487
1488         if (argc <= optind) {
1489                 dnload.filename = NULL;
1490         } else {
1491                 dnload.filename = argv[optind];
1492         }
1493
1494         dnload.serial_fd.fd = serial_init(serial_dev);
1495         if (dnload.serial_fd.fd < 0) {
1496                 fprintf(stderr, "Cannot open serial device %s\n", serial_dev);
1497                 exit(1);
1498         }
1499
1500         if (bsc_register_fd(&dnload.serial_fd) != 0) {
1501                 fprintf(stderr, "Failed to register the serial.\n");
1502                 exit(1);
1503         }
1504
1505         /* Set serial socket to non-blocking mode of operation */
1506         flags = fcntl(dnload.serial_fd.fd, F_GETFL);
1507         flags |= O_NONBLOCK;
1508         fcntl(dnload.serial_fd.fd, F_SETFL, flags);
1509
1510         dnload.serial_fd.when = BSC_FD_READ;
1511         dnload.serial_fd.cb = serial_read;
1512
1513         /* initialize the HDLC layer */
1514         sercomm_init();
1515         sercomm_register_rx_cb(SC_DLCI_CONSOLE, hdlc_console_cb);
1516         sercomm_register_rx_cb(SC_DLCI_DEBUG, hdlc_tpudbg_cb);
1517
1518         /* unix domain socket handling */
1519         if (register_tool_server(&dnload.layer2_server, layer2_un_path,
1520                                  SC_DLCI_L1A_L23) != 0)
1521                 exit(1);
1522
1523         if (register_tool_server(&dnload.loader_server, loader_un_path,
1524                                  SC_DLCI_LOADER) != 0)
1525                 exit(1);
1526
1527         /* if in romload mode, start our beacon timer */
1528         if (dnload.mode == MODE_ROMLOAD) {
1529                 tmp_load_address = ROMLOAD_ADDRESS;
1530                 serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
1531                 tick_timer.cb = &beacon_timer_cb;
1532                 tick_timer.data = &tick_timer;
1533                 bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
1534         }
1535         else if (dnload.mode == MODE_MTK) {
1536                 tmp_load_address = MTK_ADDRESS;
1537                 serial_set_baudrate(MTK_INIT_BAUDRATE);
1538                 tick_timer.cb = &mtk_timer_cb;
1539                 tick_timer.data = &tick_timer;
1540                 bsc_schedule_timer(&tick_timer, 0, BEACON_INTERVAL);
1541         }
1542
1543         dnload.load_address[0] = (tmp_load_address >> 24) & 0xff;
1544         dnload.load_address[1] = (tmp_load_address >> 16) & 0xff;
1545         dnload.load_address[2] = (tmp_load_address >> 8) & 0xff;
1546         dnload.load_address[3] = tmp_load_address & 0xff;
1547
1548         while (1)
1549                 bsc_select_main(0);
1550
1551         close(dnload.serial_fd.fd);
1552
1553         exit(0);
1554 }