Little fix.
[irreco.git] / lirc-0.8.4a / daemons / hw_udp.c
blob35b5ea9fc8168d62a46ac96ee8ec996b036ce08b
1 /****************************************************************************
2 ** hw_udp.c ****************************************************************
3 ****************************************************************************
5 * receive mode2 input via UDP
6 *
7 * Copyright (C) 2002 Jim Paris <jim@jtan.com>
9 * Distribute under GPL version 2 or later.
11 * Received UDP packets consist of some number of LE 16-bit integers.
12 * The high bit signifies whether the received signal was high or low;
13 * the low 15 bits specify the number of 1/16384-second intervals the
14 * signal lasted.
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/fcntl.h>
28 #include <netinet/in.h>
29 #include <errno.h>
31 #include "hardware.h"
32 #include "ir_remote.h"
33 #include "lircd.h"
34 #include "receive.h"
35 #include "transmit.h"
36 #include "hw_default.h"
38 static int zerofd; /* /dev/zero */
39 static int sockfd; /* the socket */
41 int udp_init()
43 int port;
44 struct sockaddr_in addr;
46 logprintf(LOG_INFO,"Initializing UDP: %s",hw.device);
48 init_rec_buffer();
50 port=atoi(hw.device);
51 if(port==0) {
52 logprintf(LOG_ERR,"invalid port: %s",hw.device);
53 return 0;
56 /* hw.fd needs to point somewhere when we have extra data */
57 if((zerofd=open("/dev/zero",O_RDONLY))<0) {
58 logprintf(LOG_ERR,"can't open /dev/zero: %s",
59 strerror(errno));
60 return 0;
63 if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) {
64 logprintf(LOG_ERR,"error creating socket: %s",
65 strerror(errno));
66 close(zerofd);
67 return 0;
70 addr.sin_family = AF_INET;
71 addr.sin_addr.s_addr = htonl(INADDR_ANY);
72 addr.sin_port = htons(port);
74 if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr))<0) {
75 logprintf(LOG_ERR,"can't bind socket to port %d: %s",
76 port,strerror(errno));
77 close(sockfd);
78 close(zerofd);
79 return 0;
82 logprintf(LOG_INFO,"Listening on port %d/udp",port);
84 hw.fd=sockfd;
86 return(1);
89 int udp_deinit(void)
91 close(sockfd);
92 close(zerofd);
93 hw.fd=-1;
94 return(1);
97 char *udp_rec(struct ir_remote *remotes)
99 if(!clear_rec_buffer()) return(NULL);
100 return(decode_all(remotes));
103 lirc_t udp_readdata(lirc_t timeout)
105 static u_int8_t buffer[8192];
106 static int buflen=0;
107 static int bufptr=0;
108 lirc_t data;
109 u_int8_t packed[2];
110 u_int32_t tmp;
111 fd_set rfd;
112 struct timeval tv;
114 /* Assume buffer is empty; LIRC should select on the socket */
115 hw.fd=sockfd;
117 /* If buffer is empty, get data into it */
118 if((bufptr+2)>buflen)
120 FD_ZERO(&rfd);
121 FD_SET(sockfd,&rfd);
122 tv.tv_sec=0;
123 tv.tv_usec=timeout;
124 if(select(sockfd+1,&rfd,NULL,NULL,&tv)!=1)
125 return 0;
126 if((buflen=recv(sockfd,&buffer,sizeof(buffer),0))<0)
128 logprintf(LOG_INFO,"Error reading from UDP socket");
129 return 0;
131 if(buflen&1)
132 buflen--;
133 if(buflen==0)
134 return 0;
135 bufptr=0;
138 /* Read as 2 bytes to avoid endian-ness issues */
139 packed[0]=buffer[bufptr++];
140 packed[1]=buffer[bufptr++];
142 /* TODO: This assumes the receiver is active low. Should
143 be specified by user, or autodetected. */
144 data = (packed[1] & 0x80) ? 0 : PULSE_BIT;
146 /* Convert 1/16384-seconds to microseconds */
147 tmp = (((u_int32_t)packed[1])<<8) | packed[0];
148 /* tmp = ((tmp & 0x7FFF) * 1000000) / 16384; */
149 /* prevent integer overflow: */
150 tmp = ((tmp & 0x7FFF) * 15625) / 256;
152 data |= tmp & PULSE_MASK;
154 /* If our buffer still has data, give LIRC /dev/zero to select on */
155 if((bufptr+2)<=buflen)
156 hw.fd=zerofd;
158 return(data);
161 struct hardware hw_udp=
163 "8765", /* "device" (port) */
164 -1, /* fd (socket) */
165 LIRC_CAN_REC_MODE2, /* features */
166 0, /* send_mode */
167 LIRC_MODE_MODE2, /* rec_mode */
168 0, /* code_length */
169 udp_init, /* init_func */
170 NULL, /* config_func */
171 udp_deinit, /* deinit_func */
172 NULL, /* send_func */
173 udp_rec, /* rec_func */
174 receive_decode, /* decode_func */
175 NULL, /* ioctl_func */
176 udp_readdata, /* readdata */
177 "udp"