/*
* Copyright (C) 2009 The Sipdroid Open Source Project
* Copyright (C) 2007 The Android Open Source Project
*
* This file is part of Sipdroid (http://www.sipdroid.org)
*
* Sipdroid is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define LOG_TAG "OSNetworkSystem"
//#include "JNIHelp.h"
#include "jni.h"
#include "errno.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/time.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/un.h>
//#include <cutils/properties.h>
//#include <cutils/adb_networking.h>
//#include <utils/LogSocket.h>
//#include "AndroidSystemNatives.h"
/**
* @name Socket Errors
* Error codes for socket operations
*
* @internal SOCKERR* range from -200 to -299 avoid overlap
*/
#define SOCKERR_BADSOCKET -200 /* generic error */
#define SOCKERR_NOTINITIALIZED -201 /* socket library uninitialized */
#define SOCKERR_BADAF -202 /* bad address family */
#define SOCKERR_BADPROTO -203 /* bad protocol */
#define SOCKERR_BADTYPE -204 /* bad type */
#define SOCKERR_SYSTEMBUSY -205 /* system busy handling requests */
#define SOCKERR_SYSTEMFULL -206 /* too many sockets */
#define SOCKERR_NOTCONNECTED -207 /* socket is not connected */
#define SOCKERR_INTERRUPTED -208 /* the call was cancelled */
#define SOCKERR_TIMEOUT -209 /* the operation timed out */
#define SOCKERR_CONNRESET -210 /* the connection was reset */
#define SOCKERR_WOULDBLOCK -211 /* the socket is marked as nonblocking operation would block */
#define SOCKERR_ADDRNOTAVAIL -212 /* address not available */
#define SOCKERR_ADDRINUSE -213 /* address already in use */
#define SOCKERR_NOTBOUND -214 /* the socket is not bound */
#define SOCKERR_UNKNOWNSOCKET -215 /* resolution of fileDescriptor to socket failed */
#define SOCKERR_INVALIDTIMEOUT -216 /* the specified timeout is invalid */
#define SOCKERR_FDSETFULL -217 /* Unable to create an FDSET */
#define SOCKERR_TIMEVALFULL -218 /* Unable to create a TIMEVAL */
#define SOCKERR_REMSOCKSHUTDOWN -219 /* The remote socket has shutdown gracefully */
#define SOCKERR_NOTLISTENING -220 /* listen() was not invoked prior to accept() */
#define SOCKERR_NOTSTREAMSOCK -221 /* The socket does not support connection-oriented service */
#define SOCKERR_ALREADYBOUND -222 /* The socket is already bound to an address */
#define SOCKERR_NBWITHLINGER -223 /* The socket is marked non-blocking & SO_LINGER is non-zero */
#define SOCKERR_ISCONNECTED -224 /* The socket is already connected */
#define SOCKERR_NOBUFFERS -225 /* No buffer space is available */
#define SOCKERR_HOSTNOTFOUND -226 /* Authoritative Answer Host not found */
#define SOCKERR_NODATA -227 /* Valid name, no data record of requested type */
#define SOCKERR_BOUNDORCONN -228 /* The socket has not been bound or is already connected */
#define SOCKERR_OPNOTSUPP -229 /* The socket does not support the operation */
#define SOCKERR_OPTUNSUPP -230 /* The socket option is not supported */
#define SOCKERR_OPTARGSINVALID -231 /* The socket option arguments are invalid */
#define SOCKERR_SOCKLEVELINVALID -232 /* The socket level is invalid */
#define SOCKERR_TIMEOUTFAILURE -233
#define SOCKERR_SOCKADDRALLOCFAIL -234 /* Unable to allocate the sockaddr structure */
#define SOCKERR_FDSET_SIZEBAD -235 /* The calculated maximum size of the file descriptor set is bad */
#define SOCKERR_UNKNOWNFLAG -236 /* The flag is unknown */
#define SOCKERR_MSGSIZE -237 /* The datagram was too big to fit the specified buffer & was truncated. */
#define SOCKERR_NORECOVERY -238 /* The operation failed with no recovery possible */
#define SOCKERR_ARGSINVALID -239 /* The arguments are invalid */
#define SOCKERR_BADDESC -240 /* The socket argument is not a valid file descriptor */
#define SOCKERR_NOTSOCK -241 /* The socket argument is not a socket */
#define SOCKERR_HOSTENTALLOCFAIL -242 /* Unable to allocate the hostent structure */
#define SOCKERR_TIMEVALALLOCFAIL -243 /* Unable to allocate the timeval structure */
#define SOCKERR_LINGERALLOCFAIL -244 /* Unable to allocate the linger structure */
#define SOCKERR_IPMREQALLOCFAIL -245 /* Unable to allocate the ipmreq structure */
#define SOCKERR_FDSETALLOCFAIL -246 /* Unable to allocate the fdset structure */
#define SOCKERR_OPFAILED -247 /* Operation failed */
#define SOCKERR_VALUE_NULL -248 /* The value indexed was NULL */
#define SOCKERR_CONNECTION_REFUSED -249 /* connection was refused */
#define SOCKERR_ENETUNREACH -250 /* network is not reachable */
#define SOCKERR_EACCES -251 /* permissions do not allow action on socket */
#define SOCKERR_EHOSTUNREACH -252 /* no route to host */
#define SOCKERR_EPIPE -253 /* broken pipe */
#define JAVASOCKOPT_TCP_NODELAY 1
#define JAVASOCKOPT_IP_TOS 3
#define JAVASOCKOPT_SO_REUSEADDR 4
#define JAVASOCKOPT_SO_KEEPALIVE 8
#define JAVASOCKOPT_MCAST_TIME_TO_LIVE 10 /* Currently unused */
#define JAVASOCKOPT_SO_BINDADDR 15
#define JAVASOCKOPT_MCAST_INTERFACE 16
#define JAVASOCKOPT_MCAST_TTL 17
#define JAVASOCKOPT_IP_MULTICAST_LOOP 18
#define JAVASOCKOPT_MCAST_ADD_MEMBERSHIP 19
#define JAVASOCKOPT_MCAST_DROP_MEMBERSHIP 20
#define JAVASOCKOPT_IP_MULTICAST_IF2 31
#define JAVASOCKOPT_SO_BROADCAST 32
#define JAVASOCKOPT_SO_LINGER 128
#define JAVASOCKOPT_REUSEADDR_AND_REUSEPORT 10001
#define JAVASOCKOPT_SO_SNDBUF 4097
#define JAVASOCKOPT_SO_RCVBUF 4098
#define JAVASOCKOPT_SO_RCVTIMEOUT 4102
#define JAVASOCKOPT_SO_OOBINLINE 4099
/* constants for calling multi-call functions */
#define SOCKET_STEP_START 10
#define SOCKET_STEP_CHECK 20
#define SOCKET_STEP_DONE 30
#define BROKEN_MULTICAST_IF 1
#define BROKEN_MULTICAST_TTL 2
#define BROKEN_TCP_NODELAY 4
#define SOCKET_CONNECT_STEP_START 0
#define SOCKET_CONNECT_STEP_CHECK 1
#define SOCKET_OP_NONE 0
#define SOCKET_OP_READ 1
#define SOCKET_OP_WRITE 2
#define SOCKET_READ_WRITE 3
#define SOCKET_MSG_PEEK 1
#define SOCKET_MSG_OOB 2
#define SOCKET_NOFLAGS 0
#undef BUFFERSIZE
#define BUFFERSIZE 2048
// wait for 500000 usec = 0.5 second
#define SEND_RETRY_TIME 500000
struct CachedFields {
jfieldID fd_descriptor;
jclass iaddr_class;
jmethodID iaddr_getbyaddress;
jmethodID iaddr_getaddress;
jclass integer_class;
jmethodID integer_class_init;
jfieldID integer_class_value;
jclass boolean_class;
jmethodID boolean_class_init;
jfieldID boolean_class_value;
jclass byte_class;
jmethodID byte_class_init;
jfieldID byte_class_value;
jclass string_class;
jmethodID string_class_init;
jfieldID socketimpl_address;
jfieldID socketimpl_port;
jclass dpack_class;
jfieldID dpack_address;
jfieldID dpack_port;
jfieldID dpack_length;
jclass fd_class;
jfieldID descriptor;
} gCachedFields;
static int useAdbNetworking =