1 package com.example.imsmediatestingapp;
2 
3 import android.util.Log;
4 
5 import java.io.ByteArrayOutputStream;
6 import java.io.IOException;
7 import java.io.ObjectOutputStream;
8 import java.net.DatagramPacket;
9 import java.net.DatagramSocket;
10 import java.net.InetAddress;
11 
12 /**
13  * The HandshakeSender is used to send the DeviceInfo and confirmation message during the handshake
14  * process, via DatagramPackets.
15  */
16 public class HandshakeSender implements Runnable {
17 
18     private final InetAddress remoteAddress;
19     private final int remotePort;
20     private byte[] data;
21     private int dataLength;
22     DatagramSocket sendSocket;
23     private static final String TAG = HandshakeSender.class.getName();
24 
HandshakeSender(InetAddress remoteAddress, int remotePort)25     public HandshakeSender(InetAddress remoteAddress, int remotePort) {
26         this.remoteAddress = remoteAddress;
27         this.remotePort = remotePort;
28     }
29 
30     @Override
run()31     public void run() {
32         try {
33             sendSocket = new DatagramSocket();
34             sendSocket.setReuseAddress(true);
35 
36             DatagramPacket packet = new DatagramPacket(data, dataLength, remoteAddress, remotePort);
37             sendSocket.send(packet);
38             Log.d(TAG, "Packet has been set to " + remoteAddress.getHostName() + ":" + remotePort);
39             close();
40         } catch (IOException e) {
41             Log.e(TAG, "IOException: " + e.toString());
42         }
43     }
44 
45     /**
46      * Sets the passed object to the data the Datagram socket will send.
47      * @param data DeviceInfo of the device or the conformation String
48      */
setData(Object data)49     public void setData(Object data) {
50         if (data instanceof String) {
51             String stringData = (String) data;
52             byte[] stringBytes = serializeData(stringData);
53             this.data = stringBytes;
54             this.dataLength = stringBytes.length;
55 
56             Log.d(TAG, "Data set as type String");
57         } else if(data instanceof DeviceInfo) {
58             DeviceInfo deviceInfoData = (DeviceInfo) data;
59             byte[] deviceInfoBytes = serializeData(deviceInfoData);
60             this.data = deviceInfoBytes;
61             this.dataLength = deviceInfoBytes.length;
62 
63             Log.d(TAG, "Data set as type DeviceInfo");
64         } else {
65             Log.e(TAG, "Data set was was not type String or DeviceInfo");
66         }
67     }
68 
close()69     public void close() {
70         sendSocket.close();
71     }
72 
73     /**
74      * Turns the given object into a byte array so it can be send through Datagram packet.
75      * @param data the object to turn into a byte array
76      * @return the byte array of the converted data
77      */
serializeData(Object data)78     public byte[] serializeData(Object data) {
79         ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
80         try {
81             ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
82             objectOutputStream.writeObject(data);
83             objectOutputStream.reset();
84             objectOutputStream.close();
85             return byteOutputStream.toByteArray();
86         } catch (IOException e) {
87             Log.e(TAG, e.getLocalizedMessage());
88         }
89         return null;
90     }
91 
92 }
93