3 Copyright (C) 2006 Kimmo Leppälä (kimmo.leppala@gmail.com)
4 Modified 2009 by Sami Mäki (kasmra@xob.kapsi.fi)
6 This is based on the original ir-send program by Christoph Bartelmus
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "backend_internal_lirc.h"
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
44 #include <netinet/in.h>
46 #define PACKET_SIZE 256
51 char *progname
= "internal_lirc backend";
62 int input_timeout(int filedes
, unsigned int seconds
)
65 struct timeval timeout
;
67 /* Initialize the file descriptor set. */
69 FD_SET (filedes
, &set
);
71 /* Initialize the timeout data structure. */
72 timeout
.tv_sec
= seconds
;
75 /* select returns 0 if timeout, 1 if input available, -1 if error. */
76 return select(FD_SETSIZE
, &set
, NULL
, NULL
, &timeout
);
79 IrrecoBackendStatus
read_string(
80 IrrecoInternalLircBackend
*internal_lirc_backend
,
83 static char buffer
[PACKET_SIZE
+ 1] = "";
90 memmove(buffer
, buffer
+ ptr
, strlen(buffer
+ ptr
) + 1);
92 end
= strchr(buffer
, '\n');
98 if (PACKET_SIZE
<= ptr
) {
101 IRRECO_RETURN_INT(internal_lirc_backend_error(
102 internal_lirc_backend
,
103 INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
));
106 if (input_timeout(internal_lirc_backend
->socket
, 3) < 1) {
109 IRRECO_RETURN_INT(internal_lirc_backend_error(
110 internal_lirc_backend
,
111 INTERNAL_LIRC_BACKEND_ERR_TIMEOUT
));;
113 ret
= read(internal_lirc_backend
->socket
, buffer
+ ptr
,
117 buffer
[ptr
+ ret
] = 0;
118 ptr
= strlen(buffer
);
119 end
= strchr(buffer
, '\n');
123 ptr
= strlen(buffer
) + 1;
124 IRRECO_DEBUG("Input buffer \"%s\".\n", buffer
);
126 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
139 IrrecoBackendStatus
send_packet(IrrecoInternalLircBackend
* internal_lirc_backend
,
141 InternalLircBackendResponseHandler handler
)
144 const char *string
, *data
;
146 enum packet_state state
;
148 unsigned long data_n
= 0;
149 IrrecoBackendStatus read_string_status
;
152 IRRECO_PRINTF("Sending packet: \"%s\".\n", packet
);
154 todo
= strlen(packet
);
157 done
= write(internal_lirc_backend
->socket
, (void *) data
, todo
);
159 IRRECO_RETURN_INT(internal_lirc_backend_error(
160 internal_lirc_backend
,
161 INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_SEND_PACKET
,
174 read_string_status
= read_string(internal_lirc_backend
,
176 if (read_string_status
!= IRRECO_BACKEND_OK
) {
177 IRRECO_RETURN_INT(read_string_status
);
182 if (strcasecmp(string
, "BEGIN") != 0) {
189 if (strncasecmp(string
, packet
, strlen(string
)) != 0 ||
190 strlen(string
) + 1 != strlen(packet
)) {
198 if (strcasecmp(string
, "SUCCESS") == 0) {
200 } else if (strcasecmp(string
, "END") == 0) {
202 goto check_status_code
;
203 } else if (strcasecmp(string
, "ERROR") == 0) {
204 status
= INTERNAL_LIRC_BACKEND_ERR_COMMAND_FAILED
;
206 status
= INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
;
207 goto check_status_code
;
213 if (strcasecmp(string
, "END") == 0) {
214 goto check_status_code
;
215 } else if (strcasecmp(string
, "DATA") == 0) {
219 status
= INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
;
220 goto check_status_code
;
224 data_n
= strtoul(string
, &endptr
, 0);
225 if (!*string
|| *endptr
) {
226 status
= INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
;
227 goto check_status_code
;
237 IRRECO_DEBUG("Response data: \"%s\".\n", string
);
238 if (handler
!= NULL
) handler(internal_lirc_backend
, string
);
240 if (n
== data_n
) state
= P_END
;
244 if (strcasecmp(string
, "END") == 0) {
245 goto check_status_code
;
247 status
= INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
;
248 goto check_status_code
;
255 case INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
:
256 IRRECO_RETURN_INT(internal_lirc_backend_error(
257 internal_lirc_backend
,
258 INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
));
260 case INTERNAL_LIRC_BACKEND_ERR_COMMAND_FAILED
:
261 IRRECO_RETURN_INT(internal_lirc_backend_error(
262 internal_lirc_backend
,
263 INTERNAL_LIRC_BACKEND_ERR_COMMAND_FAILED
, packet
));
265 case IRRECO_BACKEND_OK
:
266 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
269 IRRECO_ERROR("Weird return code \"%i\"\n", status
);
270 IRRECO_RETURN_INT(status
);
274 static IrrecoBackendStatus
internal_lirc_backend_create_device(
275 gpointer instance_context
,
279 /* irreco_info_dlg(GTK_WINDOW(parent),
280 "Feature not implemented."); */
281 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
284 static gboolean
internal_lirc_backend_is_device_editable(
285 gpointer instance_context
,
286 const gchar
*device_name
,
287 gpointer device_contex
)
289 gboolean retval
= TRUE
;
291 IRRECO_RETURN_BOOL(retval
);
294 static IrrecoBackendStatus
internal_lirc_backend_edit_device(
295 gpointer instance_context
,
296 const gchar
*device_name
,
297 gpointer device_contex
,
301 irreco_info_dlg(GTK_WINDOW(parent
),
302 "Feature not implemented.");
303 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
306 static IrrecoBackendStatus
internal_lirc_delete_device(
307 gpointer instance_context
,
308 const char *device_name
,
309 gpointer device_contex
,
312 IrrecoBackendStatus status
= IRRECO_BACKEND_OK
;
313 IrrecoInternalLircBackend
*internal_lirc_backend
= instance_context
;
314 gchar
*delete_cmd
= NULL
;
317 delete_cmd
= g_strdup_printf(
318 "%s%s\"$//g' %s > /tmp/lircd.conf.temporary\
319 && cp /tmp/lircd.conf.temporary %s;\
320 rm /tmp/lircd.conf.temporary",
321 "sed -e \'s/^include.*", device_name
,
322 INTERNAL_LIRC_LIRCD_CONF_PATH
,
323 INTERNAL_LIRC_LIRCD_CONF_PATH
);
328 case IRRECO_BACKEND_OK
:
329 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
331 case INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_DELETE_DEVICE
:
333 INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_DELETE_DEVICE
);
336 IRRECO_ERROR("Weird return code \"%i\"\n", status
);
337 IRRECO_RETURN_INT(status
);
341 /* TODO Just testing FIXME */
343 g_print("errmsg: %s\n", internal_lirc_backend
->error_msg
->str
);
345 INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_DELETE_DEVICE
);
347 else IRRECO_RETURN_INT(status
);
351 IrrecoBackendStatus
internal_lirc_export_conf(gpointer instance_context
,
352 const char *device_name
,
353 IrrecoBackendFileContainer
**file_container
)
355 IrrecoBackendStatus status
= IRRECO_BACKEND_OK
;
356 gchar
*file_data
= NULL
;
357 gboolean success
= TRUE
;
358 GString
*file_name
= g_string_new("");
359 GString
*file_path
= g_string_new(INTERNAL_LIRC_REMOTES_DIR
);
362 g_string_append_printf(file_name
, "%s", device_name
);
363 g_string_append_printf(file_path
, "/%s", file_name
->str
);
365 success
= g_file_get_contents(file_path
->str
, &file_data
, NULL
, NULL
);
366 if (success
== FALSE
) {
367 status
= INTERNAL_LIRC_BACKEND_ERR_FILE_OPEN_FAILED
;
371 *file_container
= irreco_backend_file_container_new();
372 irreco_backend_file_container_set(*file_container
,
373 "Internal Lirc", /*backend*/
375 NULL
, /*manufacturer*/
376 device_name
, /*model*/
377 file_name
->str
, /*name*/
382 g_string_free(file_name
, TRUE
);
383 g_string_free(file_path
, TRUE
);
385 IRRECO_RETURN_ENUM(status
);
388 IrrecoBackendStatus
internal_lirc_import_conf(gpointer instance_context
,
389 IrrecoBackendFileContainer
*file_container
)
393 GString
*file_path
= g_string_new(INTERNAL_LIRC_REMOTES_DIR
);
394 gchar
*sys_cmd
= NULL
;
396 length
= strlen(file_container
->data
->str
);
398 g_string_append_printf(file_path
, "/%s", file_container
->name
->str
);
400 /* Create directory/directories for Lirc devices, if needed. */
401 if(irreco_is_dir(INTERNAL_LIRC_BASE_DIR
) == FALSE
) {
402 if (g_mkdir(INTERNAL_LIRC_BASE_DIR
, 0700) != 0) {
404 INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_CREATE_BASE_DIR
);
408 if(irreco_is_dir(INTERNAL_LIRC_REMOTES_DIR
) == FALSE
) {
409 if (g_mkdir(INTERNAL_LIRC_REMOTES_DIR
, 0700) != 0) {
411 INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_CREATE_DEVICE_DIR
);
415 /* irreco_write_file from irreco_util.h */
416 success
= irreco_write_file(file_path
->str
,
417 file_container
->data
->str
, length
);
419 /* Echo include cmd to lircd.conf */
420 sys_cmd
= g_strdup_printf("%s '%s \"%s\"' >> %s", "echo", "include",
421 file_path
->str
, INTERNAL_LIRC_LIRCD_CONF_PATH
);
425 g_string_free(file_path
, TRUE
);
430 IRRECO_RETURN_ENUM(INTERNAL_LIRC_BACKEND_ERR_CONFIG_WRITE_FAILED
);
433 IRRECO_RETURN_ENUM(IRRECO_BACKEND_OK
);
436 IrrecoBackendStatus
internal_lirc_check_conf(
437 gpointer instance_context
,
438 IrrecoBackendFileContainer
*file_container
,
439 gboolean
*configuration
)
441 GString
*file_path
= g_string_new(INTERNAL_LIRC_REMOTES_DIR
);
443 g_string_append_printf(file_path
, "/%s", file_container
->name
->str
);
445 /* irreco_file_exists from irreco_util.h */
446 *configuration
= irreco_file_exists(file_path
->str
);
448 g_string_free(file_path
, TRUE
);
450 IRRECO_RETURN_ENUM(IRRECO_BACKEND_OK
);
453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
454 /* IRRECO PLUGIN API. */
455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
457 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
458 /* Construction & Destruction. */
459 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
461 IrrecoBackendFunctionTable internal_lirc_backend_function_table
= {
462 IRRECO_BACKEND_API_VERSION
, /* backend_api_version */
463 IRRECO_BACKEND_EDITABLE_DEVICES
|
464 IRRECO_BACKEND_CONFIGURATION_EXPORT
|
465 IRRECO_BACKEND_MULTI_DEVICE_SUPPORT
467 "Internal Lirc", /* name */
469 internal_lirc_backend_get_error_msg
, /* get_error_msg */
470 internal_lirc_backend_create
, /* create */
471 internal_lirc_backend_destroy
, /* destroy */
472 internal_lirc_backend_read_from_conf
, /* from_conf */
473 internal_lirc_backend_save_to_conf
, /* to_conf */
474 internal_lirc_backend_get_devices
, /* get_devices */
475 internal_lirc_backend_get_commands
, /* get_commands */
476 internal_lirc_backend_send_command
, /* send_command */
477 internal_lirc_backend_configure
, /* configure */
478 internal_lirc_backend_get_description
, /* get_description */
480 internal_lirc_backend_create_device
, /* create_device, optional */
481 internal_lirc_backend_is_device_editable
,/* is_device_editable, optional */
482 internal_lirc_backend_edit_device
, /* edit_device, optional */
483 internal_lirc_delete_device
, /* delete_device, optional */
485 internal_lirc_export_conf
, /* export_conf, optional */
486 internal_lirc_import_conf
, /* import_conf, optional */
487 internal_lirc_check_conf
, /* check_conf, optional */
492 IrrecoBackendFunctionTable
*get_irreco_backend_function_table()
495 IRRECO_RETURN_PTR(&internal_lirc_backend_function_table
);
498 void* internal_lirc_backend_create()
500 IrrecoInternalLircBackend
* internal_lirc_backend
;
503 internal_lirc_backend
= g_slice_new0(IrrecoInternalLircBackend
);
504 internal_lirc_backend
->host
= g_string_new("localhost");
505 internal_lirc_backend
->port
= 8765;
506 internal_lirc_backend
->socket
= -1;
507 internal_lirc_backend
->error_msg
= g_string_new(NULL
);
508 IRRECO_RETURN_PTR(internal_lirc_backend
);
511 void internal_lirc_backend_destroy(gpointer instance_context
, gboolean permanently
)
513 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
516 g_string_free(internal_lirc_backend
->host
, TRUE
);
517 g_string_free(internal_lirc_backend
->error_msg
, TRUE
);
518 g_slice_free(IrrecoInternalLircBackend
, internal_lirc_backend
);
525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
526 /* Error handling. */
527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
529 const gchar
*internal_lirc_backend_get_error_msg(gpointer instance_context
,
530 IrrecoBackendStatus code
)
532 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
534 IRRECO_RETURN_PTR(internal_lirc_backend
->error_msg
->str
);
537 gint
internal_lirc_backend_error(IrrecoInternalLircBackend
538 *internal_lirc_backend
,
539 IrrecoInternalLircBackendError code
, ...)
546 internal_lirc_backend_disconnect(internal_lirc_backend
);
548 /* Select message format. */
550 case INTERNAL_LIRC_BACKEND_ERR_CANT_OPEN_SOCKET
:
551 format
= _("Can not open socket.");
554 case INTERNAL_LIRC_BACKEND_ERR_CANT_CONNECT
:
555 format
= _("Can not connect to internal LIRC server.");
558 case INTERNAL_LIRC_BACKEND_ERR_CANT_RESOLVE_HOST
:
559 format
= _("Can not resolve hostname \"%s\".");
562 case INTERNAL_LIRC_BACKEND_ERR_CONFIG_WRITE_FAILED
:
563 format
= _("Failed to save configuration to file.");
566 case INTERNAL_LIRC_BACKEND_ERR_CONFIG_READ_FAILED
:
567 format
= _("Failed to read configuration from file.");
570 case INTERNAL_LIRC_BACKEND_ERR_BAD_PACKET
:
571 format
= _("Bad return packet");
574 case INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_SEND_PACKET
:
575 format
= _("Could not send packet \"%s\".");
578 case INTERNAL_LIRC_BACKEND_ERR_COMMAND_FAILED
:
579 format
= _("Command \"%s\" failed.");
582 case INTERNAL_LIRC_BACKEND_ERR_TIMEOUT
:
583 format
= _("Timeout while waiting for the server to respond.");
586 case INTERNAL_LIRC_BACKEND_ERR_FILE_OPEN_FAILED
:
587 format
= _("Failed to open file.");
590 case INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_CREATE_DEVICE_DIR
:
591 format
= _("Failed to create device directory.");
594 case INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_CREATE_BASE_DIR
:
595 format
= _("Failed to create base directory.");
598 case INTERNAL_LIRC_BACKEND_ERR_COULD_NOT_DELETE_DEVICE
:
599 format
= _("Failed to delete device.");
603 g_string_set_size(internal_lirc_backend
->error_msg
, 0);
604 g_string_append_printf(internal_lirc_backend
->error_msg
,
605 _("Unknown error code \"%i\"."), code
);
606 IRRECO_PRINTF("Error: %s\n",
607 internal_lirc_backend
->error_msg
->str
);
608 IRRECO_RETURN_INT(code
);
612 va_start(args
, code
);
613 g_vasprintf(&message
, format
, args
);
616 g_string_set_size(internal_lirc_backend
->error_msg
, 0);
617 g_string_append(internal_lirc_backend
->error_msg
, message
);
620 /* Print error and return code. */
621 IRRECO_PRINTF("Error: %s\n", internal_lirc_backend
->error_msg
->str
);
622 IRRECO_RETURN_INT(code
);
627 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
628 /* Configuration writing and reading. */
629 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
631 IrrecoBackendStatus
internal_lirc_backend_read_from_conf(
632 gpointer instance_context
, const gchar
* config_file
)
638 IrrecoKeyFile
*keyfile
= NULL
;
639 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
642 IRRECO_DEBUG("Reading config file \"%s\".\n", config_file
);
643 dir
= g_path_get_dirname(config_file
);
644 keyfile
= irreco_keyfile_create(dir
, config_file
, "internal_lirc");
646 /* Attempt to read values from keyfile. */
648 || irreco_keyfile_get_int(keyfile
, "port", &port
) == FALSE
649 || irreco_keyfile_get_str(keyfile
, "host", &host
) == FALSE
) {
650 IRRECO_PRINTF("Config read failed\n");
651 rvalue
= internal_lirc_backend_error(
652 internal_lirc_backend
,
653 INTERNAL_LIRC_BACKEND_ERR_CONFIG_READ_FAILED
);
655 /* Save values to instace if read succeeded. */
657 IRRECO_PRINTF("Host \"%s\"\n", host
);
658 IRRECO_PRINTF("Port \"%i\"\n", port
);
660 internal_lirc_backend
->port
= port
;
661 g_string_set_size(internal_lirc_backend
->host
, 0);
662 g_string_append(internal_lirc_backend
->host
, host
);
663 rvalue
= IRRECO_BACKEND_OK
;
666 /* Creanup, and return status code. */
667 irreco_keyfile_destroy(keyfile
);
670 IRRECO_RETURN_INT(rvalue
);
675 IrrecoBackendStatus
internal_lirc_backend_save_to_conf(
676 gpointer instance_context
, const gchar
* config_file
)
680 gchar group
[] = "internal_lirc";
681 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
684 IRRECO_DEBUG("Saving config file \"%s\".\n", config_file
);
686 keyfile
= g_key_file_new();
687 g_key_file_set_string(keyfile
, group
, "host",
688 internal_lirc_backend
->host
->str
);
689 g_key_file_set_integer(keyfile
, group
, "port",
690 internal_lirc_backend
->port
);
692 success
= irreco_write_keyfile(keyfile
, config_file
);
693 g_key_file_free(keyfile
);
695 if (success
== TRUE
) {
696 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
698 IRRECO_RETURN_INT(internal_lirc_backend_error(
699 internal_lirc_backend
,
700 INTERNAL_LIRC_BACKEND_ERR_CONFIG_WRITE_FAILED
));
705 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
706 /* Connection handling. */
707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
709 int internal_lirc_backend_connect(IrrecoInternalLircBackend
710 *internal_lirc_backend
)
712 struct hostent
*host
;
713 struct sockaddr_in addr
;
716 IRRECO_PRINTF("Connecting to internal LIRC server.\n");
717 IRRECO_PRINTF("Hostname: \"%s\".\n", internal_lirc_backend
->host
->str
);
718 IRRECO_PRINTF("Port: \"%i\".\n", internal_lirc_backend
->port
);
721 memset( &addr
, '\0', sizeof(addr
));
722 if ((host
= gethostbyname(internal_lirc_backend
->host
->str
)) == NULL
) {
723 IRRECO_RETURN_INT(internal_lirc_backend_error(
724 internal_lirc_backend
,
725 INTERNAL_LIRC_BACKEND_ERR_CANT_RESOLVE_HOST
,
726 internal_lirc_backend
->host
->str
));
730 addr
.sin_family
= AF_INET
;
731 addr
.sin_port
= htons(internal_lirc_backend
->port
);
732 memcpy((gpointer
) &addr
.sin_addr
, (gpointer
) host
->h_addr_list
[0],
733 (size_t) host
->h_length
);
734 if ((internal_lirc_backend
->socket
= socket(
735 PF_INET
, SOCK_STREAM
, 0)) == -1) {
736 IRRECO_RETURN_INT(internal_lirc_backend_error(
737 internal_lirc_backend
,
738 INTERNAL_LIRC_BACKEND_ERR_CANT_OPEN_SOCKET
));
741 /* Connect socket. */
742 if (connect(internal_lirc_backend
->socket
, (struct sockaddr
*) &addr
,
743 sizeof(addr
)) == -1) {
744 IRRECO_RETURN_INT(internal_lirc_backend_error(
745 internal_lirc_backend
,
746 INTERNAL_LIRC_BACKEND_ERR_CANT_OPEN_SOCKET
));
749 IRRECO_PRINTF("Connected to internal LIRC server.\n");
750 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
753 void internal_lirc_backend_disconnect(IrrecoInternalLircBackend
754 *internal_lirc_backend
)
757 if (internal_lirc_backend
->socket
!= -1) {
758 close(internal_lirc_backend
->socket
);
759 internal_lirc_backend
->socket
= -1;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
770 IrrecoBackendStatus
internal_lirc_backend_get_devices(gpointer instance_context
,
771 IrrecoGetDeviceCallback callback
)
774 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
775 gchar
*sys_cmd
= NULL
;
776 gchar
*clean_cmd
= NULL
;
777 GDir
*lirc_device_dir
= NULL
;
778 const gchar
*device_file
= "";
781 system("cat /dev/null > /home/user/.irreco/lircd.conf");
783 /* Scan INTERNAL_LIRC_REMOTES_DIR for available devices and
784 * echo them into lircd.conf */
785 lirc_device_dir
= g_dir_open(
786 INTERNAL_LIRC_REMOTES_DIR
,
788 while(device_file
!= NULL
) {
789 device_file
= g_dir_read_name(lirc_device_dir
);
790 sys_cmd
= g_strdup_printf(
791 "echo 'include \"%s/%s\"' >> %s",
792 INTERNAL_LIRC_REMOTES_DIR
,
794 INTERNAL_LIRC_LIRCD_CONF_PATH
);
797 g_dir_close(lirc_device_dir
);
799 /* Remove (null) device from lircd.conf */
800 clean_cmd
= g_strdup_printf(
801 "%s//g' %s > /tmp/lircd.conf.temporary\
802 && cp /tmp/lircd.conf.temporary %s;\
803 rm /tmp/lircd.conf.temporary",
804 "sed -e \'s/.*(null)\"$",
805 INTERNAL_LIRC_LIRCD_CONF_PATH
,
806 INTERNAL_LIRC_LIRCD_CONF_PATH
);
813 system("sudo /etc/init.d/lirc reload");
815 rvalue
= internal_lirc_backend_connect(internal_lirc_backend
);
816 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
818 internal_lirc_backend
->dev_callback
= callback
;
819 rvalue
= send_packet(internal_lirc_backend
, "LIST\n",
820 internal_lirc_backend_get_device_responce
);
821 internal_lirc_backend
->dev_callback
= NULL
;
822 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
824 internal_lirc_backend_disconnect(internal_lirc_backend
);
825 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
827 void internal_lirc_backend_get_device_responce(IrrecoInternalLircBackend
828 *internal_lirc_backend
,
829 const gchar
* response
)
832 IRRECO_PRINTF("Device: \"%s\"\n", response
);
833 internal_lirc_backend
->dev_callback(response
, NULL
);
837 IrrecoBackendStatus
internal_lirc_backend_get_commands(gpointer instance_context
,
838 const gchar
* device_name
,
839 gpointer device_contex
,
840 IrrecoGetCommandCallback callback
)
844 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
847 rvalue
= internal_lirc_backend_connect(internal_lirc_backend
);
848 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
850 internal_lirc_backend
->cmd_callback
= callback
;
851 packet
= g_string_new(NULL
);
852 g_string_append_printf(packet
, "LIST %s\n", device_name
);
853 rvalue
= send_packet(internal_lirc_backend
, packet
->str
,
854 internal_lirc_backend_get_command_responce
);
855 g_string_free(packet
, TRUE
);
856 internal_lirc_backend
->cmd_callback
= NULL
;
857 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
859 internal_lirc_backend_disconnect(internal_lirc_backend
);
860 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
862 void internal_lirc_backend_get_command_responce(IrrecoInternalLircBackend
863 *internal_lirc_backend
,
864 const gchar
* response
)
869 IRRECO_PRINTF("Command: \"%s\"\n", response
);
870 if ((pos
= irreco_char_pos(response
, ' ')) == -1) {
871 internal_lirc_backend
->cmd_callback(response
, NULL
);
873 internal_lirc_backend
->cmd_callback(response
+ pos
+ 1, NULL
);
878 gchar
*internal_lirc_backend_get_description(gpointer instance_context
)
880 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
882 IRRECO_RETURN_PTR(g_strdup(internal_lirc_backend
->host
->str
));
886 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
887 /* Command sending. */
888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
890 IrrecoBackendStatus
internal_lirc_backend_send_command(gpointer instance_context
,
891 const gchar
* device_name
,
892 gpointer device_contex
,
893 const gchar
* command_name
,
894 gpointer command_contex
)
898 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
901 rvalue
= internal_lirc_backend_connect(internal_lirc_backend
);
902 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
904 packet
= g_string_new(NULL
);
905 g_string_append_printf(packet
, "SEND_ONCE %s %s\n",
906 device_name
, command_name
);
907 rvalue
= send_packet(internal_lirc_backend
, packet
->str
, NULL
);
908 g_string_free(packet
, TRUE
);
909 if (rvalue
) IRRECO_RETURN_INT(rvalue
);
911 internal_lirc_backend_disconnect(internal_lirc_backend
);
912 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);
917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
918 /* Configuration dialog. */
919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
922 * Create label, align it, and insert it into a table.
924 void internal_lirc_backend_dlg_insert_label(GtkWidget
*table
,
933 label
= gtk_label_new(str
);
934 gtk_misc_set_alignment(GTK_MISC(label
), 0, 0.5);
935 gtk_table_attach(GTK_TABLE(table
), label
, l
, r
, t
, b
,
936 GTK_FILL
, GTK_EXPAND
| GTK_FILL
, 0, 0);
940 IrrecoBackendStatus
internal_lirc_backend_configure(gpointer instance_context
,
943 IrrecoInternalLircBackend
* internal_lirc_backend
= instance_context
;
945 GString
*port_string
;
948 GtkWidget
*host_entry
;
949 GtkWidget
*port_entry
;
952 /* Create objects. */
953 dialog
= gtk_dialog_new_with_buttons(
954 _("Internal LIRC server configuration"), parent
,
955 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
|
956 GTK_DIALOG_NO_SEPARATOR
,
957 GTK_STOCK_CANCEL
, GTK_RESPONSE_REJECT
,
959 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
,
961 table
= gtk_table_new(2, 2, FALSE
);
962 host_entry
= gtk_entry_new();
963 port_entry
= gtk_entry_new();
966 gtk_entry_set_text(GTK_ENTRY(host_entry
),
967 internal_lirc_backend
->host
->str
);
968 port_string
= g_string_new(NULL
);
969 g_string_append_printf(port_string
, "%i", internal_lirc_backend
->port
);
970 gtk_entry_set_text(GTK_ENTRY(port_entry
), port_string
->str
);
971 g_string_free(port_string
, TRUE
);
974 internal_lirc_backend_dlg_insert_label(table
, _("Hostname"), 0, 1, 0, 1);
975 gtk_table_attach_defaults(GTK_TABLE(table
), host_entry
, 1, 2, 0, 1);
976 internal_lirc_backend_dlg_insert_label(table
, _("Port"), 0, 1, 1, 2);
977 gtk_table_attach_defaults(GTK_TABLE(table
), port_entry
, 1, 2, 1, 2);
978 gtk_table_set_row_spacings(GTK_TABLE(table
), 5);
979 gtk_table_set_col_spacings(GTK_TABLE(table
), 5);
980 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), table
);
981 gtk_widget_show_all(dialog
);
983 while (loop
== TRUE
) {
984 switch (gtk_dialog_run(GTK_DIALOG(dialog
))) {
985 case GTK_RESPONSE_REJECT
:
989 case GTK_RESPONSE_ACCEPT
:
992 port
= strtol(gtk_entry_get_text(GTK_ENTRY(
993 port_entry
)), NULL
, 10);
994 if (port
< 1 || port
> 65535) {
995 irreco_error_dlg(GTK_WINDOW(dialog
),
996 _("Port number must be "
997 "in range 1 - 65535"));
1001 internal_lirc_backend
->port
= port
;
1002 g_string_set_size(internal_lirc_backend
->host
, 0);
1003 g_string_append(internal_lirc_backend
->host
,
1005 GTK_ENTRY(host_entry
)));
1012 gtk_widget_destroy(dialog
);
1013 IRRECO_RETURN_INT(IRRECO_BACKEND_OK
);