Sat Nov 1 06:29:17 2008

Asterisk developer's documentation


res_jabber.c File Reference

A resource for interfacing asterisk directly as a client or a component to a jabber compliant server. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <iksemel.h>
#include "asterisk/channel.h"
#include "asterisk/jabber.h"
#include "asterisk/file.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/astobj.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"

Include dependency graph for res_jabber.c:

Go to the source code of this file.

Defines

#define FALSE   0
#define JABBER_CONFIG   "jabber.conf"
#define TRUE   1

Functions

static int aji_act_hook (void *data, int type, iks *node)
 The action hook parses the inbound packets, constantly running.
static void aji_buddy_destroy (struct aji_buddy *obj)
 Deletes the aji_buddy data structure.
static int aji_client_connect (void *data, ikspak *pak)
 connects as a client to jabber server.
static void aji_client_destroy (struct aji_client *obj)
 Deletes the aji_client data structure.
static int aji_client_info_handler (void *data, ikspak *pak)
static int aji_client_initialize (struct aji_client *client)
 prepares client for connect.
static int aji_component_initialize (struct aji_client *client)
 prepares component for connect.
static int aji_create_buddy (char *label, struct aji_client *client)
 creates transport. creates buddy.
static int aji_create_client (char *label, struct ast_variable *var, int debug)
 creates aji_client structure.
static int aji_dinfo_handler (void *data, ikspak *pak)
static int aji_ditems_handler (void *data, ikspak *pak)
static int aji_do_debug (int fd, int argc, char *argv[])
 turnon console debugging.
static int aji_do_reload (int fd, int argc, char *argv[])
 reload jabber module.
static int aji_filter_roster (void *data, ikspak *pak)
 filters the roster packet we get back from server.
static struct aji_resourceaji_find_resource (struct aji_buddy *buddy, char *name)
static struct aji_versionaji_find_version (char *node, char *version, ikspak *pak)
 Find version in XML stream and populate our capabilities list.
static int aji_get_roster (struct aji_client *client)
static void aji_handle_iq (struct aji_client *client, iks *node)
 Handles <iq> tags.
static void aji_handle_message (struct aji_client *client, ikspak *pak)
 Handles presence packets.
static void aji_handle_presence (struct aji_client *client, ikspak *pak)
static void aji_handle_subscribe (struct aji_client *client, ikspak *pak)
 handles subscription requests.
static int aji_highest_bit (int number)
 Detects the highest bit in a number.
static int aji_load_config (void)
 load config file.
static void aji_log_hook (void *data, const char *xmpp, size_t size, int is_incoming)
 the debug loop.
static int aji_no_debug (int fd, int argc, char *argv[])
 turnoff console debugging.
static void aji_pruneregister (struct aji_client *client)
 attempts to register to a transport. attempts to register to a transport step 2. goes through roster and prunes users not needed in list, or adds them accordingly.
static int aji_reconnect (struct aji_client *client)
static void * aji_recv_loop (void *data)
 receive message loop.
static int aji_register_approve_handler (void *data, ikspak *pak)
static int aji_register_query_handler (void *data, ikspak *pak)
static int aji_reload (void)
static int aji_send_exec (struct ast_channel *chan, void *data)
 Dial plan function to send a message.
static void aji_set_presence (struct aji_client *client, char *to, char *from, int level, char *desc)
 set presence of client.
static int aji_show_clients (int fd, int argc, char *argv[])
 show client status.
static int aji_status_exec (struct ast_channel *chan, void *data)
 Dial plan function status(). puts the status of watched user into a channel variable.
static int aji_test (int fd, int argc, char *argv[])
 send test message for debugging.
int ast_aji_create_chat (struct aji_client *client, char *room, char *server, char *topic)
 create a chatroom.
int ast_aji_disconnect (struct aji_client *client)
 disconnect from jabber server.
aji_clientast_aji_get_client (const char *name)
 grab a aji_client structure by label name or JID (without the resource string)
aji_client_containerast_aji_get_clients (void)
void ast_aji_increment_mid (char *mid)
 increments the mid field for messages and other events.
int ast_aji_invite_chat (struct aji_client *client, char *user, char *room, char *message)
 invite to a chatroom.
