/* * 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; }