src/org/sipdroid/net/impl/OSNetworkSystem.java
changeset 823 2036ebfaccda
child 834 e8d6255306f8
equal deleted inserted replaced
536:537ddd8aa407 823:2036ebfaccda
       
     1 /*
       
     2  * Copyright (C) 2009 The Sipdroid Open Source Project
       
     3  * 
       
     4  * This file is part of Sipdroid (http://www.sipdroid.org)
       
     5  * 
       
     6  * Sipdroid is free software; you can redistribute it and/or modify
       
     7  * it under the terms of the GNU General Public License as published by
       
     8  * the Free Software Foundation; either version 3 of the License, or
       
     9  * (at your option) any later version.
       
    10  * 
       
    11  * This source code is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    14  * GNU General Public License for more details.
       
    15  * 
       
    16  * You should have received a copy of the GNU General Public License
       
    17  * along with this source code; if not, write to the Free Software
       
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    19  */
       
    20 
       
    21 // BEGIN android-note
       
    22 // address length was changed from long to int for performance reasons.
       
    23 // END android-note
       
    24 
       
    25 package org.sipdroid.net.impl;
       
    26 
       
    27 import java.io.FileDescriptor;
       
    28 import java.io.IOException;
       
    29 import java.net.DatagramPacket;
       
    30 import java.net.InetAddress;
       
    31 import java.net.SocketException;
       
    32 import java.net.SocketImpl;
       
    33 import java.net.UnknownHostException;
       
    34 import java.nio.channels.Channel;
       
    35 // BEGIN android-removed
       
    36 // import java.nio.channels.SelectableChannel;
       
    37 // END android-removed
       
    38 /*
       
    39  * 
       
    40  * This Class is used for native code wrap, the implement class of
       
    41  * INetworkSystem.
       
    42  * 
       
    43  */
       
    44 public final class OSNetworkSystem {
       
    45 
       
    46     // ----------------------------------------------------
       
    47     // Class Variables
       
    48     // ----------------------------------------------------
       
    49 
       
    50     private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
       
    51 
       
    52     private static OSNetworkSystem ref = new OSNetworkSystem();
       
    53     
       
    54     private static final int INETADDR_REACHABLE = 0;
       
    55     
       
    56     private static boolean isNetworkInited = false;
       
    57     
       
    58     // ----------------------------------------------------
       
    59     // Class Constructor
       
    60     // ----------------------------------------------------
       
    61 
       
    62     // can not be instantiated.
       
    63     private OSNetworkSystem() {
       
    64         super();
       
    65     }
       
    66 
       
    67     /*
       
    68      * @return a static ref of this class
       
    69      */
       
    70     public static OSNetworkSystem getOSNetworkSystem() {
       
    71         return ref;
       
    72     }
       
    73 
       
    74     // Useing when cache set/get is OK
       
    75     // public static native void oneTimeInitializationDatagram(
       
    76     // boolean jcl_IPv6_support);
       
    77     //
       
    78     // public static native void oneTimeInitializationSocket(
       
    79     // boolean jcl_IPv6_support);
       
    80 
       
    81     // --------------------------------------------------
       
    82     // java codes that wrap native codes
       
    83     // --------------------------------------------------
       
    84 
       
    85     public void createSocket(FileDescriptor fd, boolean preferIPv4Stack)
       
    86             throws IOException {
       
    87         createSocketImpl(fd, preferIPv4Stack);
       
    88     }
       
    89 
       
    90     public void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack)
       
    91             throws SocketException {
       
    92         createDatagramSocketImpl(fd, preferIPv4Stack);
       
    93     }
       
    94 
       
    95     public int read(FileDescriptor aFD, byte[] data, int offset, int count,
       
    96             int timeout) throws IOException {
       
    97         return readSocketImpl(aFD, data, offset, count, timeout);
       
    98     }
       
    99     
       
   100     public int readDirect(FileDescriptor aFD, int address, int offset, int count,
       
   101             int timeout) throws IOException {
       
   102         return readSocketDirectImpl(aFD, address, offset, count, timeout);
       
   103     }
       
   104 
       
   105     public int write(FileDescriptor aFD, byte[] data, int offset, int count)
       
   106             throws IOException {
       
   107         return writeSocketImpl(aFD, data, offset, count);
       
   108     }
       
   109     
       
   110     public int writeDirect(FileDescriptor aFD, int address, int offset,
       
   111             int count) throws IOException {
       
   112         return writeSocketDirectImpl(aFD, address, offset, count);
       
   113     }
       
   114 
       
   115     public void setNonBlocking(FileDescriptor aFD, boolean block)
       
   116             throws IOException {
       
   117         setNonBlockingImpl(aFD, block);
       
   118     }
       
   119 
       
   120     public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
       
   121             InetAddress inetAddress) throws SocketException {
       
   122         connectDatagramImpl2(aFD, port, trafficClass, inetAddress);
       
   123     }
       
   124 
       
   125     public int connect(FileDescriptor aFD, int trafficClass,
       
   126             InetAddress inetAddress, int port)  throws IOException{
       
   127         return connectSocketImpl(aFD, trafficClass, inetAddress, port);
       
   128     }
       
   129 
       
   130     // BEGIN android-changed
       
   131     public int connectWithTimeout(FileDescriptor aFD, int timeout,
       
   132             int trafficClass, InetAddress inetAddress, int port, int step,
       
   133             byte[] context)  throws IOException{
       
   134         return connectWithTimeoutSocketImpl(aFD, timeout, trafficClass,
       
   135                 inetAddress, port, step, context);
       
   136     }
       
   137     // END android-changed
       
   138 
       
   139     public void connectStreamWithTimeoutSocket(FileDescriptor aFD, int aport,
       
   140             int timeout, int trafficClass, InetAddress inetAddress)
       
   141             throws IOException {
       
   142         connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
       
   143                 inetAddress);
       
   144     }
       
   145 
       
   146     public void bind(FileDescriptor aFD, int port, InetAddress inetAddress)
       
   147             throws SocketException {
       
   148         socketBindImpl(aFD, port, inetAddress);
       
   149     }
       
   150 
       
   151     public boolean bind2(FileDescriptor aFD, int port, boolean bindToDevice,
       
   152             InetAddress inetAddress) throws SocketException {
       
   153         return socketBindImpl2(aFD, port, bindToDevice, inetAddress);
       
   154     }
       
   155 
       
   156     public void accept(FileDescriptor fdServer, SocketImpl newSocket,
       
   157             FileDescriptor fdnewSocket, int timeout) throws IOException {
       
   158         acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
       
   159     }
       
   160 
       
   161     public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
       
   162             int length, int port, boolean bindToDevice, int trafficClass,
       
   163             InetAddress inetAddress) throws IOException {
       
   164         return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
       
   165                 trafficClass, inetAddress);
       
   166     }
       
   167     
       
   168     public int sendDatagramDirect(FileDescriptor fd, int address, int offset,
       
   169             int length, int port, boolean bindToDevice, int trafficClass,
       
   170             InetAddress inetAddress) throws IOException {
       
   171         return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
       
   172                 trafficClass, inetAddress);
       
   173     }
       
   174 
       
   175     public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
       
   176             int length, int port, InetAddress inetAddress) throws IOException {
       
   177         return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
       
   178     }
       
   179 
       
   180     public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
       
   181             byte[] data, int offset, int length, int receiveTimeout,
       
   182             boolean peek) throws IOException {
       
   183         return receiveDatagramImpl(aFD, packet, data, offset, length,
       
   184                 receiveTimeout, peek);
       
   185     }
       
   186     
       
   187     public int receiveDatagramDirect(FileDescriptor aFD, DatagramPacket packet,
       
   188             int address, int offset, int length, int receiveTimeout,
       
   189             boolean peek) throws IOException {
       
   190         return receiveDatagramDirectImpl(aFD, packet, address, offset, length,
       
   191                 receiveTimeout, peek);
       
   192     }
       
   193 
       
   194     public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
       
   195             byte[] data, int offset, int length, int receiveTimeout,
       
   196             boolean peek) throws IOException {
       
   197         return recvConnectedDatagramImpl(aFD, packet, data, offset, length,
       
   198                 receiveTimeout, peek);
       
   199     }
       
   200     
       
   201     public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
       
   202              int offset, int length, int receiveTimeout, boolean peek)
       
   203             throws IOException {
       
   204         return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
       
   205     }
       
   206 
       
   207     public int peekDatagram(FileDescriptor aFD, InetAddress sender,
       
   208             int receiveTimeout) throws IOException {
       
   209         return peekDatagramImpl(aFD, sender, receiveTimeout);
       
   210     }
       
   211 
       
   212     public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
       
   213             int offset, int length, boolean bindToDevice) throws IOException {
       
   214         return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
       
   215     }
       
   216     
       
   217     public int sendConnectedDatagramDirect(FileDescriptor fd, int address,
       
   218             int offset, int length, boolean bindToDevice) throws IOException {
       
   219         return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
       
   220     }
       
   221 
       
   222     public void disconnectDatagram(FileDescriptor aFD) throws SocketException {
       
   223         disconnectDatagramImpl(aFD);
       
   224     }
       
   225 
       
   226     public void createMulticastSocket(FileDescriptor aFD,
       
   227             boolean preferIPv4Stack) throws SocketException {
       
   228         createMulticastSocketImpl(aFD, preferIPv4Stack);
       
   229     }
       
   230 
       
   231     public void createServerStreamSocket(FileDescriptor aFD,
       
   232             boolean preferIPv4Stack) throws SocketException {
       
   233         createServerStreamSocketImpl(aFD, preferIPv4Stack);
       
   234     }
       
   235 
       
   236     public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
       
   237             int count, int timeout) throws IOException {
       
   238         return receiveStreamImpl(aFD, data, offset, count, timeout);
       
   239     }
       
   240 
       
   241     public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
       
   242             throws IOException {
       
   243         return sendStreamImpl(fd, data, offset, count);
       
   244     }
       
   245 
       
   246     public void shutdownInput(FileDescriptor descriptor) throws IOException {
       
   247         shutdownInputImpl(descriptor);
       
   248     }
       
   249 
       
   250     public void shutdownOutput(FileDescriptor descriptor) throws IOException {
       
   251         shutdownOutputImpl(descriptor);
       
   252     }
       
   253 
       
   254     public boolean supportsUrgentData(FileDescriptor fd) {
       
   255         return supportsUrgentDataImpl(fd);
       
   256     }
       
   257 
       
   258     public void sendUrgentData(FileDescriptor fd, byte value) {
       
   259         sendUrgentDataImpl(fd, value);
       
   260     }
       
   261 
       
   262     public int availableStream(FileDescriptor aFD) throws SocketException {
       
   263         return availableStreamImpl(aFD);
       
   264     }
       
   265 
       
   266     // BEGIN android-removed
       
   267     // public void acceptStreamSocket(FileDescriptor fdServer,
       
   268     //         SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
       
   269     //         throws IOException {
       
   270     //     acceptStreamSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
       
   271     // }
       
   272     // 
       
   273     // public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
       
   274     //         throws SocketException {
       
   275     //     createStreamSocketImpl(aFD, preferIPv4Stack);
       
   276     // }
       
   277     // END android-removed
       
   278 
       
   279     public void listenStreamSocket(FileDescriptor aFD, int backlog)
       
   280             throws SocketException {
       
   281         listenStreamSocketImpl(aFD, backlog);
       
   282     }
       
   283     
       
   284     // BEGIN android-removed
       
   285     // public boolean isReachableByICMP(final InetAddress dest,
       
   286     //         InetAddress source, final int ttl, final int timeout) {
       
   287     //     return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
       
   288     //             timeout);
       
   289     // }
       
   290     // END android-removed
       
   291 
       
   292     /*
       
   293      * 
       
   294      * @param 
       
   295      *      readChannels all channels interested in read and accept 
       
   296      * @param
       
   297      *      writeChannels all channels interested in write and connect 
       
   298      * @param timeout
       
   299      *      timeout in millis @return a set of channels that are ready for operation
       
   300      * @throws 
       
   301      *      SocketException @return int array, each int approve one of the     * channel if OK
       
   302      */
       
   303 
       
   304     public int[] select(FileDescriptor[] readFDs,
       
   305             FileDescriptor[] writeFDs, long timeout)
       
   306             throws SocketException {
       
   307         int countRead = readFDs.length;
       
   308         int countWrite = writeFDs.length;
       
   309         int result = 0;
       
   310         if (0 == countRead + countWrite) {
       
   311             return (new int[0]);
       
   312         }
       
   313         int[] flags = new int[countRead + countWrite];
       
   314 
       
   315         // handle timeout in native
       
   316         result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
       
   317                 timeout);
       
   318 
       
   319         if (0 <= result) {
       
   320             return flags;
       
   321         }
       
   322         if (ERRORCODE_SOCKET_TIMEOUT == result) {
       
   323             return new int[0];
       
   324         }
       
   325         throw new SocketException();
       
   326 
       
   327     }
       
   328 
       
   329     public InetAddress getSocketLocalAddress(FileDescriptor aFD,
       
   330             boolean preferIPv6Addresses) {
       
   331         return getSocketLocalAddressImpl(aFD, preferIPv6Addresses);
       
   332     }
       
   333 
       
   334     /*
       
   335      * Query the IP stack for the local port to which this socket is bound.
       
   336      * 
       
   337      * @param aFD the socket descriptor @param preferIPv6Addresses address
       
   338      * preference for nodes that support both IPv4 and IPv6 @return int the
       
   339      * local port to which the socket is bound
       
   340      */
       
   341     public int getSocketLocalPort(FileDescriptor aFD,
       
   342             boolean preferIPv6Addresses) {
       
   343         return getSocketLocalPortImpl(aFD, preferIPv6Addresses);
       
   344     }
       
   345 
       
   346     /*
       
   347      * Query the IP stack for the nominated socket option.
       
   348      * 
       
   349      * @param aFD the socket descriptor @param opt the socket option type
       
   350      * @return the nominated socket option value
       
   351      * 
       
   352      * @throws SocketException if the option is invalid
       
   353      */
       
   354     public Object getSocketOption(FileDescriptor aFD, int opt)
       
   355             throws SocketException {
       
   356         return getSocketOptionImpl(aFD, opt);
       
   357     }
       
   358 
       
   359     /*
       
   360      * Set the nominated socket option in the IP stack.
       
   361      * 
       
   362      * @param aFD the socket descriptor @param opt the option selector @param
       
   363      * optVal the nominated option value
       
   364      * 
       
   365      * @throws SocketException if the option is invalid or cannot be set
       
   366      */
       
   367     public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
       
   368             throws SocketException {
       
   369         setSocketOptionImpl(aFD, opt, optVal);
       
   370     }
       
   371 
       
   372     public int getSocketFlags() {
       
   373         return getSocketFlagsImpl();
       
   374     }
       
   375 
       
   376     /*
       
   377      * Close the socket in the IP stack.
       
   378      * 
       
   379      * @param aFD the socket descriptor
       
   380      */
       
   381     public void socketClose(FileDescriptor aFD) throws IOException {
       
   382         socketCloseImpl(aFD);
       
   383     }
       
   384 
       
   385     public InetAddress getHostByAddr(byte[] addr) throws UnknownHostException {
       
   386         return getHostByAddrImpl(addr);
       
   387     }
       
   388 
       
   389     public InetAddress getHostByName(String addr, boolean preferIPv6Addresses)
       
   390             throws UnknownHostException {
       
   391         return getHostByNameImpl(addr, preferIPv6Addresses);
       
   392     }
       
   393 
       
   394     public void setInetAddress(InetAddress sender, byte[] address) {
       
   395         setInetAddressImpl(sender, address);
       
   396     }
       
   397 
       
   398     // ---------------------------------------------------
       
   399     // Native Codes
       
   400     // ---------------------------------------------------
       
   401 
       
   402     static native void createSocketImpl(FileDescriptor fd,
       
   403             boolean preferIPv4Stack);
       
   404 
       
   405     /*
       
   406      * Allocate a datagram socket in the IP stack. The socket is associated with
       
   407      * the <code>aFD</code>.
       
   408      * 
       
   409      * @param aFD the FileDescriptor to associate with the socket @param
       
   410      * preferIPv4Stack IP stack preference if underlying platform is V4/V6
       
   411      * @exception SocketException upon an allocation error
       
   412      */
       
   413     static native void createDatagramSocketImpl(FileDescriptor aFD,
       
   414             boolean preferIPv4Stack) throws SocketException;
       
   415 
       
   416     static native int readSocketImpl(FileDescriptor aFD, byte[] data,
       
   417             int offset, int count, int timeout) throws IOException;
       
   418     
       
   419     static native int readSocketDirectImpl(FileDescriptor aFD, int address,
       
   420             int offset, int count, int timeout) throws IOException;
       
   421 
       
   422     static native int writeSocketImpl(FileDescriptor fd, byte[] data,
       
   423             int offset, int count) throws IOException;
       
   424     
       
   425     static native int writeSocketDirectImpl(FileDescriptor fd, int address,
       
   426             int offset, int count) throws IOException;
       
   427 
       
   428     static native void setNonBlockingImpl(FileDescriptor aFD,
       
   429             boolean block);
       
   430 
       
   431     static native int connectSocketImpl(FileDescriptor aFD,
       
   432             int trafficClass, InetAddress inetAddress, int port);
       
   433 
       
   434     // BEGIN android-changed
       
   435     static native int connectWithTimeoutSocketImpl(
       
   436             FileDescriptor aFD, int timeout, int trafficClass,
       
   437             InetAddress hostname, int port, int step, byte[] context);
       
   438     // END android-changed
       
   439 
       
   440     static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
       
   441             int aport, int timeout, int trafficClass, InetAddress inetAddress)
       
   442             throws IOException;
       
   443 
       
   444     static native void socketBindImpl(FileDescriptor aFD, int port,
       
   445             InetAddress inetAddress) throws SocketException;
       
   446 
       
   447     static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
       
   448             throws SocketException;
       
   449 
       
   450     static native int availableStreamImpl(FileDescriptor aFD)
       
   451             throws SocketException;
       
   452 
       
   453     static native void acceptSocketImpl(FileDescriptor fdServer,
       
   454             SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
       
   455             throws IOException;
       
   456 
       
   457     static native boolean supportsUrgentDataImpl(FileDescriptor fd);
       
   458 
       
   459     static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
       
   460 
       
   461     /*
       
   462      * Connect the socket to a port and address
       
   463      * 
       
   464      * @param aFD the FileDescriptor to associate with the socket @param port
       
   465      * the port to connect to @param trafficClass the traffic Class to be used
       
   466      * then the connection is made @param inetAddress address to connect to.
       
   467      * 
       
   468      * @exception SocketException if the connect fails
       
   469      */
       
   470     static native void connectDatagramImpl2(FileDescriptor aFD,
       
   471             int port, int trafficClass, InetAddress inetAddress)
       
   472             throws SocketException;
       
   473 
       
   474     /*
       
   475      * Disconnect the socket to a port and address
       
   476      * 
       
   477      * @param aFD the FileDescriptor to associate with the socket
       
   478      * 
       
   479      * @exception SocketException if the disconnect fails
       
   480      */
       
   481     static native void disconnectDatagramImpl(FileDescriptor aFD)
       
   482             throws SocketException;
       
   483 
       
   484     /*
       
   485      * Allocate a datagram socket in the IP stack. The socket is associated with
       
   486      * the <code>aFD</code>.
       
   487      * 
       
   488      * @param aFD the FileDescriptor to associate with the socket @param
       
   489      * preferIPv4Stack IP stack preference if underlying platform is V4/V6
       
   490      * @exception SocketException upon an allocation error
       
   491      */
       
   492 
       
   493     /*
       
   494      * Bind the socket to the port/localhost in the IP stack.
       
   495      * 
       
   496      * @param aFD the socket descriptor @param port the option selector @param
       
   497      * bindToDevice bind the socket to the specified interface @param
       
   498      * inetAddress address to connect to. @return if bind successful @exception
       
   499      * SocketException thrown if bind operation fails
       
   500      */
       
   501     static native boolean socketBindImpl2(FileDescriptor aFD,
       
   502             int port, boolean bindToDevice, InetAddress inetAddress)
       
   503             throws SocketException;
       
   504 
       
   505     /*
       
   506      * Peek on the socket, update <code>sender</code> address and answer the
       
   507      * sender port.
       
   508      * 
       
   509      * @param aFD the socket FileDescriptor @param sender an InetAddress, to be
       
   510      * updated with the sender's address @param receiveTimeout the maximum
       
   511      * length of time the socket should block, reading @return int the sender
       
   512      * port
       
   513      * 
       
   514      * @exception IOException upon an read error or timeout
       
   515      */
       
   516     static native int peekDatagramImpl(FileDescriptor aFD,
       
   517             InetAddress sender, int receiveTimeout) throws IOException;
       
   518 
       
   519     /*
       
   520      * Recieve data on the socket into the specified buffer. The packet fields
       
   521      * <code>data</code> & <code>length</code> are passed in addition to
       
   522      * <code>packet</code> to eliminate the JNI field access calls.
       
   523      * 
       
   524      * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
       
   525      * receive into @param data the data buffer of the packet @param offset the
       
   526      * offset in the data buffer @param length the length of the data buffer in
       
   527      * the packet @param receiveTimeout the maximum length of time the socket
       
   528      * should block, reading @param peek indicates to peek at the data @return
       
   529      * number of data received @exception IOException upon an read error or
       
   530      * timeout
       
   531      */
       
   532     static native int receiveDatagramImpl(FileDescriptor aFD,
       
   533             DatagramPacket packet, byte[] data, int offset, int length,
       
   534             int receiveTimeout, boolean peek) throws IOException;
       
   535     
       
   536     static native int receiveDatagramDirectImpl(FileDescriptor aFD,
       
   537             DatagramPacket packet, int address, int offset, int length,
       
   538             int receiveTimeout, boolean peek) throws IOException;
       
   539 
       
   540     /*
       
   541      * Recieve data on the connected socket into the specified buffer. The
       
   542      * packet fields <code>data</code> & <code>length</code> are passed in
       
   543      * addition to <code>packet</code> to eliminate the JNI field access
       
   544      * calls.
       
   545      * 
       
   546      * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
       
   547      * receive into @param data the data buffer of the packet @param offset the
       
   548      * offset in the data buffer @param length the length of the data buffer in
       
   549      * the packet @param receiveTimeout the maximum length of time the socket
       
   550      * should block, reading @param peek indicates to peek at the data @return
       
   551      * number of data received @exception IOException upon an read error or
       
   552      * timeout
       
   553      */
       
   554     static native int recvConnectedDatagramImpl(FileDescriptor aFD,
       
   555             DatagramPacket packet, byte[] data, int offset, int length,
       
   556             int receiveTimeout, boolean peek) throws IOException;
       
   557     
       
   558     static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
       
   559             DatagramPacket packet, int address, int offset, int length,
       
   560             int receiveTimeout, boolean peek) throws IOException;
       
   561 
       
   562     /*
       
   563      * Send the <code>data</code> to the nominated target <code>address</code>
       
   564      * and <code>port</code>. These values are derived from the
       
   565      * DatagramPacket to reduce the field calls within JNI.
       
   566      * 
       
   567      * @param fd the socket FileDescriptor @param data the data buffer of the
       
   568      * packet @param offset the offset in the data buffer @param length the
       
   569      * length of the data buffer in the packet @param port the target host port
       
   570      * @param bindToDevice if bind to device @param trafficClass the traffic
       
   571      * class to be used when the datagram is sent @param inetAddress address to
       
   572      * connect to. @return number of data send
       
   573      * 
       
   574      * @exception IOException upon an read error or timeout
       
   575      */
       
   576     static native int sendDatagramImpl(FileDescriptor fd,
       
   577             byte[] data, int offset, int length, int port,
       
   578             boolean bindToDevice, int trafficClass, InetAddress inetAddress)
       
   579             throws IOException;
       
   580     
       
   581     static native int sendDatagramDirectImpl(FileDescriptor fd,
       
   582             int address, int offset, int length, int port,
       
   583             boolean bindToDevice, int trafficClass, InetAddress inetAddress)
       
   584             throws IOException;
       
   585 
       
   586     /*
       
   587      * Send the <code>data</code> to the address and port to which the was
       
   588      * connnected and <code>port</code>.
       
   589      * 
       
   590      * @param fd the socket FileDescriptor @param data the data buffer of the
       
   591      * packet @param offset the offset in the data buffer @param length the
       
   592      * length of the data buffer in the packet @param bindToDevice not used,
       
   593      * current kept in case needed as was the case for sendDatagramImpl @return
       
   594      * number of data send @exception IOException upon an read error or timeout
       
   595      */
       
   596     static native int sendConnectedDatagramImpl(FileDescriptor fd,
       
   597             byte[] data, int offset, int length, boolean bindToDevice)
       
   598             throws IOException;
       
   599     
       
   600     static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
       
   601             int address, int offset, int length, boolean bindToDevice)
       
   602             throws IOException;
       
   603 
       
   604     /*
       
   605      * Answer the result of attempting to create a server stream socket in the
       
   606      * IP stack. Any special options required for server sockets will be set by
       
   607      * this method.
       
   608      * 
       
   609      * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
       
   610      * @exception SocketException if an error occurs while creating the socket
       
   611      */
       
   612     static native void createServerStreamSocketImpl(FileDescriptor aFD,
       
   613             boolean preferIPv4Stack) throws SocketException;
       
   614 
       
   615     /*
       
   616      * Answer the result of attempting to create a multicast socket in the IP
       
   617      * stack. Any special options required for server sockets will be set by
       
   618      * this method.
       
   619      * 
       
   620      * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
       
   621      * @exception SocketException if an error occurs while creating the socket
       
   622      */
       
   623     static native void createMulticastSocketImpl(FileDescriptor aFD,
       
   624             boolean preferIPv4Stack) throws SocketException;
       
   625 
       
   626     /*
       
   627      * Recieve at most <code>count</code> bytes into the buffer <code>data</code>
       
   628      * at the <code>offset</code> on the socket.
       
   629      * 
       
   630      * @param aFD the socket FileDescriptor @param data the receive buffer
       
   631      * @param offset the offset into the buffer @param count the max number of
       
   632      * bytes to receive @param timeout the max time the read operation should
       
   633      * block waiting for data @return int the actual number of bytes read
       
   634      * @throws IOException @exception SocketException if an error occurs while
       
   635      * reading
       
   636      */
       
   637     static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
       
   638             int offset, int count, int timeout) throws IOException;
       
   639 
       
   640     /*
       
   641      * Send <code>count</code> bytes from the buffer <code>data</code> at
       
   642      * the <code>offset</code>, on the socket.
       
   643      * 
       
   644      * @param fd
       
   645      * 
       
   646      * @param data the send buffer @param offset the offset into the buffer
       
   647      * @param count the number of bytes to receive @return int the actual number
       
   648      * of bytes sent @throws IOException @exception SocketException if an error
       
   649      * occurs while writing
       
   650      */
       
   651     static native int sendStreamImpl(FileDescriptor fd, byte[] data,
       
   652             int offset, int count) throws IOException;
       
   653 
       
   654     private native void shutdownInputImpl(FileDescriptor descriptor)
       
   655             throws IOException;
       
   656 
       
   657     private native void shutdownOutputImpl(FileDescriptor descriptor)
       
   658             throws IOException;
       
   659 
       
   660     // BEGIN android-removed
       
   661     // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
       
   662     //         SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
       
   663     //         throws IOException;
       
   664     // 
       
   665     // static native void createStreamSocketImpl(FileDescriptor aFD,
       
   666     //         boolean preferIPv4Stack) throws SocketException;
       
   667     // END android-removed
       
   668 
       
   669     static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
       
   670             int offset, int length, int port, InetAddress inetAddress)
       
   671             throws IOException;
       
   672 
       
   673     static native int selectImpl(FileDescriptor[] readfd,
       
   674             FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
       
   675             long timeout);
       
   676 
       
   677     static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD,
       
   678             boolean preferIPv6Addresses);
       
   679 
       
   680     /*
       
   681      * Query the IP stack for the local port to which this socket is bound.
       
   682      * 
       
   683      * @param aFD the socket descriptor @param preferIPv6Addresses address
       
   684      * preference for nodes that support both IPv4 and IPv6 @return int the
       
   685      * local port to which the socket is bound
       
   686      */
       
   687     static native int getSocketLocalPortImpl(FileDescriptor aFD,
       
   688             boolean preferIPv6Addresses);
       
   689 
       
   690     /*
       
   691      * Query the IP stack for the nominated socket option.
       
   692      * 
       
   693      * @param aFD the socket descriptor @param opt the socket option type
       
   694      * @return the nominated socket option value
       
   695      * 
       
   696      * @throws SocketException if the option is invalid
       
   697      */
       
   698     static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
       
   699             throws SocketException;
       
   700 
       
   701     /*
       
   702      * Set the nominated socket option in the IP stack.
       
   703      * 
       
   704      * @param aFD the socket descriptor @param opt the option selector @param
       
   705      * optVal the nominated option value
       
   706      * 
       
   707      * @throws SocketException if the option is invalid or cannot be set
       
   708      */
       
   709     static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
       
   710             Object optVal) throws SocketException;
       
   711 
       
   712     static native int getSocketFlagsImpl();
       
   713 
       
   714     /*
       
   715      * Close the socket in the IP stack.
       
   716      * 
       
   717      * @param aFD the socket descriptor
       
   718      */
       
   719     static native void socketCloseImpl(FileDescriptor aFD);
       
   720 
       
   721     static native InetAddress getHostByAddrImpl(byte[] addr)
       
   722             throws UnknownHostException;
       
   723 
       
   724     static native InetAddress getHostByNameImpl(String addr,
       
   725             boolean preferIPv6Addresses) throws UnknownHostException;
       
   726 
       
   727     native void setInetAddressImpl(InetAddress sender, byte[] address);
       
   728 
       
   729     // BEGIN android-removed
       
   730     // native int isReachableByICMPImpl(InetAddress addr, InetAddress local,
       
   731     //         int ttl, int timeout);
       
   732     // END android-removed
       
   733     
       
   734     native Channel inheritedChannelImpl();
       
   735 
       
   736     public Channel inheritedChannel() {
       
   737         return inheritedChannelImpl();
       
   738     }
       
   739     
       
   740     public void oneTimeInitialization(boolean jcl_supports_ipv6){
       
   741         if (!isNetworkInited){
       
   742             oneTimeInitializationImpl(jcl_supports_ipv6);
       
   743             isNetworkInited = true;
       
   744         } 
       
   745     }
       
   746     
       
   747     native void oneTimeInitializationImpl (boolean jcl_supports_ipv6);
       
   748 }