1 /*
2  * vim:tw=80:ai:tabstop=4:softtabstop=4:shiftwidth=4:expandtab
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * (C) Copyright Phil Dibowitz 2007
19  * (C) Copyright Kevin Timmerman 2007
20  */
21 
22 #ifndef LIBCONCORD_H
23 #define LIBCONCORD_H
24 
25 #include <stdio.h>
26 #include <stdint.h>
27 
28 #define LC_ERROR 1
29 #define LC_ERROR_INVALID_DATA_FROM_REMOTE 2
30 #define LC_ERROR_READ 3
31 #define LC_ERROR_WRITE 4
32 #define LC_ERROR_INVALIDATE 5
33 #define LC_ERROR_ERASE 6
34 #define LC_ERROR_VERIFY 7
35 #define LC_ERROR_POST 8
36 #define LC_ERROR_GET_TIME 9
37 #define LC_ERROR_SET_TIME 10
38 #define LC_ERROR_CONNECT 11
39 #define LC_ERROR_OS 12
40 #define LC_ERROR_OS_NET 13
41 #define LC_ERROR_OS_FILE 14
42 #define LC_ERROR_UNSUPP 15
43 #define LC_ERROR_INVALID_CONFIG 16
44 #define LC_ERROR_IR_OVERFLOW 17
45 
46 /*
47  * Filetypes, used by identity_file()
48  */
49 #define LC_FILE_TYPE_CONNECTIVITY 1
50 #define LC_FILE_TYPE_CONFIGURATION 2
51 #define LC_FILE_TYPE_FIRMWARE 3
52 #define LC_FILE_TYPE_LEARN_IR 4
53 /*
54  * Callback counter types
55  */
56 #define LC_CB_COUNTER_TYPE_STEPS 5
57 #define LC_CB_COUNTER_TYPE_BYTES 6
58 /*
59  * Callback stages
60  */
61 #define LC_CB_STAGE_NUM_STAGES 0xFF
62 #define LC_CB_STAGE_GET_IDENTITY 7
63 /* for config updates... */
64 #define LC_CB_STAGE_INITIALIZE_UPDATE 8
65 #define LC_CB_STAGE_INVALIDATE_FLASH 9
66 #define LC_CB_STAGE_ERASE_FLASH 10
67 #define LC_CB_STAGE_WRITE_CONFIG 11
68 #define LC_CB_STAGE_VERIFY_CONFIG 12
69 #define LC_CB_STAGE_FINALIZE_UPDATE 13
70 #define LC_CB_STAGE_READ_CONFIG 14
71 /* firmware updates share most of the above, but need */
72 #define LC_CB_STAGE_WRITE_FIRMWARE 15
73 #define LC_CB_STAGE_READ_FIRMWARE 16
74 #define LC_CB_STAGE_READ_SAFEMODE 17
75 /* other... */
76 #define LC_CB_STAGE_RESET 18
77 #define LC_CB_STAGE_SET_TIME 19
78 #define LC_CB_STAGE_HTTP 20
79 #define LC_CB_STAGE_LEARN 21
80 
81 
82 /*
83  * Actual C clients are not fully supported yet, but that's the goal...
84  */
85 #ifdef __cplusplus
86 extern "C" {
87 #endif
88 
89 /*
90  * CALLBACK INFORMATION
91  *
92  * There is currently only one kind of callback, and it's for status
93  * information. It should be a void function and takes the following
94  * arguments:
95  *   uint32_t stage_id - the id of the stage
96  *   uint32_t count - the amount of times this cb has been called in a
97  *                    given call of a given functioin
98  *   uint32_t curr  - current status (usually bytes read/written)
99  *   uint32_t total - total goal status (usually bytes expected to read/write)
100  *   uint32_t counter_type - the type of counter (bytes, steps, etc.)
101  *   void *arg      - opaque object you can pass to functions to have them
102  *                    pass back to your callback.
103  *   const uint32_t* stages - a pointer to the stages that will be
104  *                            performed for this operation.  Only used when
105  *                            LC_CB_STAGE_NUM_STAGES is the callback stage.
106  */
107 typedef void (*lc_callback)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
108     void*, const uint32_t*);
109 
110 /*
111  * REMOTE INFORMATION ACCESSORS
112  *
113  * These take nothing, and return what they say. Simple stuff.
114  */
115 const char *get_mfg();
116 const char *get_model();
117 const char *get_codename();
118 int get_skin();
119 int get_fw_ver_maj();
120 int get_fw_ver_min();
121 int get_fw_type();
122 int get_hw_ver_maj();
123 int get_hw_ver_min();
124 int get_hw_ver_mic();
125 int get_flash_size();
126 int get_flash_mfg();
127 int get_flash_id();
128 const char *get_flash_part_num();
129 int get_arch();
130 int get_proto();
131 const char *get_hid_mfg_str();
132 const char *get_hid_prod_str();
133 int get_hid_irl();
134 int get_hid_orl();
135 int get_hid_frl();
136 int get_usb_vid();
137 int get_usb_pid();
138 int get_usb_bcd();
139 char *get_serial(int p);
140 int get_config_bytes_used();
141 int get_config_bytes_total();
142 
143 /*
144  * Support helpers
145  */
146 /*
147  * We don't yet support all things on all remotes, so these try to help you
148  * figure out if something is supported.
149  * NOTE WELL: If they are a remote we don't know about, the results are
150  * meaningless.
151  *
152  * This will return 0 for yes and LC_ERROR_UNSUPP otherwise.
153  */
154 int is_config_dump_supported();
155 int is_config_update_supported();
156 int is_fw_dump_supported();
157 int is_fw_update_supported(int direct);
158 
159 /*
160  * TIME ACCESSORS
161  *
162  * These can ONLY be called *after* get_time() or set_time(). Each call will
163  * initialize the internal time structures to the time used, and these
164  * accessors can be used to access that data.
165  */
166 int get_time_second();
167 int get_time_minute();
168 int get_time_hour();
169 int get_time_day();
170 int get_time_dow();
171 int get_time_month();
172 int get_time_year();
173 int get_time_utc_offset();
174 const char *get_time_timezone();
175 
176 /*
177  * HELPER FUNCTIONS
178  */
179 
180 /*
181  * Translate a return value into an actual error message. Pass in the int
182  * you received, get back a string.
183  */
184 const char *lc_strerror(int err);
185 const char *lc_cb_stage_str(int stage);
186 /*
187  * Many functions require you to pass in a ptr which then gets pointed
188  * to data that we allocate. You should then call this to clean that
189  * data up when you are done with it.
190  */
191 void delete_blob(uint8_t *ptr);
192 
193 /*
194  * Read an operations file from the website, parse it, and return a mode
195  * of operations.
196  */
197 int read_and_parse_file(char *filename, int *type);
198 /*
199  * Free the memory used by the file as allocated in read_and_parse_file.
200 */
201 void delete_opfile_obj();
202 
203 /*
204  * GENERAL REMOTE INTERACTIONS
205  */
206 
207 /*
208  * Initialize USB (and WinSock if necessary) and find the remote
209  * if possible.
210  */
211 int init_concord();
212 /*
213  * Release the USB device, and tear down anything else necessary.
214  */
215 int deinit_concord();
216 /*
217  * This is another initialization function. Generally speaking you always
218  * want to call this before you do anything. It will query the remote about
219  * it's data and fill in internal data structures with that information. This
220  * counts as a successful "connectivity test"
221  */
222 int get_identity(lc_callback cb, void *cb_arg);
223 /*
224  * Reboot the remote.
225  */
226 int reset_remote(lc_callback cb, void *cb_arg);
227 /*
228  * Get the time from the remote. Use the time accessors above to access
229  * the data.
230  */
231 int get_time();
232 /*
233  * Set the time on the remote to the system time. To find out what time was
234  * used, use the time accessors above.
235  */
236 int set_time(lc_callback cb, void *cb_arg);
237 /*
238  * POST to the members.harmonyremote.com website that the connection test was
239  * successful. A Connectivity.EZHex file must be passed in so that we
240  * can get the URL, cookie information, etc.
241  */
242 int post_connect_test_success(lc_callback cb, void *cb_arg);
243 /*
244  * Prior to updating the config, if you want to interact with the website
245  * you have to send it some initial data. This does that. The data passed
246  * in here is a pointer to the config data config block (with XML - this
247  * should NOT be the pointer result from find_binary_start().
248  */
249 int post_preconfig(lc_callback cb, void *cb_arg);
250 /*
251  * After writing the config to the remote, this should be called to tell
252  * the members.harmonyremote.com website that it was successful.
253  */
254 int post_postconfig(lc_callback cb, void *cb_arg);
255 /*
256  * After writing a new firmware to the remote, this should be called to tell
257  * the members.harmonyremote.com website that it was successful.
258  */
259 int post_postfirmware(lc_callback cb, void *cb_arg);
260 /*
261  * This sends the remote a command to tell it we're about to start
262  * writing to it's flash area and that it shouldn't read from it.
263  * This must be used before writing a config, firmware, or anything
264  * else that touches flash.
265  *
266  * If something goes wrong, or you change your mind after invalidating
267  * flash, you should reboot the device.
268  */
269 int invalidate_flash(lc_callback cb, void *cb_arg);
270 
271 /*
272  * CONFIGURATION INTERACTIONS
273  */
274 
275 /*
276  * NOTE: This is the only function you should need to update a remote's config.
277  * This wraps calls to all other calls and handles all remote-specific logic for
278  * you.
279  *
280  * The other functions are provided mostly for backwards compatibility, and for
281  * backing up remote configs. If you don't need to do that, you can skip down to
282  * the next section.
283  */
284 int update_configuration(lc_callback cb, void *cb_arg, int noreset);
285 
286 /*
287  * Read the config from the remote and store it into the unit8_t array
288  * *out. The callback is for status information. See above for CB info.
289  *
290  * NOTE: The pointer *out should not point to anything useful. We will
291  * allocate a char array and point your pointer at it. Use delete_blob to
292  * reclaim this memory.
293  */
294 int read_config_from_remote(uint8_t **out, uint32_t *size, lc_callback cb,
295                             void *cb_arg);
296 /*
297  * Given a config block in the byte array *in that is size big, write
298  * it to the remote. This should be *just* the binary blob (see
299  * find_binary_start()). CB info above.
300  *
301  */
302 int write_config_to_remote(lc_callback cb, void *cb_arg);
303 /*
304  * Given a binary-only config blob *in, write the config to a file. Unless
305  * binary is true, the XML will be constructed and written to the file
306  * as well.
307  */
308 int write_config_to_file(uint8_t *in, uint32_t size, char *file_name,
309                          int binary);
310 /*
311  * After doing a write_config_to_remote(), this should be called to verify
312  * that config. The data will be compared to what's in *in.
313  */
314 int verify_remote_config(lc_callback cb, void *cb_arg);
315 /*
316  * Preps the remote for a config upgrade.
317  *
318  * Note that this and finish_config are NO-OPs for most remotes, and even on
319  * remotes where it is implemented, testing implies that it's not necessary.
320  * However, calling these functions is necessary to completely match the
321  * original Windows software, and future remotes may require these functions
322  * to be executed to operate correctly.
323  */
324 int prep_config(lc_callback cb, void *cb_arg);
325 /*
326  * Tells the remote the config upgrade was successful and that it should
327  * use the new config upon next reboot.
328  */
329 int finish_config(lc_callback cb, void *cb_arg);
330 /*
331  * Flash can be changed to 0, but not back to 1, so you must erase the
332  * flash (to 1) in order to write the flash.
333  */
334 int erase_config(lc_callback cb, void *cb_arg);
335 
336 /*
337  * SAFEMODE FIRMWARE INTERACTIONS
338  */
339 /*
340  * Make the safemode area of the flash all 1's so you can write
341  * to it.
342  */
343 int erase_safemode(lc_callback cb, void *cb_arg);
344 /*
345  * Same as read_config_from_remote(), but reading the safemode firmware
346  * instead.
347  *
348  * NOTE: The pointer *out should not point to anything useful. We will
349  * allocate a char array and point your pointer at it. Use delete_blob to
350  * reclaim this memory.
351  */
352 int read_safemode_from_remote(uint8_t **out, uint32_t *size, lc_callback cb,
353                               void *cb_arg);
354 /*
355  * NOTE: You CAN NOT WRITE SAFEMODE FIRMWARE OVER USB!
356  */
357 
358 /*
359  * Write aforementioned safemode data to a file. Note that this is always
360  * written as pure binary.
361  */
362 int write_safemode_to_file(uint8_t *in, uint32_t size, char *file_name);
363 
364 /*
365  * FIRMWARE INTERACTIONS
366  */
367 
368 /*
369  * NOTE: This is the only function you should need.
370  * This wraps calls to all other calls and handles all remote-specific logic for
371  * you. The other functions are provided mostly for backwards compatibility.
372  * You can skip down to the next section.
373  */
374 int update_firmware(lc_callback cb, void *cb_arg, int noreset, int direct);
375 
376 /*
377  * This function tells you if the config will be wiped out by a live
378  * firmware upgrade (some remotes use the config area in memory as a
379  * staging area for the firmware). This will return 0 for yes and LC_ERROR
380  * for no.
381  */
382 int is_config_safe_after_fw();
383 /*
384  * Preps the remote for a firmware upgrade
385  */
386 int prep_firmware(lc_callback cb, void *cb_arg);
387 /*
388  * Tells the remote the firmware upgrade was successful and that it should
389  * copy the firmware from the "staging" area to the live area on next reboot.
390  * Don't forget to reboot.
391  */
392 int finish_firmware(lc_callback cb, void *cb_arg);
393 /*
394  * Make the firmware area of the flash all 1's so you can write
395  * to it.
396  */
397 int erase_firmware(int direct, lc_callback cb, void *cb_arg);
398 /*
399  * Same as read_config_from_remote(), but reading the firmware instead.
400  *
401  * NOTE: The pointer *out should not point to anything useful. We will
402  * allocate a char array and point your pointer at it. Use delete_blob to
403  * reclaim this memory.
404  */
405 int read_firmware_from_remote(uint8_t **out, uint32_t *size, lc_callback cb,
406                               void *cb_arg);
407 /*
408  * Same as write_config_to_remote(), but with the firmware instead.
409  */
410 int write_firmware_to_remote(int direct, lc_callback cb, void *cb_arg);
411 /*
412  * Same as write_config_to_file(), but with firmware instead. Note
413  * that unless binary is specified, the firmware is broken into chunks
414  * and written in ASCII-encoded HEX in XML <DATA> blocks, the way
415  * the members.harmonyremote.com website delivers it.
416  */
417 int write_firmware_to_file(uint8_t *in, uint32_t size, char *file_name,
418                            int binary);
419 
420 /*
421  * IR-stuff
422  * ===========================
423  * Data structure information:
424  *
425  * carrier_clock    : in Hz, usually ~36000..40000
426  * ir_signal        : IR mark/space durations (alternating) in microsconds
427  * ir_signal_length : total number of mark/space durations in ir_signal
428  *      ir_signal will start with a mark and end with a space duration,
429  *      hence ir_signal_length will always be an even number.
430  *
431  * They are usually filled in by calling learn_from_remote(...),
432  * to learn IR signals from an existing other remote, but may also
433  * be set by the application, e.g. be derived from Pilips Pronto Hex
434  * codes or RC5/NEC/... command codes (separate conversion library required).
435  *
436  * encoded posting format : IR code data converted to Logitech
437  *     posting string format, returned by encode_for_posting.
438  *     Having the encoding separate from the posting keeps the
439  *     parameter list of post_new_code() tidy and allows the
440  *     application to display the encoded signal when desired.
441  */
442 
443 /*
444  * Scan the contents of the received LearnIR.EZTut file
445  * (read into *data[size]) for the key names to be learned.
446  *
447  * Fills key_names with the found names and key_names_length
448  * with the number of found key names.
449  * Returns 0 for success, or an error code in case of failure.
450  *
451  * Memory allocated for the strings must be freed by the caller
452  * via delete_key_names() when not needed any longer.
453  */
454 int get_key_names(char ***key_names, uint32_t *key_names_length);
455 
456 void delete_key_names(char **key_names, uint32_t key_names_length);
457 
458 /*
459  * Fill ir_data with IR code learned from other remote
460  * via Harmony IR receiver.
461  *
462  * Returns 0 for success, error code for failure.
463  *
464  * Memory allocated for ir_signal must be freed by the caller
465  * via delete_ir_signal() when not needed any longer.
466  */
467 int learn_from_remote(uint32_t *carrier_clock, uint32_t **ir_signal,
468                       uint32_t *ir_signal_length, lc_callback cb, void *cb_arg);
469 
470 void delete_ir_signal(uint32_t *ir_signal);
471 
472 /*
473  * Fill encoded_signal with IR code encoded to Logitech
474  * posting string format.
475  *
476  * Returns 0 for success, error code in case of failure.
477  *
478  * Memory allocated for the string must be freed by the caller
479  * via delete_post_string() when not needed any longer.
480  */
481 int encode_for_posting(uint32_t carrier_clock, uint32_t *ir_signal,
482                        uint32_t ir_signal_length, char **encoded_signal);
483 
484 void delete_encoded_signal(char *encoded_signal);
485 
486 /*
487  * Post encoded IR-code with key_name and additional
488  * information from XML data[size] to Logitech.
489  *
490  * Logitech will only accept keynames already present in the
491  * database or user-defined via 'Learn new Key' web page
492  * for the current device.
493  *
494  * Returns 0 for success, error code for failure.
495  */
496 int post_new_code(char *key_name, char *encoded_signal, lc_callback cb,
497                   void *cb_arg);
498 
499 /*
500  * Special structures and methods for the Harmony Link
501  */
502 #define MH_STRING_LENGTH 255 /* arbitrary */
503 #define MH_MAX_WIFI_NETWORKS 30 /* arbitrary */
504 struct mh_cfg_properties {
505     char host_name[MH_STRING_LENGTH];
506     char email[MH_STRING_LENGTH];
507     char service_link[MH_STRING_LENGTH];
508 };
509 struct mh_wifi_config {
510     char ssid[MH_STRING_LENGTH];
511     char encryption[MH_STRING_LENGTH];
512     char password[MH_STRING_LENGTH];
513     char connect_status[MH_STRING_LENGTH];
514     char error_code[MH_STRING_LENGTH];
515 };
516 struct mh_wifi_network {
517     char ssid[MH_STRING_LENGTH];
518     char signal_strength[MH_STRING_LENGTH];
519     char channel[MH_STRING_LENGTH];
520     char encryption[MH_STRING_LENGTH];
521 };
522 struct mh_wifi_networks {
523     struct mh_wifi_network network[MH_MAX_WIFI_NETWORKS];
524 };
525 int mh_get_cfg_properties(struct mh_cfg_properties *properties);
526 int mh_set_cfg_properties(const struct mh_cfg_properties *properties);
527 int mh_get_wifi_networks(struct mh_wifi_networks *networks);
528 int mh_get_wifi_config(struct mh_wifi_config *config);
529 int mh_set_wifi_config(const struct mh_wifi_config *config);
530 const char *mh_get_serial();
531 int mh_read_file(const char *filename, uint8_t *buffer, const uint32_t buflen,
532                  uint32_t *data_read);
533 int mh_write_file(const char *filename, uint8_t *buffer,
534                   const uint32_t buflen);
535 
536 #ifdef __cplusplus
537 }
538 #endif
539 
540 #endif /* LIBCONCORD_H */
541