#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <iksemel.h>
#include "asterisk/channel.h"
#include "asterisk/jabber.h"
#include "asterisk/file.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/astobj.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
Include dependency graph for res_jabber.c:
Go to the source code of this file.
Defines | |
#define | JABBER_CONFIG "jabber.conf" |
Functions | |
static int | aji_act_hook (void *data, int type, iks *node) |
The action hook parses the inbound packets, constantly running. | |
static void | aji_buddy_destroy (struct aji_buddy *obj) |
Deletes the aji_buddy data structure. | |
static int | aji_client_connect (void *data, ikspak *pak) |
connects as a client to jabber server. | |
static void | aji_client_destroy (struct aji_client *obj) |
Deletes the aji_client data structure. | |
static int | aji_client_info_handler (void *data, ikspak *pak) |
static int | aji_client_initialize (struct aji_client *client) |
prepares client for connect. | |
static int | aji_component_initialize (struct aji_client *client) |
prepares component for connect. | |
static int | aji_create_buddy (char *label, struct aji_client *client) |
creates transport. creates buddy. | |
static int | aji_create_client (char *label, struct ast_variable *var, int debug) |
creates aji_client structure. | |
static int | aji_dinfo_handler (void *data, ikspak *pak) |
static int | aji_ditems_handler (void *data, ikspak *pak) |
static int | aji_do_debug (int fd, int argc, char *argv[]) |
turnon console debugging. | |
static int | aji_do_reload (int fd, int argc, char *argv[]) |
reload jabber module. | |
static int | aji_filter_roster (void *data, ikspak *pak) |
filters the roster packet we get back from server. | |
static struct aji_resource * | aji_find_resource (struct aji_buddy *buddy, char *name) |
static struct aji_version * | aji_find_version (char *node, char *version, ikspak *pak) |
Find version in XML stream and populate our capabilities list. | |
static int | aji_get_roster (struct aji_client *client) |
static void | aji_handle_iq (struct aji_client *client, iks *node) |
Handles <iq> tags. | |
static void | aji_handle_message (struct aji_client *client, ikspak *pak) |
Handles presence packets. | |
static void | aji_handle_presence (struct aji_client *client, ikspak *pak) |
static void | aji_handle_subscribe (struct aji_client *client, ikspak *pak) |
handles subscription requests. | |
static int | aji_highest_bit (int number) |
Detects the highest bit in a number. | |
static int | aji_load_config (void) |
load config file. | |
static void | aji_log_hook (void *data, const char *xmpp, size_t size, int is_incoming) |
the debug loop. | |
static int | aji_no_debug (int fd, int argc, char *argv[]) |
turnoff console debugging. | |
static void | aji_pruneregister (struct aji_client *client) |
attempts to register to a transport. attempts to register to a transport step 2. goes through roster and prunes users not needed in list, or adds them accordingly. | |
static int | aji_reconnect (struct aji_client *client) |
static void * | aji_recv_loop (void *data) |
receive message loop. | |
static int | aji_register_approve_handler (void *data, ikspak *pak) |
static int | aji_register_query_handler (void *data, ikspak *pak) |
static int | aji_reload (void) |
static int | aji_send_exec (struct ast_channel *chan, void *data) |
Dial plan function to send a message. | |
static void | aji_set_presence (struct aji_client *client, char *to, char *from, int level, char *desc) |
set presence of client. | |
static int | aji_show_clients (int fd, int argc, char *argv[]) |
show client status. | |
static int | aji_status_exec (struct ast_channel *chan, void *data) |
Dial plan function status(). puts the status of watched user into a channel variable. | |
static int | aji_test (int fd, int argc, char *argv[]) |
send test message for debugging. | |
int | ast_aji_create_chat (struct aji_client *client, char *room, char *server, char *topic) |
create a chatroom. | |
int | ast_aji_disconnect (struct aji_client *client) |
disconnect from jabber server. | |
aji_client * | ast_aji_get_client (const char *name) |
grab a aji_client structure by label name. | |
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" |
aji_capabilities * | capabilities = NULL |
aji_client_container | clients |
static char | debug_usage [] |
static struct ast_flags | globalflags = { AJI_AUTOPRUNE | AJI_AUTOREGISTER } |
Global flags, initialized to default values. | |
static char | mandescr_jabber_send [] |
static char | no_debug_usage [] |
static char | reload_usage [] |
static char | test_usage [] |
Definition in file res_jabber.c.
#define JABBER_CONFIG "jabber.conf" |
static int aji_act_hook | ( | void * | data, | |
int | type, | |||
iks * | node | |||
) | [static] |
The action hook parses the inbound packets, constantly running.
aji | client structure, type of packet, the actual packet. |
Definition at line 471 of file res_jabber.c.
References aji_client_connect(), aji_client_destroy(), AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, 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, aji_client::usesasl, and aji_client::usetls.
Referenced by aji_create_client().
00472 { 00473 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00474 ikspak *pak = NULL; 00475 iks *auth = NULL; 00476 00477 if(!node) { 00478 ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */ 00479 ASTOBJ_UNREF(client, aji_client_destroy); 00480 return IKS_HOOK; 00481 } 00482 00483 pak = iks_packet(node); 00484 00485 if (!client->component) { /*client */ 00486 switch (type) { 00487 case IKS_NODE_START: 00488 if (client->usetls && !iks_is_secure(client->p)) { 00489 if (iks_has_tls()) 00490 iks_start_tls(client->p); 00491 else 00492 ast_log(LOG_ERROR, "gnuTLS not installed.\n"); 00493 break; 00494 } 00495 if (!client->usesasl) { 00496 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); 00497 auth = jabber_make_auth(client->jid, client->password, iks_find_attrib(node, "id")); 00498 if (auth) { 00499 iks_insert_attrib(auth, "id", client->mid); 00500 iks_insert_attrib(auth, "to", client->jid->server); 00501 ast_aji_increment_mid(client->mid); 00502 iks_send(client->p, auth); 00503 iks_delete(auth); 00504 } else 00505 ast_log(LOG_ERROR, "Out of memory.\n"); 00506 } 00507 break; 00508 00509 case IKS_NODE_NORMAL: 00510 { 00511 int features = 0; 00512 if (!strcmp("stream:features", iks_name(node))) { 00513 features = iks_stream_features(node); 00514 if (client->usesasl) { 00515 if (client->usetls && !iks_is_secure(client->p)) 00516 break; 00517 if (client->authorized) { 00518 if (features & IKS_STREAM_BIND) { 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_DONE); 00520 auth = iks_make_resource_bind(client->jid); 00521 if (auth) { 00522 iks_insert_attrib(auth, "id", client->mid); 00523 ast_aji_increment_mid(client->mid); 00524 iks_send(client->p, auth); 00525 iks_delete(auth); 00526 } else { 00527 ast_log(LOG_ERROR, "Out of memory.\n"); 00528 break; 00529 } 00530 } 00531 if (features & IKS_STREAM_SESSION) { 00532 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); 00533 auth = iks_make_session(); 00534 if (auth) { 00535 iks_insert_attrib(auth, "id", "auth"); 00536 ast_aji_increment_mid(client->mid); 00537 iks_send(client->p, auth); 00538 iks_delete(auth); 00539 } else { 00540 ast_log(LOG_ERROR, "Out of memory.\n"); 00541 } 00542 } 00543 } else { 00544 features = aji_highest_bit(features); 00545 if (features == IKS_STREAM_SASL_MD5) 00546 iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, client->jid->user, client->password); 00547 else { 00548 if (features == IKS_STREAM_SASL_PLAIN) { 00549 iks *x = NULL; 00550 x = iks_new("auth"); 00551 if (x) { 00552 iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL); 00553 int len = strlen(client->jid->user) + strlen(client->password) + 3; 00554 /* XXX Check return values XXX */ 00555 char *s = ast_malloc(80 + len); 00556 char *base64 = ast_malloc(80 + len * 2); 00557 iks_insert_attrib(x, "mechanism", "PLAIN"); 00558 sprintf(s, "%c%s%c%s", 0, client->jid->user, 0, client->password); 00559 ast_base64encode(base64, (const unsigned char *) s, len, len * 2); 00560 iks_insert_cdata(x, base64, 0); 00561 iks_send(client->p, x); 00562 iks_delete(x); 00563 if (base64) 00564 free(base64); 00565 if (s) 00566 free(s); 00567 } else { 00568 ast_log(LOG_ERROR, "Out of memory.\n"); 00569 } 00570 } 00571 } 00572 } 00573 } 00574 } else if (!strcmp("failure", iks_name(node))) { 00575 ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n"); 00576 } else if (!strcmp("success", iks_name(node))) { 00577 client->authorized = 1; 00578 iks_send_header(client->p, client->jid->server); 00579 } 00580 break; 00581 } 00582 case IKS_NODE_ERROR: 00583 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00584 ASTOBJ_UNREF(client, aji_client_destroy); 00585 return IKS_HOOK; 00586 break; 00587 case IKS_NODE_STOP: 00588 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00589 ASTOBJ_UNREF(client, aji_client_destroy); 00590 return IKS_HOOK; 00591 break; 00592 } 00593 } else if (client->state != AJI_CONNECTED && client->component) { 00594 switch (type) { 00595 case IKS_NODE_START: 00596 if (client->state == AJI_DISCONNECTED) { 00597 char secret[160], shasum[320], *handshake; 00598 00599 sprintf(secret, "%s%s", pak->id, client->password); 00600 ast_sha1_hash(shasum, secret); 00601 handshake = NULL; 00602 asprintf(&handshake, "<handshake>%s</handshake>", shasum); 00603 if (handshake) { 00604 iks_send_raw(client->p, handshake); 00605 free(handshake); 00606 handshake = NULL; 00607 } 00608 client->state = AJI_CONNECTING; 00609 if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/ 00610 client->state = AJI_CONNECTED; 00611 else 00612 ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n"); 00613 break; 00614 } 00615 break; 00616 00617 case IKS_NODE_NORMAL: 00618 break; 00619 00620 case IKS_NODE_ERROR: 00621 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00622 ASTOBJ_UNREF(client, aji_client_destroy); 00623 return IKS_HOOK; 00624 00625 case IKS_NODE_STOP: 00626 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00627 ASTOBJ_UNREF(client, aji_client_destroy); 00628 return IKS_HOOK; 00629 } 00630 } 00631 00632 switch (pak->type) { 00633 case IKS_PAK_NONE: 00634 if (option_debug) 00635 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n"); 00636 break; 00637 case IKS_PAK_MESSAGE: 00638 aji_handle_message(client, pak); 00639 if (option_debug) 00640 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n"); 00641 break; 00642 case IKS_PAK_PRESENCE: 00643 aji_handle_presence(client, pak); 00644 if (option_debug) 00645 ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n"); 00646 break; 00647 case IKS_PAK_S10N: 00648 aji_handle_subscribe(client, pak); 00649 if (option_debug) 00650 ast_log(LOG_DEBUG, "JABBER: I Dont know S10N subscribe!!\n"); 00651 break; 00652 case IKS_PAK_IQ: 00653 if (option_debug) 00654 ast_log(LOG_DEBUG, "JABBER: I Dont have an IQ!!!\n"); 00655 aji_handle_iq(client, node); 00656 break; 00657 default: 00658 if (option_debug) 00659 ast_log(LOG_DEBUG, "JABBER: I Dont know %i\n", pak->type); 00660 break; 00661 } 00662 00663 iks_filter_packet(client->f, pak); 00664 00665 if (node) 00666 iks_delete(node); 00667 00668 ASTOBJ_UNREF(client, aji_client_destroy); 00669 return IKS_OK; 00670 }
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 197 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().
00198 { 00199 struct aji_resource *tmp; 00200 00201 while ((tmp = obj->resources)) { 00202 obj->resources = obj->resources->next; 00203 free(tmp->description); 00204 free(tmp); 00205 } 00206 00207 free(obj); 00208 }
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 1797 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().
01798 { 01799 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01800 int res = 0; 01801 01802 if (client) { 01803 if (client->state == AJI_DISCONNECTED) { 01804 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); 01805 client->state = AJI_CONNECTING; 01806 client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid; 01807 iks_filter_remove_hook(client->f, aji_client_connect); 01808 if(!client->component) /*client*/ 01809 aji_get_roster(client); 01810 } 01811 } else 01812 ast_log(LOG_ERROR, "Out of memory.\n"); 01813 01814 ASTOBJ_UNREF(client, aji_client_destroy); 01815 return res; 01816 }
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 173 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().
00174 { 00175 struct aji_message *tmp; 00176 ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy); 00177 ASTOBJ_CONTAINER_DESTROY(&obj->buddies); 00178 iks_filter_delete(obj->f); 00179 iks_parser_delete(obj->p); 00180 iks_stack_delete(obj->stack); 00181 AST_LIST_LOCK(&obj->messages); 00182 while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) { 00183 if (tmp->from) 00184 free(tmp->from); 00185 if (tmp->message) 00186 free(tmp->message); 00187 } 00188 AST_LIST_HEAD_DESTROY(&obj->messages); 00189 free(obj); 00190 }
static int aji_client_info_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 877 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().
00878 { 00879 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00880 struct aji_resource *resource = NULL; 00881 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00882 00883 resource = aji_find_resource(buddy, pak->from->resource); 00884 if (pak->subtype == IKS_TYPE_RESULT) { 00885 if (!resource) { 00886 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00887 ASTOBJ_UNREF(client, aji_client_destroy); 00888 return IKS_FILTER_EAT; 00889 } 00890 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00891 resource->cap->jingle = 1; 00892 } else 00893 resource->cap->jingle = 0; 00894 } else if (pak->subtype == IKS_TYPE_GET) { 00895 iks *iq, *disco, *ident, *google, *query; 00896 iq = iks_new("iq"); 00897 query = iks_new("query"); 00898 ident = iks_new("identity"); 00899 disco = iks_new("feature"); 00900 google = iks_new("feature"); 00901 if (iq && ident && disco && google) { 00902 iks_insert_attrib(iq, "from", client->jid->full); 00903 iks_insert_attrib(iq, "to", pak->from->full); 00904 iks_insert_attrib(iq, "type", "result"); 00905 iks_insert_attrib(iq, "id", pak->id); 00906 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00907 iks_insert_attrib(ident, "category", "client"); 00908 iks_insert_attrib(ident, "type", "pc"); 00909 iks_insert_attrib(ident, "name", "asterisk"); 00910 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info"); 00911 iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1"); 00912 iks_insert_node(iq, query); 00913 iks_insert_node(query, ident); 00914 iks_insert_node(query, google); 00915 iks_insert_node(query, disco); 00916 iks_send(client->p, iq); 00917 } else 00918 ast_log(LOG_ERROR, "Out of Memory.\n"); 00919 if (iq) 00920 iks_delete(iq); 00921 if (query) 00922 iks_delete(query); 00923 if (ident) 00924 iks_delete(ident); 00925 if (google) 00926 iks_delete(google); 00927 if (disco) 00928 iks_delete(disco); 00929 } else if (pak->subtype == IKS_TYPE_ERROR) { 00930 ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full); 00931 } 00932 ASTOBJ_UNREF(client, aji_client_destroy); 00933 return IKS_FILTER_EAT; 00934 }
static int aji_client_initialize | ( | struct aji_client * | client | ) | [static] |
prepares client for connect.
aji_client | struct. |
Definition at line 1823 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().
01824 { 01825 int connected = 0; 01826 01827 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server); 01828 01829 if (connected == IKS_NET_NOCONN) { 01830 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01831 return IKS_HOOK; 01832 } else if (connected == IKS_NET_NODNS) { 01833 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01834 return IKS_HOOK; 01835 } else 01836 iks_recv(client->p, 30); 01837 return IKS_OK; 01838 }
static int aji_component_initialize | ( | struct aji_client * | client | ) | [static] |
prepares component for connect.
aji_client | struct. |
Definition at line 1845 of file res_jabber.c.
References ast_log(), connected, aji_client::jid, LOG_ERROR, aji_client::p, aji_client::port, and aji_client::user.
Referenced by aji_reconnect().
01846 { 01847 int connected = 1; 01848 connected = iks_connect_via(client->p, client->jid->server, client->port, client->user); 01849 if (connected == IKS_NET_NOCONN) { 01850 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01851 return IKS_HOOK; 01852 } else if (connected == IKS_NET_NODNS) { 01853 ast_log(LOG_ERROR, "JABBER ERROR: No DNS\n"); 01854 return IKS_HOOK; 01855 } else if (!connected) 01856 iks_recv(client->p, 30); 01857 return IKS_OK; 01858 }
static int aji_create_buddy | ( | char * | label, | |
struct aji_client * | client | |||
) | [static] |
creates transport. creates buddy.
label,buddy | to dump it into. |
Definition at line 2234 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(), and aji_handle_presence().
02235 { 02236 struct aji_buddy *buddy = NULL; 02237 int flag = 0; 02238 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label); 02239 if (!buddy) { 02240 flag = 1; 02241 buddy = malloc(sizeof(struct aji_buddy)); 02242 if(!buddy) { 02243 ast_log(LOG_WARNING, "Out of memory\n"); 02244 return 0; 02245 } 02246 memset(buddy, 0, sizeof(struct aji_buddy)); 02247 ASTOBJ_INIT(buddy); 02248 } 02249 ASTOBJ_WRLOCK(buddy); 02250 ast_copy_string(buddy->name, label, sizeof(buddy->name)); 02251 ASTOBJ_UNLOCK(buddy); 02252 if(flag) 02253 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 02254 else { 02255 ASTOBJ_UNMARK(buddy); 02256 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 02257 } 02258 return 1; 02259 }
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 2044 of file res_jabber.c.
References aji_act_hook(), AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_client_destroy(), aji_client_info_handler(), aji_create_buddy(), aji_dinfo_handler(), AJI_DISCONNECTED, aji_ditems_handler(), aji_log_hook(), aji_register_approve_handler(), aji_register_query_handler(), asprintf, ast_copy_flags, ast_false(), AST_FLAGS_ALL, AST_LIST_HEAD_INIT, ast_log(), ast_set2_flag, ast_true(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_INIT, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::authorized, aji_client::buddies, clients, aji_client::component, aji_client::debug, aji_client::f, aji_client::forcessl, free, globalflags, aji_client::jid, aji_client::keepalive, LOG_ERROR, malloc, aji_client::message_timeout, aji_client::mid, aji_client::p, aji_client::password, aji_client::port, aji_client::serverhost, aji_client::stack, aji_client::state, aji_client::statusmessage, aji_client::timeout, aji_client::user, aji_client::usesasl, aji_client::usetls, and var.
Referenced by aji_load_config().
02045 { 02046 char *resource; 02047 struct aji_client *client = NULL; 02048 int flag = 0; 02049 02050 client = ASTOBJ_CONTAINER_FIND(&clients,label); 02051 if (!client) { 02052 flag = 1; 02053 client = (struct aji_client *) malloc(sizeof(struct aji_client)); 02054 if (!client) { 02055 ast_log(LOG_ERROR, "Out of memory!\n"); 02056 return 0; 02057 } 02058 memset(client, 0, sizeof(struct aji_client)); 02059 ASTOBJ_INIT(client); 02060 ASTOBJ_WRLOCK(client); 02061 ASTOBJ_CONTAINER_INIT(&client->buddies); 02062 } else { 02063 ASTOBJ_WRLOCK(client); 02064 ASTOBJ_UNMARK(client); 02065 } 02066 ASTOBJ_CONTAINER_MARKALL(&client->buddies); 02067 ast_copy_string(client->name, label, sizeof(client->name)); 02068 ast_copy_string(client->mid, "aaaaa", sizeof(client->mid)); 02069 02070 client->debug = debug; 02071 ast_copy_flags(client, &globalflags, AST_FLAGS_ALL); 02072 client->port = 5222; 02073 client->usetls = 1; 02074 client->usesasl = 1; 02075 client->forcessl = 0; 02076 client->keepalive = 1; 02077 client->timeout = 50; 02078 client->message_timeout = 100; 02079 AST_LIST_HEAD_INIT(&client->messages); 02080 client->component = 0; 02081 ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage)); 02082 02083 if (flag) { 02084 client->authorized = 0; 02085 client->state = AJI_DISCONNECTED; 02086 } 02087 while (var) { 02088 if (!strcasecmp(var->name, "username")) 02089 ast_copy_string(client->user, var->value, sizeof(client->user)); 02090 else if (!strcasecmp(var->name, "serverhost")) 02091 ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost)); 02092 else if (!strcasecmp(var->name, "secret")) 02093 ast_copy_string(client->password, var->value, sizeof(client->password)); 02094 else if (!strcasecmp(var->name, "statusmessage")) 02095 ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage)); 02096 else if (!strcasecmp(var->name, "port")) 02097 client->port = atoi(var->value); 02098 else if (!strcasecmp(var->name, "timeout")) 02099 client->message_timeout = atoi(var->value); 02100 else if (!strcasecmp(var->name, "debug")) 02101 client->debug = (ast_false(var->value)) ? 0 : 1; 02102 else if (!strcasecmp(var->name, "type")) { 02103 if (!strcasecmp(var->value, "component")) 02104 client->component = 1; 02105 } else if (!strcasecmp(var->name, "usetls")) { 02106 client->usetls = (ast_false(var->value)) ? 0 : 1; 02107 } else if (!strcasecmp(var->name, "usesasl")) { 02108 client->usesasl = (ast_false(var->value)) ? 0 : 1; 02109 } else if (!strcasecmp(var->name, "forceoldssl")) 02110 client->forcessl = (ast_false(var->value)) ? 0 : 1; 02111 else if (!strcasecmp(var->name, "keepalive")) 02112 client->keepalive = (ast_false(var->value)) ? 0 : 1; 02113 else if (!strcasecmp(var->name, "autoprune")) 02114 ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE); 02115 else if (!strcasecmp(var->name, "autoregister")) 02116 ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER); 02117 else if (!strcasecmp(var->name, "buddy")) 02118 aji_create_buddy(var->value, client); 02119 /* no transport support in this version */ 02120 /* else if (!strcasecmp(var->name, "transport")) 02121 aji_create_transport(var->value, client); 02122 */ 02123 var = var->next; 02124 } 02125 if (!flag) { 02126 ASTOBJ_UNLOCK(client); 02127 ASTOBJ_UNREF(client, aji_client_destroy); 02128 return 1; 02129 } 02130 client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook); 02131 if (!client->p) { 02132 ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name); 02133 return 0; 02134 } 02135 client->stack = iks_stack_new(8192, 8192); 02136 if (!client->stack) { 02137 ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name); 02138 return 0; 02139 } 02140 client->f = iks_filter_new(); 02141 if (!client->f) { 02142 ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name); 02143 return 0; 02144 } 02145 if (!strchr(client->user, '/') && !client->component) { /*client */ 02146 resource = NULL; 02147 asprintf(&resource, "%s/asterisk", client->user); 02148 if (resource) { 02149 client->jid = iks_id_new(client->stack, resource); 02150 free(resource); 02151 } 02152 } else 02153 client->jid = iks_id_new(client->stack, client->user); 02154 if (client->component) { 02155 iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02156 iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE); 02157 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); 02158 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); 02159 } else { 02160 iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02161 } 02162 if (!strchr(client->user, '/') && !client->component) { /*client */ 02163 resource = NULL; 02164 asprintf(&resource, "%s/asterisk", client->user); 02165 if (resource) { 02166 client->jid = iks_id_new(client->stack, resource); 02167 free(resource); 02168 } 02169 } else 02170 client->jid = iks_id_new(client->stack, client->user); 02171 iks_set_log_hook(client->p, aji_log_hook); 02172 ASTOBJ_UNLOCK(client); 02173 ASTOBJ_CONTAINER_LINK(&clients,client); 02174 return 1; 02175 }
static int aji_dinfo_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 936 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().
00937 { 00938 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00939 char *node = NULL; 00940 struct aji_resource *resource = NULL; 00941 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00942 00943 resource = aji_find_resource(buddy, pak->from->resource); 00944 if (pak->subtype == IKS_TYPE_ERROR) { 00945 ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n"); 00946 return IKS_FILTER_EAT; 00947 } 00948 if (pak->subtype == IKS_TYPE_RESULT) { 00949 if (!resource) { 00950 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00951 ASTOBJ_UNREF(client, aji_client_destroy); 00952 return IKS_FILTER_EAT; 00953 } 00954 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00955 resource->cap->jingle = 1; 00956 } else 00957 resource->cap->jingle = 0; 00958 } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) { 00959 iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search; 00960 00961 iq = iks_new("iq"); 00962 query = iks_new("query"); 00963 identity = iks_new("identity"); 00964 disco = iks_new("feature"); 00965 reg = iks_new("feature"); 00966 commands = iks_new("feature"); 00967 gateway = iks_new("feature"); 00968 version = iks_new("feature"); 00969 vcard = iks_new("feature"); 00970 search = iks_new("feature"); 00971 00972 if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) { 00973 iks_insert_attrib(iq, "from", client->user); 00974 iks_insert_attrib(iq, "to", pak->from->full); 00975 iks_insert_attrib(iq, "id", pak->id); 00976 iks_insert_attrib(iq, "type", "result"); 00977 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00978 iks_insert_attrib(identity, "category", "gateway"); 00979 iks_insert_attrib(identity, "type", "pstn"); 00980 iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX"); 00981 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco"); 00982 iks_insert_attrib(reg, "var", "jabber:iq:register"); 00983 iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands"); 00984 iks_insert_attrib(gateway, "var", "jabber:iq:gateway"); 00985 iks_insert_attrib(version, "var", "jabber:iq:version"); 00986 iks_insert_attrib(vcard, "var", "vcard-temp"); 00987 iks_insert_attrib(search, "var", "jabber:iq:search"); 00988 00989 iks_insert_node(iq, query); 00990 iks_insert_node(query, identity); 00991 iks_insert_node(query, disco); 00992 iks_insert_node(query, reg); 00993 iks_insert_node(query, commands); 00994 iks_insert_node(query, gateway); 00995 iks_insert_node(query, version); 00996 iks_insert_node(query, vcard); 00997 iks_insert_node(query, search); 00998 iks_send(client->p, iq); 00999 } else { 01000 ast_log(LOG_ERROR, "Out of memory.\n"); 01001 } 01002 01003 if (iq) 01004 iks_delete(iq); 01005 if (query) 01006 iks_delete(query); 01007 if (identity) 01008 iks_delete(identity); 01009 if (disco) 01010 iks_delete(disco); 01011 if (reg) 01012 iks_delete(reg); 01013 if (commands) 01014 iks_delete(commands); 01015 if (gateway) 01016 iks_delete(gateway); 01017 if (version) 01018 iks_delete(version); 01019 if (vcard) 01020 iks_delete(vcard); 01021 if (search) 01022 iks_delete(search); 01023 01024 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) { 01025 iks *iq, *query, *confirm; 01026 iq = iks_new("iq"); 01027 query = iks_new("query"); 01028 confirm = iks_new("item"); 01029 01030 if (iq && query && confirm && client) { 01031 iks_insert_attrib(iq, "from", client->user); 01032 iks_insert_attrib(iq, "to", pak->from->full); 01033 iks_insert_attrib(iq, "id", pak->id); 01034 iks_insert_attrib(iq, "type", "result"); 01035 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 01036 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 01037 iks_insert_attrib(confirm, "node", "confirmaccount"); 01038 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 01039 iks_insert_attrib(confirm, "jid", client->user); 01040 iks_insert_node(iq, query); 01041 iks_insert_node(query, confirm); 01042 iks_send(client->p, iq); 01043 } else { 01044 ast_log(LOG_ERROR, "Out of memory.\n"); 01045 } 01046 if (iq) 01047 iks_delete(iq); 01048 if (query) 01049 iks_delete(query); 01050 if (confirm) 01051 iks_delete(confirm); 01052 01053 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) { 01054 iks *iq, *query, *feature; 01055 01056 iq = iks_new("iq"); 01057 query = iks_new("query"); 01058 feature = iks_new("feature"); 01059 01060 if (iq && query && feature && 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#info"); 01066 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 01067 iks_insert_node(iq, query); 01068 iks_insert_node(query, feature); 01069 iks_send(client->p, iq); 01070 } else { 01071 ast_log(LOG_ERROR, "Out of memory.\n"); 01072 } 01073 if (iq) 01074 iks_delete(iq); 01075 if (query) 01076 iks_delete(query); 01077 if (feature) 01078 iks_delete(feature); 01079 } 01080 01081 ASTOBJ_UNREF(client, aji_client_destroy); 01082 return IKS_FILTER_EAT; 01083 }
static int aji_ditems_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 781 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().
00782 { 00783 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00784 char *node = NULL; 00785 00786 if (!(node = iks_find_attrib(pak->query, "node"))) { 00787 iks *iq = NULL, *query = NULL, *item = NULL; 00788 iq = iks_new("iq"); 00789 query = iks_new("query"); 00790 item = iks_new("item"); 00791 00792 if (iq && query && item) { 00793 iks_insert_attrib(iq, "from", client->user); 00794 iks_insert_attrib(iq, "to", pak->from->full); 00795 iks_insert_attrib(iq, "id", pak->id); 00796 iks_insert_attrib(iq, "type", "result"); 00797 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00798 iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands"); 00799 iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands"); 00800 iks_insert_attrib(item, "jid", client->user); 00801 00802 iks_insert_node(iq, query); 00803 iks_insert_node(query, item); 00804 iks_send(client->p, iq); 00805 } else { 00806 ast_log(LOG_ERROR, "Out of memory.\n"); 00807 } 00808 if (iq) 00809 iks_delete(iq); 00810 if (query) 00811 iks_delete(query); 00812 if (item) 00813 iks_delete(item); 00814 00815 } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) { 00816 iks *iq, *query, *confirm; 00817 iq = iks_new("iq"); 00818 query = iks_new("query"); 00819 confirm = iks_new("item"); 00820 if (iq && query && confirm && client) { 00821 iks_insert_attrib(iq, "from", client->user); 00822 iks_insert_attrib(iq, "to", pak->from->full); 00823 iks_insert_attrib(iq, "id", pak->id); 00824 iks_insert_attrib(iq, "type", "result"); 00825 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00826 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 00827 iks_insert_attrib(confirm, "node", "confirmaccount"); 00828 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 00829 iks_insert_attrib(confirm, "jid", "blog.astjab.org"); 00830 00831 iks_insert_node(iq, query); 00832 iks_insert_node(query, confirm); 00833 iks_send(client->p, iq); 00834 } else { 00835 ast_log(LOG_ERROR, "Out of memory.\n"); 00836 } 00837 if (iq) 00838 iks_delete(iq); 00839 if (query) 00840 iks_delete(query); 00841 if (confirm) 00842 iks_delete(confirm); 00843 00844 } else if (!strcasecmp(node, "confirmaccount")) { 00845 iks *iq = NULL, *query = NULL, *feature = NULL; 00846 00847 iq = iks_new("iq"); 00848 query = iks_new("query"); 00849 feature = iks_new("feature"); 00850 00851 if (iq && query && feature && client) { 00852 iks_insert_attrib(iq, "from", client->user); 00853 iks_insert_attrib(iq, "to", pak->from->full); 00854 iks_insert_attrib(iq, "id", pak->id); 00855 iks_insert_attrib(iq, "type", "result"); 00856 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00857 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 00858 iks_insert_node(iq, query); 00859 iks_insert_node(query, feature); 00860 iks_send(client->p, iq); 00861 } else { 00862 ast_log(LOG_ERROR, "Out of memory.\n"); 00863 } 00864 if (iq) 00865 iks_delete(iq); 00866 if (query) 00867 iks_delete(query); 00868 if (feature) 00869 iks_delete(feature); 00870 } 00871 00872 ASTOBJ_UNREF(client, aji_client_destroy); 00873 return IKS_FILTER_EAT; 00874 00875 }
static int aji_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
turnon console debugging.
fd,number | of args, args. |
Definition at line 1915 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01916 { 01917 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01918 ASTOBJ_RDLOCK(iterator); 01919 iterator->debug = 1; 01920 ASTOBJ_UNLOCK(iterator); 01921 }); 01922 ast_cli(fd, "Jabber Debugging Enabled.\n"); 01923 return RESULT_SUCCESS; 01924 }
static int aji_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
reload jabber module.
fd,number | of args, args. |
Definition at line 1931 of file res_jabber.c.
References aji_reload(), ast_cli(), and RESULT_SUCCESS.
01932 { 01933 aji_reload(); 01934 ast_cli(fd, "Jabber Reloaded.\n"); 01935 return RESULT_SUCCESS; 01936 }
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 1686 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().
01687 { 01688 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01689 int flag = 0; 01690 iks *x = NULL; 01691 struct aji_buddy *buddy; 01692 01693 client->state = AJI_CONNECTED; 01694 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01695 ASTOBJ_RDLOCK(iterator); 01696 x = iks_child(pak->query); 01697 flag = 0; 01698 while (x) { 01699 if (!iks_strcmp(iks_name(x), "item")) { 01700 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) { 01701 flag = 1; 01702 ast_clear_flag(iterator, AJI_AUTOPRUNE | AJI_AUTOREGISTER); 01703 } 01704 } 01705 x = iks_next(x); 01706 } 01707 if (!flag) 01708 ast_copy_flags(iterator, client, AJI_AUTOREGISTER); 01709 if (x) 01710 iks_delete(x); 01711 ASTOBJ_UNLOCK(iterator); 01712 }); 01713 01714 x = iks_child(pak->query); 01715 while (x) { 01716 flag = 0; 01717 if (iks_strcmp(iks_name(x), "item") == 0) { 01718 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01719 ASTOBJ_RDLOCK(iterator); 01720 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) 01721 flag = 1; 01722 ASTOBJ_UNLOCK(iterator); 01723 }); 01724 01725 if (!flag) { 01726 buddy = (struct aji_buddy *) malloc(sizeof(struct aji_buddy)); 01727 if (!buddy) { 01728 ast_log(LOG_WARNING, "Out of memory\n"); 01729 return 0; 01730 } 01731 memset(buddy, 0, sizeof(struct aji_buddy)); 01732 ASTOBJ_INIT(buddy); 01733 ASTOBJ_WRLOCK(buddy); 01734 ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name)); 01735 ast_clear_flag(buddy, AST_FLAGS_ALL); 01736 if(ast_test_flag(client, AJI_AUTOPRUNE)) { 01737 ast_set_flag(buddy, AJI_AUTOPRUNE); 01738 buddy->objflags |= ASTOBJ_FLAG_MARKED; 01739 } else 01740 ast_set_flag(buddy, AJI_AUTOREGISTER); 01741 ASTOBJ_UNLOCK(buddy); 01742 if (buddy) { 01743 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 01744 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01745 } 01746 } 01747 } 01748 x = iks_next(x); 01749 } 01750 if (x) 01751 iks_delete(x); 01752 aji_pruneregister(client); 01753 01754 ASTOBJ_UNREF(client, aji_client_destroy); 01755 return IKS_FILTER_EAT; 01756 }
static struct aji_resource* aji_find_resource | ( | struct aji_buddy * | buddy, | |
char * | name | |||
) | [static] |
Definition at line 280 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().
00281 { 00282 struct aji_resource *res = NULL; 00283 if (!buddy || !name) 00284 return res; 00285 res = buddy->resources; 00286 while (res) { 00287 if (!strcasecmp(res->resource, name)) { 00288 break; 00289 } 00290 res = res->next; 00291 } 00292 return res; 00293 }
static struct aji_version* aji_find_version | ( | char * | node, | |
char * | version, | |||
ikspak * | pak | |||
) | [static] |
Find version in XML stream and populate our capabilities list.
node | the node attribute in the caps element we'll look for or add to our list | |
version | the version attribute in the caps element we'll look for or add to our list | |
pak | the XML stanza we're processing |
Definition at line 219 of file res_jabber.c.
References ast_log(), capabilities, aji_version::jingle, LOG_ERROR, malloc, aji_capabilities::next, aji_version::next, aji_capabilities::node, aji_version::parent, aji_version::version, and aji_capabilities::versions.
Referenced by aji_handle_presence().
00220 { 00221 struct aji_capabilities *list = NULL; 00222 struct aji_version *res = NULL; 00223 00224 list = capabilities; 00225 00226 if(!node) 00227 node = pak->from->full; 00228 if(!version) 00229 version = "none supplied."; 00230 while(list) { 00231 if(!strcasecmp(list->node, node)) { 00232 res = list->versions; 00233 while(res) { 00234 if(!strcasecmp(res->version, version)) 00235 return res; 00236 res = res->next; 00237 } 00238 /* Specified version not found. Let's add it to 00239 this node in our capabilities list */ 00240 if(!res) { 00241 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00242 if(!res) { 00243 ast_log(LOG_ERROR, "Out of memory!\n"); 00244 return NULL; 00245 } 00246 res->jingle = 0; 00247 res->parent = list; 00248 ast_copy_string(res->version, version, sizeof(res->version)); 00249 res->next = list->versions; 00250 list->versions = res; 00251 return res; 00252 } 00253 } 00254 list = list->next; 00255 } 00256 /* Specified node not found. Let's add it our capabilities list */ 00257 if(!list) { 00258 list = (struct aji_capabilities *)malloc(sizeof(struct aji_capabilities)); 00259 if(!list) { 00260 ast_log(LOG_ERROR, "Out of memory!\n"); 00261 return NULL; 00262 } 00263 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00264 if(!res) { 00265 ast_log(LOG_ERROR, "Out of memory!\n"); 00266 return NULL; 00267 } 00268 ast_copy_string(list->node, node, sizeof(list->node)); 00269 ast_copy_string(res->version, version, sizeof(res->version)); 00270 res->jingle = 0; 00271 res->parent = list; 00272 res->next = NULL; 00273 list->versions = res; 00274 list->next = capabilities; 00275 capabilities = list; 00276 } 00277 return res; 00278 }
static int aji_get_roster | ( | struct aji_client * | client | ) | [static] |
Definition at line 1778 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().
01779 { 01780 iks *roster = NULL; 01781 roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER); 01782 if(roster) { 01783 iks_insert_attrib(roster, "id", "roster"); 01784 aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage); 01785 iks_send(client->p, roster); 01786 } 01787 if (roster) 01788 iks_delete(roster); 01789 return 1; 01790 }
static void aji_handle_iq | ( | struct aji_client * | client, | |
iks * | node | |||
) | [static] |
Handles <iq> tags.
client | structure and the iq node. |
Definition at line 1090 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 1100 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().
01101 { 01102 struct aji_message *insert, *tmp; 01103 int flag = 0; 01104 01105 if (!(insert = ast_calloc(1, sizeof(struct aji_message)))) 01106 return; 01107 time(&insert->arrived); 01108 if (iks_find_cdata(pak->x, "body")) 01109 insert->message = ast_strdup(iks_find_cdata(pak->x, "body")); 01110 if(pak->id) 01111 ast_copy_string(insert->id, pak->id, sizeof(insert->message)); 01112 if (pak->from) 01113 insert->from = ast_strdup(pak->from->full); 01114 AST_LIST_LOCK(&client->messages); 01115 AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) { 01116 if (flag) { 01117 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01118 if (tmp->from) 01119 free(tmp->from); 01120 if (tmp->message) 01121 free(tmp->message); 01122 } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) { 01123 flag = 1; 01124 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01125 if (tmp->from) 01126 free(tmp->from); 01127 if (tmp->message) 01128 free(tmp->message); 01129 } 01130 } 01131 AST_LIST_TRAVERSE_SAFE_END; 01132 AST_LIST_INSERT_HEAD(&client->messages, insert, list); 01133 AST_LIST_UNLOCK(&client->messages); 01134 }
static void aji_handle_presence | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 1136 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(), 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().
01137 { 01138 int status, priority; 01139 struct aji_buddy *buddy; 01140 struct aji_resource *tmp = NULL, *last = NULL, *found = NULL; 01141 char *ver, *node, *descrip, *type; 01142 01143 if(client->state != AJI_CONNECTED) 01144 aji_create_buddy(pak->from->partial, client); 01145 01146 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01147 if (!buddy) { 01148 ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial); 01149 return; 01150 } 01151 type = iks_find_attrib(pak->x, "type"); 01152 if(client->component && type &&!strcasecmp("probe", type)) { 01153 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01154 ast_verbose("what i was looking for \n"); 01155 } 01156 ASTOBJ_WRLOCK(buddy); 01157 status = (pak->show) ? pak->show : 6; 01158 priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0"); 01159 tmp = buddy->resources; 01160 descrip = ast_strdup(iks_find_cdata(pak->x,"status")); 01161 01162 while (tmp) { 01163 if (!strcasecmp(tmp->resource, pak->from->resource)) { 01164 tmp->status = status; 01165 if (tmp->description) free(tmp->description); 01166 tmp->description = descrip; 01167 found = tmp; 01168 if (status == 6) { /* Sign off Destroy resource */ 01169 if (last && found->next) { 01170 last->next = found->next; 01171 } else if (!last) { 01172 if (found->next) 01173 buddy->resources = found->next; 01174 else 01175 buddy->resources = NULL; 01176 } else if (!found->next) { 01177 if (last) 01178 last->next = NULL; 01179 else 01180 buddy->resources = NULL; 01181 } 01182 free(found); 01183 found = NULL; 01184 break; 01185 } 01186 if (tmp->priority != priority) { 01187 found->priority = priority; 01188 if (!last && !found->next) 01189 break; 01190 if (last) 01191 last->next = found->next; 01192 else 01193 buddy->resources = found->next; 01194 last = NULL; 01195 tmp = buddy->resources; 01196 if (!buddy->resources) 01197 buddy->resources = found; 01198 while (tmp) { 01199 if (found->priority > tmp->priority) { 01200 if (last) 01201 last->next = found; 01202 found->next = tmp; 01203 if (!last) 01204 buddy->resources = found; 01205 break; 01206 } 01207 if (!tmp->next) { 01208 tmp->next = found; 01209 break; 01210 } 01211 last = tmp; 01212 tmp = tmp->next; 01213 } 01214 } 01215 break; 01216 } 01217 last = tmp; 01218 tmp = tmp->next; 01219 } 01220 01221 if (!found && status != 6) { 01222 found = (struct aji_resource *) malloc(sizeof(struct aji_resource)); 01223 memset(found, 0, sizeof(struct aji_resource)); 01224 01225 if (!found) { 01226 ast_log(LOG_ERROR, "Out of memory!\n"); 01227 return; 01228 } 01229 ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource)); 01230 found->status = status; 01231 found->description = descrip; 01232 found->priority = priority; 01233 found->next = NULL; 01234 last = NULL; 01235 tmp = buddy->resources; 01236 while (tmp) { 01237 if (found->priority > tmp->priority) { 01238 if (last) 01239 last->next = found; 01240 found->next = tmp; 01241 if (!last) 01242 buddy->resources = found; 01243 break; 01244 } 01245 if (!tmp->next) { 01246 tmp->next = found; 01247 break; 01248 } 01249 last = tmp; 01250 tmp = tmp->next; 01251 } 01252 if (!tmp) 01253 buddy->resources = found; 01254 } 01255 ASTOBJ_UNLOCK(buddy); 01256 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01257 01258 node = iks_find_attrib(iks_find(pak->x, "c"), "node"); 01259 ver = iks_find_attrib(iks_find(pak->x, "c"), "ver"); 01260 01261 if(status !=6 && !found->cap) { 01262 found->cap = aji_find_version(node, ver, pak); 01263 if(gtalk_yuck(pak->x)) /* gtalk should do discover */ 01264 found->cap->jingle = 1; 01265 if(found->cap->jingle && option_debug > 4) 01266 ast_log(LOG_DEBUG,"Special case for google till they support discover.\n"); 01267 else { 01268 iks *iq, *query; 01269 iq = iks_new("iq"); 01270 query = iks_new("query"); 01271 if(query && iq) { 01272 iks_insert_attrib(iq, "type", "get"); 01273 iks_insert_attrib(iq, "to", pak->from->full); 01274 iks_insert_attrib(iq,"from",iks_find_attrib(pak->x,"to")); 01275 iks_insert_attrib(iq, "id", client->mid); 01276 ast_aji_increment_mid(client->mid); 01277 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01278 iks_insert_node(iq, query); 01279 iks_send(client->p, iq); 01280 01281 } else 01282 ast_log(LOG_ERROR, "Out of memory.\n"); 01283 if(query) 01284 iks_delete(query); 01285 if(iq) 01286 iks_delete(iq); 01287 } 01288 } 01289 if (option_verbose > 4) { 01290 switch (pak->subtype) { 01291 case IKS_TYPE_AVAILABLE: 01292 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am available ^_* %i\n", pak->subtype); 01293 break; 01294 case IKS_TYPE_UNAVAILABLE: 01295 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am unavailable ^_* %i\n", pak->subtype); 01296 break; 01297 default: 01298 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype); 01299 } 01300 switch (pak->show) { 01301 case IKS_SHOW_UNAVAILABLE: 01302 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01303 break; 01304 case IKS_SHOW_AVAILABLE: 01305 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is available\n"); 01306 break; 01307 case IKS_SHOW_CHAT: 01308 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01309 break; 01310 case IKS_SHOW_AWAY: 01311 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is away\n"); 01312 break; 01313 case IKS_SHOW_XA: 01314 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01315 break; 01316 case IKS_SHOW_DND: 01317 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01318 break; 01319 default: 01320 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Kinky! how did that happen %i\n", pak->show); 01321 } 01322 } 01323 }
static void aji_handle_subscribe | ( | struct aji_client * | client, | |
ikspak * | pak | |||
) | [static] |
handles subscription requests.
aji_client | struct and xml packet. |
Definition at line 1330 of file res_jabber.c.
References aji_set_presence(), ast_log(), ast_verbose(), 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().
01331 { 01332 if(pak->subtype == IKS_TYPE_SUBSCRIBE) { 01333 iks *presence = NULL, *status = NULL; 01334 presence = iks_new("presence"); 01335 status = iks_new("status"); 01336 if(presence && status) { 01337 iks_insert_attrib(presence, "type", "subscribed"); 01338 iks_insert_attrib(presence, "to", pak->from->full); 01339 iks_insert_attrib(presence, "from", client->jid->full); 01340 if(pak->id) 01341 iks_insert_attrib(presence, "id", pak->id); 01342 iks_insert_cdata(status, "Asterisk has approved subscription", 0); 01343 iks_insert_node(presence, status); 01344 iks_send(client->p, presence); 01345 } else 01346 ast_log(LOG_ERROR, "Unable to allocate nodes\n"); 01347 if(presence) 01348 iks_delete(presence); 01349 if(status) 01350 iks_delete(status); 01351 if(client->component) 01352 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01353 } 01354 if (option_verbose > 4) { 01355 switch (pak->subtype) { 01356 case IKS_TYPE_SUBSCRIBE: 01357 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01358 break; 01359 case IKS_TYPE_SUBSCRIBED: 01360 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01361 break; 01362 case IKS_TYPE_UNSUBSCRIBE: 01363 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01364 break; 01365 case IKS_TYPE_UNSUBSCRIBED: 01366 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01367 break; 01368 default: /*IKS_TYPE_ERROR: */ 01369 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01370 break; 01371 } 01372 } 01373 }
static int aji_highest_bit | ( | int | number | ) | [static] |
Detects the highest bit in a number.
Number | you want to have evaluated. |
Definition at line 307 of file res_jabber.c.
Referenced by aji_act_hook().
00308 { 00309 int x = sizeof(number) * 8 - 1; 00310 if (!number) 00311 return 0; 00312 for (; x > 0; x--) { 00313 if (number & (1 << x)) 00314 break; 00315 } 00316 return (1 << x); 00317 }
static int aji_load_config | ( | void | ) | [static] |
load config file.
void. |
Definition at line 2266 of file res_jabber.c.
References AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_create_client(), ast_category_browse(), ast_config_load(), ast_false(), ast_log(), ast_set2_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), debug, globalflags, JABBER_CONFIG, LOG_WARNING, and var.
Referenced by aji_reload().
02267 { 02268 char *cat = NULL; 02269 int debug = 1; 02270 struct ast_config *cfg = NULL; 02271 struct ast_variable *var = NULL; 02272 02273 cfg = ast_config_load(JABBER_CONFIG); 02274 if (!cfg) { 02275 ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG); 02276 return 0; 02277 } 02278 02279 cat = ast_category_browse(cfg, NULL); 02280 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { 02281 if (!strcasecmp(var->name, "debug")) 02282 debug = (ast_false(ast_variable_retrieve(cfg, "general", "debug"))) ? 0 : 1; 02283 else if (!strcasecmp(var->name, "autoprune")) 02284 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOPRUNE); 02285 else if (!strcasecmp(var->name, "autoregister")) 02286 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOREGISTER); 02287 } 02288 02289 while (cat) { 02290 if (strcasecmp(cat, "general")) { 02291 var = ast_variable_browse(cfg, cat); 02292 aji_create_client(cat, var, debug); 02293 } 02294 cat = ast_category_browse(cfg, cat); 02295 } 02296 return 1; 02297 }
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 446 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().
00447 { 00448 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00449 manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp); 00450 00451 if (client->debug) { 00452 if (is_incoming) 00453 ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp); 00454 else { 00455 if( strlen(xmpp) == 1) { 00456 if(option_debug > 2 && xmpp[0] == ' ') 00457 ast_verbose("\nJABBER: Keep alive packet\n"); 00458 } else 00459 ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp); 00460 } 00461 00462 } 00463 ASTOBJ_UNREF(client, aji_client_destroy); 00464 }
static int aji_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
turnoff console debugging.
fd,number | of args, args. |
Definition at line 1943 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01944 { 01945 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01946 ASTOBJ_RDLOCK(iterator); 01947 iterator->debug = 0; 01948 ASTOBJ_UNLOCK(iterator); 01949 }); 01950 ast_cli(fd, "Jabber Debugging Disabled.\n"); 01951 return RESULT_SUCCESS; 01952 }
static void aji_pruneregister | ( | struct aji_client * | client | ) | [static] |
attempts to register to a transport. attempts to register to a transport step 2. goes through roster and prunes users not needed in list, or adds them accordingly.
aji_client | struct. |
Definition at line 1633 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.
01634 { 01635 int res = 0; 01636 iks *removeiq = iks_new("iq"); 01637 iks *removequery = iks_new("query"); 01638 iks *removeitem = iks_new("item"); 01639 iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items"); 01640 01641 if (client && removeiq && removequery && removeitem && send) { 01642 iks_insert_node(removeiq, removequery); 01643 iks_insert_node(removequery, removeitem); 01644 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01645 ASTOBJ_RDLOCK(iterator); 01646 /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never 01647 * be called at the same time */ 01648 if (ast_test_flag(iterator, AJI_AUTOPRUNE)) { 01649 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name, 01650 "GoodBye your status is no longer needed by Asterisk the Open Source PBX" 01651 " so I am no longer subscribing to your presence.\n")); 01652 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name, 01653 "GoodBye you are no longer in the asterisk config file so I am removing" 01654 " your access to my presence.\n")); 01655 iks_insert_attrib(removeiq, "from", client->jid->full); 01656 iks_insert_attrib(removeiq, "type", "set"); 01657 iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster"); 01658 iks_insert_attrib(removeitem, "jid", iterator->name); 01659 iks_insert_attrib(removeitem, "subscription", "remove"); 01660 res = iks_send(client->p, removeiq); 01661 } else if (ast_test_flag(iterator, AJI_AUTOREGISTER)) { 01662 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name, 01663 "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n")); 01664 ast_clear_flag(iterator, AJI_AUTOREGISTER); 01665 } 01666 ASTOBJ_UNLOCK(iterator); 01667 }); 01668 } else 01669 ast_log(LOG_ERROR, "Out of memory.\n"); 01670 if (removeiq) 01671 iks_delete(removeiq); 01672 if (removequery) 01673 iks_delete(removequery); 01674 if (removeitem) 01675 iks_delete(removeitem); 01676 if (send) 01677 iks_delete(send); 01678 ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy); 01679 }
static int aji_reconnect | ( | struct aji_client * | client | ) | [static] |
Definition at line 1758 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().
01759 { 01760 int res = 0; 01761 01762 if (client->state) 01763 client->state = AJI_DISCONNECTED; 01764 client->timeout=50; 01765 if (client->p) 01766 iks_parser_reset(client->p); 01767 if (client->authorized) 01768 client->authorized = 0; 01769 01770 if(client->component) 01771 res = aji_component_initialize(client); 01772 else 01773 res = aji_client_initialize(client); 01774 01775 return res; 01776 }
static void * aji_recv_loop | ( | void * | data | ) | [static] |
receive message loop.
aji_client | struct. |
Definition at line 1488 of file res_jabber.c.
References aji_client_destroy(), AJI_CONNECTED, aji_reconnect(), ast_log(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, LOG_WARNING, option_verbose, aji_client::p, aji_client::state, and aji_client::timeout.
Referenced by aji_reload().
01489 { 01490 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01491 int res = IKS_HOOK; 01492 do { 01493 if (res != IKS_OK) { 01494 while(res != IKS_OK) { 01495 if(option_verbose > 3) 01496 ast_verbose("JABBER: reconnecting.\n"); 01497 res = aji_reconnect(client); 01498 sleep(4); 01499 } 01500 } 01501 01502 res = iks_recv(client->p, 1); 01503 client->timeout--; 01504 if (res == IKS_HOOK) 01505 ast_log(LOG_WARNING, "JABBER: Got hook event.\n"); 01506 else if (res == IKS_NET_TLSFAIL) 01507 ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n"); 01508 else if (client->timeout == 0 && client->state == AJI_CONNECTED) { 01509 res = iks_send_raw(client->p, " "); 01510 if(res == IKS_OK) 01511 client->timeout = 50; 01512 else 01513 ast_log(LOG_WARNING, "JABBER: Network Timeout\n"); 01514 } else if (res == IKS_NET_RWERR) 01515 ast_log(LOG_WARNING, "JABBER: socket read error\n"); 01516 } while (client); 01517 ASTOBJ_UNREF(client, aji_client_destroy); 01518 return 0; 01519 }
static int aji_register_approve_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 672 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().
00673 { 00674 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00675 iks *iq = NULL, *presence = NULL, *x = NULL; 00676 00677 iq = iks_new("iq"); 00678 presence = iks_new("presence"); 00679 x = iks_new("x"); 00680 if (client && iq && presence && x) { 00681 if (!iks_find(pak->query, "remove")) { 00682 iks_insert_attrib(iq, "from", client->jid->full); 00683 iks_insert_attrib(iq, "to", pak->from->full); 00684 iks_insert_attrib(iq, "id", pak->id); 00685 iks_insert_attrib(iq, "type", "result"); 00686 iks_send(client->p, iq); 00687 00688 iks_insert_attrib(presence, "from", client->jid->full); 00689 iks_insert_attrib(presence, "to", pak->from->partial); 00690 iks_insert_attrib(presence, "id", client->mid); 00691 ast_aji_increment_mid(client->mid); 00692 iks_insert_attrib(presence, "type", "subscribe"); 00693 iks_insert_attrib(x, "xmlns", "vcard-temp:x:update"); 00694 iks_insert_node(presence, x); 00695 iks_send(client->p, presence); 00696 } 00697 } else { 00698 ast_log(LOG_ERROR, "Out of memory.\n"); 00699 } 00700 00701 if (iq) 00702 iks_delete(iq); 00703 if(presence) 00704 iks_delete(presence); 00705 if (x) 00706 iks_delete(x); 00707 ASTOBJ_UNREF(client, aji_client_destroy); 00708 return IKS_FILTER_EAT; 00709 }
static int aji_register_query_handler | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 711 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().
00712 { 00713 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00714 struct aji_buddy *buddy = NULL; 00715 char *node = NULL; 00716 00717 client = (struct aji_client *) data; 00718 00719 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00720 if (!buddy) { 00721 ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial); 00722 iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL; 00723 iq = iks_new("iq"); 00724 query = iks_new("query"); 00725 error = iks_new("error"); 00726 notacceptable = iks_new("not-acceptable"); 00727 if(iq && query && error && notacceptable) { 00728 iks_insert_attrib(iq, "type", "error"); 00729 iks_insert_attrib(iq, "from", client->user); 00730 iks_insert_attrib(iq, "to", pak->from->full); 00731 iks_insert_attrib(iq, "id", pak->id); 00732 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00733 iks_insert_attrib(error, "code" , "406"); 00734 iks_insert_attrib(error, "type", "modify"); 00735 iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); 00736 iks_insert_node(iq, query); 00737 iks_insert_node(iq, error); 00738 iks_insert_node(error, notacceptable); 00739 iks_send(client->p, iq); 00740 } else { 00741 ast_log(LOG_ERROR, "Out of memory.\n"); 00742 } 00743 if (iq) 00744 iks_delete(iq); 00745 if (query) 00746 iks_delete(query); 00747 if (error) 00748 iks_delete(error); 00749 if (notacceptable) 00750 iks_delete(notacceptable); 00751 } else if (!(node = iks_find_attrib(pak->query, "node"))) { 00752 iks *iq = NULL, *query = NULL, *instructions = NULL; 00753 char *explain = "Welcome to Asterisk - the Open Source PBX.\n"; 00754 iq = iks_new("iq"); 00755 query = iks_new("query"); 00756 instructions = iks_new("instructions"); 00757 if (iq && query && instructions && client) { 00758 iks_insert_attrib(iq, "from", client->user); 00759 iks_insert_attrib(iq, "to", pak->from->full); 00760 iks_insert_attrib(iq, "id", pak->id); 00761 iks_insert_attrib(iq, "type", "result"); 00762 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00763 iks_insert_cdata(instructions, explain, 0); 00764 iks_insert_node(iq, query); 00765 iks_insert_node(query, instructions); 00766 iks_send(client->p, iq); 00767 } else { 00768 ast_log(LOG_ERROR, "Out of memory.\n"); 00769 } 00770 if (iq) 00771 iks_delete(iq); 00772 if (query) 00773 iks_delete(query); 00774 if (instructions) 00775 iks_delete(instructions); 00776 } 00777 ASTOBJ_UNREF(client, aji_client_destroy); 00778 return IKS_FILTER_EAT; 00779 }
static int aji_reload | ( | void | ) | [static] |
Definition at line 2368 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().
02369 { 02370 ASTOBJ_CONTAINER_MARKALL(&clients); 02371 if (!aji_load_config()) { 02372 ast_log(LOG_ERROR, "JABBER: Failed to load config.\n"); 02373 return 0; 02374 } 02375 ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy); 02376 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02377 ASTOBJ_RDLOCK(iterator); 02378 if(iterator->state == AJI_DISCONNECTED) { 02379 if (!iterator->thread) 02380 ast_pthread_create_background(&iterator->thread, NULL, aji_recv_loop, iterator); 02381 } else if (iterator->state == AJI_CONNECTING) 02382 aji_get_roster(iterator); 02383 ASTOBJ_UNLOCK(iterator); 02384 }); 02385 02386 return 1; 02387 }
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 410 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().
00411 { 00412 struct aji_client *client = NULL; 00413 00414 char *s = NULL, *sender = NULL, *recipient = NULL, *message = NULL; 00415 00416 if (!data) { 00417 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00418 return 0; 00419 } 00420 s = ast_strdupa(data); 00421 if (s) { 00422 sender = strsep(&s, "|"); 00423 if (sender && (sender[0] != '\0')) { 00424 recipient = strsep(&s, "|"); 00425 if (recipient && (recipient[0] != '\0')) { 00426 message = s; 00427 } else { 00428 ast_log(LOG_ERROR, "Bad arguments: %s\n", (char *) data); 00429 return -1; 00430 } 00431 } 00432 } 00433 if (!(client = ast_aji_get_client(sender))) { 00434 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00435 return -1; 00436 } 00437 if (strchr(recipient, '@') && message) 00438 ast_aji_send(client, recipient, message); 00439 return 0; 00440 }
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 1883 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().
01884 { 01885 int res = 0; 01886 iks *presence = iks_make_pres(level, desc); 01887 iks *cnode = iks_new("c"); 01888 iks *priority = iks_new("priority"); 01889 01890 iks_insert_cdata(priority, "0", 1); 01891 if (presence && cnode && client) { 01892 if(to) 01893 iks_insert_attrib(presence, "to", to); 01894 if(from) 01895 iks_insert_attrib(presence, "from", from); 01896 iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps"); 01897 iks_insert_attrib(cnode, "ver", "asterisk-xmpp"); 01898 iks_insert_attrib(cnode, "ext", "voice-v1"); 01899 iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps"); 01900 iks_insert_node(presence, cnode); 01901 res = iks_send(client->p, presence); 01902 } else 01903 ast_log(LOG_ERROR, "Out of memory.\n"); 01904 if (cnode) 01905 iks_delete(cnode); 01906 if (presence) 01907 iks_delete(presence); 01908 }
static int aji_show_clients | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
show client status.
fd,number | of args, args. |
Definition at line 1959 of file res_jabber.c.
References AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and clients.
01960 { 01961 char *status; 01962 int count = 0; 01963 ast_cli(fd, "Jabber Users and their status:\n"); 01964 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01965 ASTOBJ_RDLOCK(iterator); 01966 count++; 01967 switch (iterator->state) { 01968 case AJI_DISCONNECTED: 01969 status = "Disconnected"; 01970 break; 01971 case AJI_CONNECTING: 01972 status = "Connecting"; 01973 break; 01974 case AJI_CONNECTED: 01975 status = "Connected"; 01976 break; 01977 default: 01978 status = "Unknown"; 01979 } 01980 ast_cli(fd, " User: %s - %s\n", iterator->user, status); 01981 ASTOBJ_UNLOCK(iterator); 01982 }); 01983 ast_cli(fd, "----\n"); 01984 ast_cli(fd, " Number of users: %d\n", count); 01985 return RESULT_SUCCESS; 01986 }
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 346 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().
00347 { 00348 struct aji_client *client = NULL; 00349 struct aji_buddy *buddy = NULL; 00350 struct aji_resource *r = NULL; 00351 char *s = NULL, *sender = NULL, *jid = NULL, *screenname = NULL, *resource = NULL, *variable = NULL; 00352 int stat = 7; 00353 char status[2]; 00354 00355 if (!data) { 00356 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00357 return 0; 00358 } 00359 s = ast_strdupa(data); 00360 if (s) { 00361 sender = strsep(&s, "|"); 00362 if (sender && (sender[0] != '\0')) { 00363 jid = strsep(&s, "|"); 00364 if (jid && (jid[0] != '\0')) { 00365 variable = s; 00366 } else { 00367 ast_log(LOG_ERROR, "Bad arguments\n"); 00368 return -1; 00369 } 00370 } 00371 } 00372 00373 if(!strchr(jid, '/')) { 00374 resource = NULL; 00375 } else { 00376 screenname = strsep(&jid, "/"); 00377 resource = jid; 00378 } 00379 client = ast_aji_get_client(sender); 00380 if (!client) { 00381 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00382 return -1; 00383 } 00384 if(!&client->buddies) { 00385 ast_log(LOG_WARNING, "No buddies for connection : %s\n", sender); 00386 return -1; 00387 } 00388 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, resource ? screenname: jid); 00389 if (!buddy) { 00390 ast_log(LOG_WARNING, "Could not find buddy in list : %s\n", resource ? screenname : jid); 00391 return -1; 00392 } 00393 r = aji_find_resource(buddy, resource); 00394 if(!r && buddy->resources) 00395 r = buddy->resources; 00396 if(!r) 00397 ast_log(LOG_NOTICE, "Resource %s of buddy %s not found \n", resource, screenname); 00398 else 00399 stat = r->status; 00400 sprintf(status, "%d", stat); 00401 pbx_builtin_setvar_helper(chan, variable, status); 00402 return 0; 00403 }
static int aji_test | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
send test message for debugging.
fd,number | of args, args. |
Definition at line 1993 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.
01994 { 01995 struct aji_client *client; 01996 struct aji_resource *resource; 01997 const char *name = "asterisk"; 01998 struct aji_message *tmp; 01999 02000 if (argc > 3) 02001 return RESULT_SHOWUSAGE; 02002 else if (argc == 3) 02003 name = argv[2]; 02004 02005 if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) { 02006 ast_cli(fd, "Unable to find client '%s'!\n", name); 02007 return RESULT_FAILURE; 02008 } 02009 02010 /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */ 02011 ast_aji_send(client, "mogorman@astjab.org", "blahblah"); 02012 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 02013 ASTOBJ_RDLOCK(iterator); 02014 ast_verbose("User: %s\n", iterator->name); 02015 for (resource = iterator->resources; resource; resource = resource->next) { 02016 ast_verbose("Resource: %s\n", resource->resource); 02017 if(resource->cap) { 02018 ast_verbose(" client: %s\n", resource->cap->parent->node); 02019 ast_verbose(" version: %s\n", resource->cap->version); 02020 ast_verbose(" Jingle Capable: %d\n", resource->cap->jingle); 02021 } 02022 ast_verbose(" Priority: %d\n", resource->priority); 02023 ast_verbose(" Status: %d\n", resource->status); 02024 ast_verbose(" Message: %s\n", S_OR(resource->description,"")); 02025 } 02026 ASTOBJ_UNLOCK(iterator); 02027 }); 02028 ast_verbose("\nOooh a working message stack!\n"); 02029 AST_LIST_LOCK(&client->messages); 02030 AST_LIST_TRAVERSE(&client->messages, tmp, list) { 02031 ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, "")); 02032 } 02033 AST_LIST_UNLOCK(&client->messages); 02034 ASTOBJ_UNREF(client, aji_client_destroy); 02035 02036 return RESULT_SUCCESS; 02037 }
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 1404 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01405 { 01406 int res = 0; 01407 iks *iq = NULL; 01408 iq = iks_new("iq"); 01409 if (iq && client) { 01410 iks_insert_attrib(iq, "type", "get"); 01411 iks_insert_attrib(iq, "to", server); 01412 iks_insert_attrib(iq, "id", client->mid); 01413 ast_aji_increment_mid(client->mid); 01414 iks_send(client->p, iq); 01415 } else 01416 ast_log(LOG_ERROR, "Out of memory.\n"); 01417 return res; 01418 }
int ast_aji_disconnect | ( | struct aji_client * | client | ) |
disconnect from jabber server.
aji_client | struct. |
Definition at line 1865 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().
01866 { 01867 if (client) { 01868 if (option_verbose > 3) 01869 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Disconnecting\n"); 01870 iks_disconnect(client->p); 01871 iks_parser_delete(client->p); 01872 ASTOBJ_UNREF(client, aji_client_destroy); 01873 } 01874 01875 return 1; 01876 }
struct aji_client* ast_aji_get_client | ( | const char * | name | ) |
grab a aji_client structure by label name.
void. |
Definition at line 2304 of file res_jabber.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, clients, and aji_client::user.
Referenced by aji_send_exec(), aji_status_exec(), gtalk_create_member(), and manager_jabber_send().
02305 { 02306 struct aji_client *client = NULL; 02307 02308 client = ASTOBJ_CONTAINER_FIND(&clients, name); 02309 if (!client && !strchr(name, '@')) 02310 client = ASTOBJ_CONTAINER_FIND_FULL(&clients, name, user,,, strcasecmp); 02311 return client; 02312 }
struct aji_client_container* ast_aji_get_clients | ( | void | ) |
Definition at line 2314 of file res_jabber.c.
References clients.
02315 { 02316 return &clients; 02317 }
void ast_aji_increment_mid | ( | char * | mid | ) |
increments the mid field for messages and other events.
message | id. |
Definition at line 1526 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().
01527 { 01528 int i = 0; 01529 01530 for (i = strlen(mid) - 1; i >= 0; i--) { 01531 if (mid[i] != 'z') { 01532 mid[i] = mid[i] + 1; 01533 i = 0; 01534 } else 01535 mid[i] = 'a'; 01536 } 01537 }
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 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 *invite, *body, *namespace; 01457 01458 invite = iks_new("message"); 01459 body = iks_new("body"); 01460 namespace = iks_new("x"); 01461 if (client && invite && body && namespace) { 01462 iks_insert_attrib(invite, "to", user); 01463 iks_insert_attrib(invite, "id", client->mid); 01464 ast_aji_increment_mid(client->mid); 01465 iks_insert_cdata(body, message, 0); 01466 iks_insert_attrib(namespace, "xmlns", "jabber:x:conference"); 01467 iks_insert_attrib(namespace, "jid", room); 01468 iks_insert_node(invite, body); 01469 iks_insert_node(invite, namespace); 01470 res = iks_send(client->p, invite); 01471 } else 01472 ast_log(LOG_ERROR, "Out of memory.\n"); 01473 if (body) 01474 iks_delete(body); 01475 if (namespace) 01476 iks_delete(namespace); 01477 if (invite) 01478 iks_delete(invite); 01479 return res; 01480 }
int ast_aji_join_chat | ( | struct aji_client * | client, | |
char * | room | |||
) |
join a chatroom.
aji_client | struct , room. |
Definition at line 1425 of file res_jabber.c.
References ast_log(), LOG_ERROR, aji_client::p, and aji_resource::priority.
01426 { 01427 int res = 0; 01428 iks *presence = NULL, *priority = NULL; 01429 presence = iks_new("presence"); 01430 priority = iks_new("priority"); 01431 if (presence && priority && client) { 01432 iks_insert_cdata(priority, "0", 1); 01433 iks_insert_attrib(presence, "to", room); 01434 iks_insert_node(presence, priority); 01435 res = iks_send(client->p, presence); 01436 iks_insert_cdata(priority, "5", 1); 01437 iks_insert_attrib(presence, "to", room); 01438 res = iks_send(client->p, presence); 01439 } else 01440 ast_log(LOG_ERROR, "Out of memory.\n"); 01441 if (presence) 01442 iks_delete(presence); 01443 if (priority) 01444 iks_delete(priority); 01445 return res; 01446 }
int ast_aji_send | ( | struct aji_client * | client, | |
const char * | address, | |||
const char * | message | |||
) |
sends messages.
aji_client | struct , reciever, message. |
Definition at line 1380 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().
01381 { 01382 int res = 0; 01383 iks *message_packet = NULL; 01384 if (client->state == AJI_CONNECTED) { 01385 message_packet = iks_make_msg(IKS_TYPE_CHAT, address, message); 01386 if (message_packet) { 01387 iks_insert_attrib(message_packet, "from", client->jid->full); 01388 res = iks_send(client->p, message_packet); 01389 } else { 01390 ast_log(LOG_ERROR, "Out of memory.\n"); 01391 } 01392 if (message_packet) 01393 iks_delete(message_packet); 01394 } else 01395 ast_log(LOG_WARNING, "JABBER: Not connected can't send\n"); 01396 return 1; 01397 }
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 295 of file res_jabber.c.
Referenced by aji_handle_presence().
00296 { 00297 if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps")) 00298 return 1; 00299 return 0; 00300 }
static iks * jabber_make_auth | ( | iksid * | id, | |
const char * | pass, | |||
const char * | sid | |||
) | [static] |
Definition at line 319 of file res_jabber.c.
References ast_sha1_hash().
Referenced by aji_act_hook().
00320 { 00321 iks *x, *y; 00322 x = iks_new("iq"); 00323 iks_insert_attrib(x, "type", "set"); 00324 y = iks_insert(x, "query"); 00325 iks_insert_attrib(y, "xmlns", IKS_NS_AUTH); 00326 iks_insert_cdata(iks_insert(y, "username"), id->user, 0); 00327 iks_insert_cdata(iks_insert(y, "resource"), id->resource, 0); 00328 if (sid) { 00329 char buf[41]; 00330 char sidpass[100]; 00331 snprintf(sidpass, sizeof(sidpass), "%s%s", sid, pass); 00332 ast_sha1_hash(buf, sidpass); 00333 iks_insert_cdata(iks_insert(y, "digest"), buf, 0); 00334 } else { 00335 iks_insert_cdata(iks_insert(y, "password"), pass, 0); 00336 } 00337 return x; 00338 }
static int load_module | ( | void | ) | [static] |
Definition at line 2412 of file res_jabber.c.
References aji_cli, aji_reload(), aji_send_exec(), aji_status_exec(), ast_cli_register_multiple(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, ast_register_application(), ASTOBJ_CONTAINER_INIT, clients, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_jabber_send(), and mandescr_jabber_send.
02413 { 02414 ASTOBJ_CONTAINER_INIT(&clients); 02415 if(!aji_reload()) 02416 return AST_MODULE_LOAD_DECLINE; 02417 ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send, 02418 "Sends a message to a Jabber Client", mandescr_jabber_send); 02419 ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip); 02420 ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip); 02421 ast_cli_register_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02422 02423 ast_log(LOG_NOTICE, "res_jabber.so loaded.\n"); 02424 return 0; 02425 }
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 2327 of file res_jabber.c.
References ast_aji_get_client(), ast_aji_send(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), and s.
Referenced by load_module().
02328 { 02329 struct aji_client *client = NULL; 02330 const char *id = astman_get_header(m,"ActionID"); 02331 const char *jabber = astman_get_header(m,"Jabber"); 02332 const char *screenname = astman_get_header(m,"ScreenName"); 02333 const char *message = astman_get_header(m,"Message"); 02334 02335 if (ast_strlen_zero(jabber)) { 02336 astman_send_error(s, m, "No transport specified"); 02337 return 0; 02338 } 02339 if (ast_strlen_zero(screenname)) { 02340 astman_send_error(s, m, "No ScreenName specified"); 02341 return 0; 02342 } 02343 if (ast_strlen_zero(message)) { 02344 astman_send_error(s, m, "No Message specified"); 02345 return 0; 02346 } 02347 02348 astman_send_ack(s, m, "Attempting to send Jabber Message"); 02349 client = ast_aji_get_client(jabber); 02350 if (!client) { 02351 astman_send_error(s, m, "Could not find Sender"); 02352 return 0; 02353 } 02354 if (strchr(screenname, '@') && message){ 02355 ast_aji_send(client, screenname, message); 02356 if (!ast_strlen_zero(id)) 02357 astman_append(s, "ActionID: %s\r\n",id); 02358 astman_append(s, "Response: Success\r\n"); 02359 return 0; 02360 } 02361 if (!ast_strlen_zero(id)) 02362 astman_append(s, "ActionID: %s\r\n",id); 02363 astman_append(s, "Response: Failure\r\n"); 02364 return 0; 02365 }
static int reload | ( | void | ) | [static] |
Definition at line 2427 of file res_jabber.c.
References aji_reload().
02428 { 02429 aji_reload(); 02430 return 0; 02431 }
static int unload_module | ( | void | ) | [static] |
Definition at line 2389 of file res_jabber.c.
References aji_cli, aji_client_destroy(), AJI_DISCONNECTED, ast_aji_disconnect(), ast_cli_unregister_multiple(), ast_log(), ast_manager_unregister(), ast_unregister_application(), ast_verbose(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, LOG_NOTICE, option_verbose, and VERBOSE_PREFIX_3.
02390 { 02391 ast_cli_unregister_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02392 ast_unregister_application(app_ajisend); 02393 ast_unregister_application(app_ajistatus); 02394 ast_manager_unregister("JabberSend"); 02395 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02396 ASTOBJ_RDLOCK(iterator); 02397 if (option_verbose > 2) 02398 ast_verbose(VERBOSE_PREFIX_3 "JABBER: %s\n", iterator->name); 02399 iterator->state = AJI_DISCONNECTED; 02400 ast_aji_disconnect(iterator); 02401 pthread_join(iterator->thread, NULL); 02402 ASTOBJ_UNLOCK(iterator); 02403 }); 02404 02405 ASTOBJ_CONTAINER_DESTROYALL(&clients, aji_client_destroy); 02406 ASTOBJ_CONTAINER_DESTROY(&clients); 02407 02408 ast_log(LOG_NOTICE, "res_jabber unloaded.\n"); 02409 return 0; 02410 }
struct ast_cli_entry aji_cli[] [static] |
char* ajisend_descrip [static] |
Initial value:
"JabberSend(Jabber,ScreenName,Message)\n" " Jabber - Client or transport Asterisk uses to connect to Jabber\n" " ScreenName - User Name to message.\n" " Message - Message to be sent to the buddy\n"
Definition at line 143 of file res_jabber.c.
char* ajisend_synopsis = "JabberSend(jabber,screenname,message)" [static] |
Definition at line 141 of file res_jabber.c.
char* ajistatus_descrip [static] |
Definition at line 153 of file res_jabber.c.
char* ajistatus_synopsis = "JabberStatus(Jabber,ScreenName,Variable)" [static] |
Definition at line 151 of file res_jabber.c.
char* app_ajisend = "JabberSend" [static] |
Definition at line 139 of file res_jabber.c.
char* app_ajistatus = "JabberStatus" [static] |
Definition at line 149 of file res_jabber.c.
struct aji_capabilities* capabilities = NULL |
struct aji_client_container clients |
Definition at line 161 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 100 of file res_jabber.c.
struct ast_flags globalflags = { AJI_AUTOPRUNE | AJI_AUTOREGISTER } [static] |
char mandescr_jabber_send[] [static] |
char no_debug_usage[] [static] |
Initial value:
"Usage: jabber debug off\n" " Disables dumping of Jabber packets for debugging purposes.\n"
Definition at line 104 of file res_jabber.c.
char reload_usage[] [static] |
Initial value:
"Usage: jabber reload\n" " Enables reloading of Jabber module.\n"
Definition at line 108 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 112 of file res_jabber.c.