| package com.android.server.wifi.anqp; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.EOFException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.InetAddress; |
| import java.net.Socket; |
| import java.nio.ByteBuffer; |
| import java.nio.ByteOrder; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Test ANQP code by talking to an ANQP server of a socket. |
| */ |
| public class TestDriver { |
| |
| private static final Constants.ANQPElementType[] QueryElements = { |
| Constants.ANQPElementType.ANQPCapabilityList, |
| Constants.ANQPElementType.ANQPVenueName, |
| Constants.ANQPElementType.ANQPEmergencyNumber, |
| Constants.ANQPElementType.ANQPNwkAuthType, |
| Constants.ANQPElementType.ANQPRoamingConsortium, |
| Constants.ANQPElementType.ANQPIPAddrAvailability, |
| Constants.ANQPElementType.ANQPNAIRealm, |
| Constants.ANQPElementType.ANQP3GPPNetwork, |
| Constants.ANQPElementType.ANQPGeoLoc, |
| Constants.ANQPElementType.ANQPCivicLoc, |
| Constants.ANQPElementType.ANQPLocURI, |
| Constants.ANQPElementType.ANQPDomName, |
| Constants.ANQPElementType.ANQPEmergencyAlert, |
| Constants.ANQPElementType.ANQPTDLSCap, |
| Constants.ANQPElementType.ANQPEmergencyNAI, |
| Constants.ANQPElementType.ANQPNeighborReport, |
| |
| Constants.ANQPElementType.HSCapabilityList, |
| Constants.ANQPElementType.HSFriendlyName, |
| Constants.ANQPElementType.HSWANMetrics, |
| Constants.ANQPElementType.HSConnCapability, |
| Constants.ANQPElementType.HSNAIHomeRealmQuery, |
| Constants.ANQPElementType.HSOperatingclass, |
| Constants.ANQPElementType.HSOSUProviders |
| }; |
| |
| public static void runTest() throws IOException { |
| |
| Set<Constants.ANQPElementType> elements = |
| new HashSet<Constants.ANQPElementType>(QueryElements.length); |
| elements.addAll(Arrays.asList(QueryElements)); |
| |
| ByteBuffer request = ByteBuffer.allocate(8192); |
| request.order(ByteOrder.LITTLE_ENDIAN); |
| int lenPos = request.position(); |
| request.putShort((short) 0); |
| ANQPFactory.buildQueryRequest(elements, request); |
| |
| byte[] requestBytes = prepRequest(lenPos, request); |
| |
| System.out.println( "Connecting..."); |
| Socket sock = new Socket(InetAddress.getLoopbackAddress(), 6104); |
| BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); |
| System.out.println(" ### Querying for " + Arrays.toString(QueryElements)); |
| out.write(requestBytes); |
| out.flush(); |
| |
| BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); |
| ByteBuffer payload = getResponse(in); |
| |
| HSOsuProvidersElement osuProvidersElement = null; |
| List<ANQPElement> anqpResult = ANQPFactory.parsePayload(payload); |
| for ( ANQPElement element : anqpResult ) { |
| System.out.println( element ); |
| if (element.getID() == Constants.ANQPElementType.HSOSUProviders) { |
| osuProvidersElement = (HSOsuProvidersElement)element; |
| } |
| } |
| |
| if ( osuProvidersElement != null ) { |
| for (OSUProvider provider : osuProvidersElement.getProviders()) { |
| for (IconInfo iconInfo : provider.getIcons()) { |
| sendIconRequest(iconInfo.getFileName()); |
| } |
| } |
| } |
| sendIconRequest("doesNotExist.noimg"); |
| |
| sendHomeRealmQuery("nxdomain.abc", "jan.com"); |
| } |
| |
| private static void sendIconRequest(String fileName) throws IOException { |
| ByteBuffer iconRequest = ByteBuffer.allocate(fileName.length()*2) |
| .order(ByteOrder.LITTLE_ENDIAN); |
| int iconPos = iconRequest.position(); |
| iconRequest.putShort((short) 0); |
| ANQPFactory.buildIconRequest(fileName, iconRequest); |
| byte[] iconBytes = prepRequest(iconPos, iconRequest); |
| |
| System.out.println( "Connecting..."); |
| Socket sock = new Socket(InetAddress.getLoopbackAddress(), 6104); |
| BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); |
| |
| System.out.println(" ### Requesting icon '" + fileName + "'"); |
| out.write(iconBytes); |
| out.flush(); |
| |
| BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); |
| ByteBuffer payload = getResponse(in); |
| List<ANQPElement> anqpResult = ANQPFactory.parsePayload(payload); |
| System.out.println("Icon: " + anqpResult ); |
| } |
| |
| private static void sendHomeRealmQuery(String ... realms) throws IOException{ |
| ByteBuffer request = ByteBuffer.allocate(1024).order(ByteOrder.LITTLE_ENDIAN); |
| int iconPos = request.position(); |
| request.putShort((short) 0); |
| ANQPFactory.buildHomeRealmRequest(Arrays.asList(realms), request); |
| byte[] iconBytes = prepRequest(iconPos, request); |
| |
| System.out.println( "Connecting..."); |
| Socket sock = new Socket(InetAddress.getLoopbackAddress(), 6104); |
| BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); |
| |
| System.out.println(" ### Home realm query for " + Arrays.toString(realms)); |
| out.write(iconBytes); |
| out.flush(); |
| |
| BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); |
| ByteBuffer payload = getResponse(in); |
| List<ANQPElement> anqpResult = ANQPFactory.parsePayload(payload); |
| System.out.println("Home realm query: " + anqpResult ); |
| } |
| |
| private static ByteBuffer getResponse(InputStream in) throws IOException { |
| ByteBuffer lengthBuffer = read( in, 2 ); |
| int length = lengthBuffer.getShort() & Constants.SHORT_MASK; |
| System.out.println("Length " + length); |
| |
| return read(in, length); |
| } |
| |
| private static byte[] prepRequest(int pos0, ByteBuffer request) { |
| request.putShort(pos0, (short)( request.limit() - pos0 - Constants.BYTES_IN_SHORT )); |
| byte[] octets = new byte[request.remaining()]; |
| request.get(octets); |
| return octets; |
| } |
| |
| private static ByteBuffer read(InputStream in, int length) throws IOException { |
| byte[] payload = new byte[length]; |
| int position = 0; |
| while ( position < length ) { |
| int amount = in.read(payload, position, length - position); |
| if ( amount <= 0 ) { |
| throw new EOFException("Got " + amount); |
| } |
| position += amount; |
| } |
| return ByteBuffer.wrap(payload).order(ByteOrder.LITTLE_ENDIAN); |
| } |
| |
| public static void main(String[] args) throws IOException { |
| runTest(); |
| } |
| } |