/**
   * Called by Status implementations to retrieve the pending notifications and send them to the
   * connected client device
   */
  protected void managePendingNotificationMessage() {
    try {

      String username = (String) session.getAttribute(ATTRIBUTE_USERNAME);
      String deviceId = (String) session.getAttribute(ATTRIBUTE_DEVID);
      if (logger.isTraceEnabled()) {
        logger.trace(
            "Retrieving pending notifications for user '"
                + username
                + "', deviceId: '"
                + deviceId
                + "'");
      }

      com.funambol.framework.notification.Message message =
          pendingNotificationManager.getMessageFromPendingNotifications(username, deviceId);

      if (message == null) {
        if (logger.isTraceEnabled()) {
          logger.trace("No pending notification messages present.");
        }
      } else {
        sendSyncMessage(message.getMessageContent());

        pendingNotificationManager.deletePendingNotifications(
            username, deviceId, message.getSyncSources());
        if (logger.isTraceEnabled()) {
          logger.trace("Pending notifications sent to device " + deviceId);
        }
      }
    } catch (PendingNotificationException ex) {
      logger.error("Error while retrieving pending notification messages", ex);
    }
  }
  /**
   * Forward the authentication request to the Authentication Manager
   *
   * @return
   * @throws com.funambol.ctp.server.authentication.AuthenticationException
   */
  protected AuthorizationResponse forwardAuthenticationRequest() throws AuthenticationException {

    String username = (String) session.getAttribute(ATTRIBUTE_USERNAME);
    String deviceId = (String) session.getAttribute(ATTRIBUTE_DEVID);
    String credential = (String) session.getAttribute(ATTRIBUTE_CRED);
    if (logger.isTraceEnabled()) {
      logger.trace("Authenticating user '" + username + "', deviceId: '" + deviceId + "'");
    }
    AuthorizationResponse result =
        authenticationManager.authenticate(username, deviceId, credential);
    return result;
  }
  protected void forwardSubscription() {
    String deviceId = (String) session.getAttribute(ATTRIBUTE_DEVID);
    if (deviceId == null || "".equals(deviceId)) {
      logger.error("Unable to retrieve device id from session attributes");
      closeSession();
      return;
    }

    dispatcher.subscribe(deviceId, this);
    if (logger.isTraceEnabled()) {
      logger.trace("Subscribed notification for device " + deviceId);
    }
  }
  @Override
  protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out)
      throws Exception {
    // Get the XML light parser from the IoSession
    XMLLightweightParser parser =
        (XMLLightweightParser) session.getAttribute(ConnectionHandler.XML_PARSER);
    // Parse as many stanzas as possible from the received data
    parser.read(in);

    if (parser.areThereMsgs()) {
      for (String stanza : parser.getMsgs()) {
        out.write(stanza);
      }
    }
    return !in.hasRemaining();
  }
 /**
  * Returns the Device ID associated with the session
  *
  * @return the device id
  */
 public String getDeviceId() {
   return (String) session.getAttribute(ATTRIBUTE_DEVID);
 }
 /**
  * Returns the username associated with the session
  *
  * @return the username
  */
 public String getUserName() {
   return (String) session.getAttribute(ATTRIBUTE_USERNAME);
 }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.mina.common.IoFilterAdapter#messageReceived(org.apache.mina.common.IoFilter.NextFilter,
   *      org.apache.mina.common.IoSession, java.lang.Object)
   */
  @Override
  public void messageReceived(NextFilter nextFilter, IoSession session, Object message)
      throws Exception {
    if (!(message instanceof RtspRequest)) {
      // Shouldn't happen
      log.warn("Object message is not a RTSP request");
      return;
    }

    if (session.getAttribute(ATTR) != null) {
      // Client already autheticated
      log.debug("Already authenticaed: {}", session.getAttribute(ATTR));
      nextFilter.messageReceived(session, message);
    }

    String authString = ((RtspMessage) message).getHeader("Proxy-Authorization");

    if (authString == null) {
      log.debug("RTSP message: \n{}", message);
      final RtspResponse response =
          RtspResponse.errorResponse(RtspCode.ProxyAuthenticationRequired);

      response.setHeader("Proxy-Authenticate", scheme.getName() + " " + scheme.getChallenge());

      log.debug("Client MUST athenticate to Proxy: \n{}", response);
      session.write(response);
      return;
    }

    if (!validateAuthenticationScheme(authString)) {
      log.debug("Authentication scheme not valid: {}", authString);
      RtspResponse response = RtspResponse.errorResponse(RtspCode.BadRequest);
      session.write(response);
      return;
    }

    log.debug("RTSP message: \n{}", message);

    // Check the authentication credentials
    final Credentials credentials = scheme.getCredentials((RtspMessage) message);

    boolean authenticationOk = false;
    if (credentials != null) {
      String password = provider.getPassword(credentials.getUserName());
      if (password != null && scheme.computeAuthentication(credentials, password)) {
        authenticationOk = true;
      }
    }

    if (!authenticationOk) {
      log.info("Authentication failed for user: {}", credentials);
      RtspResponse response = RtspResponse.errorResponse(RtspCode.ProxyAuthenticationRequired);
      response.setHeader("Proxy-Authenticate", scheme.getName() + " " + scheme.getChallenge());

      session.write(response);
      return;
    }

    log.debug("Authentication successfull for user: {}", credentials);

    /*
     * Mark the session with an "authenticated" attribute. This will prevent
     * the check for the credentials for every message received.
     */
    session.setAttribute(ATTR, credentials.getUserName());

    // Forward message
    nextFilter.messageReceived(session, message);
  }