int ast_aji_join_chat (struct aji_client *client, char *room)
 join a chatroom.
int ast_aji_send (struct aji_client *client, const char *address, const char *message)
 sends messages.
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"AJI - Asterisk Jabber Interface",.load=load_module,.unload=unload_module,.reload=reload,)
static int gtalk_yuck (iks *node)
static iks * jabber_make_auth (iksid *id, const char *pass, const char *sid)
static int load_module (void)
static int manager_jabber_send (struct mansession *s, const struct message *m)
 Send a Jabber Message via call from the Manager.
static int reload (void)
static int unload_module (void)

Variables

static struct ast_cli_entry aji_cli []
static char * ajisend_descrip
static char * ajisend_synopsis = "JabberSend(jabber,screenname,message)"
static char * ajistatus_descrip
static char * ajistatus_synopsis = "JabberStatus(Jabber,ScreenName,Variable)"
static char * app_ajisend = "JabberSend"
static char * app_ajistatus = "JabberStatus"
aji_capabilitiescapabilities = NULL
aji_client_container clients
static char debug_usage []
static struct ast_flags globalflags = { AJI_AUTOPRUNE | AJI_AUTOREGISTER }
 Global flags, initialized to default values.
static char mandescr_jabber_send []
static char no_debug_usage []
static char reload_usage []
static char test_usage []
static int tls_initialized = FALSE


Detailed Description

A resource for interfacing asterisk directly as a client or a component to a jabber compliant server.

Todo:
If you unload this module, chan_gtalk/jingle will be dead. How do we handle that?
Todo:
If you have TLS, you can't unload this module. See bug #9738. This needs to be fixed, but the bug is in the unmantained Iksemel library

Definition in file res_jabber.c.


Define Documentation

#define FALSE   0

Definition at line 64 of file res_jabber.c.

#define JABBER_CONFIG   "jabber.conf"

Definition at line 61 of file res_jabber.c.

Referenced by aji_load_config().

#define TRUE   1

Definition at line 68 of file res_jabber.c.


Function Documentation

static int aji_act_hook ( void *  data,
int  type,
iks *  node 
) [static]

The action hook parses the inbound packets, constantly running.

Parameters:
data aji client structure
type type of packet
node the actual packet.
Returns:
IKS_OK or IKS_HOOK .

Definition at line 488 of file res_jabber.c.

