2 * Copyright (c) 2007, IRTrans GmbH
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of IRTrans GmbH nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY IRTrans GmbH ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL IRTrans GmbH BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/timeb.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
51 #include <arpa/inet.h>
57 #include <sys/ioctl.h>
65 #define closesocket close
80 BOOL WINAPI
ShutdownHandler (DWORD type
);
88 SOCKET irtlan_outbound
;
92 int rcv_status_timeout (int timeout
,uint32_t ip
);
95 int IRTransLanFlash (DEVICEINFO
*dev
,IRDATA_LAN_FLASH
*ird
,int len
,uint32_t ip
)
99 struct sockaddr_in target
;
103 memset (&target
,0,sizeof (struct sockaddr
));
104 target
.sin_family
= AF_INET
;
105 target
.sin_addr
.s_addr
= INADDR_BROADCAST
;
106 target
.sin_port
= htons ((word
)IRTRANS_PORT
);
109 else if (dev
) memcpy (&target
,&dev
->io
.IPAddr
[0],sizeof (struct sockaddr_in
));
112 if ((bcast
|| dev
) && connect (irtlan_outbound
,(struct sockaddr
*)&target
,sizeof (struct sockaddr_in
)) < 0) return (ERR_BINDSOCKET
);
115 res
= send (irtlan_outbound
,(char *)ird
,len
+ 5,0);
119 return (rcv_status_timeout (500,ip
));
124 int IRTransLanSend (DEVICEINFO
*dev
,IRDATA
*ird
)
128 struct sockaddr_in target
;
130 memset (&irdlan
,0,sizeof (IRDATA_LAN
));
132 if (ird
->command
== START_FLASH_MODE
) {
134 irdlan
.netcommand
= COMMAND_FLASH_END
;
137 else irdlan
.netcommand
= COMMAND_FLASH_START
;
140 else if (ird
->command
== TRANSFER_FLASH
) {
141 irdlan
.netcommand
= COMMAND_FLASH_DATA
;
145 irdlan
.netcommand
= COMMAND_LAN
;
148 memcpy (&target
,&dev
->io
.IPAddr
[0],sizeof (struct sockaddr_in
));
149 if (dev
&& connect (irtlan_outbound
,(struct sockaddr
*)&target
,sizeof (struct sockaddr_in
)) < 0) return (ERR_BINDSOCKET
);
152 memcpy (&(irdlan
.ir_data
),ird
,ird
->len
);
154 res
= send (irtlan_outbound
,(char *)&irdlan
,ird
->len
+ sizeof (IRDATA_LAN
) - sizeof (IRDATA
),0);
162 int rcv_status_timeout (int timeout
,uint32_t ip
)
167 struct sockaddr_in from
;
171 int maxfd
,wait
,flags
;
174 flags
= fcntl (irtlan_socket
,F_GETFL
);
179 stat
= WaitForSingleObject (IrtLanEvent
,timeout
);
180 if (stat
== WAIT_TIMEOUT
) return (-1);
186 FD_SET (irtlan_socket
,&events
);
187 maxfd
= irtlan_socket
+ 1;
189 tv
.tv_sec
= timeout
/ 1000;
190 tv
.tv_usec
= (timeout
% 1000) * 1000;
192 stat
= select (maxfd
,&events
,NULL
,NULL
,&tv
);
193 if (stat
== 0) return (-1);
195 fcntl (irtlan_socket
,F_SETFL
,flags
| O_NONBLOCK
);
200 val
= recvfrom (irtlan_socket
,data
,1000,0,(struct sockaddr
*)&from
,&sz
);
202 if (val
> 0 && (!ip
|| from
.sin_addr
.S_un
.S_addr
== ip
)) res
= data
[0];
204 if (val
> 0 && (!ip
|| from
.sin_addr
.s_addr
== ip
)) res
= data
[0];
209 WSAResetEvent (IrtLanEvent
);
211 if (res
== -1) goto retry
;
214 fcntl (irtlan_socket
,F_SETFL
,flags
);
225 val
= recv (irtlan_socket
,&res
,1,0);
234 WORD wVersionRequired
;
236 wVersionRequired
= MAKEWORD(2,2);
237 err
= WSAStartup(wVersionRequired
, &wsaData
);
238 if (err
!= 0) exit(1);
243 extern int irtrans_udp_port
;
245 int OpenIRTransLANSocket (void)
248 struct sockaddr_in serv_addr
;
250 irtlan_outbound
= socket (PF_INET
,SOCK_DGRAM
,0);
251 if (irtlan_outbound
< 0) return (ERR_OPENSOCKET
);
254 setsockopt (irtlan_outbound
,SOL_SOCKET
,SO_BROADCAST
,(char *)&res
,sizeof (int));
256 memset (&serv_addr
,0,sizeof (serv_addr
));
257 serv_addr
.sin_family
= AF_INET
;
258 serv_addr
.sin_addr
.s_addr
= 0;
259 serv_addr
.sin_port
= htons (0);
260 if (bind (irtlan_outbound
,(struct sockaddr
*)&serv_addr
,sizeof (serv_addr
)) < 0) {
261 fprintf (stderr
,"\n\nError binding send socket ... Abort [%d].\n",errno
);
266 irtlan_socket
= socket (PF_INET
,SOCK_DGRAM
,0);
267 if (irtlan_socket
< 0) return (ERR_OPENSOCKET
);
269 memset (&serv_addr
,0,sizeof (serv_addr
));
270 serv_addr
.sin_family
= AF_INET
;
272 serv_addr
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
273 serv_addr
.sin_port
= htons ((short)irtrans_udp_port
);
275 if (bind (irtlan_socket
,(struct sockaddr
*)&serv_addr
,sizeof (serv_addr
)) < 0) {
276 fprintf (stderr
,"\n\nError binding socket ... Abort [%d].\n",errno
);
284 SOCKET irt_bcast
[32];
287 int OpenIRTransBroadcastSockets (void)
290 unsigned int ips
[32];
292 struct sockaddr_in serv_addr
;
294 if_count
= GetInterfaces (ips
);
296 for (i
=0;i
< if_count
;i
++) {
298 irt_bcast
[i
] = socket (PF_INET
,SOCK_DGRAM
,0);
299 if (irt_bcast
[i
] < 0) return (ERR_OPENSOCKET
);
302 setsockopt (irt_bcast
[i
],SOL_SOCKET
,SO_BROADCAST
,(char *)&res
,sizeof (int));
304 memset (&serv_addr
,0,sizeof (serv_addr
));
305 serv_addr
.sin_family
= AF_INET
;
306 serv_addr
.sin_addr
.s_addr
= ips
[i
];
307 serv_addr
.sin_port
= htons (0);
308 if (bind (irt_bcast
[i
],(struct sockaddr
*)&serv_addr
,sizeof (serv_addr
)) < 0) {
309 fprintf (stderr
,"\n\nError binding send socket ... Abort [%d].\n",errno
);
312 memset (&serv_addr
,0,sizeof (serv_addr
));
313 serv_addr
.sin_family
= AF_INET
;
315 serv_addr
.sin_addr
.s_addr
= htonl (INADDR_BROADCAST
);
316 serv_addr
.sin_port
= htons ((short)irtrans_udp_port
);
318 if (connect (irt_bcast
[i
],(struct sockaddr
*)&serv_addr
,sizeof (struct sockaddr_in
)) < 0) return (ERR_BINDSOCKET
);
326 int GetInterfaces (unsigned int ips
[])
331 struct sockaddr_in
*sinp
;
334 char local_ip_addr
[16];
336 fp
= fopen ("/proc/net/dev","r");
338 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
341 pnt
= fgets (ln
,sizeof (ln
),fp
);
344 while (ln
[i
] == ' ') i
++;
345 if (!memcmp (ln
+i
,"eth",3) || !memcmp (ln
+i
,"wlan",4)) {
347 while ((ln
[j
] >= '0' && ln
[j
] <= '9') || (ln
[j
] >= 'a' && ln
[j
] <= 'z') || (ln
[j
] >= 'A' && ln
[j
] <= 'Z')) j
++;
349 memset (&ifr
,0,sizeof (ifr
));
350 strcpy(ifr
.ifr_name
, ln
+i
);
351 ioctl(s
, SIOCGIFADDR
, &ifr
);
352 sinp
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
353 ips
[cnt
++] = sinp
->sin_addr
.s_addr
;
355 pnt
= fgets (ln
,sizeof (ln
),fp
);