// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/AppPacket.java
// public class AppPacket extends Packet {
//     public static String CID = "app";
//     public static String TYPE = "pack";
// 
//     public AppPacket() {
//         cid = CID;
//         type = TYPE;
//         uid = 0;
//     }
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/Packet.java
// public class Packet {
//     @SerializedName("t")
//     public String type;
// 
//     public String tcid;
//     public Integer i;
//     public Integer uid;
//     public String cid;
// 
//     @SerializedName("pack")
//     public String encryptedPack;
// 
//     public transient Pack pack;
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Utils.java
// public class Utils {
// 
//     public static class Unzipped {
//         public final String[] keys;
//         public final Integer[] values;
// 
//         public Unzipped(String[] keys, Integer[] values) {
//             this.keys = keys;
//             this.values = values;
//         }
//     }
// 
//     public static Map<String, Integer> zip(String[] keys, Integer[] values) throws IllegalArgumentException {
//         if (keys.length != values.length)
//             throw new IllegalArgumentException("Length of keys and values must match");
// 
//         Map<String, Integer> zipped = new HashMap<>();
//         for (int i = 0; i < keys.length; i++) {
//             zipped.put(keys[i], values[i]);
//         }
// 
//         return zipped;
//     }
// 
//     public static Unzipped unzip(Map<String, Integer> map) {
//         return new Unzipped(map.keySet().toArray(new String[0]), map.values().toArray(new Integer[0]));
//     }
// 
//     public static Map<String, Integer> getValues(DatPack pack) {
//         return zip(pack.keys, pack.values);
//     }
// 
//     public static String serializePacket(Packet packet, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         Gson gson = gsonBuilder.create();
// 
//         if (packet.pack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = gson.toJson(packet.pack);
//             packet.encryptedPack = tomikaa.greeremote.Gree.Crypto.encrypt(plainPack, key);
//         }
// 
//         return gson.toJson(packet);
//     }
// 
//     public static Packet deserializePacket(String jsonString, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         gsonBuilder.registerTypeAdapter(Pack.class, new PackDeserializer());
// 
//         Gson gson = gsonBuilder.create();
// 
//         Packet packet = gson.fromJson(jsonString, Packet.class);
// 
//         if (packet.encryptedPack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = Crypto.decrypt(packet.encryptedPack, key);
//             packet.pack = gson.fromJson(plainPack, Pack.class);
//         }
// 
//         return packet;
//     }
// 
//     private static String getKey(DeviceKeyChain keyChain, Packet packet) {
//         String key = Crypto.GENERIC_KEY;
// 
//         Log.i("getKey", String.format("packet.cid: %s, packet.tcid: %s", packet.cid, packet.tcid));
// 
//         if (keyChain != null) {
//             if (keyChain.containsKey(packet.cid)) {
//                 key = keyChain.getKey(packet.cid);
//             } else if (keyChain.containsKey(packet.tcid)) {
//                 key = keyChain.getKey(packet.tcid);
//             }
//         }
// 
//         return key;
//     }
// }


