summaryrefslogtreecommitdiff
path: root/xine_frontend_vdrdiscovery.c
diff options
context:
space:
mode:
authorphintuka <phintuka>2006-06-03 10:04:49 +0000
committerphintuka <phintuka>2006-06-03 10:04:49 +0000
commit0e345486181ef82b681dd6047f3b6ccb44c77146 (patch)
treea5401c7f97ab047a0afa890e6806d8537564102a /xine_frontend_vdrdiscovery.c
parent321eb114c9fe9abd954ce4270595d53df6cccbae (diff)
downloadxineliboutput-0e345486181ef82b681dd6047f3b6ccb44c77146.tar.gz
xineliboutput-0e345486181ef82b681dd6047f3b6ccb44c77146.tar.bz2
Initial importxineliboutput-0_99rc4
Diffstat (limited to 'xine_frontend_vdrdiscovery.c')
-rw-r--r--xine_frontend_vdrdiscovery.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/xine_frontend_vdrdiscovery.c b/xine_frontend_vdrdiscovery.c
new file mode 100644
index 00000000..fd0637ff
--- /dev/null
+++ b/xine_frontend_vdrdiscovery.c
@@ -0,0 +1,115 @@
+/*
+ * xine_frontend_vdrdiscovery.c
+ *
+ * Try to found VDR with xineliboutput server from (local) network.
+ *
+ * See the main source file 'xineliboutput.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: xine_frontend_vdrdiscovery.c,v 1.1 2006-06-03 10:01:18 phintuka Exp $
+ *
+ */
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "xine_input_vdr_net.h" /* default ports */
+
+static int search_vdr_server(int *port, char *address)
+{
+ struct sockaddr_in sin;
+ int fd_broadcast = -1;
+ int dummy = 1, trycount = 0;
+ struct pollfd pfd;
+ char pktbuf[1024];
+
+ *port = DEFAULT_VDR_PORT;
+ strcpy(address, "vdr");
+
+ if ((fd_broadcast = socket(PF_INET, SOCK_DGRAM, 0/*IPPROTO_TCP*/)) < 0) {
+ LOGERR("fd_broadcast = socket() failed");
+ } else {
+
+ if(setsockopt(fd_broadcast, SOL_SOCKET, SO_BROADCAST,
+ &dummy, sizeof(int)) < 0)
+ LOGERR("setsockopt(SO_BROADCAST) failed");
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(DISCOVERY_PORT);
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(fd_broadcast, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ LOGERR("Can't bind fd_broadcast to %d", DISCOVERY_PORT);
+ } else {
+ char *test = "VDR xineliboutput DISCOVERY 1.0\r\n"
+ "Client: 192.168.1.21:37890\r\n"
+ "\r\n";
+ int testlen = strlen(test);
+retry:
+ sin.sin_addr.s_addr = INADDR_BROADCAST;
+ if(testlen != sendto(fd_broadcast, test, testlen, 0,
+ (struct sockaddr *)&sin, sizeof(sin))) {
+ LOGERR("UDP broadcast send failed (discovery)");
+ } else {
+
+ while(1) {
+ int err;
+ pfd.fd = fd_broadcast;
+ pfd.events = POLLIN;
+
+ errno=0;
+ while(1==(err=poll(&pfd, 1, 500))) {
+ struct sockaddr_in from;
+ socklen_t fromlen = sizeof(from);
+ memset(&from, 0, sizeof(from));
+ memset(pktbuf, 0, sizeof(pktbuf));
+
+ errno=0;
+ if((err=recvfrom(fd_broadcast, pktbuf, 1023, 0,
+ (struct sockaddr *)&from, &fromlen)) > 0) {
+ char *mystring = "VDR xineliboutput DISCOVERY 1.0\r\n"
+ "Server port: ";
+ uint32_t tmp = ntohl(from.sin_addr.s_addr);
+
+ pktbuf[err] = 0;
+ LOGDBG("Reveived broadcast: %d bytes from %d.%d.%d.%d\n %s",
+ err,
+ ((tmp>>24)&0xff), ((tmp>>16)&0xff),
+ ((tmp>>8)&0xff), ((tmp)&0xff),
+ pktbuf);
+ if(!strncmp(mystring, pktbuf, strlen(mystring))) {
+ LOGDBG("Valid discovery message");
+ close(fd_broadcast);
+ sprintf(address, "%d.%d.%d.%d",
+ ((tmp>>24)&0xff), ((tmp>>16)&0xff),
+ ((tmp>>8)&0xff), ((tmp)&0xff));
+ if(1==sscanf(pktbuf+strlen(mystring), "%d", port))
+ return 1;
+ } else {
+ LOGDBG("NOT valid discovery message");
+ }
+ } else {
+ LOGERR("broadcast recvfrom failed");
+ break;
+ }
+ }
+ if(!err) {
+ /* timeout */
+ trycount++;
+ if(trycount < 3)
+ goto retry;
+ break;
+ }
+ LOGERR("broadcast poll error");
+ break;
+ }
+ }
+ }
+ }
+
+ /* failed */
+ close(fd_broadcast);
+ return 0;
+}
+