/* irfunc.c v0.4.2 (c) 1998-99 Tom Wheeley */ /* this code is placed under the LGPL, see www.gnu.org for info */ /* * irfunc.c, infrared functions (Irman specific) */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include "irman.h" /* generic function for ir_get_code() and ir_poll_code() */ static unsigned char *ir_read_code(unsigned long timeout); /* converts a single hex character to an integer */ static int ir_hex_to_int(unsigned char hex); /* flag to enable use of higher level functions */ static int ir_enabled=0; /* output hex digits */ static char ir_hexdigit[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; int ir_init(char *filename) { #ifndef IR_SOFTWARE_TEST /* normal only */ int rdchar; #endif /* both */ int fd; if (ir_enabled) { errno = IR_EENABLED; /* we already have a high level ir setup */ return -1; } #ifndef IR_SOFTWARE_TEST /* normal only */ if ( (fd = ir_open_port(filename)) < 0) { return -1; } ir_clear_buffer(); if (ir_write_char('I') < 0) return -1; tcdrain(fd); ir_usleep(IR_HANDSHAKE_GAP); if (ir_write_char('R') < 0) return -1; /* we'll be nice and give the box a good chance to send an 'O' */ while ((rdchar = ir_read_char(IR_HANDSHAKE_TIMEOUT)) != 'O') { if (rdchar < 0) { /* error or timeout */ return -1; } } /* as regards the 'K', however, that really must be the next character */ rdchar = ir_read_char(IR_HANDSHAKE_TIMEOUT); if (rdchar < 0) { return -1; } /* ENOEXEC is the closest error I could find, that would also not be * generated by ir_read_char(). Anyway, ENOEXEC does more or less mean * "I don't understand this data I've been given" */ if (rdchar != 'K') { errno = IR_EHANDSHAKE; return -1; } #else /* software test only */ fd = 1; #endif /* IR_SOFTWARE_TEST */ /* both */ /* we are now ready to roll */ ir_enabled = 1; return fd; } /* simply a wrapper for ir_close_port() */ int ir_finish(void) { if (!ir_enabled) { errno = IR_EDISABLED; return -1; } ir_enabled = 0; #ifndef IR_SOFTWARE_TEST return ir_close_port(); #else return 0; #endif } /* this function is used by both ir_get_code() and ir_poll_code(), * the difference being in the timeout for the first piece of data. * we also have a short timeout whatever for the remaining five bytes, * in case computer and Irman get out of sync we can just raise an error * and get back to normal life. * * note esp. that these functions return a pointer to statically defined * data. In the forseeable usage of LIBIRMAN this seems the easiest way. */ #ifndef IR_SOFTWARE_TEST /* normal behaviour */ static unsigned char *ir_read_code(unsigned long timeout) { static unsigned char codebuf[2][IR_CODE_LEN]; static struct timeval lasttv = {0, 0}; static curbuf = 0; struct timeval tv; int i, datum; datum = ir_read_char(timeout); if (datum < 0) return NULL; codebuf[curbuf][0] = (unsigned char) datum; gettimeofday(&tv, NULL); for (i=1; i> 4) & 0x0f]; *j++ = ir_hexdigit[ code[i] & 0x0f]; } *j = '\0'; return text; } static int ir_hex_to_int(unsigned char hex) { if (hex >= '0' && hex <= '9') return hex - '0'; hex = tolower(hex); if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10; /* error! */ return 0; } unsigned char *ir_text_to_code(char *text) { static char code[IR_CODE_LEN]; int i; char *j; j = text; for (i=0; i