]> CyberLeo.Net >> Repos - SourceForge/eyefi-config.git/blob - eyefi-config.c
Add some new code to handle D90 commands
[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 fd;
233         char *file;
234
235         if (fake_write)
236                 return;
237
238         init_card();
239         file = eyefi_file(__file);
240         if (len == -1)
241                 len = strlen(stuff);
242
243         if (eyefi_debug_level > 3) {
244                 debug_printf(3, "%s('%s', ..., %d)\n", __func__, file, len);
245                 dumpbuf(stuff, len);
246         }
247         memset(eyefi_buf, 0, EYEFI_BUF_SIZE);
248         memcpy(eyefi_buf, stuff, len);
249         fd = open(file, O_RDWR|O_CREAT, 0600);
250         if (fd < 0 )
251                 open_error(file, fd);
252         if (eyefi_debug_level > 3)
253                 dumpbuf(eyefi_buf, 128);
254         ret = write(fd, eyefi_buf, EYEFI_BUF_SIZE);
255         if (ret < 0)
256                 open_error(file, ret);
257         ret = fd_flush(fd);
258         if (ret < 0)
259                 open_error(file, ret);
260         close(fd);
261         debug_printf(3, "wrote %d bytes to '%s' (string was %d bytes)\n", ret, file, len);
262         if (ret < 0) {
263                 fprintf(stderr, "error writing to '%s': ", file);
264                 perror("");
265                 exit(ret);
266         }
267         free(file);
268 }       
269
270 #define write_struct(file, s) write_to((file), s, sizeof(*(s)))
271
272 void inc_seq(void)
273 {
274         /*
275          * Oddly enough, the sequence number appears
276          * to be of normal endianness.
277          */
278         //u32 tmpseq = be32_to_u32(seq.seq);
279         //seq.seq = u32_to_be32(tmpseq+1);
280         eyefi_seq.seq++;
281         write_struct(REQC, &eyefi_seq);
282 }
283
284 u32 eyefi_current_seq(void)
285 {
286         return eyefi_seq.seq;
287 }
288
289 int wait_for_response(void)
290 {
291         int good_rsp = 0;
292         u32 rsp = 0;
293         int i;
294         debug_printf(3, "waiting for response...\n");
295         inc_seq();
296         for (i = 0; i < 50; i++) {
297                 struct card_seq_num cardseq = read_seq_from(RSPC);
298                 debug_printf(3, "read rsp code: %x, looking for: %x raw: %x\n", rsp, eyefi_current_seq(),
299                                 cardseq.seq);
300                 rsp = cardseq.seq;
301                 if (rsp == eyefi_current_seq()) {
302                         good_rsp = 1;
303                         break;
304                 }
305                 if (eyefi_debug_level > 4) {
306                         read_from(REQM);
307                         debug_printf(1, "command issued was: '%c'\n", ((char *)eyefi_buf)[0]);
308                 }
309                 usleep(300000);
310         }
311         if (!good_rsp) {
312                 debug_printf(1, "never saw card seq response\n");
313                 return -1;
314         }
315         debug_printf(3, "got good seq (%d), reading RSPM...\n", rsp);
316         read_from(RSPM);
317         debug_printf(3, "done reading RSPM\n");
318         return 0;
319 }
320
321 char *net_test_states[] = {
322        "not scanning",
323        "locating network",
324        "verifying network key",
325        "waiting for DHCP",
326        "testing connection to Eye-Fi server",
327        "success",
328 };
329
330 char *net_test_state_name(u8 state)
331 {
332         int size = ARRAY_SIZE(net_test_states);
333         if (state >= size)
334                 return "unknown";
335         return net_test_states[state];
336 }
337
338 const char *net_types[] = {
339         "none",
340         "WEP",
341         "WPA",
342         "unknown1",
343         "WPA2",
344 };
345 const char net_type_unknown[] = "unknown";
346
347 const char *net_type_name(u8 type)
348 {
349         int size = ARRAY_SIZE(net_types);
350         debug_printf(3, "%s(%d): '%s' size: %d\n", __func__, type, net_types[type], size);
351         if (type >= size)
352                 return net_type_unknown;
353         return net_types[type];
354 }
355
356 static char lower(char c)
357 {
358         if ((c >= 'A') && (c <= 'Z'))
359                 c += ('a' - 'A');
360         return c;
361 }
362
363 int atoh(char c)
364 {
365         char lc = lower(c);
366         if ((c >= '0') && (c <= '9'))
367                 return c - '0';
368         else if ((lc >= 'a') && (lc <= 'z'))
369                 return (lc - 'a') + 10;
370         debug_printf(5, "non-hex character: '%c'/'%c'\n", c, lc);
371         return -1;
372 }
373
374 /*
375  * Take a string like "0ab1" and make it
376  * a series of bytes: { 0x0a, 0xb1 }
377  *
378  * @len is the strlen() of the ascii
379  *
380  * Destroys the original string.
381  */
382 char *convert_ascii_to_hex(char *ascii, int len)
383 {
384         int i;
385         if (len%2) {
386                 fprintf(stderr, "%s() must be even number of bytes: %d\n",
387                 __func__, len);
388                 exit(2);
389         }
390         for (i=0; i < len; i+=2) {
391                 int high = atoh(ascii[i]);
392                 int low  = atoh(ascii[i+1]);
393                 u8 byte = (high<<4 | low);
394                 if (high < 0 || low < 0) {
395                         fprintf(stderr, "unable to parse hex string: '%s'\n", ascii);
396                         return NULL;
397                 }
398                 debug_printf(6, "high: %02x low: %02x, both: %02x\n", high, low, byte);
399                 ascii[i/2] = byte;
400         }
401         for (i=len/2; i < len; i++)
402                 ascii[i] = '\0';
403         return &ascii[0];
404 }
405
406 int make_network_key(struct network_key *key, char *essid, char *pass)
407 {
408         char tmp[WPA_KEY_BYTES+WEP_KEY_BYTES];
409         int pass_len = strlen(pass);
410         char *hex_pass;
411         memset(key, 0, sizeof(*key));
412
413         strcpy(&tmp[0], pass);
414         eyefi_printf(" interpreting passphrase as ");
415         switch (pass_len) {
416                 case WPA_KEY_BYTES*2:
417                         eyefi_printf("hex WPA");
418                         hex_pass = convert_ascii_to_hex(tmp, pass_len);
419                         if (!hex_pass)
420                                 return -EINVAL;
421                         key->len = pass_len/2;
422                         memcpy(&key->wpa.key[0], hex_pass, key->len);
423                         break;
424                 case WEP_KEY_BYTES*2:
425                 case WEP_40_KEY_BYTES*2:
426                         eyefi_printf("hex WEP");
427                         hex_pass = convert_ascii_to_hex(tmp, strlen(pass));
428                         if (!hex_pass)
429                                 return -EINVAL;
430                         key->len = pass_len/2;
431                         memcpy(&key->wep.key[0], hex_pass, key->len);
432                         break;
433                 default:
434                         eyefi_printf("ASCII WPA");
435                         pbkdf2_sha1(pass, essid, strlen(essid), 4096,
436                                     &key->wpa.key[0], WPA_KEY_BYTES);
437                         key->len = WPA_KEY_BYTES;
438                         break;
439         }
440         eyefi_printf(" key (%d bytes)\n", key->len);
441         assert(key->len != 0);
442         return 0;
443 }
444
445 int card_info_cmd(enum card_info_subcommand cmd)
446 {
447         struct card_info_req cir;
448         cir.o = 'o';
449         cir.subcommand = cmd;
450
451         write_struct(REQM, &cir);
452         return wait_for_response();
453 }
454
455 u32 fetch_log_length(void)
456 {
457         debug_printf(3, "%s()\n", __func__);
458         card_info_cmd(LOG_LEN);
459         struct card_info_log_len *loglen = eyefi_buf;
460         return be32_to_u32(loglen->val);
461 }
462
463 struct card_firmware_info *fetch_card_firmware_info(void)
464 {
465         debug_printf(2, "%s()\n", __func__);
466         card_info_cmd(FIRMWARE_INFO);
467         return (struct card_firmware_info *)eyefi_buf;
468         return NULL;
469 }
470
471 void wlan_disable(int do_disable)
472 {
473         /*
474          * This is complete voodoo to me.  I've only ever seen
475          * a single example of this, so it's hard to figure out
476          * the structure at all.
477          */
478         char new_cmd[] = {'O', 0x0a, do_disable};
479         write_to(REQM, &new_cmd[0], 3);
480         wait_for_response();
481 }
482
483 int wlan_enabled(void)
484 {
485         struct var_byte_response *rsp;
486         card_info_cmd(WLAN_ENABLED);
487         rsp = eyefi_buf;
488         return rsp->responses[0].response;
489 }
490
491 struct testbuf {
492         char cmd;
493         u8 l1;
494         char name[100];
495 };
496
497 struct z {
498         char zeros[100];
499 } z;
500
501
502 char fwbuf[1<<20];
503 char zbuf[1<<20];
504 void scan_print_nets(void);
505 void testit0(void)
506 {
507         char c;
508         struct testbuf tb;
509         int i;
510         int fdin;
511         int fdout;
512
513         printf("WLAN enabled: %d\n", wlan_enabled());
514         wlan_disable(1);
515         printf("WLAN enabled: %d\n", wlan_enabled());
516         wlan_disable(0);
517         printf("WLAN enabled: %d\n", wlan_enabled());
518         exit(0);
519         for (i = 10; i <= 13; i++) {
520                 zero_card_files();
521                 card_info_cmd(i);
522                 printf("UNKNOWN %d result:\n", i);
523                 dumpbuf(eyefi_buf, 64);
524                 printf("WLAN enabled: %d\n", wlan_enabled());
525                 scan_print_nets();
526         }
527         i = 0xff;
528         card_info_cmd(i);
529         printf("UNKNOWN %d result:\n", i);
530         dumpbuf(eyefi_buf, 64);
531         scan_print_nets();
532         printf("WLAN enabled: %d\n", wlan_enabled());
533         //wlan_disable();
534         printf("WLAN enabled: %d\n", wlan_enabled());
535         for (i = 10; i <= 13; i++) {
536                 zero_card_files();
537                 card_info_cmd(i);
538                 printf("UNKNOWN %d result:\n", i);
539                 dumpbuf(eyefi_buf, 64);
540                 printf("WLAN enabled: %d\n", wlan_enabled());
541         }
542         i = 0xff;
543         card_info_cmd(i);
544         printf("UNKNOWN %d result:\n", i);
545         dumpbuf(eyefi_buf, 64);
546         exit(3);
547
548         card_info_cmd(3);
549         printf("o3 result:\n");
550         dumpbuf(eyefi_buf, 64);
551
552         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
553         zbuf[0] = 'o';
554         zbuf[1] = 2;
555
556         write_to(REQM, &zbuf[0], 16384);
557         printf("o2 written\n");
558         printf("seq: %x\n", (int)eyefi_seq.seq);
559         inc_seq();
560
561         for (i=0; i < 4; i++) {
562                 read_from(RSPC);
563                 printf("RSPC %d:\n", i);
564                 dumpbuf(eyefi_buf, 64);
565                 usleep(20000);
566         }
567
568         printf("RSPM1:\n");
569         read_from(RSPM);
570         dumpbuf(eyefi_buf, 64);
571
572         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
573         write_to(RSPM, zbuf, EYEFI_BUF_SIZE);
574         write_to(REQM, zbuf, EYEFI_BUF_SIZE);
575
576         fdin = open("/home/dave/projects/eyefi/EYEFIFWU.BIN.2.0001", O_RDONLY);
577         perror("fdin");
578         fdout = open("/media/EYE-FI/EYEFIFWU.BIN", O_WRONLY|O_CREAT);
579         perror("fdout");
580         if (fdin <= 0 || fdout <= 0)
581                 exit(1);
582         fd_flush(fdin);
583         i = read(fdin, &fwbuf[0], 524288);
584         perror("read");
585         if (i != 524288)
586                 exit(2);
587         i = write(fdout, &fwbuf[0], 524288);
588         fd_flush(fdout);
589         perror("write");
590         if (i != 524288)
591                 exit(3);
592
593         printf("RSPM2:\n");
594         read_from(RSPM);
595         dumpbuf(eyefi_buf, 64);
596
597         reboot_card();
598         printf("after reboot:\n");
599         dumpbuf(eyefi_buf, 64);
600
601         printf("cic3:\n");
602         card_info_cmd(3);
603         dumpbuf(eyefi_buf, 64);
604
605         printf("cic2:\n");
606         card_info_cmd(2);
607         dumpbuf(eyefi_buf, 64);
608
609         memset(&zbuf[0], 0, EYEFI_BUF_SIZE);
610         write_to(RSPM, zbuf, EYEFI_BUF_SIZE);
611         write_to(REQM, zbuf, EYEFI_BUF_SIZE);
612         
613         printf("cic2v2:\n");
614         card_info_cmd(2);
615         dumpbuf(eyefi_buf, 64);
616
617         exit(0);
618         strcpy(tb.name, "www.sr71.net/");
619         tb.l1 = strlen(tb.name);
620         for (i = 0; i < 10; i++) {
621                 tb.cmd = 'O';
622                 tb.l1 = i;
623                 write_struct(RSPM, &z);
624                 write_struct(REQM, &tb);
625                 wait_for_response();
626                 printf("buffer after O %d:\n", i);
627                 dumpbuf(eyefi_buf, 64);
628                 printf("----------------\n");
629                 write_struct(REQM, &tb);
630                 card_info_cmd(i);
631                 printf("card info(%d):\n", i);
632                 dumpbuf(eyefi_buf, 64);
633                 printf("-----------\n");
634         }
635         return;
636
637         strcpy(tb.name, "/public/eyefi/servname");
638         strcpy(tb.name, "/config/networks.xml");
639         //tb.len = strlen(tb.name);
640         tb.l1 = 0;
641         for (c = 'O'; c <= 'O'; c++) {
642                 tb.cmd = c;
643                 write_struct(REQM, &tb);
644                 wait_for_response();
645                 printf("dumping buffer:\n");
646                 dumpbuf(eyefi_buf, 64);
647                 printf("buffer dump done\n");
648         }
649 }
650
651 struct card_info_rsp_key *fetch_card_key(void)
652 {
653         struct card_info_rsp_key *key;
654
655         debug_printf(2, "%s()\n", __func__);
656         card_info_cmd(CARD_KEY);
657         key = eyefi_buf;
658         return key;
659 }
660
661 int issue_noarg_command(u8 cmd)
662 {
663         struct noarg_request req;
664         debug_printf(4, "%s() cmd: %d\n", __func__, cmd);
665         req.req = cmd;
666         write_struct(REQM, &req);
667         return wait_for_response();
668 }
669
670 struct scanned_net_list *scan_nets(void)
671 {
672         struct scanned_net_list *scanned;
673
674         debug_printf(2, "%s()\n", __func__);
675         issue_noarg_command('g');
676         scanned = eyefi_response();
677         return scanned;
678 }
679
680 struct configured_net_list *fetch_configured_nets(void)
681 {
682         struct configured_net_list *configured;
683
684         debug_printf(2, "%s()\n", __func__);
685         issue_noarg_command('l');
686         configured = eyefi_buf;
687         return configured;
688 }
689
690 void reboot_card(void)
691 {
692         debug_printf(2, "%s()\n", __func__);
693         debug_printf(1, "rebooting card...");
694         issue_noarg_command('b');
695         debug_printf(1, "done\n");
696 }
697
698 int network_action(char cmd, char *essid, char *ascii_password)
699 {
700         struct net_request nr;
701         memset(&nr, 0, sizeof(nr));
702
703         nr.req = cmd;
704         strcpy(&nr.essid[0], essid);
705         nr.essid_len = strlen(essid);
706
707         if (ascii_password) {
708                 int ret = make_network_key(&nr.key, essid, ascii_password);
709                 if (ret)
710                         return ret;
711         }
712         write_struct(REQM, &nr);
713         return wait_for_response();
714 }
715
716 void add_network(char *essid, char *ascii_password)
717 {
718         debug_printf(2, "%s('%s', '%s')\n", __func__, essid, ascii_password);
719         network_action('a', essid, ascii_password);
720 }
721
722 void remove_network(char *essid)
723 {
724         debug_printf(2, "%s()\n", __func__);
725         network_action('d', essid, NULL);
726 }
727
728 int get_log_at_offset(u32 offset)
729 {
730         struct fetch_log_cmd cmd;
731         cmd.m = 'm';
732         cmd.offset = u32_to_be32(offset);
733
734         debug_printf(2, "getting log at offset: %08x\n", offset);
735         write_struct(REQM, &cmd);
736         return wait_for_response();
737 }
738
739 void add_log_piece(u8 *log, int log_len, u8 *piece, int piece_pos, int piece_size)
740 {
741         debug_printf(2, "%s(%p, %d, %p, %d, %d)\n", __func__, log, log_len, piece, piece_pos, piece_size);
742         if (piece_pos + piece_size > log_len) {
743                 int overflow_by = (piece_pos + piece_size) - log_len;
744                 int piece_overrun_pos = piece_size - overflow_by;
745                 piece_size -= overflow_by;
746                 memcpy(&log[0], &piece[piece_overrun_pos], overflow_by);
747                 debug_printf(2, "writing %d bytes to logbuf[0] from piece[%d]\n",
748                                 overflow_by, piece_overrun_pos);
749         }
750         debug_printf(2, "writing %d bytes to logbuf[%d]\n", piece_size, piece_pos);
751         memcpy(&log[piece_pos], piece, piece_size);
752 }
753
754 int get_log_into(u8 *resbuf)
755 {
756         int total_bytes = 0;
757         int ret;
758         int i;
759         u32 log_start;
760         u32 log_end;
761         u32 __log_size = fetch_log_length();
762         int log_pieces = __log_size/EYEFI_BUF_SIZE;
763
764         if (__log_size <= 0)
765                 return __log_size;
766
767         /* There are 8 bytes of header in the first log entry
768          * to specify where the log starts and ends */
769         u32 log_size = __log_size - 8;
770
771         for (i = 0; i < log_pieces; i++) {
772                 debug_printf(1, "fetching EyeFi card log part %d/%d...",
773                                 i+1, log_pieces);
774                 fflush(NULL);
775                 ret = get_log_at_offset(EYEFI_BUF_SIZE*i);
776                 debug_printf(1, "done\n");
777                 u8 *log_piece;
778                 u32 log_piece_size;
779                 if (i == 0) {
780                         struct first_log_response *log = eyefi_buf;
781                         log_end = log_size - be32_to_u32(log->log_end);
782                         log_start = log_size - be32_to_u32(log->log_start);
783                         debug_printf(2, "log end:   0x%04x\n", log_end);
784                         debug_printf(2, "log start: 0x%04x\n", log_start);
785                         log_piece = &log->data[0];
786                         log_piece_size = ARRAY_SIZE(log->data);
787                 } else {
788                         struct rest_log_response *log = eyefi_buf;
789                         log_piece = &log->data[0];
790                         log_piece_size = ARRAY_SIZE(log->data);
791                 }
792                 add_log_piece(resbuf, log_size, log_piece, log_start, log_piece_size);
793                 total_bytes += log_piece_size;
794                 log_start += log_piece_size;
795                 log_start = log_start % log_size;
796         }
797         return total_bytes;
798 }
799