References aji_client_connect(), aji_client_destroy(), AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, AJI_DISCONNECTING, aji_handle_iq(), aji_handle_message(), aji_handle_presence(), aji_handle_subscribe(), aji_highest_bit(), asprintf, ast_aji_increment_mid(), ast_base64encode(), ast_log(), ast_malloc, ast_sha1_hash(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::authorized, base64, aji_client::component, aji_client::f, free, jabber_make_auth(), aji_client::jid, len, LOG_DEBUG, LOG_ERROR, LOG_WARNING, aji_client::mid, option_debug, aji_client::p, aji_client::password, s, secret, aji_client::state, TRUE, aji_client::usesasl, and aji_client::usetls.

Referenced by aji_create_client().

00489 {
00490    struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
00491    ikspak *pak = NULL;
00492    iks *auth = NULL;
00493 
00494    if(!node) {
00495       ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
00496       ASTOBJ_UNREF(client, aji_client_destroy);
00497       return IKS_HOOK;
00498    }
00499 
00500    if (client->state == AJI_DISCONNECTING) {
00501       ASTOBJ_UNREF(client, aji_client_destroy);
00502       return IKS_HOOK;
00503    }
00504 
00505    pak = iks_packet(node);
00506 
00507    if (!client->component) { /*client */
00508       switch (type) {
00509       case IKS_NODE_START:
00510          if (client->usetls && !iks_is_secure(client->p)) {
00511             if (iks_has_tls()) {
00512                iks_start_tls(client->p);
00513                tls_initialized = TRUE;
00514             } else
00515                ast_log(LOG_ERROR, "gnuTLS not installed. You need to recompile the Iksemel library with gnuTLS support\n");
00516             break;
00517          }
00518          if (!client->usesasl) {
00519             iks_filter_add_rule(client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid, IKS_RULE_DONE);
00520             auth = jabber_make_auth(client->jid, client->password, iks_find_attrib(node, "id"));
00521             if (auth) {
00522                iks_insert_attrib(auth, "id", client->mid);
00523                iks_insert_attrib(auth, "to", client->jid->server);
00524                ast_aji_increment_mid(client->mid);
00525                iks_send(client->p, auth);
00526                iks_delete(auth);
00527             } else
00528                ast_log(LOG_ERROR, "Out of memory.\n");
00529          }
00530          break;
00531 
00532       case IKS_NODE_NORMAL:
00533          if (!strcmp("stream:features", iks_name(node))) {
00534             int features = 0;
00535             features = iks_stream_features(node);
00536             if (client->usesasl) {
00537                if (client->usetls && !iks_is_secure(client->p))
00538                   break;
00539                if (client->authorized) {
00540                   if (features & IKS_STREAM_BIND) {
00541                      iks_filter_add_rule (client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_DONE);
00542                      auth = iks_make_resource_bind(client->jid);
00543                      if (auth) {
00544                         iks_insert_attrib(auth, "id", client->mid);
00545                         ast_aji_increment_mid(client->mid);
00546                         iks_send(client->p, auth);
00547                         iks_delete(auth);
00548                      } else {
00549                         ast_log(LOG_ERROR, "Out of memory.\n");
00550                         break;
00551                      }
00552                   }
00553                   if (features & IKS_STREAM_SESSION) {
00554                      iks_filter_add_rule (client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "auth", IKS_RULE_DONE);
00555                      auth = iks_make_session();
00556                      if (auth) {
00557                         iks_insert_attrib(auth, "id", "auth");
00558                         ast_aji_increment_mid(client->mid);
00559                         iks_send(client->p, auth);
00560                         iks_delete(auth);
00561                      } else {
00562                         ast_log(LOG_ERROR, "Out of memory.\n");
00563                      }
00564                   }
00565                } else {
00566                   if (!client->jid->user) {
00567                      ast_log(LOG_ERROR, "Malformed Jabber ID : %s (domain missing?)\n", client->jid->full);
00568                      break;
00569                   }
00570                   features = aji_highest_bit(features);
00571                   if (features == IKS_STREAM_SASL_MD5)
00572                      iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, client->jid->user, client->password);
00573                   else {
00574                      if (features == IKS_STREAM_SASL_PLAIN) {
00575                         iks *x = NULL;
00576                         x = iks_new("auth");
00577                         if (x) {
00578                            int len = strlen(client->jid->user) + strlen(client->password) + 3;
00579                            /* XXX Check return values XXX */
00580                            char *s = ast_malloc(80 + len);
00581                            char *base64 = ast_malloc(80 + len * 2);
00582                            iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL);
00583                            iks_insert_attrib(x, "mechanism", "PLAIN");
00584                            sprintf(s, "%c%s%c%s", 0, client->jid->user, 0, client->password);
00585                               
00586                            /* exclude the NULL training byte from the base64 encoding operation
00587                               as some XMPP servers will refuse it.
00588                               The format for authentication is [authzid]\0authcid\0password
00589                               not [authzid]\0authcid\0password\0 */
00590                            ast_base64encode(base64, (const unsigned char *) s, len - 1, len * 2);
00591                            iks_insert_cdata(x, base64, 0);
00592                            iks_send(client->p, x);
00593                            iks_delete(x);
00594                            if (base64)
00595                               free(base64);
00596                            if (s)
00597                               free(s);
00598                         } else {
00599                            ast_log(LOG_ERROR, "Out of memory.\n");
00600                         }
00601                      }
00602                   }
00603                }
00604             }
00605          } else if (!strcmp("failure", iks_name(node))) {
00606             ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n");
00607          } else if (!strcmp("success", iks_name(node))) {
00608             client->authorized = 1;
00609             iks_send_header(client->p, client->jid->server);
00610          }
00611          break;
00612       case IKS_NODE_ERROR: 
00613             ast_log(LOG_ERROR, "JABBER: Node Error\n");
00614             ASTOBJ_UNREF(client, aji_client_destroy);
00615             return IKS_HOOK;
00616             break;
00617       case IKS_NODE_STOP: 
00618             ast_log(LOG_WARNING, "JABBER: Disconnected\n");
00619             ASTOBJ_UNREF(client, aji_client_destroy);
00620             return IKS_HOOK;
00621             break;
00622       }
00623    } else if (client->state != AJI_CONNECTED && client->component) {
00624       switch (type) {
00625       case IKS_NODE_START:
00626          if (client->state == AJI_DISCONNECTED) {
00627             char secret[160], shasum[320], *handshake;
00628 
00629             sprintf(secret, "%s%s", pak->id, client->password);
00630             ast_sha1_hash(shasum, secret);
00631             handshake = NULL;
00632             asprintf(&handshake, "<handshake>%s</handshake>", shasum);
00633             if (handshake) {
00634                iks_send_raw(client->p, handshake);
00635                free(handshake);
00636                handshake = NULL;
00637             }
00638             client->state = AJI_CONNECTING;
00639             if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
00640                client->state = AJI_CONNECTED;
00641             else
00642                ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n");
00643             break;
00644          }
00645          break;
00646 
00647       case IKS_NODE_NORMAL:
00648          break;
00649 
00650       case IKS_NODE_ERROR:
00651          ast_log(LOG_ERROR, "JABBER: Node Error\n");
00652          ASTOBJ_UNREF(client, aji_client_destroy);
00653          return IKS_HOOK;
00654 
00655       case IKS_NODE_STOP:
00656          ast_log(LOG_WARNING, "JABBER: Disconnected\n");
00657          ASTOBJ_UNREF(client, aji_client_destroy);
00658          return IKS_HOOK;
00659       }
00660    }
00661 
00662    switch (pak->type) {
00663    case IKS_PAK_NONE:
00664       if (option_debug)
00665          ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n");
00666       break;
00667    case IKS_PAK_MESSAGE:
00668       aji_handle_message(client, pak);
00669       if (option_debug)
00670          ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n");
00671       break;
00672    case IKS_PAK_PRESENCE:
00673       aji_handle_presence(client, pak);
00674       if (option_debug)
00675          ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n");
00676       break;
00677    case IKS_PAK_S10N:
00678       aji_handle_subscribe(client, pak);
00679       if (option_debug)
00680          ast_log(LOG_DEBUG, "JABBER: I Dont know S10N subscribe!!\n");
00681       break;
00682    case IKS_PAK_IQ:
00683       if (option_debug)
00684          ast_log(LOG_DEBUG, "JABBER: I Dont have an IQ!!!\n");
00685       aji_handle_iq(client, node);
00686       break;
00687    default:
00688       if (option_debug)
00689          ast_log(LOG_DEBUG, "JABBER: I Dont know %i\n", pak->type);
00690       break;
00691    }
00692    
00693    iks_filter_packet(client->f, pak);
00694 
00695    if (node)
00696       iks_delete(node);
00697 
00698    ASTOBJ_UNREF(client, aji_client_destroy);
00699    return IKS_OK;
00700 }

