mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
wip - refactoring capabilities
This commit is contained in:
parent
93058636ce
commit
99c0b3f2cf
@ -61,62 +61,15 @@ caps_init(void)
|
||||
}
|
||||
|
||||
void
|
||||
caps_add(const char * const caps_str, const char * const category,
|
||||
const char * const type, const char * const name,
|
||||
const char * const software, const char * const software_version,
|
||||
const char * const os, const char * const os_version,
|
||||
GSList *features)
|
||||
caps_add(const char * const ver, Capabilities *caps)
|
||||
{
|
||||
Capabilities *new_caps = malloc(sizeof(struct capabilities_t));
|
||||
|
||||
if (category != NULL) {
|
||||
new_caps->category = strdup(category);
|
||||
} else {
|
||||
new_caps->category = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
new_caps->type = strdup(type);
|
||||
} else {
|
||||
new_caps->type = NULL;
|
||||
}
|
||||
if (name != NULL) {
|
||||
new_caps->name = strdup(name);
|
||||
} else {
|
||||
new_caps->name = NULL;
|
||||
}
|
||||
if (software != NULL) {
|
||||
new_caps->software = strdup(software);
|
||||
} else {
|
||||
new_caps->software = NULL;
|
||||
}
|
||||
if (software_version != NULL) {
|
||||
new_caps->software_version = strdup(software_version);
|
||||
} else {
|
||||
new_caps->software_version = NULL;
|
||||
}
|
||||
if (os != NULL) {
|
||||
new_caps->os = strdup(os);
|
||||
} else {
|
||||
new_caps->os = NULL;
|
||||
}
|
||||
if (os_version != NULL) {
|
||||
new_caps->os_version = strdup(os_version);
|
||||
} else {
|
||||
new_caps->os_version = NULL;
|
||||
}
|
||||
if (features != NULL) {
|
||||
new_caps->features = features;
|
||||
} else {
|
||||
new_caps->features = NULL;
|
||||
}
|
||||
|
||||
g_hash_table_insert(capabilities, strdup(caps_str), new_caps);
|
||||
g_hash_table_insert(capabilities, strdup(ver), caps);
|
||||
}
|
||||
|
||||
gboolean
|
||||
caps_contains(const char * const caps_str)
|
||||
caps_contains(const char * const caps_ver)
|
||||
{
|
||||
return (g_hash_table_lookup(capabilities, caps_str) != NULL);
|
||||
return (g_hash_table_lookup(capabilities, caps_ver) != NULL);
|
||||
}
|
||||
|
||||
static Capabilities *
|
||||
@ -228,6 +181,109 @@ caps_create_sha1_str(xmpp_stanza_t * const query)
|
||||
return result;
|
||||
}
|
||||
|
||||
Capabilities *
|
||||
caps_create(xmpp_stanza_t *query)
|
||||
{
|
||||
const char *category = NULL;
|
||||
const char *type = NULL;
|
||||
const char *name = NULL;
|
||||
const char *software = NULL;
|
||||
const char *software_version = NULL;
|
||||
const char *os = NULL;
|
||||
const char *os_version = NULL;
|
||||
GSList *features = NULL;
|
||||
|
||||
xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
|
||||
if (identity != NULL) {
|
||||
category = xmpp_stanza_get_attribute(identity, "category");
|
||||
type = xmpp_stanza_get_attribute(identity, "type");
|
||||
name = xmpp_stanza_get_attribute(identity, "name");
|
||||
}
|
||||
|
||||
xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
|
||||
if (softwareinfo != NULL) {
|
||||
DataForm *form = form_create(softwareinfo);
|
||||
FormField *formField = NULL;
|
||||
|
||||
char *form_type = form_get_form_type_field(form);
|
||||
if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) {
|
||||
GSList *field = form->fields;
|
||||
while (field != NULL) {
|
||||
formField = field->data;
|
||||
if (formField->values != NULL) {
|
||||
if (strcmp(formField->var, "software") == 0) {
|
||||
software = formField->values->data;
|
||||
} else if (strcmp(formField->var, "software_version") == 0) {
|
||||
software_version = formField->values->data;
|
||||
} else if (strcmp(formField->var, "os") == 0) {
|
||||
os = formField->values->data;
|
||||
} else if (strcmp(formField->var, "os_version") == 0) {
|
||||
os_version = formField->values->data;
|
||||
}
|
||||
}
|
||||
field = g_slist_next(field);
|
||||
}
|
||||
}
|
||||
|
||||
form_destroy(form);
|
||||
}
|
||||
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||
while (child != NULL) {
|
||||
if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) {
|
||||
features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var")));
|
||||
}
|
||||
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
Capabilities *new_caps = malloc(sizeof(struct capabilities_t));
|
||||
|
||||
if (category != NULL) {
|
||||
new_caps->category = strdup(category);
|
||||
} else {
|
||||
new_caps->category = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
new_caps->type = strdup(type);
|
||||
} else {
|
||||
new_caps->type = NULL;
|
||||
}
|
||||
if (name != NULL) {
|
||||
new_caps->name = strdup(name);
|
||||
} else {
|
||||
new_caps->name = NULL;
|
||||
}
|
||||
if (software != NULL) {
|
||||
new_caps->software = strdup(software);
|
||||
} else {
|
||||
new_caps->software = NULL;
|
||||
}
|
||||
if (software_version != NULL) {
|
||||
new_caps->software_version = strdup(software_version);
|
||||
} else {
|
||||
new_caps->software_version = NULL;
|
||||
}
|
||||
if (os != NULL) {
|
||||
new_caps->os = strdup(os);
|
||||
} else {
|
||||
new_caps->os = NULL;
|
||||
}
|
||||
if (os_version != NULL) {
|
||||
new_caps->os_version = strdup(os_version);
|
||||
} else {
|
||||
new_caps->os_version = NULL;
|
||||
}
|
||||
if (features != NULL) {
|
||||
new_caps->features = features;
|
||||
} else {
|
||||
new_caps->features = NULL;
|
||||
}
|
||||
|
||||
return new_caps;
|
||||
}
|
||||
|
||||
|
||||
xmpp_stanza_t *
|
||||
caps_create_query_response_stanza(xmpp_ctx_t * const ctx)
|
||||
{
|
||||
|
@ -40,12 +40,10 @@
|
||||
#include "xmpp/xmpp.h"
|
||||
|
||||
void caps_init(void);
|
||||
void caps_add(const char * const caps_str, const char * const category,
|
||||
const char * const type, const char * const name,
|
||||
const char * const software, const char * const software_version,
|
||||
const char * const os, const char * const os_version, GSList *features);
|
||||
gboolean caps_contains(const char * const caps_str);
|
||||
void caps_add(const char * const ver, Capabilities *caps);
|
||||
gboolean caps_contains(const char * const caps_ver);
|
||||
char* caps_create_sha1_str(xmpp_stanza_t * const query);
|
||||
xmpp_stanza_t* caps_create_query_response_stanza(xmpp_ctx_t * const ctx);
|
||||
Capabilities* caps_create(xmpp_stanza_t *query);
|
||||
|
||||
#endif
|
||||
|
275
src/xmpp/iq.c
275
src/xmpp/iq.c
@ -66,7 +66,7 @@ static int _version_get_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_info_get_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _disco_info_result_handler(xmpp_conn_t * const conn,
|
||||
static int _disco_info_response_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _version_result_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
@ -84,6 +84,8 @@ static int _manual_pong_handler(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
static int _ping_timed_handler(xmpp_conn_t * const conn,
|
||||
void * const userdata);
|
||||
static int _caps_response_handler(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata);
|
||||
|
||||
void
|
||||
iq_add_handlers(void)
|
||||
@ -94,7 +96,6 @@ iq_add_handlers(void)
|
||||
HANDLE(NULL, STANZA_TYPE_ERROR, _error_handler);
|
||||
|
||||
HANDLE(XMPP_NS_DISCO_INFO, STANZA_TYPE_GET, _disco_info_get_handler);
|
||||
HANDLE(XMPP_NS_DISCO_INFO, STANZA_TYPE_RESULT, _disco_info_result_handler);
|
||||
|
||||
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_GET, _disco_items_get_handler);
|
||||
HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_RESULT, _disco_items_result_handler);
|
||||
@ -142,7 +143,38 @@ _iq_disco_info_request(gchar *jid)
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, "discoinforeq", jid, NULL);
|
||||
char *id = create_unique_id("disco_info");
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, jid, NULL);
|
||||
|
||||
xmpp_id_handler_add(conn, _disco_info_response_handler, id, NULL);
|
||||
|
||||
xmpp_send(conn, iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
|
||||
static void
|
||||
_iq_send_caps_request(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver)
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
|
||||
if (!node) {
|
||||
log_error("Could not create caps request, no node");
|
||||
return;
|
||||
}
|
||||
if (!ver) {
|
||||
log_error("Could not create caps request, no ver");
|
||||
return;
|
||||
}
|
||||
|
||||
GString *node_str = g_string_new("");
|
||||
g_string_printf(node_str, "%s#%s", node, ver);
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
|
||||
g_string_free(node_str, TRUE);
|
||||
|
||||
xmpp_id_handler_add(conn, _caps_response_handler, id, NULL);
|
||||
|
||||
xmpp_send(conn, iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
@ -303,6 +335,51 @@ _pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
{
|
||||
const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
|
||||
if (id) {
|
||||
log_info("Capabilities response handler fired for id %s", id);
|
||||
} else {
|
||||
log_info("Capabilities response handler fired");
|
||||
}
|
||||
|
||||
char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
||||
if (node == NULL) {
|
||||
log_warning("No node attribute found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// validate sha1
|
||||
gchar **split = g_strsplit(node, "#", -1);
|
||||
char *given_sha1 = split[1];
|
||||
char *generated_sha1 = caps_create_sha1_str(query);
|
||||
|
||||
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
||||
log_warning("Generated sha-1 does not match given:");
|
||||
log_warning("Generated : %s", generated_sha1);
|
||||
log_warning("Given : %s", given_sha1);
|
||||
} else {
|
||||
log_info("Valid SHA-1 hash found: %s", given_sha1);
|
||||
|
||||
if (caps_contains(given_sha1)) {
|
||||
log_info("Capabilties cached");
|
||||
} else {
|
||||
log_info("Capabilities not cached, storing");
|
||||
Capabilities *capabilities = caps_create(query);
|
||||
caps_add(given_sha1, capabilities);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(generated_sha1);
|
||||
g_strfreev(split);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
@ -710,171 +787,60 @@ _item_destroy(DiscoItem *item)
|
||||
}
|
||||
|
||||
static int
|
||||
_disco_info_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||
_disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
{
|
||||
log_debug("Received diso#info response");
|
||||
const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
|
||||
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||
|
||||
if (g_strcmp0(id, "discoinforeq") == 0) {
|
||||
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
|
||||
if (query != NULL) {
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||
GSList *identities = NULL;
|
||||
GSList *features = NULL;
|
||||
while (child != NULL) {
|
||||
const char *stanza_name = xmpp_stanza_get_name(child);
|
||||
if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) {
|
||||
const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR);
|
||||
if (var != NULL) {
|
||||
features = g_slist_append(features, strdup(var));
|
||||
}
|
||||
} else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) {
|
||||
const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
|
||||
const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE);
|
||||
const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY);
|
||||
|
||||
if ((name != NULL) || (category != NULL) || (type != NULL)) {
|
||||
DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t));
|
||||
|
||||
if (name != NULL) {
|
||||
identity->name = strdup(name);
|
||||
} else {
|
||||
identity->name = NULL;
|
||||
}
|
||||
if (category != NULL) {
|
||||
identity->category = strdup(category);
|
||||
} else {
|
||||
identity->category = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
identity->type = strdup(type);
|
||||
} else {
|
||||
identity->type = NULL;
|
||||
}
|
||||
|
||||
identities = g_slist_append(identities, identity);
|
||||
}
|
||||
}
|
||||
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
handle_disco_info(from, identities, features);
|
||||
g_slist_free_full(features, free);
|
||||
g_slist_free_full(identities, (GDestroyNotify)_identity_destroy);
|
||||
}
|
||||
} else if ((id != NULL) && (g_str_has_prefix(id, "capsreq"))) {
|
||||
log_debug("Response to query: %s", id);
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
||||
if (node == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *caps_key = NULL;
|
||||
|
||||
// xep-0115
|
||||
if (g_strcmp0(id, "capsreq") == 0) {
|
||||
log_debug("xep-0115 supported capabilities");
|
||||
caps_key = strdup(node);
|
||||
|
||||
// validate sha1
|
||||
gchar **split = g_strsplit(node, "#", -1);
|
||||
char *given_sha1 = split[1];
|
||||
char *generated_sha1 = caps_create_sha1_str(query);
|
||||
|
||||
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
||||
log_info("Generated sha-1 does not match given:");
|
||||
log_info("Generated : %s", generated_sha1);
|
||||
log_info("Given : %s", given_sha1);
|
||||
g_free(generated_sha1);
|
||||
g_strfreev(split);
|
||||
free(caps_key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
g_free(generated_sha1);
|
||||
g_strfreev(split);
|
||||
|
||||
// non supported hash, or legacy caps
|
||||
} else {
|
||||
log_debug("Unsupported hash, or legacy capabilities");
|
||||
caps_key = strdup(id + 8);
|
||||
log_debug("Caps key: %s", caps_key);
|
||||
}
|
||||
|
||||
// already cached
|
||||
if (caps_contains(caps_key)) {
|
||||
log_info("Client info already cached.");
|
||||
free(caps_key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("Client info not cached");
|
||||
|
||||
const char *category = NULL;
|
||||
const char *type = NULL;
|
||||
const char *name = NULL;
|
||||
const char *software = NULL;
|
||||
const char *software_version = NULL;
|
||||
const char *os = NULL;
|
||||
const char *os_version = NULL;
|
||||
GSList *features = NULL;
|
||||
|
||||
xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
|
||||
if (identity != NULL) {
|
||||
category = xmpp_stanza_get_attribute(identity, "category");
|
||||
type = xmpp_stanza_get_attribute(identity, "type");
|
||||
name = xmpp_stanza_get_attribute(identity, "name");
|
||||
}
|
||||
|
||||
xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
|
||||
if (softwareinfo != NULL) {
|
||||
DataForm *form = form_create(softwareinfo);
|
||||
FormField *formField = NULL;
|
||||
|
||||
char *form_type = form_get_form_type_field(form);
|
||||
if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) {
|
||||
GSList *field = form->fields;
|
||||
while (field != NULL) {
|
||||
formField = field->data;
|
||||
if (formField->values != NULL) {
|
||||
if (strcmp(formField->var, "software") == 0) {
|
||||
software = formField->values->data;
|
||||
} else if (strcmp(formField->var, "software_version") == 0) {
|
||||
software_version = formField->values->data;
|
||||
} else if (strcmp(formField->var, "os") == 0) {
|
||||
os = formField->values->data;
|
||||
} else if (strcmp(formField->var, "os_version") == 0) {
|
||||
os_version = formField->values->data;
|
||||
}
|
||||
}
|
||||
field = g_slist_next(field);
|
||||
}
|
||||
}
|
||||
|
||||
form_destroy(form);
|
||||
}
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
|
||||
if (query != NULL) {
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||
GSList *identities = NULL;
|
||||
GSList *features = NULL;
|
||||
while (child != NULL) {
|
||||
if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) {
|
||||
features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var")));
|
||||
const char *stanza_name = xmpp_stanza_get_name(child);
|
||||
if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) {
|
||||
const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR);
|
||||
if (var != NULL) {
|
||||
features = g_slist_append(features, strdup(var));
|
||||
}
|
||||
} else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) {
|
||||
const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
|
||||
const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE);
|
||||
const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY);
|
||||
|
||||
if ((name != NULL) || (category != NULL) || (type != NULL)) {
|
||||
DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t));
|
||||
|
||||
if (name != NULL) {
|
||||
identity->name = strdup(name);
|
||||
} else {
|
||||
identity->name = NULL;
|
||||
}
|
||||
if (category != NULL) {
|
||||
identity->category = strdup(category);
|
||||
} else {
|
||||
identity->category = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
identity->type = strdup(type);
|
||||
} else {
|
||||
identity->type = NULL;
|
||||
}
|
||||
|
||||
identities = g_slist_append(identities, identity);
|
||||
}
|
||||
}
|
||||
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
caps_add(caps_key, category, type, name, software, software_version,
|
||||
os, os_version, features);
|
||||
|
||||
free(caps_key);
|
||||
handle_disco_info(from, identities, features);
|
||||
g_slist_free_full(features, free);
|
||||
g_slist_free_full(identities, (GDestroyNotify)_identity_destroy);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -941,4 +907,5 @@ iq_init_module(void)
|
||||
iq_request_room_config_form = _iq_request_room_config_form;
|
||||
iq_room_config_cancel = _iq_room_config_cancel;
|
||||
iq_submit_room_config = _iq_submit_room_config;
|
||||
iq_send_caps_request = _iq_send_caps_request;
|
||||
}
|
||||
|
@ -581,12 +581,46 @@ _available_handler(xmpp_conn_t * const conn,
|
||||
free(priority_str);
|
||||
}
|
||||
|
||||
// get capabilities key
|
||||
char *caps_key = NULL;
|
||||
// send disco info for capabilities, if not cached
|
||||
if (stanza_contains_caps(stanza)) {
|
||||
caps_key = _get_caps_key(stanza);
|
||||
log_info("Presence contains capabilities.");
|
||||
|
||||
char *hash = stanza_caps_get_hash(stanza);
|
||||
|
||||
// hash supported xep-0115
|
||||
if (g_strcmp0(hash, "sha-1") == 0) {
|
||||
log_info("Hash %s supported");
|
||||
|
||||
char *ver = stanza_get_caps_ver(stanza);
|
||||
if (caps_contains(ver)) {
|
||||
log_info("Capabilities cached");
|
||||
} else {
|
||||
log_info("Capabilities not cached, sending service discovery request");
|
||||
char *node = stanza_caps_get_node(stanza);
|
||||
char *id = create_unique_id("caps");
|
||||
|
||||
iq_send_caps_request(from, id, node, ver);
|
||||
|
||||
// send service discovery request
|
||||
// with id handler to validate response,
|
||||
// generate hash,
|
||||
// if match, cache against hash
|
||||
}
|
||||
|
||||
// no hash, or not supported
|
||||
} else {
|
||||
if (hash) {
|
||||
log_info("Hash %s not supported, not sending service discovery request");
|
||||
// send service discovery request, cache against from full jid
|
||||
} else {
|
||||
log_info("No hash specified, not sending service discovery request");
|
||||
// do legacy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *caps_key = strdup("hello");
|
||||
|
||||
// create Resource
|
||||
Resource *resource = NULL;
|
||||
resource_presence_t presence = resource_presence_from_string(show_str);
|
||||
@ -648,8 +682,6 @@ _get_caps_key(xmpp_stanza_t * const stanza)
|
||||
char *caps_key = NULL;
|
||||
char *id = NULL;
|
||||
|
||||
log_debug("Presence contains capabilities.");
|
||||
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -973,11 +973,12 @@ stanza_contains_caps(xmpp_stanza_t * const stanza)
|
||||
{
|
||||
xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
|
||||
|
||||
if (caps == NULL) {
|
||||
if (!caps) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strcmp(xmpp_stanza_get_ns(caps), STANZA_NS_CAPS) != 0) {
|
||||
char *ns = xmpp_stanza_get_ns(caps);
|
||||
if (g_strcmp0(ns, STANZA_NS_CAPS) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -989,18 +990,50 @@ stanza_caps_get_hash(xmpp_stanza_t * const stanza)
|
||||
{
|
||||
xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
|
||||
|
||||
if (caps == NULL) {
|
||||
if (!caps) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(xmpp_stanza_get_ns(caps), STANZA_NS_CAPS) != 0) {
|
||||
char *ns = xmpp_stanza_get_ns(caps);
|
||||
if (g_strcmp0(ns, STANZA_NS_CAPS) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *result = xmpp_stanza_get_attribute(caps, STANZA_ATTR_HASH);
|
||||
return xmpp_stanza_get_attribute(caps, STANZA_ATTR_HASH);
|
||||
}
|
||||
|
||||
return result;
|
||||
char *
|
||||
stanza_caps_get_node(xmpp_stanza_t * const stanza)
|
||||
{
|
||||
xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
|
||||
|
||||
if (!caps) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ns = xmpp_stanza_get_ns(caps);
|
||||
if (g_strcmp0(ns, STANZA_NS_CAPS) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xmpp_stanza_get_attribute(caps, STANZA_ATTR_NODE);
|
||||
}
|
||||
|
||||
char *
|
||||
stanza_get_caps_ver(xmpp_stanza_t * const stanza)
|
||||
{
|
||||
xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
|
||||
|
||||
if (!caps) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ns = xmpp_stanza_get_ns(caps);
|
||||
if (g_strcmp0(ns, STANZA_NS_CAPS) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xmpp_stanza_get_attribute(caps, STANZA_ATTR_VER);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -209,6 +209,8 @@ int stanza_get_idle_time(xmpp_stanza_t * const stanza);
|
||||
char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
|
||||
gboolean stanza_contains_caps(xmpp_stanza_t * const stanza);
|
||||
char * stanza_caps_get_hash(xmpp_stanza_t * const stanza);
|
||||
char * stanza_get_caps_ver(xmpp_stanza_t * const stanza);
|
||||
char * stanza_caps_get_node(xmpp_stanza_t * const stanza);
|
||||
|
||||
DataForm * stanza_create_form(xmpp_stanza_t * const stanza);
|
||||
void stanza_destroy_form(DataForm *form);
|
||||
|
@ -189,6 +189,8 @@ void (*iq_request_room_config_form)(const char * const room_jid);
|
||||
void (*iq_submit_room_config)(const char * const room, DataForm *form);
|
||||
void (*iq_room_config_cancel)(const char * const room_jid);
|
||||
void (*iq_send_ping)(const char * const target);
|
||||
void (*iq_send_caps_request)(const char * const to, const char * const id,
|
||||
const char * const node, const char * const ver);
|
||||
|
||||
// caps functions
|
||||
Capabilities* (*caps_get)(const char * const caps_str);
|
||||
|
Loading…
Reference in New Issue
Block a user