#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"
Go to the source code of this file.
Defines | |
#define | FALSE 0 |
#define | JABBER_CONFIG "jabber.conf" |
#define | TRUE 1 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
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_resource * | aji_find_resource (struct aji_buddy *buddy, char *name) |
static struct aji_version * | aji_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_client * | ast_aji_get_client (const char *name) |
grab a aji_client structure by label name or JID (without the resource string) | |
aji_client_container * | ast_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. | |
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_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "AJI - Asterisk Jabber Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
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" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
aji_capabilities * | capabilities = 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 |
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 FALSE 0 |
Definition at line 64 of file res_jabber.c.
#define JABBER_CONFIG "jabber.conf" |
#define TRUE 1 |
Definition at line 68 of file res_jabber.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 2521 of file res_jabber.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 2521 of file res_jabber.c.
static int aji_act_hook | ( | void * | data, | |
int | type, | |||
iks * | node | |||
) | [static] |
The action hook parses the inbound packets, constantly running.
data | aji client structure | |
type | type of packet | |
node | the actual packet. |
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 if (asprintf(&handshake, "<handshake>%s</handshake>", shasum) > 0) { 00633 iks_send_raw(client->p, handshake); 00634 free(handshake); 00635 handshake = NULL; 00636 } 00637 client->state = AJI_CONNECTING; 00638 if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/ 00639 client->state = AJI_CONNECTED; 00640 else 00641 ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n"); 00642 break; 00643 } 00644 break; 00645 00646 case IKS_NODE_NORMAL: 00647 break; 00648 00649 case IKS_NODE_ERROR: 00650 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00651 ASTOBJ_UNREF(client, aji_client_destroy); 00652 return IKS_HOOK; 00653 00654 case IKS_NODE_STOP: 00655 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00656 ASTOBJ_UNREF(client, aji_client_destroy); 00657 return IKS_HOOK; 00658 } 00659 } 00660 00661 switch (pak->type) { 00662 case IKS_PAK_NONE: 00663 if (option_debug) 00664 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n"); 00665 break; 00666 case IKS_PAK_MESSAGE: 00667 aji_handle_message(client, pak); 00668 if (option_debug) 00669 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n"); 00670 break; 00671 case IKS_PAK_PRESENCE: 00672 aji_handle_presence(client, pak); 00673 if (option_debug) 00674 ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n"); 00675 break; 00676 case IKS_PAK_S10N: 00677 aji_handle_subscribe(client, pak); 00678 if (option_debug) 00679 ast_log(LOG_DEBUG, "JABBER: I Don't know S10N subscribe!!\n"); 00680 break; 00681 case IKS_PAK_IQ: 00682 if (option_debug) 00683 ast_log(LOG_DEBUG, "JABBER: I Don't have an IQ!!!\n"); 00684 aji_handle_iq(client, node); 00685 break; 00686 default: 00687 if (option_debug) 00688 ast_log(LOG_DEBUG, "JABBER: I Don't know %i\n", pak->type); 00689 break; 00690 } 00691 00692 iks_filter_packet(client->f, pak); 00693 00694 if (node) 00695 iks_delete(node); 00696 00697 ASTOBJ_UNREF(client, aji_client_destroy); 00698 return IKS_OK; 00699 }
static void aji_buddy_destroy | ( | struct aji_buddy * | obj | ) | [static] |
Deletes the aji_buddy data structure.
obj | is the structure we will delete. |
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.
aji_client | struct, and xml packet. |
Definition at line 1855 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().
01856 { 01857 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01858 int res = IKS_FILTER_PASS; 01859 01860 if (client) { 01861 if (client->state == AJI_DISCONNECTED) { 01862 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); 01863 client->state = AJI_CONNECTING; 01864 client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid; 01865 if (!client->component) { /*client*/ 01866 aji_get_roster(client); 01867 } 01868 iks_filter_remove_hook(client->f, aji_client_connect); 01869 /* Once we remove the hook for this routine, we must return EAT or we will crash or corrupt memory */ 01870 res = IKS_FILTER_EAT; 01871 } 01872 } else 01873 ast_log(LOG_ERROR, "Out of memory.\n"); 01874 01875 ASTOBJ_UNREF(client, aji_client_destroy); 01876 return res; 01877 }
static void aji_client_destroy | ( | struct aji_client * | obj | ) | [static] |
Deletes the aji_client data structure.
obj | is the structure we will delete. |
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::list, aji_message::message, aji_client::messages, 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 906 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().
00907 { 00908 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00909 struct aji_resource *resource = NULL; 00910 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00911 00912 resource = aji_find_resource(buddy, pak->from->resource); 00913 if (pak->subtype == IKS_TYPE_RESULT) { 00914 if (!resource) { 00915 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00916 ASTOBJ_UNREF(client, aji_client_destroy); 00917 return IKS_FILTER_EAT; 00918 } 00919 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00920 resource->cap->jingle = 1; 00921 } else 00922 resource->cap->jingle = 0; 00923 } else if (pak->subtype == IKS_TYPE_GET) { 00924 iks *iq, *disco, *ident, *google, *query; 00925 iq = iks_new("iq"); 00926 query = iks_new("query"); 00927 ident = iks_new("identity"); 00928 disco = iks_new("feature"); 00929 google = iks_new("feature"); 00930 if (iq && ident && disco && google) { 00931 iks_insert_attrib(iq, "from", client->jid->full); 00932 iks_insert_attrib(iq, "to", pak->from->full); 00933 iks_insert_attrib(iq, "type", "result"); 00934 iks_insert_attrib(iq, "id", pak->id); 00935 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00936 iks_insert_attrib(ident, "category", "client"); 00937 iks_insert_attrib(ident, "type", "pc"); 00938 iks_insert_attrib(ident, "name", "asterisk"); 00939 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info"); 00940 iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1"); 00941 iks_insert_node(iq, query); 00942 iks_insert_node(query, ident); 00943 iks_insert_node(query, google); 00944 iks_insert_node(query, disco); 00945 iks_send(client->p, iq); 00946 } else 00947 ast_log(LOG_ERROR, "Out of Memory.\n"); 00948 if (iq) 00949 iks_delete(iq); 00950 if (query) 00951 iks_delete(query); 00952 if (ident) 00953 iks_delete(ident); 00954 if (google) 00955 iks_delete(google); 00956 if (disco) 00957 iks_delete(disco); 00958 } else if (pak->subtype == IKS_TYPE_ERROR) { 00959 ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full); 00960 } 00961 ASTOBJ_UNREF(client, aji_client_destroy); 00962 return IKS_FILTER_EAT; 00963 }
static int aji_client_initialize | ( | struct aji_client * | client | ) | [static] |
prepares client for connect.
aji_client | struct. |
Definition at line 1884 of file res_jabber.c.
References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::name, aji_client::p, aji_client::port, S_OR, and aji_client::serverhost.
Referenced by aji_reconnect().
01885 { 01886 int connected = 0; 01887 01888 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server); 01889 01890 if (connected == IKS_NET_NOCONN) { 01891 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01892 return IKS_HOOK; 01893 } else if (connected == IKS_NET_NODNS) { 01894 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01895 return IKS_HOOK; 01896 } else 01897 iks_recv(client->p, 30); 01898 return IKS_OK; 01899 }
static int aji_component_initialize | ( | struct aji_client * | client | ) | [static] |
prepares component for connect.
aji_client | struct. |
Definition at line 1906 of file res_jabber.c.
References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::name, aji_client::p, aji_client::port, S_OR, aji_client::serverhost, and aji_client::user.
Referenced by aji_reconnect().
01907 { 01908 int connected = 1; 01909 01910 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->user); 01911 if (connected == IKS_NET_NOCONN) { 01912 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01913 return IKS_HOOK; 01914 } else if (connected == IKS_NET_NODNS) { 01915 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01916 return IKS_HOOK; 01917 } else if (!connected) 01918 iks_recv(client->p, 30); 01919 return IKS_OK; 01920 }
static int aji_create_buddy | ( | char * | label, | |
struct aji_client * | client | |||
) | [static] |
creates transport. creates buddy.
label,buddy | to dump it into. |
Definition at line 2295 of file res_jabber.c.
References aji_buddy_destroy(), ast_copy_string(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::buddies, LOG_WARNING, malloc, and aji_buddy::name.
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.
label,ast_variable,debug,pruneregister,component/client,aji_client | to dump into. |
Definition at line 2106 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_copy_string(), 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::messages, aji_client::mid, aji_client::name, 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().
02107 { 02108 char *resource; 02109 struct aji_client *client = NULL; 02110 int flag = 0; 02111 02112 client = ASTOBJ_CONTAINER_FIND(&clients,label); 02113 if (!client) { 02114 flag = 1; 02115 client = (struct aji_client *) malloc(sizeof(struct aji_client)); 02116 if (!client) { 02117 ast_log(LOG_ERROR, "Out of memory!\n"); 02118 return 0; 02119 } 02120 memset(client, 0, sizeof(struct aji_client)); 02121 ASTOBJ_INIT(client); 02122 ASTOBJ_WRLOCK(client); 02123 ASTOBJ_CONTAINER_INIT(&client->buddies); 02124 } else { 02125 ASTOBJ_WRLOCK(client); 02126 ASTOBJ_UNMARK(client); 02127 } 02128 ASTOBJ_CONTAINER_MARKALL(&client->buddies); 02129 ast_copy_string(client->name, label, sizeof(client->name)); 02130 ast_copy_string(client->mid, "aaaaa", sizeof(client->mid)); 02131 02132 /* Set default values for the client object */ 02133 client->debug = debug; 02134 ast_copy_flags(client, &globalflags, AST_FLAGS_ALL); 02135 client->port = 5222; 02136 client->usetls = 1; 02137 client->usesasl = 1; 02138 client->forcessl = 0; 02139 client->keepalive = 1; 02140 client->timeout = 50; 02141 client->message_timeout = 100; 02142 AST_LIST_HEAD_INIT(&client->messages); 02143 client->component = 0; 02144 ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage)); 02145 02146 if (flag) { 02147 client->authorized = 0; 02148 client->state = AJI_DISCONNECTED; 02149 } 02150 while (var) { 02151 if (!strcasecmp(var->name, "username")) 02152 ast_copy_string(client->user, var->value, sizeof(client->user)); 02153 else if (!strcasecmp(var->name, "serverhost")) 02154 ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost)); 02155 else if (!strcasecmp(var->name, "secret")) 02156 ast_copy_string(client->password, var->value, sizeof(client->password)); 02157 else if (!strcasecmp(var->name, "statusmessage")) 02158 ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage)); 02159 else if (!strcasecmp(var->name, "port")) 02160 client->port = atoi(var->value); 02161 else if (!strcasecmp(var->name, "timeout")) 02162 client->message_timeout = atoi(var->value); 02163 else if (!strcasecmp(var->name, "debug")) 02164 client->debug = (ast_false(var->value)) ? 0 : 1; 02165 else if (!strcasecmp(var->name, "type")) { 02166 if (!strcasecmp(var->value, "component")) 02167 client->component = 1; 02168 } else if (!strcasecmp(var->name, "usetls")) { 02169 client->usetls = (ast_false(var->value)) ? 0 : 1; 02170 } else if (!strcasecmp(var->name, "usesasl")) { 02171 client->usesasl = (ast_false(var->value)) ? 0 : 1; 02172 } else if (!strcasecmp(var->name, "forceoldssl")) 02173 client->forcessl = (ast_false(var->value)) ? 0 : 1; 02174 else if (!strcasecmp(var->name, "keepalive")) 02175 client->keepalive = (ast_false(var->value)) ? 0 : 1; 02176 else if (!strcasecmp(var->name, "autoprune")) 02177 ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE); 02178 else if (!strcasecmp(var->name, "autoregister")) 02179 ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER); 02180 else if (!strcasecmp(var->name, "buddy")) 02181 aji_create_buddy(var->value, client); 02182 /* no transport support in this version */ 02183 /* else if (!strcasecmp(var->name, "transport")) 02184 aji_create_transport(var->value, client); 02185 */ 02186 var = var->next; 02187 } 02188 if (!flag) { 02189 ASTOBJ_UNLOCK(client); 02190 ASTOBJ_UNREF(client, aji_client_destroy); 02191 return 1; 02192 } 02193 client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook); 02194 if (!client->p) { 02195 ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name); 02196 return 0; 02197 } 02198 client->stack = iks_stack_new(8192, 8192); 02199 if (!client->stack) { 02200 ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name); 02201 return 0; 02202 } 02203 client->f = iks_filter_new(); 02204 if (!client->f) { 02205 ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name); 02206 return 0; 02207 } 02208 if (!strchr(client->user, '/') && !client->component) { /*client */ 02209 resource = NULL; 02210 if (asprintf(&resource, "%s/asterisk", client->user) > 0) { 02211 client->jid = iks_id_new(client->stack, resource); 02212 free(resource); 02213 } 02214 } else 02215 client->jid = iks_id_new(client->stack, client->user); 02216 if (client->component) { 02217 iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02218 iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE); 02219 iks_filter_add_rule(client->f, aji_register_query_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE); 02220 iks_filter_add_rule(client->f, aji_register_approve_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_SET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE); 02221 } else { 02222 iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02223 } 02224 if (!strchr(client->user, '/') && !client->component) { /*client */ 02225 resource = NULL; 02226 if (asprintf(&resource, "%s/asterisk", client->user) > 0) { 02227 client->jid = iks_id_new(client->stack, resource); 02228 free(resource); 02229 } 02230 } else 02231 client->jid = iks_id_new(client->stack, client->user); 02232 iks_set_log_hook(client->p, aji_log_hook); 02233 ASTOBJ_UNLOCK(client); 02234 ASTOBJ_CONTAINER_LINK(&clients,client); 02235 return 1; 02236 }
static int aji_dinfo_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 965 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, commands, aji_version::jingle, LOG_ERROR, LOG_NOTICE, LOG_WARNING, aji_client::p, aji_resource::resource, and aji_client::user.
Referenced by aji_create_client().
00966 { 00967 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00968 char *node = NULL; 00969 struct aji_resource *resource = NULL; 00970 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00971 00972 resource = aji_find_resource(buddy, pak->from->resource); 00973 if (pak->subtype == IKS_TYPE_ERROR) { 00974 ast_log(LOG_WARNING, "Received error from a client, turn on jabber debug!\n"); 00975 return IKS_FILTER_EAT; 00976 } 00977 if (pak->subtype == IKS_TYPE_RESULT) { 00978 if (!resource) { 00979 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00980 ASTOBJ_UNREF(client, aji_client_destroy); 00981 return IKS_FILTER_EAT; 00982 } 00983 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00984 resource->cap->jingle = 1; 00985 } else 00986 resource->cap->jingle = 0; 00987 } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) { 00988 iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search; 00989 00990 iq = iks_new("iq"); 00991 query = iks_new("query"); 00992 identity = iks_new("identity"); 00993 disco = iks_new("feature"); 00994 reg = iks_new("feature"); 00995 commands = iks_new("feature"); 00996 gateway = iks_new("feature"); 00997 version = iks_new("feature"); 00998 vcard = iks_new("feature"); 00999 search = iks_new("feature"); 01000 01001 if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) { 01002 iks_insert_attrib(iq, "from", client->user); 01003 iks_insert_attrib(iq, "to", pak->from->full); 01004 iks_insert_attrib(iq, "id", pak->id); 01005 iks_insert_attrib(iq, "type", "result"); 01006 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01007 iks_insert_attrib(identity, "category", "gateway"); 01008 iks_insert_attrib(identity, "type", "pstn"); 01009 iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX"); 01010 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco"); 01011 iks_insert_attrib(reg, "var", "jabber:iq:register"); 01012 iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands"); 01013 iks_insert_attrib(gateway, "var", "jabber:iq:gateway"); 01014 iks_insert_attrib(version, "var", "jabber:iq:version"); 01015 iks_insert_attrib(vcard, "var", "vcard-temp"); 01016 iks_insert_attrib(search, "var", "jabber:iq:search"); 01017 01018 iks_insert_node(iq, query); 01019 iks_insert_node(query, identity); 01020 iks_insert_node(query, disco); 01021 iks_insert_node(query, reg); 01022 iks_insert_node(query, commands); 01023 iks_insert_node(query, gateway); 01024 iks_insert_node(query, version); 01025 iks_insert_node(query, vcard); 01026 iks_insert_node(query, search); 01027 iks_send(client->p, iq); 01028 } else { 01029 ast_log(LOG_ERROR, "Out of memory.\n"); 01030 } 01031 01032 if (iq) 01033 iks_delete(iq); 01034 if (query) 01035 iks_delete(query); 01036 if (identity) 01037 iks_delete(identity); 01038 if (disco) 01039 iks_delete(disco); 01040 if (reg) 01041 iks_delete(reg); 01042 if (commands) 01043 iks_delete(commands); 01044 if (gateway) 01045 iks_delete(gateway); 01046 if (version) 01047 iks_delete(version); 01048 if (vcard) 01049 iks_delete(vcard); 01050 if (search) 01051 iks_delete(search); 01052 01053 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) { 01054 iks *iq, *query, *confirm; 01055 iq = iks_new("iq"); 01056 query = iks_new("query"); 01057 confirm = iks_new("item"); 01058 01059 if (iq && query && confirm && client) { 01060 iks_insert_attrib(iq, "from", client->user); 01061 iks_insert_attrib(iq, "to", pak->from->full); 01062 iks_insert_attrib(iq, "id", pak->id); 01063 iks_insert_attrib(iq, "type", "result"); 01064 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 01065 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 01066 iks_insert_attrib(confirm, "node", "confirmaccount"); 01067 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 01068 iks_insert_attrib(confirm, "jid", client->user); 01069 iks_insert_node(iq, query); 01070 iks_insert_node(query, confirm); 01071 iks_send(client->p, iq); 01072 } else { 01073 ast_log(LOG_ERROR, "Out of memory.\n"); 01074 } 01075 if (iq) 01076 iks_delete(iq); 01077 if (query) 01078 iks_delete(query); 01079 if (confirm) 01080 iks_delete(confirm); 01081 01082 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) { 01083 iks *iq, *query, *feature; 01084 01085 iq = iks_new("iq"); 01086 query = iks_new("query"); 01087 feature = iks_new("feature"); 01088 01089 if (iq && query && feature && client) { 01090 iks_insert_attrib(iq, "from", client->user); 01091 iks_insert_attrib(iq, "to", pak->from->full); 01092 iks_insert_attrib(iq, "id", pak->id); 01093 iks_insert_attrib(iq, "type", "result"); 01094 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01095 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 01096 iks_insert_node(iq, query); 01097 iks_insert_node(query, feature); 01098 iks_send(client->p, iq); 01099 } else { 01100 ast_log(LOG_ERROR, "Out of memory.\n"); 01101 } 01102 if (iq) 01103 iks_delete(iq); 01104 if (query) 01105 iks_delete(query); 01106 if (feature) 01107 iks_delete(feature); 01108 } 01109 01110 ASTOBJ_UNREF(client, aji_client_destroy); 01111 return IKS_FILTER_EAT; 01112 }
static int aji_ditems_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 810 of file res_jabber.c.
References aji_client_destroy(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, LOG_ERROR, aji_client::p, and aji_client::user.
Referenced by aji_create_client().
00811 { 00812 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00813 char *node = NULL; 00814 00815 if (!(node = iks_find_attrib(pak->query, "node"))) { 00816 iks *iq = NULL, *query = NULL, *item = NULL; 00817 iq = iks_new("iq"); 00818 query = iks_new("query"); 00819 item = iks_new("item"); 00820 00821 if (iq && query && item) { 00822 iks_insert_attrib(iq, "from", client->user); 00823 iks_insert_attrib(iq, "to", pak->from->full); 00824 iks_insert_attrib(iq, "id", pak->id); 00825 iks_insert_attrib(iq, "type", "result"); 00826 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00827 iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands"); 00828 iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands"); 00829 iks_insert_attrib(item, "jid", client->user); 00830 00831 iks_insert_node(iq, query); 00832 iks_insert_node(query, item); 00833 iks_send(client->p, iq); 00834 } else { 00835 ast_log(LOG_ERROR, "Out of memory.\n"); 00836 } 00837 if (iq) 00838 iks_delete(iq); 00839 if (query) 00840 iks_delete(query); 00841 if (item) 00842 iks_delete(item); 00843 00844 } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) { 00845 iks *iq, *query, *confirm; 00846 iq = iks_new("iq"); 00847 query = iks_new("query"); 00848 confirm = iks_new("item"); 00849 if (iq && query && confirm && client) { 00850 iks_insert_attrib(iq, "from", client->user); 00851 iks_insert_attrib(iq, "to", pak->from->full); 00852 iks_insert_attrib(iq, "id", pak->id); 00853 iks_insert_attrib(iq, "type", "result"); 00854 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00855 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 00856 iks_insert_attrib(confirm, "node", "confirmaccount"); 00857 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 00858 iks_insert_attrib(confirm, "jid", "blog.astjab.org"); 00859 00860 iks_insert_node(iq, query); 00861 iks_insert_node(query, confirm); 00862 iks_send(client->p, iq); 00863 } else { 00864 ast_log(LOG_ERROR, "Out of memory.\n"); 00865 } 00866 if (iq) 00867 iks_delete(iq); 00868 if (query) 00869 iks_delete(query); 00870 if (confirm) 00871 iks_delete(confirm); 00872 00873 } else if (!strcasecmp(node, "confirmaccount")) { 00874 iks *iq = NULL, *query = NULL, *feature = NULL; 00875 00876 iq = iks_new("iq"); 00877 query = iks_new("query"); 00878 feature = iks_new("feature"); 00879 00880 if (iq && query && feature && client) { 00881 iks_insert_attrib(iq, "from", client->user); 00882 iks_insert_attrib(iq, "to", pak->from->full); 00883 iks_insert_attrib(iq, "id", pak->id); 00884 iks_insert_attrib(iq, "type", "result"); 00885 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00886 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 00887 iks_insert_node(iq, query); 00888 iks_insert_node(query, feature); 00889 iks_send(client->p, iq); 00890 } else { 00891 ast_log(LOG_ERROR, "Out of memory.\n"); 00892 } 00893 if (iq) 00894 iks_delete(iq); 00895 if (query) 00896 iks_delete(query); 00897 if (feature) 00898 iks_delete(feature); 00899 } 00900 00901 ASTOBJ_UNREF(client, aji_client_destroy); 00902 return IKS_FILTER_EAT; 00903 00904 }
static int aji_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
turnon console debugging.
fd,number | of args, args. |
Definition at line 1977 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01978 { 01979 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01980 ASTOBJ_RDLOCK(iterator); 01981 iterator->debug = 1; 01982 ASTOBJ_UNLOCK(iterator); 01983 }); 01984 ast_cli(fd, "Jabber Debugging Enabled.\n"); 01985 return RESULT_SUCCESS; 01986 }
static int aji_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
reload jabber module.
fd,number | of args, args. |
Definition at line 1993 of file res_jabber.c.
References aji_reload(), ast_cli(), and RESULT_SUCCESS.
01994 { 01995 aji_reload(); 01996 ast_cli(fd, "Jabber Reloaded.\n"); 01997 return RESULT_SUCCESS; 01998 }
static int aji_filter_roster | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
filters the roster packet we get back from server.
aji_client | struct, and xml packet. |
Definition at line 1744 of file res_jabber.c.
References AJI_AUTOPRUNE, AJI_AUTOREGISTER, AJI_CONNECTED, ast_clear_flag, ast_copy_flags, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_REF, ASTOBJ_UNLOCK, aji_client::buddies, and aji_client::state.
Referenced by aji_client_connect().
01745 { 01746 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01747 int flag = 0; 01748 iks *x = NULL; 01749 struct aji_buddy *buddy; 01750 01751 client->state = AJI_CONNECTED; 01752 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01753 ASTOBJ_RDLOCK(iterator); 01754 x = iks_child(pak->query); 01755 flag = 0; 01756 while (x) { 01757 if (!iks_strcmp(iks_name(x), "item")) { 01758 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) { 01759 flag = 1; 01760 ast_clear_flag(iterator, AJI_AUTOPRUNE | AJI_AUTOREGISTER); 01761 } 01762 } 01763 x = iks_next(x); 01764 } 01765 if (!flag) 01766 ast_copy_flags(iterator, client, AJI_AUTOREGISTER); 01767 if (x) 01768 iks_delete(x); 01769 ASTOBJ_UNLOCK(iterator); 01770 }); 01771 01772 x = iks_child(pak->query); 01773 while (x) { 01774 flag = 0; 01775 if (iks_strcmp(iks_name(x), "item") == 0) { 01776 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01777 ASTOBJ_RDLOCK(iterator); 01778 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) 01779 flag = 1; 01780 ASTOBJ_UNLOCK(iterator); 01781 }); 01782 01783 if (!flag) { 01784 buddy = (struct aji_buddy *) malloc(sizeof(struct aji_buddy)); 01785 if (!buddy) { 01786 ast_log(LOG_WARNING, "Out of memory\n"); 01787 return 0; 01788 } 01789 memset(buddy, 0, sizeof(struct aji_buddy)); 01790 ASTOBJ_INIT(buddy); 01791 ASTOBJ_WRLOCK(buddy); 01792 ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name)); 01793 ast_clear_flag(buddy, AST_FLAGS_ALL); 01794 if(ast_test_flag(client, AJI_AUTOPRUNE)) { 01795 ast_set_flag(buddy, AJI_AUTOPRUNE); 01796 buddy->objflags |= ASTOBJ_FLAG_MARKED; 01797 } else 01798 ast_set_flag(buddy, AJI_AUTOREGISTER); 01799 ASTOBJ_UNLOCK(buddy); 01800 if (buddy) { 01801 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 01802 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01803 } 01804 } 01805 } 01806 x = iks_next(x); 01807 } 01808 if (x) 01809 iks_delete(x); 01810 aji_pruneregister(client); 01811 01812 ASTOBJ_UNREF(client, aji_client_destroy); 01813 return IKS_FILTER_EAT; 01814 }
static struct aji_resource* aji_find_resource | ( | struct aji_buddy * | buddy, | |
char * | name | |||
) | [static] |
Definition at line 295 of file res_jabber.c.
References aji_resource::next, aji_resource::resource, and aji_buddy::resources.
Referenced by aji_client_info_handler(), aji_dinfo_handler(), and aji_status_exec().
00296 { 00297 struct aji_resource *res = NULL; 00298 if (!buddy || !name) 00299 return res; 00300 res = buddy->resources; 00301 while (res) { 00302 if (!strcasecmp(res->resource, name)) { 00303 break; 00304 } 00305 res = res->next; 00306 } 00307 return res; 00308 }
static struct aji_version* aji_find_version | ( | char * | node, | |
char * | version, | |||
ikspak * | pak | |||
) | [static] |
Find version in XML stream and populate our capabilities list.
node | the node attribute in the caps element we'll look for or add to our list | |
version | the version attribute in the caps element we'll look for or add to our list | |
pak | the XML stanza we're processing |
Definition at line 233 of file res_jabber.c.
References ast_copy_string(), ast_free, ast_log(), capabilities, aji_version::jingle, LOG_ERROR, malloc, aji_capabilities::next, aji_version::next, aji_capabilities::node, aji_version::parent, aji_version::version, and aji_capabilities::versions.
Referenced by aji_handle_presence().
00234 { 00235 struct aji_capabilities *list = NULL; 00236 struct aji_version *res = NULL; 00237 00238 list = capabilities; 00239 00240 if(!node) 00241 node = pak->from->full; 00242 if(!version) 00243 version = "none supplied."; 00244 while(list) { 00245 if(!strcasecmp(list->node, node)) { 00246 res = list->versions; 00247 while(res) { 00248 if(!strcasecmp(res->version, version)) 00249 return res; 00250 res = res->next; 00251 } 00252 /* Specified version not found. Let's add it to 00253 this node in our capabilities list */ 00254 if(!res) { 00255 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00256 if(!res) { 00257 ast_log(LOG_ERROR, "Out of memory!\n"); 00258 return NULL; 00259 } 00260 res->jingle = 0; 00261 res->parent = list; 00262 ast_copy_string(res->version, version, sizeof(res->version)); 00263 res->next = list->versions; 00264 list->versions = res; 00265 return res; 00266 } 00267 } 00268 list = list->next; 00269 } 00270 /* Specified node not found. Let's add it our capabilities list */ 00271 if(!list) { 00272 list = (struct aji_capabilities *)malloc(sizeof(struct aji_capabilities)); 00273 if(!list) { 00274 ast_log(LOG_ERROR, "Out of memory!\n"); 00275 return NULL; 00276 } 00277 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00278 if(!res) { 00279 ast_log(LOG_ERROR, "Out of memory!\n"); 00280 ast_free(list); 00281 return NULL; 00282 } 00283 ast_copy_string(list->node, node, sizeof(list->node)); 00284 ast_copy_string(res->version, version, sizeof(res->version)); 00285 res->jingle = 0; 00286 res->parent = list; 00287 res->next = NULL; 00288 list->versions = res; 00289 list->next = capabilities; 00290 capabilities = list; 00291 } 00292 return res; 00293 }
static int aji_get_roster | ( | struct aji_client * | client | ) | [static] |
Definition at line 1836 of file res_jabber.c.
References aji_set_presence(), aji_client::jid, aji_client::p, and aji_client::statusmessage.
Referenced by aji_client_connect(), and aji_reload().
01837 { 01838 iks *roster = NULL; 01839 roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER); 01840 if(roster) { 01841 iks_insert_attrib(roster, "id", "roster"); 01842 aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage); 01843 iks_send(client->p, roster); 01844 } 01845 if (roster) 01846 iks_delete(roster); 01847 return 1; 01848 }
static void aji_handle_iq | ( | struct aji_client * | client, | |
iks * | node | |||
) | [static] |
Handles <iq> tags.
client | structure and the iq node. |
Definition at line 1119 of file res_jabber.c.
Referenced by aji_act_hook().
static void aji_handle_message | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
Handles presence packets.
client | structure and the node. |
Definition at line 1129 of file res_jabber.c.
References aji_message::arrived, ast_calloc, ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_strdup, free, aji_message::from, aji_message::id, aji_message::list, aji_message::message, aji_client::message_timeout, and aji_client::messages.
Referenced by aji_act_hook().
01130 { 01131 struct aji_message *insert, *tmp; 01132 int flag = 0; 01133 01134 if (!(insert = ast_calloc(1, sizeof(struct aji_message)))) 01135 return; 01136 time(&insert->arrived); 01137 if (iks_find_cdata(pak->x, "body")) 01138 insert->message = ast_strdup(iks_find_cdata(pak->x, "body")); 01139 if(pak->id) 01140 ast_copy_string(insert->id, pak->id, sizeof(insert->message)); 01141 if (pak->from) 01142 insert->from = ast_strdup(pak->from->full); 01143 AST_LIST_LOCK(&client->messages); 01144 AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) { 01145 if (flag) { 01146 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01147 if (tmp->from) 01148 free(tmp->from); 01149 if (tmp->message) 01150 free(tmp->message); 01151 } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) { 01152 flag = 1; 01153 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01154 if (tmp->from) 01155 free(tmp->from); 01156 if (tmp->message) 01157 free(tmp->message); 01158 } 01159 } 01160 AST_LIST_TRAVERSE_SAFE_END; 01161 AST_LIST_INSERT_HEAD(&client->messages, insert, list); 01162 AST_LIST_UNLOCK(&client->messages); 01163 }
static void aji_handle_presence | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 1165 of file res_jabber.c.
References aji_buddy_destroy(), AJI_CONNECTED, aji_create_buddy(), aji_find_version(), aji_set_presence(), ast_aji_increment_mid(), ast_copy_string(), ast_log(), ast_strdup, ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::buddies, aji_client::component, descrip, aji_resource::description, free, gtalk_yuck(), aji_client::jid, last, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, malloc, aji_client::mid, aji_resource::next, option_debug, option_verbose, aji_client::p, aji_resource::priority, aji_resource::resource, aji_buddy::resources, aji_client::state, aji_resource::status, aji_client::statusmessage, type, and VERBOSE_PREFIX_3.
Referenced by aji_act_hook().
01166 { 01167 int status, priority; 01168 struct aji_buddy *buddy; 01169 struct aji_resource *tmp = NULL, *last = NULL, *found = NULL; 01170 char *ver, *node, *descrip, *type; 01171 01172 if(client->state != AJI_CONNECTED) 01173 aji_create_buddy(pak->from->partial, client); 01174 01175 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01176 if (!buddy && pak->from->partial) { 01177 /* allow our jid to be used to log in with another resource */ 01178 if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial)) 01179 aji_create_buddy(pak->from->partial, client); 01180 else 01181 ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial); 01182 return; 01183 } 01184 type = iks_find_attrib(pak->x, "type"); 01185 if(client->component && type &&!strcasecmp("probe", type)) { 01186 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01187 ast_verbose("what i was looking for \n"); 01188 } 01189 ASTOBJ_WRLOCK(buddy); 01190 status = (pak->show) ? pak->show : 6; 01191 priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0"); 01192 tmp = buddy->resources; 01193 descrip = ast_strdup(iks_find_cdata(pak->x,"status")); 01194 01195 while (tmp && pak->from->resource) { 01196 if (!strcasecmp(tmp->resource, pak->from->resource)) { 01197 tmp->status = status; 01198 if (tmp->description) free(tmp->description); 01199 tmp->description = descrip; 01200 found = tmp; 01201 if (status == 6) { /* Sign off Destroy resource */ 01202 if (last && found->next) { 01203 last->next = found->next; 01204 } else if (!last) { 01205 if (found->next) 01206 buddy->resources = found->next; 01207 else 01208 buddy->resources = NULL; 01209 } else if (!found->next) { 01210 if (last) 01211 last->next = NULL; 01212 else 01213 buddy->resources = NULL; 01214 } 01215 free(found); 01216 found = NULL; 01217 break; 01218 } 01219 /* resource list is sorted by descending priority */ 01220 if (tmp->priority != priority) { 01221 found->priority = priority; 01222 if (!last && !found->next) 01223 /* resource was found to be unique, 01224 leave loop */ 01225 break; 01226 /* search for resource in our list 01227 and take it out for the moment */ 01228 if (last) 01229 last->next = found->next; 01230 else 01231 buddy->resources = found->next; 01232 01233 last = NULL; 01234 tmp = buddy->resources; 01235 if (!buddy->resources) 01236 buddy->resources = found; 01237 /* priority processing */ 01238 while (tmp) { 01239 /* insert resource back according to 01240 its priority value */ 01241 if (found->priority > tmp->priority) { 01242 if (last) 01243 /* insert within list */ 01244 last->next = found; 01245 found->next = tmp; 01246 if (!last) 01247 /* insert on top */ 01248 buddy->resources = found; 01249 break; 01250 } 01251 if (!tmp->next) { 01252 /* insert at the end of the list */ 01253 tmp->next = found; 01254 found->next = NULL; 01255 break; 01256 } 01257 last = tmp; 01258 tmp = tmp->next; 01259 } 01260 } 01261 break; 01262 } 01263 last = tmp; 01264 tmp = tmp->next; 01265 } 01266 01267 /* resource not found in our list, create it */ 01268 if (!found && status != 6 && pak->from->resource) { 01269 found = (struct aji_resource *) malloc(sizeof(struct aji_resource)); 01270 memset(found, 0, sizeof(struct aji_resource)); 01271 01272 if (!found) { 01273 ast_log(LOG_ERROR, "Out of memory!\n"); 01274 return; 01275 } 01276 ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource)); 01277 found->status = status; 01278 found->description = descrip; 01279 found->priority = priority; 01280 found->next = NULL; 01281 last = NULL; 01282 tmp = buddy->resources; 01283 while (tmp) { 01284 if (found->priority > tmp->priority) { 01285 if (last) 01286 last->next = found; 01287 found->next = tmp; 01288 if (!last) 01289 buddy->resources = found; 01290 break; 01291 } 01292 if (!tmp->next) { 01293 tmp->next = found; 01294 break; 01295 } 01296 last = tmp; 01297 tmp = tmp->next; 01298 } 01299 if (!tmp) 01300 buddy->resources = found; 01301 } 01302 01303 ASTOBJ_UNLOCK(buddy); 01304 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01305 01306 node = iks_find_attrib(iks_find(pak->x, "c"), "node"); 01307 ver = iks_find_attrib(iks_find(pak->x, "c"), "ver"); 01308 01309 /* handle gmail client's special caps:c tag */ 01310 if (!node && !ver) { 01311 node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node"); 01312 ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver"); 01313 } 01314 01315 /* retrieve capabilites of the new resource */ 01316 if(status !=6 && found && !found->cap) { 01317 found->cap = aji_find_version(node, ver, pak); 01318 if(gtalk_yuck(pak->x)) /* gtalk should do discover */ 01319 found->cap->jingle = 1; 01320 if(found->cap->jingle && option_debug > 4) 01321 ast_log(LOG_DEBUG,"Special case for google till they support discover.\n"); 01322 else { 01323 iks *iq, *query; 01324 iq = iks_new("iq"); 01325 query = iks_new("query"); 01326 if(query && iq) { 01327 iks_insert_attrib(iq, "type", "get"); 01328 iks_insert_attrib(iq, "to", pak->from->full); 01329 iks_insert_attrib(iq,"from", client->jid->full); 01330 iks_insert_attrib(iq, "id", client->mid); 01331 ast_aji_increment_mid(client->mid); 01332 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01333 iks_insert_node(iq, query); 01334 iks_send(client->p, iq); 01335 01336 } else 01337 ast_log(LOG_ERROR, "Out of memory.\n"); 01338 if(query) 01339 iks_delete(query); 01340 if(iq) 01341 iks_delete(iq); 01342 } 01343 } 01344 if (option_verbose > 4) { 01345 switch (pak->subtype) { 01346 case IKS_TYPE_AVAILABLE: 01347 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am available ^_* %i\n", pak->subtype); 01348 break; 01349 case IKS_TYPE_UNAVAILABLE: 01350 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am unavailable ^_* %i\n", pak->subtype); 01351 break; 01352 default: 01353 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype); 01354 } 01355 switch (pak->show) { 01356 case IKS_SHOW_UNAVAILABLE: 01357 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01358 break; 01359 case IKS_SHOW_AVAILABLE: 01360 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is available\n"); 01361 break; 01362 case IKS_SHOW_CHAT: 01363 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01364 break; 01365 case IKS_SHOW_AWAY: 01366 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is away\n"); 01367 break; 01368 case IKS_SHOW_XA: 01369 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01370 break; 01371 case IKS_SHOW_DND: 01372 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01373 break; 01374 default: 01375 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Kinky! how did that happen %i\n", pak->show); 01376 } 01377 } 01378 }
static void aji_handle_subscribe | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
handles subscription requests.
aji_client | struct and xml packet. |
Definition at line 1385 of file res_jabber.c.
References aji_create_buddy(), aji_set_presence(), ast_log(), ast_verbose(), ASTOBJ_CONTAINER_FIND, aji_client::buddies, aji_client::component, aji_client::jid, LOG_ERROR, option_verbose, aji_client::p, aji_resource::status, aji_client::statusmessage, and VERBOSE_PREFIX_3.
Referenced by aji_act_hook().
01386 { 01387 iks *presence = NULL, *status = NULL; 01388 struct aji_buddy* buddy = NULL; 01389 01390 switch (pak->subtype) { 01391 case IKS_TYPE_SUBSCRIBE: 01392 presence = iks_new("presence"); 01393 status = iks_new("status"); 01394 if(presence && status) { 01395 iks_insert_attrib(presence, "type", "subscribed"); 01396 iks_insert_attrib(presence, "to", pak->from->full); 01397 iks_insert_attrib(presence, "from", client->jid->full); 01398 if(pak->id) 01399 iks_insert_attrib(presence, "id", pak->id); 01400 iks_insert_cdata(status, "Asterisk has approved subscription", 0); 01401 iks_insert_node(presence, status); 01402 iks_send(client->p, presence); 01403 } else 01404 ast_log(LOG_ERROR, "Unable to allocate nodes\n"); 01405 if(presence) 01406 iks_delete(presence); 01407 if(status) 01408 iks_delete(status); 01409 if(client->component) 01410 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01411 case IKS_TYPE_SUBSCRIBED: 01412 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01413 if (!buddy && pak->from->partial) { 01414 aji_create_buddy(pak->from->partial, client); 01415 } 01416 default: 01417 if (option_verbose > 4) { 01418 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01419 } 01420 } 01421 }
static int aji_highest_bit | ( | int | number | ) | [static] |
Detects the highest bit in a number.
Number | you want to have evaluated. |
Definition at line 322 of file res_jabber.c.
Referenced by aji_act_hook().
00323 { 00324 int x = sizeof(number) * 8 - 1; 00325 if (!number) 00326 return 0; 00327 for (; x > 0; x--) { 00328 if (number & (1 << x)) 00329 break; 00330 } 00331 return (1 << x); 00332 }
static int aji_load_config | ( | void | ) | [static] |
load config file.
void. |
Definition at line 2327 of file res_jabber.c.
References AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_create_client(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_false(), ast_log(), ast_set2_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), debug, globalflags, JABBER_CONFIG, LOG_WARNING, and var.
Referenced by aji_reload().
02328 { 02329 char *cat = NULL; 02330 int debug = 0; 02331 struct ast_config *cfg = NULL; 02332 struct ast_variable *var = NULL; 02333 02334 cfg = ast_config_load(JABBER_CONFIG); 02335 if (!cfg) { 02336 ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG); 02337 return 0; 02338 } 02339 02340 cat = ast_category_browse(cfg, NULL); 02341 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { 02342 if (!strcasecmp(var->name, "debug")) 02343 debug = (ast_false(ast_variable_retrieve(cfg, "general", "debug"))) ? 0 : 1; 02344 else if (!strcasecmp(var->name, "autoprune")) 02345 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOPRUNE); 02346 else if (!strcasecmp(var->name, "autoregister")) 02347 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOREGISTER); 02348 } 02349 02350 while (cat) { 02351 if (strcasecmp(cat, "general")) { 02352 var = ast_variable_browse(cfg, cat); 02353 aji_create_client(cat, var, debug); 02354 } 02355 cat = ast_category_browse(cfg, cat); 02356 } 02357 ast_config_destroy(cfg); /* or leak memory */ 02358 return 1; 02359 }
static void aji_log_hook | ( | void * | data, | |
const char * | xmpp, | |||
size_t | size, | |||
int | is_incoming | |||
) | [static] |
the debug loop.
aji_client | structure, xml data as string, size of string, direction of packet, 1 for inbound 0 for outbound. |
Definition at line 461 of file res_jabber.c.
References aji_client_destroy(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::debug, EVENT_FLAG_USER, manager_event(), aji_client::name, and option_debug.
Referenced by aji_create_client().
00462 { 00463 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00464 manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp); 00465 00466 if (client->debug) { 00467 if (is_incoming) 00468 ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp); 00469 else { 00470 if( strlen(xmpp) == 1) { 00471 if(option_debug > 2 && xmpp[0] == ' ') 00472 ast_verbose("\nJABBER: Keep alive packet\n"); 00473 } else 00474 ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp); 00475 } 00476 00477 } 00478 ASTOBJ_UNREF(client, aji_client_destroy); 00479 }
static int aji_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
turnoff console debugging.
fd,number | of args, args. |
Definition at line 2005 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
02006 { 02007 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02008 ASTOBJ_RDLOCK(iterator); 02009 iterator->debug = 0; 02010 ASTOBJ_UNLOCK(iterator); 02011 }); 02012 ast_cli(fd, "Jabber Debugging Disabled.\n"); 02013 return RESULT_SUCCESS; 02014 }
static void aji_pruneregister | ( | struct aji_client * | client | ) | [static] |
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.
aji_client | struct. |
Definition at line 1691 of file res_jabber.c.
References AJI_AUTOPRUNE, AJI_AUTOREGISTER, ast_clear_flag, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, aji_client::buddies, aji_client::jid, and aji_client::p.
01692 { 01693 int res = 0; 01694 iks *removeiq = iks_new("iq"); 01695 iks *removequery = iks_new("query"); 01696 iks *removeitem = iks_new("item"); 01697 iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items"); 01698 01699 if (client && removeiq && removequery && removeitem && send) { 01700 iks_insert_node(removeiq, removequery); 01701 iks_insert_node(removequery, removeitem); 01702 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01703 ASTOBJ_RDLOCK(iterator); 01704 /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never 01705 * be called at the same time */ 01706 if (ast_test_flag(iterator, AJI_AUTOPRUNE)) { 01707 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name, 01708 "GoodBye your status is no longer needed by Asterisk the Open Source PBX" 01709 " so I am no longer subscribing to your presence.\n")); 01710 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name, 01711 "GoodBye you are no longer in the asterisk config file so I am removing" 01712 " your access to my presence.\n")); 01713 iks_insert_attrib(removeiq, "from", client->jid->full); 01714 iks_insert_attrib(removeiq, "type", "set"); 01715 iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster"); 01716 iks_insert_attrib(removeitem, "jid", iterator->name); 01717 iks_insert_attrib(removeitem, "subscription", "remove"); 01718 res = iks_send(client->p, removeiq); 01719 } else if (ast_test_flag(iterator, AJI_AUTOREGISTER)) { 01720 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name, 01721 "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n")); 01722 ast_clear_flag(iterator, AJI_AUTOREGISTER); 01723 } 01724 ASTOBJ_UNLOCK(iterator); 01725 }); 01726 } else 01727 ast_log(LOG_ERROR, "Out of memory.\n"); 01728 if (removeiq) 01729 iks_delete(removeiq); 01730 if (removequery) 01731 iks_delete(removequery); 01732 if (removeitem) 01733 iks_delete(removeitem); 01734 if (send) 01735 iks_delete(send); 01736 ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy); 01737 }
static int aji_reconnect | ( | struct aji_client * | client | ) | [static] |
Definition at line 1816 of file res_jabber.c.
References aji_client_initialize(), aji_component_initialize(), AJI_DISCONNECTED, aji_client::authorized, aji_client::component, aji_client::p, aji_client::state, and aji_client::timeout.
Referenced by aji_recv_loop().
01817 { 01818 int res = 0; 01819 01820 if (client->state) 01821 client->state = AJI_DISCONNECTED; 01822 client->timeout=50; 01823 if (client->p) 01824 iks_parser_reset(client->p); 01825 if (client->authorized) 01826 client->authorized = 0; 01827 01828 if(client->component) 01829 res = aji_component_initialize(client); 01830 else 01831 res = aji_client_initialize(client); 01832 01833 return res; 01834 }
static void * aji_recv_loop | ( | void * | data | ) | [static] |
receive message loop.
aji_client | struct. |
Definition at line 1540 of file res_jabber.c.
References aji_client_destroy(), AJI_CONNECTED, AJI_DISCONNECTING, aji_reconnect(), ast_log(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::keepalive, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, aji_client::p, aji_client::state, and aji_client::timeout.
Referenced by aji_reload().
01541 { 01542 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01543 int res = IKS_HOOK; 01544 do { 01545 if (res != IKS_OK) { 01546 while(res != IKS_OK) { 01547 if(option_verbose > 3) 01548 ast_verbose("JABBER: reconnecting.\n"); 01549 res = aji_reconnect(client); 01550 sleep(4); 01551 } 01552 } 01553 01554 res = iks_recv(client->p, 1); 01555 01556 if (client->state == AJI_DISCONNECTING) { 01557 if (option_debug > 1) 01558 ast_log(LOG_DEBUG, "Ending our Jabber client's thread due to a disconnect\n"); 01559 pthread_exit(NULL); 01560 } 01561 client->timeout--; 01562 if (res == IKS_HOOK) 01563 ast_log(LOG_WARNING, "JABBER: Got hook event.\n"); 01564 else if (res == IKS_NET_TLSFAIL) 01565 ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n"); 01566 else if (client->timeout == 0 && client->state == AJI_CONNECTED) { 01567 res = client->keepalive ? iks_send_raw(client->p, " ") : IKS_OK; 01568 if(res == IKS_OK) 01569 client->timeout = 50; 01570 else 01571 ast_log(LOG_WARNING, "JABBER: Network Timeout\n"); 01572 } else if (res == IKS_NET_RWERR) 01573 ast_log(LOG_WARNING, "JABBER: socket read error\n"); 01574 } while (client); 01575 ASTOBJ_UNREF(client, aji_client_destroy); 01576 return 0; 01577 }
static int aji_register_approve_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 701 of file res_jabber.c.
References aji_client_destroy(), ast_aji_increment_mid(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::jid, LOG_ERROR, aji_client::mid, and aji_client::p.
Referenced by aji_create_client().
00702 { 00703 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00704 iks *iq = NULL, *presence = NULL, *x = NULL; 00705 00706 iq = iks_new("iq"); 00707 presence = iks_new("presence"); 00708 x = iks_new("x"); 00709 if (client && iq && presence && x) { 00710 if (!iks_find(pak->query, "remove")) { 00711 iks_insert_attrib(iq, "from", client->jid->full); 00712 iks_insert_attrib(iq, "to", pak->from->full); 00713 iks_insert_attrib(iq, "id", pak->id); 00714 iks_insert_attrib(iq, "type", "result"); 00715 iks_send(client->p, iq); 00716 00717 iks_insert_attrib(presence, "from", client->jid->full); 00718 iks_insert_attrib(presence, "to", pak->from->partial); 00719 iks_insert_attrib(presence, "id", client->mid); 00720 ast_aji_increment_mid(client->mid); 00721 iks_insert_attrib(presence, "type", "subscribe"); 00722 iks_insert_attrib(x, "xmlns", "vcard-temp:x:update"); 00723 iks_insert_node(presence, x); 00724 iks_send(client->p, presence); 00725 } 00726 } else { 00727 ast_log(LOG_ERROR, "Out of memory.\n"); 00728 } 00729 00730 if (iq) 00731 iks_delete(iq); 00732 if(presence) 00733 iks_delete(presence); 00734 if (x) 00735 iks_delete(x); 00736 ASTOBJ_UNREF(client, aji_client_destroy); 00737 return IKS_FILTER_EAT; 00738 }
static int aji_register_query_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 740 of file res_jabber.c.
References aji_client_destroy(), ast_log(), ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, LOG_ERROR, aji_client::p, and aji_client::user.
Referenced by aji_create_client().
00741 { 00742 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00743 struct aji_buddy *buddy = NULL; 00744 char *node = NULL; 00745 00746 client = (struct aji_client *) data; 00747 00748 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00749 if (!buddy) { 00750 iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL; 00751 ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial); 00752 iq = iks_new("iq"); 00753 query = iks_new("query"); 00754 error = iks_new("error"); 00755 notacceptable = iks_new("not-acceptable"); 00756 if(iq && query && error && notacceptable) { 00757 iks_insert_attrib(iq, "type", "error"); 00758 iks_insert_attrib(iq, "from", client->user); 00759 iks_insert_attrib(iq, "to", pak->from->full); 00760 iks_insert_attrib(iq, "id", pak->id); 00761 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00762 iks_insert_attrib(error, "code" , "406"); 00763 iks_insert_attrib(error, "type", "modify"); 00764 iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); 00765 iks_insert_node(iq, query); 00766 iks_insert_node(iq, error); 00767 iks_insert_node(error, notacceptable); 00768 iks_send(client->p, iq); 00769 } else { 00770 ast_log(LOG_ERROR, "Out of memory.\n"); 00771 } 00772 if (iq) 00773 iks_delete(iq); 00774 if (query) 00775 iks_delete(query); 00776 if (error) 00777 iks_delete(error); 00778 if (notacceptable) 00779 iks_delete(notacceptable); 00780 } else if (!(node = iks_find_attrib(pak->query, "node"))) { 00781 iks *iq = NULL, *query = NULL, *instructions = NULL; 00782 char *explain = "Welcome to Asterisk - the Open Source PBX.\n"; 00783 iq = iks_new("iq"); 00784 query = iks_new("query"); 00785 instructions = iks_new("instructions"); 00786 if (iq && query && instructions && client) { 00787 iks_insert_attrib(iq, "from", client->user); 00788 iks_insert_attrib(iq, "to", pak->from->full); 00789 iks_insert_attrib(iq, "id", pak->id); 00790 iks_insert_attrib(iq, "type", "result"); 00791 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00792 iks_insert_cdata(instructions, explain, 0); 00793 iks_insert_node(iq, query); 00794 iks_insert_node(query, instructions); 00795 iks_send(client->p, iq); 00796 } else { 00797 ast_log(LOG_ERROR, "Out of memory.\n"); 00798 } 00799 if (iq) 00800 iks_delete(iq); 00801 if (query) 00802 iks_delete(query); 00803 if (instructions) 00804 iks_delete(instructions); 00805 } 00806 ASTOBJ_UNREF(client, aji_client_destroy); 00807 return IKS_FILTER_EAT; 00808 }
static int aji_reload | ( | void | ) | [static] |
Definition at line 2443 of file res_jabber.c.
References aji_client_destroy(), AJI_CONNECTING, AJI_DISCONNECTED, aji_get_roster(), aji_load_config(), aji_recv_loop(), ast_log(), ast_pthread_create_background, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and LOG_ERROR.
Referenced by aji_do_reload(), load_module(), and reload().
02444 { 02445 ASTOBJ_CONTAINER_MARKALL(&clients); 02446 if (!aji_load_config()) { 02447 ast_log(LOG_ERROR, "JABBER: Failed to load config.\n"); 02448 return 0; 02449 } 02450 ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy); 02451 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02452 ASTOBJ_RDLOCK(iterator); 02453 if(iterator->state == AJI_DISCONNECTED) { 02454 if (!iterator->thread) 02455 ast_pthread_create_background(&iterator->thread, NULL, aji_recv_loop, iterator); 02456 } else if (iterator->state == AJI_CONNECTING) 02457 aji_get_roster(iterator); 02458 ASTOBJ_UNLOCK(iterator); 02459 }); 02460 02461 return 1; 02462 }
static int aji_send_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Dial plan function to send a message.
channel,and | data, data is sender, reciever, message. |
Definition at line 425 of file res_jabber.c.
References ast_aji_get_client(), ast_aji_send(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and s.
Referenced by load_module().
00426 { 00427 struct aji_client *client = NULL; 00428 00429 char *s = NULL, *sender = NULL, *recipient = NULL, *message = NULL; 00430 00431 if (!data) { 00432 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00433 return 0; 00434 } 00435 s = ast_strdupa(data); 00436 if (s) { 00437 sender = strsep(&s, "|"); 00438 if (sender && (sender[0] != '\0')) { 00439 recipient = strsep(&s, "|"); 00440 if (recipient && (recipient[0] != '\0')) { 00441 message = s; 00442 } else { 00443 ast_log(LOG_ERROR, "Bad arguments: %s\n", (char *) data); 00444 return -1; 00445 } 00446 } 00447 } 00448 if (!(client = ast_aji_get_client(sender))) { 00449 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00450 return -1; 00451 } 00452 if (strchr(recipient, '@') && message) 00453 ast_aji_send(client, recipient, message); 00454 return 0; 00455 }
static void aji_set_presence | ( | struct aji_client * | client, | |
char * | to, | |||
char * | from, | |||
int | level, | |||
char * | desc | |||
) | [static] |
set presence of client.
aji_client | struct, user to send it to, and from, level, description. |
Definition at line 1945 of file res_jabber.c.
References ast_log(), LOG_ERROR, and aji_client::p.
Referenced by aji_get_roster(), aji_handle_presence(), and aji_handle_subscribe().
01946 { 01947 int res = 0; 01948 iks *presence = iks_make_pres(level, desc); 01949 iks *cnode = iks_new("c"); 01950 iks *priority = iks_new("priority"); 01951 01952 iks_insert_cdata(priority, "0", 1); 01953 if (presence && cnode && client) { 01954 if(to) 01955 iks_insert_attrib(presence, "to", to); 01956 if(from) 01957 iks_insert_attrib(presence, "from", from); 01958 iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps"); 01959 iks_insert_attrib(cnode, "ver", "asterisk-xmpp"); 01960 iks_insert_attrib(cnode, "ext", "voice-v1"); 01961 iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps"); 01962 iks_insert_node(presence, cnode); 01963 res = iks_send(client->p, presence); 01964 } else 01965 ast_log(LOG_ERROR, "Out of memory.\n"); 01966 if (cnode) 01967 iks_delete(cnode); 01968 if (presence) 01969 iks_delete(presence); 01970 }
static int aji_show_clients | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
show client status.
fd,number | of args, args. |
Definition at line 2021 of file res_jabber.c.
References AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and clients.
02022 { 02023 char *status; 02024 int count = 0; 02025 ast_cli(fd, "Jabber Users and their status:\n"); 02026 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02027 ASTOBJ_RDLOCK(iterator); 02028 count++; 02029 switch (iterator->state) { 02030 case AJI_DISCONNECTED: 02031 status = "Disconnected"; 02032 break; 02033 case AJI_CONNECTING: 02034 status = "Connecting"; 02035 break; 02036 case AJI_CONNECTED: 02037 status = "Connected"; 02038 break; 02039 default: 02040 status = "Unknown"; 02041 } 02042 ast_cli(fd, " User: %s - %s\n", iterator->user, status); 02043 ASTOBJ_UNLOCK(iterator); 02044 }); 02045 ast_cli(fd, "----\n"); 02046 ast_cli(fd, " Number of users: %d\n", count); 02047 return RESULT_SUCCESS; 02048 }
static int aji_status_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Dial plan function status(). puts the status of watched user into a channel variable.
channel,and | username,watched user, status var |
Definition at line 361 of file res_jabber.c.
References aji_find_resource(), ast_aji_get_client(), ast_log(), ast_strdupa, ASTOBJ_CONTAINER_FIND, aji_client::buddies, LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), aji_resource::resource, aji_buddy::resources, s, and aji_resource::status.
Referenced by load_module().
00362 { 00363 struct aji_client *client = NULL; 00364 struct aji_buddy *buddy = NULL; 00365 struct aji_resource *r = NULL; 00366 char *s = NULL, *sender = NULL, *jid = NULL, *screenname = NULL, *resource = NULL, *variable = NULL; 00367 int stat = 7; 00368 char status[2]; 00369 00370 if (!data) { 00371 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00372 return 0; 00373 } 00374 s = ast_strdupa(data); 00375 if (s) { 00376 sender = strsep(&s, "|"); 00377 if (sender && (sender[0] != '\0')) { 00378 jid = strsep(&s, "|"); 00379 if (jid && (jid[0] != '\0')) { 00380 variable = s; 00381 } else { 00382 ast_log(LOG_ERROR, "Bad arguments\n"); 00383 return -1; 00384 } 00385 } 00386 } 00387 00388 if(!strchr(jid, '/')) { 00389 resource = NULL; 00390 } else { 00391 screenname = strsep(&jid, "/"); 00392 resource = jid; 00393 } 00394 client = ast_aji_get_client(sender); 00395 if (!client) { 00396 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00397 return -1; 00398 } 00399 if(!&client->buddies) { 00400 ast_log(LOG_WARNING, "No buddies for connection : %s\n", sender); 00401 return -1; 00402 } 00403 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, resource ? screenname: jid); 00404 if (!buddy) { 00405 ast_log(LOG_WARNING, "Could not find buddy in list : %s\n", resource ? screenname : jid); 00406 return -1; 00407 } 00408 r = aji_find_resource(buddy, resource); 00409 if(!r && buddy->resources) 00410 r = buddy->resources; 00411 if(!r) 00412 ast_log(LOG_NOTICE, "Resource %s of buddy %s not found \n", resource, screenname); 00413 else 00414 stat = r->status; 00415 sprintf(status, "%d", stat); 00416 pbx_builtin_setvar_helper(chan, variable, status); 00417 return 0; 00418 }
static int aji_test | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
send test message for debugging.
fd,number | of args, args. |
Definition at line 2055 of file res_jabber.c.
References ast_aji_send(), ast_cli(), ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, aji_client::buddies, aji_resource::cap, clients, aji_resource::description, aji_version::jingle, name, aji_resource::next, aji_capabilities::node, aji_version::parent, aji_resource::priority, aji_resource::resource, RESULT_FAILURE, RESULT_SHOWUSAGE, S_OR, aji_resource::status, and aji_version::version.
02056 { 02057 struct aji_client *client; 02058 struct aji_resource *resource; 02059 const char *name = "asterisk"; 02060 struct aji_message *tmp; 02061 02062 if (argc > 3) 02063 return RESULT_SHOWUSAGE; 02064 else if (argc == 3) 02065 name = argv[2]; 02066 02067 if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) { 02068 ast_cli(fd, "Unable to find client '%s'!\n", name); 02069 return RESULT_FAILURE; 02070 } 02071 02072 /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */ 02073 ast_aji_send(client, "mogorman@astjab.org", "blahblah"); 02074 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 02075 ASTOBJ_RDLOCK(iterator); 02076 ast_verbose("User: %s\n", iterator->name); 02077 for (resource = iterator->resources; resource; resource = resource->next) { 02078 ast_verbose("Resource: %s\n", resource->resource); 02079 if(resource->cap) { 02080 ast_verbose(" client: %s\n", resource->cap->parent->node); 02081 ast_verbose(" version: %s\n", resource->cap->version); 02082 ast_verbose(" Jingle Capable: %d\n", resource->cap->jingle); 02083 } 02084 ast_verbose(" Priority: %d\n", resource->priority); 02085 ast_verbose(" Status: %d\n", resource->status); 02086 ast_verbose(" Message: %s\n", S_OR(resource->description,"")); 02087 } 02088 ASTOBJ_UNLOCK(iterator); 02089 }); 02090 ast_verbose("\nOooh a working message stack!\n"); 02091 AST_LIST_LOCK(&client->messages); 02092 AST_LIST_TRAVERSE(&client->messages, tmp, list) { 02093 ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, "")); 02094 } 02095 AST_LIST_UNLOCK(&client->messages); 02096 ASTOBJ_UNREF(client, aji_client_destroy); 02097 02098 return RESULT_SUCCESS; 02099 }
int ast_aji_create_chat | ( | struct aji_client * | client, | |
char * | room, | |||
char * | server, | |||
char * | topic | |||
) |
create a chatroom.
aji_client | struct , room, server, topic for the room. |
Definition at line 1452 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01453 { 01454 int res = 0; 01455 iks *iq = NULL; 01456 iq = iks_new("iq"); 01457 01458 if (iq && client) { 01459 iks_insert_attrib(iq, "type", "get"); 01460 iks_insert_attrib(iq, "to", server); 01461 iks_insert_attrib(iq, "id", client->mid); 01462 ast_aji_increment_mid(client->mid); 01463 iks_send(client->p, iq); 01464 } else 01465 ast_log(LOG_ERROR, "Out of memory.\n"); 01466 01467 iks_delete(iq); 01468 01469 return res; 01470 }
int ast_aji_disconnect | ( | struct aji_client * | client | ) |
disconnect from jabber server.
aji_client | struct. |
Definition at line 1927 of file res_jabber.c.
References aji_client_destroy(), ast_verbose(), ASTOBJ_UNREF, option_verbose, aji_client::p, and VERBOSE_PREFIX_3.
Referenced by unload_module().
01928 { 01929 if (client) { 01930 if (option_verbose > 3) 01931 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Disconnecting\n"); 01932 iks_disconnect(client->p); 01933 iks_parser_delete(client->p); 01934 ASTOBJ_UNREF(client, aji_client_destroy); 01935 } 01936 01937 return 1; 01938 }
struct aji_client* ast_aji_get_client | ( | const char * | name | ) |
grab a aji_client structure by label name or JID (without the resource string)
name | label or JID |
Definition at line 2367 of file res_jabber.c.
References ast_strdupa, ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_TRAVERSE, and clients.
Referenced by aji_send_exec(), aji_status_exec(), gtalk_create_member(), gtalk_newcall(), gtalk_request(), and manager_jabber_send().
02368 { 02369 struct aji_client *client = NULL; 02370 char *aux = NULL; 02371 02372 client = ASTOBJ_CONTAINER_FIND(&clients, name); 02373 if (!client && strchr(name, '@')) { 02374 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02375 aux = ast_strdupa(iterator->user); 02376 if (strchr(aux, '/')) { 02377 /* strip resource for comparison */ 02378 aux = strsep(&aux, "/"); 02379 } 02380 if (!strncasecmp(aux, name, strlen(aux))) { 02381 client = iterator; 02382 } 02383 }); 02384 } 02385 02386 return client; 02387 }
struct aji_client_container* ast_aji_get_clients | ( | void | ) |
Definition at line 2389 of file res_jabber.c.
References clients.
02390 { 02391 return &clients; 02392 }
void ast_aji_increment_mid | ( | char * | mid | ) |
increments the mid field for messages and other events.
message | id. |
Definition at line 1584 of file res_jabber.c.
Referenced by aji_act_hook(), aji_handle_presence(), aji_register_approve_handler(), ast_aji_create_chat(), ast_aji_invite_chat(), gtalk_action(), gtalk_create_candidates(), gtalk_digit(), gtalk_invite(), and gtalk_invite_response().
01585 { 01586 int i = 0; 01587 01588 for (i = strlen(mid) - 1; i >= 0; i--) { 01589 if (mid[i] != 'z') { 01590 mid[i] = mid[i] + 1; 01591 i = 0; 01592 } else 01593 mid[i] = 'a'; 01594 } 01595 }
int ast_aji_invite_chat | ( | struct aji_client * | client, | |
char * | user, | |||
char * | room, | |||
char * | message | |||
) |
invite to a chatroom.
aji_client | struct ,user, room, message. |
Definition at line 1505 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01506 { 01507 int res = 0; 01508 iks *invite, *body, *namespace; 01509 01510 invite = iks_new("message"); 01511 body = iks_new("body"); 01512 namespace = iks_new("x"); 01513 if (client && invite && body && namespace) { 01514 iks_insert_attrib(invite, "to", user); 01515 iks_insert_attrib(invite, "id", client->mid); 01516 ast_aji_increment_mid(client->mid); 01517 iks_insert_cdata(body, message, 0); 01518 iks_insert_attrib(namespace, "xmlns", "jabber:x:conference"); 01519 iks_insert_attrib(namespace, "jid", room); 01520 iks_insert_node(invite, body); 01521 iks_insert_node(invite, namespace); 01522 res = iks_send(client->p, invite); 01523 } else 01524 ast_log(LOG_ERROR, "Out of memory.\n"); 01525 if (body) 01526 iks_delete(body); 01527 if (namespace) 01528 iks_delete(namespace); 01529 if (invite) 01530 iks_delete(invite); 01531 return res; 01532 }
int ast_aji_join_chat | ( | struct aji_client * | client, | |
char * | room | |||
) |
join a chatroom.
aji_client | struct , room. |
Definition at line 1477 of file res_jabber.c.
References ast_log(), LOG_ERROR, and aji_client::p.
01478 { 01479 int res = 0; 01480 iks *presence = NULL, *priority = NULL; 01481 presence = iks_new("presence"); 01482 priority = iks_new("priority"); 01483 if (presence && priority && client) { 01484 iks_insert_cdata(priority, "0", 1); 01485 iks_insert_attrib(presence, "to", room); 01486 iks_insert_node(presence, priority); 01487 res = iks_send(client->p, presence); 01488 iks_insert_cdata(priority, "5", 1); 01489 iks_insert_attrib(presence, "to", room); 01490 res = iks_send(client->p, presence); 01491 } else 01492 ast_log(LOG_ERROR, "Out of memory.\n"); 01493 if (presence) 01494 iks_delete(presence); 01495 if (priority) 01496 iks_delete(priority); 01497 return res; 01498 }
int ast_aji_send | ( | struct aji_client * | client, | |
const char * | address, | |||
const char * | message | |||
) |
sends messages.
aji_client | struct , reciever, message. |
Definition at line 1428 of file res_jabber.c.
References AJI_CONNECTED, ast_log(), aji_client::jid, LOG_ERROR, LOG_WARNING, aji_client::p, and aji_client::state.
Referenced by aji_send_exec(), aji_test(), and manager_jabber_send().
01429 { 01430 int res = 0; 01431 iks *message_packet = NULL; 01432 if (client->state == AJI_CONNECTED) { 01433 message_packet = iks_make_msg(IKS_TYPE_CHAT, address, message); 01434 if (message_packet) { 01435 iks_insert_attrib(message_packet, "from", client->jid->full); 01436 res = iks_send(client->p, message_packet); 01437 } else { 01438 ast_log(LOG_ERROR, "Out of memory.\n"); 01439 } 01440 if (message_packet) 01441 iks_delete(message_packet); 01442 } else 01443 ast_log(LOG_WARNING, "JABBER: Not connected can't send\n"); 01444 return 1; 01445 }
static int gtalk_yuck | ( | iks * | node | ) | [static] |
Definition at line 310 of file res_jabber.c.
Referenced by aji_handle_presence().
00311 { 00312 if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps")) 00313 return 1; 00314 return 0; 00315 }
static iks * jabber_make_auth | ( | iksid * | id, | |
const char * | pass, | |||
const char * | sid | |||
) | [static] |
Definition at line 334 of file res_jabber.c.
References ast_sha1_hash().
Referenced by aji_act_hook().
00335 { 00336 iks *x, *y; 00337 x = iks_new("iq"); 00338 iks_insert_attrib(x, "type", "set"); 00339 y = iks_insert(x, "query"); 00340 iks_insert_attrib(y, "xmlns", IKS_NS_AUTH); 00341 iks_insert_cdata(iks_insert(y, "username"), id->user, 0); 00342 iks_insert_cdata(iks_insert(y, "resource"), id->resource, 0); 00343 if (sid) { 00344 char buf[41]; 00345 char sidpass[100]; 00346 snprintf(sidpass, sizeof(sidpass), "%s%s", sid, pass); 00347 ast_sha1_hash(buf, sidpass); 00348 iks_insert_cdata(iks_insert(y, "digest"), buf, 0); 00349 } else { 00350 iks_insert_cdata(iks_insert(y, "password"), pass, 0); 00351 } 00352 return x; 00353 }
static int load_module | ( | void | ) | [static] |
Definition at line 2497 of file res_jabber.c.
References aji_cli, aji_reload(), aji_send_exec(), aji_status_exec(), ast_cli_register_multiple(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, ast_register_application(), ASTOBJ_CONTAINER_INIT, clients, EVENT_FLAG_SYSTEM, manager_jabber_send(), and mandescr_jabber_send.
02498 { 02499 ASTOBJ_CONTAINER_INIT(&clients); 02500 if(!aji_reload()) 02501 return AST_MODULE_LOAD_DECLINE; 02502 ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send, 02503 "Sends a message to a Jabber Client", mandescr_jabber_send); 02504 ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip); 02505 ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip); 02506 ast_cli_register_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02507 02508 return 0; 02509 }
static int manager_jabber_send | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a Jabber Message via call from the Manager.
Definition at line 2402 of file res_jabber.c.
References ast_aji_get_client(), ast_aji_send(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), and s.
Referenced by load_module().
02403 { 02404 struct aji_client *client = NULL; 02405 const char *id = astman_get_header(m,"ActionID"); 02406 const char *jabber = astman_get_header(m,"Jabber"); 02407 const char *screenname = astman_get_header(m,"ScreenName"); 02408 const char *message = astman_get_header(m,"Message"); 02409 02410 if (ast_strlen_zero(jabber)) { 02411 astman_send_error(s, m, "No transport specified"); 02412 return 0; 02413 } 02414 if (ast_strlen_zero(screenname)) { 02415 astman_send_error(s, m, "No ScreenName specified"); 02416 return 0; 02417 } 02418 if (ast_strlen_zero(message)) { 02419 astman_send_error(s, m, "No Message specified"); 02420 return 0; 02421 } 02422 02423 astman_send_ack(s, m, "Attempting to send Jabber Message"); 02424 client = ast_aji_get_client(jabber); 02425 if (!client) { 02426 astman_send_error(s, m, "Could not find Sender"); 02427 return 0; 02428 } 02429 if (strchr(screenname, '@') && message) { 02430 ast_aji_send(client, screenname, message); 02431 astman_append(s, "Response: Success\r\n"); 02432 } else { 02433 astman_append(s, "Response: Failure\r\n"); 02434 } 02435 if (!ast_strlen_zero(id)) { 02436 astman_append(s, "ActionID: %s\r\n", id); 02437 } 02438 astman_append(s, "\r\n"); 02439 return 0; 02440 }
static int reload | ( | void | ) | [static] |
Definition at line 2511 of file res_jabber.c.
References aji_reload().
02512 { 02513 aji_reload(); 02514 return 0; 02515 }
static int unload_module | ( | void | ) | [static] |
Definition at line 2464 of file res_jabber.c.
References aji_cli, aji_client_destroy(), AJI_DISCONNECTING, ast_aji_disconnect(), ast_cli_unregister_multiple(), ast_log(), ast_manager_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, LOG_DEBUG, LOG_ERROR, and option_debug.
02465 { 02466 02467 /* Check if TLS is initialized. If that's the case, we can't unload this 02468 module due to a bug in the iksemel library that will cause a crash or 02469 a deadlock. We're trying to find a way to handle this, but in the meantime 02470 we will simply refuse to die... 02471 */ 02472 if (tls_initialized) { 02473 ast_log(LOG_ERROR, "Module can't be unloaded due to a bug in the Iksemel library when using TLS.\n"); 02474 return 1; /* You need a forced unload to get rid of this module */ 02475 } 02476 02477 ast_cli_unregister_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02478 ast_unregister_application(app_ajisend); 02479 ast_unregister_application(app_ajistatus); 02480 ast_manager_unregister("JabberSend"); 02481 02482 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02483 ASTOBJ_RDLOCK(iterator); 02484 if (option_debug > 2) 02485 ast_log(LOG_DEBUG, "JABBER: Releasing and disconneing client: %s\n", iterator->name); 02486 iterator->state = AJI_DISCONNECTING; 02487 ast_aji_disconnect(iterator); 02488 pthread_join(iterator->thread, NULL); 02489 ASTOBJ_UNLOCK(iterator); 02490 }); 02491 02492 ASTOBJ_CONTAINER_DESTROYALL(&clients, aji_client_destroy); 02493 ASTOBJ_CONTAINER_DESTROY(&clients); 02494 return 0; 02495 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "AJI - Asterisk Jabber Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 2521 of file res_jabber.c.
struct ast_cli_entry aji_cli[] [static] |
char* ajisend_descrip [static] |
Initial value:
"JabberSend(Jabber,ScreenName,Message)\n" " Jabber - Client or transport Asterisk uses to connect to Jabber\n" " ScreenName - User Name to message.\n" " Message - Message to be sent to the buddy\n"
Definition at line 157 of file res_jabber.c.
char* ajisend_synopsis = "JabberSend(jabber,screenname,message)" [static] |
Definition at line 155 of file res_jabber.c.
char* ajistatus_descrip [static] |
Definition at line 167 of file res_jabber.c.
char* ajistatus_synopsis = "JabberStatus(Jabber,ScreenName,Variable)" [static] |
Definition at line 165 of file res_jabber.c.
char* app_ajisend = "JabberSend" [static] |
Definition at line 153 of file res_jabber.c.
char* app_ajistatus = "JabberStatus" [static] |
Definition at line 163 of file res_jabber.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 2521 of file res_jabber.c.
struct aji_capabilities* capabilities = NULL |
struct aji_client_container clients |
Definition at line 175 of file res_jabber.c.
Referenced by aji_create_client(), aji_do_debug(), aji_no_debug(), aji_reload(), aji_show_clients(), aji_test(), ast_aji_get_client(), ast_aji_get_clients(), gtalk_load_config(), load_module(), and unload_module().
char debug_usage[] [static] |
Initial value:
"Usage: jabber debug\n" " Enables dumping of Jabber packets for debugging purposes.\n"
Definition at line 114 of file res_jabber.c.
struct ast_flags globalflags = { AJI_AUTOPRUNE | AJI_AUTOREGISTER } [static] |
char mandescr_jabber_send[] [static] |
char no_debug_usage[] [static] |
Initial value:
"Usage: jabber debug off\n" " Disables dumping of Jabber packets for debugging purposes.\n"
Definition at line 118 of file res_jabber.c.
char reload_usage[] [static] |
Initial value:
"Usage: jabber reload\n" " Enables reloading of Jabber module.\n"
Definition at line 122 of file res_jabber.c.
char test_usage[] [static] |
Initial value:
"Usage: jabber test [client]\n" " Sends test message for debugging purposes. A specific client\n" " as configured in jabber.conf can be optionally specified.\n"
Definition at line 126 of file res_jabber.c.
int tls_initialized = FALSE [static] |
Definition at line 180 of file res_jabber.c.