static void aji_buddy_destroy ( struct aji_buddy obj  )  [static]

Deletes the aji_buddy data structure.

Parameters:
obj is the structure we will delete.
Returns:
void.

Definition at line 211 of file res_jabber.c.

References aji_resource::description, free, aji_resource::next, and aji_buddy::resources.

Referenced by aji_client_destroy(), aji_create_buddy(), and aji_handle_presence().

00212 {
00213    struct aji_resource *tmp;
00214 
00215    while ((tmp = obj->resources)) {
00216       obj->resources = obj->resources->next;
00217       free(tmp->description);
00218       free(tmp);
00219    }
00220 
00221    free(obj);
00222 }

static int aji_client_connect ( void *  data,
ikspak *  pak 
) [static]

connects as a client to jabber server.

Parameters:
aji_client struct, and xml packet.
Returns:
res.

Definition at line 1856 of file res_jabber.c.

References aji_client_destroy(), AJI_CONNECTING, AJI_DISCONNECTED, aji_filter_roster(), aji_get_roster(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::component, aji_client::f, aji_client::jid, LOG_ERROR, aji_client::stack, and aji_client::state.

Referenced by aji_act_hook().

01857 {
01858    struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
01859    int res = 0;
01860 
01861    if (client) {
01862       if (client->state == AJI_DISCONNECTED) {
01863          iks_filter_add_rule(client->f, aji_filter_roster, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "roster", IKS_RULE_DONE);
01864          client->state = AJI_CONNECTING;
01865          client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid;
01866          iks_filter_remove_hook(client->f, aji_client_connect);
01867          if(!client->component) /*client*/
01868             aji_get_roster(client);
01869       }
01870    } else
01871       ast_log(LOG_ERROR, "Out of memory.\n");
01872 
01873    ASTOBJ_UNREF(client, aji_client_destroy);
01874    return res;
01875 }

static void aji_client_destroy ( struct aji_client obj  )  [static]

Deletes the aji_client data structure.

Parameters:
obj is the structure we will delete.
Returns:
void.

Definition at line 187 of file res_jabber.c.

References aji_buddy_destroy(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, aji_client::buddies, aji_client::f, free, aji_message::from, aji_message::message, aji_client::p, and aji_client::stack.

Referenced by aji_act_hook(), aji_client_connect(), aji_client_info_handler(), aji_create_client(), aji_dinfo_handler(), aji_ditems_handler(), aji_log_hook(), aji_recv_loop(), aji_register_approve_handler(), aji_register_query_handler(), aji_reload(), ast_aji_disconnect(), and unload_module().

00188 {
00189    struct aji_message *tmp;
00190    ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy);
00191    ASTOBJ_CONTAINER_DESTROY(&obj->buddies);
00192    iks_filter_delete(obj->f);
00193    iks_parser_delete(obj->p);
00194    iks_stack_delete(obj->stack);
00195    AST_LIST_LOCK(&obj->messages);
00196    while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) {
00197       if (tmp->from)
00198          free(tmp->from);
00199       if (tmp->message)
00200          free(tmp->message);
00201    }
00202    AST_LIST_HEAD_DESTROY(&obj->messages);
00203    free(obj);
00204 }

