mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-06 13:07:21 +00:00
res_xmpp: Correct implementation of JABBER_STATUS & JabberStatus
The documentation for JABBER_STATUS (and the deprecated JabberStatus app) indicate that a return value of 7 indicates that the specified buddy was not in the roster. It also indicates that you can specify a "bare" JID (one without a resource). Unfortunately the actual behavior does not match the documented behavior. Assuming that our roster includes the buddy online and available "valid@example.org/Valid" and does *not* include the buddy "invalid@example.org", the JABBER_STATUS() function returns the following before this patch: +------------------------------+------------+--------------------------+ | Buddy | Status | Result | +------------------------------+------------+--------------------------+ | valid@example.org | Online | 7 (Not in roster) | | valid@example.org/Valid | Online | 1 (Online) | | valid@example.org/Invalid | N/A | 7 (Not in roster) | | invalid@example.org | N/A | Error logged, no return | | invalid@example.org/Valid | N/A | Error logged, no return | +------------------------------+------------+--------------------------+ And after this patch: +------------------------------+------------+--------------------------+ | Buddy | Status | Result | +------------------------------+------------+--------------------------+ | valid@example.org | Online | 1 (Online) | | valid@example.org/Valid | Online | 1 (Online) | | valid@example.org/Invalid | N/A | 6 (Offline) | | invalid@example.org | N/A | 7 (Not in roster) | | invalid@example.org/Valid | N/A | 7 (Not in roster) | +------------------------------+------------+--------------------------+ This brings the behavior in line with the documentation. ASTERISK-23510 #close Reported by: Anthony Critelli Change-Id: I9c3241035363ef4a6bdc21fabfd8ffcd9ec657bf
This commit is contained in:
@@ -1632,6 +1632,35 @@ static int xmpp_resource_immediate(void *obj, void *arg, int flags)
|
|||||||
return CMP_MATCH | CMP_STOP;
|
return CMP_MATCH | CMP_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BUDDY_OFFLINE 6
|
||||||
|
#define BUDDY_NOT_IN_ROSTER 7
|
||||||
|
|
||||||
|
static int get_buddy_status(struct ast_xmpp_client_config *clientcfg, char *screenname, char *resource)
|
||||||
|
{
|
||||||
|
int status = BUDDY_OFFLINE;
|
||||||
|
struct ast_xmpp_resource *res;
|
||||||
|
struct ast_xmpp_buddy *buddy = ao2_find(clientcfg->client->buddies, screenname, OBJ_KEY);
|
||||||
|
|
||||||
|
if (!buddy) {
|
||||||
|
return BUDDY_NOT_IN_ROSTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ao2_callback(
|
||||||
|
buddy->resources,
|
||||||
|
0,
|
||||||
|
ast_strlen_zero(resource) ? xmpp_resource_immediate : xmpp_resource_cmp,
|
||||||
|
resource);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
status = res->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ao2_cleanup(res);
|
||||||
|
ao2_cleanup(buddy);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \internal
|
* \internal
|
||||||
* \brief Dial plan function status(). puts the status of watched user
|
* \brief Dial plan function status(). puts the status of watched user
|
||||||
@@ -1645,10 +1674,7 @@ static int xmpp_status_exec(struct ast_channel *chan, const char *data)
|
|||||||
{
|
{
|
||||||
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
|
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
|
||||||
RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
|
||||||
struct ast_xmpp_buddy *buddy;
|
|
||||||
struct ast_xmpp_resource *resource;
|
|
||||||
char *s = NULL, status[2];
|
char *s = NULL, status[2];
|
||||||
int stat = 7;
|
|
||||||
static int deprecation_warning = 0;
|
static int deprecation_warning = 0;
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(sender);
|
AST_APP_ARG(sender);
|
||||||
@@ -1687,25 +1713,7 @@ static int xmpp_status_exec(struct ast_channel *chan, const char *data)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buddy = ao2_find(clientcfg->client->buddies, jid.screenname, OBJ_KEY))) {
|
snprintf(status, sizeof(status), "%d", get_buddy_status(clientcfg, jid.screenname, jid.resource));
|
||||||
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ast_strlen_zero(jid.resource) || !(resource = ao2_callback(buddy->resources, 0, xmpp_resource_cmp, jid.resource))) {
|
|
||||||
resource = ao2_callback(buddy->resources, OBJ_NODATA, xmpp_resource_immediate, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ao2_ref(buddy, -1);
|
|
||||||
|
|
||||||
if (resource) {
|
|
||||||
stat = resource->status;
|
|
||||||
ao2_ref(resource, -1);
|
|
||||||
} else {
|
|
||||||
ast_log(LOG_NOTICE, "Resource '%s' of buddy '%s' was not found\n", jid.resource, jid.screenname);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(status, sizeof(status), "%d", stat);
|
|
||||||
pbx_builtin_setvar_helper(chan, args.variable, status);
|
pbx_builtin_setvar_helper(chan, args.variable, status);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1724,9 +1732,6 @@ static int acf_jabberstatus_read(struct ast_channel *chan, const char *name, cha
|
|||||||
{
|
{
|
||||||
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
|
RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
|
||||||
RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
|
||||||
struct ast_xmpp_buddy *buddy;
|
|
||||||
struct ast_xmpp_resource *resource;
|
|
||||||
int stat = 7;
|
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(sender);
|
AST_APP_ARG(sender);
|
||||||
AST_APP_ARG(jid);
|
AST_APP_ARG(jid);
|
||||||
@@ -1758,25 +1763,7 @@ static int acf_jabberstatus_read(struct ast_channel *chan, const char *name, cha
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buddy = ao2_find(clientcfg->client->buddies, jid.screenname, OBJ_KEY))) {
|
snprintf(buf, buflen, "%d", get_buddy_status(clientcfg, jid.screenname, jid.resource));
|
||||||
ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ast_strlen_zero(jid.resource) || !(resource = ao2_callback(buddy->resources, 0, xmpp_resource_cmp, jid.resource))) {
|
|
||||||
resource = ao2_callback(buddy->resources, OBJ_NODATA, xmpp_resource_immediate, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ao2_ref(buddy, -1);
|
|
||||||
|
|
||||||
if (resource) {
|
|
||||||
stat = resource->status;
|
|
||||||
ao2_ref(resource, -1);
|
|
||||||
} else {
|
|
||||||
ast_log(LOG_NOTICE, "Resource %s of buddy %s was not found.\n", jid.resource, jid.screenname);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(buf, buflen, "%d", stat);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user