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