[telepathy-gabble/master] Replace 'probed' with 'ready-or-not' with a GError
Will Thompson
will.thompson at collabora.co.uk
Wed Aug 26 09:21:49 PDT 2009
---
src/search-channel.c | 80 +++++++++++++++++++++++++++++++++++--------------
src/search-manager.c | 33 +++++++++++++++-----
2 files changed, 82 insertions(+), 31 deletions(-)
diff --git a/src/search-channel.c b/src/search-channel.c
index 3b4adf5..64e0a4f 100644
--- a/src/search-channel.c
+++ b/src/search-channel.c
@@ -32,6 +32,7 @@
#define DEBUG_FLAG GABBLE_DEBUG_SEARCH
#include "base-channel.h"
#include "debug.h"
+#include "gabble-signals-marshal.h"
#include "namespaces.h"
#include "util.h"
@@ -54,7 +55,7 @@ enum
/* signal enum */
enum
{
- PROBED,
+ READY_OR_NOT,
LAST_SIGNAL
};
@@ -95,6 +96,30 @@ ensure_closed (GabbleSearchChannel *chan)
}
static void
+become_ready (GabbleSearchChannel *chan)
+{
+ DEBUG ("called");
+
+ g_assert (chan->base.closed);
+
+ chan->base.closed = FALSE;
+ g_signal_emit (chan, signals[READY_OR_NOT], 0, 0, 0, NULL);
+}
+
+static void
+give_up (GabbleSearchChannel *chan,
+ const GError *error)
+{
+ DEBUG ("called: %s, %u, %s", g_quark_to_string (error->domain), error->code,
+ error->message);
+
+ g_assert (chan->base.closed);
+
+ g_signal_emit (chan, signals[READY_OR_NOT], 0, error->domain, error->code,
+ error->message);
+}
+
+static void
parse_search_field_response (GabbleSearchChannel *chan,
LmMessageNode *query_node)
{
@@ -107,10 +132,10 @@ parse_search_field_response (GabbleSearchChannel *chan,
if (x_node != NULL)
{
- DEBUG ("response contains an XForm, which is not yet implemented");
- DEBUG ("failing the channel");
+ GError error = { TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+ "server uses data forms, which are not yet implemented in Gabble" };
- g_signal_emit (chan, signals[PROBED], 0, FALSE);
+ give_up (chan, &error);
return;
}
@@ -135,11 +160,14 @@ parse_search_field_response (GabbleSearchChannel *chan,
#undef MAP_FIELD_TO
else
{
- DEBUG ("%s is not a field defined in XEP 0055",
+ GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, NULL };
+
+ error.message = g_strdup_printf (
+ "server is broken: %s is not a field defined in XEP 0055",
field->name);
- DEBUG ("giving up on this channel");
+ give_up (chan, &error);
+ g_free (error.message);
- g_signal_emit (chan, signals[PROBED], 0, FALSE);
g_ptr_array_free (search_keys, TRUE);
return;
}
@@ -148,8 +176,8 @@ parse_search_field_response (GabbleSearchChannel *chan,
DEBUG ("extracted available fields");
g_ptr_array_add (search_keys, NULL);
chan->priv->available_search_keys = (gchar **) g_ptr_array_free (search_keys, FALSE);
- chan->base.closed = FALSE;
- g_signal_emit (chan, signals[PROBED], 0, TRUE);
+
+ become_ready (chan);
}
static LmHandlerResult
@@ -172,19 +200,19 @@ query_reply_cb (GabbleConnection *conn,
if (err == NULL)
err = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "server gave us an error we don't understand");
+ "%s gave us an error we don't understand", chan->priv->server);
}
else if (NULL == query_node)
{
err = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "server is chock-full of bees");
+ "%s is broken: it replied to our <query> with an empty IQ",
+ chan->priv->server);
}
if (err != NULL)
{
- DEBUG ("got an error back from %s: %s", chan->priv->server, err->message);
-
- g_signal_emit (chan, signals[PROBED], 0, FALSE);
+ give_up (chan, err);
+ g_error_free (err);
}
else
{
@@ -199,6 +227,7 @@ request_search_fields (GabbleSearchChannel *chan)
{
LmMessage *msg;
LmMessageNode *lm_node;
+ GError *error = NULL;
msg = lm_message_new_with_sub_type (chan->priv->server, LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_SUB_TYPE_GET);
@@ -206,9 +235,10 @@ request_search_fields (GabbleSearchChannel *chan)
lm_message_node_set_attribute (lm_node, "xmlns", NS_SEARCH);
if (! _gabble_connection_send_with_reply (chan->base.conn, msg,
- query_reply_cb, (GObject *) chan, NULL, NULL))
+ query_reply_cb, (GObject *) chan, NULL, &error))
{
- g_signal_emit (chan, signals[PROBED], 0, FALSE);
+ give_up (chan, error);
+ g_error_free (error);
}
lm_message_unref (msg);
@@ -389,18 +419,22 @@ gabble_search_channel_class_init (GabbleSearchChannelClass *klass)
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SERVER, param_spec);
- /* Emitted with argument TRUE if the service's supported search fields have
- * been discovered, and with argument FALSE if the service isn't actually a
- * XEP 0055 repository.
+ /* Emitted when we get a reply from the server about which search keys it
+ * supports. Its three arguments are the components of a GError. If the
+ * server gave us a set of search keys, and they were sane, all components
+ * will be 0 or %NULL, indicating that this channel can be announced and
+ * used; if the server doesn't actually speak XEP 0055 or is full of bees,
+ * they'll be an error in either the GABBLE_XMPP_ERROR or the TP_ERRORS
+ * domain.
*/
- signals[PROBED] =
- g_signal_new ("probed",
+ signals[READY_OR_NOT] =
+ g_signal_new ("ready-or-not",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ gabble_marshal_VOID__UINT_INT_STRING,
+ G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING);
tp_dbus_properties_mixin_implement_interface (object_class,
GABBLE_IFACE_QUARK_CHANNEL_TYPE_CONTACT_SEARCH,
diff --git a/src/search-manager.c b/src/search-manager.c
index 206b984..472eda7 100644
--- a/src/search-manager.c
+++ b/src/search-manager.c
@@ -280,11 +280,13 @@ request_context_free (RequestContext *ctx)
}
static void
-search_channel_probed_cb (GabbleSearchChannel *chan,
- gboolean success,
- RequestContext *ctx)
+search_channel_ready_or_not_cb (GabbleSearchChannel *chan,
+ GQuark domain,
+ gint code,
+ const gchar *message,
+ RequestContext *ctx)
{
- if (success)
+ if (domain == 0)
{
GSList *request_tokens = g_slist_prepend (NULL, ctx->request_token);
@@ -295,9 +297,23 @@ search_channel_probed_cb (GabbleSearchChannel *chan,
}
else
{
- tp_channel_manager_emit_request_failed_printf (ctx->self,
- ctx->request_token, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "'%s' is not a (working) user directory server", ctx->server);
+ if (domain == GABBLE_XMPP_ERROR)
+ {
+ domain = TP_ERRORS;
+ /* - Maybe CreateChannel should be specced to raise PermissionDenied?
+ * Then we could map XMPP_ERROR_FORBIDDEN to that.
+ * - Should XMPP_ERROR_JID_MALFORMED be mapped to InvalidArgument?
+ */
+ code = TP_ERROR_NOT_AVAILABLE;
+ /* Do we want to prefix the error string with something? */
+ }
+ else
+ {
+ g_assert (domain == TP_ERRORS);
+ }
+
+ tp_channel_manager_emit_request_failed (ctx->self,
+ ctx->request_token, domain, code, message);
remove_search_channel (ctx->self, chan);
}
@@ -321,7 +337,8 @@ new_search_channel (GabbleSearchManager *self,
g_hash_table_insert (priv->channels, chan, priv->channels);
g_signal_connect (chan, "closed", (GCallback) search_channel_closed_cb, self);
- g_signal_connect (chan, "probed", (GCallback) search_channel_probed_cb,
+ g_signal_connect (chan, "ready-or-not",
+ (GCallback) search_channel_ready_or_not_cb,
request_context_new (self, request_token, server));
}
--
1.5.6.5
More information about the telepathy-commits
mailing list