forked from hansendc/eyefi-config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eyefi-config.h
404 lines (346 loc) · 9.48 KB
/
eyefi-config.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
#ifndef _EYEFI_CONFIG_H
#define _EYEFI_CONFIG_H
#include <sys/types.h>
#if defined(LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN)
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#endif
#if defined(BIG_ENDIAN) && !defined(__BIG_ENDIAN)
#define __BIG_ENDIAN BIG_ENDIAN
#endif
#if !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
#include <endian.h>
#include <byteswap.h>
#endif
extern int eyefi_debug_level;
#ifdef __CHDK__
#define CONFIG_EYEFI_STANDALONE 1
#define printf(...) do{}while(0)
#define putchar(...) do{}while(0)
#define puts(...) do{}while(0)
#define exit(i) return
#define perror(i) do{}while(0)
#define system(i) do{}while(0)
#define fd_flush(fd) (0)
#define assert(x) do{}while(0)
#define output_flush() do{}while(0)
#else
#define CONFIG_EYEFI_WITH_OS 1
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#define PATHNAME_MAX 4096
#define output_flush() fflush(NULL)
#define debug_printf(level, args...) do { \
if ((level) <= eyefi_debug_level) \
fprintf(stderr, ## args); \
} while(0)
#endif
/*
* These are defined in both eyefi-unix.c and eyefi-chdk.c
*/
extern void open_error(char *file, int err);
extern int eyefi_printf(const char *fmt, ...);
/*
* These have to be created by the unix variants
*/
extern int fd_flush(int);
/*
* Do some kernel-style types to make
* definitions shorter.
*/
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define os_memset memset
#define os_memcpy memcpy
#define os_strlen strlen
#define os_strcpy strcpy
#define SHA1_MAC_LEN 20
#define MD5_MAC_LEN 16
void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac);
void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac);
void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
int iterations, u8 *buf, size_t buflen);
static inline u32 swap_bytes(u32 src)
{
u32 dest = 0;
dest |= (src & 0xff000000) >> 24;
dest |= (src & 0x00ff0000) >> 8;
dest |= (src & 0x0000ff00) << 8;
dest |= (src & 0x000000ff) << 24;
return dest;
}
#ifdef __LITTLE_ENDIAN
#define le_to_host32(n) (n)
#define be_to_host32(n) swap_bytes(n)
#define host_to_be32(n) swap_bytes(n)
#else // __BIG_ENDIAN
#define le_to_host32(n) swap_bytes(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#endif
/*
* Just a few functions so that I can't easily forget about
* endinness.
*/
struct __be32 {
u32 val;
} __attribute__((packed));
typedef struct __be32 be32;
/*
* These two obviously need to get fixed for
* big endian machines.
*/
static inline u32 be32_to_u32(be32 src)
{
return swap_bytes(src.val);
}
static inline be32 u32_to_be32(u32 src)
{
be32 ret;
ret.val = swap_bytes(src);
return ret;
}
/*
* Eye-Fi Card data structures
*/
struct card_seq_num {
u32 seq;
} __attribute__((packed));
#define EYEFI_BUF_SIZE 16384
/*
* Most of the eyefi strings are pascal-style with
* a length byte preceeding content. (Did pascal
* have just a byte for length or more??)
*/
struct pascal_string {
u8 length;
u8 value[32];
} __attribute__((packed));
struct var_byte_response {
u8 len;
u8 bytes[EYEFI_BUF_SIZE-1];
};
/*
* The 'o' command has several sub-commands:
*/
enum card_info_subcommand {
MAC_ADDRESS = 1,
FIRMWARE_INFO = 2,
CARD_KEY = 3,
API_URL = 4,
UNKNOWN_5 = 5, // Chris says these are
UNKNOWN_6 = 6, // checksums
LOG_LEN = 7,
WLAN_DISABLE = 10, // 1=disable 0=enable, write is 1 byte, read is var_byte
UPLOAD_PENDING= 11, // {0x1, STATE}
HOTSPOT_ENABLE= 12, // {0x1, STATE}
CONNECTED_TO = 13, // Currently connected Wifi network
UPLOAD_STATUS = 14, // current uploading file info
UNKNOWN_15 = 15, // always returns {0x01, 0x1d} as far as I've seen
TRANSFER_MODE = 17,
ENDLESS = 27, // 0x1b
DIRECT_MODE_SSID = 0x22, // 0 == "direct mode off"
DIRECT_MODE_PASS = 0x23, // set to 60 when direct mode off
DIRECT_WAIT_FOR_CONNECTION = 0x24, // 0 == "direct mode off"
DIRECT_WAIT_AFTER_TRANSFER = 0x25, // set to 60 when direct mode off
UPLOAD_KEY = 0xfd, //
UNKNOWN_ff = 0xff, // The D90 does this, and it looks to
// return a 1-byte response length
// followed by a number of 8-byte responses
// But I've only ever seen a single response
// [000]: 01 04 1d 00 18 56 aa d5 42 00 00 00 00 00 00 00
// It could be a consolidates info command like "info for
// everything" so the camera makes fewer calls.
};
// new code!!:
///media/NIKON D90/EYEFI/REQM
//00000000 4f 0a 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |O...............|
//00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
// that happens 3 seconds after the card goes into the D90
//
// 1301001235/0002/REQM: 00000000 4f 0c 01 01 00 00 00 00 00 00 00 00 00 00 00 00 |O...............|
// looks like it is setting the PC's IP address:
// 1300998375/0013/REQM: 00000000 4f 06 0d 0a 31 30 2e 38 2e 30 2e 31 32 33 00 00 |O...10.8.0.123..|
// 1300762293/0016/REQM: 00000000 4f 06 0d 0a 31 30 2e 36 2e 30 2e 31 32 33 00 00 |O...10.6.0.123..|
// 1300762293/0015/REQM: 00000000 4f 06 0d 0a 31 30 2e 36 2e 30 2e 31 32 33 00 00 |O...10.6.0.123..|
struct card_info_req {
u8 o;
u8 subcommand;
} __attribute__((packed));
struct card_config_cmd {
u8 O;
u8 subcommand;
union {
u8 u8_args[0];
struct var_byte_response arg;
};
} __attribute__((packed));
struct card_info_rsp_key {
struct pascal_string key;
};
struct card_firmware_info {
struct pascal_string info;
};
#define MAC_BYTES 6
struct mac_address {
u8 length;
u8 mac[MAC_BYTES];
} __attribute__((packed));
struct card_info_api_url {
struct pascal_string key;
};
struct card_info_log_len {
u8 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,
};
enum net_type {
NET_UNSECURED,
NET_WEP,
NET_WPA,
NET_WPA2
};
enum net_password_type {
NET_PASSWORD_ASCII,
NET_PASSWORD_RAW, /* raw hex bytes */
};
#define ESSID_LEN 32
struct scanned_net {
char essid[ESSID_LEN];
signed char strength;
u8 type;
} __attribute__((packed));
struct scanned_net_list {
u8 nr;
struct scanned_net nets[100];
} __attribute__((packed));
struct configured_net {
char essid[ESSID_LEN];
} __attribute__((packed));
struct configured_net_list {
u8 nr;
struct configured_net nets[100];
} __attribute__((packed));
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define WPA_KEY_BYTES 32
struct wpa_key {
u8 key[WPA_KEY_BYTES];
} __attribute((packed));
#define WEP_40_KEY_BYTES 5
#define WEP_KEY_BYTES 13
struct wep_key {
u8 key[WEP_KEY_BYTES];
} __attribute((packed));
struct network_key {
u8 len;
union {
struct wpa_key wpa;
struct wep_key wep;
};
} __attribute((packed));
#define KEY_LEN 32
struct net_request {
char req;
u8 essid_len;
char essid[ESSID_LEN];
struct network_key key;
} __attribute((packed));
struct noarg_request {
u8 req;
};
/*
* Log structures
*/
struct fetch_log_cmd {
char m;
be32 offset;
} __attribute__((packed));
/*
* When you ask for the log at offset 0x0, you
* get back 8 bytes of offsets into the rest of
* the data
*/
struct first_log_response {
be32 log_end;
be32 log_start;
u8 data[EYEFI_BUF_SIZE-8];
} __attribute__((packed));
struct rest_log_response {
u8 data[EYEFI_BUF_SIZE];
} __attribute__((packed));
struct upload_status {
u8 len;
// These are _transfer_ sizes. There's some padding probably for
// wifi metadata or something, so these end up being larger than
// the actual on-disk sizes of the jpgs or movies.
be32 http_len;
be32 http_done;
// There are two strings in here:
// 1. filename on the card
// \0
// 2. directory on the card where it was found
// \0
u8 string[0];
} __attribute__((packed));
/*
* Functions that are exported from eyefi-config.c
*/
u32 fetch_log_length(void);
int card_info_cmd(enum card_info_subcommand cmd);
int card_config_set(enum card_info_subcommand cmd, struct var_byte_response *args);
void *eyefi_response(void);
struct card_info_rsp_key *fetch_card_key(void);
struct card_info_rsp_key *fetch_card_upload_key(void);
int wlan_enabled(void);
void wlan_disable(int do_disable);
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);
int issue_noarg_command(u8 cmd);
char *net_test_state_name(u8 state);
int network_action(char cmd, char *essid, char *wpa_ascii);
char *locate_eyefi_mount(void);
void eject_card(void);
int get_log_into(u8 *resbuf);
void reboot_card(void);
void init_card(void);
void add_network(char *essid, char *ascii_password);
void remove_network(char *essid);
struct card_firmware_info *fetch_card_firmware_info(void);
int set_endless_percentage(int __percentage);
int endless_enable(int enable);
void print_endless(void);
/*
* Only used by the unix variants
*/
enum eyefi_file {
RDIR = 0,
REQC,
REQM,
RSPC,
RSPM
};
char *eyefi_file_on(enum eyefi_file file, char *mnt);
char *eyefi_file_name(enum eyefi_file file);
int atoh(char c);
#endif // _EYEFI_CONFIG_H