static int aji_client_info_handler ( void *  data,
ikspak *  pak 
) [static]

Definition at line 907 of file res_jabber.c.

References aji_client_destroy(), aji_find_resource(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, aji_resource::cap, aji_client::jid, aji_version::jingle, LOG_ERROR, LOG_NOTICE, aji_client::p, and aji_resource::resource.

Referenced by aji_create_client().

00908 {
00909    struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
00910    struct aji_resource *resource = NULL;
00911    struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
00912 
00913    resource = aji_find_resource(buddy, pak->from->resource);
00914    if (pak->subtype == IKS_TYPE_RESULT) {
00915       if (!resource) {
00916          ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
00917          ASTOBJ_UNREF(client, aji_client_destroy);
00918          return IKS_FILTER_EAT;
00919       }
00920       if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
00921          resource->cap->jingle = 1;
00922       } else
00923          resource->cap->jingle = 0;
00924    } else if (pak->subtype == IKS_TYPE_GET) {
00925       iks *iq, *disco, *ident, *google, *query;
00926       iq = iks_new("iq");
00927       query = iks_new("query");
00928       ident = iks_new("identity");
00929       disco = iks_new("feature");
00930       google = iks_new("feature");
00931       if (iq && ident && disco && google) {
00932          iks_insert_attrib(iq, "from", client->jid->full);
00933          iks_insert_attrib(iq, "to", pak->from->full);
00934          iks_insert_attrib(iq, "type", "result");
00935          iks_insert_attrib(iq, "id", pak->id);
00936          iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
00937          iks_insert_attrib(ident, "category", "client");
00938          iks_insert_attrib(ident, "type", "pc");
00939          iks_insert_attrib(ident, "name", "asterisk");
00940          iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info");
00941          iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1");
00942          iks_insert_node(iq, query);
00943          iks_insert_node(query, ident);
00944          iks_insert_node(query, google);
00945          iks_insert_node(query, disco);
00946          iks_send(client->p, iq);
00947       } else
00948          ast_log(LOG_ERROR, "Out of Memory.\n");
00949       if (iq)
00950          iks_delete(iq);
00951       if (query)
00952          iks_delete(query);
00953       if (ident)
00954          iks_delete(ident);
00955       if (google)
00956          iks_delete(google);
00957       if (disco)
00958          iks_delete(disco);
00959    } else if (pak->subtype == IKS_TYPE_ERROR) {
00960       ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
00961    }
00962    ASTOBJ_UNREF(client, aji_client_destroy);
00963    return IKS_FILTER_EAT;
00964 }

