Logo Search packages:      
Sourcecode: kmess version File versions  Download package

void MsnSwitchboardConnection::parseMimeMessage ( const QStringList &  command,
const MimeMessage message 
) [private, virtual]

Process a received MIME message.

A incoming message may look like:

MSG somecontact@kmessdemo.org KMessDemo 146
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
X-MMS-IM-Format: FN=Arial; EF=; CO=0; CS=0; PF=0

no prob. How is development doing?

Notice the MIME-style header, and body below. The Content-Type header indicates the message type, for example: text/plain (a chat message) text/x-mms-emoticon (custom emoticon definition) or text/x-msmsgsemailnotification (new email notification).

All MIME messages are preceeded by the MSG command. This command is not delivered to parseCommand(). Instead, this class waits for the payload (the MIME message) to arrive. The complete command and payload is forwarded to this method. When the MIME message was splitted in a multi-packet message, it's merged before this method is called. The last argument of command can be ignored. It indicates the size of the payload, in this case 146 bytes.

Parameters:
command The MSG command and it's arguments
message The MIME message which followed the command.

Implements MsnConnection.

Definition at line 1291 of file msnswitchboardconnection.cpp.

References MimeMessage::getBody(), CurrentAccount::getContactByHandle(), ContactBase::getContactPicturePath(), ContactBase::getFriendlyName(), and MimeMessage::getSubValue().

{
  // Get the message type from the head
  const QString& contentType( message.getSubValue( "Content-Type" ) );
#ifdef KMESSDEBUG_SWITCHBOARD_GENERAL
  kDebug() << "Received mime message of type '" << contentType << "'.";
#endif

  // Get the sender's handle and friendly name
  const QString&  contactHandle( command[1] );
  QString  friendlyName;
  QString  contactPicture;

  // Get the contact details
  ContactBase *contact = currentAccount_->getContactByHandle( contactHandle );
  if( contact == 0 )
  {
    // There was no current friendly name, so get one from the message
    friendlyName = QUrl::fromPercentEncoding( command[2].toUtf8() );
  }
  else
  {
    // get name from contact
    friendlyName   = contact->getFriendlyName( STRING_ORIGINAL );
    contactPicture = contact->getContactPicturePath();
  }


  // Link a chat window to this switchboard if it's needed.
  if( backgroundConnection_ )
  {
    if( contentType == "text/plain"
    ||  contentType == "text/x-msnmsgr-datacast"
    ||  contentType == "image/gif"
    ||  contentType == "application/x-ms-ink" )
    {
#ifdef KMESSDEBUG_SWITCHBOARD_GENERAL
      kDebug() << "chat is still in the background, requesting chat window.";
#endif

      // We've just received a message over a background connection: whoever
      // had started it initially, consider it as started by a contact.
      // That's because if we send a message first, the chat is immediately
      // changed to a foreground one.
      userStartedChat_ = false;

      backgroundConnection_ = false;
      emit requestChatWindow( this );
      emit contactJoinedChat( contact );
    }
  }


  if( contentType == "text/plain" )
  {
    // A normal chat message
    parseChatMessage( contactHandle, friendlyName, contactPicture, message );
  }
  else if( contentType == "text/x-msmsgscontrol" )
  {
    // A typing notification
    parseTypingMessage( contactHandle, message );
  }
  else if( contentType == "text/x-msmsgsinvite" )
  {
    // This is a mime application message, the old format for invitations.
    // Extract the actual MIME message from the body of the Mime container, pass it to the ChatMaster/ApplicationList.
    const MimeMessage& subMessage( message.getBody() );
    emit gotMessage( subMessage, contactHandle );
  }
  else if( contentType == "application/x-msnmsgrp2p" )
  {
    // This is an p2p message, the new format for invitations.
    parseP2PMessage( contactHandle, message );
  }
  else if( contentType == "text/x-mms-emoticon" || contentType == "text/x-mms-animemoticon" )
  {
    // Message contains the MSN objects for the emoticons.
    parseEmoticonMessage( contactHandle, message.getBody() );
  }
  else if( contentType == "text/x-msnmsgr-datacast" )
  {
    // This is a datacast message, contact wants to send a nudge or voice clip
    const MimeMessage& subMessage( message.getBody() );
    parseDatacastMessage( contactHandle, subMessage );
  }
  else if( contentType == "image/gif" )
  {
    // This is a GIF ink message.
    // Source: http://msdn.microsoft.com/en-us/library/ms818340.aspx
    // warning: WLM doesn't even seem to adhere to that standard...
    emit gotInkMessage( message.getBody(), contactHandle, FORMAT_GIF );
  }
  else if( contentType == "application/x-ms-ink" )
  {
    // This is an ISF (Ink Serialized Format) ink message.
    emit gotInkMessage( message.getBody(), contactHandle, FORMAT_ISF );
  }
  else if( contentType == "text/x-clientcaps" )
  {
    // This is a message exchanged by a lot of third party clients.
    parseClientCapsMessage( contactHandle, message );
  }
  else if( contentType == "text/x-keepalive" )
  {
#ifdef KMESSDEBUG_SWITCHBOARD_KEEPALIVE
    kDebug() << "Keep alive message from " << contactHandle << ".";
#endif
  }
  else
  {
    kDebug() << "got unhandled message type (type=" << contentType << " contact=" << contactHandle << ").";
  }

  // Messages which are part of the switchboard session management, will not be considered "activity"
  if( contentType != "text/x-clientcaps" && contentType != "text/x-keepalive" )
  {
    // Signal presence of activity
    activity();
  }
}


Generated by  Doxygen 1.6.0   Back to index