26.12.2018
Program, který je napsaný pro OS GNU/Linux, běží v terminálu a nevyžaduje (nepřijímá) žádné parametry. Zdrojový kód je možné si stáhnout. Kód se přeloží jednoduše, např. gcc -o remotePC remotePC.c.
Program na počátku testuje, zda existuje soubor /dev/ttyACM0 nebo ttyACM1. Jakmile je některý ze souborů detekován, zjišťuje se, jestli je přístupný pro čtení a zápis pro běžného uživatele (jestli má práva pro přístup k souboru skupina s ID různým od 0).
Následně se soubor otevře pro čtení a zápis a odešlou se dva byty s hodnotami 0xAA, 0x55. Dále se v cyklu čeká, až přijde 8mi znakový řetězec, který se porovnává s uloženými hodnotami. Jakmile je nalezena shoda, vykoná se předdefinovaná operace. Zároveň se v terminálu vypíše přijatý kód.
Kódy dálkového ovladače jsem do programu zapsal "napevno". Jistě by se daly programy v PICu i PC snadno upravit tak, aby se kódy z dálkového ovladače přenesly do PC, kde by si uživatel například v grafickém prostředí ke kódům přiřadil požadované akce. Nicméně je to zbytečná práce vzhledem k tomu, že využívám pouhých 7 kódů, které se nebudou měnit. Navíc případné přidání dalších kódů/akcí do programu je triviální záležitost.
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#define PREFIX "/dev/"
#define _POSIX_SOURCE 1
int main()
{
char devicename1[50];
char devicename2[50];
sprintf(devicename1,"%s%s",PREFIX,"ttyACM0");
sprintf(devicename2,"%s%s",PREFIX,"ttyACM1");
char *devicename;
unsigned int BAUDRATE=B9600;
unsigned long seconds=0;
struct stat sts1,sts2,*sts;
while (
((stat(devicename1,&sts1)==-1) && (errno==ENOENT)) &&
((stat(devicename2,&sts2)==-1) && (errno==ENOENT))
)
{
printf("\nfiles %s;%s do not exist, %lu seconds",devicename1,devicename2,seconds);
sleep(2);
seconds+=2;
}
devicename=((stat(devicename1,&sts1)!=-1) ? devicename1 : devicename2);
sts=((devicename==devicename1) ? &sts1 : &sts2);
printf("\n\nfile %s exists (%lu seconds)\n\n",devicename,seconds);
seconds=0;
while ((sts->st_gid)==0)
{
printf("group ID of the %s file's group: %u, %lu seconds\n",devicename,sts->st_gid,seconds);
sleep(2);
seconds+=2;
stat(devicename,sts);
}
printf("\ngroup ID of the %s file's group is not 0 (%lu seconds)\n\n\n",devicename,seconds);
int fd,res;
struct termios oldtio,newtio;
char buf[20];
if (!(fd=open(devicename,O_RDWR|O_NOCTTY)))
{
return(-1);
}
tcgetattr(fd,&oldtio);
memset(&newtio,0,sizeof(newtio));
newtio.c_cflag=BAUDRATE|CRTSCTS|CS8|CLOCAL|CREAD;
newtio.c_iflag=IGNPAR;
newtio.c_oflag=0;
newtio.c_lflag=0;
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
tcflush(fd,TCIOFLUSH);
unsigned char d[2]={0xAA,0x55};
write(fd,d,2);
printf("Sent: %02X%02X\n\n",d[0],d[1]);
puts("waiting for data...\n\n");
while (1)
{
res=read(fd,buf,8);
if (res==8)
{
buf[res]='\0';
printf("%s\n",buf);
if (0==strcmp(buf,"00FFE01F"))
system("pactl set-sink-volume 0 -10%");
else if (0==strcmp(buf,"00FFA857"))
system("pactl set-sink-volume 0 +10%");
else if (0==strcmp(buf,"00FF906F"))
system("pactl set-sink-mute 0 toggle");
else if (0==strcmp(buf,"00FFA25D"))
system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
/org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous");
else if (0==strcmp(buf,"00FFE21D"))
system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
/org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next");
else if (0==strcmp(buf,"00FFC23D"))
system("dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc
/org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause");
else if (0==strcmp(buf,"00FF52AD"))
{
puts("Program will be terminated in a moment...\n");
tcflush(fd,TCIOFLUSH);
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
sleep(2);
return 0;
}
}
else
tcflush(fd,TCIFLUSH);
usleep(100000);
}
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
return 0;
}