#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) |
| 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 |
| 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 459 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().
00460 { 00461 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00462 ikspak *pak = NULL; 00463 iks *auth = NULL; 00464 00465 if(!node) { 00466 ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */ 00467 ASTOBJ_UNREF(client, aji_client_destroy); 00468 return IKS_HOOK; 00469 } 00470 00471 pak = iks_packet(node); 00472 00473 if (!client->component) { /*client */ 00474 switch (type) { 00475 case IKS_NODE_START: 00476 if (client->usetls && !iks_is_secure(client->p)) { 00477 if (iks_has_tls()) 00478 iks_start_tls(client->p); 00479 else 00480 ast_log(LOG_ERROR, "gnuTLS not installed.\n"); 00481 break; 00482 } 00483 if (!client->usesasl) { 00484 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); 00485 auth = jabber_make_auth(client->jid, client->password, iks_find_attrib(node, "id")); 00486 if (auth) { 00487 iks_insert_attrib(auth, "id", client->mid); 00488 iks_insert_attrib(auth, "to", client->jid->server); 00489 ast_aji_increment_mid(client->mid); 00490 iks_send(client->p, auth); 00491 iks_delete(auth); 00492 } else 00493 ast_log(LOG_ERROR, "Out of memory.\n"); 00494 } 00495 break; 00496 00497 case IKS_NODE_NORMAL: 00498 { 00499 int features = 0; 00500 if (!strcmp("stream:features", iks_name(node))) { 00501 features = iks_stream_features(node); 00502 if (client->usesasl) { 00503 if (client->usetls && !iks_is_secure(client->p)) 00504 break; 00505 if (client->authorized) { 00506 if (features & IKS_STREAM_BIND) { 00507 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); 00508 auth = iks_make_resource_bind(client->jid); 00509 if (auth) { 00510 iks_insert_attrib(auth, "id", client->mid); 00511 ast_aji_increment_mid(client->mid); 00512 iks_send(client->p, auth); 00513 iks_delete(auth); 00514 } else { 00515 ast_log(LOG_ERROR, "Out of memory.\n"); 00516 break; 00517 } 00518 } 00519 if (features & IKS_STREAM_SESSION) { 00520 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); 00521 auth = iks_make_session(); 00522 if (auth) { 00523 iks_insert_attrib(auth, "id", "auth"); 00524 ast_aji_increment_mid(client->mid); 00525 iks_send(client->p, auth); 00526 iks_delete(auth); 00527 } else { 00528 ast_log(LOG_ERROR, "Out of memory.\n"); 00529 } 00530 } 00531 } else { 00532 features = aji_highest_bit(features); 00533 if (features == IKS_STREAM_SASL_MD5) 00534 iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, client->jid->user, client->password); 00535 else { 00536 if (features == IKS_STREAM_SASL_PLAIN) { 00537 iks *x = NULL; 00538 x = iks_new("auth"); 00539 if (x) { 00540 iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL); 00541 int len = strlen(client->jid->user) + strlen(client->password) + 3; 00542 /* XXX Check return values XXX */ 00543 char *s = ast_malloc(80 + len); 00544 char *base64 = ast_malloc(80 + len * 2); 00545 iks_insert_attrib(x, "mechanism", "PLAIN"); 00546 sprintf(s, "%c%s%c%s", 0, client->jid->user, 0, client->password); 00547 ast_base64encode(base64, (const unsigned char *) s, len, len * 2); 00548 iks_insert_cdata(x, base64, 0); 00549 iks_send(client->p, x); 00550 iks_delete(x); 00551 if (base64) 00552 free(base64); 00553 if (s) 00554 free(s); 00555 } else { 00556 ast_log(LOG_ERROR, "Out of memory.\n"); 00557 } 00558 } 00559 } 00560 } 00561 } 00562 } else if (!strcmp("failure", iks_name(node))) { 00563 ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n"); 00564 } else if (!strcmp("success", iks_name(node))) { 00565 client->authorized = 1; 00566 iks_send_header(client->p, client->jid->server); 00567 } 00568 break; 00569 } 00570 case IKS_NODE_ERROR: 00571 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00572 ASTOBJ_UNREF(client, aji_client_destroy); 00573 return IKS_HOOK; 00574 break; 00575 case IKS_NODE_STOP: 00576 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00577 ASTOBJ_UNREF(client, aji_client_destroy); 00578 return IKS_HOOK; 00579 break; 00580 } 00581 } else if (client->state != AJI_CONNECTED && client->component) { 00582 switch (type) { 00583 case IKS_NODE_START: 00584 if (client->state == AJI_DISCONNECTED) { 00585 char secret[160], shasum[320], *handshake; 00586 00587 sprintf(secret, "%s%s", pak->id, client->password); 00588 ast_sha1_hash(shasum, secret); 00589 handshake = NULL; 00590 asprintf(&handshake, "<handshake>%s</handshake>", shasum); 00591 if (handshake) { 00592 iks_send_raw(client->p, handshake); 00593 free(handshake); 00594 handshake = NULL; 00595 } 00596 client->state = AJI_CONNECTING; 00597 if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/ 00598 client->state = AJI_CONNECTED; 00599 else 00600 ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n"); 00601 break; 00602 } 00603 break; 00604 00605 case IKS_NODE_NORMAL: 00606 break; 00607 00608 case IKS_NODE_ERROR: 00609 ast_log(LOG_ERROR, "JABBER: Node Error\n"); 00610 ASTOBJ_UNREF(client, aji_client_destroy); 00611 return IKS_HOOK; 00612 00613 case IKS_NODE_STOP: 00614 ast_log(LOG_WARNING, "JABBER: Disconnected\n"); 00615 ASTOBJ_UNREF(client, aji_client_destroy); 00616 return IKS_HOOK; 00617 } 00618 } 00619 00620 switch (pak->type) { 00621 case IKS_PAK_NONE: 00622 if (option_debug) 00623 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n"); 00624 break; 00625 case IKS_PAK_MESSAGE: 00626 aji_handle_message(client, pak); 00627 if (option_debug) 00628 ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n"); 00629 break; 00630 case IKS_PAK_PRESENCE: 00631 aji_handle_presence(client, pak); 00632 if (option_debug) 00633 ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n"); 00634 break; 00635 case IKS_PAK_S10N: 00636 aji_handle_subscribe(client, pak); 00637 if (option_debug) 00638 ast_log(LOG_DEBUG, "JABBER: I Dont know S10N subscribe!!\n"); 00639 break; 00640 case IKS_PAK_IQ: 00641 if (option_debug) 00642 ast_log(LOG_DEBUG, "JABBER: I Dont have an IQ!!!\n"); 00643 aji_handle_iq(client, node); 00644 break; 00645 default: 00646 if (option_debug) 00647 ast_log(LOG_DEBUG, "JABBER: I Dont know %i\n", pak->type); 00648 break; 00649 } 00650 00651 iks_filter_packet(client->f, pak); 00652 00653 if (node) 00654 iks_delete(node); 00655 00656 ASTOBJ_UNREF(client, aji_client_destroy); 00657 return IKS_OK; 00658 }
| 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 1785 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().
01786 { 01787 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01788 int res = 0; 01789 01790 if (client) { 01791 if (client->state == AJI_DISCONNECTED) { 01792 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); 01793 client->state = AJI_CONNECTING; 01794 client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid; 01795 iks_filter_remove_hook(client->f, aji_client_connect); 01796 if(!client->component) /*client*/ 01797 aji_get_roster(client); 01798 } 01799 } else 01800 ast_log(LOG_ERROR, "Out of memory.\n"); 01801 01802 ASTOBJ_UNREF(client, aji_client_destroy); 01803 return res; 01804 }
| 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 865 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().
00866 { 00867 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00868 struct aji_resource *resource = NULL; 00869 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00870 00871 resource = aji_find_resource(buddy, pak->from->resource); 00872 if (pak->subtype == IKS_TYPE_RESULT) { 00873 if (!resource) { 00874 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00875 ASTOBJ_UNREF(client, aji_client_destroy); 00876 return IKS_FILTER_EAT; 00877 } 00878 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00879 resource->cap->jingle = 1; 00880 } else 00881 resource->cap->jingle = 0; 00882 } else if (pak->subtype == IKS_TYPE_GET) { 00883 iks *iq, *disco, *ident, *google, *query; 00884 iq = iks_new("iq"); 00885 query = iks_new("query"); 00886 ident = iks_new("identity"); 00887 disco = iks_new("feature"); 00888 google = iks_new("feature"); 00889 if (iq && ident && disco && google) { 00890 iks_insert_attrib(iq, "from", client->jid->full); 00891 iks_insert_attrib(iq, "to", pak->from->full); 00892 iks_insert_attrib(iq, "type", "result"); 00893 iks_insert_attrib(iq, "id", pak->id); 00894 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00895 iks_insert_attrib(ident, "category", "client"); 00896 iks_insert_attrib(ident, "type", "pc"); 00897 iks_insert_attrib(ident, "name", "asterisk"); 00898 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info"); 00899 iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1"); 00900 iks_insert_node(iq, query); 00901 iks_insert_node(query, ident); 00902 iks_insert_node(query, google); 00903 iks_insert_node(query, disco); 00904 iks_send(client->p, iq); 00905 } else 00906 ast_log(LOG_ERROR, "Out of Memory.\n"); 00907 if (iq) 00908 iks_delete(iq); 00909 if (query) 00910 iks_delete(query); 00911 if (ident) 00912 iks_delete(ident); 00913 if (google) 00914 iks_delete(google); 00915 if (disco) 00916 iks_delete(disco); 00917 } else if (pak->subtype == IKS_TYPE_ERROR) { 00918 ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full); 00919 } 00920 ASTOBJ_UNREF(client, aji_client_destroy); 00921 return IKS_FILTER_EAT; 00922 }
| static int aji_client_initialize | ( | struct aji_client * | client | ) | [static] |
prepares client for connect.
| aji_client | struct. |
Definition at line 1811 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().
01812 { 01813 int connected = 0; 01814 01815 connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server); 01816 01817 if (connected == IKS_NET_NOCONN) { 01818 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01819 return IKS_HOOK; 01820 } else if (connected == IKS_NET_NODNS) { 01821 ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server)); 01822 return IKS_HOOK; 01823 } else 01824 iks_recv(client->p, 30); 01825 return IKS_OK; 01826 }
| static int aji_component_initialize | ( | struct aji_client * | client | ) | [static] |
prepares component for connect.
| aji_client | struct. |
Definition at line 1833 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().
01834 { 01835 int connected = 1; 01836 connected = iks_connect_via(client->p, client->jid->server, client->port, client->user); 01837 if (connected == IKS_NET_NOCONN) { 01838 ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n"); 01839 return IKS_HOOK; 01840 } else if (connected == IKS_NET_NODNS) { 01841 ast_log(LOG_ERROR, "JABBER ERROR: No DNS\n"); 01842 return IKS_HOOK; 01843 } else if (!connected) 01844 iks_recv(client->p, 30); 01845 return IKS_OK; 01846 }
| 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 2222 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().
02223 { 02224 struct aji_buddy *buddy = NULL; 02225 int flag = 0; 02226 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label); 02227 if (!buddy) { 02228 flag = 1; 02229 buddy = malloc(sizeof(struct aji_buddy)); 02230 if(!buddy) { 02231 ast_log(LOG_WARNING, "Out of memory\n"); 02232 return 0; 02233 } 02234 memset(buddy, 0, sizeof(struct aji_buddy)); 02235 ASTOBJ_INIT(buddy); 02236 } 02237 ASTOBJ_WRLOCK(buddy); 02238 ast_copy_string(buddy->name, label, sizeof(buddy->name)); 02239 ASTOBJ_UNLOCK(buddy); 02240 if(flag) 02241 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 02242 else { 02243 ASTOBJ_UNMARK(buddy); 02244 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 02245 } 02246 return 1; 02247 }
| 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 2032 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().
02033 { 02034 char *resource; 02035 struct aji_client *client = NULL; 02036 int flag = 0; 02037 02038 client = ASTOBJ_CONTAINER_FIND(&clients,label); 02039 if (!client) { 02040 flag = 1; 02041 client = (struct aji_client *) malloc(sizeof(struct aji_client)); 02042 if (!client) { 02043 ast_log(LOG_ERROR, "Out of memory!\n"); 02044 return 0; 02045 } 02046 memset(client, 0, sizeof(struct aji_client)); 02047 ASTOBJ_INIT(client); 02048 ASTOBJ_WRLOCK(client); 02049 ASTOBJ_CONTAINER_INIT(&client->buddies); 02050 } else { 02051 ASTOBJ_WRLOCK(client); 02052 ASTOBJ_UNMARK(client); 02053 } 02054 ASTOBJ_CONTAINER_MARKALL(&client->buddies); 02055 ast_copy_string(client->name, label, sizeof(client->name)); 02056 ast_copy_string(client->mid, "aaaaa", sizeof(client->mid)); 02057 02058 client->debug = debug; 02059 ast_copy_flags(client, &globalflags, AST_FLAGS_ALL); 02060 client->port = 5222; 02061 client->usetls = 1; 02062 client->usesasl = 1; 02063 client->forcessl = 0; 02064 client->keepalive = 1; 02065 client->timeout = 50; 02066 client->message_timeout = 100; 02067 AST_LIST_HEAD_INIT(&client->messages); 02068 client->component = 0; 02069 ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage)); 02070 02071 if (flag) { 02072 client->authorized = 0; 02073 client->state = AJI_DISCONNECTED; 02074 } 02075 while (var) { 02076 if (!strcasecmp(var->name, "username")) 02077 ast_copy_string(client->user, var->value, sizeof(client->user)); 02078 else if (!strcasecmp(var->name, "serverhost")) 02079 ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost)); 02080 else if (!strcasecmp(var->name, "secret")) 02081 ast_copy_string(client->password, var->value, sizeof(client->password)); 02082 else if (!strcasecmp(var->name, "statusmessage")) 02083 ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage)); 02084 else if (!strcasecmp(var->name, "port")) 02085 client->port = atoi(var->value); 02086 else if (!strcasecmp(var->name, "timeout")) 02087 client->message_timeout = atoi(var->value); 02088 else if (!strcasecmp(var->name, "debug")) 02089 client->debug = (ast_false(var->value)) ? 0 : 1; 02090 else if (!strcasecmp(var->name, "type")) { 02091 if (!strcasecmp(var->value, "component")) 02092 client->component = 1; 02093 } else if (!strcasecmp(var->name, "usetls")) { 02094 client->usetls = (ast_false(var->value)) ? 0 : 1; 02095 } else if (!strcasecmp(var->name, "usesasl")) { 02096 client->usesasl = (ast_false(var->value)) ? 0 : 1; 02097 } else if (!strcasecmp(var->name, "forceoldssl")) 02098 client->forcessl = (ast_false(var->value)) ? 0 : 1; 02099 else if (!strcasecmp(var->name, "keepalive")) 02100 client->keepalive = (ast_false(var->value)) ? 0 : 1; 02101 else if (!strcasecmp(var->name, "autoprune")) 02102 ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE); 02103 else if (!strcasecmp(var->name, "autoregister")) 02104 ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER); 02105 else if (!strcasecmp(var->name, "buddy")) 02106 aji_create_buddy(var->value, client); 02107 /* no transport support in this version */ 02108 /* else if (!strcasecmp(var->name, "transport")) 02109 aji_create_transport(var->value, client); 02110 */ 02111 var = var->next; 02112 } 02113 if (!flag) { 02114 ASTOBJ_UNLOCK(client); 02115 ASTOBJ_UNREF(client, aji_client_destroy); 02116 return 1; 02117 } 02118 client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook); 02119 if (!client->p) { 02120 ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name); 02121 return 0; 02122 } 02123 client->stack = iks_stack_new(8192, 8192); 02124 if (!client->stack) { 02125 ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name); 02126 return 0; 02127 } 02128 client->f = iks_filter_new(); 02129 if (!client->f) { 02130 ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name); 02131 return 0; 02132 } 02133 if (!strchr(client->user, '/') && !client->component) { /*client */ 02134 resource = NULL; 02135 asprintf(&resource, "%s/asterisk", client->user); 02136 if (resource) { 02137 client->jid = iks_id_new(client->stack, resource); 02138 free(resource); 02139 } 02140 } else 02141 client->jid = iks_id_new(client->stack, client->user); 02142 if (client->component) { 02143 iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02144 iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE); 02145 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); 02146 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); 02147 } else { 02148 iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE); 02149 } 02150 if (!strchr(client->user, '/') && !client->component) { /*client */ 02151 resource = NULL; 02152 asprintf(&resource, "%s/asterisk", client->user); 02153 if (resource) { 02154 client->jid = iks_id_new(client->stack, resource); 02155 free(resource); 02156 } 02157 } else 02158 client->jid = iks_id_new(client->stack, client->user); 02159 iks_set_log_hook(client->p, aji_log_hook); 02160 ASTOBJ_UNLOCK(client); 02161 ASTOBJ_CONTAINER_LINK(&clients,client); 02162 return 1; 02163 }
| static int aji_dinfo_handler | ( | void * | data, | |
| ikspak * | pak | |||
| ) | [static] |
Definition at line 924 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().
00925 { 00926 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00927 char *node = NULL; 00928 struct aji_resource *resource = NULL; 00929 struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00930 00931 resource = aji_find_resource(buddy, pak->from->resource); 00932 if (pak->subtype == IKS_TYPE_ERROR) { 00933 ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n"); 00934 return IKS_FILTER_EAT; 00935 } 00936 if (pak->subtype == IKS_TYPE_RESULT) { 00937 if (!resource) { 00938 ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full); 00939 ASTOBJ_UNREF(client, aji_client_destroy); 00940 return IKS_FILTER_EAT; 00941 } 00942 if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) { 00943 resource->cap->jingle = 1; 00944 } else 00945 resource->cap->jingle = 0; 00946 } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) { 00947 iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search; 00948 00949 iq = iks_new("iq"); 00950 query = iks_new("query"); 00951 identity = iks_new("identity"); 00952 disco = iks_new("feature"); 00953 reg = iks_new("feature"); 00954 commands = iks_new("feature"); 00955 gateway = iks_new("feature"); 00956 version = iks_new("feature"); 00957 vcard = iks_new("feature"); 00958 search = iks_new("feature"); 00959 00960 if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) { 00961 iks_insert_attrib(iq, "from", client->user); 00962 iks_insert_attrib(iq, "to", pak->from->full); 00963 iks_insert_attrib(iq, "id", pak->id); 00964 iks_insert_attrib(iq, "type", "result"); 00965 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 00966 iks_insert_attrib(identity, "category", "gateway"); 00967 iks_insert_attrib(identity, "type", "pstn"); 00968 iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX"); 00969 iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco"); 00970 iks_insert_attrib(reg, "var", "jabber:iq:register"); 00971 iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands"); 00972 iks_insert_attrib(gateway, "var", "jabber:iq:gateway"); 00973 iks_insert_attrib(version, "var", "jabber:iq:version"); 00974 iks_insert_attrib(vcard, "var", "vcard-temp"); 00975 iks_insert_attrib(search, "var", "jabber:iq:search"); 00976 00977 iks_insert_node(iq, query); 00978 iks_insert_node(query, identity); 00979 iks_insert_node(query, disco); 00980 iks_insert_node(query, reg); 00981 iks_insert_node(query, commands); 00982 iks_insert_node(query, gateway); 00983 iks_insert_node(query, version); 00984 iks_insert_node(query, vcard); 00985 iks_insert_node(query, search); 00986 iks_send(client->p, iq); 00987 } else { 00988 ast_log(LOG_ERROR, "Out of memory.\n"); 00989 } 00990 00991 if (iq) 00992 iks_delete(iq); 00993 if (query) 00994 iks_delete(query); 00995 if (identity) 00996 iks_delete(identity); 00997 if (disco) 00998 iks_delete(disco); 00999 if (reg) 01000 iks_delete(reg); 01001 if (commands) 01002 iks_delete(commands); 01003 if (gateway) 01004 iks_delete(gateway); 01005 if (version) 01006 iks_delete(version); 01007 if (vcard) 01008 iks_delete(vcard); 01009 if (search) 01010 iks_delete(search); 01011 01012 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) { 01013 iks *iq, *query, *confirm; 01014 iq = iks_new("iq"); 01015 query = iks_new("query"); 01016 confirm = iks_new("item"); 01017 01018 if (iq && query && confirm && client) { 01019 iks_insert_attrib(iq, "from", client->user); 01020 iks_insert_attrib(iq, "to", pak->from->full); 01021 iks_insert_attrib(iq, "id", pak->id); 01022 iks_insert_attrib(iq, "type", "result"); 01023 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 01024 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 01025 iks_insert_attrib(confirm, "node", "confirmaccount"); 01026 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 01027 iks_insert_attrib(confirm, "jid", client->user); 01028 iks_insert_node(iq, query); 01029 iks_insert_node(query, confirm); 01030 iks_send(client->p, iq); 01031 } else { 01032 ast_log(LOG_ERROR, "Out of memory.\n"); 01033 } 01034 if (iq) 01035 iks_delete(iq); 01036 if (query) 01037 iks_delete(query); 01038 if (confirm) 01039 iks_delete(confirm); 01040 01041 } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) { 01042 iks *iq, *query, *feature; 01043 01044 iq = iks_new("iq"); 01045 query = iks_new("query"); 01046 feature = iks_new("feature"); 01047 01048 if (iq && query && feature && client) { 01049 iks_insert_attrib(iq, "from", client->user); 01050 iks_insert_attrib(iq, "to", pak->from->full); 01051 iks_insert_attrib(iq, "id", pak->id); 01052 iks_insert_attrib(iq, "type", "result"); 01053 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01054 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 01055 iks_insert_node(iq, query); 01056 iks_insert_node(query, feature); 01057 iks_send(client->p, iq); 01058 } else { 01059 ast_log(LOG_ERROR, "Out of memory.\n"); 01060 } 01061 if (iq) 01062 iks_delete(iq); 01063 if (query) 01064 iks_delete(query); 01065 if (feature) 01066 iks_delete(feature); 01067 } 01068 01069 ASTOBJ_UNREF(client, aji_client_destroy); 01070 return IKS_FILTER_EAT; 01071 }
| static int aji_ditems_handler | ( | void * | data, | |
| ikspak * | pak | |||
| ) | [static] |
Definition at line 769 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().
00770 { 00771 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00772 char *node = NULL; 00773 00774 if (!(node = iks_find_attrib(pak->query, "node"))) { 00775 iks *iq = NULL, *query = NULL, *item = NULL; 00776 iq = iks_new("iq"); 00777 query = iks_new("query"); 00778 item = iks_new("item"); 00779 00780 if (iq && query && item) { 00781 iks_insert_attrib(iq, "from", client->user); 00782 iks_insert_attrib(iq, "to", pak->from->full); 00783 iks_insert_attrib(iq, "id", pak->id); 00784 iks_insert_attrib(iq, "type", "result"); 00785 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00786 iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands"); 00787 iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands"); 00788 iks_insert_attrib(item, "jid", client->user); 00789 00790 iks_insert_node(iq, query); 00791 iks_insert_node(query, item); 00792 iks_send(client->p, iq); 00793 } else { 00794 ast_log(LOG_ERROR, "Out of memory.\n"); 00795 } 00796 if (iq) 00797 iks_delete(iq); 00798 if (query) 00799 iks_delete(query); 00800 if (item) 00801 iks_delete(item); 00802 00803 } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) { 00804 iks *iq, *query, *confirm; 00805 iq = iks_new("iq"); 00806 query = iks_new("query"); 00807 confirm = iks_new("item"); 00808 if (iq && query && confirm && client) { 00809 iks_insert_attrib(iq, "from", client->user); 00810 iks_insert_attrib(iq, "to", pak->from->full); 00811 iks_insert_attrib(iq, "id", pak->id); 00812 iks_insert_attrib(iq, "type", "result"); 00813 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00814 iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands"); 00815 iks_insert_attrib(confirm, "node", "confirmaccount"); 00816 iks_insert_attrib(confirm, "name", "Confirm AIM account"); 00817 iks_insert_attrib(confirm, "jid", "blog.astjab.org"); 00818 00819 iks_insert_node(iq, query); 00820 iks_insert_node(query, confirm); 00821 iks_send(client->p, iq); 00822 } else { 00823 ast_log(LOG_ERROR, "Out of memory.\n"); 00824 } 00825 if (iq) 00826 iks_delete(iq); 00827 if (query) 00828 iks_delete(query); 00829 if (confirm) 00830 iks_delete(confirm); 00831 00832 } else if (!strcasecmp(node, "confirmaccount")) { 00833 iks *iq = NULL, *query = NULL, *feature = NULL; 00834 00835 iq = iks_new("iq"); 00836 query = iks_new("query"); 00837 feature = iks_new("feature"); 00838 00839 if (iq && query && feature && client) { 00840 iks_insert_attrib(iq, "from", client->user); 00841 iks_insert_attrib(iq, "to", pak->from->full); 00842 iks_insert_attrib(iq, "id", pak->id); 00843 iks_insert_attrib(iq, "type", "result"); 00844 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items"); 00845 iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands"); 00846 iks_insert_node(iq, query); 00847 iks_insert_node(query, feature); 00848 iks_send(client->p, iq); 00849 } else { 00850 ast_log(LOG_ERROR, "Out of memory.\n"); 00851 } 00852 if (iq) 00853 iks_delete(iq); 00854 if (query) 00855 iks_delete(query); 00856 if (feature) 00857 iks_delete(feature); 00858 } 00859 00860 ASTOBJ_UNREF(client, aji_client_destroy); 00861 return IKS_FILTER_EAT; 00862 00863 }
| static int aji_do_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
turnon console debugging.
| fd,number | of args, args. |
Definition at line 1903 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01904 { 01905 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01906 ASTOBJ_RDLOCK(iterator); 01907 iterator->debug = 1; 01908 ASTOBJ_UNLOCK(iterator); 01909 }); 01910 ast_cli(fd, "Jabber Debugging Enabled.\n"); 01911 return RESULT_SUCCESS; 01912 }
| static int aji_do_reload | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
reload jabber module.
| fd,number | of args, args. |
Definition at line 1919 of file res_jabber.c.
References aji_reload(), ast_cli(), and RESULT_SUCCESS.
01920 { 01921 aji_reload(); 01922 ast_cli(fd, "Jabber Reloaded.\n"); 01923 return RESULT_SUCCESS; 01924 }
| 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 1674 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().
01675 { 01676 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01677 int flag = 0; 01678 iks *x = NULL; 01679 struct aji_buddy *buddy; 01680 01681 client->state = AJI_CONNECTED; 01682 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01683 ASTOBJ_RDLOCK(iterator); 01684 x = iks_child(pak->query); 01685 flag = 0; 01686 while (x) { 01687 if (!iks_strcmp(iks_name(x), "item")) { 01688 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) { 01689 flag = 1; 01690 ast_clear_flag(iterator, AJI_AUTOPRUNE | AJI_AUTOREGISTER); 01691 } 01692 } 01693 x = iks_next(x); 01694 } 01695 if (!flag) 01696 ast_copy_flags(iterator, client, AJI_AUTOREGISTER); 01697 if (x) 01698 iks_delete(x); 01699 ASTOBJ_UNLOCK(iterator); 01700 }); 01701 01702 x = iks_child(pak->query); 01703 while (x) { 01704 flag = 0; 01705 if (iks_strcmp(iks_name(x), "item") == 0) { 01706 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01707 ASTOBJ_RDLOCK(iterator); 01708 if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) 01709 flag = 1; 01710 ASTOBJ_UNLOCK(iterator); 01711 }); 01712 01713 if (!flag) { 01714 buddy = (struct aji_buddy *) malloc(sizeof(struct aji_buddy)); 01715 if (!buddy) { 01716 ast_log(LOG_WARNING, "Out of memory\n"); 01717 return 0; 01718 } 01719 memset(buddy, 0, sizeof(struct aji_buddy)); 01720 ASTOBJ_INIT(buddy); 01721 ASTOBJ_WRLOCK(buddy); 01722 ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name)); 01723 ast_clear_flag(buddy, AST_FLAGS_ALL); 01724 if(ast_test_flag(client, AJI_AUTOPRUNE)) { 01725 ast_set_flag(buddy, AJI_AUTOPRUNE); 01726 buddy->objflags |= ASTOBJ_FLAG_MARKED; 01727 } else 01728 ast_set_flag(buddy, AJI_AUTOREGISTER); 01729 ASTOBJ_UNLOCK(buddy); 01730 if (buddy) { 01731 ASTOBJ_CONTAINER_LINK(&client->buddies, buddy); 01732 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01733 } 01734 } 01735 } 01736 x = iks_next(x); 01737 } 01738 if (x) 01739 iks_delete(x); 01740 aji_pruneregister(client); 01741 01742 ASTOBJ_UNREF(client, aji_client_destroy); 01743 return IKS_FILTER_EAT; 01744 }
| static struct aji_resource* aji_find_resource | ( | struct aji_buddy * | buddy, | |
| char * | name | |||
| ) | [static] |
Definition at line 268 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().
00269 { 00270 struct aji_resource *res = NULL; 00271 if (!buddy || !name) 00272 return res; 00273 res = buddy->resources; 00274 while (res) { 00275 if (!strcasecmp(res->resource, name)) { 00276 break; 00277 } 00278 res = res->next; 00279 } 00280 return res; 00281 }
| static struct aji_version* aji_find_version | ( | char * | node, | |
| char * | version, | |||
| ikspak * | pak | |||
| ) | [static] |
Definition at line 210 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().
00211 { 00212 struct aji_capabilities *list = NULL; 00213 struct aji_version *res = NULL; 00214 00215 list = capabilities; 00216 00217 if(!node) 00218 node = pak->from->full; 00219 if(!version) 00220 version = "none supplied."; 00221 while(list) { 00222 if(!strcasecmp(list->node, node)) { 00223 res = list->versions; 00224 while(res) { 00225 if(!strcasecmp(res->version, version)) 00226 return res; 00227 res = res->next; 00228 } 00229 if(!res) { 00230 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00231 if(!res) { 00232 ast_log(LOG_ERROR, "Out of memory!\n"); 00233 return NULL; 00234 } 00235 res->jingle = 0; 00236 res->parent = list; 00237 ast_copy_string(res->version, version, sizeof(res->version)); 00238 res->next = list->versions; 00239 list->versions = res; 00240 return res; 00241 } 00242 } 00243 list = list->next; 00244 } 00245 if(!list) { 00246 list = (struct aji_capabilities *)malloc(sizeof(struct aji_capabilities)); 00247 if(!list) { 00248 ast_log(LOG_ERROR, "Out of memory!\n"); 00249 return NULL; 00250 } 00251 res = (struct aji_version *)malloc(sizeof(struct aji_version)); 00252 if(!res) { 00253 ast_log(LOG_ERROR, "Out of memory!\n"); 00254 return NULL; 00255 } 00256 ast_copy_string(list->node, node, sizeof(list->node)); 00257 ast_copy_string(res->version, version, sizeof(res->version)); 00258 res->jingle = 0; 00259 res->parent = list; 00260 res->next = list->versions; 00261 list->versions = res; 00262 list->next = capabilities; 00263 capabilities = list; 00264 } 00265 return res; 00266 }
| static int aji_get_roster | ( | struct aji_client * | client | ) | [static] |
Definition at line 1766 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().
01767 { 01768 iks *roster = NULL; 01769 roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER); 01770 if(roster) { 01771 iks_insert_attrib(roster, "id", "roster"); 01772 aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage); 01773 iks_send(client->p, roster); 01774 } 01775 if (roster) 01776 iks_delete(roster); 01777 return 1; 01778 }
| static void aji_handle_iq | ( | struct aji_client * | client, | |
| iks * | node | |||
| ) | [static] |
Handles <iq> tags.
| client | structure and the iq node. |
Definition at line 1078 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 1088 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().
01089 { 01090 struct aji_message *insert, *tmp; 01091 int flag = 0; 01092 01093 if (!(insert = ast_calloc(1, sizeof(struct aji_message)))) 01094 return; 01095 time(&insert->arrived); 01096 if (iks_find_cdata(pak->x, "body")) 01097 insert->message = ast_strdup(iks_find_cdata(pak->x, "body")); 01098 if(pak->id) 01099 ast_copy_string(insert->id, pak->id, sizeof(insert->message)); 01100 if (pak->from) 01101 insert->from = ast_strdup(pak->from->full); 01102 AST_LIST_LOCK(&client->messages); 01103 AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) { 01104 if (flag) { 01105 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01106 if (tmp->from) 01107 free(tmp->from); 01108 if (tmp->message) 01109 free(tmp->message); 01110 } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) { 01111 flag = 1; 01112 AST_LIST_REMOVE_CURRENT(&client->messages, list); 01113 if (tmp->from) 01114 free(tmp->from); 01115 if (tmp->message) 01116 free(tmp->message); 01117 } 01118 } 01119 AST_LIST_TRAVERSE_SAFE_END; 01120 AST_LIST_INSERT_HEAD(&client->messages, insert, list); 01121 AST_LIST_UNLOCK(&client->messages); 01122 }
| static void aji_handle_presence | ( | struct aji_client * | client, | |
| ikspak * | pak | |||
| ) | [static] |
Definition at line 1124 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().
01125 { 01126 int status, priority; 01127 struct aji_buddy *buddy; 01128 struct aji_resource *tmp = NULL, *last = NULL, *found = NULL; 01129 char *ver, *node, *descrip, *type; 01130 01131 if(client->state != AJI_CONNECTED) 01132 aji_create_buddy(pak->from->partial, client); 01133 01134 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 01135 if (!buddy) { 01136 ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial); 01137 return; 01138 } 01139 type = iks_find_attrib(pak->x, "type"); 01140 if(client->component && type &&!strcasecmp("probe", type)) { 01141 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01142 ast_verbose("what i was looking for \n"); 01143 } 01144 ASTOBJ_WRLOCK(buddy); 01145 status = (pak->show) ? pak->show : 6; 01146 priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0"); 01147 tmp = buddy->resources; 01148 descrip = ast_strdup(iks_find_cdata(pak->x,"status")); 01149 01150 while (tmp) { 01151 if (!strcasecmp(tmp->resource, pak->from->resource)) { 01152 tmp->status = status; 01153 if (tmp->description) free(tmp->description); 01154 tmp->description = descrip; 01155 found = tmp; 01156 if (status == 6) { /* Sign off Destroy resource */ 01157 if (last && found->next) { 01158 last->next = found->next; 01159 } else if (!last) { 01160 if (found->next) 01161 buddy->resources = found->next; 01162 else 01163 buddy->resources = NULL; 01164 } else if (!found->next) { 01165 if (last) 01166 last->next = NULL; 01167 else 01168 buddy->resources = NULL; 01169 } 01170 free(found); 01171 found = NULL; 01172 break; 01173 } 01174 if (tmp->priority != priority) { 01175 found->priority = priority; 01176 if (!last && !found->next) 01177 break; 01178 if (last) 01179 last->next = found->next; 01180 else 01181 buddy->resources = found->next; 01182 last = NULL; 01183 tmp = buddy->resources; 01184 if (!buddy->resources) 01185 buddy->resources = found; 01186 while (tmp) { 01187 if (found->priority > tmp->priority) { 01188 if (last) 01189 last->next = found; 01190 found->next = tmp; 01191 if (!last) 01192 buddy->resources = found; 01193 break; 01194 } 01195 if (!tmp->next) { 01196 tmp->next = found; 01197 break; 01198 } 01199 last = tmp; 01200 tmp = tmp->next; 01201 } 01202 } 01203 break; 01204 } 01205 last = tmp; 01206 tmp = tmp->next; 01207 } 01208 01209 if (!found && status != 6) { 01210 found = (struct aji_resource *) malloc(sizeof(struct aji_resource)); 01211 memset(found, 0, sizeof(struct aji_resource)); 01212 01213 if (!found) { 01214 ast_log(LOG_ERROR, "Out of memory!\n"); 01215 return; 01216 } 01217 ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource)); 01218 found->status = status; 01219 found->description = descrip; 01220 found->priority = priority; 01221 found->next = NULL; 01222 last = NULL; 01223 tmp = buddy->resources; 01224 while (tmp) { 01225 if (found->priority > tmp->priority) { 01226 if (last) 01227 last->next = found; 01228 found->next = tmp; 01229 if (!last) 01230 buddy->resources = found; 01231 break; 01232 } 01233 if (!tmp->next) { 01234 tmp->next = found; 01235 break; 01236 } 01237 last = tmp; 01238 tmp = tmp->next; 01239 } 01240 if (!tmp) 01241 buddy->resources = found; 01242 } 01243 ASTOBJ_UNLOCK(buddy); 01244 ASTOBJ_UNREF(buddy, aji_buddy_destroy); 01245 01246 node = iks_find_attrib(iks_find(pak->x, "c"), "node"); 01247 ver = iks_find_attrib(iks_find(pak->x, "c"), "ver"); 01248 01249 if(status !=6 && !found->cap) { 01250 found->cap = aji_find_version(node, ver, pak); 01251 if(gtalk_yuck(pak->x)) /* gtalk should do discover */ 01252 found->cap->jingle = 1; 01253 if(found->cap->jingle && option_debug > 4) 01254 ast_log(LOG_DEBUG,"Special case for google till they support discover.\n"); 01255 else { 01256 iks *iq, *query; 01257 iq = iks_new("iq"); 01258 query = iks_new("query"); 01259 if(query && iq) { 01260 iks_insert_attrib(iq, "type", "get"); 01261 iks_insert_attrib(iq, "to", pak->from->full); 01262 iks_insert_attrib(iq,"from",iks_find_attrib(pak->x,"to")); 01263 iks_insert_attrib(iq, "id", client->mid); 01264 ast_aji_increment_mid(client->mid); 01265 iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info"); 01266 iks_insert_node(iq, query); 01267 iks_send(client->p, iq); 01268 01269 } else 01270 ast_log(LOG_ERROR, "Out of memory.\n"); 01271 if(query) 01272 iks_delete(query); 01273 if(iq) 01274 iks_delete(iq); 01275 } 01276 } 01277 if (option_verbose > 4) { 01278 switch (pak->subtype) { 01279 case IKS_TYPE_AVAILABLE: 01280 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am available ^_* %i\n", pak->subtype); 01281 break; 01282 case IKS_TYPE_UNAVAILABLE: 01283 ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am unavailable ^_* %i\n", pak->subtype); 01284 break; 01285 default: 01286 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype); 01287 } 01288 switch (pak->show) { 01289 case IKS_SHOW_UNAVAILABLE: 01290 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01291 break; 01292 case IKS_SHOW_AVAILABLE: 01293 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is available\n"); 01294 break; 01295 case IKS_SHOW_CHAT: 01296 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01297 break; 01298 case IKS_SHOW_AWAY: 01299 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is away\n"); 01300 break; 01301 case IKS_SHOW_XA: 01302 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01303 break; 01304 case IKS_SHOW_DND: 01305 ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show); 01306 break; 01307 default: 01308 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Kinky! how did that happen %i\n", pak->show); 01309 } 01310 } 01311 }
| static void aji_handle_subscribe | ( | struct aji_client * | client, | |
| ikspak * | pak | |||
| ) | [static] |
handles subscription requests.
| aji_client | struct and xml packet. |
Definition at line 1318 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().
01319 { 01320 if(pak->subtype == IKS_TYPE_SUBSCRIBE) { 01321 iks *presence = NULL, *status = NULL; 01322 presence = iks_new("presence"); 01323 status = iks_new("status"); 01324 if(presence && status) { 01325 iks_insert_attrib(presence, "type", "subscribed"); 01326 iks_insert_attrib(presence, "to", pak->from->full); 01327 iks_insert_attrib(presence, "from", client->jid->full); 01328 if(pak->id) 01329 iks_insert_attrib(presence, "id", pak->id); 01330 iks_insert_cdata(status, "Asterisk has approved subscription", 0); 01331 iks_insert_node(presence, status); 01332 iks_send(client->p, presence); 01333 } else 01334 ast_log(LOG_ERROR, "Unable to allocate nodes\n"); 01335 if(presence) 01336 iks_delete(presence); 01337 if(status) 01338 iks_delete(status); 01339 if(client->component) 01340 aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage); 01341 } 01342 if (option_verbose > 4) { 01343 switch (pak->subtype) { 01344 case IKS_TYPE_SUBSCRIBE: 01345 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01346 break; 01347 case IKS_TYPE_SUBSCRIBED: 01348 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01349 break; 01350 case IKS_TYPE_UNSUBSCRIBE: 01351 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01352 break; 01353 case IKS_TYPE_UNSUBSCRIBED: 01354 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01355 break; 01356 default: /*IKS_TYPE_ERROR: */ 01357 ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype); 01358 break; 01359 } 01360 } 01361 }
| static int aji_highest_bit | ( | int | number | ) | [static] |
Detects the highest bit in a number.
| Number | you want to have evaluated. |
Definition at line 295 of file res_jabber.c.
Referenced by aji_act_hook().
00296 { 00297 int x = sizeof(number) * 8 - 1; 00298 if (!number) 00299 return 0; 00300 for (; x > 0; x--) { 00301 if (number & (1 << x)) 00302 break; 00303 } 00304 return (1 << x); 00305 }
| static int aji_load_config | ( | void | ) | [static] |
load config file.
| void. |
Definition at line 2254 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().
02255 { 02256 char *cat = NULL; 02257 int debug = 1; 02258 struct ast_config *cfg = NULL; 02259 struct ast_variable *var = NULL; 02260 02261 cfg = ast_config_load(JABBER_CONFIG); 02262 if (!cfg) { 02263 ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG); 02264 return 0; 02265 } 02266 02267 cat = ast_category_browse(cfg, NULL); 02268 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { 02269 if (!strcasecmp(var->name, "debug")) 02270 debug = (ast_false(ast_variable_retrieve(cfg, "general", "debug"))) ? 0 : 1; 02271 else if (!strcasecmp(var->name, "autoprune")) 02272 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOPRUNE); 02273 else if (!strcasecmp(var->name, "autoregister")) 02274 ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOREGISTER); 02275 } 02276 02277 while (cat) { 02278 if (strcasecmp(cat, "general")) { 02279 var = ast_variable_browse(cfg, cat); 02280 aji_create_client(cat, var, debug); 02281 } 02282 cat = ast_category_browse(cfg, cat); 02283 } 02284 return 1; 02285 }
| 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 434 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().
00435 { 00436 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00437 manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp); 00438 00439 if (client->debug) { 00440 if (is_incoming) 00441 ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp); 00442 else { 00443 if( strlen(xmpp) == 1) { 00444 if(option_debug > 2 && xmpp[0] == ' ') 00445 ast_verbose("\nJABBER: Keep alive packet\n"); 00446 } else 00447 ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp); 00448 } 00449 00450 } 00451 ASTOBJ_UNREF(client, aji_client_destroy); 00452 }
| static int aji_no_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
turnoff console debugging.
| fd,number | of args, args. |
Definition at line 1931 of file res_jabber.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and RESULT_SUCCESS.
01932 { 01933 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01934 ASTOBJ_RDLOCK(iterator); 01935 iterator->debug = 0; 01936 ASTOBJ_UNLOCK(iterator); 01937 }); 01938 ast_cli(fd, "Jabber Debugging Disabled.\n"); 01939 return RESULT_SUCCESS; 01940 }
| 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 1621 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.
01622 { 01623 int res = 0; 01624 iks *removeiq = iks_new("iq"); 01625 iks *removequery = iks_new("query"); 01626 iks *removeitem = iks_new("item"); 01627 iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items"); 01628 01629 if (client && removeiq && removequery && removeitem && send) { 01630 iks_insert_node(removeiq, removequery); 01631 iks_insert_node(removequery, removeitem); 01632 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 01633 ASTOBJ_RDLOCK(iterator); 01634 /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never 01635 * be called at the same time */ 01636 if (ast_test_flag(iterator, AJI_AUTOPRUNE)) { 01637 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name, 01638 "GoodBye your status is no longer needed by Asterisk the Open Source PBX" 01639 " so I am no longer subscribing to your presence.\n")); 01640 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name, 01641 "GoodBye you are no longer in the asterisk config file so I am removing" 01642 " your access to my presence.\n")); 01643 iks_insert_attrib(removeiq, "from", client->jid->full); 01644 iks_insert_attrib(removeiq, "type", "set"); 01645 iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster"); 01646 iks_insert_attrib(removeitem, "jid", iterator->name); 01647 iks_insert_attrib(removeitem, "subscription", "remove"); 01648 res = iks_send(client->p, removeiq); 01649 } else if (ast_test_flag(iterator, AJI_AUTOREGISTER)) { 01650 res = iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name, 01651 "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n")); 01652 ast_clear_flag(iterator, AJI_AUTOREGISTER); 01653 } 01654 ASTOBJ_UNLOCK(iterator); 01655 }); 01656 } else 01657 ast_log(LOG_ERROR, "Out of memory.\n"); 01658 if (removeiq) 01659 iks_delete(removeiq); 01660 if (removequery) 01661 iks_delete(removequery); 01662 if (removeitem) 01663 iks_delete(removeitem); 01664 if (send) 01665 iks_delete(send); 01666 ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy); 01667 }
| static int aji_reconnect | ( | struct aji_client * | client | ) | [static] |
Definition at line 1746 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().
01747 { 01748 int res = 0; 01749 01750 if (client->state) 01751 client->state = AJI_DISCONNECTED; 01752 client->timeout=50; 01753 if (client->p) 01754 iks_parser_reset(client->p); 01755 if (client->authorized) 01756 client->authorized = 0; 01757 01758 if(client->component) 01759 res = aji_component_initialize(client); 01760 else 01761 res = aji_client_initialize(client); 01762 01763 return res; 01764 }
| static void * aji_recv_loop | ( | void * | data | ) | [static] |
receive message loop.
| aji_client | struct. |
Definition at line 1476 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().
01477 { 01478 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 01479 int res = IKS_HOOK; 01480 do { 01481 if (res != IKS_OK) { 01482 while(res != IKS_OK) { 01483 if(option_verbose > 3) 01484 ast_verbose("JABBER: reconnecting.\n"); 01485 res = aji_reconnect(client); 01486 sleep(4); 01487 } 01488 } 01489 01490 res = iks_recv(client->p, 1); 01491 client->timeout--; 01492 if (res == IKS_HOOK) 01493 ast_log(LOG_WARNING, "JABBER: Got hook event.\n"); 01494 else if (res == IKS_NET_TLSFAIL) 01495 ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n"); 01496 else if (client->timeout == 0 && client->state == AJI_CONNECTED) { 01497 res = iks_send_raw(client->p, " "); 01498 if(res == IKS_OK) 01499 client->timeout = 50; 01500 else 01501 ast_log(LOG_WARNING, "JABBER: Network Timeout\n"); 01502 } else if (res == IKS_NET_RWERR) 01503 ast_log(LOG_WARNING, "JABBER: socket read error\n"); 01504 } while (client); 01505 ASTOBJ_UNREF(client, aji_client_destroy); 01506 return 0; 01507 }
| static int aji_register_approve_handler | ( | void * | data, | |
| ikspak * | pak | |||
| ) | [static] |
Definition at line 660 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().
00661 { 00662 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00663 iks *iq = NULL, *presence = NULL, *x = NULL; 00664 00665 iq = iks_new("iq"); 00666 presence = iks_new("presence"); 00667 x = iks_new("x"); 00668 if (client && iq && presence && x) { 00669 if (!iks_find(pak->query, "remove")) { 00670 iks_insert_attrib(iq, "from", client->jid->full); 00671 iks_insert_attrib(iq, "to", pak->from->full); 00672 iks_insert_attrib(iq, "id", pak->id); 00673 iks_insert_attrib(iq, "type", "result"); 00674 iks_send(client->p, iq); 00675 00676 iks_insert_attrib(presence, "from", client->jid->full); 00677 iks_insert_attrib(presence, "to", pak->from->partial); 00678 iks_insert_attrib(presence, "id", client->mid); 00679 ast_aji_increment_mid(client->mid); 00680 iks_insert_attrib(presence, "type", "subscribe"); 00681 iks_insert_attrib(x, "xmlns", "vcard-temp:x:update"); 00682 iks_insert_node(presence, x); 00683 iks_send(client->p, presence); 00684 } 00685 } else { 00686 ast_log(LOG_ERROR, "Out of memory.\n"); 00687 } 00688 00689 if (iq) 00690 iks_delete(iq); 00691 if(presence) 00692 iks_delete(presence); 00693 if (x) 00694 iks_delete(x); 00695 ASTOBJ_UNREF(client, aji_client_destroy); 00696 return IKS_FILTER_EAT; 00697 }
| static int aji_register_query_handler | ( | void * | data, | |
| ikspak * | pak | |||
| ) | [static] |
Definition at line 699 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().
00700 { 00701 struct aji_client *client = ASTOBJ_REF((struct aji_client *) data); 00702 struct aji_buddy *buddy = NULL; 00703 char *node = NULL; 00704 00705 client = (struct aji_client *) data; 00706 00707 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial); 00708 if (!buddy) { 00709 ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial); 00710 iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL; 00711 iq = iks_new("iq"); 00712 query = iks_new("query"); 00713 error = iks_new("error"); 00714 notacceptable = iks_new("not-acceptable"); 00715 if(iq && query && error && notacceptable) { 00716 iks_insert_attrib(iq, "type", "error"); 00717 iks_insert_attrib(iq, "from", client->user); 00718 iks_insert_attrib(iq, "to", pak->from->full); 00719 iks_insert_attrib(iq, "id", pak->id); 00720 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00721 iks_insert_attrib(error, "code" , "406"); 00722 iks_insert_attrib(error, "type", "modify"); 00723 iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); 00724 iks_insert_node(iq, query); 00725 iks_insert_node(iq, error); 00726 iks_insert_node(error, notacceptable); 00727 iks_send(client->p, iq); 00728 } else { 00729 ast_log(LOG_ERROR, "Out of memory.\n"); 00730 } 00731 if (iq) 00732 iks_delete(iq); 00733 if (query) 00734 iks_delete(query); 00735 if (error) 00736 iks_delete(error); 00737 if (notacceptable) 00738 iks_delete(notacceptable); 00739 } else if (!(node = iks_find_attrib(pak->query, "node"))) { 00740 iks *iq = NULL, *query = NULL, *instructions = NULL; 00741 char *explain = "Welcome to Asterisk - the Open Source PBX.\n"; 00742 iq = iks_new("iq"); 00743 query = iks_new("query"); 00744 instructions = iks_new("instructions"); 00745 if (iq && query && instructions && client) { 00746 iks_insert_attrib(iq, "from", client->user); 00747 iks_insert_attrib(iq, "to", pak->from->full); 00748 iks_insert_attrib(iq, "id", pak->id); 00749 iks_insert_attrib(iq, "type", "result"); 00750 iks_insert_attrib(query, "xmlns", "jabber:iq:register"); 00751 iks_insert_cdata(instructions, explain, 0); 00752 iks_insert_node(iq, query); 00753 iks_insert_node(query, instructions); 00754 iks_send(client->p, iq); 00755 } else { 00756 ast_log(LOG_ERROR, "Out of memory.\n"); 00757 } 00758 if (iq) 00759 iks_delete(iq); 00760 if (query) 00761 iks_delete(query); 00762 if (instructions) 00763 iks_delete(instructions); 00764 } 00765 ASTOBJ_UNREF(client, aji_client_destroy); 00766 return IKS_FILTER_EAT; 00767 }
| static int aji_reload | ( | void | ) | [static] |
Definition at line 2356 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().
02357 { 02358 ASTOBJ_CONTAINER_MARKALL(&clients); 02359 if (!aji_load_config()) { 02360 ast_log(LOG_ERROR, "JABBER: Failed to load config.\n"); 02361 return 0; 02362 } 02363 ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy); 02364 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02365 ASTOBJ_RDLOCK(iterator); 02366 if(iterator->state == AJI_DISCONNECTED) { 02367 if (!iterator->thread) 02368 ast_pthread_create_background(&iterator->thread, NULL, aji_recv_loop, iterator); 02369 } else if (iterator->state == AJI_CONNECTING) 02370 aji_get_roster(iterator); 02371 ASTOBJ_UNLOCK(iterator); 02372 }); 02373 02374 return 1; 02375 }
| 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 398 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().
00399 { 00400 struct aji_client *client = NULL; 00401 00402 char *s = NULL, *sender = NULL, *recipient = NULL, *message = NULL; 00403 00404 if (!data) { 00405 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00406 return 0; 00407 } 00408 s = ast_strdupa(data); 00409 if (s) { 00410 sender = strsep(&s, "|"); 00411 if (sender && (sender[0] != '\0')) { 00412 recipient = strsep(&s, "|"); 00413 if (recipient && (recipient[0] != '\0')) { 00414 message = s; 00415 } else { 00416 ast_log(LOG_ERROR, "Bad arguments: %s\n", (char *) data); 00417 return -1; 00418 } 00419 } 00420 } 00421 if (!(client = ast_aji_get_client(sender))) { 00422 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00423 return -1; 00424 } 00425 if (strchr(recipient, '@') && message) 00426 ast_aji_send(client, recipient, message); 00427 return 0; 00428 }
| 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 1871 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().
01872 { 01873 int res = 0; 01874 iks *presence = iks_make_pres(level, desc); 01875 iks *cnode = iks_new("c"); 01876 iks *priority = iks_new("priority"); 01877 01878 iks_insert_cdata(priority, "0", 1); 01879 if (presence && cnode && client) { 01880 if(to) 01881 iks_insert_attrib(presence, "to", to); 01882 if(from) 01883 iks_insert_attrib(presence, "from", from); 01884 iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps"); 01885 iks_insert_attrib(cnode, "ver", "asterisk-xmpp"); 01886 iks_insert_attrib(cnode, "ext", "voice-v1"); 01887 iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps"); 01888 iks_insert_node(presence, cnode); 01889 res = iks_send(client->p, presence); 01890 } else 01891 ast_log(LOG_ERROR, "Out of memory.\n"); 01892 if (cnode) 01893 iks_delete(cnode); 01894 if (presence) 01895 iks_delete(presence); 01896 }
| static int aji_show_clients | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
show client status.
| fd,number | of args, args. |
Definition at line 1947 of file res_jabber.c.
References AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and clients.
01948 { 01949 char *status; 01950 int count = 0; 01951 ast_cli(fd, "Jabber Users and their status:\n"); 01952 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 01953 ASTOBJ_RDLOCK(iterator); 01954 count++; 01955 switch (iterator->state) { 01956 case AJI_DISCONNECTED: 01957 status = "Disconnected"; 01958 break; 01959 case AJI_CONNECTING: 01960 status = "Connecting"; 01961 break; 01962 case AJI_CONNECTED: 01963 status = "Connected"; 01964 break; 01965 default: 01966 status = "Unknown"; 01967 } 01968 ast_cli(fd, " User: %s - %s\n", iterator->user, status); 01969 ASTOBJ_UNLOCK(iterator); 01970 }); 01971 ast_cli(fd, "----\n"); 01972 ast_cli(fd, " Number of users: %d\n", count); 01973 return RESULT_SUCCESS; 01974 }
| 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 334 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().
00335 { 00336 struct aji_client *client = NULL; 00337 struct aji_buddy *buddy = NULL; 00338 struct aji_resource *r = NULL; 00339 char *s = NULL, *sender = NULL, *jid = NULL, *screenname = NULL, *resource = NULL, *variable = NULL; 00340 int stat = 7; 00341 char status[2]; 00342 00343 if (!data) { 00344 ast_log(LOG_ERROR, "This application requires arguments.\n"); 00345 return 0; 00346 } 00347 s = ast_strdupa(data); 00348 if (s) { 00349 sender = strsep(&s, "|"); 00350 if (sender && (sender[0] != '\0')) { 00351 jid = strsep(&s, "|"); 00352 if (jid && (jid[0] != '\0')) { 00353 variable = s; 00354 } else { 00355 ast_log(LOG_ERROR, "Bad arguments\n"); 00356 return -1; 00357 } 00358 } 00359 } 00360 00361 if(!strchr(jid, '/')) { 00362 resource = NULL; 00363 } else { 00364 screenname = strsep(&jid, "/"); 00365 resource = jid; 00366 } 00367 client = ast_aji_get_client(sender); 00368 if (!client) { 00369 ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender); 00370 return -1; 00371 } 00372 if(!&client->buddies) { 00373 ast_log(LOG_WARNING, "No buddies for connection : %s\n", sender); 00374 return -1; 00375 } 00376 buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, resource ? screenname: jid); 00377 if (!buddy) { 00378 ast_log(LOG_WARNING, "Could not find buddy in list : %s\n", resource ? screenname : jid); 00379 return -1; 00380 } 00381 r = aji_find_resource(buddy, resource); 00382 if(!r && buddy->resources) 00383 r = buddy->resources; 00384 if(!r) 00385 ast_log(LOG_NOTICE, "Resource %s of buddy %s not found \n", resource, screenname); 00386 else 00387 stat = r->status; 00388 sprintf(status, "%d", stat); 00389 pbx_builtin_setvar_helper(chan, variable, status); 00390 return 0; 00391 }
| static int aji_test | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
send test message for debugging.
| fd,number | of args, args. |
Definition at line 1981 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.
01982 { 01983 struct aji_client *client; 01984 struct aji_resource *resource; 01985 const char *name = "asterisk"; 01986 struct aji_message *tmp; 01987 01988 if (argc > 3) 01989 return RESULT_SHOWUSAGE; 01990 else if (argc == 3) 01991 name = argv[2]; 01992 01993 if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) { 01994 ast_cli(fd, "Unable to find client '%s'!\n", name); 01995 return RESULT_FAILURE; 01996 } 01997 01998 /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */ 01999 ast_aji_send(client, "mogorman@astjab.org", "blahblah"); 02000 ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, { 02001 ASTOBJ_RDLOCK(iterator); 02002 ast_verbose("User: %s\n", iterator->name); 02003 for (resource = iterator->resources; resource; resource = resource->next) { 02004 ast_verbose("Resource: %s\n", resource->resource); 02005 if(resource->cap) { 02006 ast_verbose(" client: %s\n", resource->cap->parent->node); 02007 ast_verbose(" version: %s\n", resource->cap->version); 02008 ast_verbose(" Jingle Capable: %d\n", resource->cap->jingle); 02009 } 02010 ast_verbose(" Priority: %d\n", resource->priority); 02011 ast_verbose(" Status: %d\n", resource->status); 02012 ast_verbose(" Message: %s\n", S_OR(resource->description,"")); 02013 } 02014 ASTOBJ_UNLOCK(iterator); 02015 }); 02016 ast_verbose("\nOooh a working message stack!\n"); 02017 AST_LIST_LOCK(&client->messages); 02018 AST_LIST_TRAVERSE(&client->messages, tmp, list) { 02019 ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, "")); 02020 } 02021 AST_LIST_UNLOCK(&client->messages); 02022 ASTOBJ_UNREF(client, aji_client_destroy); 02023 02024 return RESULT_SUCCESS; 02025 }
| 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 1392 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01393 { 01394 int res = 0; 01395 iks *iq = NULL; 01396 iq = iks_new("iq"); 01397 if (iq && client) { 01398 iks_insert_attrib(iq, "type", "get"); 01399 iks_insert_attrib(iq, "to", server); 01400 iks_insert_attrib(iq, "id", client->mid); 01401 ast_aji_increment_mid(client->mid); 01402 iks_send(client->p, iq); 01403 } else 01404 ast_log(LOG_ERROR, "Out of memory.\n"); 01405 return res; 01406 }
| int ast_aji_disconnect | ( | struct aji_client * | client | ) |
disconnect from jabber server.
| aji_client | struct. |
Definition at line 1853 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().
01854 { 01855 if (client) { 01856 if (option_verbose > 3) 01857 ast_verbose(VERBOSE_PREFIX_3 "JABBER: Disconnecting\n"); 01858 iks_disconnect(client->p); 01859 iks_parser_delete(client->p); 01860 ASTOBJ_UNREF(client, aji_client_destroy); 01861 } 01862 01863 return 1; 01864 }
| struct aji_client* ast_aji_get_client | ( | const char * | name | ) |
grab a aji_client structure by label name.
| void. |
Definition at line 2292 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().
02293 { 02294 struct aji_client *client = NULL; 02295 02296 client = ASTOBJ_CONTAINER_FIND(&clients, name); 02297 if (!client && !strchr(name, '@')) 02298 client = ASTOBJ_CONTAINER_FIND_FULL(&clients, name, user,,, strcasecmp); 02299 return client; 02300 }
| struct aji_client_container* ast_aji_get_clients | ( | void | ) |
Definition at line 2302 of file res_jabber.c.
References clients.
02303 { 02304 return &clients; 02305 }
| void ast_aji_increment_mid | ( | char * | mid | ) |
increments the mid field for messages and other events.
| message | id. |
Definition at line 1514 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().
01515 { 01516 int i = 0; 01517 01518 for (i = strlen(mid) - 1; i >= 0; i--) { 01519 if (mid[i] != 'z') { 01520 mid[i] = mid[i] + 1; 01521 i = 0; 01522 } else 01523 mid[i] = 'a'; 01524 } 01525 }
| 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 1441 of file res_jabber.c.
References ast_aji_increment_mid(), ast_log(), LOG_ERROR, aji_client::mid, and aji_client::p.
01442 { 01443 int res = 0; 01444 iks *invite, *body, *namespace; 01445 01446 invite = iks_new("message"); 01447 body = iks_new("body"); 01448 namespace = iks_new("x"); 01449 if (client && invite && body && namespace) { 01450 iks_insert_attrib(invite, "to", user); 01451 iks_insert_attrib(invite, "id", client->mid); 01452 ast_aji_increment_mid(client->mid); 01453 iks_insert_cdata(body, message, 0); 01454 iks_insert_attrib(namespace, "xmlns", "jabber:x:conference"); 01455 iks_insert_attrib(namespace, "jid", room); 01456 iks_insert_node(invite, body); 01457 iks_insert_node(invite, namespace); 01458 res = iks_send(client->p, invite); 01459 } else 01460 ast_log(LOG_ERROR, "Out of memory.\n"); 01461 if (body) 01462 iks_delete(body); 01463 if (namespace) 01464 iks_delete(namespace); 01465 if (invite) 01466 iks_delete(invite); 01467 return res; 01468 }
| int ast_aji_join_chat | ( | struct aji_client * | client, | |
| char * | room | |||
| ) |
join a chatroom.
| aji_client | struct , room. |
Definition at line 1413 of file res_jabber.c.
References ast_log(), LOG_ERROR, aji_client::p, and aji_resource::priority.
01414 { 01415 int res = 0; 01416 iks *presence = NULL, *priority = NULL; 01417 presence = iks_new("presence"); 01418 priority = iks_new("priority"); 01419 if (presence && priority && client) { 01420 iks_insert_cdata(priority, "0", 1); 01421 iks_insert_attrib(presence, "to", room); 01422 iks_insert_node(presence, priority); 01423 res = iks_send(client->p, presence); 01424 iks_insert_cdata(priority, "5", 1); 01425 iks_insert_attrib(presence, "to", room); 01426 res = iks_send(client->p, presence); 01427 } else 01428 ast_log(LOG_ERROR, "Out of memory.\n"); 01429 if (presence) 01430 iks_delete(presence); 01431 if (priority) 01432 iks_delete(priority); 01433 return res; 01434 }
| int ast_aji_send | ( | struct aji_client * | client, | |
| const char * | address, | |||
| const char * | message | |||
| ) |
sends messages.
| aji_client | struct , reciever, message. |
Definition at line 1368 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().
01369 { 01370 int res = 0; 01371 iks *message_packet = NULL; 01372 if (client->state == AJI_CONNECTED) { 01373 message_packet = iks_make_msg(IKS_TYPE_CHAT, address, message); 01374 if (message_packet) { 01375 iks_insert_attrib(message_packet, "from", client->jid->full); 01376 res = iks_send(client->p, message_packet); 01377 } else { 01378 ast_log(LOG_ERROR, "Out of memory.\n"); 01379 } 01380 if (message_packet) 01381 iks_delete(message_packet); 01382 } else 01383 ast_log(LOG_WARNING, "JABBER: Not connected can't send\n"); 01384 return 1; 01385 }
| 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 283 of file res_jabber.c.
Referenced by aji_handle_presence().
00284 { 00285 if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps")) 00286 return 1; 00287 return 0; 00288 }
| static iks * jabber_make_auth | ( | iksid * | id, | |
| const char * | pass, | |||
| const char * | sid | |||
| ) | [static] |
Definition at line 307 of file res_jabber.c.
References ast_sha1_hash().
Referenced by aji_act_hook().
00308 { 00309 iks *x, *y; 00310 x = iks_new("iq"); 00311 iks_insert_attrib(x, "type", "set"); 00312 y = iks_insert(x, "query"); 00313 iks_insert_attrib(y, "xmlns", IKS_NS_AUTH); 00314 iks_insert_cdata(iks_insert(y, "username"), id->user, 0); 00315 iks_insert_cdata(iks_insert(y, "resource"), id->resource, 0); 00316 if (sid) { 00317 char buf[41]; 00318 char sidpass[100]; 00319 snprintf(sidpass, sizeof(sidpass), "%s%s", sid, pass); 00320 ast_sha1_hash(buf, sidpass); 00321 iks_insert_cdata(iks_insert(y, "digest"), buf, 0); 00322 } else { 00323 iks_insert_cdata(iks_insert(y, "password"), pass, 0); 00324 } 00325 return x; 00326 }
| static int load_module | ( | void | ) | [static] |
Definition at line 2400 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.
02401 { 02402 ASTOBJ_CONTAINER_INIT(&clients); 02403 if(!aji_reload()) 02404 return AST_MODULE_LOAD_DECLINE; 02405 ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send, 02406 "Sends a message to a Jabber Client", mandescr_jabber_send); 02407 ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip); 02408 ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip); 02409 ast_cli_register_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02410 02411 ast_log(LOG_NOTICE, "res_jabber.so loaded.\n"); 02412 return 0; 02413 }
| 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 2315 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().
02316 { 02317 struct aji_client *client = NULL; 02318 const char *id = astman_get_header(m,"ActionID"); 02319 const char *jabber = astman_get_header(m,"Jabber"); 02320 const char *screenname = astman_get_header(m,"ScreenName"); 02321 const char *message = astman_get_header(m,"Message"); 02322 02323 if (ast_strlen_zero(jabber)) { 02324 astman_send_error(s, m, "No transport specified"); 02325 return 0; 02326 } 02327 if (ast_strlen_zero(screenname)) { 02328 astman_send_error(s, m, "No ScreenName specified"); 02329 return 0; 02330 } 02331 if (ast_strlen_zero(message)) { 02332 astman_send_error(s, m, "No Message specified"); 02333 return 0; 02334 } 02335 02336 astman_send_ack(s, m, "Attempting to send Jabber Message"); 02337 client = ast_aji_get_client(jabber); 02338 if (!client) { 02339 astman_send_error(s, m, "Could not find Sender"); 02340 return 0; 02341 } 02342 if (strchr(screenname, '@') && message){ 02343 ast_aji_send(client, screenname, message); 02344 if (!ast_strlen_zero(id)) 02345 astman_append(s, "ActionID: %s\r\n",id); 02346 astman_append(s, "Response: Success\r\n"); 02347 return 0; 02348 } 02349 if (!ast_strlen_zero(id)) 02350 astman_append(s, "ActionID: %s\r\n",id); 02351 astman_append(s, "Response: Failure\r\n"); 02352 return 0; 02353 }
| static int reload | ( | void | ) | [static] |
Definition at line 2415 of file res_jabber.c.
References aji_reload().
02416 { 02417 aji_reload(); 02418 return 0; 02419 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 2377 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.
02378 { 02379 ast_cli_unregister_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry)); 02380 ast_unregister_application(app_ajisend); 02381 ast_unregister_application(app_ajistatus); 02382 ast_manager_unregister("JabberSend"); 02383 ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { 02384 ASTOBJ_RDLOCK(iterator); 02385 if (option_verbose > 2) 02386 ast_verbose(VERBOSE_PREFIX_3 "JABBER: %s\n", iterator->name); 02387 iterator->state = AJI_DISCONNECTED; 02388 ast_aji_disconnect(iterator); 02389 pthread_join(iterator->thread, NULL); 02390 ASTOBJ_UNLOCK(iterator); 02391 }); 02392 02393 ASTOBJ_CONTAINER_DESTROYALL(&clients, aji_client_destroy); 02394 ASTOBJ_CONTAINER_DESTROY(&clients); 02395 02396 ast_log(LOG_NOTICE, "res_jabber unloaded.\n"); 02397 return 0; 02398 }
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 |
| 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.
1.5.1