示例#1
0
  /*
   * This method handles:
   * - Receiving incoming messages
   * - Signalling the message
   * - Setting up the UINICQSubType for the ACK
   * (the actual ACK is sent in the caller - dependent on whether it
   *  was direct/thru server)
   */
  bool MessageHandler::handleIncoming(ICQSubType *ist, time_t t)
  {
    ContactRef contact;
    bool advanced, ack = false;

    if (ist->getType() == MSG_Type_FT)
    {
      ostringstream ostr;
      ostr << "FileTransfer request through server." <<endl;
      SignalLog( LogEvent::WARN, ostr.str() );
      //handleIncomingFT(static_cast<FTICQSubType*>(ist));
      return false;
    }
    
    UINICQSubType *uist = dynamic_cast<UINICQSubType*>(ist);
    MessageEvent *ev = ICQSubTypeToEvent(ist, contact, advanced);
    ICQMessageEvent *mev = dynamic_cast<ICQMessageEvent*>(ev);

    Status st = m_self_contact->getStatus();

    if (!advanced) {
      /* mark all non-advanced (ICQ) messages when in Occupied/DND as 'to
       * contact list', so they can be guaranteed to arrive, as they should
       * never be turned down (no ack is sent back) */
      if (mev != NULL && (st == STATUS_OCCUPIED || st == STATUS_DND))
	mev->setToContactList(true);
    }
    
    if (t == 0) t = ev->getTime();
    else ev->setTime(t);

    ev->setDelivered(true);
    // default to true - for clients that ignore this functionality

    if (ev->getType() != MessageEvent::AwayMessage) {
      messaged.emit(ev);
      contact->set_last_message_time( t );
    } else {
      contact->set_last_away_msg_check_time( t );

      ostringstream ostr;
      ostr << "Away_msg respons to: " << contact->getAlias() << endl;
      SignalLog( LogEvent::INFO, ostr.str() );
    }

    if (advanced) {
      /* All these operations only apply to advanced messages -
       * UINICQSubType messages, those that are associated to a UIN and
       * that were sent as an advanced message (through server or
       * direct, NOT offline), and consequently will the ack'ed.
       */

      /* request away message if we are not online */
      if (st != STATUS_ONLINE && advanced)
      {
	want_auto_resp.emit(mev);
	uist->setAwayMessage( m_translator->client_to_server(mev->getAwayMessage(), ENCODING_CONTACT_LOCALE, contact ) );
      }
      else
      {
	uist->setAwayMessage( "" );
      }

      /* update the UINICQSubType */
	
      uist->setACK(true);
      ack = true;
      
      if (ev->isDelivered())
      {
	/* set accept-status of ACK */
	switch(st) {
	case STATUS_ONLINE:
	  uist->setStatus(AcceptStatus_Online);
	  break;
	case STATUS_AWAY:
	  uist->setStatus(AcceptStatus_Away);
	  break;
	case STATUS_NA:
	  uist->setStatus(AcceptStatus_NA);
	  break;
	case STATUS_OCCUPIED:
	  uist->setStatus(AcceptStatus_Occ_Accept);
	  break;
	default:
	  uist->setStatus(AcceptStatus_Online);
	}
      } else {
	MessageEvent::DeliveryFailureReason r = ev->getDeliveryFailureReason();
	/* set accept-status of ACK */
	switch(r) {
	case MessageEvent::Failed_Denied:
	  uist->setStatus(AcceptStatus_Denied);
	  break;
	case MessageEvent::Failed_Occupied:
	  uist->setStatus(AcceptStatus_Occupied);
	  break;
	case MessageEvent::Failed_DND:
	  uist->setStatus(AcceptStatus_DND);
	  break;
	case MessageEvent::Failed_Ignored:
	  ack = false;
	  break;
	default:
	  uist->setStatus(AcceptStatus_Denied);
	}
      }

    }

    // delete the temporary event
    delete ev;

    // whether the message needs ack'ing
    return ack;
  }