<commit_before>/****************************************************************************
** irtoy.c **********************************************************
****************************************************************************
*
* Routines for USB Infrared Toy receiver/transmitter in sampling mode
*
* Copyright (C) 2011 <NAME> <<EMAIL>>
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Library General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>

#include "lirc_driver.h"
#include "lirc/serial.h"


#define IRTOY_MINFWVERSION 20

#define IRTOY_UNIT 21.3333
#define IRTOY_LONGSPACE 1000000


const unsigned char IRTOY_COMMAND_TXSTART[] = { 0x24, 0x25, 0x26, 0x03 };
static const unsigned char cmdIOwrite = 0x30; // Sets the IO pins to ground (0) or +5volt (1).
static const unsigned char cmdIOdirection = 0x31; // Sets the IO pins to input (1) or output (0).
#define IRTOY_COMMAND_RESET 0
#define IRTOY_COMMAND_SMODE_ENTER 's'
#define IRTOY_COMMAND_VERSION 'v'

#define IRTOY_REPLY_XMITCOUNT 't'
#define IRTOY_REPLY_XMITSUCCESS 'C'
#define IRTOY_REPLY_VERSION 'V'
#define IRTOY_REPLY_SAMPLEMODEPROTO 'S'

#define IRTOY_LEN_XMITRES 4
#define IRTOY_LEN_VERSION 4
#define IRTOY_LEN_SAMPLEMODEPROTO 3

#define IRTOY_TIMEOUT_READYFORDATA 1000000
#define IRTOY_TIMEOUT_FLUSH 20000
#define IRTOY_TIMEOUT_SMODE_ENTER 500000
#define IRTOY_TIMEOUT_VERSION 500000

// To aid debugging, attach LEDs to the pins below. They will light up
// under certain circumstances, helping to find out what the driver does.
// If not needed, the performance penalty is believed to be very small.

/** This LED lights when device is held open. */
static const int openPin = 5; // RA5

/** This LED lights when the device is listening for inputs. */
static const int receivePin = 3; // RA3

/** This LED LED lights during IR signal transmission. */
static const int sendingPin = 4; // RA4

struct tag_irtoy_t {
	int	hwVersion;
	int	swVersion;
	int	protoVersion;
	int	fd;
	int	awaitingNewSig;
	int	pulse;
};

typedef struct tag_irtoy_t irtoy_t;

static irtoy_t* dev = NULL;

static unsigned char rawSB[WBUF_SIZE * 2 + 2];

/* exported functions  */
static int init(void);
static int deinit(void);
static int send(struct ir_remote* remote, struct ir_ncode* code);
static char* receive(struct ir_remote* remotes);
static int decode(struct ir_remote* remote, struct decode_ctx_t* ctx);
static lirc_t readdata(lirc_t timeout);


const struct driver hw_usbirtoy = {
	.name		= "irtoy",
	.device		= "/dev/ttyACM0",
	.features	= LIRC_CAN_REC_MODE2 | LIRC_CAN_SEND_PULSE,
	.send_mode	= LIRC_MODE_PULSE,
	.rec_mode	= LIRC_MODE_MODE2,
	.code_length	= 0,
	.init_func	= init,
	.deinit_func	= deinit,
	.open_func	= default_open,
	.close_func	= default_close,
	.send_func	= send,
	.rec_func	= receive,
	.decode_func	= decode,
	.drvctl_func	= NULL,
	.readdata	= readdata,
	.api_version	= 2,
	.driver_version = "0.9.2",
	.info		= "No info available"
};


const struct driver* hardwares[] = {
	&hw_usbirtoy,
	(const struct driver*)NULL
};


static int decode(struct ir_remote* remote, struct decode_ctx_t* ctx)
{
	int res;

	LOGPRINTF(1, "decode: enter");

	res = receive_decode(remote, ctx);

	LOGPRINTF(1, "decode: %d", res);

	return res;
}

static unsigned int IOdirections = (unsigned int) -1;
static unsigned int IOdata = 0U;

int send3(unsigned char cmd, unsigned int data)
{
	unsigned char array[3];
	int res;
	array[0] = cmd;
	array[1] = (unsigned char) ((data >> 8) & 0xff);
	array[2] = (unsigned char) (data & 0xff);
	res = write(dev->fd, array, 3);
	if (res != 3)
		logprintf(LIRC_ERROR, "irtoy_setIOData: couldn't write command");
	return res == 3;
}

static int setIOData(void)
{
	return send3(cmdIOdirection, IOdirections) && send3(cmdIOwrite, IOdata);
}

static int setPin(unsigned int pin, int state)
{
	unsigned int mask = 1 << pin;
	IOdirections &= ~mask;
	if (state)
		IOdata |= mask;
	else
		IOdata &= ~mask;
	return setIOData();
}

static ssize_t
read_with_timeout(int fd, void* buf, size_t count, long to_usec)
{
	ssize_t rc;
	size_t numread = 0;
	struct timeval timeout;
	fd_set fds;

	timeout.tv_sec = 0;
	timeout.tv_usec = to_usec;

	rc = read(fd, (char*)buf, count);

	if (rc > 0)
		numread += rc;

	while ((rc == -1 && errno == EAGAIN) || (rc >= 0 && numread < count)) {
		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		rc = select(fd + 1, &fds, NULL, NULL, &timeout);

		if (rc == 0)
			/* timeout */
			break;
		else if (rc == -1)
			/* continue for EAGAIN case */
			continue;

		rc = read(fd, ((char*)buf) + numread, count - numread);

		if (rc > 0)
			numread += rc;
	}
	return (numread == 0) ? -1 : numread;
}
<commit_msg>plugins:irtoy:Use poll() instead of select().<commit_after>/****************************************************************************
** irtoy.c **********************************************************
****************************************************************************
*
* Routines for USB Infrared Toy receiver/transmitter in sampling mode
*
* Copyright (C) 2011 <NAME> <<EMAIL>>
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Library General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
*/