static int aji_client_initialize ( struct aji_client client  )  [static]

prepares client for connect.

Parameters:
aji_client struct.
Returns:
1.

Definition at line 1882 of file res_jabber.c.

References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::p, aji_client::port, S_OR, and aji_client::serverhost.

Referenced by aji_reconnect().

01883 {
01884    int connected = 0;
01885 
01886    connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server);
01887 
01888    if (connected == IKS_NET_NOCONN) {
01889       ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n");
01890       return IKS_HOOK;
01891    } else   if (connected == IKS_NET_NODNS) {
01892       ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to  %s\n", client->name, S_OR(client->serverhost, client->jid->server));
01893       return IKS_HOOK;
01894    } else
01895       iks_recv(client->p, 30);
01896    return IKS_OK;
01897 }

static int aji_component_initialize ( struct aji_client client  )  [static]

prepares component for connect.

Parameters:
aji_client struct.
Returns:
1.

Definition at line 1904 of file res_jabber.c.

References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::p, aji_client::port, S_OR, aji_client::serverhost, and aji_client::user.

Referenced by aji_reconnect().

01905 {
01906    int connected = 1;
01907 
01908    connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->user);
01909    if (connected == IKS_NET_NOCONN) {
01910       ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n");
01911       return IKS_HOOK;
01912    } else if (connected == IKS_NET_NODNS) {
01913       ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to  %s\n", client->name, S_OR(client->serverhost, client->jid->server));
01914       return IKS_HOOK;
01915    } else if (!connected) 
01916       iks_recv(client->p, 30);
01917    return IKS_OK;
01918 }

static int aji_create_buddy ( char *  label,
struct aji_client client 
) [static]

creates transport. creates buddy.

Parameters:
label,buddy to dump it into.
Returns:
0.

Definition at line 2295 of file res_jabber.c.

References aji_buddy_destroy(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::buddies, LOG_WARNING, and malloc.

Referenced by aji_create_client(), aji_handle_presence(), and aji_handle_subscribe().

02296 {
02297    struct aji_buddy *buddy = NULL;
02298    int flag = 0;
02299    buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label);
02300    if (!buddy) {
02301       flag = 1;
02302       buddy = malloc(sizeof(struct aji_buddy));
02303       if(!buddy) {
02304          ast_log(LOG_WARNING, "Out of memory\n");
02305          return 0;
02306       }
02307       memset(buddy, 0, sizeof(struct aji_buddy));
02308       ASTOBJ_INIT(buddy);
02309    }
02310    ASTOBJ_WRLOCK(buddy);
02311    ast_copy_string(buddy->name, label, sizeof(buddy->name));
02312    ASTOBJ_UNLOCK(buddy);
02313    if(flag)
02314       ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
02315    else {
02316       ASTOBJ_UNMARK(buddy);
02317       ASTOBJ_UNREF(buddy, aji_buddy_destroy);
02318    }
02319    return 1;
02320 }

static int aji_create_client ( char *  label,
struct ast_variable var,
int  debug 
) [static]

creates aji_client structure.

Parameters:
label,ast_variable,debug,pruneregister,component/client,aji_client to dump into.
Returns:
0.

Definition at line 2104 of file res_jabber.c.

