// Path: TCC/src/Dependencias/Message.java
// public class Message implements Serializable {
// 
//     private long chId; //-1 means from client to server, otherwise chId generated by the server
//     private long timestamp, //-1 means from client to server, otherwise timeStamp of the moment when the server receives the message
//             ttl = 2000; //2 seconds TTL
//     private Object data; //can carry any type of object. in this program, i used a sound packet, but it could be a string, a chunk of video, ...
// 
//     public Message(long chId, long timestamp, Object data) {
//         this.chId = chId;
//         this.timestamp = timestamp;
//         this.data = data;
//     }
// 
//     public void setTimestamp(long timestamp) {
//         this.timestamp = timestamp;
//     }
// 
//     public long getChId() {
//         return chId;
//     }
// 
//     public Object getData() {
//         return data;
//     }
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public long getTtl() {
//         return ttl;
//     }
// 
//     public void setTtl(long ttl) {
//         this.ttl = ttl;
//     }
// 
//     public void setChId(long chId) {
//         this.chId = chId;
//     }
// 
// }
// 
// Path: TCC/src/Dependencias/SoundPacket.java
// public class SoundPacket implements Serializable {
// 
//     public static AudioFormat defaultFormat = new AudioFormat(11025f, 8, 1, true, true); //11.025khz, 8bit, mono, signed, big endian (changes nothing in 8 bit) ~8kb/s
//     public static int defaultDataLenght = 1200; //send 1200 samples/packet by default
//     private byte[] data; //actual data. if null, comfort noise will be played
// 
//     public SoundPacket(byte[] data) {
//         this.data = data;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
// }
// 
// Path: TCC/src/Dependencias/Utils.java
// public class Utils {
// 
//     public static void sleep(int ms) {
//         try {
//             Thread.sleep(ms);
//         } catch (InterruptedException ex) {
//         }
//     }
// 
//     public static String getExternalIP() {
//         try {
//             URL myIp = new URL("http://checkip.dyndns.org/");
//             BufferedReader in = new BufferedReader(new InputStreamReader(myIp.openStream()));
//             String s = in.readLine();
//             return s.substring(s.lastIndexOf(":") + 2, s.lastIndexOf("</body>"));
//         } catch (Exception ex) {
//             return "error " + ex;
//         }
//     }
// 
//     public static String getInternalIP() {
//         try {
//             return InetAddress.getLocalHost().getHostAddress();
//         } catch (UnknownHostException ex) {
//             return "error";
//         }
//     }
// }


import Dependencias.Message;
import Dependencias.SoundPacket;
import Dependencias.Utils;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
        } catch (IOException ex) { //connection error, close connection
            try {
                s.close();
                Log.add("ERROR " + getInetAddress() + ":" + getPort() + " " + ex);
            } catch (IOException ex1) {
            }
            stop();
        }
        for (;;) {
            try {
                if (s.getInputStream().available() > 0) { //we got something from the client
                    Message toBroadcast = (Message) in.readObject(); //read data from client
                    if (toBroadcast.getChId() == -1) { //set its chId and timestamp and pass it to the server
                        toBroadcast.setChId(chId);
                        toBroadcast.setTimestamp(System.nanoTime() / 1000000L);
                        serv.addTofilaDeTransmissao(toBroadcast);
                    } else {
                        continue; //invalid message
                    }
                }
                try {
                    if (!toSend.isEmpty()) {
                        Message toClient = toSend.get(0); //we got something to send to the client
                        if (!(toClient.getData() instanceof SoundPacket) || toClient.getTimestamp() + toClient.getTtl() < System.nanoTime() / 1000000L) { //is the message too old or of an unknown type?
                            Log.add("dropping packet from " + toClient.getChId() + " to " + chId);
                            continue;
                        }
                        out.writeObject(toClient); //send the message
                        toSend.remove(toClient); //and remove it from the queue
                    } else {
// Path: TCC/src/Dependencias/Message.java
// public class Message implements Serializable {
// 
//     private long chId; //-1 means from client to server, otherwise chId generated by the server
//     private long timestamp, //-1 means from client to server, otherwise timeStamp of the moment when the server receives the message
//             ttl = 2000; //2 seconds TTL
//     private Object data; //can carry any type of object. in this program, i used a sound packet, but it could be a string, a chunk of video, ...
// 
//     public Message(long chId, long timestamp, Object data) {
//         this.chId = chId;
//         this.timestamp = timestamp;
//         this.data = data;
//     }
// 
//     public void setTimestamp(long timestamp) {
//         this.timestamp = timestamp;
//     }
// 
//     public long getChId() {
//         return chId;
//     }
// 
//     public Object getData() {
//         return data;
//     }
// 
//     public long getTimestamp() {
//         return timestamp;
//     }
// 
//     public long getTtl() {
//         return ttl;
//     }
// 
//     public void setTtl(long ttl) {
//         this.ttl = ttl;
//     }
// 
//     public void setChId(long chId) {
//         this.chId = chId;
//     }
// 
// }
// 
// Path: TCC/src/Dependencias/SoundPacket.java
// public class SoundPacket implements Serializable {
// 
//     public static AudioFormat defaultFormat = new AudioFormat(11025f, 8, 1, true, true); //11.025khz, 8bit, mono, signed, big endian (changes nothing in 8 bit) ~8kb/s
//     public static int defaultDataLenght = 1200; //send 1200 samples/packet by default
//     private byte[] data; //actual data. if null, comfort noise will be played
// 
//     public SoundPacket(byte[] data) {
//         this.data = data;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
// }
// 
// Path: TCC/src/Dependencias/Utils.java
// public class Utils {
// 
//     public static void sleep(int ms) {
//         try {
//             Thread.sleep(ms);
//         } catch (InterruptedException ex) {
//         }
//     }
// 
//     public static String getExternalIP() {
//         try {
//             URL myIp = new URL("http://checkip.dyndns.org/");
//             BufferedReader in = new BufferedReader(new InputStreamReader(myIp.openStream()));
//             String s = in.readLine();
//             return s.substring(s.lastIndexOf(":") + 2, s.lastIndexOf("</body>"));
//         } catch (Exception ex) {
//             return "error " + ex;
//         }
//     }
// 
//     public static String getInternalIP() {
//         try {
//             return InetAddress.getLocalHost().getHostAddress();
//         } catch (UnknownHostException ex) {
//             return "error";
//         }
//     }
// }


// Path: TCC/src/ServidorVoIP/ClientConnection.java
import Dependencias.Message;
import Dependencias.SoundPacket;
import Dependencias.Utils;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;

        } catch (IOException ex) { //connection error, close connection
            try {
                s.close();
                Log.add("ERROR " + getInetAddress() + ":" + getPort() + " " + ex);
            } catch (IOException ex1) {
            }
            stop();
        }
        for (;;) {
            try {
                if (s.getInputStream().available() > 0) { //we got something from the client
                    Message toBroadcast = (Message) in.readObject(); //read data from client
                    if (toBroadcast.getChId() == -1) { //set its chId and timestamp and pass it to the server
                        toBroadcast.setChId(chId);
                        toBroadcast.setTimestamp(System.nanoTime() / 1000000L);
                        serv.addTofilaDeTransmissao(toBroadcast);
                    } else {
                        continue; //invalid message
                    }
                }
                try {
                    if (!toSend.isEmpty()) {
                        Message toClient = toSend.get(0); //we got something to send to the client
                        if (!(toClient.getData() instanceof SoundPacket) || toClient.getTimestamp() + toClient.getTtl() < System.nanoTime() / 1000000L) { //is the message too old or of an unknown type?
                            Log.add("dropping packet from " + toClient.getChId() + " to " + chId);
                            continue;
                        }
                        out.writeObject(toClient); //send the message
                        toSend.remove(toClient); //and remove it from the queue
                    } else {
                        Utils.sleep(10); //avoid busy wait