import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import tomikaa.greeremote.Gree.Packets.AppPacket;
import tomikaa.greeremote.Gree.Packets.Packet;
import tomikaa.greeremote.Gree.Utils;
                InetAddress.getByName("255.255.255.255"), DATAGRAM_PORT);

        mSocket.send(datagramPacket);
    }

    private Packet[] receivePackets(int timeout) throws IOException {
        mSocket.setSoTimeout(timeout);

        ArrayList<Packet> responses = new ArrayList<>();
        ArrayList<DatagramPacket> datagramPackets = new ArrayList<>();

        try {
            while (true) {
                byte[] buffer = new byte[65536];
                DatagramPacket datagramPacket = new DatagramPacket(buffer, 65536);

                mSocket.receive(datagramPacket);

                datagramPackets.add(datagramPacket);
            }
        } catch (Exception e) {
            Log.w(LOG_TAG, "Exception: " + e.getMessage());
        }

        for (DatagramPacket p : datagramPackets) {
            String data = new String(p.getData(), 0, p.getLength());
            InetAddress address = p.getAddress();

            Log.d(LOG_TAG, String.format("Received response from %s: %s", address.getHostAddress(), data));

// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/AppPacket.java
// public class AppPacket extends Packet {
//     public static String CID = "app";
//     public static String TYPE = "pack";
// 
//     public AppPacket() {
//         cid = CID;
//         type = TYPE;
//         uid = 0;
//     }
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/Packet.java
// public class Packet {
//     @SerializedName("t")
//     public String type;
// 
//     public String tcid;
//     public Integer i;
//     public Integer uid;
//     public String cid;
// 
//     @SerializedName("pack")
//     public String encryptedPack;
// 
//     public transient Pack pack;
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Utils.java
// public class Utils {
// 
//     public static class Unzipped {
//         public final String[] keys;
//         public final Integer[] values;
// 
//         public Unzipped(String[] keys, Integer[] values) {
//             this.keys = keys;
//             this.values = values;
//         }
//     }
// 
//     public static Map<String, Integer> zip(String[] keys, Integer[] values) throws IllegalArgumentException {
//         if (keys.length != values.length)
//             throw new IllegalArgumentException("Length of keys and values must match");
// 
//         Map<String, Integer> zipped = new HashMap<>();
//         for (int i = 0; i < keys.length; i++) {
//             zipped.put(keys[i], values[i]);
//         }
// 
//         return zipped;
//     }
// 
//     public static Unzipped unzip(Map<String, Integer> map) {
//         return new Unzipped(map.keySet().toArray(new String[0]), map.values().toArray(new Integer[0]));
//     }
// 
//     public static Map<String, Integer> getValues(DatPack pack) {
//         return zip(pack.keys, pack.values);
//     }
// 
//     public static String serializePacket(Packet packet, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         Gson gson = gsonBuilder.create();
// 
//         if (packet.pack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = gson.toJson(packet.pack);
//             packet.encryptedPack = tomikaa.greeremote.Gree.Crypto.encrypt(plainPack, key);
//         }
// 
//         return gson.toJson(packet);
//     }
// 
//     public static Packet deserializePacket(String jsonString, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         gsonBuilder.registerTypeAdapter(Pack.class, new PackDeserializer());
// 
//         Gson gson = gsonBuilder.create();
// 
//         Packet packet = gson.fromJson(jsonString, Packet.class);
// 
//         if (packet.encryptedPack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = Crypto.decrypt(packet.encryptedPack, key);
//             packet.pack = gson.fromJson(plainPack, Pack.class);
//         }
// 
//         return packet;
//     }
// 
//     private static String getKey(DeviceKeyChain keyChain, Packet packet) {
//         String key = Crypto.GENERIC_KEY;
// 
//         Log.i("getKey", String.format("packet.cid: %s, packet.tcid: %s", packet.cid, packet.tcid));
// 
//         if (keyChain != null) {
//             if (keyChain.containsKey(packet.cid)) {
//                 key = keyChain.getKey(packet.cid);
//             } else if (keyChain.containsKey(packet.tcid)) {
//                 key = keyChain.getKey(packet.tcid);
//             }
//         }
// 
//         return key;
//     }
// }


// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Network/AsyncCommunicator.java
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import tomikaa.greeremote.Gree.Packets.AppPacket;
import tomikaa.greeremote.Gree.Packets.Packet;
import tomikaa.greeremote.Gree.Utils;

                InetAddress.getByName("255.255.255.255"), DATAGRAM_PORT);

        mSocket.send(datagramPacket);
    }

    private Packet[] receivePackets(int timeout) throws IOException {
        mSocket.setSoTimeout(timeout);

        ArrayList<Packet> responses = new ArrayList<>();
        ArrayList<DatagramPacket> datagramPackets = new ArrayList<>();

        try {
            while (true) {
                byte[] buffer = new byte[65536];
                DatagramPacket datagramPacket = new DatagramPacket(buffer, 65536);

                mSocket.receive(datagramPacket);

                datagramPackets.add(datagramPacket);
            }
        } catch (Exception e) {
            Log.w(LOG_TAG, "Exception: " + e.getMessage());
        }

        for (DatagramPacket p : datagramPackets) {
            String data = new String(p.getData(), 0, p.getLength());
            InetAddress address = p.getAddress();

            Log.d(LOG_TAG, String.format("Received response from %s: %s", address.getHostAddress(), data));

            Packet response = Utils.deserializePacket(data, mKeyChain);