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();
}
}