Mostly minor fixes up until version 0.8.10.
[irreco.git] / irtrans / irserver / src / server.c
blob250e97a78847401c764ec786533d92ce9a890db3
1 /*
2 * Copyright (c) 2007, IRTrans GmbH
3 * All rights reserved.
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.
30 #ifdef WIN32
32 #include <winsock2.h>
33 #include <windows.h>
34 #include <winuser.h>
35 #include <io.h>
36 #include <direct.h>
37 #include <sys/types.h>
38 #include <time.h>
39 #include <sys/timeb.h>
40 #include <process.h>
42 #define MSG_NOSIGNAL 0
44 #endif
47 #ifdef WINCE
49 #include <winsock2.h>
50 #include <windows.h>
51 #include <winuser.h>
52 #include <time.h>
54 #define MSG_NOSIGNAL 0
55 extern int errno;
57 #endif
60 #include <stdio.h>
61 #include <stdlib.h>
63 #ifdef LINUX
64 #include <time.h>
65 #include <sys/types.h>
66 #include <sys/socket.h>
67 #include <netinet/in.h>
68 #include <sys/un.h>
69 #include <sys/time.h>
70 #include <arpa/inet.h>
71 #include <dirent.h>
72 #include <sys/stat.h>
73 #include <errno.h>
74 #include <fcntl.h>
75 #include <signal.h>
76 #include <netdb.h>
77 #include <stdint.h>
78 #include <sys/utsname.h>
80 typedef int SOCKET;
81 typedef int DWORD;
82 typedef int WSAEVENT;
84 #define closesocket close
85 #define _getpid getpid
87 extern int hCom;
89 SOCKET local_socket;
91 #define LIRCD "/dev/lircd"
92 #define PERMISSIONS 0666
95 #endif
98 #include "remote.h"
99 #include "dbstruct.h"
100 #include "network.h"
101 #include "errcode.h"
102 #include "fileio.h"
103 #include "lowlevel.h"
104 #include "server.h"
105 #include "global.h"
106 #include "webserver.h"
107 #include "flash.h"
108 #include "xap.h"
109 #include "ccf.h"
112 #ifdef WIN32
114 #include "winusbio.h"
115 #include "winio.h"
117 #endif
119 int InitServerSocket (SOCKET *,SOCKET *, SOCKET *, SOCKET*);
120 int ConfigSocket (SOCKET *sock,unsigned short port);
121 void ExecuteNetCommand (SOCKET sockfd);
122 void DoExecuteNetCommand (int client,NETWORKCOMMAND *com,STATUSBUFFER *stat);
123 void PutNetworkStatus (int res,char msg[],STATUSBUFFER *stat);
124 void PutDeviceStatus (NETWORKMODE *mode);
125 void PutDeviceStatusEx (void *pnt,byte command,byte offset);
126 int CheckIdx (char ip[],int idx,NETWORKSTATUS *stat);
127 int GetNetworkClient (SOCKET sockfd);
128 int ReadIRDatabase (void);
129 int ExecuteReceivedCommand (byte command[],int len,int bus);
130 SOCKET register_remote_client (SOCKET fd,int mode);
131 void clear_existing_socket (SOCKET fd);
132 void process_lirc_command (SOCKET fd);
133 void process_udp_command (char *data,int len,struct sockaddr_in *send_adr);
134 void lirc_list_command (SOCKET fd,char rem[],char key[],char msg[]);
135 void lirc_send_success (SOCKET fd,char msg[]);
136 void lirc_send_error (SOCKET fd,char msg[],char err[]);
137 void CloseIRSocket (int client);
138 void ResultStoreTiming (IRDATA *ird,NETWORKTIMING *stat);
139 int GetHotcode (char rem[],char com[],byte data[]);
140 void ReformatHotcode (byte data[],int len);
141 void display_usage (void);
142 void compress_lcdbuffer (LCDCOMMAND *lcd,char *buf,int bus);
143 int count_difference (LCDCOMMAND *lcd);
144 void compress_char (char ln[],char src,char tar);
145 int OpenIRTransLANSocket (void);
146 int OpenIRTransBroadcastSockets (void);
147 void GetBusList (REMOTEBUFFER *buf,int offset);
148 void SendUDPAck (char stat[],struct sockaddr_in *target,int port);
149 void DoExecuteASCIICommand (byte command[],SOCKET sockfd,int client);
152 #define SELECT_TRANS 1
153 #define SELECT_SERVER 2
154 #define SELECT_LIRC 3
155 #define SELECT_LOCAL 4
156 #define SELECT_COMMAND 5
157 #define SELECT_REOPEN 6
158 #define SELECT_WEB 7
159 #define SELECT_UDP 8
160 #define SELECT_XAP 9
161 #define SELECT_IRTLAN 10
162 #define SELECT_CLIENT 11
164 #define COMMAND_SERVER 102
165 #define COMMAND_LIRC 103
166 #define COMMAND_LOCAL 104
167 #define COMMAND_REOPEN 106
170 #ifdef WIN32
172 int build_event_table (HANDLE events[],byte event_type[],byte event_num[],OVERLAPPED OvCom[],int *ser_event);
173 int get_selected_event (int eventnum,HANDLE events[],byte event_type[],byte event_num[],SOCKET *sockfd);
174 int AnalyzeUDPString (char *st,int *netcom,char *remote,char *command,char *ccf,int *netmask,int *bus,int *led,int *port);
176 WSAEVENT SockEvent;
177 WSAEVENT LircEvent;
178 WSAEVENT UDPEvent;
179 WSAEVENT WebEvent;
180 WSAEVENT xAPEvent;
181 WSAEVENT IrtLanEvent;
183 #endif
186 byte IRDataBaseRead;
187 byte lcd_init = 1;
188 STATUS_BUFFER remote_statusex[MAX_IR_DEVICES];
189 byte status_changed = 1;
190 time_t status_cache_timeout = 86400;
191 time_t last_status_read;
192 byte last_adress,resend_flag;
193 SOCKET server_socket;
194 SOCKET lirc_socket;
195 SOCKET udp_socket;
196 SOCKET web_socket;
197 SOCKET udp_relay_socket;
198 extern SOCKET irtlan_socket;
199 extern SOCKET irtlan_outbound;
201 char udp_relay_host[100];
202 int udp_relay_port = 0;
203 char udp_relay_format[255];
204 int irtrans_udp_port = IRTRANS_PORT;
206 unsigned short webport = 0;
207 unsigned int seq_client = 10;
208 unsigned int seq_call;
209 unsigned int netmask[32];
210 unsigned int netip[32];
211 byte netcount = 0;
213 NETWORKCLIENT sockinfo[CLIENT_COUNT];
216 extern IRREMOTE *rem_pnt;
217 extern int rem_cnt;
218 extern IRCOMMAND *cmd_pnt;
219 extern int cmd_cnt;
220 extern char irtrans_usage[];
222 unsigned int mode_flag = 0;
223 char logfile[256];
224 char hexfile[256];
225 char baudrate[10];
226 char pidfile[256];
227 FILE *hexfp;
228 byte hexflag;
229 char irserver_version[20];
230 char irtrans_version[100];
231 FILE *logfp;
232 byte time_len;
233 byte new_lcd_flag;
234 int display_bus;
235 int protocol_version;
236 int device_wait = 2;
240 // System:
241 // LOCALE für Fehlermeldungen
242 // Timeout bevor Repeat beginnt
243 // Fehlermeldungen mit Parametern erweitern.
244 // Neuer Parameter für remotes Verzeichnis
247 // Diverses:
248 // Export / Import
250 // Adresse für LCD übergeben
254 // 1.0.0 Erstes Final Release MM 20.04.03
255 // 2.0.0 Neues Network Format (Rückgabe) MM 25.04.03
256 // 2.0.1 Fehlermeldung bei nicht definiertem Hotcode überm. MM 25.04.03
257 // 2.0.2 Erkennung von globalen Wiederholungscodes MM 26.04.03
258 // 2.0.3 Erweiterungen des Loggings MM 01.05.03
259 // 2.0.4 Erweiterungen des Loggings MM 02.05.03
260 // 2.1.0 Neues Network Command "Reload" (Girder Client) MM 06.05.03
261 // 2.1.1 Kein Bus Scan beim Start des Systems MM 07.05.03
262 // 2.2.0 LCD Support MM 11.05.03
263 // 2.2.1 Ausblenden von Togglebits auf dem Server MM 15.05.03
264 // 2.2.2 LIRC Socket abschaltbar MM 19.05.03
265 // 2.3.1 LCD Support erweitert MM 09.06.03
266 // 2.3.2 LCD Komprimierung implementiert MM 10.06.03
267 // 2.3.3 Lernen jetzt auch mit alten Timings möglich MM 02.07.03
268 // 2.3.4 Byteordererkennung und Korrektur (PowerPC) MM 05.07.03
269 // 2.3.5 Fixed LCD Display init Bug MM 17.07.03
270 // 2.3.6 Changed Receive Code MM 24.07.03
271 // 2.3.7 Last Command Korrektur bei nicht bekannten Befehlen MM 24.07.03
272 // 2.3.8 B&O Anpassungen MM 02.08.03
273 // 2.3.9 B&O Anpassungen MM 04.08.03
274 // 2.3.10 B&O Carrier MM 07.08.03
275 // 2.3.11 Bug nach Client Connect unter LINUX beseitigt MM 11.09.03
276 // 2.3.12 Command Nummer für MyHTPC Client ergänzt MM 15.09.03
277 // 2.3.13 Anpassung an neue FW Versionen MM 17.09.03
278 // 2.3.14 Bug in learnok behoben MM 23.09.03
279 // 2.3.15 Small corrections MM 24.09.03
280 // 2.3.16 Check for duplicate Commands MM 24.09.03
281 // 2.3.17 Send all instances of duplicate Commands MM 27.09.03
282 // 2.3.18 Support for temperature sensors MM 28.09.03
283 // 2.3.19 Adresse des Empfängers wird an Client übergeben MM 12.10.03
284 // 2.3.20 Send Routing MM 12.10.03
285 // 2.3.21 Globales Toggle Bit supported MM 17.10.03
286 // 2.3.22 Set ID supported MM 03.11.03
287 // 2.3.23 UDP Support FB 08.11.03
288 // 2.3.24 PowerOn Command wird gespeichert MM 09.11.03
289 // 2.3.25 Fehler bei Short Repeat beseitigt MM 11.11.03
290 // 2.3.26 Serial Number + no_reset als Default MM 12.11.03
291 // 2.3.27 Bugfixes MM 21.12.03
292 // 3.0.0 Webserver integriert MM 24.12.03
293 // 3.0.1 Bugfix Device Status MM 05.01.04
294 // 3.0.2 Neue Option -reset_eeprom MM 06.01.04
295 // 3.1.0 Protocol Version im Netzwerk MM 07.01.04
296 // 3.1.1 Liste der FBs + Commands MM 17.01.04
297 // 3.1.2 Translator Support erweitert MM 21.01.04
298 // 3.1.3 Altes Commandformat wird parallel unterstützt MM 03.02.04
299 // 3.1.4 Translator erweitert MM 08.02.04
300 // 3.1.5 Code Korrektur von RCMM Codes MM 01.03.04
301 // 3.2.0 Support for CCF Codes MM 05.03.04
302 // 3.2.2 Parallele Unterstützung von altem & neuem Format MM 17.03.04
303 // 3.2.3 Fehler bei Timingneuerkennung beseitigt MM 01.04.04
304 // 3.2.4 Pronto Codes: Remotes bei Repeat Codes ergänzt MM 02.04.04
305 // 3.2.5 CCF Bugfix MM 03.04.04
306 // 3.2.6 Test ob Command vorhanden MM 09.04.04
307 // 3.2.7 RAW HF Codes werden richtig gesendet MM 12.04.04
308 // 3.2.8 Korrektur von LIRC Send Command MM 13.04.04
309 // 3.2.9 Returnstruct von Testcommand verkürzt MM 25.04.04
310 // 3.2.10 Empfang langer Pakete korrigiert MM 28.04.04
311 // 3.2.11 RAW CCF Bugfix MM 29.04.04
312 // 3.2.12 CCF Support für RC5 & RC6 MM 30.04.04
313 // 3.2.13 Lernen von Codes wenn nur Timing da ist MM 30.04.04
314 // 3.2.14 Erweiterung des RAW Supports MM 01.05.04
315 // 3.2.15 Variable Flashwordsize MM 01.05.04
316 // 3.2.16 LONGSEND Support MM 02.05.04
317 // 3.2.17 Server Shutdown via Client MM 07.05.04
318 // 3.2.18 Translator Support: Gruppen MM 10.05.04
319 // 3.2.19 RC6A MM 11.05.04
320 // 3.2.20 Mixed fixes MM 13.05.04
321 // 3.2.21 Korrektur Receive kurzer RAW Codes MM 15.05.04
322 // 3.2.22 Senderauswahl via Adress MM 17.05.04
323 // 3.2.23 Capabilities in Statusabfrage MM 02.06.04
324 // 3.2.24 Flash Translator via SBUS MM 03.06.04
325 // 3.2.25 Neuer Debug Mode -codedump MM 19.06.04
326 // 3.2.26 Crash bei großen Hexdumps beseitigt MM 20.06.04
327 // Sendmask für Translatorbefehle
328 // 3.2.27 CCF RAW Bugs beseitigt MM 21.06.04
329 // 3.2.28 Old Commandbuffer Bug fixed MM 11.07.04
330 // 3.2.29 Berechtigung über IP Adressen MM 03.08.04
331 // 3.3.0 Macro Support MM 09.08.04
332 // 3.3.1 Support für Macro Wait Translator MM 16.08.04
333 // 3.3.2 Bug behoben: Multisend an Clients MM 21.08.04
334 // 3.3.3 Support der -learned_only Funtion MM 24.08.04
335 // 3.3.4 CCF Präzision verbessert MM 24.08.04
336 // 3.3.5 Neue usage Meldung beim Start MM 25.08.04
337 // 3.3.6 UDP Relay MM 04.09.04
338 // 3.3.7 Keine Netmask auf Local Socket MM 04.09.04
339 // 3.3.8 CCF Präzision weiter verbessert MM 04.09.04
340 // 4.1.1 Support für TIME_LEN = 8 MM 11.09.04
341 // 4.1.2 Fehler bei Togglecodes behoben MM 12.09.04
342 // 4.1.3 Commandlist Togglecodes MM 15.09.04
343 // 4.1.4 Fehler in Swap_Irdata beseitigt MM 19.09.04
344 // 4.1.5 Uneed Version MM 21.09.04
345 // 4.2.1 CCF RAW Codes mit Repeat MM 26.09.04
346 // CCF Rundung von Timingwerten optimiert MM 26.09.04
347 // 4.2.2 CCF Mode 7000 Codes MM 27.09.04
348 // 4.3.1 Support for extended IR Carrier MM 29.09.04
349 // 4.3.2 64 Bit Support for AMD64 on LINUX MM 05.10.04
350 // 5.1.1 Multiple Device support MM 10.10.04
351 // 5.1.2 Multiple Device extensions MM 16.10.04
352 // 5.1.3 Multiple Switch devices MM 17.10.04
353 // 5.1.4 Extended Carriermode für mehrere Devices MM 21.10.04
354 // 5.1.5 Support für Reset Display Option MM 22.10.04
355 // 5.1.6 Mediacenter Support MM 24.10.04
356 // 5.1.7 Mediacenter Remote beschleunigt MM 25.10.04
357 // 5.1.8 Fix für Translator Flash Problem MM 28.10.04
358 // 5.1.9 Erweiterung Multibus Send MM 31.10.04
359 // 5.1.10 V5 für LINUX MM 02.11.04
360 // 5.1.11 LCD Init bei Display Reset MM 05.11.04
361 // 5.1.12 CCF Tolerance erweitert MM 08.11.04
362 // 5.1.13 Capability Fix für alte Translator MM 08.11.04
363 // 5.1.14 MCE Remote Erweiterung MM 15.11.04
364 // 5.1.15 LINUX USB I/O MM 16.11.04
365 // 5.1.16 Diag Message removed MM 04.12.04
366 // 5.1.17 Mediacenter IR support Standard MM 07.12.04
367 // 5.1.18 Support für neue Statusflags (Receive Timeout) MM 10.12.04
368 // 5.1.19 Receive while LCD Update MM 12.12.04
369 // 5.1.20 Receive while LCD Update LINUX MM 13.12.04
370 // 5.1.21 Set Status Webserver korrigiert MM 13.12.04
371 // 5.1.22 Charset Konvertierung MM 14.12.04
372 // 5.1.23 Numeric Codes für B&O angepaßt MM 14.12.04
373 // 5.1.24 RC6 Send Fix MM 15.12.04
374 // 5.1.25 Charset Konvertierung MM 15.12.04
375 // 5.1.26 RC6 + RAW Repeat MM 15.12.04
376 // 5.1.27 Tastenentprellung MM 17.12.04
377 // 5.1.28 Get Device Command MM 19.12.04
378 // 5.2.1 MCE Steuerung konfigurierbar MM 20.12.04
379 // 5.2.2 I/O für langsame Systeme weiter verbessert MM 24.12.04
380 // 5.2.3 Realtime Clock Support MM 27.12.04
381 // 5.2.4 Realtime Clock on Shutdown MM 28.12.04
382 // 5.2.5 Realtime Clock set on Shutdown MM 29.12.04
383 // 5.2.6 Genauere Zeit für die Realtime Clock MM 31.12.04
384 // 5.2.7 Support für einstellbaren Learn Timeout MM 02.01.05
385 // 5.2.8 Device Status über den Bus MM 03.01.05
386 // 5.2.9 Erweiterte Keyboard Steuerung MM 06.01.05
387 // 5.2.10 Korrektur Mediacenter Funktionen MM 17.01.05
388 // 5.2.11 Support für Character Sets MM 18.01.05
389 // 5.2.12 MCE Volume Fix MM 19.01.05
390 // 5.2.13 MCE Volume Fix MM 19.01.05
391 // 5.2.14 Special Character Support MM 20.01.05
392 // 5.2.15 Support für Uneed Mega32 Modul MM 20.01.05
393 // Leeren Translator flashen MM 20.01.05
394 // 0 Chars auf LCD Display MM 20.01.05
395 // 5.2.16 Neues LCD Protokoll MM 21.01.05
396 // 5.2.17 VFD Level Support MM 22.01.05
397 // 5.2.18 LCD Mode fix MM 24.01.05
398 // 5.2.19 Korrektur Init EEPROM (Extended Mode 2) MM 27.01.05
399 // 5.2.20 Korrektur Resend über mehrere Busse MM 27.01.05
400 // 5.2.21 Fix for Send with very old devices MM 01.02.05
401 // 5.2.22 Update für Multikeys Translator MM 04.02.05
402 // 5.2.23 MCE Commands via Events MM 08.02.05
403 // 5.2.24 Support für 1MHz Carrier MM 16.02.05
404 // 5.2.25 Support für LCD Module V 2.0 MM 20.02.05
405 // 5.2.26 Support für UNEED V2 MM 22.02.05
406 // 5.2.27 Displaytyp am Bus einstellbar MM 22.02.05
407 // 5.2.28 CH+ / CH- wieder über Keyboard an Mediacenter MM 24.02.05
408 // 5.3.01 Events beliebig konfigurierbar MM 27.02.05
409 // 5.3.02 Event Steuerung für externe Apps erweitert MM 02.03.05
410 // 5.3.03 Support für RC5/RC6 Notoggle Flag MM 08.03.05
411 // 5.3.04 Bug für Sendkey ohne Window behoben MM 09.03.05
412 // 5.3.05 Support für Suspend / Resume MM 24.03.05
413 // 5.3.06 Reihenfolge beim Exit geändert MM 24.03.05
414 // 5.3.07 Zeichenumsetzung erweitert (FR) MM 29.03.05
415 // 5.3.08 Sommerzeit Fix MM 02.04.05
416 // 5.3.09 Fix für alte LCDs MM 06.04.05
417 // 5.3.10 Fix für alte Uneed LCDs MM 08.04.05
418 // 5.3.11 Neues Networkcommand DELETE_COMMAND MM 11.04.05
419 // Nach Delete keine Leerzeichen mehr am Fileende MM 11.04.05
420 // 5.3.12 Kleine Erweiterungen für schnellen SBUS MM 17.04.05
421 // 5.3.13 Erweiterungen für SBUS Flash Translator (Fast SBUS) MM 19.04.05
422 // 5.3.14 COMMAND_EMPTY für PHP MM 01.05.05
423 // 5.3.15 Mehrer IRTrans + DisplayIRTrans MM 02.05.05
424 // 5.3.16 Timeout für Status Cache MM 04.05.05
425 // 5.3.17 Statusproblem LINUX mit großen Buffern MM 05.05.05
426 // 5.3.18 Update für Translator Flash via SBUS (Classic) MM 09.05.05
427 // 5.3.19 Neue Option -hexfile MM 09.05.05
428 // 5.3.20 Serielles IF Handling geändert MM 11.05.05
429 // 5.3.21 xAP Support MM 16.05.05
430 // 5.3.22 xAP Pronto Support MM 17.05.05
431 // 5.3.23 Längenangabe [RCV-LEN] im .rem File MM 18.05.05
432 // 5.3.24 IRDA Support MM 20.05.05
433 // 5.3.25 Wait nach Setstatus verlängert MM 23.05.05
434 // 5.3.26 Support für PowerOff Code MM 23.05.05
435 // 5.3.27 RCV-LEN korrigiert MM 23.05.05
436 // 5.3.28 Support für PowerOn + PowerOff MM 24.05.05
437 // 5.3.29 Send Result Sockethandling geändert MM 27.05.05
438 // 5.3.30 Dummydevice für Tests ohne IRTrans Hardware MM 02.06.05
439 // 5.3.31 IRDA RAW Modus MM 05.06.05
440 // 5.3.32 IRDA Data Modus MM 07.06.05
441 // 5.3.33 Errorstatus für GetRemoteCommands MM 15.06.05
442 // 5.3.34 Set Brightness Command MM 17.06.05
443 // 5.3.35 Instant Receive Timeout vergrößert MM 17.06.05
444 // 5.3.36 LIRC LIST Command extended MM 29.06.05
445 // 5.3.38 LIRC LIST Command corrected MM 29.06.05
446 // 5.4.01 Support for IRTrans LAN module MM 18.07.05
447 // 5.4.02 Fix for ReadSerialStringEx MM 22.07.05
448 // 5.4.03 Get Status für LAN Modul MM 25.07.05
449 // 5.4.04 LINUX USB Paths extended MM 08.08.05
450 // 5.4.05 Autoscan new USB paths MM 09.08.05
451 // 5.4.06 New Function Keys MM 09.08.05
452 // 5.4.07 Support für IRDB Devices MM 15.08.05
453 // 5.4.08 RS232 Baudrate MM 18.08.05
454 // 5.4.09 Support für Binäre IR Actions MM 20.08.05
455 // 5.4.10 Support für IRDB & IRTrans LAN MM 22.08.05
456 // 5.4.11 LINUX Device Scan erweitert MM 22.08.05
457 // 5.4.12 LINUX Support für IRTrans LAN MM 22.08.05
458 // 5.4.13 Clock Display Switch MM 07.09.05
459 // 5.5.01 Support für MCE Keyboard MM 09.09.05
460 // 5.5.02 MCE Keyboard Support über Scancodes MM 15.09.05
461 // 5.5.03 MCE Keyboard Maus Support MM 16.09.05
462 // 5.5.04 Fixed MCE Bug MM 18.09.05
463 // 5.5.05 Weitere MCE Erweiterungen MM 18.09.05
464 // 5.5.06 Medialon Hexdump MM 20.09.05
465 // 5.5.07 Support für Frontview Treiber MM 02.10.05
466 // 5.5.08 Timestamp im Logfile MM 12.10.05
467 // 5.5.09 Erweiterung Ethernet Learn mode MM 13.10.05
468 // 5.5.10 -deviceinfo für LAN Versionen MM 17.10.05
469 // 5.5.11 Autofind LAN devices on startup MM 18.10.05
470 // 5.5.12 Warnung vor dem Überschreiben von Translations MM 01.11.05
471 // 5.5.14 Support für Combobox Translation / IRDB MM 02.11.05
472 // 5.5.15 Erweiterung auf max. 256 Busse MM 04.11.05
473 // 5.5.16 Auflistung der IRTrans Busse MM 05.11.05
474 // 5.5.17 Send CCF MM 09.11.05
475 // 5.5.18 LANIO Sleep geändert MM 10.11.05
476 // 5.5.19 Send CCF lang MM 11.11.05
477 // 5.5.20 Fehler in Learn Next IR korrigiert MM 11.11.05
478 // 5.5.21 LiveTV Fehler korrigiert MM 11.11.05
479 // 5.5.22 Support für Send RAW aus IRDB MM 13.11.05
480 // 5.5.23 -no_lirc Option erweitert MM 19.11.05
481 // 5.5.24 -ip_relay Option MM 23.11.05
482 // 5.5.25 Learn Direct MM 26.11.05
483 // 5.5.26 Repeat von Befehlen erweitert MM 27.11.05
484 // 5.5.27 Pause beim Repeat von Befehlen MM 28.11.05
485 // 5.5.28 Fehler bei illegalen Timings in .rem Files MM 02.12.05
486 // 5.5.29 LAN + Busmodule MM 04.12.05
487 // 5.5.30 UDP Sendstring MM 10.12.05
488 // 5.5.31 UDP Learn erweitert MM 14.12.05
489 // 5.5.32 UDP ACK MM 17.12.05
490 // 5.5.33 UDP Learn Ready ACK MM 18.12.05
491 // 5.5.34 TESTCOMMANDEX MM 19.12.05
492 // 5.5.35 CCF Carrier > 400 korrigiert MM 26.12.05
493 // 5.5.36 CCF Handling erweitert MM 26.12.05
494 // 5.5.37 UDP ACK Port wählbar MM 27.12.05
495 // 5.5.38 UDP ACK Port wählbar für Ping MM 27.12.05
496 // 5.5.39 UDP Format angepasst MM 27.12.05
497 // 5.5.40 UDP Send CCF MM 29.12.05
498 // 5.5.41 -daemon Mode / xAP Port unter LINUX MM 02.01.06
499 // 5.5.42 xAP Heartbeat korrigiert MM 12.01.06
500 // 5.5.43 ms Timestamps (Windows) MM 22.01.06
501 // 5.5.44 Macrobefehle korrigiert MM 23.01.06
502 // 5.5.45 Macropause korrigiert MM 24.01.06
503 // 5.5.46 Fehler bei Repeatcodes korrigiert MM 26.01.06
504 // 5.5.47 Erweiterte Statuscodelänge MM 29.01.06
505 // 5.5.48 SetstatusEx MM 30.01.06
506 // 5.5.49 Setatatus Timeout MM 31.01.06
507 // 5.5.50 Send Log erweitert MM 08.02.06
508 // 5.5.51 Support für > 16 USB Devices MM 09.02.06
509 // 5.5.52 Clear NETWORKRCV Buffer vor jedem Push MM 10.02.06
510 // 5.5.53 Bus in Address bei recv_command richtig gefüllt MM 13.03.06
511 // 5.5.54 Delete Remote MM 16.03.06
512 // 5.6.01 Support for Long IR Codes MM 24.04.06
513 // 5.6.02 Longsend korrigiert MM 26.04.06
514 // 5.6.03 Sort distinct device Nodes MM 28.04.06
515 // 5.6.04 Bereiche für LINUX USB Devices MM 01.05.06
516 // 5.6.05 Fix für LINUX USB Devices MM 02.05.06
517 // 5.6.06 Include Names für LAN Translator MM 05.05.06
518 // 5.6.07 Support für Multi LEDs MM 11.05.06
519 // 5.6.08 Differenz Count Displayversorgung = 16 MM 15.05.06
520 // 5.6.09 Pulse/Pause = 0->1 (CCF Codes) MM 24.05.06
521 // 5.6.10 Versionsunterscheidung Translator FW MM 24.05.06
522 // 5.6.11 Timingkorrektur je nach Carrier FREQ MM 29.05.06
523 // 5.6.12 Support für Toggle Codes in IRDB MM 30.05.06
524 // 5.6.13 Auch in /etc/irserver/remotes suchen SvS 02.06.06
525 // 5.6.14 RCV-LEN für Translator MM 13.06.06
526 // 5.6.15 Support für Hostbroadcast MM 28.06.06
527 // 5.6.16 Set Relais MM 04.07.06
528 // 5.6.17 Relaisauswahl IRDB MM 07.07.06
529 // 5.6.18 Neues DB Format MM 12.07.06
530 // 5.6.19 Sonderzeichen in der apps.cfg MM 14.07.06
531 // 5.6.20 Div. lcdproc Korrekturen MM 23.07.06
532 // 5.6.21 Unterschiedliche Displaytypen MM 26.07.06
533 // 5.6.22 Bug beim Status mehrerer LAN Module behoben MM 27.07.06
534 // 5.6.23 Webserver defaultmäßig aus MM 09.08.06
535 // 5.6.24 -pidfile Option MM 10.08.06
536 // 5.6.25 -wait Option MM 01.09.06
537 // 5.6.26 2s Wait als default MM 01.09.06
538 // 5.6.27 Path Variable für IR Datenbank MM 05.09.06
539 // 5.6.28 Status message bei IRDB Flash MM 09.09.06
540 // 5.6.29 Client ID in logs MM 09.09.06
541 // 5.6.30 Client ID in logs MM 11.09.06
542 // 5.6.31 Read Analog Inputs MM 03.10.06
543 // 5.6.32 Read Analog Inputs V2 MM 14.10.06
544 // 5.6.33 Init Server für LINUX korrigiert MM 20.11.06
545 // 5.6.34 Mac Adresse für Set Status gefiltert MM 12.12.06
546 // 5.6.35 RS232 Send für LAN Controller XL MM 19.12.06
547 // 5.7.01 ASCII Commands MM 24.12.06
548 // 5.7.02 Flash User HTML Pages MM 26.12.06
549 // 5.7.03 IP + MAC in Device Node String MM 03.01.07
550 // 5.7.04 IP + MAC in Device Node String korrektur MM 03.01.07
551 // 5.7.05 No Toggle bei RC5/6 Relay MM 07.01.07
552 // 5.7.06 ASCII Send / Receive MM 08.01.07
553 // 5.7.07 Support für mehr als 8 Busse beim Device Status MM 12.01.07
554 // 5.7.08 IRDB EX Format MM 24.01.07
555 // 5.7.09 UDP Port Option MM 24.01.07
556 // 5.7.10 ASCII Getremotes / Getcommands MM 26.01.07
557 // 5.7.11 FT2232 Support MM 22.02.07
558 // 5.7.12 Debug Log extension MM 23.02.07
559 // 5.7.13 Debug Log extension MM 23.02.07
560 // 5.7.14 Handshake Wait LINUX MM 23.02.07
561 // 5.7.15 Handshake Wait LINUX MM 23.02.07
562 // 5.7.16 Error bei Berechnung Action LEN IRDBEX MM 01.03.07
563 // 5.7.17 SEQ Nr. für USB Devices MM 03.03.07
564 // 5.7.18 Timeout Values changed MM 05.03.07
565 // 5.7.19 Timeout Values changed MM 08.03.07
566 // 5.7.20 send_forward Option MM 15.03.07
567 // 5.7.21 USB COM Port support für Vista x64 MM 30.03.07
568 // 5.7.22 LINUX mehrere Codes in einem Read MM 16.04.07
569 // 5.7.23 LINUX USB Read Timeout MM 17.04.07
570 // 5.8.01 Long Code Calibration MM 23.04.07
571 // 5.8.02 RCMM Adjustments MM 02.05.07
572 // 5.8.03 RCMM Adjustments MM 02.05.07
573 // 5.8.04 RCMM Adjustments MM 03.05.07
574 // 5.8.05 SendCCF Mods MM 09.05.07
575 // 5.8.06 LAN Autofind mit mehreren LAN Interfaces MM 29.05.07
576 // 5.8.07 Select LAN Interface to use MM 31.05.07
577 // 5.8.08 Multiple device support LINUX MM 01.06.07
578 // 5.8.09 Startup Delay MM 07.06.07
579 // 5.8.10 Device DB Off error MM 11.06.07
580 // 5.8.11 MCE Handling erweitert (C. Tergusek) MM 13.06.07
581 // 5.8.12 CCF Bugfix MM 13.06.07
582 // 5.8.13 New Flash Transfer Status code MM 14.06.07
583 // 5.8.14 Fix für TCP/IP ASCII Commands MM 14.06.07
584 // 5.8.15 Flash Transfer status MM 19.06.07
585 // 5.8.16 Liste von LAN Modulen ohne Init MM 25.06.07
586 // 5.8.17 Korrektur für Timing bei genau 256 Befehlen in IRDB MM 06.07.07
587 // 5.8.18 Commandlist mit > 200 Commands MM 06.07.07
588 // 5.9.01 x64 Port MM 03.08.07
589 // 5.9.02 Toggle Command Support für Translator MM 07.08.07
590 // 5.9.03 Remote Open Statuscode MM 08.08.07
591 // 5.9.04 BSD license MM 17.08.07
592 // 5.9.05 Umlaute am Ende von Strings (DBReadString) MM 04.09.07
593 // 5.9.06 Support für Relaissteuerung via Broadcast MM 21.09.07
594 // 5.9.06 Support für Relaissteuerung via Broadcast MM 21.09.07
595 // 5.9.07 Fix für Suche nach WLAN Interfaces (LINUX/N800) MM 16.10.07
598 #define VERSION "5.9.07"
602 #if defined LINUX || defined _CONSOLE
604 main (int argc,char *argv[])
607 int res,i,adr;
608 char *pnt;
609 int device_id = -1;
610 int eeprom_id = -1;
611 char st[255];
613 #if defined (WIN32) && !defined (_M_X64)
614 int vers;
615 vers = GetOSInfo ();
616 if (vers >= 510 && (vers & 1)) { // Running on x64 (WOW64)
617 if (_execv (".\\irserver64.exe",argv)) {
618 fprintf (stderr,"Error executing the 64Bit IRServer\n");
619 exit (-1);
623 #endif
624 #if defined (LINUX) && !defined (X64)
625 struct utsname u;
627 uname (&u);
628 if (!strcmp (u.machine,"x86_64")) { // Running on x64
629 argv[0] = "irserver64";
630 if (execv ("./irserver64",argv)) {
631 fprintf (stderr,"Error executing the 64Bit IRServer\n");
632 exit (-1);
635 #endif
637 new_lcd_flag = 0;
638 mode_flag |= NO_RESET;
639 mode_flag |= LOG_FATAL;
640 mode_flag |= NO_WEB;
641 strcpy (irserver_version,VERSION);
643 if (argc == 2 && !strcmp (argv[1],"-version")) {
644 printf ("IRServer Version %s\nMinimun IRTrans FW Version %s\n",VERSION,MINIMUM_SW_VERSION);
645 exit (0);
648 if (argc == 2 && !strcmp (argv[1],"-deviceinfo")) {
649 mode_flag = (mode_flag & ~LOG_MASK) | 3;
650 #ifdef WIN32
651 strcpy (st,"usb;com1;com2;com3;com4;lan");
652 #else
653 strcpy (st,"usb;/dev/ttyS0;/dev/ttyS1;/dev/ttyS2;/dev/ttyS3;lan");
654 #endif
655 return (get_devices (st,1));
657 argc++;
658 for (;--argc > 2;argv++) { // Process all Command Line Arguments
660 if (!strcmp (argv[1],"-no_reconnect")) {
661 mode_flag |= NO_RECONNECT;
662 continue;
664 if (!strcmp (argv[1],"-no_init_lan")) {
665 mode_flag |= NO_INIT_LAN;
666 continue;
668 if (!strcmp (argv[1],"-start_clock")) {
669 mode_flag |= CLOCK_STARTUP;
670 continue;
672 if (!strcmp (argv[1],"-send_forward")) {
673 mode_flag |= SEND_FORWARD;
674 continue;
676 if (!strcmp (argv[1],"-send_forwardall")) {
677 mode_flag |= SEND_FORWARDALL;
678 continue;
680 if (!strcmp (argv[1],"-ip_relay")) {
681 mode_flag |= IP_RELAY;
682 continue;
684 if (!strcmp (argv[1],"-no_clock")) {
685 mode_flag |= NO_CLOCK;
686 continue;
688 if (!strcmp (argv[1],"-no_lirc")) {
689 mode_flag |= NO_LIRC;
690 continue;
692 if (!strcmp (argv[1],"-debug_code")) {
693 mode_flag |= DEBUG_CODE;
694 continue;
696 if (!strcmp (argv[1],"-hexdump")) {
697 mode_flag |= HEXDUMP;
698 continue;
700 if (!strcmp (argv[1],"-timestamp")) {
701 mode_flag |= TIMESTAMP;
702 continue;
704 if (!strcmp (argv[1],"-medialon")) {
705 mode_flag |= MEDIALON;
706 continue;
708 if (!strcmp (argv[1],"-codedump")) {
709 mode_flag |= CODEDUMP;
710 continue;
712 if (!strcmp (argv[1],"-xap")) {
713 mode_flag |= XAP;
714 continue;
716 if (!strcmp (argv[1],"-learned_only")) {
717 mode_flag |= LEARNED_ONLY;
718 continue;
720 if (!strcmp (argv[1],"-logfile")) {
721 argc--;
722 argv++;
723 strcpy (logfile,argv[1]);
724 continue;
726 if (!strcmp (argv[1],"-baudrate")) {
727 argc--;
728 argv++;
729 strncpy (baudrate,argv[1],10);
730 continue;
732 if (!strcmp (argv[1],"-hexfile")) {
733 argc--;
734 argv++;
735 strcpy (hexfile,argv[1]);
736 continue;
738 if (!strcmp (argv[1],"-pidfile")) {
739 argc--;
740 argv++;
741 strcpy (pidfile,argv[1]);
742 continue;
744 if (!strcmp (argv[1],"-udp_relay")) {
745 argc--;
746 argv++;
747 strcpy (udp_relay_host,argv[1]);
748 argc--;
749 argv++;
750 udp_relay_port = atoi (argv[1]);
751 argc--;
752 argv++;
753 strcpy (udp_relay_format,argv[1]);
754 continue;
756 if (!strcmp (argv[1],"-loglevel")) {
757 argc--;
758 argv++;
759 mode_flag = (mode_flag & ~LOG_MASK) | (atoi (argv[1]) & LOG_MASK);
760 continue;
762 if (!strcmp (argv[1],"-set_id")) {
763 argc--;
764 argv++;
765 device_id = atoi (argv[1]) & 0xf;
766 continue;
768 if (!strcmp (argv[1],"-delay")) {
769 argc--;
770 argv++;
771 msSleep (atoi (argv[1]));
772 continue;
774 if (!strcmp (argv[1],"-wait")) {
775 argc--;
776 argv++;
777 device_wait = atoi (argv[1]);
778 continue;
780 if (!strcmp (argv[1],"-stat_timeout")) {
781 argc--;
782 argv++;
783 status_cache_timeout = atoi (argv[1]);
784 continue;
786 if (!strcmp (argv[1],"-lcd")) {
787 argc--;
788 argv++;
789 new_lcd_flag = atoi (argv[1]);
790 continue;
793 if (!strcmp (argv[1],"-netmask")) {
794 argc--;
795 argv++;
796 if (netcount < 32) {
797 netip[netcount] = ntohl (inet_addr (strtok (argv[1],"/")));
798 pnt = strtok (NULL,"/");
799 if (pnt) {
800 adr = 0;
801 res = atoi (pnt);
802 for (i=0;i < res;i++) adr |= 1 << (31-i);
803 netmask[netcount++] = adr;
807 continue;
809 if (!strcmp (argv[1],"-reset_eeprom")) {
810 argc--;
811 argv++;
812 eeprom_id = atoi (argv[1]) & 0xf;
813 continue;
815 if (!strcmp (argv[1],"-udp_port")) {
816 argc--;
817 argv++;
818 irtrans_udp_port = atoi (argv[1]);
819 continue;
821 if (!strcmp (argv[1],"-http_port")) {
822 argc--;
823 argv++;
824 mode_flag &= ~NO_WEB;
825 webport = atoi (argv[1]);
826 continue;
828 if (!strcmp (argv[1],"-no_web")) {
829 mode_flag |= NO_WEB;
830 continue;
832 if (!strcmp (argv[1],"-read_eeprom")) {
833 mode_flag |= READ_EEPROM;
834 continue;
836 #ifdef LINUX
837 if (!strcmp (argv[1],"-daemon")) {
838 if (*logfile == 0) strcpy (logfile,"irserver.log");
839 mode_flag |= DAEMON_MODE;
840 continue;
842 #endif
843 fprintf (stderr,"Unknown option %s\n",argv[1]);
844 display_usage ();
847 if (argc == 1 || argv[1][0] == '-') display_usage ();
849 res = InitServer (argv[1]);
852 if (res) {
853 GetError (res,st);
854 log_print (st,LOG_FATAL);
855 exit (res);
858 if (device_id != -1) { // Bus !!!
859 res = SetTransceiverIDEx (0,(byte)device_id);
860 exit (res);
863 if (eeprom_id != -1) { // Bus !!!
864 res = SetTransceiverModusEx (0,159,0xffff,0,"",0,0xf,3,0,0,0);
865 exit (res);
868 res = RunServer ();
870 if (res) {
871 GetError (res,st);
872 log_print (st,LOG_FATAL);
873 exit (res);
875 return (0);
879 void display_usage (void)
881 fprintf (stderr,"%s",irtrans_usage);
882 exit (1);
885 #endif
887 int InitServer (char dev[])
889 int res,i;
890 char msg[256];
891 time_t ti;
893 #ifdef LINUX
894 FILE *fp;
895 #endif
897 for (i=0;i < CLIENT_COUNT;i++) sockinfo[i].fd = -1;
899 res = InitServerSocket (&server_socket,&lirc_socket,&udp_socket,&web_socket);
900 if (res) return (res);
903 #ifdef WIN32
904 SockEvent = WSACreateEvent ();
905 WSAEventSelect (server_socket,SockEvent,FD_ACCEPT);
907 UDPEvent = WSACreateEvent ();
908 WSAEventSelect (udp_socket, UDPEvent,FD_READ);
910 xAPEvent = WSACreateEvent ();
911 WSAEventSelect (xAP_rcv, xAPEvent,FD_READ);
913 IrtLanEvent = WSACreateEvent ();
914 WSAEventSelect (irtlan_socket, IrtLanEvent,FD_READ);
916 if (mode_flag & NO_LIRC) LircEvent = NULL;
917 else {
918 LircEvent = WSACreateEvent ();
919 WSAEventSelect (lirc_socket,LircEvent,FD_ACCEPT);
922 if (mode_flag & NO_WEB) WebEvent = NULL;
923 else {
924 WebEvent = WSACreateEvent ();
925 WSAEventSelect (web_socket,WebEvent,FD_ACCEPT);
927 #endif
930 // InitInput ();
931 ti = time (0) + device_wait;
933 do {
934 res = InitCommunicationEx (dev);
935 if (res && device_wait) msSleep (500);
936 } while (res && device_wait && time (0) < ti);
938 if (res) return (res);
940 if (*logfile) {
941 logfp = fopen (logfile,"w");
942 if (!logfp) {
943 fprintf (stderr,"Unable to open Logfile %s\n",logfile);
944 exit (-1);
948 if (*hexfile) {
949 hexfp = fopen (hexfile,"w");
950 if (!hexfp) {
951 fprintf (stderr,"Unable to open Hexfile %s\n",hexfile);
952 exit (-1);
956 #ifdef LINUX
957 if (mode_flag & DAEMON_MODE) {
958 if (fork () == 0) {
959 fclose (stdin);
960 fclose (stdout);
961 fclose (stderr);
962 stderr = NULL;
963 setsid ();
964 fp = fopen ("/tmp/.irserver.pid","w");
965 if (fp) {
966 fprintf (fp,"%d\n",getpid ());
967 fclose (fp);
970 else exit (0);
972 #endif
974 sprintf (msg,"IRServer Version %s\n",VERSION);
975 log_print (msg,LOG_FATAL);
977 if (!device_cnt && strcmp (dev,"dummy")) {
978 sprintf (msg,"No IRTrans Devices found.\nAborting ...\n\n");
979 log_print (msg,LOG_FATAL);
980 exit (-1);
982 for (i=0;i < device_cnt;i++) {
983 if (IRDevices[i].io.if_type == IF_LAN) sprintf (msg,"[%2d]: %-10s: IR VER: %-8s ETH VER: %-8s SN: %u MAC:%02x-%02x-%02x-%02x-%02x-%02x\n",i,
984 IRDevices[i].name,IRDevices[i].version,IRDevices[i].lan_version,IRDevices[i].fw_serno,
985 IRDevices[i].mac_adr[0],
986 IRDevices[i].mac_adr[1],
987 IRDevices[i].mac_adr[2],
988 IRDevices[i].mac_adr[3],
989 IRDevices[i].mac_adr[4],
990 IRDevices[i].mac_adr[5]);
991 else if (IRDevices[i].fw_serno) sprintf (msg,"[%2d]: %-20s %-12s SN: %u\n",i,IRDevices[i].name,IRDevices[i].version,IRDevices[i].fw_serno);
992 else sprintf (msg,"[%2d]: %-20s %-12s\n",i,IRDevices[i].name,IRDevices[i].version);
993 log_print (msg,LOG_FATAL);
996 if (udp_relay_port) {
997 sprintf (msg,"Relaying to UDP %s:%d using Format %s\n",udp_relay_host,udp_relay_port,udp_relay_format);
998 log_print (msg,LOG_INFO);
1001 res = ReadIRDatabase ();
1002 if (res) return (res);
1004 InitConversionTables ();
1006 if (pidfile[0]) {
1007 FILE *pf;
1008 pf = fopen (pidfile,"w");
1009 if (pf == NULL) {
1010 sprintf (msg,"Cannot create PID file %s\n",pidfile);
1011 log_print (msg,LOG_ERROR);
1013 else {
1014 fprintf (pf,"%d\n",_getpid ());
1015 fclose (pf);
1018 return (0);
1021 int RunServer ()
1023 char err[256];
1024 int res,wait,evnt,i,j;
1025 SOCKET sockfd;
1026 DWORD cnt;
1027 byte rdcom[1000],dummy;
1028 time_t lasttimesync = 0;
1029 struct sockaddr_in send_adr;
1030 IRDATA_LAN_SHORT ir;
1033 #ifdef LINUX
1034 fd_set events;
1035 int maxfd,ionum;
1036 int socktype;
1037 struct timeval tv;
1038 byte usbflag;
1039 #endif
1041 #ifdef WIN32
1042 int numevents;
1043 int waittime;
1044 int ser_event;
1045 HANDLE events[CLIENT_COUNT + MAX_IR_DEVICES + 4];
1046 OVERLAPPED OvCom[MAX_IR_DEVICES];
1047 byte event_type[CLIENT_COUNT + MAX_IR_DEVICES + 4];
1048 byte event_num[CLIENT_COUNT + MAX_IR_DEVICES + 4];
1049 #endif
1051 if (mode_flag & READ_EEPROM) {
1052 ReadFlashdataEx (0,0);
1053 ReadFlashdataEx (0,128);
1054 ReadFlashdataEx (0,256);
1055 ReadFlashdataEx (0,384);
1056 ReadFlashdataEx (0,512);
1057 ReadFlashdataEx (0,768);
1058 ReadFlashdataEx (0,896);
1059 ReadFlashdataEx (0,1024);
1060 ReadFlashdataEx (0,1152);
1061 exit (0);
1064 if (webport) {
1065 sprintf (rdcom,"IRTrans Webserver started on Port %d.\n",webport);
1066 if (webport) log_print (rdcom,LOG_FATAL);
1069 if (mode_flag & CLOCK_STARTUP) LCDTimeCommand (LCD_DISPLAYTIME);
1070 else LCDTimeCommand (LCD_SETTIME);
1071 LCDBrightness (5);
1072 lasttimesync = time (0);
1073 #ifdef LINUX
1074 if (new_lcd_flag) {
1075 SetLCDProcCharsV (rdcom);
1077 AdvancedLCD (LCD_DATA | LCD_DEFINECHAR,rdcom,rdcom[0] * 9 + 1);
1078 msSleep (250);
1080 #endif
1082 #ifdef WIN32
1083 waittime = INFINITE;
1084 for (i=0;i < device_cnt;i++) if ((!(mode_flag & NO_RECONNECT) && IRDevices[i].io.if_type == IF_USB) || mode_flag & XAP) waittime = 10000;
1086 while (1) {
1087 for (i=0;i < device_cnt;i++) {
1088 for (j=0;j < IRDevices[i].io.receive_buffer_cnt;j++) {
1089 if (IRDevices[i].io.receive_cnt[j] > 2) ExecuteReceivedCommand (IRDevices[i].io.receive_buffer[j],IRDevices[i].io.receive_cnt[j],i);
1090 IRDevices[i].io.receive_cnt[j] = 0;
1092 IRDevices[i].io.receive_buffer_cnt = 0;
1094 for (i=0;i < device_cnt;i++) while (GetAvailableDataEx (IRDevices+i)) {
1095 cnt = ReadInstantReceive (&IRDevices[i],rdcom,1000);
1096 if (cnt > 2) ExecuteReceivedCommand (rdcom,cnt,i);
1098 numevents = build_event_table (events,event_type,event_num,OvCom,&ser_event);
1100 wait = WaitForMultipleObjects (numevents,events,FALSE,waittime);
1101 if ((time (0) - lasttimesync) > 3600) {
1102 LCDTimeCommand (LCD_SETTIME);
1103 lasttimesync = time (0);
1106 if ((time (0) - xAP_last_hbeat) > XAP_HBEAT) xAP_SendHeartbeat ();
1108 if (wait == WAIT_TIMEOUT) {
1109 dummy = 1;
1110 for (i=0;i < device_cnt;i++) if (IRDevices[i].io.if_type == IF_USB) WriteUSBStringEx (IRDevices + i,&dummy,1);
1112 else {
1113 evnt = get_selected_event (wait,events,event_type,event_num,&sockfd);
1114 switch (evnt) {
1115 case SELECT_TRANS:
1116 cnt = ReadInstantReceive (&IRDevices[event_num[wait]],rdcom,1000);
1117 if (cnt > 2) ExecuteReceivedCommand (rdcom,cnt,event_num[wait]);
1118 break;
1119 case SELECT_IRTLAN:
1120 i = sizeof (send_adr);
1121 res = recvfrom(irtlan_socket,(byte *)&ir,1024,MSG_NOSIGNAL,(struct sockaddr *)&send_adr,&i);
1122 if (res > 3 && (ir.netcommand == 's' || ir.netcommand == 'S' || ir.netcommand == 'l' || ir.netcommand == 'L' || ir.netcommand == 'p' || ir.netcommand == 'P')) {
1123 process_udp_command ((char *)&ir,res,&send_adr);
1124 break;
1126 if (res <= 0 || res != ir.ir_data.len + 1 || (ir.netcommand != RESULT_IR_BROADCAST_LED && ir.netcommand != RESULT_IR_BROADCAST && ir.netcommand != RESULT_IR_HOSTBROADCAST)) break;
1127 if (ir.netcommand == RESULT_IR_BROADCAST_LED) ir.ir_data.address = 0;
1128 if (ir.ir_data.command != SBUS_REPEAT) break;
1129 for (i=0;i < device_cnt;i++) if (IRDevices[i].io.if_type == IF_LAN) {
1130 if (IRDevices[i].io.IPAddr[0].sin_addr.s_addr == send_adr.sin_addr.s_addr) goto ip_found;
1132 GetError (ERR_DEVICEUNKNOWN,err);
1133 sprintf (rdcom,err,inet_ntoa (send_adr.sin_addr));
1134 log_print (rdcom,LOG_ERROR);
1135 break;
1137 ip_found: if (mode_flag & IP_RELAY) {
1138 ir.ir_data.command = HOST_SEND;
1139 ir.ir_data.target_mask = 0xffff;
1140 for (res=0;res<device_cnt;res++) if (IRDevices[res].io.if_type != IF_LAN) WriteTransceiverEx (&IRDevices[res],&ir.ir_data);
1143 rdcom[0] = ((ir.ir_data.mode & (RC5_DATA | RC6_DATA | RAW_DATA)) << 2) | ir.ir_data.address;
1144 memcpy (rdcom+1,ir.ir_data.data,ir.ir_data.ir_length);
1145 rdcom[ir.ir_data.ir_length+1] = 0;
1146 ExecuteReceivedCommand (rdcom,ir.ir_data.ir_length+1,i);
1147 break;
1148 case SELECT_LIRC:
1149 case SELECT_LOCAL:
1150 case SELECT_SERVER:
1151 register_remote_client (sockfd,evnt);
1152 break;
1153 case SELECT_WEB:
1154 ProcessWebRequest (sockfd);
1155 break;
1156 case SELECT_UDP:
1157 // process_udp_command (sockfd);
1158 break;
1159 case SELECT_XAP:
1160 xAP_EventReceived ();
1161 break;
1162 case COMMAND_LIRC:
1163 case COMMAND_LOCAL:
1164 process_lirc_command (sockfd);
1165 break;
1166 case COMMAND_SERVER:
1167 case COMMAND_REOPEN:
1168 ExecuteNetCommand (sockfd);
1169 break;
1173 #endif
1175 #ifdef LINUX
1176 while (1) {
1178 maxfd = build_select_table (&events);
1180 tv.tv_sec = 10;
1181 tv.tv_usec = 0;
1183 usbflag = 0;
1184 for (i=0;i < device_cnt;i++) if (!(mode_flag & NO_RECONNECT) && IRDevices[i].io.if_type == IF_USB) usbflag = 1;
1186 if ((usbflag && !(mode_flag & NO_RECONNECT)) || mode_flag & XAP) wait = select (maxfd,&events,NULL,NULL,&tv);
1187 else wait = select (maxfd,&events,NULL,NULL,NULL);
1190 if (wait == -1) {
1191 sprintf (rdcom,"Select Error: %d\n",errno);
1192 log_print (rdcom,LOG_FATAL);
1193 exit (-1);
1196 if ((time (0) - lasttimesync) > 3600) {
1197 LCDTimeCommand (LCD_SETTIME);
1198 lasttimesync = time (0);
1201 if ((time (0) - xAP_last_hbeat) > XAP_HBEAT) xAP_SendHeartbeat ();
1203 if (!wait) {
1204 dummy = 1;
1205 for (i=0;i < device_cnt;i++) if (IRDevices[i].io.if_type == IF_USB) WriteIRStringEx (IRDevices + i,&dummy,1);
1207 while (wait > 0) {
1208 evnt = get_selected_fd (&events,&sockfd,&ionum);
1209 switch (evnt) {
1210 case SELECT_TRANS:
1211 cnt = ReadInstantReceive (IRDevices + ionum,rdcom,1000);
1212 if (cnt > 2) ExecuteReceivedCommand (rdcom,cnt,ionum);
1213 break;
1214 case SELECT_IRTLAN:
1215 i = sizeof (send_adr);
1216 res = recvfrom(irtlan_socket,(byte *)&ir,1024,MSG_NOSIGNAL,(struct sockaddr *)&send_adr,&i);
1217 if (res > 5 && ir.netcommand == 's' || ir.netcommand == 'S' || ir.netcommand == 'l' || ir.netcommand == 'L') {
1218 process_udp_command ((char *)&ir,res,&send_adr);
1219 break;
1221 if (res <= 0 || res != ir.ir_data.len + 1 || (ir.netcommand != RESULT_IR_BROADCAST_LED && ir.netcommand != RESULT_IR_BROADCAST && ir.netcommand != RESULT_IR_HOSTBROADCAST)) break;
1222 if (ir.netcommand == RESULT_IR_BROADCAST_LED) ir.ir_data.address = 0;
1223 if (ir.ir_data.command != SBUS_REPEAT) break;
1224 for (i=0;i < device_cnt;i++) if (IRDevices[i].io.if_type == IF_LAN) {
1225 for (j=0;j < 16 && IRDevices[i].io.IPAddr[j].sin_addr.s_addr;j++) {
1226 if (IRDevices[i].io.IPAddr[j].sin_addr.s_addr == send_adr.sin_addr.s_addr) goto ip_found;
1229 GetError (ERR_DEVICEUNKNOWN,err);
1230 sprintf (rdcom,err,inet_ntoa (send_adr.sin_addr));
1231 log_print (rdcom,LOG_ERROR);
1232 break;
1234 ip_found: if (mode_flag & IP_RELAY) {
1235 ir.ir_data.command = HOST_SEND;
1236 ir.ir_data.target_mask = 0xffff;
1237 for (res=0;res<device_cnt;res++) if (IRDevices[res].io.if_type != IF_LAN) WriteTransceiverEx (&IRDevices[res],&ir.ir_data);
1239 rdcom[0] = ((ir.ir_data.mode & (RC5_DATA | RC6_DATA | RAW_DATA)) << 2) | j;
1240 memcpy (rdcom+1,ir.ir_data.data,ir.ir_data.ir_length);
1241 rdcom[ir.ir_data.ir_length+1] = 0;
1242 ExecuteReceivedCommand (rdcom,ir.ir_data.ir_length+1,i);
1243 break;
1244 case SELECT_LIRC:
1245 case SELECT_LOCAL:
1246 case SELECT_SERVER:
1247 register_remote_client (sockfd,evnt);
1248 break;
1249 case SELECT_WEB:
1250 ProcessWebRequest (sockfd);
1251 break;
1252 case COMMAND_LIRC:
1253 case COMMAND_LOCAL:
1254 process_lirc_command (sockfd);
1255 break;
1256 case SELECT_XAP:
1257 xAP_EventReceived ();
1258 break;
1259 case SELECT_UDP:
1260 // process_udp_command (sockfd);
1261 break;
1262 case COMMAND_SERVER:
1263 case COMMAND_REOPEN:
1264 ExecuteNetCommand (sockfd);
1265 break;
1267 for (i=0;i < device_cnt;i++) {
1268 for (j=0;j < IRDevices[i].io.receive_buffer_cnt;j++) {
1269 if (IRDevices[i].io.receive_cnt[j] > 2) ExecuteReceivedCommand (IRDevices[i].io.receive_buffer[j],IRDevices[i].io.receive_cnt[j],i);
1270 IRDevices[i].io.receive_cnt[j] = 0;
1272 IRDevices[i].io.receive_buffer_cnt = 0;
1274 wait--;
1278 #endif
1283 #ifdef WIN32
1285 int build_event_table (HANDLE events[],byte event_type[],byte event_num[],OVERLAPPED OvCom[],int *ser_event)
1287 int i,num = 0;
1289 for (i=0;i < device_cnt;i++) {
1290 if (IRDevices[i].io.if_type != IF_LAN) {
1291 if (IRDevices[i].io.if_type == IF_USB) SetUSBEventEx (&IRDevices[i],FT_EVENT_RXCHAR);
1292 else {
1293 memset (&OvCom[i],0,sizeof (OVERLAPPED));
1294 OvCom[i].hEvent = IRDevices[i].io.event;
1295 SetCommMask (IRDevices[i].io.comport,EV_RXCHAR);
1296 WaitCommEvent (IRDevices[i].io.comport,ser_event,&OvCom[i]);
1298 event_type[num] = SELECT_TRANS;
1299 event_num[num] = i;
1300 events[num++] = IRDevices[i].io.event;
1304 event_type[num] = SELECT_SERVER;
1305 event_num[num] = 0;
1306 events[num++] = SockEvent;
1308 if (LircEvent) {
1309 event_type[num] = SELECT_LIRC;
1310 event_num[num] = 0;
1311 events[num++] = LircEvent;
1314 event_type[num] = SELECT_UDP;
1315 event_num[num] = 0;
1316 events[num++] = UDPEvent;
1318 event_type[num] = SELECT_IRTLAN;
1319 event_num[num] = 0;
1320 events[num++] = IrtLanEvent;
1322 if (WebEvent) {
1323 event_type[num] = SELECT_WEB;
1324 event_num[num] = 0;
1325 events[num++] = WebEvent;
1328 if (mode_flag & XAP) {
1329 event_type[num] = SELECT_XAP;
1330 event_num[num] = 0;
1331 events[num++] = xAPEvent;
1334 for (i=0;i < CLIENT_COUNT;i++) if (sockinfo[i].fd != -1 && sockinfo[i].event) {
1335 event_type[num] = SELECT_CLIENT;
1336 event_num[num] = i;
1337 events[num++] = sockinfo[i].event;
1340 return (num);
1343 int get_selected_event (int eventnum,HANDLE events[],byte event_type[],byte event_num[],SOCKET *sockfd)
1346 int fds = 0,i = 0;
1348 if (event_type[eventnum] == SELECT_TRANS) ResetEvent (events[eventnum]);
1349 else WSAResetEvent (events[eventnum]);
1351 if (event_type[eventnum] == SELECT_SERVER) *sockfd = server_socket;
1352 else if (event_type[eventnum] == SELECT_LIRC) *sockfd = lirc_socket;
1353 else if (event_type[eventnum] == SELECT_UDP) *sockfd = udp_socket;
1354 else if (event_type[eventnum] == SELECT_WEB) *sockfd = web_socket;
1355 else if (event_type[eventnum] == SELECT_XAP) *sockfd = xAP_rcv;
1356 else if (event_type[eventnum] == SELECT_IRTLAN) *sockfd = irtlan_socket;
1359 fds = event_type[eventnum];
1361 if (event_type[eventnum] == SELECT_CLIENT) {
1362 *sockfd = sockinfo[event_num[eventnum]].fd;
1363 fds = sockinfo[event_num[eventnum]].type + 100;
1366 for (i=0;i < device_cnt;i++) {
1367 if (IRDevices[i].io.if_type == IF_USB) SetUSBEventEx (&IRDevices[i],0);
1368 else SetCommMask (IRDevices[i].io.comport,0);
1371 return (fds);
1374 #endif
1376 #ifdef LINUX
1378 int get_selected_fd (fd_set *events,SOCKET *sockfd,int *ionum)
1380 int fds = 0,i = 0;
1382 for (i=0;i < device_cnt && !fds;i++) if (IRDevices[i].io.if_type != IF_LAN){
1383 if (FD_ISSET (IRDevices[i].io.comport,events)) {
1384 fds = SELECT_TRANS;
1385 *sockfd = IRDevices[i].io.comport;
1386 *ionum = i;
1389 if (!fds && FD_ISSET (server_socket,events)) {
1390 fds = SELECT_SERVER;
1391 *sockfd = server_socket;
1393 if (!(mode_flag & NO_LIRC) && !fds && FD_ISSET (lirc_socket,events)) {
1394 fds = SELECT_LIRC;
1395 *sockfd = lirc_socket;
1397 if (!(mode_flag & NO_LIRC) && !fds && FD_ISSET (local_socket,events)) {
1398 fds = SELECT_LOCAL;
1399 *sockfd = local_socket;
1402 if (!(mode_flag & NO_WEB) && !fds && FD_ISSET (web_socket,events)) {
1403 fds = SELECT_WEB;
1404 *sockfd = web_socket;
1407 if (!fds && FD_ISSET (udp_socket,events)) {
1408 fds = SELECT_UDP;
1409 *sockfd = udp_socket;
1412 if (mode_flag & XAP && !fds && FD_ISSET (xAP_rcv,events)) {
1413 fds = SELECT_XAP;
1414 *sockfd = xAP_rcv;
1417 if (!fds && FD_ISSET (irtlan_socket,events)) {
1418 fds = SELECT_IRTLAN;
1419 *sockfd = irtlan_socket;
1422 i = 0;
1423 while (!fds && i < CLIENT_COUNT) {
1424 if (sockinfo[i].type && FD_ISSET (sockinfo[i].fd,events)) {
1425 fds = sockinfo[i].type + 100;
1426 *sockfd = sockinfo[i].fd;
1428 i++;
1431 if (fds) FD_CLR (*sockfd,events);
1433 return (fds);
1437 int build_select_table (fd_set *events)
1439 int i,max;
1441 FD_ZERO (events);
1443 FD_SET (server_socket,events);
1444 max = server_socket;
1446 for (i=0;i < device_cnt;i++) if (IRDevices[i].io.if_type != IF_LAN){
1447 FD_SET (IRDevices[i].io.comport,events);
1448 if (IRDevices[i].io.comport > max) max = IRDevices[i].io.comport;
1451 if (!(mode_flag & NO_LIRC)) {
1452 FD_SET (lirc_socket,events);
1453 if (lirc_socket > max) max = lirc_socket;
1454 FD_SET (local_socket,events);
1455 if (local_socket > max) max = local_socket;
1459 FD_SET (udp_socket,events);
1460 if (udp_socket > max) max = udp_socket;
1462 if (!(mode_flag & NO_WEB)) {
1463 FD_SET (web_socket,events);
1464 if (web_socket > max) max = web_socket;
1467 if (mode_flag & XAP) {
1468 FD_SET (xAP_rcv,events);
1469 if (xAP_rcv > max) max = xAP_rcv;
1472 FD_SET (irtlan_socket,events);
1473 if (irtlan_socket > max) max = irtlan_socket;
1476 for (i=0;i < CLIENT_COUNT;i++) if (sockinfo[i].fd != -1) {
1477 FD_SET (sockinfo[i].fd,events);
1478 if (sockinfo[i].fd > max) max = sockinfo[i].fd;
1480 return (max + 1);
1483 #endif
1488 SOCKET register_remote_client (SOCKET fd,int mode)
1490 int res,num,asciimode = 0;
1491 unsigned int adr;
1492 SOCKET call;
1493 int clilen;
1494 char rdcom[1024];
1495 uint32_t clientid;
1496 struct sockaddr_in cli_addr;
1498 if (mode == SELECT_LIRC) sprintf (rdcom,"LIRC TCP/IP Socket connection request\n");
1499 if (mode == SELECT_LOCAL) sprintf (rdcom,"Local Socket connection request\n");
1500 if (mode == SELECT_SERVER) sprintf (rdcom,"IRTRANS TCP/IP Socket connection request\n");
1502 log_print (rdcom,LOG_DEBUG);
1503 clilen = sizeof (cli_addr);
1505 call = accept (fd,(struct sockaddr *)&cli_addr,&clilen);
1506 if (call < 0) {
1507 sprintf (rdcom,"Accept error %d\n",errno);
1508 log_print (rdcom,LOG_ERROR);
1510 else {
1511 #ifdef WIN32
1512 adr = ntohl (cli_addr.sin_addr.S_un.S_addr);
1513 #else
1514 adr = ntohl (cli_addr.sin_addr.s_addr);
1515 #endif
1516 if (adr != 0x7f000001 && mode != SELECT_LOCAL) {
1517 for (res=0;res < netcount;res++) {
1518 if ((netip[res] & netmask[res]) == (adr & netmask[res])) break;
1520 if (netcount && res == netcount) {
1521 sprintf (rdcom,"Error: IP Address %s not allowed (Access rights).\n",inet_ntoa (cli_addr.sin_addr));
1522 log_print (rdcom,LOG_ERROR);
1523 shutdown (call,2);
1524 closesocket (call);
1525 return (0);
1529 res = 0;
1530 if (mode == SELECT_SERVER) {
1531 #ifdef WIN32
1532 WSAEventSelect (call,SockEvent,0);
1533 ioctlsocket (call,FIONBIO,&res);
1534 #endif
1535 res = recv (call,(char *)&clientid,4,MSG_NOSIGNAL);
1536 if (res != 4) {
1537 shutdown (call,2);
1538 closesocket (call);
1539 return (0);
1541 #ifdef LINUX
1542 fcntl (call,F_SETFL,O_NONBLOCK);
1543 #endif
1544 if (!memcmp ((char *)&clientid,"ASCI",4) || !memcmp ((char *)&clientid,"****",4)) {
1545 asciimode = MODE_ASCII;
1546 clientid = 0;
1548 swap_int (&clientid);
1549 res = 0;
1550 if (clientid > 1) {
1551 while (res < CLIENT_COUNT) {
1552 if (sockinfo[res].type == SELECT_REOPEN &&
1553 clientid == sockinfo[res].clientid) {
1554 if (sockinfo[res].fd != -1) {
1555 #ifdef WIN32
1556 WSACloseEvent (sockinfo[res].event);
1557 sockinfo[res].event = NULL;
1558 #endif
1559 shutdown (sockinfo[res].fd,2);
1560 closesocket (sockinfo[res].fd);
1562 sockinfo[res].fd = call;
1563 #ifdef WIN32
1564 sockinfo[res].event = WSACreateEvent ();
1565 WSAEventSelect (call,sockinfo[res].event,FD_READ | FD_CLOSE);
1566 #endif
1567 return (call);
1569 res++;
1571 // Send Status illegal ID
1573 if (clientid == 1) mode = SELECT_REOPEN;
1575 while (res < CLIENT_COUNT) { // Leeren Eintrag suchen
1576 if (sockinfo[res].type == 0) {
1577 sockinfo[res].fd = call;
1578 sockinfo[res].type = mode;
1579 sockinfo[res].mode = asciimode;
1580 if (mode == SELECT_REOPEN) sockinfo[res].clientid = seq_client++;
1581 strcpy (sockinfo[res].ip,inet_ntoa (cli_addr.sin_addr));
1582 #ifdef WIN32
1583 sockinfo[res].event = WSACreateEvent ();
1584 WSAEventSelect (call,sockinfo[res].event,FD_READ | FD_CLOSE);
1585 #endif
1586 if (mode == SELECT_LIRC) sprintf (rdcom,"LIRC TCP/IP Client %d accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1587 if (mode == SELECT_LOCAL) sprintf (rdcom,"Local Client %d accepted on %d\n",res,call);
1588 if (mode == SELECT_SERVER) {
1589 if (asciimode == MODE_ASCII) sprintf (rdcom,"IRTRANS TCP/IP Client %d [ASCII Mode] accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1590 else sprintf (rdcom,"IRTRANS TCP/IP Client %d accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1592 if (mode == SELECT_REOPEN) sprintf (rdcom,"IRTRANS [R] TCP/IP Client %d accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1593 log_print (rdcom,LOG_INFO);
1594 break;
1596 res++;
1598 if (res == CLIENT_COUNT) {
1599 res = 0;
1600 num = -1;
1601 clientid = 0xffffffff;
1602 while (res < CLIENT_COUNT) { // Ältesten Eintrag suchen
1603 if (sockinfo[res].type == SELECT_REOPEN &&
1604 sockinfo[res].callno < clientid && sockinfo[res].fd == -1) {
1605 num = res;
1606 clientid = sockinfo[res].callno;
1608 res++;
1611 res = num;
1612 if (res >= 0) {
1613 if (sockinfo[res].fp) fclose ((sockinfo[res].fp));
1614 sockinfo[res].fp = NULL;
1616 sockinfo[res].fd = call;
1617 sockinfo[res].type = mode;
1618 if (mode == SELECT_REOPEN) sockinfo[res].clientid = seq_client++;
1619 strcpy (sockinfo[res].ip,inet_ntoa (cli_addr.sin_addr));
1620 #ifdef WIN32
1621 sockinfo[res].event = WSACreateEvent ();
1622 WSAEventSelect (call,sockinfo[res].event,FD_READ | FD_CLOSE);
1623 #endif
1624 if (mode == SELECT_LIRC) sprintf (rdcom,"LIRC TCP/IP Client %d accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1625 if (mode == SELECT_LOCAL) sprintf (rdcom,"Local Client %d accepted on %d\n",res,call);
1626 if (mode == SELECT_SERVER) sprintf (rdcom,"IRTRANS TCP/IP Client %d accepted from %s\n",res,inet_ntoa (cli_addr.sin_addr));
1627 log_print (rdcom,LOG_INFO);
1631 if (res == CLIENT_COUNT) {
1632 sprintf (rdcom,"No more socket client (max=%d)\n",res);
1633 log_print (rdcom,LOG_ERROR);
1634 shutdown (call,2);
1635 closesocket (call);
1639 return (call);
1643 void process_lirc_command (SOCKET fd)
1645 int res,i;
1646 int num;
1647 char com[1024],msg[1024],*pnt,*key,*rem,err[256];
1648 char remote[80],command[20];
1649 static char active_lirc_string[1024];
1650 char *mp;
1651 char *ep;
1653 res = recv (fd,com,1024,MSG_NOSIGNAL);
1654 if (res <= 0) {
1655 i = 0;
1656 while (i < CLIENT_COUNT) {
1657 if (sockinfo[i].fd == fd) CloseIRSocket (i);
1658 i++;
1660 *active_lirc_string = 0;
1661 return;
1663 com[res] = 0;
1664 strcat (active_lirc_string,com);
1665 if (com[res-1] != 13 && com[res-1] != 10) return;
1666 strcpy (com,active_lirc_string);
1667 *active_lirc_string = 0;
1669 sprintf (err,"LIRC Command String: %s\n",com);
1670 log_print (err,LOG_DEBUG);
1672 for (mp = com; *mp && (ep = strchr(mp, '\n')); mp = ep)
1674 *ep++ = '\0';
1675 strcpy (msg,mp);
1676 strcat (msg, "\n");
1677 pnt = strtok (mp," \t\n\r");
1678 // Unterstützung Start / Stop Repeat ??
1679 if (!strcmp (mp,"SEND_ONCE") || !strcmp (mp,"send_once")) {
1680 rem = strtok (NULL," \t\n\r");
1681 key = strtok (NULL," \t\n\r");
1682 if (rem == NULL || key == NULL) {
1683 sprintf (err,"IR Send Error: No Remote / Command specified\n");
1684 log_print (err,LOG_ERROR);
1685 lirc_send_error (fd,msg,err);
1686 continue;
1688 strcpy (remote,rem);
1689 ConvertLcase (remote,(int)strlen (remote));
1690 strcpy (command,key);
1691 ConvertLcase (command,(int)strlen (command));
1692 sprintf (err,"LIRC SEND_ONCE Rem: %s Key: %s\n",remote,command);
1693 log_print (err,LOG_DEBUG);
1695 if (!memcmp (command,"+++wait",7)) {
1696 msSleep (atol (command + 7));
1698 else {
1699 res = DBFindRemoteCommand (remote,command,&num,NULL);
1700 if (res) {
1701 sprintf (err,"IR Send Error %d\n",res);
1702 log_print (err,LOG_ERROR);
1703 lirc_send_error (fd,msg,err);
1704 continue;
1706 SendIR (num,0x40000000);
1708 resend_flag = 0;
1709 lirc_send_success (fd,msg);
1710 continue;
1712 if (!strcmp (mp,"LIST") || !strcmp (mp,"list") || !strcmp (mp,"List")) {
1713 rem = strtok (NULL," \t\n\r");
1714 key = strtok (NULL," \t\n\r");
1715 lirc_list_command (fd,rem,key,msg);
1716 continue;
1719 sprintf (err,"Unknown LIRC Command received: %s\n",pnt);
1720 log_print (err,LOG_ERROR);
1721 lirc_send_error (fd,msg,err);
1726 void lirc_list_command (SOCKET fd,char rem[],char key[],char msg[])
1728 int i,j;
1729 char st[1024],err[256],num[1000];
1730 char remote[80],command[20];
1732 memset (remote,0,80);
1733 memset (command,0,20);
1736 if (rem == NULL && key == NULL) {
1737 sprintf (err,"LIRC LIST REMOTES received.\n");
1738 log_print (err,LOG_DEBUG);
1740 sprintf (st,"BEGIN\n%sSUCCESS\nDATA\n%d\n",msg,rem_cnt);
1741 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1742 for (i=0;i < rem_cnt;i++) {
1743 sprintf (st,"%s\n",rem_pnt[i].name);
1744 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1747 sprintf (st,"END\n");
1748 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1749 return;
1752 if (key == NULL) {
1753 strcpy (remote,rem);
1754 ConvertLcase (remote,(int)strlen (remote));
1755 sprintf (err,"LIRC LIST COMMANDS %s received.\n",remote);
1756 log_print (err,LOG_DEBUG);
1758 i = DBFindRemote (remote);
1759 if (i == -1) {
1760 sprintf (st,"No Remote %s found",rem);
1761 lirc_send_error (fd,msg,st);
1762 return;
1764 sprintf (st,"BEGIN\n%sSUCCESS\nDATA\n%d\n",msg,rem_pnt[i].command_end - rem_pnt[i].command_start);
1765 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1766 for (j=0;j < rem_pnt[i].command_end - rem_pnt[i].command_start;j++) {
1768 GetNumericCode (cmd_pnt[rem_pnt[i].command_start + j].data,num,remote,cmd_pnt[rem_pnt[i].command_start + j].name);
1770 sprintf (st,"%s %s\n",num,cmd_pnt[rem_pnt[i].command_start + j].name);
1771 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1774 sprintf (st,"END\n");
1775 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1776 return;
1778 strcpy (remote,rem);
1779 ConvertLcase (remote,(int)strlen (remote));
1780 i = DBFindRemote (remote);
1781 if (i == -1) {
1782 sprintf (st,"No Remote %s found",rem);
1783 lirc_send_error (fd,msg,st);
1784 return;
1786 strcpy (command,key);
1787 ConvertLcase (command,(int)strlen (command));
1789 sprintf (err,"LIRC LIST COMMAND DETAIL %s-%s received.\n",remote,command);
1790 log_print (err,LOG_DEBUG);
1792 j = DBFindCommand (command,i);
1793 if (j == -1) {
1794 sprintf (st,"No Remote/Command %s/%s found",rem,key);
1795 lirc_send_error (fd,msg,st);
1796 return;
1798 sprintf (st,"BEGIN\n%sSUCCESS\nDATA\n%d\n",msg,1);
1799 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1801 GetNumericCode (cmd_pnt[j].data,num,remote,command);
1803 sprintf (st,"%s %s\n",num,command);
1804 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1806 sprintf (st,"END\n");
1807 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1811 void lirc_send_success (SOCKET fd,char msg[])
1813 char st[1024];
1815 sprintf (st,"BEGIN\n%sSUCCESS\nEND\n",msg);
1816 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1820 void lirc_send_error (SOCKET fd,char msg[],char err[])
1822 char st[1024];
1824 sprintf (st,"BEGIN\n%sERROR\nDATA\n1\n%s\nEND\n",msg,err);
1825 send (fd,st,(int)strlen (st),MSG_NOSIGNAL);
1829 // Erkannte IR Codes an Clients schicken
1831 #ifdef WIN32
1832 #ifndef WINCE
1833 unsigned int GetFineTime (void)
1835 struct _timeb tb;
1837 _ftime (&tb);
1838 return (unsigned int)((tb.time & 0x7fffff) * 1000 + tb.millitm);
1840 #endif
1841 #endif
1843 #ifdef LINUX
1844 unsigned int GetFineTime (void)
1846 struct timeval tb;
1848 gettimeofday (&tb,NULL);
1849 return (tb.tv_sec & 0x7fffff) * 1000 + tb.tv_usec / 1000;
1851 #endif
1853 #ifdef WINCE
1854 unsigned int GetFineTime (void)
1856 // GetLocalTime (...);
1860 #endif
1863 void send_forward (int client,char rem[],char name[])
1865 int res,i;
1866 NETWORKRECV nr;
1867 char msg[256];
1869 memset (&nr,0,sizeof (NETWORKRECV));
1870 memset (nr.data,' ',200);
1871 memset (nr.remote,' ',80);
1872 memset (nr.command,' ',20);
1874 nr.clientid = 0;
1875 nr.statuslen = sizeof (NETWORKRECV);
1876 nr.statustype = STATUS_RECEIVE;
1877 memcpy (nr.remote,rem,strlen (rem));
1878 memcpy (nr.command,name,strlen (name));
1880 SwapNetworkheader ((NETWORKSTATUS *)&nr);
1882 for (i=0;i < CLIENT_COUNT;i++) if (i != client) {
1884 if (sockinfo[i].type == SELECT_SERVER || sockinfo[i].type == SELECT_REOPEN) {
1885 if (sockinfo[i].mode == MODE_ASCII) {
1886 sprintf (msg,"**00000 RCV_COM %s,%s,%d,%d\n",rem,name,0,0);
1887 sprintf (msg+2,"%05d",strlen (msg));
1888 msg[7] = ' ';
1889 res = send (sockinfo[i].fd,msg,(int)strlen (msg),MSG_NOSIGNAL);
1891 else res = send (sockinfo[i].fd,(char *)&nr,sizeof (NETWORKRECV),MSG_NOSIGNAL);
1892 if (res <= 0) CloseIRSocket (i);
1899 int ExecuteReceivedCommand (byte command[],int len,int bus)
1901 int res,i = 0;
1902 int start_pos = 0;
1903 static time_t l_time;
1904 static char l_command[21];
1905 static char l_remote[81];
1906 static int l_repeat;
1907 static char l_addr;
1908 int com_num,rem_num;
1909 static unsigned int ltv;
1910 static int rcnt;
1911 unsigned int tv;
1914 char rem[512],name[512],num[512],dat[1024],msg[256];
1915 NETWORKRECV nr;
1917 memset (&nr,0,sizeof (NETWORKRECV));
1918 memset (nr.data,' ',200);
1919 memset (nr.remote,' ',80);
1920 memset (nr.command,' ',20);
1923 if (!(IRDevices[bus].io.inst_receive_mode & 2)) {
1924 tv = GetFineTime ();
1926 if ((!rcnt && (tv - ltv) < 200) || (tv - ltv) < 250) {
1927 rcnt++;
1928 ltv = tv;
1929 if (rcnt < 5) return (1);
1931 else rcnt = 0;
1932 ltv = tv;
1935 start_pos = DBFindCommandName (command + 1,rem,name,*command,&rem_num,&com_num,&nr.command_num,start_pos);
1936 if (start_pos) {
1937 while (start_pos) {
1938 if (time (0) != l_time || strcmp (l_command,name) || strcmp (l_remote,rem)) l_repeat = 0;
1940 if ((time (0) - l_time) < 2 && !strcmp (l_command,name) && !strcmp (l_remote,rem) && l_addr != (*command & 0xf)) return (1);
1941 GetNumericCode (command + 1,num,rem,name);
1942 if (mode_flag & DEBUG_CODE) {
1943 sprintf (msg,"[%d.%d] %s %s\n",bus,(*command & 15),name,rem);
1944 log_print (msg,LOG_FATAL);
1946 sprintf (dat,"%s %02d %s %s%c",num,l_repeat,name,rem,10);
1948 memset (&nr,0,sizeof (NETWORKRECV));
1949 memset (nr.data,' ',200);
1950 memset (nr.remote,' ',80);
1951 memset (nr.command,' ',20);
1952 nr.clientid = 0;
1953 nr.statuslen = sizeof (NETWORKRECV);
1954 nr.statustype = STATUS_RECEIVE;
1955 memcpy (nr.remote,rem,strlen (rem));
1956 memcpy (nr.command,name,strlen (name));
1957 if (command[1] >= '0') memcpy (nr.data,command+1,strlen (command+1));
1958 else memcpy (nr.data,num,strlen (num));
1959 nr.adress = (*command & 15) + bus * 16;
1961 SwapNetworkheader ((NETWORKSTATUS *)&nr);
1962 if (command[1] != 'M' && command[1] != 'K') {
1963 i = 0;
1964 while (i < CLIENT_COUNT) {
1965 if (sockinfo[i].type == SELECT_LIRC || sockinfo[i].type == SELECT_LOCAL) {
1966 res = send (sockinfo[i].fd,dat,(int)strlen (dat),MSG_NOSIGNAL);
1967 if (res <= 0) CloseIRSocket (i);
1969 if (sockinfo[i].type == SELECT_SERVER || sockinfo[i].type == SELECT_REOPEN) {
1970 if (sockinfo[i].mode == MODE_ASCII) {
1971 sprintf (msg,"**00000 RCV_COM %s,%s,%d,%d\n",rem,name,bus,*command & 15);
1972 sprintf (msg+2,"%05d",strlen (msg));
1973 msg[7] = ' ';
1974 res = send (sockinfo[i].fd,msg,(int)strlen (msg),MSG_NOSIGNAL);
1976 else res = send (sockinfo[i].fd,(char *)&nr,sizeof (NETWORKRECV),MSG_NOSIGNAL);
1977 if (res <= 0) CloseIRSocket (i);
1979 i++;
1981 if (udp_relay_port) udp_relay (rem,name,*command & 15);
1983 if (mode_flag & XAP) xAP_SendIREvent (rem,name,bus,*command & 15);
1985 #ifdef WIN32
1986 PostWindowsMessage (rem_num,com_num,name);
1987 #endif
1988 l_repeat++;
1989 l_time = time (0);
1990 strcpy (l_command,name);
1991 strcpy (l_remote,rem);
1992 l_addr = *command & 0xf;
1993 start_pos = DBFindCommandName (command + 1,rem,name,*command,&rem_num,&com_num,&nr.command_num,start_pos);
1995 return (0);
1997 else if (!(((*command & 0xf0) >> 2) & RAW_DATA) && command[1] >= '0' && !(mode_flag & LEARNED_ONLY)) {
1998 memset (&nr,0,sizeof (NETWORKRECV));
1999 memset (nr.data,' ',200);
2000 memset (nr.remote,' ',80);
2001 memset (nr.command,' ',20);
2002 nr.clientid = 0;
2003 nr.statuslen = sizeof (NETWORKRECV);
2004 nr.statustype = STATUS_RECEIVE;
2005 memcpy (nr.data,command+1,strlen (command+1));
2006 nr.adress = (*command & 15) + bus * 16;
2007 nr.command_num = 0;
2009 SwapNetworkheader ((NETWORKSTATUS *)&nr);
2010 i = 0;
2011 while (i < CLIENT_COUNT) {
2012 if (sockinfo[i].type == SELECT_SERVER || sockinfo[i].type == SELECT_REOPEN) {
2013 if (sockinfo[i].mode == MODE_ASCII) {
2014 sprintf (msg,"**00000 RCV_COD %s,%d,%d\n",command+1,bus,*command & 15);
2015 sprintf (msg+2,"%05d",strlen (msg));
2016 msg[7] = ' ';
2017 res = send (sockinfo[i].fd,msg,(int)strlen (msg),MSG_NOSIGNAL);
2019 else res = send (sockinfo[i].fd,(char *)&nr,sizeof (NETWORKRECV),MSG_NOSIGNAL);
2020 if (res <= 0) CloseIRSocket (i);
2022 i++;
2024 if (mode_flag & DEBUG_CODE) {
2025 sprintf (msg,"[%d.%d]: %s %d\n",bus,(*command & 15),command+1,strlen(command+1));
2026 log_print (msg,LOG_FATAL);
2029 return (1);
2033 void udp_relay (char rem[],char com[],int adr)
2035 int i,p;
2036 char frm[255],dat[255];
2037 char adrst[10];
2038 char *parm[3];
2040 parm[0] = parm[1] = parm[2] = 0;
2041 sprintf (adrst,"%02d",adr);
2042 strcpy (frm,udp_relay_format);
2044 p = 0;
2045 for (i=0;frm[i];i++) {
2046 if (frm[i] == '%') {
2047 if (p == 3) frm[i] = ' ';
2048 else {
2049 i++;
2050 if (frm[i] == 'r') {
2051 parm[p++] = rem;
2052 frm[i] = 's';
2054 else if (frm[i] == 'c') {
2055 parm[p++] = com;
2056 frm[i] = 's';
2058 else if (frm[i] == 'a') {
2059 parm[p++] = adrst;
2060 frm[i] = 's';
2062 else frm[i-1] = ' ';
2067 sprintf (dat,frm,parm[0],parm[1],parm[2]);
2068 i = send (udp_relay_socket,dat,(int)strlen (dat),0);
2072 void CloseIRSocket (int client)
2074 #ifdef WIN32
2075 WSACloseEvent (sockinfo[client].event);
2076 sockinfo[client].event = NULL;
2077 #endif
2078 if (sockinfo[client].fd) {
2079 shutdown (sockinfo[client].fd,2);
2080 closesocket (sockinfo[client].fd);
2082 sockinfo[client].fd = -1;
2083 if (sockinfo[client].type == SELECT_REOPEN) return;
2085 sockinfo[client].type = 0;
2086 sockinfo[client].callno = 0;
2088 if (sockinfo[client].fp) fclose ((sockinfo[client].fp));
2089 sockinfo[client].fp = NULL;
2093 #ifdef LINUX
2094 #ifdef DBOX
2096 int ReadIRDatabase (void)
2099 int res,fl;
2100 char st[1024],*pnt,msg[256];
2101 FILE *fd;
2102 char *home = getenv("HOME");
2104 if (home)
2105 snprintf(st, sizeof(st), "%s/.irtrans/remotes", home);
2107 if (IRDataBaseRead) FreeDatabaseMemory ();
2109 else if (chdir ("./remotes")
2110 && !(home && chdir (st) == 0)
2111 && chdir ("/etc/irserver/remotes")
2112 && chdir ("/usr/local/share/irtrans/remotes")
2113 && chdir ("/usr/share/irtrans/remotes")
2114 ) return (ERR_NODATABASE);
2116 ReadRoutingTable ();
2117 ReadSwitches ();
2119 fd = popen ("ls","r");
2121 pnt = fgets (st,1000,fd);
2122 while (pnt) {
2124 if (pnt[strlen (pnt) - 1] == 10) pnt[strlen (pnt) - 1] = 0;
2125 fl = strlen (pnt) - 4;
2126 if (fl >= 1 && !strcmp (pnt + fl,".rem")) {
2127 res = DBReadCommandFile (pnt);
2128 if (res) {
2129 sprintf (msg,"Error %d reading DB-File %s\n",res,pnt);
2130 log_print (msg,LOG_ERROR);
2133 pnt = fgets (st,1000,fd);
2136 pclose (fd);
2138 DBShowStatus ();
2140 ReadAppConfig ();
2142 IRDataBaseRead = 1;
2143 return (0);
2146 #else // Keine DBOX, normales LINUX
2148 int ReadIRDatabase (void)
2151 int fd,i,len,pos,res,fl;
2152 long off;
2153 char st[2048],msg[256];
2154 struct dirent *di;
2155 char *home = getenv("HOME");
2156 char *rdir = getenv("IRTRANS_REMOTES");
2158 if (rdir) {
2159 if (chdir (rdir)) {
2160 sprintf (msg,"Error opening remote database %s\n",rdir);
2161 log_print (msg,LOG_FATAL);
2163 return (ERR_NODATABASE);
2167 else {
2168 if (home)
2169 snprintf(st, sizeof(st), "%s/.irtrans/remotes", home);
2171 if (IRDataBaseRead) FreeDatabaseMemory ();
2173 else if (chdir ("./remotes")
2174 && !(home && chdir (st) == 0)
2175 && chdir ("/etc/irserver/remotes")
2176 && chdir ("/usr/local/share/irtrans/remotes")
2177 && chdir ("/usr/share/irtrans/remotes")) return (ERR_NODATABASE);
2180 ReadRoutingTable ();
2181 ReadSwitches ();
2183 fd = open (".",0);
2185 do {
2186 len = getdirentries (fd,st,2048,&off);
2188 pos = 0;
2189 while (pos < len) {
2190 di = (struct dirent *)&st[pos];
2191 fl = strlen (di -> d_name) - 4;
2192 if (fl >= 1 && !strcmp (di->d_name + fl,".rem")) {
2193 res = DBReadCommandFile (di->d_name);
2194 if (res) {
2195 sprintf (msg,"Error %d reading DB-File %s\n",res,di->d_name);
2196 log_print (msg,LOG_ERROR);
2199 pos += di -> d_reclen;
2201 } while (len);
2203 close (fd);
2205 DBShowStatus ();
2206 ReadAppConfig ();
2208 IRDataBaseRead = 1;
2209 return (0);
2212 #endif
2214 #endif
2218 #ifdef WIN32
2220 #ifdef WINCE
2221 int ReadIRDatabase (void)
2223 return (0);
2226 #else
2227 int ReadIRDatabase (void)
2229 int res;
2230 struct _finddata_t c_file;
2231 #ifdef _M_X64
2232 intptr_t hFile;
2233 #else
2234 int hFile;
2235 #endif
2236 char msg[256];
2237 char *rdir = getenv("IRTRANS_REMOTES");
2239 if (rdir) {
2240 if (_chdir (rdir)) {
2241 sprintf (msg,"Error opening remote database %s\n",rdir);
2242 log_print (msg,LOG_FATAL);
2244 return (ERR_NODATABASE);
2248 else {
2249 if (IRDataBaseRead) FreeDatabaseMemory ();
2250 else if (_chdir ("remotes")) return (ERR_NODATABASE);
2253 ReadRoutingTable ();
2254 ReadSwitches ();
2256 if((hFile = _findfirst( "*.rem", &c_file )) != -1L) {
2257 do {
2258 res = DBReadCommandFile (c_file.name);
2259 if (res) {
2260 sprintf (msg,"Error %d reading DB-File %s\n",res,c_file.name);
2261 log_print (msg,LOG_ERROR);
2263 } while( _findnext( hFile, &c_file ) == 0);
2264 _findclose( hFile );
2268 DBShowStatus ();
2269 ReadAppConfig ();
2271 IRDataBaseRead = 1;
2272 return (0);
2276 #endif
2277 #endif
2280 void ExecuteNetCommand (SOCKET sockfd)
2282 int client,errcnt;
2283 int res,sz,len;
2284 char err[255];
2285 char c;
2286 char buffer[sizeof (CCFSTRINGCOMMAND)];
2287 char buffer1[sizeof (CCFSTRINGCOMMAND)];
2289 STATUSBUFFER stat;
2290 NETWORKCOMMAND *com;
2292 client = GetNetworkClient (sockfd);
2293 if (client == -1) {
2294 // Error not found
2295 return;
2299 sockinfo[client].callno = seq_call++;
2301 com = (NETWORKCOMMAND *)buffer;
2303 while (1) {
2304 if (sockinfo[client].restlen) {
2305 memcpy (buffer,sockinfo[client].restdata,sockinfo[client].restlen + 1);
2307 sz = sockinfo[client].restread - sockinfo[client].restlen;
2309 res = recv (sockfd,buffer + sockinfo[client].restlen + 1,sz,MSG_NOSIGNAL);
2310 if (res < 0) {
2311 #ifdef WIN32
2312 if (WSAGetLastError () == WSAEWOULDBLOCK) return;
2313 #else
2314 if (errno == EAGAIN) return;
2315 #endif
2318 sockinfo[client].restlen = 0;
2321 else {
2322 res = recv (sockfd,buffer,1,MSG_NOSIGNAL);
2324 if (res != 1 || *buffer < 1 || *buffer > COMMAND_ASCII) {
2325 if (res < 0) {
2326 #ifdef WIN32
2327 if (WSAGetLastError () == WSAEWOULDBLOCK) return;
2328 #else
2329 if (errno == EAGAIN) return;
2330 #endif
2332 if (res <= 0) CloseIRSocket (client);
2333 if (res == 0) {
2334 sprintf (err,"Client [%d] disconnect\n",client);
2335 log_print (err,LOG_INFO);
2337 else {
2338 if (res == 1) sprintf (err,"Illegal Network command [%d]\n",*buffer);
2339 if (res < 0) sprintf (err,"Network connection [%d] closed\n",client);
2340 log_print (err,LOG_ERROR);
2342 return;
2345 if (*buffer == COMMAND_ASCII) {
2346 len = 1;
2347 res = recv (sockfd,&c,1,MSG_NOSIGNAL);
2348 while (res == 1 && c != '\n') {
2349 buffer[len++] = c;
2350 res = recv (sockfd,&c,1,MSG_NOSIGNAL);
2352 if (c == '\n') buffer[len++] = c;
2353 buffer[len] = 0;
2354 if (buffer[len-1] != 13 && buffer[len-1] != 10) {
2355 sprintf (err,"Non terminated ASCII string: %d\n",buffer[len-1]);
2356 log_print (err,LOG_ERROR);
2357 return;
2360 while (buffer[len-1] == 13 || buffer[len-1] == 10) {
2361 buffer[len-1] = 0;
2362 len--;
2365 sprintf (err,"ASCII Command: %s\n",buffer+1);
2366 log_print (err,LOG_INFO);
2368 DoExecuteASCIICommand ((byte *)buffer+1,sockfd,client);
2369 return;
2372 sz = sizeof (NETWORKCOMMAND) - 1;
2373 if (*buffer == COMMAND_LCD) sz = sizeof (LCDCOMMAND) - 1;
2374 if (*buffer == COMMAND_STORETRANS) sz = sizeof (TRANSLATECOMMAND) - 1;
2375 if (*buffer == COMMAND_SENDCCF) sz = sizeof (CCFCOMMAND) - 1;
2376 if (*buffer == COMMAND_SENDCCFLONG) sz = sizeof (LONGCCFCOMMAND) - 1;
2377 if (*buffer == COMMAND_RS232_SEND) sz = sizeof (SERCOMMAND) - 1;
2378 if (*buffer == COMMAND_STOREIRDB) sz = sizeof (IRDBHEADER) - 1;
2379 if (*buffer == COMMAND_SENDCCFSTR) sz = sizeof (CCFSTRINGCOMMAND) - 1;
2380 if (*buffer == COMMAND_SENDCCFSTRS) sz = sizeof (CCFSTRINGCOMMAND_SHORT) - 1;
2381 if (*buffer == COMMAND_SETSTATEX) sz = sizeof (MODUSCOMMAND) - 1;
2383 res = recv (sockfd,buffer + 1,sz,MSG_NOSIGNAL);
2386 if (*buffer == COMMAND_STOREIRDB && res == (sizeof (IRDBCOMMAND) - 1)) sz = (sizeof (IRDBCOMMAND) - 1);
2388 if (res == sz - 4) { // Altes Commandformat
2389 sz = res;
2390 memcpy (buffer1,buffer,res);
2391 memcpy (buffer,buffer1,8);
2392 memcpy (buffer+12,buffer1+8,res-8);
2395 else if (res > 12 && (com->protocol_version / 100) != (PROTOCOL_VERSION / 100)) {
2396 sprintf (err,"ExecuteNetCommand: Illegal Protocol Version %d.%d (should be %d.%d)\n",
2397 com->protocol_version/100,com->protocol_version%100,PROTOCOL_VERSION/100,PROTOCOL_VERSION%100);
2398 log_print (err,LOG_FATAL);
2399 return;
2401 protocol_version = com->protocol_version;
2403 if (res != sz) {
2404 if (res <= 0) CloseIRSocket (client);
2405 if (res) {
2406 memcpy (sockinfo[client].restdata,buffer,res + 1);
2407 sockinfo[client].restlen = res;
2408 sockinfo[client].restread = sz;
2410 return;
2413 SwapNetworkcommand (com);
2414 DoExecuteNetCommand (client,com,&stat);
2416 stat.clientid = sockinfo[client].clientid;
2417 len = stat.statuslen;
2418 SwapNetworkstatus (&stat);
2420 errcnt = sz = 0;
2421 while (sz < len && errcnt < 20) {
2422 res = send (sockfd,((char *)&stat) + sz,len - sz,MSG_NOSIGNAL);
2423 if (res > 0) sz += res;
2424 if (res == -1) {
2425 msSleep (100);
2426 errcnt++;
2430 if (res <= 0) {
2431 CloseIRSocket (client);
2432 sprintf (err,"IP Connection lost\n");
2433 log_print (err,LOG_ERROR);
2441 void DoExecuteNetCommand (int client,NETWORKCOMMAND *com,STATUSBUFFER *stat)
2443 int res,i;
2444 int bus;
2445 byte cal;
2446 int cmd_num;
2447 IRDATA ird;
2448 IRRAW *irw;
2449 FILE *fp;
2450 HANDLE hfile;
2451 char st[255],err[255];
2452 byte dat[255];
2453 NETWORKSTATUS *ns;
2454 LCDCOMMAND *lcd;
2455 TRANSLATECOMMAND *tr;
2456 NETWORKLEARNSTAT *lstat;
2457 FUNCTIONBUFFER *fb;
2458 ANALOGBUFFER *ab;
2459 FUNCTIONBUFFEREX *fbex;
2460 NETWORKLCDSTAT *lcdb;
2461 IRDBCOMMAND *db;
2462 SERCOMMAND *ser;
2463 CCFSTRINGCOMMAND *ccf;
2464 CCFSTRINGCOMMAND_SHORT *ccfs;
2465 MODUSCOMMAND *mcom;
2466 unsigned int end_time;
2467 static byte suspend;
2470 memset (stat,0,sizeof (STATUSBUFFER));
2471 stat ->statuslen = 8;
2473 sprintf (st,"Netcommand: %d [%d]\n",com->netcommand,client);
2474 log_print (st,LOG_DEBUG);
2476 switch (com->netcommand) {
2478 case COMMAND_EMPTY:
2479 break;
2480 case COMMAND_LED:
2481 SetPowerLED (0,com->remote[0],com->command[0]);
2482 break;
2483 case COMMAND_DEFINECHAR:
2484 AdvancedLCD (LCD_DATA | LCD_DEFINECHAR,com->remote,com->remote[0] * 9 + 1);
2485 if (new_lcd_flag) msSleep (250);
2487 break;
2488 case COMMAND_MCE_CHARS:
2489 SetSpecialChars (dat);
2491 AdvancedLCD (LCD_DATA | LCD_DEFINECHAR,dat,dat[0] * 9 + 1);
2492 if (new_lcd_flag) msSleep (250);
2494 break;
2495 case COMMAND_LCDSTATUS:
2496 lcdb = (NETWORKLCDSTAT *)stat;
2497 memset (lcdb,0,sizeof (NETWORKLCDSTAT));
2498 lcdb->statustype = STATUS_LCDDATA;
2499 lcdb->statuslen = sizeof (NETWORKLCDSTAT);
2500 lcdb->numcol = 0;
2501 lcdb->numrows = 0;
2502 lcdb->clockflag = 0;
2504 if (new_lcd_flag == 1) {
2505 lcdb->clockflag = 3;
2506 lcdb->virtual_col = 40;
2507 lcdb->numcol = 20;
2508 lcdb->numrows = 4;
2511 if (new_lcd_flag == 2) {
2512 lcdb->clockflag = 3;
2513 lcdb->virtual_col = 40;
2514 lcdb->numcol = 40;
2515 lcdb->numrows = 4;
2518 if (new_lcd_flag) {
2519 display_bus = 0xffff;
2520 return;
2524 for (i=0;i < device_cnt;i++) if (IRDevices[i].version[0] == 'D' || (IRDevices[i].fw_capabilities & FN_DISPMASK)) {
2525 display_bus = i;
2526 break;
2529 if (IRDevices[display_bus].version[0] == 'D') {
2530 lcdb->numcol = 16;
2531 lcdb->numrows = 2;
2534 if ((IRDevices[display_bus].fw_capabilities & FN_DISPMASK) == FN_DISP1) {
2535 lcdb->numcol = 16;
2536 lcdb->numrows = 2;
2537 if (IRDevices[display_bus].fw_capabilities & FN_NOSCROLL) lcdb->virtual_col = lcdb->numcol;
2538 else lcdb->virtual_col = 40;
2540 if ((IRDevices[display_bus].fw_capabilities & FN_DISPMASK) == FN_DISP2) {
2541 lcdb->numcol = 20;
2542 lcdb->numrows = 4;
2543 if (IRDevices[display_bus].fw_capabilities & FN_NOSCROLL) lcdb->virtual_col = lcdb->numcol;
2544 else lcdb->virtual_col = 40;
2546 if (IRDevices[display_bus].fw_capabilities & FN_CLOCK) lcdb->clockflag |= 1;
2547 if (IRDevices[display_bus].io.advanced_lcd & 1) lcdb->clockflag |= 2;
2548 if (IRDevices[display_bus].io.advanced_lcd & 4) lcdb->clockflag |= 4;
2549 break;
2550 case COMMAND_SHUTDOWN:
2551 if (strcmp (com->remote,"XXXshutdownXXX")) {
2552 PutNetworkStatus (ERR_SHUTDOWN,NULL,stat);
2553 break;
2555 LCDBrightness (4);
2556 if (!(mode_flag & NO_CLOCK)) LCDTimeCommand (LCD_DISPLAYTIME);
2557 sprintf (st,"IRTrans Server Shutdown via Client");
2558 log_print (st,LOG_FATAL);
2559 exit (0);
2560 break;
2561 case COMMAND_BRIGHTNESS:
2562 LCDBrightness (com->adress);
2563 break;
2564 case COMMAND_SUSPEND:
2565 suspend = 1;
2566 if (!(mode_flag & NO_CLOCK)) LCDTimeCommand (LCD_DISPLAYTIME);
2567 lcd_init = 1;
2568 LCDBrightness (4);
2569 break;
2570 case COMMAND_RESUME:
2571 suspend = 0;
2572 lcd_init = 1;
2573 LCDBrightness (5);
2574 break;
2575 case COMMAND_STORETRANS:
2576 tr = (TRANSLATECOMMAND *)com;
2577 StoreTransItem (tr);
2578 break;
2579 case COMMAND_STOREIRDB:
2580 db = (IRDBCOMMAND *)com;
2581 StoreDbItem (db);
2582 break;
2583 case COMMAND_FLASHIRDB:
2584 res = SetIRDBEx ((byte)((com->adress) >> 8),(com->adress & 0xf),stat);
2585 if (res) PutNetworkStatus (res,NULL,stat);
2586 break;
2587 case COMMAND_SAVETRANS:
2588 res = FileTransData (com->remote,1,(byte)com->adress);
2589 if (res) PutNetworkStatus (res,NULL,stat);
2590 break;
2591 case COMMAND_SAVEIRDB:
2592 res = FileTransData (com->remote,2,(byte)com->adress);
2593 if (res) PutNetworkStatus (res,NULL,stat);
2594 break;
2595 case COMMAND_LOADIRDB:
2596 res = LoadIRDB ((IRDBBUFFER *)stat,com->remote,(word)com->adress);
2597 if (res) PutNetworkStatus (res,NULL,stat);
2598 break;
2599 case COMMAND_LOADTRANS:
2600 res = LoadTranslation ((TRANSLATEBUFFER *)stat,com->remote,(word)com->adress);
2601 if (res) PutNetworkStatus (res,NULL,stat);
2602 break;
2603 case COMMAND_FLASHTRANS:
2604 res = SetFlashdataEx ((byte)((com->adress) >> 8),(com->adress & 0xf));
2605 if (res) PutNetworkStatus (res,NULL,stat);
2606 break;
2607 case COMMAND_RS232_SEND:
2608 ser = (SERCOMMAND *)com;
2610 if (protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2611 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2613 res = SendSerialBlock (bus,ser->data,ser->len);
2614 if (res) PutNetworkStatus (res,NULL,stat);
2615 break;
2616 case COMMAND_READ_ANALOG:
2617 ab = (ANALOGBUFFER *)stat;
2619 if (protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2620 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2622 memset (ab,0,sizeof (ANALOGBUFFER));
2623 ab->statustype = STATUS_ANALOGINPUT;
2624 ab->statuslen = sizeof (ANALOGBUFFER);
2625 ReadAnalogInputs (bus,com->trasmit_freq,&(ab->inputs));
2626 break;
2627 case COMMAND_FUNCTIONS:
2628 fb = (FUNCTIONBUFFER *)stat;
2629 memset (fb,0,sizeof (FUNCTIONBUFFER));
2630 fb->statustype = STATUS_FUNCTION;
2631 fb->statuslen = sizeof (FUNCTIONBUFFER);
2632 fb->serno = IRDevices[com->adress].fw_serno;
2633 fb->functions = IRDevices[com->adress].fw_capabilities;
2634 break;
2635 case COMMAND_FUNCTIONEX:
2636 fbex = (FUNCTIONBUFFEREX *)stat;
2637 memset (fbex,0,sizeof (FUNCTIONBUFFEREX));
2638 fbex->statustype = STATUS_FUNCTIONEX;
2639 fbex->statuslen = sizeof (FUNCTIONBUFFEREX);
2640 fbex->serno = IRDevices[com->adress].fw_serno;
2641 fbex->functions = IRDevices[com->adress].fw_capabilities;
2642 memcpy (fbex->version,IRDevices[com->adress].version,8);
2643 break;
2644 case COMMAND_LONGSEND:
2645 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2646 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2648 if (com->adress & 0x40000000) {
2649 bus = 0xffff;
2650 cal = (IRDevices[0].fw_capabilities & FN_CALIBRATE) != 0;
2652 else cal = (IRDevices[bus].fw_capabilities & FN_CALIBRATE) != 0;
2654 end_time = GetMsTime () + com->timeout * 10;
2656 sprintf (st,"Longsend %s-%s for %d ms\n",com->remote,com->command,com->timeout * 10);
2657 log_print (st,LOG_DEBUG);
2658 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
2659 if (res) {
2660 if (mode_flag & SEND_FORWARDALL) send_forward (client,com->remote,com->command);
2661 ns = (NETWORKSTATUS *)stat;
2662 PutNetworkStatus (res,NULL,stat);
2663 strcpy (err,ns->message);
2664 if (res == ERR_REMOTENOTFOUND) sprintf (ns->message,err,com->remote);
2665 if (res == ERR_COMMANDNOTFOUND) sprintf (ns->message,err,com->command);
2666 log_print (ns->message,LOG_ERROR);
2668 else {
2669 if ((mode_flag & SEND_FORWARDALL) || (mode_flag & SEND_FORWARD)) send_forward (client,com->remote,com->command);
2670 SendIRDataEx (&ird,com->adress);
2673 resend_flag = 0;
2674 while (GetMsTime () < end_time) {
2675 if (!resend_flag) { // 1. Resend; Command Laden
2676 strcat (com->command,"@");
2677 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
2678 if (res) {
2679 com->command[strlen (com->command) - 1] = 0;
2680 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
2681 if (res) PutNetworkStatus (res,NULL,stat);
2682 else {
2683 bus = 0;
2684 if (com->adress & 0x10000) {
2685 ird.target_mask = (word)com->adress & 0xffff;
2687 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2688 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2690 if (com->adress & 0x40000000) bus = 0xffff;
2691 if (com->adress & 0x60000) ird.address = (com->adress >> 17) & 0x3;
2692 ResendIREx (bus,&ird);
2693 resend_flag = 2;
2696 else {
2697 SendIRDataEx (&ird,com->adress);
2698 resend_flag = 1;
2699 com->command[strlen (com->command) - 1] = 0;
2701 continue;
2703 if (resend_flag == 1) strcat (com->command,"@");
2704 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
2705 if (res) PutNetworkStatus (res,NULL,stat);
2706 else {
2707 if (com->adress & 0x10000) {
2708 ird.target_mask = (word)com->adress & 0xffff;
2710 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2711 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2713 if (com->adress & 0x40000000) bus = 0xffff;
2714 if (com->adress & 0x60000) ird.address = (com->adress >> 17) & 0x3;
2715 ResendIREx (bus,&ird);
2718 if (resend_flag == 1) com->command[strlen (com->command) - 1] = 0;
2720 break;
2721 case COMMAND_DELETEREM:
2722 sprintf (st,"Delete %s\n",com->remote,com->command);
2723 log_print (st,LOG_DEBUG);
2724 strcpy (st,com->remote);
2725 if (com->adress != 1234) return;
2726 if (strcmp (st + strlen (st) - 4,".rem")) strcat (st,".rem");
2728 if (sockinfo[client].fp) fclose ((sockinfo[client].fp));
2729 sockinfo[client].fp = NULL;
2730 memset (sockinfo[client].learnstatus.remote,' ',80);
2731 memset (sockinfo[client].learnstatus.received,' ',80);
2733 #ifdef WIN32
2734 res = _unlink (st);
2735 #else
2736 res = unlink (st);
2737 #endif
2738 if (res) {
2739 PutNetworkStatus (ERR_OPENASCII,com->remote,stat);
2740 return;
2743 ReadIRDatabase ();
2744 break;
2745 case COMMAND_DELETECOM:
2746 sprintf (st,"Delete %s-%s\n",com->remote,com->command);
2747 log_print (st,LOG_DEBUG);
2748 strcpy (st,com->remote);
2749 if (com->adress != 1234) return;
2750 if (strcmp (st + strlen (st) - 4,".rem")) strcat (st,".rem");
2751 fp = DBOpenFile (st,"r+");
2752 if (!fp) {
2753 PutNetworkStatus (ERR_OPENASCII,com->remote,stat);
2754 return;
2756 if (!ASCIIFindCommand (fp,com->command,NULL)) {
2757 ns = (NETWORKSTATUS *)stat;
2758 PutNetworkStatus (ERR_COMMANDNOTFOUND,NULL,stat);
2759 strcpy (err,ns->message);
2760 sprintf (ns->message,err,com->command);
2761 return;
2763 res = ftell (fp);
2764 fclose (fp);
2765 #ifdef WIN32
2766 hfile = CreateFile (st,GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
2767 if (hfile) {
2768 SetFilePointer (hfile,res,NULL,FILE_BEGIN);
2769 SetEndOfFile (hfile);
2770 CloseHandle (hfile);
2772 #endif
2773 #ifdef LINUX
2774 truncate (st,res);
2775 #endif
2777 ReadIRDatabase ();
2778 break;
2779 case COMMAND_SENDCCFSTR:
2780 case COMMAND_SENDCCFSTRS:
2781 case COMMAND_SENDCCF:
2782 case COMMAND_SENDCCFLONG:
2783 ccf = (CCFSTRINGCOMMAND *)com;
2784 ccfs = (CCFSTRINGCOMMAND_SHORT *)com;
2786 if (com->netcommand == COMMAND_SENDCCFSTR) i = ccf->repeatmode;
2787 else if (com->netcommand == COMMAND_SENDCCFSTRS) i = ccfs->repeatmode;
2788 else i = ccf->timeout;
2790 sprintf (st,"Send CCF %s [%x]\n",ccf->ccf_data,ccf->adress);
2791 log_print (st,LOG_DEBUG);
2793 res = DecodeCCF ((char *)ccf->ccf_data,&ird,i);
2794 if (res <= 0) {
2795 sprintf (err,"Illegal xAP Pronto command\n");
2796 log_print (err, LOG_ERROR);
2797 ns = (NETWORKSTATUS *)stat;
2798 PutNetworkStatus (ERR_CCF,NULL,stat);
2799 return;
2802 ird.target_mask = 0xffff;
2804 if (ccf->adress & 0x10000) {
2805 ird.target_mask = (word)ccf->adress & 0xffff;
2807 if (ccf->adress & 0x60000) ird.address = (ccf->adress >> 17) & 0x3;
2808 if (ccf->adress & 0x80000000) ird.address |= ((ccf->adress >> 25) & 28) + 4;
2810 if (ccf->protocol_version >= 210) bus = (ccf->adress >> 19) & (MAX_IR_DEVICES - 1);
2811 else bus = (ccf->adress >> 20) & (MAX_IR_DEVICES - 1);
2813 if (ccf->adress & 0x40000000) bus = 0xffff;
2815 res = DoSendIR (&ird,NULL,0,0,bus);
2817 if (res) {
2818 ns = (NETWORKSTATUS *)stat;
2819 PutNetworkStatus (res,NULL,stat);
2820 strcpy (err,ns->message);
2821 if (res == ERR_REMOTENOTFOUND) sprintf (ns->message,err,com->remote);
2822 if (res == ERR_COMMANDNOTFOUND) sprintf (ns->message,err,com->command);
2823 if (res == ERR_WRONGBUS) {
2824 if (com->protocol_version >= 210) sprintf (ns->message,err,(com->adress >> 19) & (MAX_IR_DEVICES - 1));
2825 else sprintf (ns->message,err,(com->adress >> 20) & (MAX_IR_DEVICES - 1));
2827 log_print (ns->message,LOG_ERROR);
2830 resend_flag = 0;
2831 break;
2832 case COMMAND_SEND:
2833 if (com->protocol_version >= 210) sprintf (st,"Send %s-%s [%x - B:%d M:0x%x L:%d Ext L: %d]\n",com->remote,com->command,com->adress,(com->adress >> 19) & (MAX_IR_DEVICES - 1),com->adress & 0xffff,(com->adress >> 17) & 0x3,(com->adress >> 27) & 0x7);
2834 else sprintf (st,"Send %s-%s [%x - B:%d M:0x%x L:%d Ext L: %d]\n",com->remote,com->command,com->adress,(com->adress >> 20) & (MAX_IR_DEVICES - 1),com->adress & 0xffff,(com->adress >> 17) & 0x3,(com->adress >> 27) & 0x7);
2835 log_print (st,LOG_DEBUG);
2836 if (hexfp) {
2837 fprintf (hexfp,"%s-%s\n",com->remote,com->command);
2838 hexflag = 1;
2841 if (!strncmp (com->remote,"***relais_",10)) {
2842 int bus;
2843 if (protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2844 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2846 res = SetRelaisEx (bus,(byte)com->command[0],(byte)(com->remote[10] - '1'));
2847 break;
2849 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
2850 if (!res) {
2851 if ((mode_flag & SEND_FORWARDALL) || (mode_flag & SEND_FORWARD)) send_forward (client,com->remote,com->command);
2852 res = SendIR (cmd_num,com->adress);
2854 if (res) {
2855 if (mode_flag & SEND_FORWARDALL) send_forward (client,com->remote,com->command);
2856 ns = (NETWORKSTATUS *)stat;
2857 PutNetworkStatus (res,NULL,stat);
2858 strcpy (err,ns->message);
2859 if (res == ERR_REMOTENOTFOUND) sprintf (ns->message,err,com->remote);
2860 if (res == ERR_COMMANDNOTFOUND) sprintf (ns->message,err,com->command);
2861 if (res == ERR_WRONGBUS) {
2862 if (com->protocol_version >= 210) sprintf (ns->message,err,(com->adress >> 19) & (MAX_IR_DEVICES - 1));
2863 else sprintf (ns->message,err,(com->adress >> 20) & (MAX_IR_DEVICES - 1));
2865 log_print (ns->message,LOG_ERROR);
2868 resend_flag = 0;
2869 break;
2870 case COMMAND_DEVICEDATA:
2871 sprintf (st,"Get Devicedata %s-%s\n",com->remote,com->command);
2872 log_print (st,LOG_DEBUG);
2873 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
2874 if (!res) res = GetDeviceData (cmd_num,(DATABUFFER *)stat);
2875 if (res) {
2876 ns = (NETWORKSTATUS *)stat;
2877 PutNetworkStatus (res,NULL,stat);
2878 strcpy (err,ns->message);
2879 if (res == ERR_REMOTENOTFOUND) sprintf (ns->message,err,com->remote);
2880 if (res == ERR_COMMANDNOTFOUND) sprintf (ns->message,err,com->command);
2881 log_print (ns->message,LOG_ERROR);
2883 break;
2884 case COMMAND_TESTCOM:
2885 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
2886 if (res) {
2887 ns = (NETWORKSTATUS *)stat;
2888 PutNetworkStatus (ERR_TESTCOM,NULL,stat);
2889 ns->statuslevel = (word)com->adress;
2890 ns->statuslen -= 256;
2892 break;
2893 case COMMAND_TESTCOMEX:
2894 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
2895 ns = (NETWORKSTATUS *)stat;
2896 if (res) {
2897 PutNetworkStatus (ERR_TESTCOM,NULL,stat);
2899 else {
2900 PutNetworkStatus (ERR_TESTCOMOK,NULL,stat);
2902 ns->statuslevel = (word)com->adress;
2903 ns->statuslen -= 256;
2904 break;
2906 case COMMAND_TEMP:
2907 sprintf (st,"Temperature %s-%d\n",com->remote,com->adress);
2908 log_print (st,LOG_DEBUG);
2909 memset (&ird,0,sizeof (IRDATA));
2910 ird.ir_length = 5;
2911 ird.target_mask = 1 << com->adress;
2912 if (!strcmp (com->remote,"get") || !strcmp (com->remote,"Get") || !strcmp (com->remote,"GET")) {
2913 ird.mode = TEMP_DATA | TEMP_GET;
2915 if (!strcmp (com->remote,"reset") || !strcmp (com->remote,"Reset") || !strcmp (com->remote,"RESET")) {
2916 ird.mode = TEMP_DATA | TEMP_RESET;
2918 if (ird.mode == 0) {
2919 ns = (NETWORKSTATUS *)stat;
2920 PutNetworkStatus (ERR_TEMPCOMMAND,NULL,stat);
2921 strcpy (err,ns->message);
2922 sprintf (ns->message,err,com->remote);
2923 log_print (ns->message,LOG_ERROR);
2925 else SendIRDataEx (&ird,com->adress);
2926 break;
2927 case COMMAND_STARTCLOCK:
2928 if (!(mode_flag & NO_CLOCK)) LCDTimeCommand (LCD_DISPLAYTIME);
2929 lcd_init = 1;
2930 break;
2931 case COMMAND_LCD:
2932 lcd = (LCDCOMMAND *)com;
2933 irw = (IRRAW *)&ird;
2934 memset (irw,0,sizeof (IRRAW));
2935 if (lcd->lcdcommand & LCD_TEXT) {
2936 memset (err,0,sizeof (err));
2937 memcpy (err,lcd->framebuffer,40);
2938 memcpy (err+100,lcd->framebuffer+40,40);
2939 sprintf (st,"LCD: %s\n%s\n",err,err+100);
2940 log_print (st,LOG_DEBUG);
2941 compress_lcdbuffer (lcd,irw->data,display_bus);
2943 // sprintf (st,"COMPRESS: %s\n",irw->data);
2944 // log_print (st,LOG_DEBUG);
2947 if (suspend) return;
2948 irw->target_mask = (unsigned short)(lcd->adress & 0xffff);
2949 if (lcd->adress == 'L') irw->target_mask = 0xffff;
2950 irw->ir_length = 0;
2951 irw->mode = LCD_DATA | lcd->lcdcommand;
2952 irw->transmit_freq = lcd->timeout;
2953 SendLCD (irw,lcd->adress);
2954 resend_flag = 0;
2955 if (new_lcd_flag) msSleep (100);
2956 //printf ("<%s>\n",irw->data);
2957 //lcd_init = 1; // Debug für LCD Test
2958 break;
2959 case COMMAND_SETSWITCH:
2960 memset (&ird,0,sizeof (IRDATA));
2961 sprintf (st,"SWITCH: %d - %d\n",com->remote[0],com->command[0]);
2962 log_print (st,LOG_DEBUG);
2964 ird.target_mask = 0xffff;
2965 ird.ir_length = 0;
2966 ird.mode = SWITCH_DATA | com->command[0];
2967 ird.transmit_freq = com->remote[0];
2968 DoSendIR (&ird,NULL,0,0,0); // !!!!!! Auf Multibus erweitern
2969 resend_flag = 0;
2970 break;
2971 case COMMAND_LCDINIT:
2972 lcd = (LCDCOMMAND *)com;
2973 irw = (IRRAW *)&ird;
2974 memset (irw,0,sizeof (IRRAW));
2975 memcpy (irw->data,lcd->framebuffer,40);
2976 sprintf (st,"LCDINIT: %s\n",lcd->framebuffer);
2977 log_print (st,LOG_DEBUG);
2979 irw->target_mask = (unsigned short)lcd->adress;
2980 if (lcd->adress == 'L') irw->target_mask = 0xffff;
2981 irw->ir_length = 0;
2982 irw->mode = LCD_DATA | LCD_INIT;
2983 irw->transmit_freq = lcd->timeout;
2984 SendLCD (irw,lcd->adress);
2985 resend_flag = 0;
2986 break;
2987 case COMMAND_RESEND:
2988 sprintf (st,"Resend %s-%s\n",com->remote,com->command);
2989 log_print (st,LOG_DEBUG);
2990 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
2991 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
2993 if (com->adress & 0x40000000) {
2994 bus = 0xffff;
2995 cal = (IRDevices[0].fw_capabilities & FN_CALIBRATE) != 0;
2997 else cal = (IRDevices[bus].fw_capabilities & FN_CALIBRATE) != 0;
2999 if (!resend_flag) { // 1. Resend; Command Laden
3000 strcat (com->command,"@");
3001 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
3002 if (res) {
3003 com->command[strlen (com->command) - 1] = 0;
3004 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
3005 if (!res) resend_flag = 2;
3006 if (res == ERR_ISMACRO) {
3007 res = DBFindRemoteCommand (com->remote,com->command,&cmd_num,NULL);
3008 if (!res) res = SendIR (cmd_num,com->adress);
3009 resend_flag = 0;
3012 if (res) {
3013 if (mode_flag & SEND_FORWARDALL) send_forward (client,com->remote,com->command);
3014 PutNetworkStatus (res,NULL,stat);
3016 else {
3017 if ((mode_flag & SEND_FORWARDALL) || (mode_flag & SEND_FORWARD)) send_forward (client,com->remote,com->command);
3018 if (com->adress & 0x10000) {
3019 ird.target_mask = (word)com->adress & 0xffff;
3021 if (com->adress & 0x60000) ird.address = (com->adress >> 17) & 0x3;
3022 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
3023 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
3024 if (com->adress & 0x40000000) bus = 0xffff;
3025 ResendIREx (bus,&ird);
3028 else {
3029 if ((mode_flag & SEND_FORWARDALL) || (mode_flag & SEND_FORWARD)) send_forward (client,com->remote,com->command);
3030 SendIRDataEx (&ird,com->adress);
3031 resend_flag = 1;
3033 break;
3035 if (resend_flag == 1) strcat (com->command,"@");
3036 res = DBFindRemoteCommandEx (com->remote,com->command,&ird,cal);
3037 if (res) {
3038 if (mode_flag & SEND_FORWARDALL) send_forward (client,com->remote,com->command);
3039 PutNetworkStatus (res,NULL,stat);
3041 else {
3042 if ((mode_flag & SEND_FORWARDALL) || (mode_flag & SEND_FORWARD)) send_forward (client,com->remote,com->command);
3043 if (com->adress & 0x10000) {
3044 ird.target_mask = (word)com->adress & 0xffff;
3046 if (com->adress & 0x60000) ird.address = (com->adress >> 17) & 0x3;
3047 if (com->protocol_version >= 210) bus = (com->adress >> 19) & (MAX_IR_DEVICES - 1);
3048 else bus = (com->adress >> 20) & (MAX_IR_DEVICES - 1);
3049 if (com->adress & 0x40000000) bus = 0xffff;
3050 ResendIREx (bus,&ird);
3052 break;
3053 case COMMAND_LRNREM:
3054 if (sockinfo[client].fp != NULL) fclose (sockinfo[client].fp);
3055 sockinfo[client].fp = ASCIIOpenRemote (com->remote,&sockinfo[client]);
3056 if (sockinfo[client].learnstatus.num_timings > 0) sockinfo[client].learnstatus.learnok = 1;
3057 if (sockinfo[client].fp == NULL) PutNetworkStatus (ERR_OPENASCII,com->remote,stat);
3058 break;
3059 case COMMAND_LRNTIM:
3060 if (sockinfo[client].fp == NULL) {
3061 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3062 break;
3064 res = LearnIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3066 if (res) PutNetworkStatus (res,NULL,stat);
3067 else {
3068 sockinfo[client].timing = ASCIIStoreTiming (sockinfo[client].fp,&sockinfo[client].ird,&sockinfo[client].learnstatus);
3069 last_adress = sockinfo[client].ird.address;
3070 ResultStoreTiming (&sockinfo[client].ird,(NETWORKTIMING *)stat);
3071 sockinfo[client].learnstatus.learnok = 1;
3073 break;
3074 case COMMAND_LRNRAW:
3075 if (sockinfo[client].fp == NULL) {
3076 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3077 break;
3079 res = LearnRawIREx ((IRRAW *)&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3081 if (res) PutNetworkStatus (res,NULL,stat);
3082 else {
3083 if (ASCIIFindCommand (sockinfo[client].fp,com->command,sockinfo + client) == 0) sockinfo[client].learnstatus.num_commands++;
3084 ASCIIStoreRAW (sockinfo[client].fp,(IRRAW *)&sockinfo[client].ird,com->command);
3085 last_adress = sockinfo[client].ird.address;
3087 break;
3088 case COMMAND_LRNRAWRPT:
3089 if (sockinfo[client].fp == NULL) {
3090 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3091 break;
3093 res = LearnRawIRRepeatEx ((IRRAW *)&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3095 if (res) PutNetworkStatus (res,NULL,stat);
3096 else {
3097 strcat (com->command,"@");
3098 if (ASCIIFindCommand (sockinfo[client].fp,com->command,sockinfo + client) == 0) sockinfo[client].learnstatus.num_commands++;
3099 ASCIIStoreRAW (sockinfo[client].fp,(IRRAW *)&sockinfo[client].ird,com->command);
3100 last_adress = sockinfo[client].ird.address;
3102 break;
3103 case COMMAND_LRNCOM:
3104 if (sockinfo[client].fp == NULL) {
3105 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3106 break;
3108 if (sockinfo[client].ird.ir_length == 0) {
3109 PutNetworkStatus (ERR_NOTIMING,NULL,stat);
3110 break;
3112 res = LearnNextIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3113 if (res) PutNetworkStatus (res,NULL,stat);
3114 else {
3115 if (ASCIIFindCommand (sockinfo[client].fp,com->command,sockinfo + client) == 0) sockinfo[client].learnstatus.num_commands++;
3116 res = ASCIIStoreCommand (sockinfo[client].fp,&sockinfo[client].ird,com->command,sockinfo[client].timing,0);
3117 if (sockinfo[client].ird.data[0] & LONG_CODE_FLAG) strcpy (sockinfo[client].learnstatus.received,"Long Code");
3118 else memcpy (sockinfo[client].learnstatus.received,sockinfo[client].ird.data,sockinfo[client].ird.ir_length);
3120 break;
3122 case COMMAND_LEARNDIRECT:
3123 res = LearnIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3125 if (res) {
3126 ns = (NETWORKSTATUS *)stat;
3127 PutNetworkStatus (res,NULL,stat);
3128 strcpy (err,ns->message);
3129 if (res == ERR_WRONGBUS) {
3130 if (com->protocol_version >= 210) sprintf (ns->message,err,(com->adress >> 19) & (MAX_IR_DEVICES - 1));
3131 else sprintf (ns->message,err,(com->adress >> 20) & (MAX_IR_DEVICES - 1));
3133 log_print (ns->message,LOG_ERROR);
3135 else {
3136 IRDATA_BUFFER *irdb;
3138 irdb = (IRDATA_BUFFER *)stat;
3140 memset (irdb,0,sizeof (irdb));
3141 irdb->statustype = STATUS_LEARNDIRECT;
3142 irdb->statuslen = sizeof (IRDATA_BUFFER);
3143 memcpy (&irdb->ird,&sockinfo[client].ird,sizeof (IRDATA));
3144 irdb->ird.target_mask = 0xffff;
3145 irdb->ird.command = HOST_SEND;
3146 irdb->ird.checksumme = get_checksumme (&irdb->ird);
3148 break;
3149 case COMMAND_LRNLONG:
3150 if (sockinfo[client].fp == NULL) {
3151 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3152 break;
3154 res = LearnIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3156 if (res) PutNetworkStatus (res,NULL,stat);
3157 else {
3158 sockinfo[client].timing = ASCIIStoreTiming (sockinfo[client].fp,&sockinfo[client].ird,&sockinfo[client].learnstatus);
3159 if (ASCIIFindCommand (sockinfo[client].fp,com->command,sockinfo + client) == 0) sockinfo[client].learnstatus.num_commands++;
3160 ASCIIStoreCommand (sockinfo[client].fp,&sockinfo[client].ird,com->command,sockinfo[client].timing,0);
3161 last_adress = sockinfo[client].ird.address;
3162 if (sockinfo[client].ird.data[0] & LONG_CODE_FLAG) strcpy (sockinfo[client].learnstatus.received,"Long Code");
3163 else memcpy (sockinfo[client].learnstatus.received,sockinfo[client].ird.data,sockinfo[client].ird.ir_length);
3164 // ResultStoreTiming (&sockinfo[client].ird,(NETWORKTIMING *)stat);
3165 // stat->adress = last_adress | ((com->adress,com >> 8) & (MAX_IR_DEVICES - 1));
3168 break;
3170 case COMMAND_LRNTOG:
3171 if (sockinfo[client].fp == NULL) {
3172 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3173 break;
3175 res = LearnNextIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3176 if (res) PutNetworkStatus (res,NULL,stat);
3177 else {
3178 res = ASCIIFindToggleSeq (sockinfo[client].fp,&sockinfo[client].ird,com->command);
3179 if (res < 0) PutNetworkStatus (ERR_TOGGLE_DUP,NULL,stat);
3180 else {
3181 res = ASCIIStoreCommand (sockinfo[client].fp,&sockinfo[client].ird,com->command,sockinfo[client].timing,res);
3182 sockinfo[client].learnstatus.num_commands++;
3183 if (sockinfo[client].ird.data[0] & LONG_CODE_FLAG) strcpy (sockinfo[client].learnstatus.received,"Long Code");
3184 else memcpy (sockinfo[client].learnstatus.received,sockinfo[client].ird.data,sockinfo[client].ird.ir_length);
3187 break;
3189 case COMMAND_LRNRPT:
3190 if (sockinfo[client].fp == NULL) {
3191 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3192 break;
3194 res = LearnRepeatIREx (&sockinfo[client].ird,(word)com->adress,com->timeout,(word)(com->adress >> 16),com -> trasmit_freq);
3196 if (res) PutNetworkStatus (res,NULL,stat);
3197 else {
3198 sockinfo[client].timing = ASCIIStoreTiming (sockinfo[client].fp,&sockinfo[client].ird,&sockinfo[client].learnstatus);
3199 strcat (com->command,"@");
3200 if (ASCIIFindCommand (sockinfo[client].fp,com->command,sockinfo + client) == 0) sockinfo[client].learnstatus.num_commands++;
3201 ASCIIStoreCommand (sockinfo[client].fp,&sockinfo[client].ird,com->command,sockinfo[client].timing,0);
3202 last_adress = sockinfo[client].ird.address;
3203 if (sockinfo[client].ird.data[0] & LONG_CODE_FLAG) strcpy (sockinfo[client].learnstatus.received,"Long Code");
3204 else memcpy (sockinfo[client].learnstatus.received,sockinfo[client].ird.data,sockinfo[client].ird.ir_length);
3206 break;
3208 case COMMAND_CLOSE:
3209 if (sockinfo[client].fp == NULL) {
3210 PutNetworkStatus (ERR_NOFILEOPEN,NULL,stat);
3211 break;
3213 if (sockinfo[client].fp) fclose ((sockinfo[client].fp));
3214 sockinfo[client].fp = NULL;
3215 memset (sockinfo[client].learnstatus.remote,' ',80);
3216 memset (sockinfo[client].learnstatus.received,' ',80);
3217 ReadIRDatabase ();
3218 break;
3220 case COMMAND_RELOAD:
3221 if (sockinfo[client].fp) fflush ((sockinfo[client].fp));
3222 ReadIRDatabase ();
3223 break;
3224 case COMMAND_STATUS:
3225 if (status_changed || (time (0) - last_status_read) >= status_cache_timeout) {
3226 res = GetBusInfoEx (remote_statusex,0);
3227 if (res) {
3228 PutNetworkStatus (res,NULL,stat);
3229 break;
3231 else {
3232 status_changed = 0;
3233 last_status_read = time (0);
3236 PutDeviceStatus ((NETWORKMODE *)stat);
3237 break;
3239 case COMMAND_STATUSEX:
3240 case COMMAND_STATUSEXN:
3241 if (status_changed || (time (0) - last_status_read) >= status_cache_timeout) {
3242 res = GetBusInfoEx (remote_statusex,0xffff);
3243 if (res) {
3244 PutNetworkStatus (res,NULL,stat);
3245 break;
3247 else {
3248 status_changed = 0;
3249 last_status_read = time (0);
3252 PutDeviceStatusEx (stat,com->netcommand,(byte)com->adress);
3253 break;
3255 case COMMAND_LEARNSTAT:
3256 if (sockinfo[client].fp == NULL) {
3257 memset (stat,0,sizeof (NETWORKLEARNSTAT));
3258 stat->statustype = STATUS_LEARN;
3259 stat->statuslen = sizeof (NETWORKLEARNSTAT);
3260 lstat = (NETWORKLEARNSTAT *)stat;
3261 memset (lstat->remote,' ',80);
3262 memset (lstat->received,' ',CODE_LEN);
3264 else memcpy (stat,&sockinfo[client].learnstatus,sizeof (NETWORKLEARNSTAT));
3265 memset (sockinfo[client].learnstatus.received,' ',CODE_LEN);
3266 break;
3268 case COMMAND_RESET:
3269 lcd_init = 1;
3270 res = ResetTransceiverEx ((byte)((com->adress >> 8) & (MAX_IR_DEVICES-1)));
3271 if (res) PutNetworkStatus (res,NULL,stat);
3272 break;
3273 case COMMAND_SETSTATEX:
3274 mcom = (MODUSCOMMAND *)com;
3275 res = GetHotcode (mcom->hotremote,mcom->hotcommand,st);
3276 if (res == -1) {
3277 GetError (ERR_HOTCODE,st);
3278 sprintf (err,st,mcom->hotremote,mcom->hotcommand);
3279 log_print (err,LOG_ERROR);
3280 PutNetworkStatus (ERR_HOTCODE,err,stat);
3281 break;
3283 if (strcmp (mcom->hotremote_2,"_")) res = GetHotcode (mcom->hotremote_2,mcom->hotcommand_2,st);
3284 if (res == -1) {
3285 GetError (ERR_HOTCODE,st);
3286 sprintf (err,st,mcom->hotremote_2,mcom->hotcommand_2);
3287 log_print (err,LOG_ERROR);
3288 PutNetworkStatus (ERR_HOTCODE,err,stat);
3289 break;
3291 res = GetHotcode (mcom->hotremote,mcom->hotcommand,st);
3292 res = SetTransceiverModusEx ((byte)(mcom->adress >> 8),mcom->mode,(word)mcom->targetmask,(byte)(mcom->adress & 0xff),st,res,mcom->extmode,mcom->extmode_2,mcom->extmode_3,mcom->extmode_4,mcom->wakeup_mac);
3293 StoreSwitch ((word)mcom->adress,0,mcom->hotremote,mcom->hotcommand,1);
3294 if (res) PutNetworkStatus (res,NULL,stat);
3295 if (strcmp (mcom->hotremote_2,"_")) {
3296 res = GetHotcode (mcom->hotremote_2,mcom->hotcommand_2,st);
3297 StoreSwitch ((word)mcom->adress,1,mcom->hotremote_2,mcom->hotcommand_2,1);
3298 res = SetTransceiverModusEx2 ((byte)(mcom->adress >> 8),(byte)(mcom->adress & 0xff),st,res);
3299 if (res) PutNetworkStatus (res,NULL,stat);
3301 WriteSwitches ();
3302 status_changed = 1;
3303 msSleep (800);
3304 LCDTimeCommand (LCD_REFRESHDATE);
3305 break;
3306 case COMMAND_SETSTAT:
3307 res = GetHotcode (com->remote,com->command,st);
3308 if (res == -1) {
3309 GetError (ERR_HOTCODE,st);
3310 sprintf (err,st,com->remote,com->command);
3311 log_print (err,LOG_ERROR);
3312 PutNetworkStatus (ERR_HOTCODE,err,stat);
3314 else {
3315 StoreSwitch ((word)com->timeout,0,com->remote,com->command,1);
3316 WriteSwitches ();
3317 res = SetTransceiverModusEx ((byte)(com->timeout >> 8),com->mode,(word)com->adress,(byte)(com->timeout & 0xff),st,res,(byte)((com->adress >> 16) & 0xff),com->trasmit_freq,0,0,0);
3318 if (res) PutNetworkStatus (res,NULL,stat);
3319 msSleep (800);
3320 status_changed = 1;
3321 LCDTimeCommand (LCD_REFRESHDATE);
3323 break;
3324 case COMMAND_SETSTAT2:
3325 res = GetHotcode (com->remote,com->command,st);
3326 if (res == -1) {
3327 GetError (ERR_HOTCODE,st);
3328 sprintf (err,st,com->remote,com->command);
3329 log_print (err,LOG_ERROR);
3330 PutNetworkStatus (ERR_HOTCODE,err,stat);
3332 else {
3333 StoreSwitch ((word)com->timeout,1,com->remote,com->command,1);
3334 WriteSwitches ();
3335 res = SetTransceiverModusEx2 ((byte)(com->timeout >> 8),(byte)(com->timeout & 0xff),st,res);
3336 if (res) PutNetworkStatus (res,NULL,stat);
3337 status_changed = 1;
3339 break;
3340 case COMMAND_IRDBFILE:
3341 #ifdef WIN32
3342 ReadIRTransDirectory ("*.irdb",(REMOTEBUFFER *)stat,com->adress,STATUS_IRDBFILE);
3343 #endif
3344 #ifdef LINUX
3345 ReadIRTransDirectory (".irdb",(REMOTEBUFFER *)stat,com->adress,STATUS_IRDBFILE);
3346 #endif
3347 break;
3348 case COMMAND_TRANSFILE:
3349 #ifdef WIN32
3350 ReadIRTransDirectory ("*.tra",(REMOTEBUFFER *)stat,com->adress,STATUS_TRANSLATIONFILE);
3351 #endif
3352 #ifdef LINUX
3353 ReadIRTransDirectory (".tra",(REMOTEBUFFER *)stat,com->adress,STATUS_TRANSLATIONFILE);
3354 #endif
3355 break;
3356 case COMMAND_GETREMOTES:
3357 GetRemoteDatabase ((REMOTEBUFFER *)stat,com->adress);
3358 break;
3359 case COMMAND_LISTBUS:
3360 GetBusList ((REMOTEBUFFER *)stat,com->adress);
3361 break;
3362 case COMMAND_GETCOMMANDS:
3363 res = GetCommandDatabase ((COMMANDBUFFER *)stat,com->remote,com->adress);
3364 if (res) {
3365 ns = (NETWORKSTATUS *)stat;
3366 PutNetworkStatus (ERR_REMOTENOTFOUND,NULL,stat);
3367 strcpy (err,ns->message);
3368 sprintf (ns->message,err,com->remote);
3369 log_print (ns->message,LOG_ERROR);
3371 break;
3376 // Time with 1ms resolution
3378 unsigned int GetMsTime (void)
3380 #ifdef WIN32
3381 return (GetTickCount ());
3382 #endif
3384 #ifdef LINUX
3385 struct timeval tv;
3386 gettimeofday (&tv,0);
3388 return (tv.tv_sec * 1000 + tv.tv_usec);
3389 #endif
3393 char shadow_buf[256];
3395 int GetDeviceStatus (STATUSBUFFER *buf)
3397 int res;
3399 if (status_changed || (time (0) - last_status_read) >= status_cache_timeout) {
3400 res = GetBusInfoEx (remote_statusex,0);
3401 if (res) {
3402 PutNetworkStatus (res,NULL,buf);
3403 return (res);
3405 else {
3406 status_changed = 0;
3407 last_status_read = time (0);
3410 PutDeviceStatus ((NETWORKMODE *)buf);
3411 return (0);
3417 void compress_lcdbuffer (LCDCOMMAND *lcd,char *buf,int bus)
3419 int i = 0;
3420 int pos = 0;
3421 char line[100];
3422 char lf[2];
3423 int x,y;
3426 byte LINEFEED = 0x1f;
3427 byte C_SPACE = 16;
3428 byte C_BLOCK = 17;
3429 byte C_DATA = 18;
3431 if (bus == 0xffff) bus = 0;
3433 if ((IRDevices[bus].io.advanced_lcd & 2) || new_lcd_flag) {
3434 LINEFEED = 10;
3435 C_SPACE = 11;
3436 C_BLOCK = 12;
3437 C_DATA = 13;
3438 ConvertLCDCharset ((byte *)(lcd->framebuffer));
3440 else if (IRDevices[bus].version[0] == 'D') ConvertLCDCharset ((byte *)(lcd->framebuffer));
3442 lf[0] = LINEFEED;
3443 lf[1] = 0;
3446 buf[0] = 0;
3447 if (count_difference (lcd) <= 16) {
3448 i = 0;
3449 buf[i++] = C_DATA;
3450 for (y = 0;y < lcd->hgt;y++) {
3451 for (x = 0;x < lcd->wid;x++) {
3452 if (shadow_buf[x + y * lcd->wid] != lcd->framebuffer[x + y * lcd->wid] && lcd->framebuffer[x + y * lcd->wid]) {
3453 buf[i++] = (x + 1) | y << 6;
3454 buf[i++] = lcd->framebuffer[x + y * lcd->wid];
3458 buf[i++] = 0;
3460 else for (i=0;i < lcd -> hgt;i++) {
3461 memset (line,0,100);
3462 memcpy (line,lcd->framebuffer + i * lcd->wid,lcd->wid);
3463 pos = (int)strlen (line) - 1;
3464 while (line[pos] == ' ' && pos) pos--;
3465 if (line[pos + 1] == ' ') line[pos + 1] = 0;
3466 compress_char (line,' ',C_SPACE);
3467 // compress_char (line,(char)255,C_BLOCK);
3468 strcat (line,lf);
3469 strcat (buf,line);
3472 memcpy (shadow_buf,lcd->framebuffer,lcd->wid * lcd->hgt);
3474 if (!(IRDevices[bus].io.advanced_lcd & 2) && !new_lcd_flag && IRDevices[bus].version[0] != 'D' && IRDevices[bus].version[0] != 'F') buf[strlen(buf)-1] = 0;
3478 int count_difference (LCDCOMMAND *lcd)
3480 int i = 0;
3481 int diff = 0;
3482 if (lcd_init) {
3483 lcd_init = 0;
3484 return (99);
3486 while (i < lcd->wid * lcd->hgt) {
3487 if (shadow_buf[i] != lcd->framebuffer[i]) diff++;
3488 i++;
3490 return (diff);
3494 void compress_char (char ln[],char src,char tar)
3496 char st[100];
3497 char tr[100];
3498 int i = 0;
3499 int pos;
3501 strcpy (tr,ln);
3502 while (ln[i]) {
3503 if (ln[i] == src) {
3504 pos = i;
3505 while (ln[i] == src) i++;
3506 if ((i - pos) > 2) {
3507 strcpy (st,ln + i);
3508 tr[pos] = tar;
3509 tr[pos+1] = i - pos;
3510 tr[pos+2] = 0;
3511 strcpy (tr + pos + 2,st);
3514 i++;
3516 strcpy (ln,tr);
3521 int GetHotcode (char rem[],char com[],byte data[])
3523 IRDATA ir;
3524 int i = 0;
3526 *data = 0;
3528 if (*rem == 0 || *com == 0) return (0);
3530 if (DBFindRemoteCommandEx (rem,com,&ir,0)) return (-1);
3531 if (ir.mode & RAW_DATA) {
3532 memcpy (data,ir.pause_len,ir.ir_length);
3533 ReformatHotcode (data,ir.ir_length);
3534 return (ir.ir_length);
3536 else {
3537 memcpy (data,ir.data,ir.ir_length);
3538 return (ir.ir_length);
3543 void ReformatHotcode (byte data[],int len)
3545 int i = 0;
3546 word wert;
3547 while (i < len) {
3548 if (!data[i]) {
3549 i++;
3550 wert = (data[i] << 8) + data[i+1];
3551 wert -= (wert >> 4) + RAW_TOLERANCE;
3552 data[i] = wert >> 8;
3553 data[i+1] = wert & 0xff;
3554 i += 2;
3556 else {
3557 data[i] -= (data[i] >> 4) + RAW_TOLERANCE;
3558 i++;
3564 void PutDeviceStatus (NETWORKMODE *mode)
3566 int i;
3567 mode->adress = remote_statusex[0].my_adress;
3568 mode->statustype = STATUS_DEVICEMODE;
3569 mode->statuslen = sizeof (NETWORKMODE);
3571 for (i=0;i < 16;i++) {
3572 if (i == mode->adress) mode->stat[i].features = IRDevices[0].fw_capabilities;
3573 else mode->stat[i].features = remote_statusex[0].stat[i].capabilities;
3574 mode->stat[i].extended_mode = remote_statusex[0].stat[i].extended_mode;
3575 mode->stat[i].extended_mode2 = remote_statusex[0].stat[i].extended_mode2;
3576 mode->stat[i].device_mode = remote_statusex[0].stat[i].device_mode;
3577 mode->stat[i].send_mask = remote_statusex[0].stat[i].send_mask;
3578 memcpy (mode->stat[i].version,remote_statusex[0].stat[i].version,10);
3579 if (mode->stat[i].version[0]) {
3580 FindSwitch ((word)i,0,mode->stat[i].remote,mode->stat[i].command,&mode->stat[i].switch_mode);
3586 void PutDeviceStatusEx (void *pnt,byte command,byte offset)
3588 int i,bus;
3589 NETWORKMODEEX *mode;
3590 NETWORKMODEEXN *moden;
3592 if (command == COMMAND_STATUSEX) {
3593 mode = (NETWORKMODEEX *)pnt;
3594 mode->statustype = STATUS_DEVICEMODEEX;
3595 mode->statuslen = sizeof (NETWORKMODEEX);
3596 mode->count = device_cnt;
3597 for (bus=0;bus < device_cnt;bus++) {
3598 mode->dev_adr[bus] = remote_statusex[bus].my_adress;
3599 for (i=0;i < 16;i++) {
3600 if (i == mode->dev_adr[bus]) mode->stat[bus][i].features = IRDevices[bus].fw_capabilities;
3601 else mode->stat[bus][i].features = remote_statusex[bus].stat[i].capabilities;
3602 mode->stat[bus][i].extended_mode = remote_statusex[bus].stat[i].extended_mode;
3603 mode->stat[bus][i].extended_mode2 = remote_statusex[bus].stat[i].extended_mode2;
3604 mode->stat[bus][i].device_mode = remote_statusex[bus].stat[i].device_mode;
3605 mode->stat[bus][i].send_mask = remote_statusex[bus].stat[i].send_mask;
3606 memcpy (mode->stat[bus][i].version,remote_statusex[bus].stat[i].version,10);
3607 if (mode->stat[bus][i].version[0]) {
3608 FindSwitch ((word)(i + bus * 16),0,mode->stat[bus][i].remote,mode->stat[bus][i].command,&mode->stat[bus][i].switch_mode);
3615 if (command == COMMAND_STATUSEXN) {
3616 moden = (NETWORKMODEEXN *)pnt;
3617 moden->statustype = STATUS_DEVICEMODEEXN;
3618 moden->statuslen = sizeof (NETWORKMODEEXN);
3619 moden->count = device_cnt;
3620 moden->offset = offset;
3621 for (bus=0;bus < 8;bus++) {
3622 moden->dev_adr[bus] = remote_statusex[offset + bus].my_adress;
3623 for (i=0;i < 16;i++) {
3624 if (i == moden->dev_adr[bus]) moden->stat[bus][i].features = IRDevices[offset + bus].fw_capabilities;
3625 else moden->stat[bus][i].features = remote_statusex[offset + bus].stat[i].capabilities;
3626 moden->stat[bus][i].extended_mode = remote_statusex[offset + bus].stat[i].extended_mode;
3627 moden->stat[bus][i].extended_mode2 = remote_statusex[offset + bus].stat[i].extended_mode2;
3628 moden->stat[bus][i].device_mode = remote_statusex[offset + bus].stat[i].device_mode;
3629 moden->stat[bus][i].send_mask = remote_statusex[offset + bus].stat[i].send_mask;
3630 moden->stat[bus][i].extended_mode3 = remote_statusex[offset + bus].stat[i].extended_mode3;
3631 moden->stat[bus][i].extended_mode4 = remote_statusex[offset + bus].stat[i].extended_mode4;
3632 memcpy (moden->stat[bus][i].version,remote_statusex[offset + bus].stat[i].version,10);
3633 if (moden->stat[bus][i].version[0]) {
3634 FindSwitch ((word)(i + bus * 16),0,moden->stat[bus][i].remote,moden->stat[bus][i].command,&moden->stat[bus][i].switch_mode);
3635 if (remote_statusex[offset + bus].stat[i].wake_mac[0] || remote_statusex[offset + bus].stat[i].wake_mac[1] || remote_statusex[offset + bus].stat[i].wake_mac[2] ||
3636 remote_statusex[offset + bus].stat[i].wake_mac[3] || remote_statusex[offset + bus].stat[i].wake_mac[4] || remote_statusex[offset + bus].stat[i].wake_mac[5]) {
3638 sprintf (moden->stat[bus][i].remote2,"@@@~~~LAN~~~@@@ %s %s ",IRDevices[offset + bus].usb_serno,IRDevices[offset + bus].device_node);
3639 memcpy (moden->stat[bus][i].command2,remote_statusex[offset + bus].stat[i].wake_mac,6);
3641 else {
3642 if (moden->stat[bus][i].features & FN_LAN) {
3643 sprintf (moden->stat[bus][i].remote2,"@@@~~~lan~~~@@@ %s %s ",IRDevices[offset + bus].usb_serno,IRDevices[offset + bus].device_node);
3644 memset (moden->stat[bus][i].command2,0,6);
3646 else FindSwitch ((word)(i + bus * 16),1,moden->stat[bus][i].remote2,moden->stat[bus][i].command2,&moden->stat[bus][i].switch_mode2);
3655 void PutNetworkStatus (int res,char msg[],STATUSBUFFER *buf)
3658 NETWORKSTATUS *stat;
3659 char txt[256];
3661 stat = (NETWORKSTATUS *)buf;
3663 stat->statustype = STATUS_MESSAGE;
3665 if (!res) {
3666 stat->statuslen = 8;
3667 return;
3670 stat->netstatus = res;
3671 stat->statuslen = sizeof (NETWORKSTATUS);
3673 if (res == ERR_TIMEOUT) {
3674 stat->statuslevel = IRTIMEOUT;
3675 sprintf (stat->message,"Timeout");
3676 return;
3679 if (res == ERR_OPENASCII) {
3680 stat->statuslevel = FATAL;
3681 sprintf (stat->message,"Error opening Remote %s",msg);
3682 return;
3685 if (res == ERR_NOFILEOPEN) {
3686 stat->statuslevel = FATAL;
3687 sprintf (stat->message,"No Remote open");
3688 return;
3691 stat->statuslevel = IR;
3693 if (msg) {
3694 strcpy (stat->message,msg);
3695 return;
3698 GetError (res,txt);
3699 sprintf (stat->message,"IR Error: %s",txt);
3702 void ResultStoreTiming (IRDATA *ird,NETWORKTIMING *stat)
3704 stat->statustype = STATUS_TIMING;
3705 stat->statuslen = sizeof (NETWORKTIMING);
3707 stat->timing.mode = ird->mode;
3708 stat->timing.time_cnt = ird->time_cnt;
3709 stat->timing.ir_repeat = ird->ir_repeat;
3710 stat->timing.repeat_pause = ird->repeat_pause;
3711 memcpy (stat->timing.pause_len,ird->pause_len,12);
3712 memcpy (stat->timing.pulse_len,ird->pulse_len,12);
3713 memcpy (stat->timing.data,ird->data,CODE_LEN);
3714 stat->adress = ird->address;
3718 void SwapNetworkheader (NETWORKSTATUS *ns)
3720 if (!byteorder) return;
3722 swap_int (&ns->clientid);
3723 swap_word (&ns->statuslen);
3724 swap_word (&ns->statustype);
3725 swap_word (&ns->adress);
3729 void SwapNetworkcommand (NETWORKCOMMAND *nc)
3731 if (!byteorder) return;
3733 swap_int (&nc->adress);
3734 swap_word (&nc->timeout);
3737 void SwapNetworkstatus (void *pnt)
3739 int i;
3740 word type;
3741 NETWORKSTATUS *ns;
3742 NETWORKTIMING *nt;
3743 NETWORKMODE *nm;
3744 REMOTEBUFFER *rb;
3745 COMMANDBUFFER *cb;
3746 FUNCTIONBUFFER *fb;
3748 if (!byteorder) return;
3750 ns = (NETWORKSTATUS *)pnt;
3751 type = ns->statustype;
3753 SwapNetworkheader ((NETWORKSTATUS *)pnt);
3755 if (type == STATUS_MESSAGE) {
3756 swap_word (&ns->netstatus);
3757 swap_word (&ns->statuslevel);
3758 return;
3760 if (type == STATUS_TIMING) {
3761 nt = (NETWORKTIMING *)pnt;
3762 for (i=0;i < TIME_LEN;i++) {
3763 swap_word (&nt->timing.pause_len[i]);
3764 swap_word (&nt->timing.pulse_len[i]);
3766 return;
3768 if (type == STATUS_DEVICEMODE) {
3769 nm = (NETWORKMODE *)pnt;
3770 for (i=0;i<16;i++) swap_int (&nm->stat[i].send_mask);
3771 return;
3773 if (type == STATUS_REMOTELIST) {
3774 rb = (REMOTEBUFFER *)pnt;
3775 swap_word (&rb->offset);
3776 swap_word (&rb->count_buffer);
3777 swap_word (&rb->count_remaining);
3778 swap_word (&rb->count_total);
3779 for (i=0;i<rb->count_buffer;i++) {
3780 swap_int (&rb->remotes[i].source_mask);
3781 swap_int (&rb->remotes[i].target_mask);
3783 return;
3785 if (type == STATUS_COMMANDLIST) {
3786 cb = (COMMANDBUFFER *)pnt;
3788 swap_word (&cb->offset);
3789 swap_word (&cb->count_buffer);
3790 swap_word (&cb->count_remaining);
3791 swap_word (&cb->count_total);
3792 return;
3794 if (type == STATUS_FUNCTION) {
3795 fb = (FUNCTIONBUFFER *)pnt;
3796 swap_int (&fb->functions);
3797 swap_int (&fb->serno);
3798 return;
3802 int GetNetworkClient (SOCKET sockfd)
3805 int i = 0;
3806 while (i < CLIENT_COUNT) {
3807 if ((sockinfo[i].type == SELECT_SERVER || sockinfo[i].type == SELECT_REOPEN)
3808 && sockfd == sockinfo[i].fd) return (i);
3809 i++;
3811 return (-1);
3814 int InitServerSocket (SOCKET *sock,SOCKET *lirc, SOCKET *udp,SOCKET *web)
3816 char msg[256],hub[50];
3817 struct sockaddr_in serv_addr;
3819 #ifdef LINUX
3820 int res,new = 1;
3821 struct stat s;
3822 struct sockaddr_un serv_addr_un;
3823 #endif
3825 #ifdef WIN32
3826 int err,res;
3827 WORD wVersionRequired;
3828 WSADATA wsaData;
3829 wVersionRequired = MAKEWORD(2,2);
3830 err = WSAStartup(wVersionRequired, &wsaData);
3831 if (err != 0) exit(1);
3833 #endif
3834 // ************************************************************* LIRC local Socket
3835 #ifdef LINUX
3836 if (mode_flag & NO_LIRC) {
3837 local_socket = 0;
3839 else {
3840 local_socket = socket(AF_UNIX,SOCK_STREAM,0);
3841 if (local_socket == -1) return (ERR_OPENSOCKET);
3843 res = stat (LIRCD,&s);
3844 if (res == -1 && errno != ENOENT) {
3845 close (local_socket);
3846 return (ERR_OPENSOCKET);
3849 if(res != -1) {
3850 new = 0;
3851 res = unlink (LIRCD);
3852 if (res == -1 && errno != ENOENT) {
3853 close (local_socket);
3854 return (ERR_OPENSOCKET);
3858 serv_addr_un.sun_family = AF_UNIX;
3859 strcpy (serv_addr_un.sun_path,LIRCD);
3861 if (bind (local_socket,(struct sockaddr *)&serv_addr_un,sizeof(serv_addr)) == -1) {
3862 close(local_socket);
3863 return (ERR_OPENSOCKET);
3866 if (new) chmod (LIRCD,PERMISSIONS);
3867 else {
3868 chmod(LIRCD,s.st_mode);
3869 chown(LIRCD,s.st_uid,s.st_gid);
3872 listen(local_socket,3);
3875 #endif
3877 // ************************************************************* IRTrans Socket
3878 *sock = socket (PF_INET,SOCK_STREAM,0);
3879 if (*sock < 0) return (ERR_OPENSOCKET);
3881 if (res = ConfigSocket (sock,TCP_PORT)) return (res);
3883 // ************************************************************* LIRC TCP/IP Socket
3885 if (mode_flag & NO_LIRC) {
3886 *lirc = 0;
3888 else {
3889 *lirc = socket (PF_INET,SOCK_STREAM,0);
3890 if (*lirc < 0) return (ERR_OPENSOCKET);
3891 if (res = ConfigSocket (lirc,LIRC_PORT)) return (res);
3893 // ************************************************************* Web Socket
3894 *web = socket (PF_INET,SOCK_STREAM,0);
3895 if (*web < 0) return (ERR_OPENSOCKET);
3897 if (mode_flag & NO_WEB) {
3898 *web = 0;
3900 else {
3901 if (webport) {
3902 if (res = ConfigSocket (web,webport)) return (ERR_BINDWEB);
3905 else {
3906 if (res = ConfigSocket (web,webport = WEB_PORT)) {
3907 if (ConfigSocket (web,webport = ALTERNATE_WEB)) return (ERR_BINDWEB);
3912 // ************************************************************* UDP Socket
3913 *udp = socket (PF_INET,SOCK_DGRAM,0);
3914 if (*udp < 0) return (ERR_OPENSOCKET);
3916 memset (&serv_addr,0,sizeof (serv_addr));
3917 serv_addr.sin_family = AF_INET;
3918 #ifdef DBOX
3919 serv_addr.sin_addr.s_addr = INADDR_ANY;
3920 serv_addr.sin_port = UDP_PORT;
3921 #else
3922 serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
3923 serv_addr.sin_port = htons (8765);
3924 #endif
3926 if (bind (*udp,(struct sockaddr *)&serv_addr,sizeof (serv_addr)) < 0) return (ERR_BINDSOCKET);
3929 // ************************************************************* UDP Socket Port 21000 für IRTrans LAN Module
3931 if (res = OpenIRTransLANSocket ()) return res;
3933 #ifdef LINUX
3934 OpenIRTransBroadcastSockets ();
3935 #endif
3937 // ************************************************************* UDP Relay Socket
3938 if (udp_relay_port) {
3939 udp_relay_socket = socket (PF_INET,SOCK_DGRAM,0);
3940 if (udp_relay_socket < 0) return (ERR_OPENSOCKET);
3942 memset (&serv_addr,0,sizeof (serv_addr));
3943 serv_addr.sin_family = AF_INET;
3945 serv_addr.sin_addr.s_addr = *((unsigned int *)gethostbyname (udp_relay_host)->h_addr);
3946 serv_addr.sin_port = htons ((word)udp_relay_port);
3948 if (connect (udp_relay_socket,(struct sockaddr *)&serv_addr,sizeof (serv_addr)) < 0) return (ERR_BINDSOCKET);
3952 if (mode_flag & XAP) {
3953 xAP_rcv_port = XAP_PORT;
3954 xAP_rcv = socket (PF_INET,SOCK_DGRAM,0);
3955 if (xAP_rcv < 0) return (ERR_OPENSOCKET);
3957 memset (&serv_addr,0,sizeof (serv_addr));
3958 serv_addr.sin_family = AF_INET;
3960 serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
3961 serv_addr.sin_port = htons ((word)xAP_rcv_port);
3963 hub[0] = 0;
3965 if (bind (xAP_rcv,(struct sockaddr *)&serv_addr,sizeof (serv_addr)) < 0) { // Hub aktiv
3966 sprintf (hub,"Hub active. ");
3967 for (xAP_rcv_port = XAP_PORT + 1;xAP_rcv_port < XAP_PORT + 100;xAP_rcv_port++) {
3968 memset (&serv_addr,0,sizeof (serv_addr));
3969 serv_addr.sin_family = AF_INET;
3971 serv_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
3972 serv_addr.sin_port = htons ((word)xAP_rcv_port);
3973 res = bind (xAP_rcv,(struct sockaddr *)&serv_addr,sizeof (serv_addr));
3974 if (!res) break;
3976 if (res < 0) return (ERR_OPENSOCKET);
3979 xAP_send = socket (PF_INET,SOCK_DGRAM,0);
3980 if (xAP_send < 0) return (ERR_OPENSOCKET);
3982 res = 1;
3983 setsockopt (xAP_send,SOL_SOCKET,SO_BROADCAST,(char *)&res,sizeof (int));
3985 memset (&serv_addr,0,sizeof (serv_addr));
3986 serv_addr.sin_family = AF_INET;
3988 serv_addr.sin_addr.s_addr = INADDR_BROADCAST;
3989 serv_addr.sin_port = htons ((word)XAP_PORT);
3991 if (res = connect (xAP_send,(struct sockaddr *)&serv_addr,sizeof (serv_addr)) < 0) {
3992 printf ("RES: %d errno: %d\n",res,errno);
3993 return (ERR_BINDSOCKET);
3996 if (mode_flag & XAP) {
3997 sprintf (msg,"xAP Interface enabled. %sListening on port %d\n",hub,xAP_rcv_port);
3998 log_print (msg,LOG_INFO);
4001 xAP_SendHeartbeat ();
4004 return (0);
4009 int ConfigSocket (SOCKET *sock,unsigned short port)
4011 struct sockaddr_in serv_addr;
4012 memset (&serv_addr,0,sizeof (serv_addr));
4013 serv_addr.sin_family = AF_INET;
4015 #ifdef DBOX
4016 serv_addr.sin_addr.s_addr = INADDR_ANY;
4017 serv_addr.sin_port = port;
4018 #else
4019 serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
4020 serv_addr.sin_port = htons (port);
4021 #endif
4022 if (bind (*sock,(struct sockaddr *)&serv_addr,sizeof (serv_addr)) < 0) return (ERR_BINDSOCKET);
4024 listen (*sock,5);
4025 return (0);
4028 void process_udp_command (char *data,int len,struct sockaddr_in *send_adr)
4030 int res;
4031 int cmd_num,adr;
4032 char err[256],txt[256];
4033 char remote[80],command[20],ccf[2048];
4034 int netcom,netmask,bus,led,port;
4035 NETWORKCLIENT client;
4037 data[len] = 0;
4039 res = AnalyzeUDPString (data,&netcom,remote,command,ccf,&netmask,&bus,&led,&port);
4040 if (res) {
4041 log_print ("Illegal UDP Command\n", LOG_ERROR);
4042 return;
4045 sprintf (txt,"UDP Command: %d %s,%s,%d,%d [%x]\n", netcom,remote,command,bus,led,send_adr->sin_addr.s_addr);
4046 log_print (txt,LOG_DEBUG);
4048 adr = 0;
4050 if (netmask) adr |= 0x10000 | netmask;
4051 adr |= (led & 3) << 17;
4052 if (bus == 255) adr |= 0x40000000;
4053 else adr |= bus << 19;
4054 protocol_version = 210;
4056 if (netcom == 1) {
4057 res = DBFindRemoteCommand (remote,command,&cmd_num,NULL);
4058 if (res) {
4059 GetError (res, txt);
4060 switch(res) {
4061 case ERR_REMOTENOTFOUND:
4062 sprintf (err, txt, remote);
4063 break;
4064 case ERR_COMMANDNOTFOUND:
4065 sprintf (err, txt, command);
4066 break;
4067 default:
4068 sprintf (err, txt);
4069 break;
4071 log_print (err, LOG_ERROR);
4072 SendUDPAck ("ERR",send_adr,port);
4073 return;
4075 SendIR (cmd_num,adr);
4076 SendUDPAck ("OK",send_adr,port);
4079 if (netcom == 2) {
4080 memset (&client,0,sizeof (client));
4081 client.fp = ASCIIOpenRemote (remote,&client);
4082 if (!client.fp) {
4083 sprintf (txt,"Unable to open remote %s\n",remote);
4084 log_print (txt,LOG_DEBUG);
4085 SendUDPAck ("ERR",send_adr,port);
4086 return;
4088 SendUDPAck ("READY",send_adr,port);
4089 res = LearnIREx (&client.ird,(word)'L',30000,0,0);
4090 if (res) {
4091 fclose (client.fp);
4092 sprintf (txt,"Learn Error\n");
4093 log_print (txt,LOG_DEBUG);
4094 SendUDPAck ("ERR",send_adr,port);
4095 return;
4098 client.timing = ASCIIStoreTiming (client.fp,&client.ird,&client.learnstatus);
4099 ASCIIFindCommand (client.fp,command,&client);
4100 ASCIIStoreCommand (client.fp,&client.ird,command,client.timing,0);
4101 fclose (client.fp);
4102 ReadIRDatabase ();
4103 SendUDPAck ("OK",send_adr,port);
4105 if (netcom == 3) SendUDPAck ("OK",send_adr,port);
4108 void SendUDPAck (char stat[],struct sockaddr_in *target,int port)
4110 target->sin_family = AF_INET;
4111 target->sin_port = htons ((word)port);
4113 connect (irtlan_outbound,(struct sockaddr *)target,sizeof (struct sockaddr_in));
4115 send (irtlan_outbound,stat,(int)strlen (stat),0);
4119 int AnalyzeUDPString (char *st,int *netcom,char *remote,char *command,char *ccf,int *netmask,int *bus,int *led,int *port)
4121 int i,p,v;
4123 *netcom = 0;
4124 ccf[0] = remote[0] = command[0] = 0;
4125 *bus = *led = 0;
4126 *netmask = 0;
4127 *port = 21000;
4129 i = 3;
4131 if (!strncmp (st,"sndccfr",7) || !strncmp (st,"Sndccfr",7) || !strncmp (st,"SNDCCFR",7)) {
4132 i = 7;
4133 *netcom = 5;
4135 else if (!strncmp (st,"sndccf",6) || !strncmp (st,"Sndccf",6) || !strncmp (st,"SNDCCF",6)) {
4136 i = 6;
4137 *netcom = 4;
4139 else if (!strncmp (st,"snd",3) || !strncmp (st,"Snd",3) || !strncmp (st,"SND",3)) *netcom = 1;
4140 else if (!strncmp (st,"lrn",3) || !strncmp (st,"Lrn",3) || !strncmp (st,"LRN",3)) *netcom = 2;
4141 else if (!strncmp (st,"ping",4) || !strncmp (st,"Ping",4) || !strncmp (st,"PING",4)) {
4142 *netcom = 3;
4143 i = 4;
4145 while (st[i] == ' ') i++;
4146 p = i;
4147 while (st[i] && st[i] != ',') i++;
4148 st[i++] = 0;
4150 if (st[p] == 'p' || st[p] == 'P') *port = atoi (st+p+1);
4151 return (0);
4153 else return ERR_UDPFORMAT;
4155 while (st[i] == ' ') i++;
4157 if (*netcom == 4 || *netcom == 5) {
4158 p = i;
4159 while (st[i] && st[i] != ',') i++;
4161 v = st[i];
4162 st[i++] = 0;
4163 strcpy (ccf,st+p);
4165 else {
4166 p = i;
4167 while (st[i] && st[i] != ',') i++;
4169 if (!st[i]) return ERR_UDPFORMAT;
4170 st[i++] = 0;
4171 strncpy (remote,st+p,80);
4173 p = i;
4174 while (st[i] && st[i] != ',') i++;
4176 v = st[i];
4177 st[i++] = 0;
4178 strncpy (command,st+p,20);
4181 while (v) {
4182 p = i;
4184 while (st[i] && st[i] != ',' && st[i] != ' ') i++;
4185 v = st[i];
4186 st[i++] = 0;
4188 if (st[p] == 'l' || st[p] == 'L') {
4189 p++;
4190 if (st[p] == 'i' || st[p] == 'I') *led = 1;
4191 else if (st[p] == 'e' || st[p] == 'E') *led = 2;
4192 else if (st[p] == 'b' || st[p] == 'B') *led = 3;
4193 else return ERR_UDPFORMAT;
4196 else if (st[p] == 'b' || st[p] == 'B') {
4197 p++;
4198 *bus = atoi (st+p);
4199 if (*bus > 255) return ERR_UDPFORMAT;
4202 else if (st[p] == 'm' || st[p] == 'M') {
4203 p++;
4204 *netmask = atoi (st+p);
4207 else if (st[p] == 'p' || st[p] == 'P') {
4208 p++;
4209 *port = atoi (st+p);
4212 else return ERR_UDPFORMAT;
4215 return (0);