/** Handle a connection DROP_DOWN request from the FE. */
  protected void handleDropDown(Connection c, JICPPacket pkt, InetAddress addr, int port) {
    if (myLogger.isLoggable(Logger.INFO)) {
      myLogger.log(Logger.INFO, myID + ": DROP_DOWN request received.");
    }

    try {
      // If the INP connection is down or we have some postponed command
      // to flush, refuse dropping the connection
      if (inpManager.isConnected() && inpManager.isEmpty()) {
        JICPPacket rsp =
            new JICPPacket(JICPProtocol.RESPONSE_TYPE, JICPProtocol.DEFAULT_INFO, null);
        c.writePacket(rsp);

        inpManager.resetConnection();
        outManager.resetConnection();
        connectionDropped = true;
      } else {
        myLogger.log(Logger.WARNING, myID + ": DROP_DOWN request refused.");
        JICPPacket rsp = new JICPPacket(JICPProtocol.ERROR_TYPE, getReconnectInfo(), null);
        c.writePacket(rsp);
      }
    } catch (Exception e) {
      myLogger.log(Logger.WARNING, myID + ": Error writing DROP_DOWN response. " + e);
    }
  }
 private final byte getReconnectInfo() {
   byte info = JICPProtocol.DEFAULT_INFO;
   // If the inpConnection is null request the FrontEnd to reconnect
   if (!inpManager.isConnected()) {
     info |= JICPProtocol.RECONNECT_INFO;
   }
   return info;
 }
  /**
   * This is periodically called by the JICPMediatorManager and is used by this NIOMediator to
   * evaluate the elapsed time without the need of a dedicated thread or timer.
   */
  public final void tick(long currentTime) {
    if (active && !connectionDropped) {
      // 1) If there is a blocking read operation in place check the
      // response timeout
      inpManager.checkResponseTime(currentTime);

      // 2) Evaluate the keep alive
      if (keepAliveTime > 0) {
        if ((currentTime - lastReceivedTime) > (keepAliveTime + RESPONSE_TIMEOUT)) {
          // Missing keep-alive.
          // The OUT connection is no longer valid
          if (outManager.isConnected()) {
            myLogger.log(Logger.WARNING, myID + ": Missing keep-alive");
            outManager.resetConnection();
          }
          // Check the INP connection. Since this method must return
          // asap, does it in a separated Thread
          if (inpManager.isConnected()) {
            Thread t =
                new Thread() {

                  public void run() {
                    try {
                      // JICPPacket pkt = new JICPPacket(JICPProtocol.KEEP_ALIVE_TYPE,
                      // JICPProtocol.DEFAULT_INFO, null);
                      // inpManager.dispatch(pkt, false);
                      inpManager.sendServerKeepAlive();
                      if (myLogger.isLoggable(Logger.CONFIG)) {
                        myLogger.log(Logger.CONFIG, myID + ": IC valid");
                      }
                    } catch (Exception e) {
                      // Just do nothing: the INP connection has been reset
                    }
                  }
                };
            t.start();
          }
        }
      }

      // 3) Evaluate the max disconnection time
      if (outManager.checkMaxDisconnectionTime(currentTime)) {
        myLogger.log(Logger.SEVERE, myID + ": Max disconnection time expired.");
        // Consider as if the FrontEnd has terminated spontaneously -->
        // Kill the above container (this will also kill this NIOBEDispatcher).
        kill();
      }
    }
  }
 public boolean isConnected() {
   return inpManager.isConnected() && outManager.isConnected();
 }