📄 irfunc.c
字号:
/* irfunc.c v0.3 (c) 1998 Tom Wheeley <tomw@tsys.demon.co.uk> */
/* this code is placed under the LGPL, see www.gnu.org for info */
/*
* irfunc.c, infrared functions (Irman specific)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "ir.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)
{
int rdchar;
if (ir_enabled) {
errno = EBUSY; /* we already have a high level ir setup */
return -1;
}
if (ir_open_port(filename) < 0) {
return -1;
}
ir_clear_buffer();
if (ir_write_char('I') < 0)
return -1;
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 = ENOEXEC;
return -1;
}
/* we are now ready to roll */
ir_enabled = 1;
return 0;
}
/* simply a wrapper for ir_close_port() */
int ir_finish(void)
{
if (!ir_enabled) {
errno = ENXIO;
return -1;
}
ir_enabled = 0;
return ir_close_port();
}
/* 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 LIBIR this seems the easiest way.
*/
static unsigned char *ir_read_code(unsigned long timeout)
{
static unsigned char codebuf[IR_CODE_LEN];
int i, datum;
datum = ir_read_char(timeout);
if (datum < 0)
return NULL;
codebuf[0] = (unsigned char) datum;
for (i=1; i<IR_CODE_LEN; i++) {
datum = ir_read_char(IR_POLL_TIMEOUT);
if (datum < 0) {
return NULL;
} else {
codebuf[i] = (unsigned char)datum;
}
}
return codebuf;
}
unsigned char *ir_get_code(void)
{
/* well dodgy choice of error here...! */
if (!ir_enabled) {
errno = ENXIO;
return NULL;
}
return ir_read_code(IR_BLOCKING);
}
unsigned char *ir_poll_code(void)
{
if (!ir_enabled) {
errno = ENXIO;
return NULL;
}
return ir_read_code(0);
}
char *ir_code_to_text(unsigned char *code)
{
static char text[2 * IR_CODE_LEN + 1];
int i;
char *j;
j = text;
for (i=0; i < IR_CODE_LEN; i++) {
*j++ = ir_hexdigit[code[i] >> 4];
*j++ = ir_hexdigit[code[i] & 15];
}
*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<IR_CODE_LEN; i++) {
if (!j[0] || !j[1]) {
break;
}
code[i] = (ir_hex_to_int(*j++) << 4) & 0xf0;
code[i] += (ir_hex_to_int(*j++) ) & 0x0f;
}
/* if string isn't long enough, pad with zeros. This is (marginally)
* better than the leaving in the remains of the last conversion
*/
for ( ; i<IR_CODE_LEN; i++)
code[i] = '\0';
return code;
}
/* this function should never be called, but maybe someone wants to manually
* open the ir channel, then use the higher level functions. If you use this
* then you deserve any problems you get! It is only here because I don't
* believe in unneccesary restrictions.
*/
void ir_set_enabled(int val)
{
ir_enabled = val;
}
/* end of irfunc.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -