static char * _get_caps_key(xmpp_stanza_t * const stanza) { char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *hash_type = stanza_caps_get_hash(stanza); char *node = stanza_get_caps_str(stanza); char *caps_key = NULL; char *id = NULL; log_debug("Presence contains capabilities."); if (node == NULL) { return NULL; } // xep-0115 if ((hash_type != NULL) && (strcmp(hash_type, "sha-1") == 0)) { log_debug("Hash type %s supported.", hash_type); caps_key = strdup(node); id = create_unique_id("caps"); _send_caps_request(node, caps_key, id, from); free(id); // unsupported hash or legacy capabilities } else { if (hash_type != NULL) { log_debug("Hash type %s unsupported.", hash_type); } else { log_debug("No hash type, using legacy capabilities."); } guint from_hash = g_str_hash(from); char from_hash_str[9]; g_snprintf(from_hash_str, sizeof(from_hash_str), "%08x", from_hash); caps_key = strdup(from_hash_str); GString *id_str = g_string_new("capsreq_"); g_string_append(id_str, from_hash_str); id = id_str->str; _send_caps_request(node, caps_key, id, from); g_string_free(id_str, TRUE); } g_free(node); return caps_key; }
static void _handle_caps(xmpp_stanza_t *const stanza) { char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (from) { 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 (ver) { if (caps_contains(ver)) { log_info("Capabilities cached: %s", ver); caps_map(from, ver); } else { log_info("Capabilities not cached: %s, sending service discovery request", ver); char *node = stanza_caps_get_node(stanza); char *id = create_unique_id("caps"); iq_send_caps_request(from, id, node, ver); free(id); } } // 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 } } } }