#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>

#include "lirc_driver.h"
#include "lirc/serial.h"


#define IRTOY_MINFWVERSION 20

#define IRTOY_UNIT 21.3333
#define IRTOY_LONGSPACE 1000000


const unsigned char IRTOY_COMMAND_TXSTART[] = { 0x24, 0x25, 0x26, 0x03 };
static const unsigned char cmdIOwrite = 0x30; // Sets the IO pins to ground (0) or +5volt (1).
static const unsigned char cmdIOdirection = 0x31; // Sets the IO pins to input (1) or output (0).
#define IRTOY_COMMAND_RESET 0
#define IRTOY_COMMAND_SMODE_ENTER 's'
#define IRTOY_COMMAND_VERSION 'v'

#define IRTOY_REPLY_XMITCOUNT 't'
#define IRTOY_REPLY_XMITSUCCESS 'C'
#define IRTOY_REPLY_VERSION 'V'
#define IRTOY_REPLY_SAMPLEMODEPROTO 'S'

#define IRTOY_LEN_XMITRES 4
#define IRTOY_LEN_VERSION 4
#define IRTOY_LEN_SAMPLEMODEPROTO 3

#define IRTOY_TIMEOUT_READYFORDATA 1000000
#define IRTOY_TIMEOUT_FLUSH 20000
#define IRTOY_TIMEOUT_SMODE_ENTER 500000
#define IRTOY_TIMEOUT_VERSION 500000

// To aid debugging, attach LEDs to the pins below. They will light up
// under certain circumstances, helping to find out what the driver does.
// If not needed, the performance penalty is believed to be very small.

/** This LED lights when device is held open. */
static const int openPin = 5; // RA5

/** This LED lights when the device is listening for inputs. */
static const int receivePin = 3; // RA3

/** This LED LED lights during IR signal transmission. */
static const int sendingPin = 4; // RA4

struct tag_irtoy_t {
	int	hwVersion;
	int	swVersion;
	int	protoVersion;
	int	fd;
	int	awaitingNewSig;
	int	pulse;
};

typedef struct tag_irtoy_t irtoy_t;

static irtoy_t* dev = NULL;

static unsigned char rawSB[WBUF_SIZE * 2 + 2];

/* exported functions  */
static int init(void);
static int deinit(void);
static int send(struct ir_remote* remote, struct ir_ncode* code);
static char* receive(struct ir_remote* remotes);
static int decode(struct ir_remote* remote, struct decode_ctx_t* ctx);
static lirc_t readdata(lirc_t timeout);


const struct driver hw_usbirtoy = {
	.name		= "irtoy",
	.device		= "/dev/ttyACM0",
	.features	= LIRC_CAN_REC_MODE2 | LIRC_CAN_SEND_PULSE,
	.send_mode	= LIRC_MODE_PULSE,
	.rec_mode	= LIRC_MODE_MODE2,
	.code_length	= 0,
	.init_func	= init,
	.deinit_func	= deinit,
	.open_func	= default_open,
	.close_func	= default_close,
	.send_func	= send,
	.rec_func	= receive,
	.decode_func	= decode,
	.drvctl_func	= NULL,
	.readdata	= readdata,
	.api_version	= 2,
	.driver_version = "0.9.2",
	.info		= "No info available"
};


const struct driver* hardwares[] = {
	&hw_usbirtoy,
	(const struct driver*)NULL
};


static int decode(struct ir_remote* remote, struct decode_ctx_t* ctx)
{
	int res;

	LOGPRINTF(1, "decode: enter");

	res = receive_decode(remote, ctx);

	LOGPRINTF(1, "decode: %d", res);

	return res;
}

static unsigned int IOdirections = (unsigned int) -1;
static unsigned int IOdata = 0U;

int send3(unsigned char cmd, unsigned int data)
{
	unsigned char array[3];
	int res;
	array[0] = cmd;
	array[1] = (unsigned char) ((data >> 8) & 0xff);
	array[2] = (unsigned char) (data & 0xff);
	res = write(dev->fd, array, 3);
	if (res != 3)
		logprintf(LIRC_ERROR, "irtoy_setIOData: couldn't write command");
	return res == 3;
}

static int setIOData(void)
{
	return send3(cmdIOdirection, IOdirections) && send3(cmdIOwrite, IOdata);
}

static int setPin(unsigned int pin, int state)
{
	unsigned int mask = 1 << pin;
	IOdirections &= ~mask;
	if (state)
		IOdata |= mask;
	else
		IOdata &= ~mask;
	return setIOData();
}

static ssize_t
read_with_timeout(int fd, void* buf, size_t count, long to_usec)
{
	ssize_t rc;
	size_t numread = 0;
	struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};

	rc = read(fd, (char*)buf, count);

	if (rc > 0)
		numread += rc;

	while ((rc == -1 && errno == EAGAIN) || (rc >= 0 && numread < count)) {

		rc = poll(&pfd, 1, to_usec / 1000);

		if (rc == 0)
			/* timeout */
			break;
		else if (rc == -1)
			/* continue for EAGAIN case */
			continue;

		rc = read(fd, ((char*)buf) + numread, count - numread);

		if (rc > 0)
			numread += rc;
	}
	return (numread == 0) ? -1 : numread;
}

{'fraction_non_alphanumeric': 0.14854573814111385, 'fraction_numerical': 0.023671896504266446, 'mean_word_length': 4.406746031746032, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3255078', 'n_tokens_mistral': 4136, 'n_tokens_neox': 3836, 'n_words': 1253}