package jp.naist.inet_lab.android.ipv6multicast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

import android.content.Context;
import android.net.wifi.WifiManager;

/**
 * Manage communicating over the IP multicast.
 * 
 * @author yohei-ka
 * 
 */
public class MulticastManager {

    /**
     * An address of the joined multicast group.
     */
    InetAddress group_address;

    /**
     * A socket for communicating over the multicast.
     */
    MulticastSocket socket;

    /**
     * A state of a MulticastLock on the WiFi interface
     */
    protected WifiManager.MulticastLock multicast_lock;

    /**
     * Join the specified multicast group.
     * 
     * @param group_address_hr
     *            An address of the multicast group (Human-readable string)
     * @param local_port
     *            A port number which bind on the local. If specify 0 as a port
     *            number, it may automatically choose a port number from
     *            available ports.
     * @throws UnknownHostException
     *             The specified group address is not found, or invalid format.
     */
    public void join(String group_address_hr, int local_port)
            throws UnknownHostException {
        // Convert the human-readable address to a machine-readable address
        this.group_address = InetAddress.getByName(group_address_hr);

        // Create a socket and join the multicast group
        try {
            this.socket = new MulticastSocket(local_port);
            this.socket.joinGroup(this.group_address);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Join the specified multicast group.
     * 
     * A local port will automatically chosen from available ports.
     * 
     * @see MulticastManager#join(String, int)
     */
    public void join(String group_address_hr) throws UnknownHostException {
        this.join(group_address_hr, 0);
    }

    /**
     * Leave the multicast group that already joined.
     */
    public void leave() {
        try {
            this.socket.leaveGroup(this.group_address);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Send data to the joined multicast group.
     * 
     * @param data
     *            Data that you want to send
     * @param remote_port
     *            Remote-side port number
     * @return Size of the data that I actually sent
     */
    public int sendData(byte[] data, int remote_port) {
        DatagramPacket packet = new DatagramPacket(data, data.length,
                this.group_address, remote_port);
        try {
            this.socket.send(packet);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * Receive data from the joined multicast group.
     * 
     * @param buffer_size
     *            Maximum size by byte that I receive
     * @return Size of the data that I actually received
     */
    public int receiveData(int buffer_size) {
        return 0;
    }

    /**
     * Enable IP multicast on WiFi interface.
     * 
     * A developer who want to use IP multicast on WiFi interface MUST call this
     * method manually before joining a multicast group. Also, you don't forget
     * to call disableMulticastOnWifi(). It may cause battery issue if you
     * forget to call that method.
     * 
     * 
     * @param context
     *            Context of the application
     * @param tag
     *            A tag for identify a state of the WiFi. This tag is only used
     *            internally.
     */
    public void enableMulticastOnWifi(Context context, String tag) {
        WifiManager wifiman = (WifiManager) context
                .getSystemService(android.content.Context.WIFI_SERVICE);
        this.multicast_lock = wifiman.createMulticastLock(tag);
        this.multicast_lock.setReferenceCounted(true);
        this.multicast_lock.acquire();
    }

    /**
     * Disable IP multicast on WiFi interface.
     */
    public void disableMulticastOnWifi() {
        this.multicast_lock.release();
    }

}

@@ -1210,16 +1210,50 @@
 format.%0A
+     * @throws MulticastException%0A
      */%0A
@@ -1329,33 +1329,31 @@
      throws 
-UnknownHo
+Multica
 stException 
@@ -1346,32 +1346,50 @@
 castException %7B%0A
+        try %7B%0A    
         // Conve
@@ -1448,16 +1448,20 @@
 address%0A
+    
         
@@ -1527,24 +1527,28 @@
 );%0A%0A        
+    
 // Create a 
@@ -1583,30 +1583,16 @@
 t group%0A
-        try %7B%0A
         
@@ -1706,34 +1706,43 @@
        %7D catch (
-IO
+UnknownHost
 Exception e) %7B%0A 
@@ -1756,73 +1756,117 @@
     
-// TODO Auto-generated catch block%0A            e.printStackTrace(
+throw new MulticastException(e);%0A        %7D catch (IOException e) %7B%0A            throw new MulticastException(e
 );%0A 
@@ -2004,24 +2004,59 @@
 able ports.%0A
+     * @throws MulticastException %0A
      * %0A    
@@ -2155,33 +2155,31 @@
 _hr) throws 
-UnknownHo
+Multica
 stException 
@@ -2299,33 +2299,94 @@
    *
-/%0A    public void leave()
+ @throws MulticastException %0A     */%0A    public void leave() throws MulticastException
  %7B%0A 
@@ -2504,73 +2504,38 @@
     
-// TODO Auto-generated catch block%0A            e.printStackTrace(
+throw new MulticastException(e
 );%0A 
@@ -2799,16 +2799,51 @@
 ly sent%0A
+     * @throws MulticastException %0A
      */%0A
@@ -2895,16 +2895,42 @@
 te_port)
+ throws MulticastException
  %7B%0A     
@@ -3146,73 +3146,38 @@
     
-// TODO Auto-generated catch block%0A            e.printStackTrace(
+throw new MulticastException(e
 );%0A 

Add handling the networking error, e.g. IOException, UnknownHostException, with MulticastException.