diff --git a/eyefi-config.c b/eyefi-config.c index 0c4da7a..0dd546c 100755 --- a/eyefi-config.c +++ b/eyefi-config.c @@ -495,6 +495,27 @@ int wlan_enabled(void) return rsp->responses[0].response; } +enum transfer_mode fetch_transfer_mode(void) +{ + struct var_byte_response *rsp; + card_info_cmd(TRANSFER_MODE); + rsp = eyefi_buf; + return rsp->responses[0].response; +} + +void set_transfer_mode(enum transfer_mode transfer_mode) +{ + /* + * This is complete voodoo to me. I've only ever seen + * a single example of this, so it's hard to figure out + * the structure at all. + */ + char new_cmd[] = {'O', TRANSFER_MODE, 0x1, transfer_mode}; + write_to(REQM, &new_cmd[0], 4); + wait_for_response(); +} + + struct testbuf { char cmd; u8 l1; @@ -517,6 +538,15 @@ void testit0(void) int fdin; int fdout; + printf("transfer_mode: %d\n", fetch_transfer_mode()); + set_transfer_mode(SELECTIVE_TRANSFER); + printf("transfer_mode: %d\n", fetch_transfer_mode()); + set_transfer_mode(SELECTIVE_SHARE); +// printf("transfer_mode: %d\n", fetch_transfer_mode()); +// set_transfer_mode(AUTO_TRANSFER); + printf("transfer_mode: %d\n", fetch_transfer_mode()); + exit(0); + printf("WLAN enabled: %d\n", wlan_enabled()); wlan_disable(1); printf("WLAN enabled: %d\n", wlan_enabled()); diff --git a/eyefi-config.h b/eyefi-config.h index b10d945..2df97b5 100644 --- a/eyefi-config.h +++ b/eyefi-config.h @@ -168,7 +168,7 @@ enum card_info_subcommand { WLAN_ENABLED = 10, UNKNOWN_13 = 13, // Returns an ASCII SSID. Last connected or // current WiFi network, maybe? - // + TRANSFER_MODE = 17, UNKNOWN_ff = 0xff, // The D90 does this, and it looks to // return a 1-byte response length @@ -211,6 +211,13 @@ struct card_info_log_len { be32 val; } __attribute__((packed)); +// These go along with 'o' 17 aka. TRANSFER_MODE +enum transfer_mode { + AUTO_TRANSFER = 0, + SELECTIVE_TRANSFER = 1, + SELECTIVE_SHARE = 2, +}; + struct byte_response { u8 response; }; @@ -317,6 +324,8 @@ u32 fetch_log_length(void); int card_info_cmd(enum card_info_subcommand cmd); void *eyefi_response(void); struct card_info_rsp_key *fetch_card_key(void); +enum transfer_mode fetch_transfer_mode(void); +void set_transfer_mode(enum transfer_mode); struct scanned_net_list *scan_nets(void); const char *net_type_name(u8 type); struct configured_net_list *fetch_configured_nets(void); diff --git a/eyefi-unix.c b/eyefi-unix.c index 9c575db..fd70433 100755 --- a/eyefi-unix.c +++ b/eyefi-unix.c @@ -156,6 +156,65 @@ int try_connection_to(char *essid, char *ascii_password) return ret; } +const char *transfer_mode_names[] = { + "AUTO", + "SELUPLOAD", + "SELSHARE", +}; + +int __index_of_str(char *find_me, const char **to_search, int array_size) +{ + int i; + + for (i = 0; i < array_size; i++) { + if (!strcmp(find_me, to_search[i])) + return i; + } + return -1; +} +#define index_of_str(findit, chr_array) __index_of_str(findit, chr_array, ARRAY_SIZE(chr_array)) +static char unknown_buf[1024]; +const char *__index_to_str(const char **array, int index, int array_size) +{ + // This is funky and not thread safe + if (index >= array_size) { + sprintf(&unknown_buf[0], "UNKNOWN[%d]", index); + return &unknown_buf[0]; + } + return array[index]; +} +#define index_to_str(chr_array, index) __index_to_str(chr_array, index, ARRAY_SIZE(chr_array)) + +enum transfer_mode str_to_transfer_mode(char *mode_str) +{ + return index_of_str(mode_str, transfer_mode_names); +} + +void handle_transfer_mode(char *arg) +{ + enum transfer_mode new_mode; + if (!arg) { + enum transfer_mode mode = fetch_transfer_mode(); + const char *mode_name = index_to_str(transfer_mode_names, mode); + printf("transfer mode is: %s\n", mode_name); + return; + } + new_mode = str_to_transfer_mode(arg); + if (new_mode == -1) { + int i; + if (strcmp(arg, "help")) { + printf("invalid --transfer-mode: %s\n", arg); + } + printf("valid --transfer-mode modes are:\n"); + for (i = 0; i < ARRAY_SIZE(transfer_mode_names); i++) { + printf("\t%s\n", transfer_mode_names[i]); + } + exit(1); + } + set_transfer_mode(new_mode); + exit(0); +} + int print_log(void) { int i; @@ -226,10 +285,23 @@ void usage(void) printf(" -d level set debugging level (default: 1)\n"); printf(" -k print card unique key\n"); printf(" -l dump card log\n"); - printf(" -m print card mac\n"); + printf(" -m print card mac\n"); + printf(" --transfer_mode[=mode] print or change card transfer mode\n"); + printf(" or =help to list modes\n"); exit(4); } +int is_long_opt(int cint, struct option *long_options) +{ + struct option *opt = long_options; + + while (opt && opt->name) { + if (opt->val == cint) + return 1; + } + return 0; +} + int main(int argc, char *argv[]) { int option_index; @@ -239,11 +311,13 @@ int main(int argc, char *argv[]) char *passwd = NULL; char network_action = 0; static int force = 0; + static int transfer_mode = 0; static struct option long_options[] = { //{"wep", 'x', &passed_wep, 1}, //{"wpa", 'y', &passed_wpa, 1}, - {"force", 0, &force, 1}, - {"help", 'h', NULL, 1}, + {"force", 0, &force, 0}, + {"help", 0, NULL, 'h'}, + {"transfer-mode", 2, &transfer_mode, 1}, {0, 0, 0, 0} }; @@ -259,6 +333,11 @@ int main(int argc, char *argv[]) &long_options[0], &option_index)) != -1) { c = cint; debug_printf(3, "argument: '%c' %d optarg: '%s'\n", c, c, optarg); + if (transfer_mode) { + handle_transfer_mode(optarg); + transfer_mode = 0; + continue; + } switch (c) { case 0: // was a long argument @@ -307,6 +386,8 @@ int main(int argc, char *argv[]) usage(); break; } + printf( "argument: '%c' %d optarg: '%s'\n", c, c, optarg); + exit(0); } debug_printf(3, "after arguments1 essid: '%s' passwd: '%s'\n", essid, passwd);