References aji_act_hook(), AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_client_destroy(), aji_client_info_handler(), aji_create_buddy(), aji_dinfo_handler(), AJI_DISCONNECTED, aji_ditems_handler(), aji_log_hook(), aji_register_approve_handler(), aji_register_query_handler(), asprintf, ast_copy_flags, ast_false(), AST_FLAGS_ALL, AST_LIST_HEAD_INIT, ast_log(), ast_set2_flag, ast_true(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_INIT, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::authorized, aji_client::buddies, clients, aji_client::component, aji_client::debug, aji_client::f, aji_client::forcessl, free, globalflags, aji_client::jid, aji_client::keepalive, LOG_ERROR, malloc, aji_client::message_timeout, aji_client::mid, aji_client::p, aji_client::password, aji_client::port, aji_client::serverhost, aji_client::stack, aji_client::state, aji_client::statusmessage, aji_client::timeout, aji_client::user, aji_client::usesasl, aji_client::usetls, and var.

Referenced by aji_load_config().

02105 {
02106    char *resource;
02107    struct aji_client *client = NULL;
02108    int flag = 0;
02109 
02110    client = ASTOBJ_CONTAINER_FIND(&clients,label);
02111    if (!client) {
02112       flag = 1;
02113       client = (struct aji_client *) malloc(sizeof(struct aji_client));
02114       if (!client) {
02115          ast_log(LOG_ERROR, "Out of memory!\n");
02116          return 0;
02117       }
02118       memset(client, 0, sizeof(struct aji_client));
02119       ASTOBJ_INIT(client);
02120       ASTOBJ_WRLOCK(client);
02121       ASTOBJ_CONTAINER_INIT(&client->buddies);
02122    } else {
02123       ASTOBJ_WRLOCK(client);
02124       ASTOBJ_UNMARK(client);
02125    }
02126    ASTOBJ_CONTAINER_MARKALL(&client->buddies);
02127    ast_copy_string(client->name, label, sizeof(client->name));
02128    ast_copy_string(client->mid, "aaaaa", sizeof(client->mid));
02129 
02130    /* Set default values for the client object */
02131    client->debug = debug;
02132    ast_copy_flags(client, &globalflags, AST_FLAGS_ALL);
02133    client->port = 5222;
02134    client->usetls = 1;
02135    client->usesasl = 1;
02136    client->forcessl = 0;
02137    client->keepalive = 1;
02138    client->timeout = 50;
02139    client->message_timeout = 100;
02140    AST_LIST_HEAD_INIT(&client->messages);
02141    client->component = 0;
02142    ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage));
02143 
02144    if (flag) {
02145       client->authorized = 0;
02146       client->state = AJI_DISCONNECTED;
02147    }
02148    while (var) {
02149       if (!strcasecmp(var->name, "username"))
02150          ast_copy_string(client->user, var->value, sizeof(client->user));
02151       else if (!strcasecmp(var->name, "serverhost"))
02152          ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost));
02153       else if (!strcasecmp(var->name, "secret"))
02154          ast_copy_string(client->password, var->value, sizeof(client->password));
02155       else if (!strcasecmp(var->name, "statusmessage"))
02156          ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage));
02157       else if (!strcasecmp(var->name, "port"))
02158          client->port = atoi(var->value);
02159       else if (!strcasecmp(var->name, "timeout"))
02160          client->message_timeout = atoi(var->value);
02161       else if (!strcasecmp(var->name, "debug"))
02162          client->debug = (ast_false(var->value)) ? 0 : 1;
02163       else if (!strcasecmp(var->name, "type")) {
02164          if (!strcasecmp(var->value, "component"))
02165             client->component = 1;
02166       } else if (!strcasecmp(var->name, "usetls")) {
02167          client->usetls = (ast_false(var->value)) ? 0 : 1;
02168       } else if (!strcasecmp(var->name, "usesasl")) {
02169          client->usesasl = (ast_false(var->value)) ? 0 : 1;
02170       } else if (!strcasecmp(var->name, "forceoldssl"))
02171          client->forcessl = (ast_false(var->value)) ? 0 : 1;
02172       else if (!strcasecmp(var->name, "keepalive"))
02173          client->keepalive = (ast_false(var->value)) ? 0 : 1;
02174       else if (!strcasecmp(var->name, "autoprune"))
02175          ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE);
02176       else if (!strcasecmp(var->name, "autoregister"))
02177          ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER);
02178       else if (!strcasecmp(var->name, "buddy"))
02179             aji_create_buddy(var->value, client);
02180    /* no transport support in this version */