docs/api.mdwn
author Myhailo Danylenko <isbear@ukrpost.net>
Sun, 17 Feb 2013 06:58:49 +0200
changeset 62 f4ad0e7bf1ef
permissions -rw-r--r--
Add short api description


# Service Discovery Requests

## Overview

This module provides C API for other MCabber modules to perform disco requests.
Currently module does not support x-data forms in disco results, so, this part of
information will be silently omitted from results.

Module provides three functions:

gpointer disco_info_request (gchar *, gchar *, disco_info_handler_t, gpointer, GDestroyNotify)
:   Perform disco#info request on entity.

gpointer disco_items_request (gchar *, gchar *, disco_items_handler_t, gpointer, GDestroyNotify)
:   Perform disco#items request on entity.

void disco_cancel_request (gpointer)
:   Cancel not yet finished request.

When you create new request, corresponding function returns ID, that can be used
to cancel it. Otherwise it is not useful for anything and may be ignored. When
module will receive reply to request, it will call handler, that user provided. If
request for some reason fails, handler will be called with NULL as results.
Currently, request can fail under next circumstances:

 - MCabber is not connected;
 - Loudmouth returned error, when trying to send request message;
 - MCabber lost connection before reply arrived;
 - Module is being unloaded.

In first two cases, as well as if you do not specify handler for request results,
function will return NULL instead of ID. Handler will not be called, however, if
you cancel request yourself. Note, that DestroyNotify function (if specified)
will be **always** called, even if function returns NULL, which means, that
userdata may no longer exist after a call to request-making function. Though, you
can detect this case by checking returned ID.

## Simple example

    static void info_handler (GSList *identities, GSList *features, gpointer userdata)
    {
        gchar *jid = userdata;
        while ( identities ) {
            disco_identity_t *identity = identities -> data;
            identities = identities -> next;
            if (!g_strcmp0 (identity -> category, "proxy") &&
                !g_strcmp0 (identity -> type, "bytestreams")) {
                // do something with jid of SOCKS5
                // bytestreams proxy of your server
            }
        }
    }
    
    static void items_handler (GSList *items, gpointer userdata)
    {
        while ( items ) {
            disco_item_t *item = items -> data;
            items = items -> next;
            disco_info_request (item -> jid, NULL, info_handler,
                                g_strdup (item -> jid), g_free);
        }
    }
    
    ...
        const gchar *jid = lm_connection_get_jid (lconnection);
        disco_items_request (jid, NULL, items_handler, NULL, NULL);
    ...