summaryrefslogtreecommitdiff
path: root/tools/cxsocket.h
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 /tools/cxsocket.h
parent321eb114c9fe9abd954ce4270595d53df6cccbae (diff)
downloadxineliboutput-0_99rc4.tar.gz
xineliboutput-0_99rc4.tar.bz2
Initial importxineliboutput-0_99rc4
Diffstat (limited to 'tools/cxsocket.h')
-rw-r--r--tools/cxsocket.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/tools/cxsocket.h b/tools/cxsocket.h
new file mode 100644
index 00000000..f3d823e5
--- /dev/null
+++ b/tools/cxsocket.h
@@ -0,0 +1,192 @@
+/*
+ * cxsocket.h: Socket wrapper classes
+ *
+ * See the main source file 'xineliboutput.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: cxsocket.h,v 1.1 2006-06-03 10:04:27 phintuka Exp $
+ *
+ */
+
+#ifndef __CXSOCKET_H
+#define __CXSOCKET_H
+
+#define CLOSESOCKET(fd) do { if(fd>=0) { close(fd); fd=-1; } } while(0)
+
+//
+// Connect data socket to client (take address from fd_control)
+//
+static inline int sock_connect(int fd_control, int port, int type)
+{
+ struct sockaddr_in sin;
+ socklen_t len = sizeof(sin);
+ int s;
+
+ if(getpeername(fd_control, (struct sockaddr *)&sin, &len)) {
+ LOGERR("sock_connect: getpeername failed");
+ return -1;
+ }
+
+ uint32_t tmp = ntohl(sin.sin_addr.s_addr);
+ LOGMSG("Client address: %d.%d.%d.%d",
+ ((tmp>>24)&0xff), ((tmp>>16)&0xff),
+ ((tmp>>8)&0xff), ((tmp)&0xff));
+
+#if 0
+ if ((h = gethostbyname(tmp)) == NULL) {
+ LOGDBG("sock_connect: unable to resolve host name", tmp);
+ }
+#endif
+
+ if ((s = socket(PF_INET, type,
+ type==SOCK_DGRAM?IPPROTO_UDP:IPPROTO_TCP)) < 0) {
+ LOGERR("sock_connect: failed to create socket");
+ return -1;
+ }
+
+#if 1
+ // Set socket buffers: large send buffer, small receive buffer
+ {
+ int max_buf = KILOBYTE(128);
+ //while(max_buf) {
+ errno = 0;
+ if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(int))) {
+ LOGERR("setsockopt(SO_SNDBUF,%d) failed", max_buf);
+ max_buf >>= 1;
+ } else {
+ int tmp = 0;
+ int len = sizeof(int);
+ errno = 0;
+ if(getsockopt(s, SOL_SOCKET, SO_SNDBUF, &tmp, (socklen_t*)&len)) {
+ LOGERR("getsockopt(SO_SNDBUF,%d) failed", max_buf);
+ max_buf >>= 1;
+ } else if(tmp != max_buf) {
+ LOGDBG("setsockopt(SO_SNDBUF): got %d bytes", tmp);
+ max_buf >>= 1;
+ }
+ }
+ max_buf = 1024;
+ setsockopt(s, SOL_SOCKET, SO_RCVBUF, &max_buf, sizeof(int));
+ }
+#endif
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 &&
+ errno != EINPROGRESS) {
+ LOGERR("connect() failed");
+ CLOSESOCKET(s);
+ }
+
+ if (fcntl (s, F_SETFL, fcntl (s, F_GETFL) | O_NONBLOCK) == -1) {
+ LOGERR("can't put socket in non-blocking mode");
+ CLOSESOCKET(s);
+ return -1;
+ }
+
+ return s;
+}
+
+static inline int timed_write(int fd, const void *buffer, size_t size,
+ int timeout_ms)
+{
+ int written = size;
+ const unsigned char *ptr = (const unsigned char *)buffer;
+ cPoller poller(fd, true);
+
+ while (size > 0) {
+
+ if(!poller.Poll(timeout_ms)) {
+ LOGERR("timed_write: poll() failed");
+ return written-size;
+ }
+
+ errno = 0;
+ int p = write(fd, ptr, size);
+
+ if (p <= 0) {
+ if (errno == EINTR || errno == EAGAIN) {
+ LOGDBG("timed_write: EINTR during write(), retrying");
+ continue;
+ }
+ LOGERR("timed_write: write() error");
+ return p;
+ }
+
+ ptr += p;
+ size -= p;
+ }
+
+ return written;
+}
+
+//#include "xine_osd_command.h"
+
+static inline int write_osd_command(int fd, osd_command_t *cmd)
+{
+ if(8 != timed_write(fd, "OSDCMD\r\n", 8, 200)) {
+ LOGDBG("write_osd_command: write (command) failed");
+ return 0;
+ }
+ if(sizeof(osd_command_t) !=
+ timed_write(fd, cmd, sizeof(osd_command_t), 200)) {
+ LOGDBG("write_osd_command: write (data) failed");
+ return 0;
+ }
+ if(cmd->palette && cmd->colors &&
+ (int)(sizeof(xine_clut_t)*ntohl(cmd->colors)) !=
+ timed_write(fd, cmd->palette, (int)(sizeof(xine_clut_t)*ntohl(cmd->colors)), 200)) {
+ LOGDBG("write_osd_command: write (palette) failed");
+ return 0;
+ }
+ if(cmd->data && cmd->datalen &&
+ (int)ntohl(cmd->datalen) != timed_write(fd, cmd->data, ntohl(cmd->datalen), 1000)) {
+ LOGDBG("write_osd_command: write (bitmap) failed");
+ return 0;
+ }
+ return 1;
+}
+
+static inline int write_str(int fd, const char *str, int timeout_ms=-1)
+{
+ return timed_write(fd, str, strlen(str), timeout_ms);
+}
+
+static inline int write_cmd(int fd, const char *str)
+{
+ return write_str(fd, str, 10);
+}
+
+static inline int udp_discovery_broadcast(int fd_discovery, int m_Port)
+{
+ if(!xc.remote_usebcast) {
+ LOGDBG("UDP broadcasts (discovery) disabled in configuration");
+ return -1;
+ }
+
+ struct sockaddr_in sin;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(DISCOVERY_PORT);
+ sin.sin_addr.s_addr = INADDR_BROADCAST;
+
+ char *test = NULL;
+ asprintf(&test,
+ "VDR xineliboutput DISCOVERY 1.0\r\n"
+ "Server port: %d\r\n"
+ "\r\n",
+ m_Port);
+ int testlen = strlen(test);
+ if(testlen != sendto(fd_discovery, test, testlen, 0,
+ (struct sockaddr *)&sin, sizeof(sin))) {
+ LOGERR("UDP broadcast send failed (discovery)");
+ return -1;
+ } else {
+ LOGDBG("UDP broadcast send succeed (discovery)");
+ }
+ return 1;
+}
+
+
+#endif // __CXSOCKET_H