2 * Copyright (c) 2007, IRTrans GmbH
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of IRTrans GmbH nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY IRTrans GmbH ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL IRTrans GmbH BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <sys/types.h>
39 #include <sys/timeb.h>
42 #define MSG_NOSIGNAL 0
54 #define MSG_NOSIGNAL 0
65 #include <sys/types.h>
66 #include <sys/socket.h>
67 #include <netinet/in.h>
70 #include <arpa/inet.h>
78 #include <sys/utsname.h>
84 #define closesocket close
85 #define _getpid getpid
91 #define LIRCD "/dev/lircd"
92 #define PERMISSIONS 0666
103 #include "lowlevel.h"
106 #include "webserver.h"
114 #include "winusbio.h"
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
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
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
);
181 WSAEVENT IrtLanEvent
;
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
;
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];
213 NETWORKCLIENT sockinfo
[CLIENT_COUNT
];
216 extern IRREMOTE
*rem_pnt
;
218 extern IRCOMMAND
*cmd_pnt
;
220 extern char irtrans_usage
[];
222 unsigned int mode_flag
= 0;
229 char irserver_version
[20];
230 char irtrans_version
[100];
235 int protocol_version
;
241 // LOCALE für Fehlermeldungen
242 // Timeout bevor Repeat beginnt
243 // Fehlermeldungen mit Parametern erweitern.
244 // Neuer Parameter für remotes Verzeichnis
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
[])
613 #if defined (WIN32) && !defined (_M_X64)
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");
624 #if defined (LINUX) && !defined (X64)
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");
638 mode_flag
|= NO_RESET
;
639 mode_flag
|= LOG_FATAL
;
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
);
648 if (argc
== 2 && !strcmp (argv
[1],"-deviceinfo")) {
649 mode_flag
= (mode_flag
& ~LOG_MASK
) | 3;
651 strcpy (st
,"usb;com1;com2;com3;com4;lan");
653 strcpy (st
,"usb;/dev/ttyS0;/dev/ttyS1;/dev/ttyS2;/dev/ttyS3;lan");
655 return (get_devices (st
,1));
658 for (;--argc
> 2;argv
++) { // Process all Command Line Arguments
660 if (!strcmp (argv
[1],"-no_reconnect")) {
661 mode_flag
|= NO_RECONNECT
;
664 if (!strcmp (argv
[1],"-no_init_lan")) {
665 mode_flag
|= NO_INIT_LAN
;
668 if (!strcmp (argv
[1],"-start_clock")) {
669 mode_flag
|= CLOCK_STARTUP
;
672 if (!strcmp (argv
[1],"-send_forward")) {
673 mode_flag
|= SEND_FORWARD
;
676 if (!strcmp (argv
[1],"-send_forwardall")) {
677 mode_flag
|= SEND_FORWARDALL
;
680 if (!strcmp (argv
[1],"-ip_relay")) {
681 mode_flag
|= IP_RELAY
;
684 if (!strcmp (argv
[1],"-no_clock")) {
685 mode_flag
|= NO_CLOCK
;
688 if (!strcmp (argv
[1],"-no_lirc")) {
689 mode_flag
|= NO_LIRC
;
692 if (!strcmp (argv
[1],"-debug_code")) {
693 mode_flag
|= DEBUG_CODE
;
696 if (!strcmp (argv
[1],"-hexdump")) {
697 mode_flag
|= HEXDUMP
;
700 if (!strcmp (argv
[1],"-timestamp")) {
701 mode_flag
|= TIMESTAMP
;
704 if (!strcmp (argv
[1],"-medialon")) {
705 mode_flag
|= MEDIALON
;
708 if (!strcmp (argv
[1],"-codedump")) {
709 mode_flag
|= CODEDUMP
;
712 if (!strcmp (argv
[1],"-xap")) {
716 if (!strcmp (argv
[1],"-learned_only")) {
717 mode_flag
|= LEARNED_ONLY
;
720 if (!strcmp (argv
[1],"-logfile")) {
723 strcpy (logfile
,argv
[1]);
726 if (!strcmp (argv
[1],"-baudrate")) {
729 strncpy (baudrate
,argv
[1],10);
732 if (!strcmp (argv
[1],"-hexfile")) {
735 strcpy (hexfile
,argv
[1]);
738 if (!strcmp (argv
[1],"-pidfile")) {
741 strcpy (pidfile
,argv
[1]);
744 if (!strcmp (argv
[1],"-udp_relay")) {
747 strcpy (udp_relay_host
,argv
[1]);
750 udp_relay_port
= atoi (argv
[1]);
753 strcpy (udp_relay_format
,argv
[1]);
756 if (!strcmp (argv
[1],"-loglevel")) {
759 mode_flag
= (mode_flag
& ~LOG_MASK
) | (atoi (argv
[1]) & LOG_MASK
);
762 if (!strcmp (argv
[1],"-set_id")) {
765 device_id
= atoi (argv
[1]) & 0xf;
768 if (!strcmp (argv
[1],"-delay")) {
771 msSleep (atoi (argv
[1]));
774 if (!strcmp (argv
[1],"-wait")) {
777 device_wait
= atoi (argv
[1]);
780 if (!strcmp (argv
[1],"-stat_timeout")) {
783 status_cache_timeout
= atoi (argv
[1]);
786 if (!strcmp (argv
[1],"-lcd")) {
789 new_lcd_flag
= atoi (argv
[1]);
793 if (!strcmp (argv
[1],"-netmask")) {
797 netip
[netcount
] = ntohl (inet_addr (strtok (argv
[1],"/")));
798 pnt
= strtok (NULL
,"/");
802 for (i
=0;i
< res
;i
++) adr
|= 1 << (31-i
);
803 netmask
[netcount
++] = adr
;
809 if (!strcmp (argv
[1],"-reset_eeprom")) {
812 eeprom_id
= atoi (argv
[1]) & 0xf;
815 if (!strcmp (argv
[1],"-udp_port")) {
818 irtrans_udp_port
= atoi (argv
[1]);
821 if (!strcmp (argv
[1],"-http_port")) {
824 mode_flag
&= ~NO_WEB
;
825 webport
= atoi (argv
[1]);
828 if (!strcmp (argv
[1],"-no_web")) {
832 if (!strcmp (argv
[1],"-read_eeprom")) {
833 mode_flag
|= READ_EEPROM
;
837 if (!strcmp (argv
[1],"-daemon")) {
838 if (*logfile
== 0) strcpy (logfile
,"irserver.log");
839 mode_flag
|= DAEMON_MODE
;
843 fprintf (stderr
,"Unknown option %s\n",argv
[1]);
847 if (argc
== 1 || argv
[1][0] == '-') display_usage ();
849 res
= InitServer (argv
[1]);
854 log_print (st
,LOG_FATAL
);
858 if (device_id
!= -1) { // Bus !!!
859 res
= SetTransceiverIDEx (0,(byte
)device_id
);
863 if (eeprom_id
!= -1) { // Bus !!!
864 res
= SetTransceiverModusEx (0,159,0xffff,0,"",0,0xf,3,0,0,0);
872 log_print (st
,LOG_FATAL
);
879 void display_usage (void)
881 fprintf (stderr
,"%s",irtrans_usage
);
887 int InitServer (char dev
[])
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
);
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
;
918 LircEvent
= WSACreateEvent ();
919 WSAEventSelect (lirc_socket
,LircEvent
,FD_ACCEPT
);
922 if (mode_flag
& NO_WEB
) WebEvent
= NULL
;
924 WebEvent
= WSACreateEvent ();
925 WSAEventSelect (web_socket
,WebEvent
,FD_ACCEPT
);
931 ti
= time (0) + device_wait
;
934 res
= InitCommunicationEx (dev
);
935 if (res
&& device_wait
) msSleep (500);
936 } while (res
&& device_wait
&& time (0) < ti
);
938 if (res
) return (res
);
941 logfp
= fopen (logfile
,"w");
943 fprintf (stderr
,"Unable to open Logfile %s\n",logfile
);
949 hexfp
= fopen (hexfile
,"w");
951 fprintf (stderr
,"Unable to open Hexfile %s\n",hexfile
);
957 if (mode_flag
& DAEMON_MODE
) {
964 fp
= fopen ("/tmp/.irserver.pid","w");
966 fprintf (fp
,"%d\n",getpid ());
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
);
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 ();
1008 pf
= fopen (pidfile
,"w");
1010 sprintf (msg
,"Cannot create PID file %s\n",pidfile
);
1011 log_print (msg
,LOG_ERROR
);
1014 fprintf (pf
,"%d\n",_getpid ());
1024 int res
,wait
,evnt
,i
,j
;
1027 byte rdcom
[1000],dummy
;
1028 time_t lasttimesync
= 0;
1029 struct sockaddr_in send_adr
;
1030 IRDATA_LAN_SHORT ir
;
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];
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);
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
);
1072 lasttimesync
= time (0);
1075 SetLCDProcCharsV (rdcom
);
1077 AdvancedLCD (LCD_DATA
| LCD_DEFINECHAR
,rdcom
,rdcom
[0] * 9 + 1);
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;
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
) {
1110 for (i
=0;i
< device_cnt
;i
++) if (IRDevices
[i
].io
.if_type
== IF_USB
) WriteUSBStringEx (IRDevices
+ i
,&dummy
,1);
1113 evnt
= get_selected_event (wait
,events
,event_type
,event_num
,&sockfd
);
1116 cnt
= ReadInstantReceive (&IRDevices
[event_num
[wait
]],rdcom
,1000);
1117 if (cnt
> 2) ExecuteReceivedCommand (rdcom
,cnt
,event_num
[wait
]);
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
);
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
);
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
);
1151 register_remote_client (sockfd
,evnt
);
1154 ProcessWebRequest (sockfd
);
1157 // process_udp_command (sockfd);
1160 xAP_EventReceived ();
1164 process_lirc_command (sockfd
);
1166 case COMMAND_SERVER
:
1167 case COMMAND_REOPEN
:
1168 ExecuteNetCommand (sockfd
);
1178 maxfd
= build_select_table (&events
);
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
);
1191 sprintf (rdcom
,"Select Error: %d\n",errno
);
1192 log_print (rdcom
,LOG_FATAL
);
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 ();
1205 for (i
=0;i
< device_cnt
;i
++) if (IRDevices
[i
].io
.if_type
== IF_USB
) WriteIRStringEx (IRDevices
+ i
,&dummy
,1);
1208 evnt
= get_selected_fd (&events
,&sockfd
,&ionum
);
1211 cnt
= ReadInstantReceive (IRDevices
+ ionum
,rdcom
,1000);
1212 if (cnt
> 2) ExecuteReceivedCommand (rdcom
,cnt
,ionum
);
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
);
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
);
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
);
1247 register_remote_client (sockfd
,evnt
);
1250 ProcessWebRequest (sockfd
);
1254 process_lirc_command (sockfd
);
1257 xAP_EventReceived ();
1260 // process_udp_command (sockfd);
1262 case COMMAND_SERVER
:
1263 case COMMAND_REOPEN
:
1264 ExecuteNetCommand (sockfd
);
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;
1285 int build_event_table (HANDLE events
[],byte event_type
[],byte event_num
[],OVERLAPPED OvCom
[],int *ser_event
)
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
);
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
;
1300 events
[num
++] = IRDevices
[i
].io
.event
;
1304 event_type
[num
] = SELECT_SERVER
;
1306 events
[num
++] = SockEvent
;
1309 event_type
[num
] = SELECT_LIRC
;
1311 events
[num
++] = LircEvent
;
1314 event_type
[num
] = SELECT_UDP
;
1316 events
[num
++] = UDPEvent
;
1318 event_type
[num
] = SELECT_IRTLAN
;
1320 events
[num
++] = IrtLanEvent
;
1323 event_type
[num
] = SELECT_WEB
;
1325 events
[num
++] = WebEvent
;
1328 if (mode_flag
& XAP
) {
1329 event_type
[num
] = SELECT_XAP
;
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
;
1337 events
[num
++] = sockinfo
[i
].event
;
1343 int get_selected_event (int eventnum
,HANDLE events
[],byte event_type
[],byte event_num
[],SOCKET
*sockfd
)
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);
1378 int get_selected_fd (fd_set
*events
,SOCKET
*sockfd
,int *ionum
)
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
)) {
1385 *sockfd
= IRDevices
[i
].io
.comport
;
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
)) {
1395 *sockfd
= lirc_socket
;
1397 if (!(mode_flag
& NO_LIRC
) && !fds
&& FD_ISSET (local_socket
,events
)) {
1399 *sockfd
= local_socket
;
1402 if (!(mode_flag
& NO_WEB
) && !fds
&& FD_ISSET (web_socket
,events
)) {
1404 *sockfd
= web_socket
;
1407 if (!fds
&& FD_ISSET (udp_socket
,events
)) {
1409 *sockfd
= udp_socket
;
1412 if (mode_flag
& XAP
&& !fds
&& FD_ISSET (xAP_rcv
,events
)) {
1417 if (!fds
&& FD_ISSET (irtlan_socket
,events
)) {
1418 fds
= SELECT_IRTLAN
;
1419 *sockfd
= irtlan_socket
;
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
;
1431 if (fds
) FD_CLR (*sockfd
,events
);
1437 int build_select_table (fd_set
*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
;
1488 SOCKET
register_remote_client (SOCKET fd
,int mode
)
1490 int res
,num
,asciimode
= 0;
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
);
1507 sprintf (rdcom
,"Accept error %d\n",errno
);
1508 log_print (rdcom
,LOG_ERROR
);
1512 adr
= ntohl (cli_addr
.sin_addr
.S_un
.S_addr
);
1514 adr
= ntohl (cli_addr
.sin_addr
.s_addr
);
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
);
1530 if (mode
== SELECT_SERVER
) {
1532 WSAEventSelect (call
,SockEvent
,0);
1533 ioctlsocket (call
,FIONBIO
,&res
);
1535 res
= recv (call
,(char *)&clientid
,4,MSG_NOSIGNAL
);
1542 fcntl (call
,F_SETFL
,O_NONBLOCK
);
1544 if (!memcmp ((char *)&clientid
,"ASCI",4) || !memcmp ((char *)&clientid
,"****",4)) {
1545 asciimode
= MODE_ASCII
;
1548 swap_int (&clientid
);
1551 while (res
< CLIENT_COUNT
) {
1552 if (sockinfo
[res
].type
== SELECT_REOPEN
&&
1553 clientid
== sockinfo
[res
].clientid
) {
1554 if (sockinfo
[res
].fd
!= -1) {
1556 WSACloseEvent (sockinfo
[res
].event
);
1557 sockinfo
[res
].event
= NULL
;
1559 shutdown (sockinfo
[res
].fd
,2);
1560 closesocket (sockinfo
[res
].fd
);
1562 sockinfo
[res
].fd
= call
;
1564 sockinfo
[res
].event
= WSACreateEvent ();
1565 WSAEventSelect (call
,sockinfo
[res
].event
,FD_READ
| FD_CLOSE
);
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
));
1583 sockinfo
[res
].event
= WSACreateEvent ();
1584 WSAEventSelect (call
,sockinfo
[res
].event
,FD_READ
| FD_CLOSE
);
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
);
1598 if (res
== CLIENT_COUNT
) {
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) {
1606 clientid
= sockinfo
[res
].callno
;
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
));
1621 sockinfo
[res
].event
= WSACreateEvent ();
1622 WSAEventSelect (call
,sockinfo
[res
].event
,FD_READ
| FD_CLOSE
);
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
);
1643 void process_lirc_command (SOCKET fd
)
1647 char com
[1024],msg
[1024],*pnt
,*key
,*rem
,err
[256];
1648 char remote
[80],command
[20];
1649 static char active_lirc_string
[1024];
1653 res
= recv (fd
,com
,1024,MSG_NOSIGNAL
);
1656 while (i
< CLIENT_COUNT
) {
1657 if (sockinfo
[i
].fd
== fd
) CloseIRSocket (i
);
1660 *active_lirc_string
= 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
)
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
);
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));
1699 res
= DBFindRemoteCommand (remote
,command
,&num
,NULL
);
1701 sprintf (err
,"IR Send Error %d\n",res
);
1702 log_print (err
,LOG_ERROR
);
1703 lirc_send_error (fd
,msg
,err
);
1706 SendIR (num
,0x40000000);
1709 lirc_send_success (fd
,msg
);
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
);
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
[])
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
);
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
);
1760 sprintf (st
,"No Remote %s found",rem
);
1761 lirc_send_error (fd
,msg
,st
);
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
);
1778 strcpy (remote
,rem
);
1779 ConvertLcase (remote
,(int)strlen (remote
));
1780 i
= DBFindRemote (remote
);
1782 sprintf (st
,"No Remote %s found",rem
);
1783 lirc_send_error (fd
,msg
,st
);
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
);
1794 sprintf (st
,"No Remote/Command %s/%s found",rem
,key
);
1795 lirc_send_error (fd
,msg
,st
);
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
[])
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
[])
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
1833 unsigned int GetFineTime (void)
1838 return (unsigned int)((tb
.time
& 0x7fffff) * 1000 + tb
.millitm
);
1844 unsigned int GetFineTime (void)
1848 gettimeofday (&tb
,NULL
);
1849 return (tb
.tv_sec
& 0x7fffff) * 1000 + tb
.tv_usec
/ 1000;
1854 unsigned int GetFineTime (void)
1856 // GetLocalTime (...);
1863 void send_forward (int client
,char rem
[],char name
[])
1869 memset (&nr
,0,sizeof (NETWORKRECV
));
1870 memset (nr
.data
,' ',200);
1871 memset (nr
.remote
,' ',80);
1872 memset (nr
.command
,' ',20);
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
));
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
)
1903 static time_t l_time
;
1904 static char l_command
[21];
1905 static char l_remote
[81];
1906 static int l_repeat
;
1908 int com_num
,rem_num
;
1909 static unsigned int ltv
;
1914 char rem
[512],name
[512],num
[512],dat
[1024],msg
[256];
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) {
1929 if (rcnt
< 5) return (1);
1935 start_pos
= DBFindCommandName (command
+ 1,rem
,name
,*command
,&rem_num
,&com_num
,&nr
.command_num
,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);
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') {
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
));
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
);
1981 if (udp_relay_port
) udp_relay (rem
,name
,*command
& 15);
1983 if (mode_flag
& XAP
) xAP_SendIREvent (rem
,name
,bus
,*command
& 15);
1986 PostWindowsMessage (rem_num
,com_num
,name
);
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
);
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);
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;
2009 SwapNetworkheader ((NETWORKSTATUS
*)&nr
);
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
));
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
);
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
);
2033 void udp_relay (char rem
[],char com
[],int adr
)
2036 char frm
[255],dat
[255];
2040 parm
[0] = parm
[1] = parm
[2] = 0;
2041 sprintf (adrst
,"%02d",adr
);
2042 strcpy (frm
,udp_relay_format
);
2045 for (i
=0;frm
[i
];i
++) {
2046 if (frm
[i
] == '%') {
2047 if (p
== 3) frm
[i
] = ' ';
2050 if (frm
[i
] == 'r') {
2054 else if (frm
[i
] == 'c') {
2058 else if (frm
[i
] == 'a') {
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
)
2075 WSACloseEvent (sockinfo
[client
].event
);
2076 sockinfo
[client
].event
= NULL
;
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
;
2096 int ReadIRDatabase (void)
2100 char st
[1024],*pnt
,msg
[256];
2102 char *home
= getenv("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 ();
2119 fd
= popen ("ls","r");
2121 pnt
= fgets (st
,1000,fd
);
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
);
2129 sprintf (msg
,"Error %d reading DB-File %s\n",res
,pnt
);
2130 log_print (msg
,LOG_ERROR
);
2133 pnt
= fgets (st
,1000,fd
);
2146 #else // Keine DBOX, normales LINUX
2148 int ReadIRDatabase (void)
2151 int fd
,i
,len
,pos
,res
,fl
;
2153 char st
[2048],msg
[256];
2155 char *home
= getenv("HOME");
2156 char *rdir
= getenv("IRTRANS_REMOTES");
2160 sprintf (msg
,"Error opening remote database %s\n",rdir
);
2161 log_print (msg
,LOG_FATAL
);
2163 return (ERR_NODATABASE
);
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 ();
2186 len
= getdirentries (fd
,st
,2048,&off
);
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
);
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
;
2221 int ReadIRDatabase (void)
2227 int ReadIRDatabase (void)
2230 struct _finddata_t c_file
;
2237 char *rdir
= getenv("IRTRANS_REMOTES");
2240 if (_chdir (rdir
)) {
2241 sprintf (msg
,"Error opening remote database %s\n",rdir
);
2242 log_print (msg
,LOG_FATAL
);
2244 return (ERR_NODATABASE
);
2249 if (IRDataBaseRead
) FreeDatabaseMemory ();
2250 else if (_chdir ("remotes")) return (ERR_NODATABASE
);
2253 ReadRoutingTable ();
2256 if((hFile
= _findfirst( "*.rem", &c_file
)) != -1L) {
2258 res
= DBReadCommandFile (c_file
.name
);
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
);
2280 void ExecuteNetCommand (SOCKET sockfd
)
2286 char buffer
[sizeof (CCFSTRINGCOMMAND
)];
2287 char buffer1
[sizeof (CCFSTRINGCOMMAND
)];
2290 NETWORKCOMMAND
*com
;
2292 client
= GetNetworkClient (sockfd
);
2299 sockinfo
[client
].callno
= seq_call
++;
2301 com
= (NETWORKCOMMAND
*)buffer
;
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
);
2312 if (WSAGetLastError () == WSAEWOULDBLOCK
) return;
2314 if (errno
== EAGAIN
) return;
2318 sockinfo
[client
].restlen
= 0;
2322 res
= recv (sockfd
,buffer
,1,MSG_NOSIGNAL
);
2324 if (res
!= 1 || *buffer
< 1 || *buffer
> COMMAND_ASCII
) {
2327 if (WSAGetLastError () == WSAEWOULDBLOCK
) return;
2329 if (errno
== EAGAIN
) return;
2332 if (res
<= 0) CloseIRSocket (client
);
2334 sprintf (err
,"Client [%d] disconnect\n",client
);
2335 log_print (err
,LOG_INFO
);
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
);
2345 if (*buffer
== COMMAND_ASCII
) {
2347 res
= recv (sockfd
,&c
,1,MSG_NOSIGNAL
);
2348 while (res
== 1 && c
!= '\n') {
2350 res
= recv (sockfd
,&c
,1,MSG_NOSIGNAL
);
2352 if (c
== '\n') buffer
[len
++] = c
;
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
);
2360 while (buffer
[len
-1] == 13 || buffer
[len
-1] == 10) {
2365 sprintf (err
,"ASCII Command: %s\n",buffer
+1);
2366 log_print (err
,LOG_INFO
);
2368 DoExecuteASCIICommand ((byte
*)buffer
+1,sockfd
,client
);
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
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
);
2401 protocol_version
= com
->protocol_version
;
2404 if (res
<= 0) CloseIRSocket (client
);
2406 memcpy (sockinfo
[client
].restdata
,buffer
,res
+ 1);
2407 sockinfo
[client
].restlen
= res
;
2408 sockinfo
[client
].restread
= sz
;
2413 SwapNetworkcommand (com
);
2414 DoExecuteNetCommand (client
,com
,&stat
);
2416 stat
.clientid
= sockinfo
[client
].clientid
;
2417 len
= stat
.statuslen
;
2418 SwapNetworkstatus (&stat
);
2421 while (sz
< len
&& errcnt
< 20) {
2422 res
= send (sockfd
,((char *)&stat
) + sz
,len
- sz
,MSG_NOSIGNAL
);
2423 if (res
> 0) sz
+= res
;
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
)
2451 char st
[255],err
[255];
2455 TRANSLATECOMMAND
*tr
;
2456 NETWORKLEARNSTAT
*lstat
;
2459 FUNCTIONBUFFEREX
*fbex
;
2460 NETWORKLCDSTAT
*lcdb
;
2463 CCFSTRINGCOMMAND
*ccf
;
2464 CCFSTRINGCOMMAND_SHORT
*ccfs
;
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
) {
2481 SetPowerLED (0,com
->remote
[0],com
->command
[0]);
2483 case COMMAND_DEFINECHAR
:
2484 AdvancedLCD (LCD_DATA
| LCD_DEFINECHAR
,com
->remote
,com
->remote
[0] * 9 + 1);
2485 if (new_lcd_flag
) msSleep (250);
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);
2495 case COMMAND_LCDSTATUS
:
2496 lcdb
= (NETWORKLCDSTAT
*)stat
;
2497 memset (lcdb
,0,sizeof (NETWORKLCDSTAT
));
2498 lcdb
->statustype
= STATUS_LCDDATA
;
2499 lcdb
->statuslen
= sizeof (NETWORKLCDSTAT
);
2502 lcdb
->clockflag
= 0;
2504 if (new_lcd_flag
== 1) {
2505 lcdb
->clockflag
= 3;
2506 lcdb
->virtual_col
= 40;
2511 if (new_lcd_flag
== 2) {
2512 lcdb
->clockflag
= 3;
2513 lcdb
->virtual_col
= 40;
2519 display_bus
= 0xffff;
2524 for (i
=0;i
< device_cnt
;i
++) if (IRDevices
[i
].version
[0] == 'D' || (IRDevices
[i
].fw_capabilities
& FN_DISPMASK
)) {
2529 if (IRDevices
[display_bus
].version
[0] == 'D') {
2534 if ((IRDevices
[display_bus
].fw_capabilities
& FN_DISPMASK
) == FN_DISP1
) {
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
) {
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;
2550 case COMMAND_SHUTDOWN
:
2551 if (strcmp (com
->remote
,"XXXshutdownXXX")) {
2552 PutNetworkStatus (ERR_SHUTDOWN
,NULL
,stat
);
2556 if (!(mode_flag
& NO_CLOCK
)) LCDTimeCommand (LCD_DISPLAYTIME
);
2557 sprintf (st
,"IRTrans Server Shutdown via Client");
2558 log_print (st
,LOG_FATAL
);
2561 case COMMAND_BRIGHTNESS
:
2562 LCDBrightness (com
->adress
);
2564 case COMMAND_SUSPEND
:
2566 if (!(mode_flag
& NO_CLOCK
)) LCDTimeCommand (LCD_DISPLAYTIME
);
2570 case COMMAND_RESUME
:
2575 case COMMAND_STORETRANS
:
2576 tr
= (TRANSLATECOMMAND
*)com
;
2577 StoreTransItem (tr
);
2579 case COMMAND_STOREIRDB
:
2580 db
= (IRDBCOMMAND
*)com
;
2583 case COMMAND_FLASHIRDB
:
2584 res
= SetIRDBEx ((byte
)((com
->adress
) >> 8),(com
->adress
& 0xf),stat
);
2585 if (res
) PutNetworkStatus (res
,NULL
,stat
);
2587 case COMMAND_SAVETRANS
:
2588 res
= FileTransData (com
->remote
,1,(byte
)com
->adress
);
2589 if (res
) PutNetworkStatus (res
,NULL
,stat
);
2591 case COMMAND_SAVEIRDB
:
2592 res
= FileTransData (com
->remote
,2,(byte
)com
->adress
);
2593 if (res
) PutNetworkStatus (res
,NULL
,stat
);
2595 case COMMAND_LOADIRDB
:
2596 res
= LoadIRDB ((IRDBBUFFER
*)stat
,com
->remote
,(word
)com
->adress
);
2597 if (res
) PutNetworkStatus (res
,NULL
,stat
);
2599 case COMMAND_LOADTRANS
:
2600 res
= LoadTranslation ((TRANSLATEBUFFER
*)stat
,com
->remote
,(word
)com
->adress
);
2601 if (res
) PutNetworkStatus (res
,NULL
,stat
);
2603 case COMMAND_FLASHTRANS
:
2604 res
= SetFlashdataEx ((byte
)((com
->adress
) >> 8),(com
->adress
& 0xf));
2605 if (res
) PutNetworkStatus (res
,NULL
,stat
);
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
);
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
));
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
;
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);
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) {
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
);
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
);
2669 if ((mode_flag
& SEND_FORWARDALL
) || (mode_flag
& SEND_FORWARD
)) send_forward (client
,com
->remote
,com
->command
);
2670 SendIRDataEx (&ird
,com
->adress
);
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
);
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
);
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
);
2697 SendIRDataEx (&ird
,com
->adress
);
2699 com
->command
[strlen (com
->command
) - 1] = 0;
2703 if (resend_flag
== 1) strcat (com
->command
,"@");
2704 res
= DBFindRemoteCommandEx (com
->remote
,com
->command
,&ird
,cal
);
2705 if (res
) PutNetworkStatus (res
,NULL
,stat
);
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;
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);
2739 PutNetworkStatus (ERR_OPENASCII
,com
->remote
,stat
);
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+");
2753 PutNetworkStatus (ERR_OPENASCII
,com
->remote
,stat
);
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
);
2766 hfile
= CreateFile (st
,GENERIC_WRITE
,FILE_SHARE_READ
| FILE_SHARE_WRITE
,NULL
,OPEN_EXISTING
,FILE_ATTRIBUTE_NORMAL
,NULL
);
2768 SetFilePointer (hfile
,res
,NULL
,FILE_BEGIN
);
2769 SetEndOfFile (hfile
);
2770 CloseHandle (hfile
);
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
);
2795 sprintf (err
,"Illegal xAP Pronto command\n");
2796 log_print (err
, LOG_ERROR
);
2797 ns
= (NETWORKSTATUS
*)stat
;
2798 PutNetworkStatus (ERR_CCF
,NULL
,stat
);
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
);
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
);
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
);
2837 fprintf (hexfp
,"%s-%s\n",com
->remote
,com
->command
);
2841 if (!strncmp (com
->remote
,"***relais_",10)) {
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'));
2849 res
= DBFindRemoteCommand (com
->remote
,com
->command
,&cmd_num
,NULL
);
2851 if ((mode_flag
& SEND_FORWARDALL
) || (mode_flag
& SEND_FORWARD
)) send_forward (client
,com
->remote
,com
->command
);
2852 res
= SendIR (cmd_num
,com
->adress
);
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
);
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
);
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
);
2884 case COMMAND_TESTCOM
:
2885 res
= DBFindRemoteCommand (com
->remote
,com
->command
,&cmd_num
,NULL
);
2887 ns
= (NETWORKSTATUS
*)stat
;
2888 PutNetworkStatus (ERR_TESTCOM
,NULL
,stat
);
2889 ns
->statuslevel
= (word
)com
->adress
;
2890 ns
->statuslen
-= 256;
2893 case COMMAND_TESTCOMEX
:
2894 res
= DBFindRemoteCommand (com
->remote
,com
->command
,&cmd_num
,NULL
);
2895 ns
= (NETWORKSTATUS
*)stat
;
2897 PutNetworkStatus (ERR_TESTCOM
,NULL
,stat
);
2900 PutNetworkStatus (ERR_TESTCOMOK
,NULL
,stat
);
2902 ns
->statuslevel
= (word
)com
->adress
;
2903 ns
->statuslen
-= 256;
2907 sprintf (st
,"Temperature %s-%d\n",com
->remote
,com
->adress
);
2908 log_print (st
,LOG_DEBUG
);
2909 memset (&ird
,0,sizeof (IRDATA
));
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
);
2927 case COMMAND_STARTCLOCK
:
2928 if (!(mode_flag
& NO_CLOCK
)) LCDTimeCommand (LCD_DISPLAYTIME
);
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;
2951 irw
->mode
= LCD_DATA
| lcd
->lcdcommand
;
2952 irw
->transmit_freq
= lcd
->timeout
;
2953 SendLCD (irw
,lcd
->adress
);
2955 if (new_lcd_flag
) msSleep (100);
2956 //printf ("<%s>\n",irw->data);
2957 //lcd_init = 1; // Debug für LCD Test
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;
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
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;
2982 irw
->mode
= LCD_DATA
| LCD_INIT
;
2983 irw
->transmit_freq
= lcd
->timeout
;
2984 SendLCD (irw
,lcd
->adress
);
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) {
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
);
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
);
3013 if (mode_flag
& SEND_FORWARDALL
) send_forward (client
,com
->remote
,com
->command
);
3014 PutNetworkStatus (res
,NULL
,stat
);
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
);
3029 if ((mode_flag
& SEND_FORWARDALL
) || (mode_flag
& SEND_FORWARD
)) send_forward (client
,com
->remote
,com
->command
);
3030 SendIRDataEx (&ird
,com
->adress
);
3035 if (resend_flag
== 1) strcat (com
->command
,"@");
3036 res
= DBFindRemoteCommandEx (com
->remote
,com
->command
,&ird
,cal
);
3038 if (mode_flag
& SEND_FORWARDALL
) send_forward (client
,com
->remote
,com
->command
);
3039 PutNetworkStatus (res
,NULL
,stat
);
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
);
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
);
3059 case COMMAND_LRNTIM
:
3060 if (sockinfo
[client
].fp
== NULL
) {
3061 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
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;
3074 case COMMAND_LRNRAW
:
3075 if (sockinfo
[client
].fp
== NULL
) {
3076 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
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
;
3088 case COMMAND_LRNRAWRPT
:
3089 if (sockinfo
[client
].fp
== NULL
) {
3090 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
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
;
3103 case COMMAND_LRNCOM
:
3104 if (sockinfo
[client
].fp
== NULL
) {
3105 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
3108 if (sockinfo
[client
].ird
.ir_length
== 0) {
3109 PutNetworkStatus (ERR_NOTIMING
,NULL
,stat
);
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
);
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
);
3122 case COMMAND_LEARNDIRECT
:
3123 res
= LearnIREx (&sockinfo
[client
].ird
,(word
)com
->adress
,com
->timeout
,(word
)(com
->adress
>> 16),com
-> trasmit_freq
);
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
);
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
);
3149 case COMMAND_LRNLONG
:
3150 if (sockinfo
[client
].fp
== NULL
) {
3151 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
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));
3170 case COMMAND_LRNTOG
:
3171 if (sockinfo
[client
].fp
== NULL
) {
3172 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
3178 res
= ASCIIFindToggleSeq (sockinfo
[client
].fp
,&sockinfo
[client
].ird
,com
->command
);
3179 if (res
< 0) PutNetworkStatus (ERR_TOGGLE_DUP
,NULL
,stat
);
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
);
3189 case COMMAND_LRNRPT
:
3190 if (sockinfo
[client
].fp
== NULL
) {
3191 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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
);
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
);
3209 if (sockinfo
[client
].fp
== NULL
) {
3210 PutNetworkStatus (ERR_NOFILEOPEN
,NULL
,stat
);
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);
3220 case COMMAND_RELOAD
:
3221 if (sockinfo
[client
].fp
) fflush ((sockinfo
[client
].fp
));
3224 case COMMAND_STATUS
:
3225 if (status_changed
|| (time (0) - last_status_read
) >= status_cache_timeout
) {
3226 res
= GetBusInfoEx (remote_statusex
,0);
3228 PutNetworkStatus (res
,NULL
,stat
);
3233 last_status_read
= time (0);
3236 PutDeviceStatus ((NETWORKMODE
*)stat
);
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);
3244 PutNetworkStatus (res
,NULL
,stat
);
3249 last_status_read
= time (0);
3252 PutDeviceStatusEx (stat
,com
->netcommand
,(byte
)com
->adress
);
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
);
3270 res
= ResetTransceiverEx ((byte
)((com
->adress
>> 8) & (MAX_IR_DEVICES
-1)));
3271 if (res
) PutNetworkStatus (res
,NULL
,stat
);
3273 case COMMAND_SETSTATEX
:
3274 mcom
= (MODUSCOMMAND
*)com
;
3275 res
= GetHotcode (mcom
->hotremote
,mcom
->hotcommand
,st
);
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
);
3283 if (strcmp (mcom
->hotremote_2
,"_")) res
= GetHotcode (mcom
->hotremote_2
,mcom
->hotcommand_2
,st
);
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
);
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
);
3304 LCDTimeCommand (LCD_REFRESHDATE
);
3306 case COMMAND_SETSTAT
:
3307 res
= GetHotcode (com
->remote
,com
->command
,st
);
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
);
3315 StoreSwitch ((word
)com
->timeout
,0,com
->remote
,com
->command
,1);
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
);
3321 LCDTimeCommand (LCD_REFRESHDATE
);
3324 case COMMAND_SETSTAT2
:
3325 res
= GetHotcode (com
->remote
,com
->command
,st
);
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
);
3333 StoreSwitch ((word
)com
->timeout
,1,com
->remote
,com
->command
,1);
3335 res
= SetTransceiverModusEx2 ((byte
)(com
->timeout
>> 8),(byte
)(com
->timeout
& 0xff),st
,res
);
3336 if (res
) PutNetworkStatus (res
,NULL
,stat
);
3340 case COMMAND_IRDBFILE
:
3342 ReadIRTransDirectory ("*.irdb",(REMOTEBUFFER
*)stat
,com
->adress
,STATUS_IRDBFILE
);
3345 ReadIRTransDirectory (".irdb",(REMOTEBUFFER
*)stat
,com
->adress
,STATUS_IRDBFILE
);
3348 case COMMAND_TRANSFILE
:
3350 ReadIRTransDirectory ("*.tra",(REMOTEBUFFER
*)stat
,com
->adress
,STATUS_TRANSLATIONFILE
);
3353 ReadIRTransDirectory (".tra",(REMOTEBUFFER
*)stat
,com
->adress
,STATUS_TRANSLATIONFILE
);
3356 case COMMAND_GETREMOTES
:
3357 GetRemoteDatabase ((REMOTEBUFFER
*)stat
,com
->adress
);
3359 case COMMAND_LISTBUS
:
3360 GetBusList ((REMOTEBUFFER
*)stat
,com
->adress
);
3362 case COMMAND_GETCOMMANDS
:
3363 res
= GetCommandDatabase ((COMMANDBUFFER
*)stat
,com
->remote
,com
->adress
);
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
);
3376 // Time with 1ms resolution
3378 unsigned int GetMsTime (void)
3381 return (GetTickCount ());
3386 gettimeofday (&tv
,0);
3388 return (tv
.tv_sec
* 1000 + tv
.tv_usec
);
3393 char shadow_buf
[256];
3395 int GetDeviceStatus (STATUSBUFFER
*buf
)
3399 if (status_changed
|| (time (0) - last_status_read
) >= status_cache_timeout
) {
3400 res
= GetBusInfoEx (remote_statusex
,0);
3402 PutNetworkStatus (res
,NULL
,buf
);
3407 last_status_read
= time (0);
3410 PutDeviceStatus ((NETWORKMODE
*)buf
);
3417 void compress_lcdbuffer (LCDCOMMAND
*lcd
,char *buf
,int bus
)
3426 byte LINEFEED
= 0x1f;
3431 if (bus
== 0xffff) bus
= 0;
3433 if ((IRDevices
[bus
].io
.advanced_lcd
& 2) || new_lcd_flag
) {
3438 ConvertLCDCharset ((byte
*)(lcd
->framebuffer
));
3440 else if (IRDevices
[bus
].version
[0] == 'D') ConvertLCDCharset ((byte
*)(lcd
->framebuffer
));
3447 if (count_difference (lcd
) <= 16) {
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
];
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);
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
)
3486 while (i
< lcd
->wid
* lcd
->hgt
) {
3487 if (shadow_buf
[i
] != lcd
->framebuffer
[i
]) diff
++;
3494 void compress_char (char ln
[],char src
,char tar
)
3505 while (ln
[i
] == src
) i
++;
3506 if ((i
- pos
) > 2) {
3509 tr
[pos
+1] = i
- pos
;
3511 strcpy (tr
+ pos
+ 2,st
);
3521 int GetHotcode (char rem
[],char com
[],byte data
[])
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
);
3537 memcpy (data
,ir
.data
,ir
.ir_length
);
3538 return (ir
.ir_length
);
3543 void ReformatHotcode (byte data
[],int len
)
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;
3557 data
[i
] -= (data
[i
] >> 4) + RAW_TOLERANCE
;
3564 void PutDeviceStatus (NETWORKMODE
*mode
)
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
)
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);
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
;
3661 stat
= (NETWORKSTATUS
*)buf
;
3663 stat
->statustype
= STATUS_MESSAGE
;
3666 stat
->statuslen
= 8;
3670 stat
->netstatus
= res
;
3671 stat
->statuslen
= sizeof (NETWORKSTATUS
);
3673 if (res
== ERR_TIMEOUT
) {
3674 stat
->statuslevel
= IRTIMEOUT
;
3675 sprintf (stat
->message
,"Timeout");
3679 if (res
== ERR_OPENASCII
) {
3680 stat
->statuslevel
= FATAL
;
3681 sprintf (stat
->message
,"Error opening Remote %s",msg
);
3685 if (res
== ERR_NOFILEOPEN
) {
3686 stat
->statuslevel
= FATAL
;
3687 sprintf (stat
->message
,"No Remote open");
3691 stat
->statuslevel
= IR
;
3694 strcpy (stat
->message
,msg
);
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
)
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
);
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
]);
3768 if (type
== STATUS_DEVICEMODE
) {
3769 nm
= (NETWORKMODE
*)pnt
;
3770 for (i
=0;i
<16;i
++) swap_int (&nm
->stat
[i
].send_mask
);
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
);
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
);
3794 if (type
== STATUS_FUNCTION
) {
3795 fb
= (FUNCTIONBUFFER
*)pnt
;
3796 swap_int (&fb
->functions
);
3797 swap_int (&fb
->serno
);
3802 int GetNetworkClient (SOCKET sockfd
)
3806 while (i
< CLIENT_COUNT
) {
3807 if ((sockinfo
[i
].type
== SELECT_SERVER
|| sockinfo
[i
].type
== SELECT_REOPEN
)
3808 && sockfd
== sockinfo
[i
].fd
) return (i
);
3814 int InitServerSocket (SOCKET
*sock
,SOCKET
*lirc
, SOCKET
*udp
,SOCKET
*web
)
3816 char msg
[256],hub
[50];
3817 struct sockaddr_in serv_addr
;
3822 struct sockaddr_un serv_addr_un
;
3827 WORD wVersionRequired
;
3829 wVersionRequired
= MAKEWORD(2,2);
3830 err
= WSAStartup(wVersionRequired
, &wsaData
);
3831 if (err
!= 0) exit(1);
3834 // ************************************************************* LIRC local Socket
3836 if (mode_flag
& NO_LIRC
) {
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
);
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
);
3868 chmod(LIRCD
,s
.st_mode
);
3869 chown(LIRCD
,s
.st_uid
,s
.st_gid
);
3872 listen(local_socket
,3);
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
) {
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
) {
3902 if (res
= ConfigSocket (web
,webport
)) return (ERR_BINDWEB
);
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
;
3919 serv_addr
.sin_addr
.s_addr
= INADDR_ANY
;
3920 serv_addr
.sin_port
= UDP_PORT
;
3922 serv_addr
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
3923 serv_addr
.sin_port
= htons (8765);
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
;
3934 OpenIRTransBroadcastSockets ();
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
);
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
));
3976 if (res
< 0) return (ERR_OPENSOCKET
);
3979 xAP_send
= socket (PF_INET
,SOCK_DGRAM
,0);
3980 if (xAP_send
< 0) return (ERR_OPENSOCKET
);
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 ();
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
;
4016 serv_addr
.sin_addr
.s_addr
= INADDR_ANY
;
4017 serv_addr
.sin_port
= port
;
4019 serv_addr
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
4020 serv_addr
.sin_port
= htons (port
);
4022 if (bind (*sock
,(struct sockaddr
*)&serv_addr
,sizeof (serv_addr
)) < 0) return (ERR_BINDSOCKET
);
4028 void process_udp_command (char *data
,int len
,struct sockaddr_in
*send_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
;
4039 res
= AnalyzeUDPString (data
,&netcom
,remote
,command
,ccf
,&netmask
,&bus
,&led
,&port
);
4041 log_print ("Illegal UDP Command\n", LOG_ERROR
);
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
);
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;
4057 res
= DBFindRemoteCommand (remote
,command
,&cmd_num
,NULL
);
4059 GetError (res
, txt
);
4061 case ERR_REMOTENOTFOUND
:
4062 sprintf (err
, txt
, remote
);
4064 case ERR_COMMANDNOTFOUND
:
4065 sprintf (err
, txt
, command
);
4071 log_print (err
, LOG_ERROR
);
4072 SendUDPAck ("ERR",send_adr
,port
);
4075 SendIR (cmd_num
,adr
);
4076 SendUDPAck ("OK",send_adr
,port
);
4080 memset (&client
,0,sizeof (client
));
4081 client
.fp
= ASCIIOpenRemote (remote
,&client
);
4083 sprintf (txt
,"Unable to open remote %s\n",remote
);
4084 log_print (txt
,LOG_DEBUG
);
4085 SendUDPAck ("ERR",send_adr
,port
);
4088 SendUDPAck ("READY",send_adr
,port
);
4089 res
= LearnIREx (&client
.ird
,(word
)'L',30000,0,0);
4092 sprintf (txt
,"Learn Error\n");
4093 log_print (txt
,LOG_DEBUG
);
4094 SendUDPAck ("ERR",send_adr
,port
);
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);
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
)
4124 ccf
[0] = remote
[0] = command
[0] = 0;
4131 if (!strncmp (st
,"sndccfr",7) || !strncmp (st
,"Sndccfr",7) || !strncmp (st
,"SNDCCFR",7)) {
4135 else if (!strncmp (st
,"sndccf",6) || !strncmp (st
,"Sndccf",6) || !strncmp (st
,"SNDCCF",6)) {
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)) {
4145 while (st
[i
] == ' ') i
++;
4147 while (st
[i
] && st
[i
] != ',') i
++;
4150 if (st
[p
] == 'p' || st
[p
] == 'P') *port
= atoi (st
+p
+1);
4153 else return ERR_UDPFORMAT
;
4155 while (st
[i
] == ' ') i
++;
4157 if (*netcom
== 4 || *netcom
== 5) {
4159 while (st
[i
] && st
[i
] != ',') i
++;
4167 while (st
[i
] && st
[i
] != ',') i
++;
4169 if (!st
[i
]) return ERR_UDPFORMAT
;
4171 strncpy (remote
,st
+p
,80);
4174 while (st
[i
] && st
[i
] != ',') i
++;
4178 strncpy (command
,st
+p
,20);
4184 while (st
[i
] && st
[i
] != ',' && st
[i
] != ' ') i
++;
4188 if (st
[p
] == 'l' || st
[p
] == 'L') {
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') {
4199 if (*bus
> 255) return ERR_UDPFORMAT
;
4202 else if (st
[p
] == 'm' || st
[p
] == 'M') {
4204 *netmask
= atoi (st
+p
);
4207 else if (st
[p
] == 'p' || st
[p
] == 'P') {
4209 *port
= atoi (st
+p
);
4212 else return ERR_UDPFORMAT
;