package org.microg.networklocation.backends.apple;
import com.squareup.wire.Wire;
import org.microg.networklocation.helper.Networking;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class LocationRetriever {
public static final byte[] APPLE_MAGIC_BYTES =
{0, 1, 0, 5, 101, 110, 95, 85, 83, 0, 0, 0, 11, 52, 46, 50, 46, 49, 46, 56, 67, 49, 52, 56, 0, 0, 0, 1, 0,
0, 0};
private static final String SERVICE_URL = "https://iphone-services.apple.com/clls/wloc";
private static final String HTTP_FIELD_CONTENT_TYPE = "Content-Type";
private static final String HTTP_FIELD_CONTENT_LENGTH = "Content-Length";
private static final String CONTENT_TYPE_URLENCODED = "application/x-www-form-urlencoded";
private final Wire wire = new Wire();
private static byte[] combineBytes(byte[] first, byte[] second, byte divider) {
byte[] bytes = new byte[first.length + second.length + 1];
System.arraycopy(first, 0, bytes, 0, first.length);
bytes[first.length] = divider;
System.arraycopy(second, 0, bytes, first.length + 1, second.length);
return bytes;
}
private static HttpsURLConnection createConnection() throws IOException {
return createConnection(SERVICE_URL);
}
private static HttpsURLConnection createConnection(String url) throws IOException {
return createConnection(new URL(url));
}
private static HttpsURLConnection createConnection(URL url) throws IOException {
return (HttpsURLConnection) url.openConnection();
}
private static Request createRequest(String... macs) {
List<Request.RequestWifi> wifis = new ArrayList<Request.RequestWifi>();
for (final String mac : macs) {
wifis.add(new Request.RequestWifi.Builder().mac(mac).build());
}
return new Request.Builder().source("com.apple.maps").unknown3(0).unknown4(0).wifis(wifis).build();
}
private static void prepareConnection(HttpsURLConnection connection, int length) throws ProtocolException {
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty(HTTP_FIELD_CONTENT_TYPE, CONTENT_TYPE_URLENCODED);
connection.setRequestProperty(HTTP_FIELD_CONTENT_LENGTH, String.valueOf(length));
}
public Response retrieveLocations(String... macs) throws IOException {
Request request = createRequest(macs);
byte[] byteb = request.toByteArray();
byte[] bytes = combineBytes(APPLE_MAGIC_BYTES, byteb, (byte) byteb.length);
HttpsURLConnection connection = createConnection();
prepareConnection(connection, bytes.length);
OutputStream out = connection.getOutputStream();
out.write(bytes);
out.flush();
out.close();
InputStream in = connection.getInputStream();
in.skip(10);
Response response = wire.parseFrom(Networking.readStreamToEnd(in), Response.class);
in.close();
return response;
}
public Response retrieveLocations(Collection<String> macs) throws IOException {
return retrieveLocations(macs.toArray(new String[macs.size()]));
}
}