[asterisk-commits] snuffy: branch snuffy/ao2_jabber_take2 r161217 - in /team/snuffy/ao2_jabber_t...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Dec 5 04:29:46 CST 2008
Author: snuffy
Date: Fri Dec 5 04:29:45 2008
New Revision: 161217
URL: http://svn.digium.com/view/asterisk?view=rev&rev=161217
Log:
put back ao2 jabber changes
Modified:
team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c
team/snuffy/ao2_jabber_take2/channels/chan_jingle.c
team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h
team/snuffy/ao2_jabber_take2/res/res_jabber.c
Modified: team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c (original)
+++ team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c Fri Dec 5 04:29:45 2008
@@ -65,6 +65,7 @@
#include "asterisk/astobj.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/jabber.h"
+#include "asterisk/astobj2.h"
#define GOOGLE_CONFIG "gtalk.conf"
@@ -234,6 +235,9 @@
static void gtalk_member_destroy(struct gtalk *obj)
{
+ //ao2_t_ref(obj->connection->buddies, -1, "die ref");
+ ao2_t_ref(obj->connection, -1, "die client ref");
+ ao2_t_ref(obj->buddy, -1, "die buddy ref");
ast_free(obj);
}
@@ -880,14 +884,15 @@
{
struct gtalk_pvt *tmp = NULL;
struct aji_resource *resources = NULL;
- struct aji_buddy *buddy;
+ struct aji_buddy *buddy, tmp_buddy;
char idroster[200];
char *data, *exten = NULL;
ast_debug(1, "The client is %s for alloc\n", client->name);
if (!sid && !strchr(them, '/')) { /* I started call! */
if (!strcasecmp(client->name, "guest")) {
- buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, them);
+ ast_copy_string(tmp_buddy.name, them, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
if (buddy)
resources = buddy->resources;
} else if (client->buddy)
@@ -1844,9 +1849,12 @@
}
var = var->next;
}
- if (member->connection && member->user)
- member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
- else {
+ if (member->connection && member->user) {
+ struct aji_buddy tmp_buddy;
+ ast_copy_string(tmp_buddy.name, member->user, sizeof(tmp_buddy.name));
+ member->buddy = ao2_t_find(member->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
+ //ao2_t_ref(member->buddy, -1, "create etc");
+ } else {
ast_log(LOG_ERROR, "No Connection or Username!\n");
}
return 1;
@@ -1862,7 +1870,7 @@
struct ast_variable *var;
struct gtalk *member;
struct ast_codec_pref prefs;
- struct aji_client_container *clients;
+ struct ao2_container *clients;
struct gtalk_candidate *global_candidates = NULL;
struct hostent *hp;
struct ast_hostent ahp;
@@ -1955,15 +1963,20 @@
ASTOBJ_UNLOCK(member);
clients = ast_aji_get_clients();
if (clients) {
- ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
- ASTOBJ_WRLOCK(iterator);
+ struct ao2_iterator iter;
+ struct aji_client *c;
+
+ iter = ao2_iterator_init(clients, 0);
+ while ((c =ao2_t_iterator_next(&iter,"iter clients"))) {
+ ao2_lock(c);
ASTOBJ_WRLOCK(member);
member->connection = NULL;
- iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
- iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
+ iks_filter_add_rule(c->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
+ iks_filter_add_rule(c->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
ASTOBJ_UNLOCK(member);
- ASTOBJ_UNLOCK(iterator);
- });
+ ao2_unlock(c);
+ ao2_ref(c, -1);
+ }
ASTOBJ_CONTAINER_LINK(>alk_list, member);
ASTOBJ_UNREF(member, gtalk_member_destroy);
} else {
Modified: team/snuffy/ao2_jabber_take2/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/channels/chan_jingle.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/channels/chan_jingle.c (original)
+++ team/snuffy/ao2_jabber_take2/channels/chan_jingle.c Fri Dec 5 04:29:45 2008
@@ -68,6 +68,7 @@
#include "asterisk/abstract_jb.h"
#include "asterisk/jabber.h"
#include "asterisk/jingle.h"
+#include "asterisk/astobj2.h"
#define JINGLE_CONFIG "jingle.conf"
@@ -741,13 +742,14 @@
{
struct jingle_pvt *tmp = NULL;
struct aji_resource *resources = NULL;
- struct aji_buddy *buddy;
+ struct aji_buddy *buddy,tmp_buddy;
char idroster[200];
ast_debug(1, "The client is %s for alloc\n", client->name);
if (!sid && !strchr(from, '/')) { /* I started call! */
if (!strcasecmp(client->name, "guest")) {
- buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from);
+ ast_copy_string(tmp_buddy.name, from, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find client");
if (buddy)
resources = buddy->resources;
} else if (client->buddy)
@@ -1712,9 +1714,11 @@
}
var = var->next;
}
- if (member->connection && member->user)
- member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
- else {
+ if (member->connection && member->user) {
+ struct aji_buddy tmp_buddy;
+ ast_copy_string(tmp_buddy.name, member->user, sizeof(tmp_buddy.name));
+ member->buddy = ao2_t_find(member->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
+ } else {
ast_log(LOG_ERROR, "No Connection or Username!\n");
}
return 1;
@@ -1731,7 +1735,7 @@
struct hostent *hp;
struct ast_hostent ahp;
struct ast_codec_pref prefs;
- struct aji_client_container *clients;
+ struct ao2_container *clients;
struct jingle_candidate *global_candidates = NULL;
struct ast_flags config_flags = { 0 };
@@ -1739,7 +1743,7 @@
if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
return 0;
}
-
+
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -1818,15 +1822,20 @@
ASTOBJ_UNLOCK(member);
clients = ast_aji_get_clients();
if (clients) {
- ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
- ASTOBJ_WRLOCK(iterator);
+ struct ao2_iterator iter;
+ struct aji_client *c;
+
+ iter = ao2_iterator_init(clients, 0);
+ while ((c = ao2_t_iterator_next(&iter,"client iter"))) {
+ ao2_lock(c);
ASTOBJ_WRLOCK(member);
member->connection = NULL;
- iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE);
- iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE);
+ iks_filter_add_rule(c->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE);
+ iks_filter_add_rule(c->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE);
ASTOBJ_UNLOCK(member);
- ASTOBJ_UNLOCK(iterator);
- });
+ ao2_unlock(c);
+ ao2_ref(c, -1);
+ }
ASTOBJ_CONTAINER_LINK(&jingle_list, member);
} else {
ASTOBJ_UNLOCK(member);
Modified: team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h (original)
+++ team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h Fri Dec 5 04:29:45 2008
@@ -57,9 +57,10 @@
#define IKS_NET_EXPIRED 12
#include <iksemel.h>
+#define REF_DEBUG 1
#include "asterisk/astobj.h"
+#include "asterisk/astobj2.h"
#include "asterisk/linkedlists.h"
-
/*
* As per RFC 3920 - section 3.1, the maximum length for a full Jabber ID
* is 3071 bytes.
@@ -122,23 +123,18 @@
};
struct aji_buddy {
- ASTOBJ_COMPONENTS_FULL(struct aji_buddy, AJI_MAX_JIDLEN, 1);
+ char name[AJI_MAX_JIDLEN];
char channel[160];
struct aji_resource *resources;
enum aji_btype btype;
struct ast_flags flags;
+ char needdestroy;
+ int mark;
};
-struct aji_buddy_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_buddy);
-};
-
-struct aji_transport_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_transport);
-};
struct aji_client {
- ASTOBJ_COMPONENTS(struct aji_client);
+ char name[80];
char password[160];
char user[AJI_MAX_JIDLEN];
char serverhost[AJI_MAX_RESJIDLEN];
@@ -169,16 +165,13 @@
int authorized;
struct ast_flags flags;
int component; /* 0 client, 1 component */
- struct aji_buddy_container buddies;
+ struct ao2_container *buddies;
AST_LIST_HEAD(messages,aji_message) messages;
void *jingle;
pthread_t thread;
int priority;
enum ikshowtype status;
-};
-
-struct aji_client_container{
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_client);
+ int mark;
};
/* !Send XML stanza over the established XMPP connection */
@@ -196,6 +189,6 @@
/*! Join existing Chat session */
int ast_aji_join_chat(struct aji_client *client,char *room);
struct aji_client *ast_aji_get_client(const char *name);
-struct aji_client_container *ast_aji_get_clients(void);
+struct ao2_container *ast_aji_get_clients(void);
#endif
Modified: team/snuffy/ao2_jabber_take2/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/res/res_jabber.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/res/res_jabber.c (original)
+++ team/snuffy/ao2_jabber_take2/res/res_jabber.c Fri Dec 5 04:29:45 2008
@@ -55,7 +55,8 @@
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
-#include "asterisk/astobj.h"
+/*#include "asterisk/astobj.h"*/
+#include "asterisk/astobj2.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
@@ -71,9 +72,16 @@
#define TRUE 1
#endif
+#ifdef LOW_MEMORY
+static int hash_buddy_size = 20;
+static int hash_client_size = 20;
+#else
+static int hash_buddy_size = 256;
+static int hash_client_size = 256;
+#endif
/*-- Forward declarations */
-static void aji_buddy_destroy(struct aji_buddy *obj);
-static void aji_client_destroy(struct aji_client *obj);
+static void aji_buddy_destroy(void *obj);
+static void aji_client_destroy(void *obj);
static int aji_send_exec(struct ast_channel *chan, void *data);
static int aji_status_exec(struct ast_channel *chan, void *data);
static int aji_is_secure(struct aji_client *client);
@@ -132,12 +140,12 @@
static char *app_ajisend = "JabberSend";
-static char *ajisend_synopsis = "JabberSend(Jabber,JID,Message)";
+static char *ajisend_synopsis = "JabberSend(Jabber,JID,message)";
static char *ajisend_descrip =
-"JabberSend(Jabber,JID,Message)\n"
+"JabberSend(Jabber,ScreenName,Message)\n"
" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
-" JID - XMPP/Jabber JID (Name) of recipient\n"
+" JID - User Name to message.\n"
" Message - Message to be sent to the buddy\n";
static char *app_ajistatus = "JabberStatus";
@@ -145,42 +153,168 @@
static char *ajistatus_synopsis = "JabberStatus(Jabber,JID,Variable)";
static char *ajistatus_descrip =
-"JabberStatus(Jabber,JID,Variable)\n"
-" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
-" JID - User Name to retrieve status from.\n"
-" Variable - Variable to store presence in will be 1-6.\n"
+"JabberStatus(Jabber,ScreenName,Variable)\n"
+" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
+" JID - User Name to retrieve status from.\n"
+" Variable - Variable to store presence in will be 1-6.\n"
" In order, 1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline\n"
" If not in roster variable will be set to 7\n\n"
"Note: This application is deprecated. Please use the JABBER_STATUS() function instead.\n";
-struct aji_client_container clients;
+struct ao2_container *clients;
struct aji_capabilities *capabilities = NULL;
/*! \brief Global flags, initialized to default values */
static struct ast_flags globalflags = { AJI_AUTOREGISTER };
+
+#ifdef REF_DEBUG
+#define client_ref(arg1,arg2) client_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define client_unref(arg1,arg2) client_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define buddy_ref(arg1,arg2) buddy_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define buddy_unref(arg1,arg2) buddy_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static struct aji_buddy *buddy_ref_debug(struct aji_buddy *b, char *tag, char *file, int line, const char *func)
+{
+ if (b) {
+ _ao2_ref_debug(b, 1, tag, file, line,func);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+ }
+
+ return b;
+}
+
+static void buddy_unref_debug(struct aji_buddy *b, char *tag, char *file, int line, const char *func)
+{
+ if (b) {
+ _ao2_ref_debug(b, -1, tag, file, line, func);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+ }
+}
+
+static struct aji_client *client_ref_debug(struct aji_client *c, char *tag, char *file, int line, const char *func)
+{
+ if (c) {
+ _ao2_ref_debug(c, 1, tag, file, line, func);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+ }
+
+ return c;
+}
+
+static void client_unref_debug(struct aji_client *c, char *tag, char *file, int line, const char *func)
+{
+ if (c) {
+ _ao2_ref_debug(c, -1, tag, file, line, func);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+ }
+}
+#else
+static struct aji_buddy *buddy_ref(struct aji_buddy *b, char *tag)
+{
+ if (b) {
+ ao2_ref(b, 1);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+ }
+
+ return b;
+}
+
+static void buddy_unref(struct aji_buddy *b, char *tag)
+{
+ if (b) {
+ ao2_ref(b, -1);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+ }
+}
+
+static struct aji_client *client_ref(struct aji_client *c, char *tag)
+{
+ if (c) {
+ ao2_ref(c, 1);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+ }
+
+ return c;
+}
+
+static void client_unref(struct aji_client *c, char *tag)
+{
+ if (c) {
+ ao2_ref(c, -1);
+ } else {
+ ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+ }
+}
+#endif
+
+static int client_cmp_cb(void *obj, void *arg, void *data, int flags)
+{
+ struct aji_client *client = obj, *client2 = arg;
+
+ return !strcasecmp(client->name, client2->name) ? CMP_MATCH : 0;
+}
+
+static int buddy_cmp_cb(void *obj, void *arg, void *data, int flags)
+{
+ struct aji_buddy *buddy = obj, *buddy2 = arg;
+
+ return !strcasecmp(buddy->name, buddy2->name) ? CMP_MATCH : 0;
+}
+
+static int buddy_hash_cb(const void *obj, const int flags)
+{
+ const struct aji_buddy *buddy = obj;
+
+ return ast_str_hash(buddy->name);
+}
+
+static int client_hash_cb(const void *obj, const int flags)
+{
+ const struct aji_client *client = obj;
+
+ return ast_str_hash(client->name);
+}
/*!
* \brief Deletes the aji_client data structure.
* \param obj aji_client The structure we will delete.
* \return void.
*/
-static void aji_client_destroy(struct aji_client *obj)
-{
+static void aji_client_destroy(void *obj)
+{
+ struct aji_client *c = obj;
struct aji_message *tmp;
- ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy);
- ASTOBJ_CONTAINER_DESTROY(&obj->buddies);
- iks_filter_delete(obj->f);
- iks_parser_delete(obj->p);
- iks_stack_delete(obj->stack);
- AST_LIST_LOCK(&obj->messages);
- while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) {
+ struct aji_buddy *b;
+ struct ao2_iterator biter;
+
+ biter = ao2_iterator_init(c->buddies, 0);
+
+ while( (b = ao2_t_iterator_next(&biter, "iterate thru buddies")) ) {
+ ao2_t_unlink(c->buddies, b, "Remove buddy from list");
+ buddy_unref(b, "unref buddy");
+ }
+
+ iks_filter_delete(c->f);
+ iks_parser_delete(c->p);
+ iks_stack_delete(c->stack);
+ AST_LIST_LOCK(&c->messages);
+ while ((tmp = AST_LIST_REMOVE_HEAD(&c->messages, list))) {
if (tmp->from)
ast_free(tmp->from);
if (tmp->message)
ast_free(tmp->message);
}
- AST_LIST_HEAD_DESTROY(&obj->messages);
- ast_free(obj);
+ AST_LIST_HEAD_DESTROY(&c->messages);
+
+ ao2_lock(clients); /* required locking for removal? */
+ ao2_t_unlink(clients,obj,"Remove client from list");
+ ao2_unlock(clients);
}
/*!
@@ -188,17 +322,18 @@
* \param obj aji_buddy The structure we will delete.
* \return void.
*/
-static void aji_buddy_destroy(struct aji_buddy *obj)
-{
+static void aji_buddy_destroy(void *obj)
+{
+ struct aji_buddy *b = obj;
struct aji_resource *tmp;
- while ((tmp = obj->resources)) {
- obj->resources = obj->resources->next;
+ while ((tmp = b->resources)) {
+ b->resources = b->resources->next;
ast_free(tmp->description);
ast_free(tmp);
}
- ast_free(obj);
+ ast_free(b);
}
/*!
@@ -343,6 +478,7 @@
{
struct aji_client *client = NULL;
struct aji_buddy *buddy = NULL;
+ struct aji_buddy tmp_buddy;
struct aji_resource *r = NULL;
char *s = NULL;
int stat = 7;
@@ -362,7 +498,7 @@
ast_log(LOG_WARNING, "JabberStatus is deprecated. Please use the JABBER_STATUS dialplan function in the future.\n");
if (!data) {
- ast_log(LOG_ERROR, "Usage: JabberStatus(<sender>,<jid>[/<resource>],<varname>\n");
+ ast_log(LOG_ERROR, "Usage: JabberStatus(<sender>,<screenname>[/<resource>],<varname>\n");
return 0;
}
s = ast_strdupa(data);
@@ -375,22 +511,33 @@
AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
+/* I NEED A FUNCTION */
if (!(client = ast_aji_get_client(args.sender))) {
ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
return -1;
}
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
+
+ ast_copy_string(tmp_buddy.name, jid.screenname, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
+
if (!buddy) {
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
+ client_unref(client, "unref client");
return -1;
}
+
r = aji_find_resource(buddy, jid.resource);
+
if (!r && buddy->resources)
r = buddy->resources;
if (!r)
ast_log(LOG_NOTICE, "Resource '%s' of buddy '%s' was not found\n", jid.resource, jid.screenname);
else
stat = r->status;
+
+ buddy_unref(buddy,"stat_exec");
+ client_unref(client, "unref client");
+/* END I NEED A FUNCTION */
snprintf(status, sizeof(status), "%d", stat);
pbx_builtin_setvar_helper(chan, args.variable, status);
return 0;
@@ -400,6 +547,7 @@
{
struct aji_client *client = NULL;
struct aji_buddy *buddy = NULL;
+ struct aji_buddy tmp_buddy;
struct aji_resource *r = NULL;
int stat = 7;
AST_DECLARE_APP_ARGS(args,
@@ -412,25 +560,28 @@
);
if (!data) {
- ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
+ ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<screenname>[/<resource>])\n");
return 0;
}
AST_STANDARD_APP_ARGS(args, data);
if (args.argc != 2) {
- ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
+ ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments.\n");
return -1;
}
AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
+/* I NEED A FUNCTION */
if (!(client = ast_aji_get_client(args.sender))) {
ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
return -1;
}
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
+ ast_copy_string(tmp_buddy.name, jid.screenname, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
if (!buddy) {
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
+ client_unref(client, "unref client");
return -1;
}
r = aji_find_resource(buddy, jid.resource);
@@ -440,6 +591,9 @@
ast_log(LOG_NOTICE, "Resource %s of buddy %s was not found.\n", jid.resource, jid.screenname);
else
stat = r->status;
+ buddy_unref(buddy,"stat_read");
+ client_unref(client, "unref client");
+/* END I NEED A FUNCTION */
snprintf(buf, buflen, "%d", stat);
return 0;
}
@@ -491,6 +645,8 @@
}
if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message))
ast_aji_send_chat(client, args.recipient, args.message);
+
+ client_unref(client, "unref client");
return 0;
}
@@ -774,7 +930,8 @@
*/
static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
+ client_ref(client,"log_hook");
if (!ast_strlen_zero(xmpp))
manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp);
@@ -784,15 +941,14 @@
ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
else {
if( strlen(xmpp) == 1) {
- if(option_debug > 2 && xmpp[0] == ' ') {
- ast_verbose("\nJABBER: Keep alive packet\n");
- }
+ if(option_debug > 2 && xmpp[0] == ' ')
+ ast_verbose("\nJABBER: Keep alive packet\n");
} else
ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
}
}
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client,"log_hook");
}
/*!
@@ -855,19 +1011,21 @@
*/
static int aji_act_hook(void *data, int type, iks *node)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
ikspak *pak = NULL;
iks *auth = NULL;
int features = 0;
+ client_ref(client,"act_hook");
+
if(!node) {
ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_packet");
return IKS_HOOK;
}
if (client->state == AJI_DISCONNECTING) {
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_disc");
return IKS_HOOK;
}
@@ -879,12 +1037,12 @@
if (client->usetls && !aji_is_secure(client)) {
#ifndef HAVE_OPENSSL
ast_log(LOG_ERROR, "OpenSSL not installed. You need to install OpenSSL on this system, or disable the TLS option in your configuration file\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client,"act_hook_no_openssl_tls");
return IKS_HOOK;
#else
if (aji_start_tls(client) == IKS_NET_TLSFAIL) {
ast_log(LOG_ERROR, "Could not start TLS\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client,"act_hook_openssl_tls");
return IKS_HOOK;
}
#endif
@@ -908,6 +1066,7 @@
#ifdef HAVE_OPENSSL
if (client->stream_flags & TRY_SECURE) {
if (!strcmp("proceed", iks_name(node))) {
+ client_unref(client,"try_sec");
return aji_tls_handshake(client);
}
}
@@ -952,7 +1111,7 @@
ret = aji_start_sasl(client, features, client->jid->user, client->password);
if (ret != IKS_OK) {
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_not_ok");
return IKS_HOOK;
}
break;
@@ -967,12 +1126,12 @@
break;
case IKS_NODE_ERROR:
ast_log(LOG_ERROR, "JABBER: Node Error\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_node_error");
return IKS_HOOK;
break;
case IKS_NODE_STOP:
ast_log(LOG_WARNING, "JABBER: Disconnected\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_discon_error");
return IKS_HOOK;
break;
}
@@ -985,7 +1144,8 @@
sprintf(secret, "%s%s", pak->id, client->password);
ast_sha1_hash(shasum, secret);
handshake = NULL;
- if (asprintf(&handshake, "<handshake>%s</handshake>", shasum) >= 0) {
+ asprintf(&handshake, "<handshake>%s</handshake>", shasum);
+ if (handshake) {
aji_send_raw(client, handshake);
ast_free(handshake);
handshake = NULL;
@@ -1004,12 +1164,12 @@
case IKS_NODE_ERROR:
ast_log(LOG_ERROR, "JABBER: Node Error\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_node_error");
return IKS_HOOK;
case IKS_NODE_STOP:
ast_log(LOG_WARNING, "JABBER: Disconnected\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "act_hook_discon_error");
return IKS_HOOK;
}
}
@@ -1044,20 +1204,21 @@
if (node)
iks_delete(node);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "end_act_hook");
return IKS_OK;
}
/*!
- * \brief Unknown
+ * \brief Uknown
* \param data void
* \param pak ikspak
* \return IKS_FILTER_EAT.
*/
static int aji_register_approve_handler(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
iks *iq = NULL, *presence = NULL, *x = NULL;
+ client_ref(client,"arpv_hand");
iq = iks_new("iq");
presence = iks_new("presence");
x = iks_new("x");
@@ -1087,29 +1248,29 @@
iks_delete(presence);
iks_delete(x);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "aprv_hand");
return IKS_FILTER_EAT;
}
/*!
- * \brief register handler for incoming querys (IQ's)
+ * \brief register query
* \param data incoming aji_client request
* \param pak ikspak
* \return IKS_FILTER_EAT.
*/
static int aji_register_query_handler(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
struct aji_buddy *buddy = NULL;
+ struct aji_buddy tmp_buddy;
char *node = NULL;
- iks *iq = NULL, *query = NULL;
-
- client = (struct aji_client *) data;
-
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+
+ client_ref(client,"qry_hand");
+ ast_copy_string(tmp_buddy.name, pak->from->partial,sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find Buddy");
if (!buddy) {
- iks *error = NULL, *notacceptable = NULL;
-
- ast_log(LOG_ERROR, "Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
+ iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL;
+
+ ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
iq = iks_new("iq");
query = iks_new("query");
error = iks_new("error");
@@ -1131,10 +1292,12 @@
ast_log(LOG_ERROR, "Out of memory.\n");
}
+ iks_delete(iq);
+ iks_delete(query);
iks_delete(error);
iks_delete(notacceptable);
} else if (!(node = iks_find_attrib(pak->query, "node"))) {
- iks *instructions = NULL;
+ iks *iq = NULL, *query = NULL, *instructions = NULL;
char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
iq = iks_new("iq");
query = iks_new("query");
@@ -1153,11 +1316,12 @@
ast_log(LOG_ERROR, "Out of memory.\n");
}
+ iks_delete(iq);
+ iks_delete(query);
iks_delete(instructions);
}
- iks_delete(iq);
- iks_delete(query);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ buddy_unref(buddy, "qry_hand");
+ client_unref(client, "qry_hand");
return IKS_FILTER_EAT;
}
@@ -1169,8 +1333,10 @@
*/
static int aji_ditems_handler(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
char *node = NULL;
+
+ client_ref(client,"itm_hand");
if (!(node = iks_find_attrib(pak->query, "node"))) {
iks *iq = NULL, *query = NULL, *item = NULL;
@@ -1252,7 +1418,7 @@
iks_delete(feature);
}
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "itm_hand");
return IKS_FILTER_EAT;
}
@@ -1264,15 +1430,20 @@
*/
static int aji_client_info_handler(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
struct aji_resource *resource = NULL;
- struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
+ struct aji_buddy *buddy = NULL;
+ struct aji_buddy tmp_buddy;
+
+ client_ref(client, "info_hand");
+ ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
resource = aji_find_resource(buddy, pak->from->resource);
+
if (pak->subtype == IKS_TYPE_RESULT) {
if (!resource) {
- ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
+ client_unref(client, "info_hand");
return IKS_FILTER_EAT;
}
if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
@@ -1313,7 +1484,8 @@
} else if (pak->subtype == IKS_TYPE_ERROR) {
ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
}
- ASTOBJ_UNREF(client, aji_client_destroy);
+ buddy_unref(buddy,"info_hand");
+ client_unref(client, "info_hand");
return IKS_FILTER_EAT;
}
/*!
@@ -1324,20 +1496,28 @@
*/
static int aji_dinfo_handler(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
+ struct aji_resource *resource = NULL;
+ struct aji_buddy *buddy = NULL;
+ struct aji_buddy tmp_buddy;
char *node = NULL;
- struct aji_resource *resource = NULL;
- struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
+
+ client_ref(client, "dinfo_hand");
+ ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
resource = aji_find_resource(buddy, pak->from->resource);
+
if (pak->subtype == IKS_TYPE_ERROR) {
ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n");
+ buddy_unref(buddy, "dinfo_hand");
+ client_unref(client, "dinfo_hand");
return IKS_FILTER_EAT;
}
if (pak->subtype == IKS_TYPE_RESULT) {
if (!resource) {
ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ buddy_unref(buddy, "dinfo_hand");
+ client_unref(client, "dinfo_hand");
return IKS_FILTER_EAT;
}
if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
@@ -1453,7 +1633,8 @@
iks_delete(feature);
}
- ASTOBJ_UNREF(client, aji_client_destroy);
+ buddy_unref(buddy, "dinfo_hand");
+ client_unref(client, "dinfo_hand");
return IKS_FILTER_EAT;
}
@@ -1516,14 +1697,16 @@
static void aji_handle_presence(struct aji_client *client, ikspak *pak)
{
int status, priority;
- struct aji_buddy *buddy;
+ struct aji_buddy tmp_buddy, *buddy;
struct aji_resource *tmp = NULL, *last = NULL, *found = NULL;
char *ver, *node, *descrip, *type;
if(client->state != AJI_CONNECTED)
aji_create_buddy(pak->from->partial, client);
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+ ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find Buddy");
+
if (!buddy && pak->from->partial) {
/* allow our jid to be used to log in with another resource */
if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial))
@@ -1532,16 +1715,19 @@
ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial);
return;
}
+
type = iks_find_attrib(pak->x, "type");
+
if(client->component && type &&!strcasecmp("probe", type)) {
aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
ast_verbose("what i was looking for \n");
}
- ASTOBJ_WRLOCK(buddy);
+
status = (pak->show) ? pak->show : 6;
priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
tmp = buddy->resources;
descrip = ast_strdup(iks_find_cdata(pak->x,"status"));
+ ao2_lock(buddy);
while (tmp && pak->from->resource) {
if (!strcasecmp(tmp->resource, pak->from->resource)) {
@@ -1650,8 +1836,8 @@
buddy->resources = found;
}
- ASTOBJ_UNLOCK(buddy);
- ASTOBJ_UNREF(buddy, aji_buddy_destroy);
+ ao2_unlock(buddy);
+ buddy_unref(buddy, "hld_pres");
node = iks_find_attrib(iks_find(pak->x, "c"), "node");
ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
@@ -1735,6 +1921,7 @@
{
iks *presence = NULL, *status = NULL;
struct aji_buddy* buddy = NULL;
+ struct aji_buddy tmp_buddy;
switch (pak->subtype) {
case IKS_TYPE_SUBSCRIBE:
@@ -1758,14 +1945,15 @@
if (client->component)
aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
case IKS_TYPE_SUBSCRIBED:
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+ ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+ buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
if (!buddy && pak->from->partial) {
aji_create_buddy(pak->from->partial, client);
+ } else {
+ buddy_unref(buddy,"hand_sub");
}
default:
- if (option_verbose > 4) {
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype);
- }
+ ast_verb(3, "JABBER: This is a subcription of type %i\n", pak->subtype);
}
}
@@ -1896,11 +2084,13 @@
*/
static void *aji_recv_loop(void *data)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
int res = IKS_HOOK;
+ client_ref(client,"recv_loop");
+
while(res != IKS_OK) {
- ast_debug(3, "JABBER: Connecting.\n");
+ ast_verb(4, "JABBER: Connecting.\n");
res = aji_reconnect(client);
sleep(4);
}
@@ -1938,7 +2128,7 @@
} else if (res == IKS_NET_RWERR)
ast_log(LOG_WARNING, "JABBER: socket read error\n");
} while (client);
- ASTOBJ_UNREF(client, aji_client_destroy);
+ client_unref(client, "recv_loop");
return 0;
}
@@ -2053,11 +2243,13 @@
* \brief goes through roster and prunes users not needed in list, or adds them accordingly.
* \param client the configured XMPP client we use to connect to a XMPP server
* \return void.
- * \note The messages here should be configurable.
*/
static void aji_pruneregister(struct aji_client *client)
{
int res = 0;
+ struct ao2_iterator biter;
+ struct aji_buddy *b = NULL;
+
iks *removeiq = iks_new("iq");
iks *removequery = iks_new("query");
iks *removeitem = iks_new("item");
@@ -2069,30 +2261,33 @@
iks_insert_node(removeiq, removequery);
iks_insert_node(removequery, removeitem);
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
+ biter = ao2_iterator_init(client->buddies, 0);
+
+ while ((b = ao2_t_iterator_next(&biter, "Iter through buddies"))) {
+ ao2_lock(b);
/* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never
* be called at the same time */
- if (ast_test_flag(&iterator->flags, AJI_AUTOPRUNE)) { /* If autoprune is set on jabber.conf */
- res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
- "GoodBye. Your status is no longer needed by Asterisk the Open Source PBX"
+ if (ast_test_flag(&b->flags, AJI_AUTOPRUNE)) {
+ res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, b->name,
+ "GoodBye your status is no longer needed by Asterisk the Open Source PBX"
" so I am no longer subscribing to your presence.\n"));
- res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
- "GoodBye. You are no longer in the Asterisk config file so I am removing"
+ res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, b->name,
+ "GoodBye you are no longer in the asterisk config file so I am removing"
" your access to my presence.\n"));
iks_insert_attrib(removeiq, "from", client->jid->full);
iks_insert_attrib(removeiq, "type", "set");
iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster");
- iks_insert_attrib(removeitem, "jid", iterator->name);
+ iks_insert_attrib(removeitem, "jid", b->name);
iks_insert_attrib(removeitem, "subscription", "remove");
res = ast_aji_send(client, removeiq);
- } else if (ast_test_flag(&iterator->flags, AJI_AUTOREGISTER)) {
- res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name,
- "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
- ast_clear_flag(&iterator->flags, AJI_AUTOREGISTER);
- }
- ASTOBJ_UNLOCK(iterator);
- });
+ } else if (ast_test_flag(&b->flags, AJI_AUTOREGISTER)) {
+ res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, b->name,
+ "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
+ ast_clear_flag(&b->flags, AJI_AUTOREGISTER);
+ }
+ ao2_unlock(b);
+ buddy_unref(b,"iter list");
+ }
safeout:
iks_delete(removeiq);
@@ -2100,7 +2295,6 @@
iks_delete(removeitem);
iks_delete(send);
- ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy);
}
/*!
@@ -2111,42 +2305,46 @@
*/
static int aji_filter_roster(void *data, ikspak *pak)
{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+ struct aji_client *client = (struct aji_client *) data;
+ struct aji_buddy *buddy = NULL, *b = NULL;
+ struct ao2_iterator biter;
int flag = 0;
iks *x = NULL;
- struct aji_buddy *buddy;
-
+
+ client_ref(client, "filter_ros");
client->state = AJI_CONNECTED;
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
+ biter= ao2_iterator_init(client->buddies, 0);
+ while ((b = ao2_t_iterator_next(&biter, "iterate through buddies"))) {
+ ao2_lock(b);
x = iks_child(pak->query);
flag = 0;
while (x) {
if (!iks_strcmp(iks_name(x), "item")) {
- if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) {
+ if (!strcasecmp(b->name, iks_find_attrib(x, "jid"))) {
flag = 1;
- ast_clear_flag(&iterator->flags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
+ ast_clear_flag(&b->flags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
}
}
x = iks_next(x);
}
- if (!flag)
- ast_copy_flags(&iterator->flags, &client->flags, AJI_AUTOREGISTER);
+ if (!flag) {
+ ast_copy_flags(&b->flags, &client->flags, AJI_AUTOREGISTER);
+ }
iks_delete(x);
-
- ASTOBJ_UNLOCK(iterator);
- });
+ ao2_unlock(b);
+ buddy_unref(b, "filter_ros");
+ }
x = iks_child(pak->query);
while (x) {
flag = 0;
if (iks_strcmp(iks_name(x), "item") == 0) {
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid")))
+ biter = ao2_iterator_init(client->buddies, 0);
+ while ((b = ao2_t_iterator_next(&biter,"iter through buddies"))) {
+ if (!strcasecmp(b->name, iks_find_attrib(x, "jid")))
flag = 1;
- ASTOBJ_UNLOCK(iterator);
- });
+ buddy_unref(b, "filter_ros");
+ }
if (flag) {
/* found buddy, don't create a new one */
@@ -2154,28 +2352,26 @@
[... 659 lines stripped ...]
More information about the asterisk-commits
mailing list