132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong/* 232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * Copyright (C) 2015 The Android Open Source Project 332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * 432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * Licensed under the Apache License, Version 2.0 (the "License"); 532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * you may not use this file except in compliance with the License. 632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * You may obtain a copy of the License at 732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * 832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * http://www.apache.org/licenses/LICENSE-2.0 932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * 1032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * Unless required by applicable law or agreed to in writing, software 1132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * distributed under the License is distributed on an "AS IS" BASIS, 1232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * See the License for the specific language governing permissions and 1432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong * limitations under the License. 1532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong */ 1632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 1732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongpackage android.net; 1832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 19dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewiczimport android.content.Context; 20dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewiczimport android.test.AndroidTestCase; 2132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport android.util.Log; 2232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport libcore.util.HexEncoding; 2332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 2432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.io.IOException; 2532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.net.DatagramPacket; 2632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.net.DatagramSocket; 2732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.net.InetAddress; 2832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.net.SocketException; 2932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wongimport java.util.Arrays; 3032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 3132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 32dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewiczpublic class SntpClientTest extends AndroidTestCase { 3332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final String TAG = "SntpClientTest"; 3432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 3532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final int ORIGINATE_TIME_OFFSET = 24; 3632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final int TRANSMIT_TIME_OFFSET = 40; 3732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 3832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final int NTP_MODE_SERVER = 4; 3932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final int NTP_MODE_BROADCAST = 5; 4032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 4132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // From tcpdump (admittedly, an NTPv4 packet): 4232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // 4332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Server, Leap indicator: (0), Stratum 2 (secondary reference), poll 6 (64s), precision -20 4432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Root Delay: 0.005447, Root dispersion: 0.002716, Reference-ID: 221.253.71.41 4532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Reference Timestamp: 3653932102.507969856 (2015/10/15 14:08:22) 4632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Originator Timestamp: 3653932113.576327741 (2015/10/15 14:08:33) 4732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Receive Timestamp: 3653932113.581012725 (2015/10/15 14:08:33) 4832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Transmit Timestamp: 3653932113.581012725 (2015/10/15 14:08:33) 4932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Originator - Receive Timestamp: +0.004684958 5032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Originator - Transmit Timestamp: +0.004684958 5132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static final String WORKING_VERSION4 = 5232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "240206ec" + 5332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "00000165" + 5432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "000000b2" + 5532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "ddfd4729" + 5632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "d9ca9446820a5000" + 5732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "d9ca9451938a3771" + 5832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "d9ca945194bd3fff" + 5932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong "d9ca945194bd4001"; 6032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 6132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final SntpTestServer mServer = new SntpTestServer(); 6232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final SntpClient mClient = new SntpClient(); 6332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 64dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz private Network mNetwork; 65dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz 66dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz @Override 67dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz protected void setUp() throws Exception { 68dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz super.setUp(); 69dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz ConnectivityManager mCM = getContext().getSystemService(ConnectivityManager.class); 70dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz mNetwork = mCM.getActiveNetwork(); 71dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz } 72dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz 7332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testBasicWorkingSntpClientQuery() throws Exception { 7432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.setServerReply(HexEncoding.decode(WORKING_VERSION4.toCharArray(), false)); 75dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz assertTrue(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork)); 7632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRequestsReceived()); 7732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRepliesSent()); 7832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 7932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 8032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testDnsResolutionFailure() throws Exception { 81dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz assertFalse(mClient.requestTime("ntp.server.doesnotexist.example", 5000, mNetwork)); 8232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 8332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 8432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testTimeoutFailure() throws Exception { 8532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.clearServerReply(); 86dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork)); 8732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRequestsReceived()); 8832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(0, mServer.numRepliesSent()); 8932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 9032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 9132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testIgnoreLeapNoSync() throws Exception { 9232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false); 9332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong reply[0] |= (byte) 0xc0; 9432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.setServerReply(reply); 95dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork)); 9632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRequestsReceived()); 9732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRepliesSent()); 9832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 9932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 10032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testAcceptOnlyServerAndBroadcastModes() throws Exception { 10132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false); 10232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong for (int i = 0; i <= 7; i++) { 10332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final String logMsg = "mode: " + i; 10432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong reply[0] &= (byte) 0xf8; 10532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong reply[0] |= (byte) i; 10632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.setServerReply(reply); 107dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, 108dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz mNetwork); 10932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong switch (i) { 11032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong case NTP_MODE_SERVER: 11132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong case NTP_MODE_BROADCAST: 11232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertTrue(logMsg, rval); 11332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong break; 11432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong default: 11532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertFalse(logMsg, rval); 11632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong break; 11732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 11832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(logMsg, 1, mServer.numRequestsReceived()); 11932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(logMsg, 1, mServer.numRepliesSent()); 12032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 12132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 12232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 12332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testAcceptableStrataOnly() throws Exception { 12432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final int STRATUM_MIN = 1; 12532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final int STRATUM_MAX = 15; 12632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 12732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false); 12832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong for (int i = 0; i < 256; i++) { 12932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final String logMsg = "stratum: " + i; 13032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong reply[1] = (byte) i; 13132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.setServerReply(reply); 132dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, 133dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz mNetwork); 13432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong if (STRATUM_MIN <= i && i <= STRATUM_MAX) { 13532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertTrue(logMsg, rval); 13632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } else { 13732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertFalse(logMsg, rval); 13832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 13932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(logMsg, 1, mServer.numRequestsReceived()); 14032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(logMsg, 1, mServer.numRepliesSent()); 14132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 14232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 14332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 14432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void testZeroTransmitTime() throws Exception { 14532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false); 14632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong Arrays.fill(reply, TRANSMIT_TIME_OFFSET, TRANSMIT_TIME_OFFSET + 8, (byte) 0x00); 14732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mServer.setServerReply(reply); 148dfdd82e84fcd102ab9b4d2233d195a013914c2aeKurt Marcinkiewicz assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork)); 14932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRequestsReceived()); 15032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong assertEquals(1, mServer.numRepliesSent()); 15132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 15232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 15332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 15432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private static class SntpTestServer { 15532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final Object mLock = new Object(); 15632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final DatagramSocket mSocket; 15732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final InetAddress mAddress; 15832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private final int mPort; 15932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private byte[] mReply; 16032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private int mRcvd; 16132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private int mSent; 16232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private Thread mListeningThread; 16332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 16432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public SntpTestServer() { 16532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSocket = makeSocket(); 16632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mAddress = mSocket.getLocalAddress(); 16732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mPort = mSocket.getLocalPort(); 16832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong Log.d(TAG, "testing server listening on (" + mAddress + ", " + mPort + ")"); 16932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 17032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mListeningThread = new Thread() { 17132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void run() { 17232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong while (true) { 17332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong byte[] buffer = new byte[512]; 17432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong DatagramPacket ntpMsg = new DatagramPacket(buffer, buffer.length); 17532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong try { 17632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSocket.receive(ntpMsg); 17732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } catch (IOException e) { 17832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong Log.e(TAG, "datagram receive error: " + e); 17932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong break; 18032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 18132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong synchronized (mLock) { 18232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mRcvd++; 18332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong if (mReply == null) { continue; } 18432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // Copy transmit timestamp into originate timestamp. 18532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong // TODO: bounds checking. 18632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong System.arraycopy(ntpMsg.getData(), TRANSMIT_TIME_OFFSET, 18732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mReply, ORIGINATE_TIME_OFFSET, 8); 18832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong ntpMsg.setData(mReply); 18932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong ntpMsg.setLength(mReply.length); 19032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong try { 19132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSocket.send(ntpMsg); 19232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } catch (IOException e) { 19332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong Log.e(TAG, "datagram send error: " + e); 19432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong break; 19532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 19632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSent++; 19732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 19832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 19932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSocket.close(); 20032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 20132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong }; 20232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mListeningThread.start(); 20332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 20432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 20532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong private DatagramSocket makeSocket() { 20632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong DatagramSocket socket; 20732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong try { 20832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong socket = new DatagramSocket(0, InetAddress.getLoopbackAddress()); 20932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } catch (SocketException e) { 21032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong Log.e(TAG, "Failed to create test server socket: " + e); 21132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong return null; 21232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 21332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong return socket; 21432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 21532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 21632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void clearServerReply() { 21732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong setServerReply(null); 21832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 21932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 22032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public void setServerReply(byte[] reply) { 22132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong synchronized (mLock) { 22232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mReply = reply; 22332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mRcvd = 0; 22432d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong mSent = 0; 22532d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 22632d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 22732d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong 22832d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public InetAddress getAddress() { return mAddress; } 22932d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public int getPort() { return mPort; } 23032d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public int numRequestsReceived() { synchronized (mLock) { return mRcvd; } } 23132d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong public int numRepliesSent() { synchronized (mLock) { return mSent; } } 23232d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong } 23332d52f344aa564154b96cadc2dda3f0de3d0f455Jerry Wong} 234