========================== An Overview of ``libmsn`` ========================== :Author: Mark Rowe :Contact: bdash@users.sourceforge.net :Version: $Id: overview.txt 339 2005-02-06 06:50:39Z bdash $ :Status: Work in Progress .. contents:: This document contains a high level overview of ``libmsn`` 3.2. ``libmsn`` 3.2 is based on Meredydd Luff's ``libmsn`` 2.1, but is closer to a complete rewrite than a new version. ---------------------------------------- An Overview of the MSN Messenger System ---------------------------------------- Communication with MSN Messenger takes place in connections to two primary types of servers. A connection is established with the *notification server* when you signed in, and this connection is maintained until you sign out of the service. Instant messages to other users take place after connecting to *switchboard servers*. A connection is made to a switchboard server for every conversation that you take part in. The notification server is responsible for managing your online presence, buddy list, and dispatching invitations to join conversations to your buddies. It also notifies you of changes in your buddy's status, and when a buddy requests your presence in a chat. The switchboard server's sole responsibility is the transmission of messages between buddies. Connections to the switchboard server map one-to-one to the concept of a conversation with one or more buddies. That is to say, a switchboard connection is opened for every conversation that you participate in. For more detailed information about the MSN Messenger system, you should look to the hypothetic.org `MSN Messenger protocol documentation`_. .. _MSN Messenger protocol documentation: http://hypothetic.org/docs/msn/ ------------------------------ An Introduction to ``libmsn`` ------------------------------ ``libmsn`` is a single-threaded, asynchronous library that is written in ``C++``. All of it's code is defined within the namespace ``MSN``. In this documentation, the qualifying ``MSN::`` will omitted for the sake of brevity. The Library's Files ==================== All code that needs to access ``libmsn``'s functionality should use the following syntax to include it's headers:: #include Bare in mind that you will need to instruct your compiler to link to the ``libmsn`` library. This can be done by passing ``-lmsn`` as an argument to ``gcc``. Communication with the Library ============================== Communication with ``libmsn`` is done via an object-oriented ``API`` and user-provided callback functions. An instance of a user-defined subclass of ``MSN::Callbacks`` should be passed to the ``NotificationServerConnection`` constructor. All callbacks are declared within `msn/externals.h`_. All callbacks listed need to be defined, otherwise you will get linker errors when you attempt to build your program. Many of the callbacks can be defined as an empty function, but those listed under `Required Callbacks`_ need to be implemented with the documented semantics. .. _msn/externals.h: http://libmsn.bdash.net.nz/svn/branches/libmsn-3.2.x/msn/externals.h Core Classes ============= To use ``libmsn`` you need to be aware of several key classes. ``NotificationServerConnection`` This represents a connection to a notification server, and provides the ability to change your online status, manipulate your buddy list, and request a new switchboard server connection. ``SwitchboardServerConnection`` This represents a connection to a switchboard server, and provides the ability to invite additional users into the switchboard session, and to send a message to the members of the session. ``FileTransferInvitation`` This represents an invitation to either send or receive a file to or from another buddy. It allows you to accept or decline the transfer, and monitor it's progress. ``Message`` ``Message`` represents a message that will be sent to a switchboard session. Basic Program Flow =================== Below is a list of the general program flow and interaction with ``libmsn``. 1. Create a ``NotificationServerConnection`` with the correct username and password, and ask it to connect to ``messenger.hotmail.com`` on port 1863:: struct pollfd mySockets[32]; int numberOfSockets = 0; MSN::NotificationServerConnection *mainConnection; Callbacks cb; mainConnection = new MSN::NotificationServerConnect("myPassport@example.com", "myS3cr3t", cb); mainConnection->connect("messenger.hotmail.com", 1863); ``libmsn`` will then register and unregister sockets to be checked for completed connections, available data, and writability by calling ``MSN::Callbacks::registerSocket`` and ``MSN::Callbacks::unregisterSocket`` one or more times as is appropriate. 2. Enter your main event loop. This may be based on ``select``, ``poll``, or a similar ``API`` that will notify you when data is available on a given socket:: poll(mySockets, numberOfSockets, -1); 3. Inform ``libmsn`` when data has a socket connection has completed, data has arrived on a socket, or a socket has become writable. This can be done by using the ``Connection`` object's ``socketConnectionCompleted``, ``dataArrivedOnSocket``, and ``socketIsWritable`` methods as is appropriate:: MSN::Connection *c; // Retrieve the connection associated with the // socket's file handle on which the event has // occurred. c = mainConnection->connectionWithSocket(mySockets[i].fd); // if this is a libmsn socket if (c != NULL) { // If we aren't yet connected, a socket event means that // our connection attempt has completed. if (c->isConnected() == false) c->socketConnectionCompleted(); // If this event is due to new data becoming available if (mySockets[i].revents & POLLIN) c->dataArrivedOnSocket(); // If this event is due to the socket becoming writable if (mySockets[i].revents & POLLOUT) c->socketIsWritable(); } 4. When a socket used by ``libmsn`` is closed, you should ``delete`` the ``Connection`` object that it is associated with:: MSN::Connection *c; // Retrieve the connection associated with the // socket's file handle on which the event has // occurred. c = mainConnection->connectionWithSocket(mySockets[i].fd); // if this is a libmsn socket if (c != NULL) { // Delete the connection. This will cause the resources // that are being used to be freed. delete c; } These four steps are all that is required to use ``libmsn``. Your program code can then use the ``API`` that is provided to manipulate your buddy list, `request switchboard sessions`_, and `send instant messages`_. .. _request switchboard sessions: `Requesting a Switchboard Session`_ .. _send instant messages: `Sending Instant Messages`_ Callbacks ========== Required Callbacks ------------------- The following callbacks are required by ``libmsn`` to implement the documented semantics as they are used to integrate with your program: ``int MSN::Callbacks::connectToServer(std::string server, int port, bool *connected)`` Return an integer containing a socket that has been connected to server:port. ``libmsn`` will call this when it wants to establish a connection a computer named ``server`` that is listening on ``port``. The value ``true`` should be stored in ``*connected`` if the connection has completed, or ``false`` if the connection did not complete. ``-1`` should be returned if an error occurs. ``void MSN::Callbacks::registerSocket(int socket, int reading, int writing)`` Called by ``libmsn`` to inform you which events you should watch for on ``socket``. If ``reading`` is ``true``, then ``libmsn`` wishes to be informed when data arrives on the socket. If ``writing`` is ``true``, ``libmsn`` wishes to be informed when it is possible to write data to ``socket``. ``void MSN::Callbacks::unregisterSocket(int socket)`` Called by ``libmsn`` to inform you that it no longer wishes to be notified of events relating to ``socket``. Optional Callbacks ------------------- All other callback functions may optionally be implemented. If you have no use for the callback, it may be defined as an empty function. ------------- Common Tasks ------------- Requesting a Switchboard Session ================================= A switchboard connection is required for interaction with any other buddy on the MSN Messenger service. You can use the ``NotificationServerConnection``'s ``requestSwitchboardConnection`` method to request a session. You may pass an optional piece of data as the ``tag`` argument so that you can identify this switchboard request:: // Request a switchboard session, using requestContext to allow // us to identify this session request void *requestContext = ; mainConnection->requestSwitchboardConnection(requestContext); ``MSN::Callbacks::gotSwitchboard`` will be called when the requested switchboard session is established. Inviting Buddies Into a Switchboard Session ============================================ Once you have established a switchboard session, you need to invite your receiving buddy into the session. You can do this by using the ``SwitchboardServerConnection``'s ``inviteUser`` method. Note that the buddy is not considered to have joined the session until ``MSN::Callbacks::buddyJoinedConversation`` has been called with the switchboard server and buddy as arguments. Sending Instant Messages ========================= When your switchboard session has been established, and buddies invited, you can then send an instant message. ``libmsn`` represents messages with it's ``Message`` class, so an instance needs to be created that contains the message that you wish to send. This instance will then allow you to control such things as the font and color that the message will appear in. The message can then be transmitted into the switchboard session by using the ``SwitchboardServerConnection``'s ``sendMessage`` method:: MSN::SwitchboardServerConnection *theSwitchboard = ; MSN::Message msg(myMessageText); msg.setFontName("Courier New"); msg.setFontEffects(MSN::Message::ITALIC_FONT); theSwitchboard->sendMessage(&msg);