/* (non-Javadoc)
   * @see madkit.netcomm.MadkitNetworkAgent#handleNetworkMessage(madkit.netcomm.NetworkMessage)
   */
  protected void handleNetworkMessage(NetworkMessage message) {
    switch (message.getType()) {
      case NetworkMessage.SYNCH_REQUEST:
        debug("handling NetworkMessage.SYNCH_REQUEST");
        Vector vec = (Vector) message.getArgument();
        handleSynchRequest(message.getSender(), vec);
        break;
      case NetworkMessage.ROUTE_MESSAGE:
        debug("Routing message");
        sendDistantMessage((KernelMessage) message.getArgument());
        break;

      case NetworkMessage.CONNECT_KERNEL:
        debug("CONNECT_KERNEL received");
        Vector v1 = (Vector) message.getArgument();
        Socket brSocket = (Socket) v1.get(0);
        KernelAddress id = (KernelAddress) v1.get(1); // check if the kernel is known
        SocketKernel distantSK = (SocketKernel) v1.get(2);

        if (id != null && routeTable.containsKey(id)) {
          debug("broadcast from known kernel");
          try {
            brSocket.close();
          } catch (IOException e) {
            debug(e.toString());
          }
          break;
        }
        launchNetConfigConnection(distantSK, brSocket, id);
        break;
      case NetworkMessage.KERNEL_DISCONNECTED:
        routeTable.remove(((KernelAddress) message.getArgument()).getID());
        break;
      case NetworkMessage.UPDATE_ROUTE:
        debug("UPDATE_ROUTE");
        Vector v = (Vector) message.getArgument();
        KernelAddress addr = (KernelAddress) v.get(0);
        AgentAddress p2p = (AgentAddress) v.get(1);
        DistantKernelInformation info = (DistantKernelInformation) routeTable.remove(addr.getID());
        info.setP2PAgent(p2p);
        info.setProtocol((String) v.get(2));
        routeTable.put(addr.getID(), info);
        sendMessage(
            getAgentWithRole(community, group, "netagent"),
            new NetworkMessage(NetworkMessage.UPDATE_ROUTE, v));
        sendMessage(
            message.getSender(), new NetworkMessage(NetworkMessage.UPDATE_ROUTE_DONE, addr));
        break;
      default:
        debug("unknown NetworkMessage Received");
        debug(message.toString());
        break;
    }
  }
 /**
  * Launches a new NetConfigAgent to configure and establish a connection with a distant Kernel.
  *
  * @param distantSocket SocketKernel of the distant kernel.
  */
 private void launchNetConfigConnection(
     SocketKernel distantSocket, Socket socket, KernelAddress dka) {
   try {
     if (socket == null) {
       socket = new Socket(distantSocket.getHost(), distantSocket.getPort());
     }
     NetConfigAgent configa =
         new NetConfigAgent(socket, myInfo, distantSocket, new HashSet(routeTable.values()));
     String name = "netconfigAgent@";
     if (distantSocket != null) {
       name += distantSocket.getHost() + distantSocket.getPort();
     }
     launchAgent(configa, name, false);
     if (dka != null)
       System.err.println("This agent will be connected to me ! " + dka.getInformation());
     pause(500); // Needed unless some agents couldn't be launched when we invoke them
   } catch (UnknownHostException e) {
     debug("UnknownHostException caught " + e);
   } catch (IOException e) {
     debug("IOException caught " + e);
   } catch (Exception e) {
     System.err.println("Connexion failed for this reason : " + e.getMessage());
   }
 }
 /**
  * @param address
  * @return
  */
 private boolean isConfiguring(KernelAddress address) {
   return routeTable.containsKey(address.getID());
 }
  /**
   * Adds a route to the routing table. Before adding a new kernel, it checks if the kernel's ID
   * already existes in the routing table. if it does, no action is taken and returns false.
   *
   * @param ka KernelAddress of the distant kernel to add.
   * @param addr AgentAddress of the P2PAgent responsable for the connection with the kernel
   * @param dkinfo SocketKernel of the distant Kernel
   * @return true iff the distant kernel was add. false if the kernel already has an entry in the
   *     route table
   */
  private boolean addRoute(
      KernelAddress ka, AgentAddress addr, SocketKernel dkinfo, String protocol) {
    DistantKernelInformation tmp = (DistantKernelInformation) routeTable.get(ka.getID());
    if (tmp != null) {
      if (tmp.getProtocol().equals(CONFIG)) {
        if (protocol.equals(CONFIG)) {
          // Added by saber
          KernelAddress agency = tmp.getDistantKernelAddress();
          if (!agency.getKernelName().equals(ka.getKernelName())
              || (agency.supportMobility()
                  != ka.supportMobility())) // the distantKernel has changed its name or mobility
          // aspect
          {
            agency.setKernelName(ka.getKernelName());
            if (ka.supportMobility()) agency.enableMobility();
            else agency.disableMobility();
            return true;
          } else // end of saber modification
          return false;
        } else {
          routeTable.remove(ka.getID());
          updateDistantAgencies();
        }
      } else {
        debug("Kernel " + ka + " already added");
        return false;
      }
    }

    debug("adding new kernel " + ka.getID());
    routeTable.put(ka.getID(), new DistantKernelInformation(ka, addr, dkinfo, protocol));
    updateDistantAgencies();

    if (!protocol.equals(CONFIG)) sendConnectedKernelInformation(dkinfo, ka, addr, protocol);
    return true;
  }
 private AgentAddress getP2PAddress(KernelAddress kernelAddress) {
   DistantKernelInformation info =
       (DistantKernelInformation) routeTable.get(kernelAddress.getID());
   return info.getP2PAgent();
 }