/* * lampd.c * * Written by Daan Vreeken * Danovitsch @ Vitsch . net * * Published under the terms of the GNU Public License 2.0 * (or any later version) */ #include "lampd.h" #define Lamps 3 #define Invert 1 struct SLamp { enum LampState State; enum LampState DefaultState; int DataBit; int CurrState; int Timeout; }; struct SLamp Lamp[Lamps]; int DefaultTimeout = 60; void outp(unsigned short Port, unsigned char Data) { unsigned char D = Data; __asm __volatile("outb %0,%%dx" : : "a" (D), "d" (Port) ); } void LampLoop(void *Ptr) { int Cnt; int Data; struct SLamp *L; while (1) { Data=0; for (Cnt=0; CntTimeout>0) { L->Timeout--; if (L->Timeout==0) L->State=L->DefaultState; } switch (L->State) { case Off: L->CurrState=0; break; case On: L->CurrState=1; break; case Blink: L->CurrState=1-L->CurrState; break; } Data|= (L->CurrState ^ Invert) * L->DataBit; } outp(0x378,Data); sleep(1); } } void HandlePacket(int Sock) { struct sockaddr_in InAddr; int InAddrSize; struct SInPacket Request; int RequestSize; char Response[2000]; int ResponseSize = 0; struct SOutPacket *Out = (struct SOutPacket *)&Response; int Cnt; RequestSize = recvfrom(Sock,&Request,sizeof(Request),0,(struct sockaddr *)&InAddr,&InAddrSize); if (RequestSize!=sizeof(Request)) return; if (Request.LampNr>Lamps) return; if (Request.Cmd & FlagSet) { printf("'Set' packet received! (lamp:%d, state:%d)\x07\n",Request.LampNr,Request.NewState); if (Request.Cmd & FlagDefault) { Lamp[Request.LampNr].DefaultState=Request.NewState; if (Lamp[Request.LampNr].Timeout==0) Lamp[Request.LampNr].Timeout=1; } else { Lamp[Request.LampNr].State=Request.NewState; Lamp[Request.LampNr].Timeout=DefaultTimeout; } } if (Request.Cmd & FlagGet) { for (Cnt=0; CntLampNr=Cnt; if (Request.Cmd & FlagDefault) Out->State=Lamp[Cnt].DefaultState; else Out->State=Lamp[Cnt].State; Out->Timeout=Lamp[Cnt].Timeout; Out++; ResponseSize+=sizeof(*Out); } } sendto(Sock,&Response,ResponseSize,0,(struct sockaddr *)&InAddr,InAddrSize); } int main(int argc, char *argv[]) { FILE *IO = fopen("/dev/io","rw"); pthread_t LampThread; int Cnt; char ListenAddr[20]; struct sockaddr_in Addr; int Len; int Sock; if (IO==NULL) { printf("Could not open /dev/io !\n"); exit(1); } if (argc!=2) { printf("Usage: lampd [listenaddr]\n"); exit(1); } /// Reset all lamps to default // for (Cnt=0; Cnt>Cnt; Lamp[Cnt].CurrState=0; } ///Create out udp socket // sprintf(ListenAddr,"%s",argv[1]); memset(&(Addr.sin_zero),0,8); Addr.sin_family=AF_INET; Addr.sin_port=htons(LampPort); Addr.sin_addr.s_addr=inet_addr(ListenAddr); Len=sizeof(Addr); Sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if (bind(Sock,(struct sockaddr *)&Addr,Len)==-1) { printf("Could not bind udp socket!\n"); exit(1); } // Start the lamp update thread pthread_create(&LampThread,NULL,(pthread_startroutine_t)&LampLoop,NULL); ///main loop // while (1) { HandlePacket(Sock); } /// close all that we opened and get out of here... // fclose(IO); close(Sock); }