]> CyberLeo.Net >> Repos - SourceForge/eyefi-config.git/blob - eyefi-config.c
Test implementation using mmap and msync(MS_INVALIDATE)
[SourceForge/eyefi-config.git] / eyefi-config.c
1 /*
2  * eyefi-config.c
3  *
4  * Copyright (C) 2008 Dave Hansen <dave@sr71.net>
5  *
6  * This software may be redistributed and/or modified under the terms of
7  * the GNU General Public License ("GPL") version 2 as published by the
8  * Free Software Foundation.
9  */
10
11 #include "eyefi-config.h"
12 #include <sys/mman.h>
13
14 int eyefi_debug_level = 1;
15
16 int eyefi_printf(const char *fmt, ...)
17 {
18         va_list args;
19         int r;
20
21         va_start(args, fmt);
22         r = vprintf(fmt, args);
23         va_end(args);
24
25         return r;
26 }
27  
28 static char *eyefi_file_name(enum eyefi_file file)
29 {
30         switch (file) {
31         case REQC: return "reqc";
32         case REQM: return "reqm";
33         case RSPC: return "rspc";
34         case RSPM: return "rspm";
35         }
36
37         return NULL;
38 }
39
40 char *eyefi_file_on(enum eyefi_file file, char *mnt)
41 {
42         char *filename = eyefi_file_name(file);
43         char *full = malloc(PATHNAME_MAX);
44         
45         if (!full)
46                 return NULL;
47
48         sprintf(&full[0], "%s/EyeFi/%s", mnt, filename);
49         debug_printf(4, "eyefile nr: %d on '%s' is: '%s'\n", file, mnt, &full[0]);
50         return full;
51 }
52
53 /*
54  * This lets us get away with a static allocation
55  * for the buffer.  We make it size*2 so that we're
56  * guaranteed to be able to get a "size" buffer
57  * aligned inside of the larger one.
58  */
59 static char unaligned_buf[EYEFI_BUF_SIZE*2];
60 static void *eyefi_buf;
61
62 void *eyefi_response(void)
63 {
64         return eyefi_buf;
65 }
66
67 void dumpbuf(const char *buffer, int bytesToWrite)
68 {
69     int i;
70     static char linebuf[500];
71
72     for (i=0; i < bytesToWrite; i += 16) {
73         char *tmpbuf = &linebuf[0];
74         unsigned long sum = 0;
75         int j;
76 #define lprintf(args...)        do {            \
77         tmpbuf += sprintf(tmpbuf, ## args);\
78 } while (0)
79
80         lprintf("[%03d]: ", i);
81         for (j=0; j < 16; j++) {
82                 u8 c = ((unsigned char *)buffer)[i+j];
83                 lprintf("%02x ", (unsigned int)c);
84                 sum += c;
85         }
86         lprintf(" |");
87         for (j=0; j < 16; j++) {
88                 u8 c = ((unsigned char *)buffer)[i+j];
89                 if (c >= 'a' && c <= 'z')
90                         lprintf("%c", c);
91                 else if (c >= 'A' && c <= 'Z')
92                         lprintf("%c", c);
93                 else if (c >= '0' && c <= '9')
94                         lprintf("%c", c);
95                 else if (c >= 0x20 && c <= 127)
96                         lprintf("%c", c);
97                 else
98                         lprintf(".");
99         }
100         lprintf("|\n");
101         if (sum == 0)
102                 continue;
103         printf("%s", linebuf);
104         //if (i > 200)
105         //      break;
106     }
107 }
108
109 void read_from(enum eyefi_file);
110 void write_to(enum eyefi_file, void *, int);
111
112 struct card_seq_num eyefi_seq;
113 struct card_seq_num read_seq_from(enum eyefi_file file)
114 {
115         struct card_seq_num *ret;
116         read_from(file);
117         ret = eyefi_buf;
118         return *ret;
119 }
120
121 /*
122  * For O_DIRECT writes to files, we need
123  * to be 512 byte aligned on Linux, I think.
124  * So, just align this to something big
125  * and be done with it.  FIXME :)
126  *
127  * This probably isn't necessary on chdk,
128  * since I don't think it buffers I/O at
129  * all.
130  */
131 void align_buf(void)
132 {
133         unsigned long addr = (unsigned long)&unaligned_buf[EYEFI_BUF_SIZE];
134         addr &= ~(EYEFI_BUF_SIZE-1);
135         eyefi_buf = (void *)addr;
136         debug_printf(4, "buf: %p\n", eyefi_buf);
137         debug_printf(4, "unaligned: %p\n", &unaligned_buf[0]);
138 }
139
140 /*
141  * The real manager does this so we might
142  * as well, too.
143  */
144 void zero_card_files(void)
145 {
146         char zbuf[EYEFI_BUF_SIZE];
147
148         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
149         //write_to(REQM, zbuf, EYEFI_BUF_SIZE);
150         write_to(REQC, zbuf, EYEFI_BUF_SIZE);
151         write_to(RSPM, zbuf, EYEFI_BUF_SIZE);
152         write_to(RSPC, zbuf, EYEFI_BUF_SIZE);
153
154         read_from(REQM);
155         read_from(REQC);
156         read_from(RSPM);
157         read_from(RSPC);
158 }
159
160 void init_card()
161 {
162         char *mnt;
163         if (eyefi_buf != NULL)
164                 return;
165
166         debug_printf(2, "Initializing card...\n");
167         mnt = locate_eyefi_mount();
168         if (mnt == NULL)
169                 return;
170
171         align_buf();
172         zero_card_files();
173         eyefi_seq = read_seq_from(RSPC);
174         if (eyefi_seq.seq == 0)
175                 eyefi_seq.seq = 0x1234;
176         eyefi_seq.seq++;
177         debug_printf(2, "Done initializing card...\n");
178         debug_printf(2, "seq was: %04x\n", eyefi_seq.seq);
179 }
180
181 static char *eyefi_file(enum eyefi_file file)
182 {
183         init_card();
184         return eyefi_file_on(file, locate_eyefi_mount());
185 }
186
187 void read_from(enum eyefi_file __file)
188 {
189         int ret;
190         int fd;
191         char *file = eyefi_file(__file);
192         
193         init_card();
194
195 retry:
196         fd = open(file, O_RDONLY);
197         if (fd < 0)
198                 open_error(file, fd);
199         fd_flush(fd);
200
201         void * map = mmap(0, EYEFI_BUF_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
202         if (ret = msync(map, EYEFI_BUF_SIZE, MS_INVALIDATE))
203                 debug_printf(0, "msync error %u", ret);
204
205         ret = memcpy(eyefi_buf, map, EYEFI_BUF_SIZE);
206
207         if (ret = msync(map, EYEFI_BUF_SIZE, MS_INVALIDATE))
208                 debug_printf(0, "msync error %u", ret);
209         munmap(map, EYEFI_BUF_SIZE);
210
211         if (eyefi_debug_level > 3)
212                 dumpbuf(eyefi_buf, 128);
213         if (ret < 0) {
214                 close(fd);
215                 perror("bad read, retrying...");
216                 goto retry;
217                 exit(1);
218         }
219         debug_printf(4, "read '%s': bytes: %d\n", file, EYEFI_BUF_SIZE);
220         /*
221          * There was a time when I was carefully recording how each response
222          * looked, and I counted the zeros in each response.  I don't care
223          * any more.
224         u8 c;
225         int zeros = 0;
226         int i;
227         for (i=0; i < EYEFI_BUF_SIZE; i++) {
228                 c = ((char *)eyefi_buf)[i];
229                 if (c == '\0') {
230                         zeros++;
231                         continue;
232                 }
233         }
234         */
235         free(file);
236         close(fd);
237 }
238
239 int fake_write = 0;
240 void write_to(enum eyefi_file __file, void *stuff, int len)
241 {
242         int ret;
243         int wrote;
244         int fd;
245         char *file;
246
247         if (fake_write)
248                 return;
249
250         init_card();
251         file = eyefi_file(__file);
252         if (len == -1)
253                 len = strlen(stuff);
254
255         if (eyefi_debug_level > 3) {
256                 debug_printf(3, "%s('%s', ..., %d)\n", __func__, file, len);
257                 dumpbuf(stuff, len);
258         }
259         memset(eyefi_buf, 0, EYEFI_BUF_SIZE);
260         memcpy(eyefi_buf, stuff, len);
261         fd = open(file, O_RDWR|O_CREAT, 0600);
262         if (fd < 0 )
263                 open_error(file, fd);
264         if (eyefi_debug_level > 3)
265                 dumpbuf(eyefi_buf, 128);
266         wrote = write(fd, eyefi_buf, EYEFI_BUF_SIZE);
267         if (wrote < 0)
268                 open_error(file, wrote);
269         ret = fd_flush(fd);
270         if (ret < 0)
271                 open_error(file, ret);
272         close(fd);
273         debug_printf(3, "wrote %d bytes to '%s' (string was %d bytes)\n", wrote, file, len);
274         if (ret < 0) {
275                 fprintf(stderr, "error writing to '%s': ", file);
276                 perror("");
277                 exit(ret);
278         }
279         free(file);
280 }       
281
282 #define write_struct(file, s) write_to((file), s, sizeof(*(s)))
283
284 void inc_seq(void)
285 {
286         /*
287          * Oddly enough, the sequence number appears
288          * to be of normal endianness.
289          */
290         //u32 tmpseq = be32_to_u32(seq.seq);
291         //seq.seq = u32_to_be32(tmpseq+1);
292         eyefi_seq.seq++;
293         write_struct(REQC, &eyefi_seq);
294 }
295
296 u32 eyefi_current_seq(void)
297 {
298         return eyefi_seq.seq;
299 }
300
301 int wait_for_response(void)
302 {
303         int good_rsp = 0;
304         u32 rsp = 0;
305         int i;
306         debug_printf(3, "waiting for response...\n");
307         inc_seq();
308         for (i = 0; i < 50; i++) {
309                 struct card_seq_num cardseq = read_seq_from(RSPC);
310                 debug_printf(3, "read rsp code: %x, looking for: %x raw: %x\n", rsp, eyefi_current_seq(),
311                                 cardseq.seq);
312                 rsp = cardseq.seq;
313                 if (rsp == eyefi_current_seq()) {
314                         good_rsp = 1;
315                         break;
316                 }
317                 if (eyefi_debug_level > 4) {
318                         read_from(REQM);
319                         debug_printf(1, "command issued was: '%c'\n", ((char *)eyefi_buf)[0]);
320                 }
321                 usleep(300000);
322         }
323         if (!good_rsp) {
324                 debug_printf(1, "never saw card seq response\n");
325                 return -1;
326         }
327         debug_printf(3, "got good seq (%d), reading RSPM...\n", rsp);
328         read_from(RSPM);
329         debug_printf(3, "done reading RSPM\n");
330         return 0;
331 }
332
333 char *net_test_states[] = {
334        "not scanning",
335        "locating network",
336        "verifying network key",
337        "waiting for DHCP",
338        "testing connection to Eye-Fi server",
339        "success",
340 };
341
342 char *net_test_state_name(u8 state)
343 {
344         int size = ARRAY_SIZE(net_test_states);
345         if (state >= size)
346                 return "unknown";
347         return net_test_states[state];
348 }
349
350 const char *net_types[] = {
351         "none",
352         "WEP",
353         "WPA",
354         "unknown1",
355         "WPA2",
356 };
357 const char net_type_unknown[] = "unknown";
358
359 const char *net_type_name(u8 type)
360 {
361         int size = ARRAY_SIZE(net_types);
362         debug_printf(3, "%s(%d): '%s' size: %d\n", __func__, type, net_types[type], size);
363         if (type >= size)
364                 return net_type_unknown;
365         return net_types[type];
366 }
367
368 static char lower(char c)
369 {
370         if ((c >= 'A') && (c <= 'Z'))
371                 c += ('a' - 'A');
372         return c;
373 }
374
375 int atoh(char c)
376 {
377         char lc = lower(c);
378         if ((c >= '0') && (c <= '9'))
379                 return c - '0';
380         else if ((lc >= 'a') && (lc <= 'z'))
381                 return (lc - 'a') + 10;
382         debug_printf(5, "non-hex character: '%c'/'%c'\n", c, lc);
383         return -1;
384 }
385
386 /*
387  * Take a string like "0ab1" and make it
388  * a series of bytes: { 0x0a, 0xb1 }
389  *
390  * @len is the strlen() of the ascii
391  *
392  * Destroys the original string.
393  */
394 char *convert_ascii_to_hex(char *ascii, int len)
395 {
396         int i;
397         if (len%2) {
398                 fprintf(stderr, "%s() must be even number of bytes: %d\n",
399                 __func__, len);
400                 exit(2);
401         }
402         for (i=0; i < len; i+=2) {
403                 int high = atoh(ascii[i]);
404                 int low  = atoh(ascii[i+1]);
405                 u8 byte = (high<<4 | low);
406                 if (high < 0 || low < 0) {
407                         fprintf(stderr, "unable to parse hex string: '%s'\n", ascii);
408                         return NULL;
409                 }
410                 debug_printf(6, "high: %02x low: %02x, both: %02x\n", high, low, byte);
411                 ascii[i/2] = byte;
412         }
413         for (i=len/2; i < len; i++)
414                 ascii[i] = '\0';
415         return &ascii[0];
416 }
417
418 int make_network_key(struct network_key *key, char *essid, char *pass)
419 {
420         char tmp[WPA_KEY_BYTES+WEP_KEY_BYTES];
421         int pass_len = strlen(pass);
422         char *hex_pass;
423         memset(key, 0, sizeof(*key));
424
425         strcpy(&tmp[0], pass);
426         eyefi_printf(" interpreting passphrase as ");
427         switch (pass_len) {
428                 case WPA_KEY_BYTES*2:
429                         eyefi_printf("hex WPA");
430                         hex_pass = convert_ascii_to_hex(tmp, pass_len);
431                         if (!hex_pass)
432                                 return -EINVAL;
433                         key->len = pass_len/2;
434                         memcpy(&key->wpa.key[0], hex_pass, key->len);
435                         break;
436                 case WEP_KEY_BYTES*2:
437                 case WEP_40_KEY_BYTES*2:
438                         eyefi_printf("hex WEP");
439                         hex_pass = convert_ascii_to_hex(tmp, strlen(pass));
440                         if (!hex_pass)
441                                 return -EINVAL;
442                         key->len = pass_len/2;
443                         memcpy(&key->wep.key[0], hex_pass, key->len);
444                         break;
445                 default:
446                         eyefi_printf("ASCII WPA");
447                         pbkdf2_sha1(pass, essid, strlen(essid), 4096,
448                                     &key->wpa.key[0], WPA_KEY_BYTES);
449                         key->len = WPA_KEY_BYTES;
450                         break;
451         }
452         eyefi_printf(" key (%d bytes)\n", key->len);
453         assert(key->len != 0);
454         return 0;
455 }
456
457 int card_info_cmd(enum card_info_subcommand cmd)
458 {
459         struct card_info_req cir;
460         cir.o = 'o';
461         cir.subcommand = cmd;
462
463         write_struct(REQM, &cir);
464         return wait_for_response();
465 }
466
467 u32 fetch_log_length(void)
468 {
469         debug_printf(3, "%s()\n", __func__);
470         card_info_cmd(LOG_LEN);
471         struct card_info_log_len *loglen = eyefi_buf;
472         return be32_to_u32(loglen->val);
473 }
474
475 struct card_firmware_info *fetch_card_firmware_info(void)
476 {
477         debug_printf(2, "%s()\n", __func__);
478         card_info_cmd(FIRMWARE_INFO);
479         return (struct card_firmware_info *)eyefi_buf;
480         return NULL;
481 }
482
483 void wlan_disable(int do_disable)
484 {
485         /*
486          * This is complete voodoo to me.  I've only ever seen
487          * a single example of this, so it's hard to figure out
488          * the structure at all.
489          */
490         char new_cmd[] = {'O', 0x0a, do_disable};
491         write_to(REQM, &new_cmd[0], 3);
492         wait_for_response();
493 }
494
495 int wlan_enabled(void)
496 {
497         struct var_byte_response *rsp;
498         card_info_cmd(WLAN_ENABLED);
499         rsp = eyefi_buf;
500         return rsp->responses[0].response;
501 }
502
503 struct testbuf {
504         char cmd;
505         u8 l1;
506         char name[100];
507 };
508
509 struct z {
510         char zeros[100];
511 } z;
512
513
514 char fwbuf[1<<20];
515 char zbuf[1<<20];
516 void scan_print_nets(void);
517 void testit0(void)
518 {
519         char c;
520         struct testbuf tb;
521         int i;
522         int fdin;
523         int fdout;
524
525         printf("WLAN enabled: %d\n", wlan_enabled());
526         wlan_disable(1);
527         printf("WLAN enabled: %d\n", wlan_enabled());
528         wlan_disable(0);
529         printf("WLAN enabled: %d\n", wlan_enabled());
530         exit(0);
531         for (i = 10; i <= 13; i++) {
532                 zero_card_files();
533                 card_info_cmd(i);
534                 printf("UNKNOWN %d result:\n", i);
535                 dumpbuf(eyefi_buf, 64);
536                 printf("WLAN enabled: %d\n", wlan_enabled());
537                 scan_print_nets();
538         }
539         i = 0xff;
540         card_info_cmd(i);
541         printf("UNKNOWN %d result:\n", i);
542         dumpbuf(eyefi_buf, 64);
543         scan_print_nets();
544         printf("WLAN enabled: %d\n", wlan_enabled());
545         //wlan_disable();
546         printf("WLAN enabled: %d\n", wlan_enabled());
547         for (i = 10; i <= 13; i++) {
548                 zero_card_files();
549                 card_info_cmd(i);
550                 printf("UNKNOWN %d result:\n", i);
551                 dumpbuf(eyefi_buf, 64);
552                 printf("WLAN enabled: %d\n", wlan_enabled());
553         }
554         i = 0xff;
555         card_info_cmd(i);
556         printf("UNKNOWN %d result:\n", i);
557         dumpbuf(eyefi_buf, 64);
558         exit(3);
559
560         card_info_cmd(3);
561         printf("o3 result:\n");
562         dumpbuf(eyefi_buf, 64);
563
564         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
565         zbuf[0] = 'o';
566         zbuf[1] = 2;
567
568         write_to(REQM, &zbuf[0], 16384);
569         printf("o2 written\n");
570         printf("seq: %x\n", (int)eyefi_seq.seq);
571         inc_seq();
572
573         for (i=0; i < 4; i++) {
574                 read_from(RSPC);
575                 printf("RSPC %d:\n", i);
576                 dumpbuf(eyefi_buf, 64);
577                 usleep(20000);
578         }
579
580         printf("RSPM1:\n");
581         read_from(RSPM);
582         dumpbuf(eyefi_buf, 64);
583
584         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
585         write_to(RSPM, zbuf, EYEFI_BUF_SIZE);
586         write_to(REQM, zbuf, EYEFI_BUF_SIZE);
587
588         fdin = open("/home/dave/projects/eyefi/EYEFIFWU.BIN.2.0001", O_RDONLY);
589         perror("fdin");
590         fdout = open("/media/EYE-FI/EYEFIFWU.BIN", O_WRONLY|O_CREAT);
591         perror("fdout");
592         if (fdin <= 0 || fdout <= 0)
593                 exit(1);
594         fd_flush(fdin);
595         i = read(fdin, &fwbuf[0], 524288);
596         perror("read");
597         if (i != 524288)
598                 exit(2);
599         i = write(fdout, &fwbuf[0], 524288);
600         fd_flush(fdout);
601         perror("write");
602         if (i != 524288)
603                 exit(3);
604
605         printf("RSPM2:\n");
606         read_from(RSPM);
607         dumpbuf(eyefi_buf, 64);
608
609         reboot_card();
610         printf("after reboot:\n");
611         dumpbuf(eyefi_buf, 64);
612
613         printf("cic3:\n");
614         card_info_cmd(3);
615         dumpbuf(eyefi_buf, 64);
616
617         printf("cic2:\n");
618         card_info_cmd(2);
619         dumpbuf(eyefi_buf, 64);
620
621         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
622         write_to(RSPM, zbuf, EYEFI_BUF_SIZE);
623         write_to(REQM, zbuf, EYEFI_BUF_SIZE);
624         
625         printf("cic2v2:\n");
626         card_info_cmd(2);
627         dumpbuf(eyefi_buf, 64);
628
629         exit(0);
630         strcpy(tb.name, "www.sr71.net/");
631         tb.l1 = strlen(tb.name);
632         for (i = 0; i < 10; i++) {
633                 tb.cmd = 'O';
634                 tb.l1 = i;
635                 write_struct(RSPM, &z);
636                 write_struct(REQM, &tb);
637                 wait_for_response();
638                 printf("buffer after O %d:\n", i);
639                 dumpbuf(eyefi_buf, 64);
640                 printf("----------------\n");
641                 write_struct(REQM, &tb);
642                 card_info_cmd(i);
643                 printf("card info(%d):\n", i);
644                 dumpbuf(eyefi_buf, 64);
645                 printf("-----------\n");
646         }
647         return;
648
649         strcpy(tb.name, "/public/eyefi/servname");
650         strcpy(tb.name, "/config/networks.xml");
651         //tb.len = strlen(tb.name);
652         tb.l1 = 0;
653         for (c = 'O'; c <= 'O'; c++) {
654                 tb.cmd = c;
655                 write_struct(REQM, &tb);
656                 wait_for_response();
657                 printf("dumping buffer:\n");
658                 dumpbuf(eyefi_buf, 64);
659                 printf("buffer dump done\n");
660         }
661 }
662
663 struct card_info_rsp_key *fetch_card_key(void)
664 {
665         struct card_info_rsp_key *key;
666
667         debug_printf(2, "%s()\n", __func__);
668         card_info_cmd(CARD_KEY);
669         key = eyefi_buf;
670         return key;
671 }
672
673 int issue_noarg_command(u8 cmd)
674 {
675         struct noarg_request req;
676         debug_printf(4, "%s() cmd: %d\n", __func__, cmd);
677         req.req = cmd;
678         write_struct(REQM, &req);
679         return wait_for_response();
680 }
681
682 struct scanned_net_list *scan_nets(void)
683 {
684         struct scanned_net_list *scanned;
685
686         debug_printf(2, "%s()\n", __func__);
687         issue_noarg_command('g');
688         scanned = eyefi_response();
689         return scanned;
690 }
691
692 struct configured_net_list *fetch_configured_nets(void)
693 {
694         struct configured_net_list *configured;
695
696         debug_printf(2, "%s()\n", __func__);
697         issue_noarg_command('l');
698         configured = eyefi_buf;
699         return configured;
700 }
701
702 void reboot_card(void)
703 {
704         debug_printf(2, "%s()\n", __func__);
705         debug_printf(1, "rebooting card...");
706         issue_noarg_command('b');
707         debug_printf(1, "done\n");
708 }
709
710 int network_action(char cmd, char *essid, char *ascii_password)
711 {
712         struct net_request nr;
713         memset(&nr, 0, sizeof(nr));
714
715         nr.req = cmd;
716         strcpy(&nr.essid[0], essid);
717         nr.essid_len = strlen(essid);
718
719         if (ascii_password) {
720                 int ret = make_network_key(&nr.key, essid, ascii_password);
721                 if (ret)
722                         return ret;
723         }
724         write_struct(REQM, &nr);
725         return wait_for_response();
726 }
727
728 void add_network(char *essid, char *ascii_password)
729 {
730         debug_printf(2, "%s('%s', '%s')\n", __func__, essid, ascii_password);
731         network_action('a', essid, ascii_password);
732 }
733
734 void remove_network(char *essid)
735 {
736         debug_printf(2, "%s()\n", __func__);
737         network_action('d', essid, NULL);
738 }
739
740 int get_log_at_offset(u32 offset)
741 {
742         struct fetch_log_cmd cmd;
743         cmd.m = 'm';
744         cmd.offset = u32_to_be32(offset);
745
746         debug_printf(2, "getting log at offset: %08x\n", offset);
747         write_struct(REQM, &cmd);
748         return wait_for_response();
749 }
750
751 void add_log_piece(u8 *log, int log_len, u8 *piece, int piece_pos, int piece_size)
752 {
753         debug_printf(2, "%s(%p, %d, %p, %d, %d)\n", __func__, log, log_len, piece, piece_pos, piece_size);
754         if (piece_pos + piece_size > log_len) {
755                 int overflow_by = (piece_pos + piece_size) - log_len;
756                 int piece_overrun_pos = piece_size - overflow_by;
757                 piece_size -= overflow_by;
758                 memcpy(&log[0], &piece[piece_overrun_pos], overflow_by);
759                 debug_printf(2, "writing %d bytes to logbuf[0] from piece[%d]\n",
760                                 overflow_by, piece_overrun_pos);
761         }
762         debug_printf(2, "writing %d bytes to logbuf[%d]\n", piece_size, piece_pos);
763         memcpy(&log[piece_pos], piece, piece_size);
764 }
765
766 int get_log_into(u8 *resbuf)
767 {
768         int total_bytes = 0;
769         int ret;
770         int i;
771         u32 log_start;
772         u32 log_end;
773         u32 __log_size = fetch_log_length();
774         int log_pieces = __log_size/EYEFI_BUF_SIZE;
775
776         if (__log_size <= 0)
777                 return __log_size;
778
779         /* There are 8 bytes of header in the first log entry
780          * to specify where the log starts and ends */
781         u32 log_size = __log_size - 8;
782
783         for (i = 0; i < log_pieces; i++) {
784                 debug_printf(1, "fetching EyeFi card log part %d/%d...",
785                                 i+1, log_pieces);
786                 fflush(NULL);
787                 ret = get_log_at_offset(EYEFI_BUF_SIZE*i);
788                 debug_printf(1, "done\n");
789                 u8 *log_piece;
790                 u32 log_piece_size;
791                 if (i == 0) {
792                         struct first_log_response *log = eyefi_buf;
793                         log_end = log_size - be32_to_u32(log->log_end);
794                         log_start = log_size - be32_to_u32(log->log_start);
795                         debug_printf(2, "log end:   0x%04x\n", log_end);
796                         debug_printf(2, "log start: 0x%04x\n", log_start);
797                         log_piece = &log->data[0];
798                         log_piece_size = ARRAY_SIZE(log->data);
799                 } else {
800                         struct rest_log_response *log = eyefi_buf;
801                         log_piece = &log->data[0];
802                         log_piece_size = ARRAY_SIZE(log->data);
803                 }
804                 add_log_piece(resbuf, log_size, log_piece, log_start, log_piece_size);
805                 total_bytes += log_piece_size;
806                 log_start += log_piece_size;
807                 log_start = log_start % log_size;
808         }
809         return total_bytes;
810 }
811