/* -*- c -*-
*
* ----------------------------------------------------------------------
* CcXstream Client Library for XBOX Media Player
* ----------------------------------------------------------------------
*
* Copyright (c) 2002-2003 by PuhPuh
*
* This code is copyrighted property of the author. It can still
* be used for any non-commercial purpose following conditions:
*
* 1) This copyright notice is not removed.
* 2) Source code follows any distribution of the software
* if possible.
* 3) Copyright notice above is found in the documentation
* of the distributed software.
*
* Any express or implied warranties are disclaimed. Author is
* not liable for any direct or indirect damages caused by the use
* of this software.
*
* ----------------------------------------------------------------------
*
*/
#include "ccincludes.h"
#include "ccbuffer.h"
#include "ccxclient.h"
#ifndef _XBOX
#define CC_XSTREAM_SOCKET_FD_TYPE int
#define CC_XSTREAM_SOCKET_CLOSE(s) close((s))
#define CC_XSTREAM_SOCKET_WRITE(s, b, l) write((s), (b), (l))
#define CC_XSTREAM_SOCKET_READ(s, b, l) read((s), (b), (l))
#else /* ! _XBOX */
#define CC_XSTREAM_SOCKET_FD_TYPE SOCKET
#define CC_XSTREAM_SOCKET_CLOSE(s) closesocket((s))
#define CC_XSTREAM_SOCKET_WRITE(s, b, l) send((s), (b), (l), 0)
#define CC_XSTREAM_SOCKET_READ(s, b, l) recv((s), (b), (l), 0)
#endif /* ! _XBOX */
static void cc_xstream_client_socket_setup(CC_XSTREAM_SOCKET_FD_TYPE sock)
{
int i;
#ifdef TCP_NODELAY
i = 1;
setsockopt(sock, IPPROTO_TCP,TCP_NODELAY, &i, sizeof (i));
#endif /* TCP_NODELAY */
#ifdef SO_KEEPALIVE
i = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof (i));
#endif /* SO_KEEPALIVE */
}
CcXstreamClientError cc_xstream_client_connect(const char *host,
int port,
CcXstreamServerConnection *s)
{
CC_XSTREAM_SOCKET_FD_TYPE sock;
struct sockaddr_in sa;
#ifndef _XBOX
struct hostent *he;
#endif /* ! _XBOX */
memset(&sa, 0, sizeof (sa));
sa.sin_port = htons(port);
sa.sin_family = AF_INET;
if (inet_addr(host) == INADDR_NONE)
{
#ifndef _XBOX
he = gethostbyname(host);
if ((he == NULL) || (he->h_addrtype != AF_INET) || (he->h_length != 4))
return CC_XSTREAM_CLIENT_SERVER_NOT_FOUND;
memcpy(&(sa.sin_addr), he->h_addr, 4);
#else /* ! _XBOX */
return CC_XSTREAM_CLIENT_SERVER_NOT_FOUND;
#endif /* ! _XBOX */
}
else
{
sa.sin_addr.s_addr = inet_addr(host);
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
return CC_XSTREAM_CLIENT_FATAL_ERROR;
if (connect(sock, (struct sockaddr *)&sa, sizeof (sa)) != 0)
{
CC_XSTREAM_SOCKET_CLOSE(sock);
return CC_XSTREAM_CLIENT_SERVER_CONNECTION_FAILED;
}
cc_xstream_client_socket_setup(sock);
*s = (CcXstreamServerConnection)sock;
return CC_XSTREAM_CLIENT_OK;
}
CcXstreamClientError cc_xstream_client_disconnect(CcXstreamServerConnection s)
{
CC_XSTREAM_SOCKET_FD_TYPE sock;
sock = (CC_XSTREAM_SOCKET_FD_TYPE)s;
CC_XSTREAM_SOCKET_CLOSE(s);
return CC_XSTREAM_CLIENT_OK;
}
unsigned char *cc_xstream_client_read_data(CcXstreamServerConnection s,
size_t len,
unsigned long timeout_ms)
{
unsigned char *buf;
size_t done;
CC_XSTREAM_SOCKET_FD_TYPE sock;
int rv;
struct timeval tv;
fd_set fds;
/* Convert the conenction handle to simple file descriptor. */
sock = (CC_XSTREAM_SOCKET_FD_TYPE)s;
/* We terminate incoming buffer just to make code safer.
Caller should not count on it anyway. */
buf = cc_xmalloc(len + 1);
buf[len] = '\0';
for (done = 0; done < len; /*NOTHING*/)
{
if (timeout_ms > 0)
{
tv.tv_sec = timeout_ms / 1000U;
tv.tv_usec = (timeout_ms % 1000U) * 1000U;
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (select(sock + 1, &fds, NULL, NULL, &tv) != 1)
{
/* Timeout or error, we don't really care. */
cc_xfree(buf);
return NULL;
}
}
rv = CC_XSTREAM_SOCKET_READ(sock, buf + done, len - done);
if (rv < 1)
{
cc_xfree(buf);
return NULL;
}
done += rv;
}
return buf;
}
int cc_xstream_client_write_data(CcXstreamServerConnection s,
unsigned char *buf,
size_t len,
unsigned long timeout_ms)
{
size_t done;
CC_XSTREAM_SOCKET_FD_TYPE sock;
int rv;
struct timeval tv;
fd_set fds;
/* Convert the conenction handle to simple file descriptor. */
sock = (CC_XSTREAM_SOCKET_FD_TYPE)s;
for (done = 0; done < len; /*NOTHING*/)
{
if (timeout_ms > 0)
{
tv.tv_sec = timeout_ms / 1000U;
tv.tv_usec = (timeout_ms % 1000U) * 1000U;
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (select(sock + 1, NULL, &fds, NULL, &tv) != 1)
{
/* Timeout or error, we don't really care. */
cc_xfree(buf);
return 0;
}
}
rv = CC_XSTREAM_SOCKET_WRITE(sock, buf + done, len - done);
if (rv < 1)
return 0;
done += rv;
}
return 1;
}
/* eof (ccxclientconn.c) */
syntax highlighted by Code2HTML, v. 0.9.1