1 /*****************************************************************************
2 * comm.c: Handles the communication socket (linux-dvb only)
3 *****************************************************************************
4 * Copyright (C) 2008 VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software. It comes without any warranty, to
10 * the extent permitted by applicable law. You can redistribute it
11 * and/or modify it under the terms of the Do What The Fuck You Want
12 * To Public License, Version 2, as published by Sam Hocevar. See
13 * http://sam.zoy.org/wtfpl/COPYING for more details.
14 *****************************************************************************/
22 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
34 /*****************************************************************************
36 *****************************************************************************/
39 /*****************************************************************************
41 *****************************************************************************/
42 void comm_Open( void )
45 struct sockaddr_un sun_server
;
47 if ( (i_comm_fd
= socket( AF_UNIX
, SOCK_DGRAM
, 0 )) == -1 )
49 msg_Err( NULL
, "cannot create comm socket (%s)", strerror(errno
) );
53 setsockopt( i_comm_fd
, SOL_SOCKET
, SO_RCVBUF
, &i_size
, sizeof(i_size
) );
55 memset( &sun_server
, 0, sizeof(sun_server
) );
56 sun_server
.sun_family
= AF_UNIX
;
57 strncpy( sun_server
.sun_path
, psz_srv_socket
, sizeof(sun_server
.sun_path
) );
58 sun_server
.sun_path
[sizeof(sun_server
.sun_path
) - 1] = '\0';
60 if ( bind( i_comm_fd
, (struct sockaddr
*)&sun_server
,
61 SUN_LEN(&sun_server
) ) < 0 )
63 msg_Err( NULL
, "cannot bind comm socket (%s)", strerror(errno
) );
70 /*****************************************************************************
72 *****************************************************************************/
73 void comm_Read( void )
75 struct sockaddr_un sun_client
;
76 socklen_t sun_length
= sizeof(sun_client
);
77 ssize_t i_size
, i_answer_size
= 0;
78 uint8_t p_buffer
[COMM_BUFFER_SIZE
], p_answer
[COMM_BUFFER_SIZE
];
79 uint8_t i_command
, i_answer
;
81 i_size
= recvfrom( i_comm_fd
, p_buffer
, COMM_BUFFER_SIZE
, 0,
82 (struct sockaddr
*)&sun_client
, &sun_length
);
83 if ( i_size
< COMM_HEADER_SIZE
)
85 msg_Err( NULL
, "cannot read comm socket (%d:%s)\n", i_size
,
89 if ( sun_length
== 0 || sun_length
> sizeof(sun_client
) )
91 msg_Err( NULL
, "anonymous packet from comm socket\n" );
95 if ( p_buffer
[0] != COMM_HEADER_MAGIC
)
97 msg_Err( NULL
, "wrong protocol version 0x%x", p_buffer
[0] );
101 i_command
= p_buffer
[1];
111 case CMD_FRONTEND_STATUS
:
112 i_answer
= dvb_FrontendStatus( p_answer
+ COMM_HEADER_SIZE
,
117 i_answer
= en50221_StatusMMI( p_answer
+ COMM_HEADER_SIZE
,
121 case CMD_MMI_SLOT_STATUS
:
122 i_answer
= en50221_StatusMMISlot( p_buffer
+ COMM_HEADER_SIZE
,
123 i_size
- COMM_HEADER_SIZE
,
124 p_answer
+ COMM_HEADER_SIZE
,
129 i_answer
= en50221_OpenMMI( p_buffer
+ COMM_HEADER_SIZE
,
130 i_size
- COMM_HEADER_SIZE
);
134 i_answer
= en50221_CloseMMI( p_buffer
+ COMM_HEADER_SIZE
,
135 i_size
- COMM_HEADER_SIZE
);
139 i_answer
= en50221_GetMMIObject( p_buffer
+ COMM_HEADER_SIZE
,
140 i_size
- COMM_HEADER_SIZE
,
141 p_answer
+ COMM_HEADER_SIZE
,
146 i_answer
= en50221_SendMMIObject( p_buffer
+ COMM_HEADER_SIZE
,
147 i_size
- COMM_HEADER_SIZE
);
151 msg_Err( NULL
, "shutdown via comm" );
153 /* this is a bit violent, but hey, closing everything cleanly
154 * would do approximately the same */
157 msg_Err( NULL
, "wrong command %u", i_command
);
163 p_answer
[0] = COMM_HEADER_MAGIC
;
164 p_answer
[1] = i_answer
;
167 msg_Dbg( NULL
, "answering %d to %d with size %d", i_answer
, i_command
,
170 if ( sendto( i_comm_fd
, p_answer
, i_answer_size
+ COMM_HEADER_SIZE
, 0,
171 (struct sockaddr
*)&sun_client
, sun_length
) < 0 )
172 msg_Err( NULL
, "cannot send comm socket (%s)", strerror(errno
) );