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