1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18ae704b984c10a63883cc366e823d53902d6ac7a9Elliott Hughespackage java.nio; 19f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InterruptedIOException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.ConnectException; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.DatagramPacket; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.DatagramSocket; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.DatagramSocketImpl; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetAddress; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetSocketAddress; 298de7cf6bff36093dda9e25a1ab3718720cb54906Elliott Hughesimport java.net.PlainDatagramSocketImpl; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketAddress; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketException; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.AlreadyConnectedException; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ClosedChannelException; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.DatagramChannel; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.IllegalBlockingModeException; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.NotYetConnectedException; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.spi.SelectorProvider; 38a1603838fe9e865575c87982e32c6343740e464cElliott Hughesimport java.util.Arrays; 3932b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughesimport libcore.io.ErrnoException; 400b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughesimport libcore.io.IoBridge; 41454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughesimport libcore.io.IoUtils; 4232b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughesimport libcore.io.Libcore; 436186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default implementation class of java.nio.channels.DatagramChannel. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 48d320e321d5567a4ac94b6e5874eda4b1f1189e13Elliott Hughesclass DatagramChannelImpl extends DatagramChannel implements FileDescriptorChannel { 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The fd to interact with native code 50c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson private final FileDescriptor fd; 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Our internal DatagramSocket. 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private DatagramSocket socket = null; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The address to be connected. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress connectAddress = null; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // local port 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int localPort; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // At first, uninitialized. 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean connected = false; 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // whether the socket is bound 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isBound = false; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 675e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes private final Object readLock = new Object(); 685e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes private final Object writeLock = new Object(); 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructor 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 734e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes protected DatagramChannelImpl(SelectorProvider selectorProvider) throws IOException { 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(selectorProvider); 750b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes fd = IoBridge.socket(false); 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for native call 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 81f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("unused") 82f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private DatagramChannelImpl() { 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(SelectorProvider.provider()); 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fd = new FileDescriptor(); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connectAddress = new InetSocketAddress(0); 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Getting the internal DatagramSocket If we have not the socket, we create 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a new one. 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public DatagramSocket socket() { 94b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (socket == null) { 954e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes socket = new DatagramSocketAdapter(new PlainDatagramSocketImpl(fd, localPort), this); 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return socket; 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1010a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes * Returns the local address to which the socket is bound. 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetAddress getLocalAddress() { 1040b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes return IoBridge.getSocketLocalAddress(fd); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.DatagramChannel#isConnected() 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public boolean isConnected() { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return connected; 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.DatagramChannel#connect(java.net.SocketAddress) 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 1194e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes synchronized public DatagramChannel connect(SocketAddress address) throws IOException { 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // must open 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpen(); 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // status must be un-connected. 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (connected) { 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException(); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the address 1284e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes InetSocketAddress inetSocketAddress = SocketChannelImpl.validateAddress(address); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 1310b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes IoBridge.connect(fd, inetSocketAddress.getAddress(), inetSocketAddress.getPort()); 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ConnectException e) { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ConnectException means connect fail, not exception 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(true); 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set the connected address. 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connectAddress = inetSocketAddress; 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connected = true; 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = true; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.DatagramChannel#disconnect() 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public DatagramChannel disconnect() throws IOException { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected() || !isOpen()) { 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connected = false; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connectAddress = null; 15532b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughes try { 15632b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughes Libcore.os.connect(fd, InetAddress.UNSPECIFIED, 0); 15732b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughes } catch (ErrnoException errnoException) { 15832b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughes throw errnoException.rethrowAsIOException(); 15932b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughes } 160b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (socket != null) { 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.disconnect(); 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketAddress receive(ByteBuffer target) throws IOException { 168e3b6fa2bf357f2712ab2ee9e8487f157595ea0c7Elliott Hughes target.checkWritable(); 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpen(); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isBound) { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SocketAddress retAddr = null; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // receive real data packet, (not peek) 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (readLock) { 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean loop = isBlocking(); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!target.isDirect()) { 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project retAddr = receiveImpl(target, loop); 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project retAddr = receiveDirectImpl(target, loop); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedIOException e) { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // this line used in Linux 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 192b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes end(retAddr != null); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return retAddr; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 196eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 19779ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes private SocketAddress receiveImpl(ByteBuffer target, boolean loop) throws IOException { 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SocketAddress retAddr = null; 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DatagramPacket receivePacket; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int oldposition = target.position(); 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int received = 0; 20223ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes // TODO: disallow mapped buffers and lose this conditional? 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target.hasArray()) { 20423ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes receivePacket = new DatagramPacket(target.array(), target.position() + target.arrayOffset(), target.remaining()); 205eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else { 20623ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes receivePacket = new DatagramPacket(new byte[target.remaining()], target.remaining()); 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 2090b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes received = IoBridge.recvfrom(false, fd, receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength(), 0, receivePacket, isConnected()); 210b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (receivePacket != null && receivePacket.getAddress() != null) { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (received > 0) { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target.hasArray()) { 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project target.position(oldposition + received); 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // copy the data of received packet 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project target.put(receivePacket.getData(), 0, received); 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project retAddr = receivePacket.getSocketAddress(); 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (loop); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return retAddr; 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 22679ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes private SocketAddress receiveDirectImpl(ByteBuffer target, boolean loop) throws IOException { 227f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson SocketAddress retAddr = null; 228693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes DatagramPacket receivePacket = new DatagramPacket(EmptyArray.BYTE, 0); 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int oldposition = target.position(); 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int received = 0; 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 2320b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes received = IoBridge.recvfrom(false, fd, target, 0, receivePacket, isConnected()); 233b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (receivePacket != null && receivePacket.getAddress() != null) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // copy the data of received packet 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (received > 0) { 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project target.position(oldposition + received); 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project retAddr = receivePacket.getSocketAddress(); 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (loop); 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return retAddr; 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 2464e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes public int send(ByteBuffer source, SocketAddress socketAddress) throws IOException { 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkNotNull(source); 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpen(); 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress isa = (InetSocketAddress) socketAddress; 251b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (isa.getAddress() == null) { 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IOException(); 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes if (isConnected() && !connectAddress.equals(isa)) { 256ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes throw new IllegalArgumentException(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25990d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes synchronized (writeLock) { 26090d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes int sendCount = 0; 26190d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes try { 26290d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes begin(); 26390d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes int oldPosition = source.position(); 2640b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes sendCount = IoBridge.sendto(fd, source, 0, isa.getAddress(), isa.getPort()); 265a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes if (sendCount > 0) { 266a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes source.position(oldPosition + sendCount); 267a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes } 26890d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes } finally { 26990d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes end(sendCount >= 0); 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sendCount; 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(ByteBuffer target) throws IOException { 277e3b6fa2bf357f2712ab2ee9e8487f157595ea0c7Elliott Hughes target.checkWritable(); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!target.hasRemaining()) { 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 284f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int readCount = 0; 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target.isDirect() || target.hasArray()) { 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readCount = readImpl(target); 287f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (readCount > 0) { 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project target.position(target.position() + readCount); 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] readArray = new byte[target.remaining()]; 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer readBuffer = ByteBuffer.wrap(readArray); 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readCount = readImpl(readBuffer); 295f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (readCount > 0) { 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project target.put(readArray, 0, readCount); 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readCount; 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 3032620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes public long read(ByteBuffer[] targets, int offset, int length) throws IOException { 304a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(targets.length, offset, length); 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // status must be open and connected 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 3082620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int totalCount = FileChannelImpl.calculateTotalRemaining(targets, offset, length, true); 3092620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes if (totalCount == 0) { 3102620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes return 0; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read data to readBuffer, and then transfer data from readBuffer to 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // targets. 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer readBuffer = ByteBuffer.allocate(totalCount); 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int readCount; 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readCount = readImpl(readBuffer); 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int left = readCount; 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = offset; 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // transfer data from readBuffer to targets 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] readArray = readBuffer.array(); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (left > 0) { 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int putLength = Math.min(targets[index].remaining(), left); 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project targets[index].put(readArray, readCount - left, putLength); 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project index++; 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project left -= putLength; 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readCount; 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from channel, and store the result in the target. 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33423ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes private int readImpl(ByteBuffer dst) throws IOException { 335f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson synchronized (readLock) { 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int readCount = 0; 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 3390b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes readCount = IoBridge.recvfrom(false, fd, dst, 0, null, isConnected()); 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedIOException e) { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // InterruptedIOException will be thrown when timeout. 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(readCount > 0); 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 34623ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes return readCount; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35023ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes @Override public int write(ByteBuffer src) throws IOException { 35123ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes checkNotNull(src); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 35323ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes if (!src.hasRemaining()) { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35723ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes int writeCount = writeImpl(src); 358a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes if (writeCount > 0) { 359a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes src.position(src.position() + writeCount); 360a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes } 36123ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes return writeCount; 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 364f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.DatagramChannel#write(java.nio.ByteBuffer[], int, 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * int) 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 3692620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes public long write(ByteBuffer[] sources, int offset, int length) throws IOException { 370a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(sources.length, offset, length); 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // status must be open and connected 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 3742620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int count = FileChannelImpl.calculateTotalRemaining(sources, offset, length, false); 3752620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes if (count == 0) { 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer writeBuf = ByteBuffer.allocate(count); 379f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int val = offset; val < length + offset; val++) { 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer source = sources[val]; 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int oldPosition = source.position(); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project writeBuf.put(source); 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project source.position(oldPosition); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project writeBuf.flip(); 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = writeImpl(writeBuf); 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int val = offset; 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int written = result; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (result > 0) { 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer source = sources[val]; 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int gap = Math.min(result, source.remaining()); 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project source.position(source.position() + gap); 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project val++; 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result -= gap; 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return written; 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int writeImpl(ByteBuffer buf) throws IOException { 400f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson synchronized (writeLock) { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = 0; 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 4040b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes result = IoBridge.sendto(fd, buf, 0, null, 0); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(result > 0); 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 40890d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes return result; 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41290d96a4f168b7e56cff54dc94dca2f3cde60ebcdElliott Hughes @Override protected synchronized void implCloseSelectableChannel() throws IOException { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connected = false; 414c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson if (socket != null && !socket.isClosed()) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.close(); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 4170b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes IoBridge.closeSocket(fd); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 421a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes @Override protected void implConfigureBlocking(boolean blocking) throws IOException { 422a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes synchronized (blockingLock()) { 423a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes IoUtils.setBlocking(fd, blocking); 424a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes } 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 428f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Status check, must be open. 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkOpen() throws IOException { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 437f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Status check, must be open and connected, for read and write. 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkOpenConnected() throws IOException { 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpen(); 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotYetConnectedException(); 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 447f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Buffer check, must not null 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkNotNull(ByteBuffer source) { 450b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (source == null) { 45186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("source == null"); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 456f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Get the fd for internal use. 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public FileDescriptor getFD() { 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fd; 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The adapter class of DatagramSocket 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class DatagramSocketAdapter extends DatagramSocket { 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The internal datagramChannelImpl. 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private DatagramChannelImpl channelImpl; 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 473f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Constructor initialize the datagramSocketImpl and datagramChannelImpl 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DatagramSocketAdapter(DatagramSocketImpl socketimpl, 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DatagramChannelImpl channelImpl) { 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(socketimpl); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.channelImpl = channelImpl; 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 482f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Get the internal datagramChannelImpl 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DatagramChannel getChannel() { 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl; 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 489f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#isBound() 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isBound() { 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl.isBound; 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 497f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#isConnected() 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isConnected() { 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl.isConnected(); 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 505f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#getInetAddress() 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getInetAddress() { 510b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (channelImpl.connectAddress == null) { 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl.connectAddress.getAddress(); 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 516f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#getLocalAddress() 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getLocalAddress() { 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl.getLocalAddress(); 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 524f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#getPort() 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getPort() { 529b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (channelImpl.connectAddress == null) { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channelImpl.connectAddress.getPort(); 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 535f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#bind(java.net.SocketAddress) 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void bind(SocketAddress localAddr) throws SocketException { 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (channelImpl.isConnected()) { 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AlreadyConnectedException(); 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.bind(localAddr); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channelImpl.isBound = true; 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 547f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#receive(java.net.DatagramPacket) 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void receive(DatagramPacket packet) throws IOException { 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channelImpl.isBlocking()) { 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.receive(packet); 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 558f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#send(java.net.DatagramPacket) 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void send(DatagramPacket packet) throws IOException { 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channelImpl.isBlocking()) { 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.send(packet); 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 569f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#close() 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() { 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (channelImpl) { 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (channelImpl.isOpen()) { 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channelImpl.close(); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Ignore 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 586f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.DatagramSocket#disconnect() 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void disconnect() { 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channelImpl.disconnect(); 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Ignore 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.disconnect(); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 600