/* AWSIotP2PManager.java Copyright (c) 2016 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.awsiot.cores.p2p; import android.content.Context; import android.net.wifi.WifiManager; import android.util.Log; import org.deviceconnect.android.deviceplugin.awsiot.remote.BuildConfig; import org.deviceconnect.android.deviceplugin.awsiot.udt.P2PConnection; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public class AWSIotP2PManager { private static final boolean DEBUG = BuildConfig.DEBUG; private static final String TAG = "AWS"; public static final String KEY_CONNECTION_ID = "connectionId"; public static final String KEY_GLOBAL = "global"; public static final String KEY_LOCAL = "local"; public static final String KEY_ADDRESS = "address"; public static final String KEY_PORT = "port"; public void onReceivedSignaling(final String signaling) { } public void onNotifySignaling(final String signaling) { } protected P2PConnection createP2PConnection() { return new P2PConnection(); } protected P2PConnection createP2PConnection(final String signal, final P2PConnection.OnP2PConnectionListener listener) { if (DEBUG) { Log.i(TAG, "createP2PConnection: " + signal); } try { JSONObject json = new JSONObject(signal); JSONObject global = json.getJSONObject(AWSIotP2PManager.KEY_GLOBAL); JSONObject local = json.getJSONObject(AWSIotP2PManager.KEY_LOCAL); P2PConnection connection = createP2PConnection(); connection.setOnP2PConnectionListener(listener); for (int i = 0; i < 3; i++) { if (connect(connection, global, local)) { return connection; } } return null; } catch (JSONException e) { if (DEBUG) { Log.e(TAG, "Invalid the json.", e); } return null; } } private boolean connect(final P2PConnection connection, final JSONObject global, final JSONObject local) throws JSONException { String address = global.getString(AWSIotP2PManager.KEY_ADDRESS); int port = global.getInt(AWSIotP2PManager.KEY_PORT); try { connection.connect(address, port); } catch (IOException e) { address = local.getString(AWSIotP2PManager.KEY_ADDRESS); port = local.getInt(AWSIotP2PManager.KEY_PORT); try { connection.connect(address, port); } catch (IOException e1) { try { connection.close(); } catch (IOException e2) { if (DEBUG) { Log.w(TAG, "", e2); } } return false; } } return true; } protected String createSignaling(final Context context, final int connectionId, final String address, final int port) { try { JSONObject json = new JSONObject(); json.put(KEY_CONNECTION_ID, connectionId); JSONObject global = new JSONObject(); global.put(KEY_ADDRESS, address); global.put(KEY_PORT, port); json.put(KEY_GLOBAL, global); JSONObject local = new JSONObject(); local.put(KEY_ADDRESS, getIPAddress(context)); local.put(KEY_PORT, port); json.put(KEY_LOCAL, local); return json.toString(); } catch (JSONException e) { if (DEBUG) { Log.e(TAG, "", e); } } return null; } protected int getConnectionId(final String signal) { try { JSONObject json = new JSONObject(signal); return json.getInt(AWSIotP2PManager.KEY_CONNECTION_ID); } catch (JSONException e) { return -1; } } protected String generateInternalServerError() { return generateErrorHeader("500", "<html><head><title>500 - Error</title></head><body>500 - Error</body></html>"); } private String generateErrorHeader(final String status, final String body) { SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT")); StringBuilder sb = new StringBuilder(); sb.append("HTTP/1.1 " + status + " OK\r\n"); sb.append("Server: Server\r\n"); sb.append("Content-length: "+ body.getBytes().length + "\r\n"); sb.append("Date: " + gmtFrmt.format(new Date()) + "\r\n"); sb.append("Connection: close\r\n"); sb.append("\r\n"); sb.append(body); return sb.toString(); } protected int findHeaderEnd(final byte[] buf, final int rlen) { int splitbyte = 0; while (splitbyte + 1 < rlen) { // RFC2616 if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n' && splitbyte + 3 < rlen && buf[splitbyte + 2] == '\r' && buf[splitbyte + 3] == '\n') { return splitbyte + 4; } // tolerance if (buf[splitbyte] == '\n' && buf[splitbyte + 1] == '\n') { return splitbyte + 2; } splitbyte++; } return 0; } private static String getIPAddress(final Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }