/* IR: A program to control the InfraRed Xpander(tm) IR-XP2(tm) device Copyright (C) 2005 Richard Heurtley 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /**---------------------------------------------------------------------------*/ #include #include /**---------------------------------------------------------------------------*/ int Receive(HANDLE handle, char *bufferp, DWORD nbytes, DWORD *nrecvp) { int rv = 0; int rc; DWORD nrecv; rc = ReadFile ( handle, bufferp, nbytes, &nrecv, 0 // overlapped structure ); if (!rc) { rc = GetLastError(); printf("Error: Windows error #%d during receive.\n", rc); rv = 1; goto EGRESS; } if (nrecv != nbytes) { printf("Error: %d of %d bytes received.\n", nrecv, nbytes); rv = 1; goto EGRESS; } if (nrecvp) *nrecvp = nrecv; EGRESS: return(rv); } /**---------------------------------------------------------------------------*/ int Transmit(HANDLE handle, char *bufferp, DWORD nbytes) { int rv = 0; int rc; DWORD nsent; if (nbytes == -1) nbytes = strlen(bufferp); rc = WriteFile ( handle, bufferp, nbytes, &nsent, 0 // overlapped structure ); if (!rc) { rc = GetLastError(); printf("Error: Windows error #%d during transmit.\n", rc); rv = 1; goto EGRESS; } if (nsent != nbytes) { printf("Error: %d of %d bytes sent.\n", nsent, nbytes); rv = 1; goto EGRESS; } EGRESS: return(rv); } /**---------------------------------------------------------------------------*/ #define NBYTES (2 * (3+2+2 + 64*2 + 2)) // 2x(---SSPP + 64*2 + CRLF) int main(int npars, char **pars) { int rv = 0; int n; int rc; int emitter; int freq; DWORD nrecv; double f; HANDLE handle; FILE *filep; static DCB dcb; static char command[64]; static char filename[64]; static char seq[NBYTES+64]; // padding handle = 0; filep = 0; if ( npars == 1 || (pars[1][0] != 'r' && pars[1][0] != 'p') || (pars[1][0] == 'r' && (npars != 3 && npars != 4)) || (pars[1][0] == 'p' && npars != 4) ) { printf("\n"); printf("IR: A program to control the InfraRed Xpander(tm) IR-XP2 device.\n"); printf("\n"); printf("Usage:\n"); printf("\n"); printf("C:\\>ir r sample_name -- to record a sequence\n"); printf("C:\\>ir p sample_name emitter_code -- to play a sequence\n"); printf("\n"); printf("The sample name cannot contain spaces or special characters.\n"); printf("\n"); printf("The emitter codes are:\n"); printf("\n"); printf(" Emitter Code\n"); printf(" ------- ----\n"); printf(" 1 1\n"); printf(" 2 2\n"); printf(" 3 4\n"); printf(" 4 8\n"); printf("\n"); printf("Emitter codes can be added to play a sequence\n"); printf("on more than one emitter at a time.\n"); printf("\n"); printf("You have five seconds to press the remote's button while recording a sequence.\n"); printf("\n"); printf("The optional carrier frequency is in KHz. The default is 40.0.\n"); printf("Other frequencies are 20.0, 36.7, 38.0, 56.8, 85.0.\n"); goto EGRESS; } if (pars[1][0] == 'r') // record { freq = 0; // 40KHz default if (npars == 4) { n = sscanf(pars[3], "%f", &f); if (n != 1) { printf("Error: Bad frequency \"%s\".\n", pars[3]); rv = 1; goto EGRESS; } freq = (int)((5000000.0 / f) + 0.5); } } else // play { n = sscanf(pars[3], "%d", &emitter); if (n != 1) { printf("Error: Bad emitter number \"%s\".\n", pars[3]); rv = 1; goto EGRESS; } } handle = CreateFile ( "COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 ); if (handle == INVALID_HANDLE_VALUE) { printf("Invalid handle value.\n"); rv = 1; goto EGRESS; } dcb.DCBlength = sizeof(dcb); rc = GetCommState(handle, &dcb); if (!rc) { printf("Error: Unable to get comm state.\n"); rv = 1; goto EGRESS; } dcb.BaudRate = CBR_2400; // 2400bps dcb.ByteSize = DATABITS_8; // 8 data bits dcb.StopBits = ONESTOPBIT; // one stop bit dcb.Parity = NOPARITY; // no parity dcb.fParity = FALSE; // do not check parity dcb.fDtrControl = DTR_CONTROL_ENABLE; // raise the outgoing DTR line dcb.fOutxDsrFlow = FALSE; // ignore incoming DSR flow control dcb.fOutxCtsFlow = FALSE; // ignore incoming CTS flow control dcb.fDsrSensitivity = FALSE; // ignore incoming DSR dcb.fDtrControl = RTS_CONTROL_ENABLE; // raise the outgoing RTS line dcb.fOutX = FALSE; // ignore incoming XON/XOFF flow control dcb.fInX = FALSE; // do not generate outgoing XON/XOFF flow control rc = SetCommState(handle, &dcb); if (!rc) { printf("Error: Unable to set comm state.\n"); rv = 1; goto EGRESS; } sprintf(filename, "%s.txt", pars[2]); if (pars[1][0] == 'r') // record { sprintf(command, "6C86F40105%2.2X00CC", freq); rv = Transmit(handle, command, -1); if (rv) { printf("Error: Unable to transmit learn command.\n"); goto EGRESS; } Sleep(6000); // sleep six seconds rv = Transmit(handle, "6C84F80101CC6D", -1); if (rv) { printf("Error: Unable to transmit download command.\n"); goto EGRESS; } rv = Receive(handle, seq, NBYTES, &nrecv); if (rv) { printf("Error: Unable to receive sequence.\n"); goto EGRESS; } filep = fopen(filename, "wb"); if (!filep) { printf("Error: Unable to create file \"%s\".\n", filename); rv = 1; goto EGRESS; } n = fwrite(seq, 1, NBYTES, filep); fclose(filep); filep = 0; if (n != NBYTES) { printf("Error: Unable to write file \"%s\".\n", filename); rv = 1; goto EGRESS; } } else // play { filep = fopen(filename, "rb"); if (!filep) { printf("Error: Unable to open file \"%s\".\n", filename); rv = 1; goto EGRESS; } n = fread(seq, 1, NBYTES, filep); fclose(filep); filep = 0; if (n != NBYTES) { printf("Error: Unable to read file \"%s\".\n", filename); rv = 1; goto EGRESS; } rv = Transmit(handle, "6C8FF901", -1); if (rv) { printf("Error: Unable to transmit upload command.\n"); rv = 1; goto EGRESS; } rv = Transmit(handle, seq, NBYTES); if (rv) { printf("Error: Unable to transmit sequence.\n"); rv = 1; goto EGRESS; } Sleep(100); // rest for a bit sprintf(command, "6C85F50101%2.2XCC", emitter); rv = Transmit(handle, command, -1); if (rv) { printf("Error: Unable to transmit play command.\n"); rv = 1; goto EGRESS; } } CloseHandle(handle); handle = 0; EGRESS: if (handle) CloseHandle(handle); if (filep) fclose(filep); return(rv); }