/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits r?serv?s.
 * Ce logiciel est propri?t? de Sun Microsystems, Inc.
 * Distribu? par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)MfDiscoveryActualResponder.java 1.11     05/04/20 SMI"
 *
 */


package com.sun.mfwk.discovery;

import java.util.*;
import java.net.*;
import java.io.*;

import com.sun.mfwk.discovery.*;

// Java ES-MF log
import com.sun.mfwk.util.log.MfLogService;
import java.util.logging.Logger;

public class MfDiscoveryActualResponder extends MfDiscoveryCommon {

  // Msg to send in Protocol
  private MfMcastMessage myMsgToSend = null;
  
// ----------------------------------------------------------  
// Constructor
// ----------------------------------------------------------
    public MfDiscoveryActualResponder(String multicastGroup, int multicastPort, MfMcastMessage msgToSend) throws IOException {
					
        // Set multicastSocket parameters
     	super(multicastGroup,multicastPort);
        logger.entering("MfDiscoveryActualResponder", "MfDiscoveryActualResponder (after super)");        
        // Retrieve Mcast Message to apply
        myMsgToSend = msgToSend;
        logger.info("group = " + multicastGroup  + 
                    ", port  = " + multicastPort ); 
        logger.exiting("MfDiscoveryActualResponder", "MfDiscoveryActualResponder");        

    }

// ------------------------------------------
// protocol implemented by the derived object 
// ------------------------------------------
    
    final void applyProtocol() {
        logger.entering("MfDiscoveryActualResponder", "applyProtocol");        
        while (true) {
            try {
                String Packet;
                byte[] inbuf = new byte [65526]; // maximum size of a UDP packet = 64Kbytes
                DatagramPacket packet = new DatagramPacket(inbuf, inbuf.length);
                
                //Blocks untill a packet is received or timeout expires (5s)
                //if timeout expires we check in the Exception below wether
                //the thread should be stopped or not

                logger.finest("waiting for Packet");                
                setSoTimeout(5000);
                receive(packet);
                logger.finer("Packet received");
                
                // Data is now in inbuf
                int numBytesReceived = packet.getLength();
                logger.finer("Packet received length:" + numBytesReceived);
                
                // process the received message
                
                // Transfers it in receivedData array first
                // as the arrayy returned by getData is the full packet (65536)
                // even though we received only 120 bytes for instance
                
                byte[] receivedData = new byte [numBytesReceived];
                System.arraycopy(packet.getData(), 0, receivedData, 0, numBytesReceived);
                
                //checks if it is a Java ES-MF Mcast Packet and if it is a DISC
                //Packet, if not, discards it
                // DISC triggers the sending of a RESP
                
                if ((MfMcastMessage.isMcastMessage(receivedData)) && (MfMcastMessage.isDiscoveryPacket(receivedData))) {
                    //creates a new Mcast object
                    MfMcastMessage receivedMsg = new MfMcastMessage(receivedData);
                    logger.finer("received packet type:" + receivedMsg.getMsgType());
                    //BS TBD... cleanup!!! make a send function...
                    logger.finer("sending packet" + MfMcastMessage.RESPONSE + "\n") ;
                    byte myPacketByteArray[];
                    myPacketByteArray =   myMsgToSend.getByteArrayMcastMessage();
                    DatagramPacket myPacket = new DatagramPacket(myPacketByteArray, myPacketByteArray.length,multicastGroup,multicastPort);
                    send(myPacket);
                }
            } catch (java.net.SocketTimeoutException ste){
                //check if cacao module has been stopped, if so, then we close the
                // Mcast channel and return, otherwise we continue.
                if (super.stopListeningThread) {
                    close();
                    logger.info ("stopping listening thread");                  
                    return;
                }            
            } catch (java.io.IOException e) {
                logger.severe("Problem occured while receiving/sending/processing Mcast Message: " + e.getMessage());
            }
        }
    }
}

