#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 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. | |
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. | |
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. | |
struct aji_client * | ast_aji_get_client (const char *name) |
grab a aji_client structure by label name or JID (without the resource string) | |
struct 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. | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"AJI - Asterisk Jabber Interface",.load=load_module,.unload=unload_module,.reload=reload,) | |
static int | gtalk_yuck (iks *node) |
static iks * | jabber_make_auth (iksid *id, const char *pass, const char *sid) |
static int | load_module (void) |
static int | manager_jabber_send (struct mansession *s, const struct message *m) |
Send a Jabber Message via call from the Manager. | |
static int | reload (void) |
static int | unload_module (void) |
Variables | |
static struct ast_cli_entry | aji_cli [] |
static char * | ajisend_descrip |
static char * | ajisend_synopsis = "JabberSend(jabber,screenname,message)" |
static char * | ajistatus_descrip |
static char * | ajistatus_synopsis = "JabberStatus(Jabber,ScreenName,Variable)" |
static char * | app_ajisend = "JabberSend" |
static char * | app_ajistatus = "JabberStatus" |
struct aji_capabilities * | capabilities = NULL |
struct 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 |
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 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 asprintf(&handshake, "<handshake>%s</handshake>", shasum); 00633 if (handshake) { 00634 iks_send_raw(client->p, handshake); 00635 free(handshake); 00636 handshake = NULL; 00637 } 00638 client->state = AJI_CONNECTING; 00639 if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/ 00640 client->state = AJI_CONNECTED; 00641 else 00642 ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n"); 00643 break; 00644 } 00645 break; 00646 00647 case IKS_NODE_NORMAL: 00648 break; 00649 00650 case IKS_NODE_ERROR: 00651 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00652 ASTOBJ_UNREF(client, aji_client_destroy); 00653 return IKS_HOOK; 00654 00655 case IKS_NODE_STOP: 00656 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00657 ASTOBJ_UNREF(client, aji_client_destroy); 00658 return IKS_HOOK; 00659 } 00660 } 00661 00662 switch (pak->type) { 00663 case IKS_PAK_NONE: 00664 if (option_debug) 00665 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n"); 00666 break; 00667 case IKS_PAK_MESSAGE: 00668 aji_handle_message(client, pak); 00669 if (option_debug) 00670 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n"); 00671 break; 00672 case IKS_PAK_PRESENCE: 00673 aji_handle_presence(client, pak); 00674 if (option_debug) 00675 ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n"); 00676 break; 00677 case IKS_PAK_S10N: 00678 aji_handle_subscribe(client, pak); 00679 if (option_debug) 00680 ast_log(LOG_DEBUG, "JABBER: I Dont know S10N subscribe!!\n"); 00681 break; 00682 case IKS_PAK_IQ: 00683 if (option_debug) 00684 ast_log(LOG_DEBUG, "JABBER: I Dont have an IQ!!!\n"); 00685 aji_handle_iq(client, node); 00686 break; 00687 default: 00688 if (option_debug) 00689 ast_log(LOG_DEBUG, "JABBER: I Dont know %i\n", pak->type); 00690 break; 00691 } 00692 00693 iks_filter_packet(client->f, pak); 00694 00695 if (node) 00696 iks_delete(node); 00697 00698 ASTOBJ_UNREF(client, aji_client_destroy); 00699 return IKS_OK; 00700 }
static void aji_buddy_destroy | ( | struct aji_buddy * | obj | ) | [static] |
Deletes the aji_buddy data structure.
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 1856 of file res_jabber.c.
References aji_client_destroy(), AJI_CONNECTING, AJI_DISCONNECTED, aji_filter_roster(), aji_get_roster(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::component, aji_client::f, aji_client::jid, LOG_ERROR, aji_client::stack, and aji_client::state.
Referenced by aji_act_hook().
01857 { 01858 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01859 int res = 0; 01860 01861 if (client) { 01862 if (client->state == AJI_DISCONNECTED) { 01863 iks_filter_add_rule(client->f, aji_filter_roster, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "roster", IKS_RULE_DONE); 01864 client->state = AJI_CONNECTING; 01865 client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid; 01866 iks_filter_remove_hook(client->f, aji_client_connect); 01867 if(!client->component) /*client*/ 01868 aji_get_roster(client); 01869 } 01870 } else 01871 ast_log(LOG_ERROR, "Out of memory.\n"); 01872 01873 ASTOBJ_UNREF(client, aji_client_destroy); 01874 return res; 01875 }
static void aji_client_destroy | ( | struct aji_client * | obj | ) | [static] |
Deletes the aji_client data structure.
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::message, aji_client::p, and aji_client::stack.
Referenced by aji_act_hook(), aji_client_connect(), aji_client_info_handler(), aji_create_client(), aji_dinfo_handler(), aji_ditems_handler(), aji_log_hook(), aji_recv_loop(), aji_register_approve_handler(), aji_register_query_handler(), aji_reload(), ast_aji_disconnect(), and unload_module().
00188 { 00189 struct aji_message *tmp; 00190 ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy); 00191 ASTOBJ_CONTAINER_DESTROY(&obj->buddies); 00192 iks_filter_delete(obj->f); 00193 iks_parser_delete(obj->p); 00194 iks_stack_delete(obj->stack); 00195 AST_LIST_LOCK(&obj->messages); 00196 while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) { 00197 if (tmp->from) 00198 free(tmp->from); 00199 if (tmp->message) 00200 free(tmp->message); 00201 } 00202 AST_LIST_HEAD_DESTROY(&obj->messages); 00203 free(obj); 00204 }
static int aji_client_info_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 907 of file res_jabber.c.
References aji_client_destroy(), aji_find_resource(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, aji_resource::cap, aji_client::jid, aji_version::jingle, LOG_ERROR, LOG_NOTICE, aji_client::p, and aji_resource::resource.
Referenced by aji_create_client().
00908 { 00909 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00910 struct aji_resource *resource = NULL; 00911 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00912 00913 resource = aji_find_resource(buddy, pak->from->resource); 00914 if (pak->subtype == IKS_TYPE_RESULT) { 00915 if (!resource) { 00916 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00917 ASTOBJ_UNREF(client, aji_client_destroy); 00918 return IKS_FILTER_EAT; 00919 } 00920 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00921 resource->cap->jingle = 1; 00922 } else 00923 resource->cap->jingle = 0; 00924 } else if (pak->subtype == IKS_TYPE_GET) { 00925 iks *iq, *disco, *ident, *google, *query; 00926 iq = iks_new("iq"); 00927 query = iks_new("query"); 00928 ident = iks_new("identity"); 00929 disco = iks_new("feature"); 00930 google = iks_new("feature"); 00931 if (iq && ident && disco && google) { 00932 iks_insert_attrib(iq, "from", client->jid->full); 00933 iks_insert_attrib(iq, "to", pak->from->full); 00934 iks_insert_attrib(iq, "type", "result"); 00935 iks_insert_attrib(iq, "id", pak->id); 00936 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00937 iks_insert_attrib(ident, "category", "client"); 00938 iks_insert_attrib(ident, "type", "pc"); 00939 iks_insert_attrib(ident, "name", "asterisk"); 00940 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info"); 00941 iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1"); 00942 iks_insert_node(iq, query); 00943 iks_insert_node(query, ident); 00944 iks_insert_node(query, google); 00945 iks_insert_node(query, disco); 00946 iks_send(client->p, iq); 00947 } else 00948 ast_log(LOG_ERROR, "Out of Memory.\n"); 00949 if (iq) 00950 iks_delete(iq); 00951 if (query) 00952 iks_delete(query); 00953 if (ident) 00954 iks_delete(ident); 00955 if (google) 00956 iks_delete(google); 00957 if (disco) 00958 iks_delete(disco); 00959 } else if (pak->subtype == IKS_TYPE_ERROR) { 00960 ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full); 00961 } 00962 ASTOBJ_UNREF(client, aji_client_destroy); 00963 return IKS_FILTER_EAT; 00964 }
static int aji_client_initialize | ( | struct aji_client * | client | ) | [static] |
prepares client for connect.
aji_client | struct. |
Definition at line 1882 of file res_jabber.c.
References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::p, aji_client::port, S_OR, and aji_client::serverhost.
Referenced by aji_reconnect().
01883 { 01884 int connected = 0; 01885 01886 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server); 01887 01888 if (connected == IKS_NET_NOCONN) { 01889 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01890 return IKS_HOOK; 01891 } else if (connected == IKS_NET_NODNS) { 01892 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01893 return IKS_HOOK; 01894 } else 01895 iks_recv(client->p, 30); 01896 return IKS_OK; 01897 }
static int aji_component_initialize | ( | struct aji_client * | client | ) | [static] |
prepares component for connect.
aji_client | struct. |
Definition at line 1904 of file res_jabber.c.
References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::p, aji_client::port, S_OR, aji_client::serverhost, and aji_client::user.
Referenced by aji_reconnect().
01905 { 01906 int connected = 1; 01907 01908 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->user); 01909 if (connected == IKS_NET_NOCONN) { 01910 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01911 return IKS_HOOK; 01912 } else if (connected == IKS_NET_NODNS) { 01913 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01914 return IKS_HOOK; 01915 } else if (!connected) 01916 iks_recv(client->p, 30); 01917 return IKS_OK; 01918 }
static int aji_create_buddy | ( | char * | label, | |
struct aji_client * | client | |||
) | [static] |
creates transport.
label,buddy | to dump it into. |
label,buddy | to dump it into. |
Definition at line 2295 of file res_jabber.c.
References aji_buddy_destroy(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::buddies, LOG_WARNING, and malloc.
Referenced by aji_create_client(), aji_handle_presence(), and aji_handle_subscribe().
02296 { 02297 struct aji_buddy *buddy = NULL; 02298 int flag = 0; 02299 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label); 02300 if (!buddy) { 02301 flag = 1; 02302 buddy = malloc(sizeof(struct aji_buddy)); 02303 if(!buddy) { 02304 ast_log(LOG_WARNING, "Out of memory\n"); 02305 return 0; 02306 } 02307 memset(buddy, 0, sizeof(struct aji_buddy)); 02308 ASTOBJ_INIT(buddy); 02309 } 02310 ASTOBJ_WRLOCK(buddy); 02311 ast_copy_string(buddy->name, label, sizeof(buddy->name)); 02312 ASTOBJ_UNLOCK(buddy); 02313 if(flag) 02314 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 02315 else { 02316 ASTOBJ_UNMARK(buddy); 02317 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 02318 } 02319 return 1; 02320 }
static int aji_create_client | ( | char * | label, | |
struct ast_variable * | var, | |||
int | debug | |||
) | [static] |
creates aji_client structure.
label,ast_variable,debug,pruneregister,component/client,aji_client | to dump into. |
Definition at line 2104 of file res_jabber.c.
References aji_act_hook(), AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_client_destroy(), aji_client_info_handler(), aji_create_buddy(), aji_dinfo_handler(), AJI_DISCONNECTED, aji_ditems_handler(), aji_log_hook(), aji_register_approve_handler(), aji_register_query_handler(), asprintf, ast_copy_flags, ast_false(), AST_FLAGS_ALL, AST_LIST_HEAD_INIT, ast_log(), ast_set2_flag, ast_true(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_INIT, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::authorized, aji_client::buddies, clients, aji_client::component, aji_client::debug, aji_client::f, aji_client::forcessl, free, aji_client::jid, aji_client::keepalive, LOG_ERROR, malloc, aji_client::message_timeout, aji_client::mid, ast_variable::name, ast_variable::next, 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 ast_variable::value.
Referenced by aji_load_config().
02105 { 02106 char *resource; 02107 struct aji_client *client = NULL; 02108 int flag = 0; 02109 02110 client = ASTOBJ_CONTAINER_FIND(&clients,label); 02111 if (!client) { 02112 flag = 1; 02113 client = (struct aji_client *) malloc(sizeof(struct aji_client)); 02114 if (!client) { 02115 ast_log(LOG_ERROR, "Out of memory!\n"); 02116 return 0; 02117 } 02118 memset(client, 0, sizeof(struct aji_client)); 02119 ASTOBJ_INIT(client); 02120 ASTOBJ_WRLOCK(client); 02121 ASTOBJ_CONTAINER_INIT(&client->buddies); 02122 } else { 02123 ASTOBJ_WRLOCK(client); 02124 ASTOBJ_UNMARK(client); 02125 } 02126 ASTOBJ_CONTAINER_MARKALL(&client->buddies); 02127 ast_copy_string(client->name, label, sizeof(client->name)); 02128 ast_copy_string(client->mid, "aaaaa", sizeof(client->mid)); 02129 02130 /* Set default values for the client object */ 02131 client->debug = debug; 02132 ast_copy_flags(client, &globalflags, AST_FLAGS_ALL); 02133 client->port = 5222; 02134 client->usetls = 1; 02135 client->usesasl = 1; 02136 client->forcessl = 0; 02137 client->keepalive = 1; 02138 client->timeout = 50; 02139 client->message_timeout = 100; 02140 AST_LIST_HEAD_INIT(&client->messages); 02141 client->component = 0; 02142 ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage)); 02143 02144 if (flag) { 02145 client->authorized = 0; 02146 client->state = AJI_DISCONNECTED; 02147 } 02148 while (var) { 02149 if (!strcasecmp(var->name, "username")) 02150 ast_copy_string(client->user, var->value, sizeof(client->user)); 02151 else if (!strcasecmp(var->name, "serverhost")) 02152 ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost)); 02153 else if (!strcasecmp(var->name, "secret")) 02154 ast_copy_string(client->password, var->value, sizeof(client->password)); 02155 else if (!strcasecmp(var->name, "statusmessage")) 02156 ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage)); 02157 else if (!strcasecmp(var->name, "port")) 02158 client->port = atoi(var->value); 02159 else if (!strcasecmp(var->name, "timeout")) 02160 client->message_timeout = atoi(var->value); 02161 else if (!strcasecmp(var->name, "debug")) 02162 client->debug = (ast_false(var->value)) ? 0 : 1; 02163 else if (!strcasecmp(var->name, "type")) { 02164 if (!strcasecmp(var->value, "component")) 02165 client->component = 1; 02166 } else if (!strcasecmp(var->name, "usetls")) { 02167 client->usetls = (ast_false(var->value)) ? 0 : 1; 02168 } else if (!strcasecmp(var->name, "usesasl")) { 02169 client->usesasl = (ast_false(var->value)) ? 0 : 1; 02170 } else if (!strcasecmp(var->name, "forceoldssl")) 02171 client->forcessl = (ast_false(var->value)) ? 0 : 1; 02172 else if (!strcasecmp(var->name, "keepalive")) 02173 client->keepalive = (ast_false(var->value)) ? 0 : 1; 02174 else if (!strcasecmp(var->name, "autoprune")) 02175 ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE); 02176 else if (!strcasecmp(var->name, "autoregister")) 02177 ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER); 02178 else if (!strcasecmp(var->name, "buddy")) 02179 aji_create_buddy(var->value, client); 02180 /* no transport support in this version */ 02181 /* else if (!strcasecmp(var->name, "transport")) 02182 aji_create_transport(var->value, client); 02183 */ 02184 var = var->next; 02185 } 02186 if (!flag) { 02187 ASTOBJ_UNLOCK(client); 02188 ASTOBJ_UNREF(client, aji_client_destroy); 02189 return 1; 02190 } 02191 client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook); 02192 if (!client->p) { 02193 ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name); 02194 return 0; 02195 } 02196 client->stack = iks_stack_new(8192, 8192); 02197 if (!client->stack) { 02198 ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name); 02199 return 0; 02200 } 02201 client->f = iks_filter_new(); 02202 if (!client->f) { 02203 ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name); 02204 return 0; 02205 } 02206 if (!strchr(client->user, '/') && !client->component) { /*client */ 02207 resource = NULL; 02208 asprintf(&resource, "%s/asterisk", client->user); 02209 if (resource) { 02210 client->jid = iks_id_new(client->stack, resource); 02211 free(resource); 02212 } 02213 } else 02214 client->jid = iks_id_new(client->stack, client->user); 02215 if (client->component) { 02216 iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02217 iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE); 02218 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); 02219 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); 02220 } else { 02221 iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02222 } 02223 if (!strchr(client->user, '/') && !client->component) { /*client */ 02224 resource = NULL; 02225 asprintf(&resource, "%s/asterisk", client->user); 02226 if (resource) { 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 966 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().
00967 { 00968 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00969 char *node = NULL; 00970 struct aji_resource *resource = NULL; 00971 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00972 00973 resource = aji_find_resource(buddy, pak->from->resource); 00974 if (pak->subtype == IKS_TYPE_ERROR) { 00975 ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n"); 00976 return IKS_FILTER_EAT; 00977 } 00978 if (pak->subtype == IKS_TYPE_RESULT) { 00979 if (!resource) { 00980 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00981 ASTOBJ_UNREF(client, aji_client_destroy); 00982 return IKS_FILTER_EAT; 00983 } 00984 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00985 resource->cap->jingle = 1; 00986 } else 00987 resource->cap->jingle = 0; 00988 } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) { 00989 iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search; 00990 00991 iq = iks_new("iq"); 00992 query = iks_new("query"); 00993 identity = iks_new("identity"); 00994 disco = iks_new("feature"); 00995 reg = iks_new("feature"); 00996 commands = iks_new("feature"); 00997 gateway = iks_new("feature"); 00998 version = iks_new("feature"); 00999 vcard = iks_new("feature"); 01000 search = iks_new("feature"); 01001 01002 if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) { 01003 iks_insert_attrib(iq, "from", client->user); 01004 iks_insert_attrib(iq, "to", pak->from->full); 01005 iks_insert_attrib(iq, "id", pak->id); 01006 iks_insert_attrib(iq, "type", "result"); 01007 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01008 iks_insert_attrib(identity, "category", "gateway"); 01009 iks_insert_attrib(identity, "type", "pstn"); 01010 iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX"); 01011 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco"); 01012 iks_insert_attrib(reg, "var", "jabber:iq:register"); 01013 iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands"); 01014 iks_insert_attrib(gateway, "var", "jabber:iq:gateway"); 01015 iks_insert_attrib(version, "var", "jabber:iq:version"); 01016 iks_insert_attrib(vcard, "var", "vcard-temp"); 01017 iks_insert_attrib(search, "var", "jabber:iq:search"); 01018 01019 iks_insert_node(iq, query); 01020 iks_insert_node(query, identity); 01021 iks_insert_node(query, disco); 01022 iks_insert_node(query, reg); 01023 iks_insert_node(query, commands); 01024 iks_insert_node(query, gateway); 01025 iks_insert_node(query, version); 01026 iks_insert_node(query, vcard); 01027 iks_insert_node(query, search); 01028 iks_send(client->p, iq); 01029 } else { 01030 ast_log(LOG_ERROR, "Out of memory.\n"); 01031 } 01032 01033 if (iq) 01034 iks_delete(iq); 01035 if (query) 01036 iks_delete(query); 01037 if (identity) 01038 iks_delete(identity); 01039 if (disco) 01040 iks_delete(disco); 01041 if (reg) 01042 iks_delete(reg); 01043 if (commands) 01044 iks_delete(commands); 01045 if (gateway) 01046 iks_delete(gateway); 01047 if (version) 01048 iks_delete(version); 01049 if (vcard) 01050 iks_delete(vcard); 01051 if (search) 01052 iks_delete(search); 01053 01054 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) { 01055 iks *iq, *query, *confirm; 01056 iq = iks_new("iq"); 01057 query = iks_new("query"); 01058 confirm = iks_new("item"); 01059 01060 if (iq && query && confirm && client) { 01061 iks_insert_attrib(iq, "from", client->user); 01062 iks_insert_attrib(iq, "to", pak->from->full); 01063 iks_insert_attrib(iq, "id", pak->id); 01064 iks_insert_attrib(iq, "type", "result"); 01065 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 01066 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 01067 iks_insert_attrib(confirm, "node", "confirmaccount"); 01068 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 01069 iks_insert_attrib(confirm, "jid", client->user); 01070 iks_insert_node(iq, query); 01071 iks_insert_node(query, confirm); 01072 iks_send(client->p, iq); 01073 } else { 01074 ast_log(LOG_ERROR, "Out of memory.\n"); 01075 } 01076 if (iq) 01077 iks_delete(iq); 01078 if (query) 01079 iks_delete(query); 01080 if (confirm) 01081 iks_delete(confirm); 01082 01083 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) { 01084 iks *iq, *query, *feature; 01085 01086 iq = iks_new("iq"); 01087 query = iks_new("query"); 01088 feature = iks_new("feature"); 01089 01090 if (iq && query && feature && client) { 01091 iks_insert_attrib(iq, "from", client->user); 01092 iks_insert_attrib(iq, "to", pak->from->full); 01093 iks_insert_attrib(iq, "id", pak->id); 01094 iks_insert_attrib(iq, "type", "result"); 01095 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01096 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 01097 iks_insert_node(iq, query); 01098 iks_insert_node(query, feature); 01099 iks_send(client->p, iq); 01100 } else { 01101 ast_log(LOG_ERROR, "Out of memory.\n"); 01102 } 01103 if (iq) 01104 iks_delete(iq); 01105 if (query) 01106 iks_delete(query); 01107 if (feature) 01108 iks_delete(feature); 01109 } 01110 01111 ASTOBJ_UNREF(client, aji_client_destroy); 01112 return IKS_FILTER_EAT; 01113 }
static int aji_ditems_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 811 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().
00812 { 00813 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00814 char *node = NULL; 00815 00816 if (!(node = iks_find_attrib(pak->query, "node"))) { 00817 iks *iq = NULL, *query = NULL, *item = NULL; 00818 iq = iks_new("iq"); 00819 query = iks_new("query"); 00820 item = iks_new("item"); 00821 00822 if (iq && query && item) { 00823 iks_insert_attrib(iq, "from", client->user); 00824 iks_insert_attrib(iq, "to", pak->from->full); 00825 iks_insert_attrib(iq, "id", pak->id); 00826 iks_insert_attrib(iq, "type", "result"); 00827 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00828 iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands"); 00829 iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands"); 00830 iks_insert_attrib(item, "jid", client->user); 00831 00832 iks_insert_node(iq, query); 00833 iks_insert_node(query, item); 00834 iks_send(client->p, iq); 00835 } else { 00836 ast_log(LOG_ERROR, "Out of memory.\n"); 00837 } 00838 if (iq) 00839 iks_delete(iq); 00840 if (query) 00841 iks_delete(query); 00842 if (item) 00843 iks_delete(item); 00844 00845 } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) { 00846 iks *iq, *query, *confirm; 00847 iq = iks_new("iq"); 00848 query = iks_new("query"); 00849 confirm = iks_new("item"); 00850 if (iq && query && confirm && client) { 00851 iks_insert_attrib(iq, "from", client->user); 00852 iks_insert_attrib(iq, "to", pak->from->full); 00853 iks_insert_attrib(iq, "id", pak->id); 00854 iks_insert_attrib(iq, "type", "result"); 00855 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00856 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 00857 iks_insert_attrib(confirm, "node", "confirmaccount"); 00858 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 00859 iks_insert_attrib(confirm, "jid", "blog.astjab.org"); 00860 00861 iks_insert_node(iq, query); 00862 iks_insert_node(query, confirm); 00863 iks_send(client->p, iq); 00864 } else { 00865 ast_log(LOG_ERROR, "Out of memory.\n"); 00866 } 00867 if (iq) 00868 iks_delete(iq); 00869 if (query) 00870 iks_delete(query); 00871 if (confirm) 00872 iks_delete(confirm); 00873 00874 } else if (!strcasecmp(node, "confirmaccount")) { 00875 iks *iq = NULL, *query = NULL, *feature = NULL; 00876 00877 iq = iks_new("iq"); 00878 query = iks_new("query"); 00879 feature = iks_new("feature"); 00880 00881 if (iq && query && feature && client) { 00882 iks_insert_attrib(iq, "from", client->user); 00883 iks_insert_attrib(iq, "to", pak->from->full); 00884 iks_insert_attrib(iq, "id", pak->id); 00885 iks_insert_attrib(iq, "type", "result"); 00886 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00887 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 00888 iks_insert_node(iq, query); 00889 iks_insert_node(query, feature); 00890 iks_send(client->p, iq); 00891 } else { 00892 ast_log(LOG_ERROR, "Out of memory.\n"); 00893 } 00894 if (iq) 00895 iks_delete(iq); 00896 if (query) 00897 iks_delete(query); 00898 if (feature) 00899 iks_delete(feature); 00900 } 00901 00902 ASTOBJ_UNREF(client, aji_client_destroy); 00903 return IKS_FILTER_EAT; 00904 00905 }
static int aji_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
turnon console debugging.
fd,number | of args, args. |
Definition at line 1975 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01976 { 01977 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01978 ASTOBJ_RDLOCK(iterator); 01979 iterator->debug = 1; 01980 ASTOBJ_UNLOCK(iterator); 01981 }); 01982 ast_cli(fd, "Jabber Debugging Enabled.\n"); 01983 return RESULT_SUCCESS; 01984 }
static int aji_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
reload jabber module.
fd,number | of args, args. |
Definition at line 1991 of file res_jabber.c.
References aji_reload(), ast_cli(), and RESULT_SUCCESS.
01992 { 01993 aji_reload(); 01994 ast_cli(fd, "Jabber Reloaded.\n"); 01995 return RESULT_SUCCESS; 01996 }
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 1745 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().
01746 { 01747 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01748 int flag = 0; 01749 iks *x = NULL; 01750 struct aji_buddy *buddy; 01751 01752 client->state = AJI_CONNECTED; 01753 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01754 ASTOBJ_RDLOCK(iterator); 01755 x = iks_child(pak->query); 01756 flag = 0; 01757 while (x) { 01758 if (!iks_strcmp(iks_name(x), "item")) { 01759 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) { 01760 flag = 1; 01761 ast_clear_flag(iterator, AJI_AUTOPRUNE | AJI_AUTOREGISTER); 01762 } 01763 } 01764 x = iks_next(x); 01765 } 01766 if (!flag) 01767 ast_copy_flags(iterator, client, AJI_AUTOREGISTER); 01768 if (x) 01769 iks_delete(x); 01770 ASTOBJ_UNLOCK(iterator); 01771 }); 01772 01773 x = iks_child(pak->query); 01774 while (x) { 01775 flag = 0; 01776 if (iks_strcmp(iks_name(x), "item") == 0) { 01777 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01778 ASTOBJ_RDLOCK(iterator); 01779 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) 01780 flag = 1; 01781 ASTOBJ_UNLOCK(iterator); 01782 }); 01783 01784 if (!flag) { 01785 buddy = (struct aji_buddy *) malloc(sizeof(struct aji_buddy)); 01786 if (!buddy) { 01787 ast_log(LOG_WARNING, "Out of memory\n"); 01788 return 0; 01789 } 01790 memset(buddy, 0, sizeof(struct aji_buddy)); 01791 ASTOBJ_INIT(buddy); 01792 ASTOBJ_WRLOCK(buddy); 01793 ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name)); 01794 ast_clear_flag(buddy, AST_FLAGS_ALL); 01795 if(ast_test_flag(client, AJI_AUTOPRUNE)) { 01796 ast_set_flag(buddy, AJI_AUTOPRUNE); 01797 buddy->objflags |= ASTOBJ_FLAG_MARKED; 01798 } else 01799 ast_set_flag(buddy, AJI_AUTOREGISTER); 01800 ASTOBJ_UNLOCK(buddy); 01801 if (buddy) { 01802 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 01803 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01804 } 01805 } 01806 } 01807 x = iks_next(x); 01808 } 01809 if (x) 01810 iks_delete(x); 01811 aji_pruneregister(client); 01812 01813 ASTOBJ_UNREF(client, aji_client_destroy); 01814 return IKS_FILTER_EAT; 01815 }
static struct aji_resource* aji_find_resource | ( | struct aji_buddy * | buddy, | |
char * | name | |||
) | [static, read] |
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, read] |
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_free, ast_log(), 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 1837 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().
01838 { 01839 iks *roster = NULL; 01840 roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER); 01841 if(roster) { 01842 iks_insert_attrib(roster, "id", "roster"); 01843 aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage); 01844 iks_send(client->p, roster); 01845 } 01846 if (roster) 01847 iks_delete(roster); 01848 return 1; 01849 }
static void aji_handle_iq | ( | struct aji_client * | client, | |
iks * | node | |||
) | [static] |
Handles <iq> tags.
client | structure and the iq node. |
Definition at line 1120 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 1130 of file res_jabber.c.
References aji_message::arrived, ast_calloc, 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::message, and aji_client::message_timeout.
Referenced by aji_act_hook().
01131 { 01132 struct aji_message *insert, *tmp; 01133 int flag = 0; 01134 01135 if (!(insert = ast_calloc(1, sizeof(struct aji_message)))) 01136 return; 01137 time(&insert->arrived); 01138 if (iks_find_cdata(pak->x, "body")) 01139 insert->message = ast_strdup(iks_find_cdata(pak->x, "body")); 01140 if(pak->id) 01141 ast_copy_string(insert->id, pak->id, sizeof(insert->message)); 01142 if (pak->from) 01143 insert->from = ast_strdup(pak->from->full); 01144 AST_LIST_LOCK(&client->messages); 01145 AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) { 01146 if (flag) { 01147 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01148 if (tmp->from) 01149 free(tmp->from); 01150 if (tmp->message) 01151 free(tmp->message); 01152 } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) { 01153 flag = 1; 01154 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01155 if (tmp->from) 01156 free(tmp->from); 01157 if (tmp->message) 01158 free(tmp->message); 01159 } 01160 } 01161 AST_LIST_TRAVERSE_SAFE_END; 01162 AST_LIST_INSERT_HEAD(&client->messages, insert, list); 01163 AST_LIST_UNLOCK(&client->messages); 01164 }
static void aji_handle_presence | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 1166 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_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().
01167 { 01168 int status, priority; 01169 struct aji_buddy *buddy; 01170 struct aji_resource *tmp = NULL, *last = NULL, *found = NULL; 01171 char *ver, *node, *descrip, *type; 01172 01173 if(client->state != AJI_CONNECTED) 01174 aji_create_buddy(pak->from->partial, client); 01175 01176 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01177 if (!buddy && pak->from->partial) { 01178 /* allow our jid to be used to log in with another resource */ 01179 if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial)) 01180 aji_create_buddy(pak->from->partial, client); 01181 else 01182 ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial); 01183 return; 01184 } 01185 type = iks_find_attrib(pak->x, "type"); 01186 if(client->component && type &&!strcasecmp("probe", type)) { 01187 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01188 ast_verbose("what i was looking for \n"); 01189 } 01190 ASTOBJ_WRLOCK(buddy); 01191 status = (pak->show) ? pak->show : 6; 01192 priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0"); 01193 tmp = buddy->resources; 01194 descrip = ast_strdup(iks_find_cdata(pak->x,"status")); 01195 01196 while (tmp && pak->from->resource) { 01197 if (!strcasecmp(tmp->resource, pak->from->resource)) { 01198 tmp->status = status; 01199 if (tmp->description) free(tmp->description); 01200 tmp->description = descrip; 01201 found = tmp; 01202 if (status == 6) { /* Sign off Destroy resource */ 01203 if (last && found->next) { 01204 last->next = found->next; 01205 } else if (!last) { 01206 if (found->next) 01207 buddy->resources = found->next; 01208 else 01209 buddy->resources = NULL; 01210 } else if (!found->next) { 01211 if (last) 01212 last->next = NULL; 01213 else 01214 buddy->resources = NULL; 01215 } 01216 free(found); 01217 found = NULL; 01218 break; 01219 } 01220 /* resource list is sorted by descending priority */ 01221 if (tmp->priority != priority) { 01222 found->priority = priority; 01223 if (!last && !found->next) 01224 /* resource was found to be unique, 01225 leave loop */ 01226 break; 01227 /* search for resource in our list 01228 and take it out for the moment */ 01229 if (last) 01230 last->next = found->next; 01231 else 01232 buddy->resources = found->next; 01233 01234 last = NULL; 01235 tmp = buddy->resources; 01236 if (!buddy->resources) 01237 buddy->resources = found; 01238 /* priority processing */ 01239 while (tmp) { 01240 /* insert resource back according to 01241 its priority value */ 01242 if (found->priority > tmp->priority) { 01243 if (last) 01244 /* insert within list */ 01245 last->next = found; 01246 found->next = tmp; 01247 if (!last) 01248 /* insert on top */ 01249 buddy->resources = found; 01250 break; 01251 } 01252 if (!tmp->next) { 01253 /* insert at the end of the list */ 01254 tmp->next = found; 01255 found->next = NULL; 01256 break; 01257 } 01258 last = tmp; 01259 tmp = tmp->next; 01260 } 01261 } 01262 break; 01263 } 01264 last = tmp; 01265 tmp = tmp->next; 01266 } 01267 01268 /* resource not found in our list, create it */ 01269 if (!found && status != 6 && pak->from->resource) { 01270 found = (struct aji_resource *) malloc(sizeof(struct aji_resource)); 01271 memset(found, 0, sizeof(struct aji_resource)); 01272 01273 if (!found) { 01274 ast_log(LOG_ERROR, "Out of memory!\n"); 01275 return; 01276 } 01277 ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource)); 01278 found->status = status; 01279 found->description = descrip; 01280 found->priority = priority; 01281 found->next = NULL; 01282 last = NULL; 01283 tmp = buddy->resources; 01284 while (tmp) { 01285 if (found->priority > tmp->priority) { 01286 if (last) 01287 last->next = found; 01288 found->next = tmp; 01289 if (!last) 01290 buddy->resources = found; 01291 break; 01292 } 01293 if (!tmp->next) { 01294 tmp->next = found; 01295 break; 01296 } 01297 last = tmp; 01298 tmp = tmp->next; 01299 } 01300 if (!tmp) 01301 buddy->resources = found; 01302 } 01303 01304 ASTOBJ_UNLOCK(buddy); 01305 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01306 01307 node = iks_find_attrib(iks_find(pak->x, "c"), "node"); 01308 ver = iks_find_attrib(iks_find(pak->x, "c"), "ver"); 01309 01310 /* handle gmail client's special caps:c tag */ 01311 if (!node && !ver) { 01312 node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node"); 01313 ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver"); 01314 } 01315 01316 /* retrieve capabilites of the new resource */ 01317 if(status !=6 && found && !found->cap) { 01318 found->cap = aji_find_version(node, ver, pak); 01319 if(gtalk_yuck(pak->x)) /* gtalk should do discover */ 01320 found->cap->jingle = 1; 01321 if(found->cap->jingle && option_debug > 4) 01322 ast_log(LOG_DEBUG,"Special case for google till they support discover.\n"); 01323 else { 01324 iks *iq, *query; 01325 iq = iks_new("iq"); 01326 query = iks_new("query"); 01327 if(query && iq) { 01328 iks_insert_attrib(iq, "type", "get"); 01329 iks_insert_attrib(iq, "to", pak->from->full); 01330 iks_insert_attrib(iq,"from", client->jid->full); 01331 iks_insert_attrib(iq, "id", client->mid); 01332 ast_aji_increment_mid(client->mid); 01333 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01334 iks_insert_node(iq, query); 01335 iks_send(client->p, iq); 01336 01337 } else 01338 ast_log(LOG_ERROR, "Out of memory.\n"); 01339 if(query) 01340 iks_delete(query); 01341 if(iq) 01342 iks_delete(iq); 01343 } 01344 } 01345 if (option_verbose > 4) { 01346 switch (pak->subtype) { 01347 case IKS_TYPE_AVAILABLE: 01348 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am available ^_* %i\n", pak->subtype); 01349 break; 01350 case IKS_TYPE_UNAVAILABLE: 01351 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am unavailable ^_* %i\n", pak->subtype); 01352 break; 01353 default: 01354 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype); 01355 } 01356 switch (pak->show) { 01357 case IKS_SHOW_UNAVAILABLE: 01358 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01359 break; 01360 case IKS_SHOW_AVAILABLE: 01361 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is available\n"); 01362 break; 01363 case IKS_SHOW_CHAT: 01364 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01365 break; 01366 case IKS_SHOW_AWAY: 01367 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is away\n"); 01368 break; 01369 case IKS_SHOW_XA: 01370 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01371 break; 01372 case IKS_SHOW_DND: 01373 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01374 break; 01375 default: 01376 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Kinky! how did that happen %i\n", pak->show); 01377 } 01378 } 01379 }
static void aji_handle_subscribe | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
handles subscription requests.
aji_client | struct and xml packet. |
Definition at line 1386 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().
01387 { 01388 iks *presence = NULL, *status = NULL; 01389 struct aji_buddy* buddy = NULL; 01390 01391 switch (pak->subtype) { 01392 case IKS_TYPE_SUBSCRIBE: 01393 presence = iks_new("presence"); 01394 status = iks_new("status"); 01395 if(presence && status) { 01396 iks_insert_attrib(presence, "type", "subscribed"); 01397 iks_insert_attrib(presence, "to", pak->from->full); 01398 iks_insert_attrib(presence, "from", client->jid->full); 01399 if(pak->id) 01400 iks_insert_attrib(presence, "id", pak->id); 01401 iks_insert_cdata(status, "Asterisk has approved subscription", 0); 01402 iks_insert_node(presence, status); 01403 iks_send(client->p, presence); 01404 } else 01405 ast_log(LOG_ERROR, "Unable to allocate nodes\n"); 01406 if(presence) 01407 iks_delete(presence); 01408 if(status) 01409 iks_delete(status); 01410 if(client->component) 01411 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01412 case IKS_TYPE_SUBSCRIBED: 01413 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01414 if (!buddy && pak->from->partial) { 01415 aji_create_buddy(pak->from->partial, client); 01416 } 01417 default: 01418 if (option_verbose > 4) { 01419 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01420 } 01421 } 01422 }
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, JABBER_CONFIG, LOG_WARNING, ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by aji_reload().
02328 { 02329 char *cat = NULL; 02330 int debug = 1; 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(), 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 2003 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
02004 { 02005 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02006 ASTOBJ_RDLOCK(iterator); 02007 iterator->debug = 0; 02008 ASTOBJ_UNLOCK(iterator); 02009 }); 02010 ast_cli(fd, "Jabber Debugging Disabled.\n"); 02011 return RESULT_SUCCESS; 02012 }
static void aji_pruneregister | ( | struct aji_client * | client | ) | [static] |
attempts to register to a transport.
aji_client | struct, and xml packet. |
aji_client | struct, and xml packet. |
aji_client | struct. |
Definition at line 1692 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.
01693 { 01694 int res = 0; 01695 iks *removeiq = iks_new("iq"); 01696 iks *removequery = iks_new("query"); 01697 iks *removeitem = iks_new("item"); 01698 iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items"); 01699 01700 if (client && removeiq && removequery && removeitem && send) { 01701 iks_insert_node(removeiq, removequery); 01702 iks_insert_node(removequery, removeitem); 01703 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01704 ASTOBJ_RDLOCK(iterator); 01705 /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never 01706 * be called at the same time */ 01707 if (ast_test_flag(iterator, AJI_AUTOPRUNE)) { 01708 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name, 01709 "GoodBye your status is no longer needed by Asterisk the Open Source PBX" 01710 " so I am no longer subscribing to your presence.\n")); 01711 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name, 01712 "GoodBye you are no longer in the asterisk config file so I am removing" 01713 " your access to my presence.\n")); 01714 iks_insert_attrib(removeiq, "from", client->jid->full); 01715 iks_insert_attrib(removeiq, "type", "set"); 01716 iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster"); 01717 iks_insert_attrib(removeitem, "jid", iterator->name); 01718 iks_insert_attrib(removeitem, "subscription", "remove"); 01719 res = iks_send(client->p, removeiq); 01720 } else if (ast_test_flag(iterator, AJI_AUTOREGISTER)) { 01721 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name, 01722 "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n")); 01723 ast_clear_flag(iterator, AJI_AUTOREGISTER); 01724 } 01725 ASTOBJ_UNLOCK(iterator); 01726 }); 01727 } else 01728 ast_log(LOG_ERROR, "Out of memory.\n"); 01729 if (removeiq) 01730 iks_delete(removeiq); 01731 if (removequery) 01732 iks_delete(removequery); 01733 if (removeitem) 01734 iks_delete(removeitem); 01735 if (send) 01736 iks_delete(send); 01737 ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy); 01738 }
static int aji_reconnect | ( | struct aji_client * | client | ) | [static] |
Definition at line 1817 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().
01818 { 01819 int res = 0; 01820 01821 if (client->state) 01822 client->state = AJI_DISCONNECTED; 01823 client->timeout=50; 01824 if (client->p) 01825 iks_parser_reset(client->p); 01826 if (client->authorized) 01827 client->authorized = 0; 01828 01829 if(client->component) 01830 res = aji_component_initialize(client); 01831 else 01832 res = aji_client_initialize(client); 01833 01834 return res; 01835 }
static void * aji_recv_loop | ( | void * | data | ) | [static] |
receive message loop.
aji_client | struct. |
Definition at line 1541 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().
01542 { 01543 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01544 int res = IKS_HOOK; 01545 do { 01546 if (res != IKS_OK) { 01547 while(res != IKS_OK) { 01548 if(option_verbose > 3) 01549 ast_verbose("JABBER: reconnecting.\n"); 01550 res = aji_reconnect(client); 01551 sleep(4); 01552 } 01553 } 01554 01555 res = iks_recv(client->p, 1); 01556 01557 if (client->state == AJI_DISCONNECTING) { 01558 if (option_debug > 1) 01559 ast_log(LOG_DEBUG, "Ending our Jabber client's thread due to a disconnect\n"); 01560 pthread_exit(NULL); 01561 } 01562 client->timeout--; 01563 if (res == IKS_HOOK) 01564 ast_log(LOG_WARNING, "JABBER: Got hook event.\n"); 01565 else if (res == IKS_NET_TLSFAIL) 01566 ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n"); 01567 else if (client->timeout == 0 && client->state == AJI_CONNECTED) { 01568 res = client->keepalive ? iks_send_raw(client->p, " ") : IKS_OK; 01569 if(res == IKS_OK) 01570 client->timeout = 50; 01571 else 01572 ast_log(LOG_WARNING, "JABBER: Network Timeout\n"); 01573 } else if (res == IKS_NET_RWERR) 01574 ast_log(LOG_WARNING, "JABBER: socket read error\n"); 01575 } while (client); 01576 ASTOBJ_UNREF(client, aji_client_destroy); 01577 return 0; 01578 }
static int aji_register_approve_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 702 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().
00703 { 00704 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00705 iks *iq = NULL, *presence = NULL, *x = NULL; 00706 00707 iq = iks_new("iq"); 00708 presence = iks_new("presence"); 00709 x = iks_new("x"); 00710 if (client && iq && presence && x) { 00711 if (!iks_find(pak->query, "remove")) { 00712 iks_insert_attrib(iq, "from", client->jid->full); 00713 iks_insert_attrib(iq, "to", pak->from->full); 00714 iks_insert_attrib(iq, "id", pak->id); 00715 iks_insert_attrib(iq, "type", "result"); 00716 iks_send(client->p, iq); 00717 00718 iks_insert_attrib(presence, "from", client->jid->full); 00719 iks_insert_attrib(presence, "to", pak->from->partial); 00720 iks_insert_attrib(presence, "id", client->mid); 00721 ast_aji_increment_mid(client->mid); 00722 iks_insert_attrib(presence, "type", "subscribe"); 00723 iks_insert_attrib(x, "xmlns", "vcard-temp:x:update"); 00724 iks_insert_node(presence, x); 00725 iks_send(client->p, presence); 00726 } 00727 } else { 00728 ast_log(LOG_ERROR, "Out of memory.\n"); 00729 } 00730 00731 if (iq) 00732 iks_delete(iq); 00733 if(presence) 00734 iks_delete(presence); 00735 if (x) 00736 iks_delete(x); 00737 ASTOBJ_UNREF(client, aji_client_destroy); 00738 return IKS_FILTER_EAT; 00739 }
static int aji_register_query_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 741 of file res_jabber.c.
References aji_client_destroy(), ast_log(), ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, error(), LOG_ERROR, aji_client::p, and aji_client::user.
Referenced by aji_create_client().
00742 { 00743 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00744 struct aji_buddy *buddy = NULL; 00745 char *node = NULL; 00746 00747 client = (struct aji_client *) data; 00748 00749 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00750 if (!buddy) { 00751 iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL; 00752 ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial); 00753 iq = iks_new("iq"); 00754 query = iks_new("query"); 00755 error = iks_new("error"); 00756 notacceptable = iks_new("not-acceptable"); 00757 if(iq && query && error && notacceptable) { 00758 iks_insert_attrib(iq, "type", "error"); 00759 iks_insert_attrib(iq, "from", client->user); 00760 iks_insert_attrib(iq, "to", pak->from->full); 00761 iks_insert_attrib(iq, "id", pak->id); 00762 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00763 iks_insert_attrib(error, "code" , "406"); 00764 iks_insert_attrib(error, "type", "modify"); 00765 iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); 00766 iks_insert_node(iq, query); 00767 iks_insert_node(iq, error); 00768 iks_insert_node(error, notacceptable); 00769 iks_send(client->p, iq); 00770 } else { 00771 ast_log(LOG_ERROR, "Out of memory.\n"); 00772 } 00773 if (iq) 00774 iks_delete(iq); 00775 if (query) 00776 iks_delete(query); 00777 if (error) 00778 iks_delete(error); 00779 if (notacceptable) 00780 iks_delete(notacceptable); 00781 } else if (!(node = iks_find_attrib(pak->query, "node"))) { 00782 iks *iq = NULL, *query = NULL, *instructions = NULL; 00783 char *explain = "Welcome to Asterisk - the Open Source PBX.\n"; 00784 iq = iks_new("iq"); 00785 query = iks_new("query"); 00786 instructions = iks_new("instructions"); 00787 if (iq && query && instructions && client) { 00788 iks_insert_attrib(iq, "from", client->user); 00789 iks_insert_attrib(iq, "to", pak->from->full); 00790 iks_insert_attrib(iq, "id", pak->id); 00791 iks_insert_attrib(iq, "type", "result"); 00792 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00793 iks_insert_cdata(instructions, explain, 0); 00794 iks_insert_node(iq, query); 00795 iks_insert_node(query, instructions); 00796 iks_send(client->p, iq); 00797 } else { 00798 ast_log(LOG_ERROR, "Out of memory.\n"); 00799 } 00800 if (iq) 00801 iks_delete(iq); 00802 if (query) 00803 iks_delete(query); 00804 if (instructions) 00805 iks_delete(instructions); 00806 } 00807 ASTOBJ_UNREF(client, aji_client_destroy); 00808 return IKS_FILTER_EAT; 00809 }
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, s, and strsep().
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 1943 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().
01944 { 01945 int res = 0; 01946 iks *presence = iks_make_pres(level, desc); 01947 iks *cnode = iks_new("c"); 01948 iks *priority = iks_new("priority"); 01949 01950 iks_insert_cdata(priority, "0", 1); 01951 if (presence && cnode && client) { 01952 if(to) 01953 iks_insert_attrib(presence, "to", to); 01954 if(from) 01955 iks_insert_attrib(presence, "from", from); 01956 iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps"); 01957 iks_insert_attrib(cnode, "ver", "asterisk-xmpp"); 01958 iks_insert_attrib(cnode, "ext", "voice-v1"); 01959 iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps"); 01960 iks_insert_node(presence, cnode); 01961 res = iks_send(client->p, presence); 01962 } else 01963 ast_log(LOG_ERROR, "Out of memory.\n"); 01964 if (cnode) 01965 iks_delete(cnode); 01966 if (presence) 01967 iks_delete(presence); 01968 }
static int aji_show_clients | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
show client status.
fd,number | of args, args. |
Definition at line 2019 of file res_jabber.c.
References AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
02020 { 02021 char *status; 02022 int count = 0; 02023 ast_cli(fd, "Jabber Users and their status:\n"); 02024 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02025 ASTOBJ_RDLOCK(iterator); 02026 count++; 02027 switch (iterator->state) { 02028 case AJI_DISCONNECTED: 02029 status = "Disconnected"; 02030 break; 02031 case AJI_CONNECTING: 02032 status = "Connecting"; 02033 break; 02034 case AJI_CONNECTED: 02035 status = "Connected"; 02036 break; 02037 default: 02038 status = "Unknown"; 02039 } 02040 ast_cli(fd, " User: %s - %s\n", iterator->user, status); 02041 ASTOBJ_UNLOCK(iterator); 02042 }); 02043 ast_cli(fd, "----\n"); 02044 ast_cli(fd, " Number of users: %d\n", count); 02045 return RESULT_SUCCESS; 02046 }
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, aji_resource::status, and strsep().
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 2053 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.
02054 { 02055 struct aji_client *client; 02056 struct aji_resource *resource; 02057 const char *name = "asterisk"; 02058 struct aji_message *tmp; 02059 02060 if (argc > 3) 02061 return RESULT_SHOWUSAGE; 02062 else if (argc == 3) 02063 name = argv[2]; 02064 02065 if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) { 02066 ast_cli(fd, "Unable to find client '%s'!\n", name); 02067 return RESULT_FAILURE; 02068 } 02069 02070 /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */ 02071 ast_aji_send(client, "mogorman@astjab.org", "blahblah"); 02072 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 02073 ASTOBJ_RDLOCK(iterator); 02074 ast_verbose("User: %s\n", iterator->name); 02075 for (resource = iterator->resources; resource; resource = resource->next) { 02076 ast_verbose("Resource: %s\n", resource->resource); 02077 if(resource->cap) { 02078 ast_verbose(" client: %s\n", resource->cap->parent->node); 02079 ast_verbose(" version: %s\n", resource->cap->version); 02080 ast_verbose(" Jingle Capable: %d\n", resource->cap->jingle); 02081 } 02082 ast_verbose(" Priority: %d\n", resource->priority); 02083 ast_verbose(" Status: %d\n", resource->status); 02084 ast_verbose(" Message: %s\n", S_OR(resource->description,"")); 02085 } 02086 ASTOBJ_UNLOCK(iterator); 02087 }); 02088 ast_verbose("\nOooh a working message stack!\n"); 02089 AST_LIST_LOCK(&client->messages); 02090 AST_LIST_TRAVERSE(&client->messages, tmp, list) { 02091 ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, "")); 02092 } 02093 AST_LIST_UNLOCK(&client->messages); 02094 ASTOBJ_UNREF(client, aji_client_destroy); 02095 02096 return RESULT_SUCCESS; 02097 }
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 1453 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01454 { 01455 int res = 0; 01456 iks *iq = NULL; 01457 iq = iks_new("iq"); 01458 01459 if (iq && client) { 01460 iks_insert_attrib(iq, "type", "get"); 01461 iks_insert_attrib(iq, "to", server); 01462 iks_insert_attrib(iq, "id", client->mid); 01463 ast_aji_increment_mid(client->mid); 01464 iks_send(client->p, iq); 01465 } else 01466 ast_log(LOG_ERROR, "Out of memory.\n"); 01467 01468 iks_delete(iq); 01469 01470 return res; 01471 }
int ast_aji_disconnect | ( | struct aji_client * | client | ) |
disconnect from jabber server.
aji_client | struct. |
Definition at line 1925 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().
01926 { 01927 if (client) { 01928 if (option_verbose > 3) 01929 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Disconnecting\n"); 01930 iks_disconnect(client->p); 01931 iks_parser_delete(client->p); 01932 ASTOBJ_UNREF(client, aji_client_destroy); 01933 } 01934 01935 return 1; 01936 }
struct aji_client* ast_aji_get_client | ( | const char * | name | ) | [read] |
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, clients, and strsep().
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 | ) | [read] |
Definition at line 2389 of file res_jabber.c.
References clients.
Referenced by gtalk_load_config().
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 1585 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().
01586 { 01587 int i = 0; 01588 01589 for (i = strlen(mid) - 1; i >= 0; i--) { 01590 if (mid[i] != 'z') { 01591 mid[i] = mid[i] + 1; 01592 i = 0; 01593 } else 01594 mid[i] = 'a'; 01595 } 01596 }
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 1506 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01507 { 01508 int res = 0; 01509 iks *invite, *body, *namespace; 01510 01511 invite = iks_new("message"); 01512 body = iks_new("body"); 01513 namespace = iks_new("x"); 01514 if (client && invite && body && namespace) { 01515 iks_insert_attrib(invite, "to", user); 01516 iks_insert_attrib(invite, "id", client->mid); 01517 ast_aji_increment_mid(client->mid); 01518 iks_insert_cdata(body, message, 0); 01519 iks_insert_attrib(namespace, "xmlns", "jabber:x:conference"); 01520 iks_insert_attrib(namespace, "jid", room); 01521 iks_insert_node(invite, body); 01522 iks_insert_node(invite, namespace); 01523 res = iks_send(client->p, invite); 01524 } else 01525 ast_log(LOG_ERROR, "Out of memory.\n"); 01526 if (body) 01527 iks_delete(body); 01528 if (namespace) 01529 iks_delete(namespace); 01530 if (invite) 01531 iks_delete(invite); 01532 return res; 01533 }
int ast_aji_join_chat | ( | struct aji_client * | client, | |
char * | room | |||
) |
join a chatroom.
aji_client | struct , room. |
Definition at line 1478 of file res_jabber.c.
References ast_log(), LOG_ERROR, and aji_client::p.
01479 { 01480 int res = 0; 01481 iks *presence = NULL, *priority = NULL; 01482 presence = iks_new("presence"); 01483 priority = iks_new("priority"); 01484 if (presence && priority && client) { 01485 iks_insert_cdata(priority, "0", 1); 01486 iks_insert_attrib(presence, "to", room); 01487 iks_insert_node(presence, priority); 01488 res = iks_send(client->p, presence); 01489 iks_insert_cdata(priority, "5", 1); 01490 iks_insert_attrib(presence, "to", room); 01491 res = iks_send(client->p, presence); 01492 } else 01493 ast_log(LOG_ERROR, "Out of memory.\n"); 01494 if (presence) 01495 iks_delete(presence); 01496 if (priority) 01497 iks_delete(priority); 01498 return res; 01499 }
int ast_aji_send | ( | struct aji_client * | client, | |
const char * | address, | |||
const char * | message | |||
) |
sends messages.
aji_client | struct , reciever, message. |
Definition at line 1429 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().
01430 { 01431 int res = 0; 01432 iks *message_packet = NULL; 01433 if (client->state == AJI_CONNECTED) { 01434 message_packet = iks_make_msg(IKS_TYPE_CHAT, address, message); 01435 if (message_packet) { 01436 iks_insert_attrib(message_packet, "from", client->jid->full); 01437 res = iks_send(client->p, message_packet); 01438 } else { 01439 ast_log(LOG_ERROR, "Out of memory.\n"); 01440 } 01441 if (message_packet) 01442 iks_delete(message_packet); 01443 } else 01444 ast_log(LOG_WARNING, "JABBER: Not connected can't send\n"); 01445 return 1; 01446 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
"AJI - Asterisk Jabber Interface" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
static int gtalk_yuck | ( | iks * | node | ) | [static] |
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_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, and manager_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(), and astman_send_error().
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 if (!ast_strlen_zero(id)) 02432 astman_append(s, "ActionID: %s\r\n",id); 02433 astman_append(s, "Response: Success\r\n"); 02434 return 0; 02435 } 02436 if (!ast_strlen_zero(id)) 02437 astman_append(s, "ActionID: %s\r\n",id); 02438 astman_append(s, "Response: Failure\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_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_cli_entry aji_cli[] [static] |
Definition at line 131 of file res_jabber.c.
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.
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] |
Definition at line 2394 of file res_jabber.c.
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.