[Telepathy-commits] [telepathy-gabble/master] parse_incoming_message: return TpDeliveryStatus based on error type

Will Thompson will.thompson at collabora.co.uk
Tue Feb 3 06:34:51 PST 2009


---
 src/im-factory.c           |    3 +-
 src/message-util.c         |   21 +++++++--
 src/message-util.h         |    3 +-
 src/muc-factory.c          |    3 +-
 tests/test-parse-message.c |  109 ++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 127 insertions(+), 12 deletions(-)

diff --git a/src/im-factory.c b/src/im-factory.c
index b7122d7..8f56aae 100644
--- a/src/im-factory.c
+++ b/src/im-factory.c
@@ -215,9 +215,10 @@ im_factory_message_cb (LmMessageHandler *handler,
   GabbleIMChannel *chan;
   gint state;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
 
   if (!gabble_message_util_parse_incoming_message (message, &from, &stamp,
-        &msgtype, &body, &state, &send_error))
+        &msgtype, &body, &state, &send_error, &delivery_status))
     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 
   if (body == NULL && state == -1)
diff --git a/src/message-util.c b/src/message-util.c
index 475a96e..5ba4fd6 100644
--- a/src/message-util.c
+++ b/src/message-util.c
@@ -218,14 +218,22 @@ gabble_message_util_send_chat_state (GObject *obj,
 
 
 static TpChannelTextSendError
-_tp_send_error_from_error_node (LmMessageNode *error_node)
+_tp_send_error_from_error_node (LmMessageNode *error_node,
+                                TpDeliveryStatus *delivery_status)
 {
   if (error_node != NULL)
     {
-      GabbleXmppError err = gabble_xmpp_error_from_node (error_node, NULL);
+      GabbleXmppErrorType err_type = XMPP_ERROR_TYPE_UNDEFINED;
+      GabbleXmppError err = gabble_xmpp_error_from_node (error_node, &err_type);
+
       DEBUG ("got xmpp error: %s: %s", gabble_xmpp_error_string (err),
           gabble_xmpp_error_description (err));
 
+      if (err_type == XMPP_ERROR_TYPE_WAIT)
+        *delivery_status = TP_DELIVERY_STATUS_TEMPORARILY_FAILED;
+      else
+        *delivery_status = TP_DELIVERY_STATUS_PERMANENTLY_FAILED;
+
       /* these are based on descriptions of errors, and some testing */
       switch (err)
         {
@@ -294,6 +302,9 @@ _tp_chat_state_from_message (LmMessage *message)
  *         there was no chat state in the message.
  * @send_error: set to the relevant send error if the message contained an
  *              error node, or to %GABBLE_TEXT_CHANNEL_SEND_NO_ERROR otherwise.
+ * @delivery_status: set to TemporarilyFailed if an <error type="wait"/> is
+ *                   encountered, to PermanentlyFailed if any other <error/> is
+ *                   encountered, and to Unknown otherwise.
  *
  * Parses an incoming <message> stanza, producing various bits of the message
  * as various out parameters.
@@ -308,12 +319,14 @@ gabble_message_util_parse_incoming_message (LmMessage *message,
                                             TpChannelTextMessageType *msgtype,
                                             const gchar **body_ret,
                                             gint *state,
-                                            TpChannelTextSendError *send_error)
+                                            TpChannelTextSendError *send_error,
+                                            TpDeliveryStatus *delivery_status)
 {
   const gchar *type, *body;
   LmMessageNode *node;
 
   *send_error = GABBLE_TEXT_CHANNEL_SEND_NO_ERROR;
+  *delivery_status = TP_DELIVERY_STATUS_UNKNOWN;
 
   if (lm_message_get_sub_type (message) == LM_MESSAGE_SUB_TYPE_ERROR)
     {
@@ -321,7 +334,7 @@ gabble_message_util_parse_incoming_message (LmMessage *message,
 
       error_node = lm_message_node_get_child (message->node, "error");
 
-      *send_error = _tp_send_error_from_error_node (error_node);
+      *send_error = _tp_send_error_from_error_node (error_node, delivery_status);
     }
 
   *from = lm_message_node_get_attribute (message->node, "from");
diff --git a/src/message-util.h b/src/message-util.h
index eb68e96..233c431 100644
--- a/src/message-util.h
+++ b/src/message-util.h
@@ -42,7 +42,8 @@ gboolean gabble_message_util_send_chat_state (GObject *obj,
 
 gboolean gabble_message_util_parse_incoming_message (LmMessage *message,
     const gchar **from, time_t *stamp, TpChannelTextMessageType *msgtype,
-    const gchar **body_ret, gint *state, TpChannelTextSendError *send_error);
+    const gchar **body_ret, gint *state, TpChannelTextSendError *send_error,
+    TpDeliveryStatus *delivery_status);
 
 G_END_DECLS
 
diff --git a/src/muc-factory.c b/src/muc-factory.c
index f53b5ae..80997a9 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -732,11 +732,12 @@ muc_factory_message_cb (LmMessageHandler *handler,
   GabbleMucChannel *chan;
   gint state;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   gchar *room;
   LmMessageNode *subj_node;
 
   if (!gabble_message_util_parse_incoming_message (message, &from, &stamp,
-        &msgtype, &body, &state, &send_error))
+        &msgtype, &body, &state, &send_error, &delivery_status))
     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 
   if (conn_olpc_process_activity_properties_message (priv->conn, message,
diff --git a/tests/test-parse-message.c b/tests/test-parse-message.c
index 1c7b6f3..2ab2943 100644
--- a/tests/test-parse-message.c
+++ b/tests/test-parse-message.c
@@ -16,6 +16,7 @@ test1 (void)
   time_t stamp;
   TpChannelTextMessageType type;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   const gchar *body;
   gint state;
 
@@ -23,13 +24,14 @@ test1 (void)
         '@', "from", "foo at bar.com",
         NULL);
   ret = gabble_message_util_parse_incoming_message (
-      msg, &from, &stamp, &type, &body, &state, &send_error);
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
   g_assert (ret == TRUE);
   g_assert (0 == strcmp (from, "foo at bar.com"));
   g_assert (stamp == 0);
   g_assert (type == TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE);
   g_assert (body == NULL);
   g_assert (state == -1);
+  g_assert (send_error == GABBLE_TEXT_CHANNEL_SEND_NO_ERROR);
   lm_message_unref (msg);
   return TRUE;
 }
@@ -46,6 +48,7 @@ test2 (void)
   time_t stamp;
   TpChannelTextMessageType type;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   const gchar *body;
   gint state;
 
@@ -54,7 +57,7 @@ test2 (void)
         '(', "body", "hello", ')',
         NULL);
   ret = gabble_message_util_parse_incoming_message (
-      msg, &from, &stamp, &type, &body, &state, &send_error);
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
   g_assert (ret == TRUE);
   g_assert (0 == strcmp (from, "foo at bar.com"));
   g_assert (stamp == 0);
@@ -76,6 +79,7 @@ test3 (void)
   time_t stamp;
   TpChannelTextMessageType type;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   const gchar *body;
   gint state;
 
@@ -85,7 +89,7 @@ test3 (void)
         '(', "body", "hello", ')',
         NULL);
   ret = gabble_message_util_parse_incoming_message (
-      msg, &from, &stamp, &type, &body, &state, &send_error);
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
   g_assert (ret == TRUE);
   g_assert (0 == strcmp (from, "foo at bar.com"));
   g_assert (stamp == 0);
@@ -107,6 +111,7 @@ test_error (void)
   time_t stamp;
   TpChannelTextMessageType type;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   const gchar *body;
   gint state;
 
@@ -117,7 +122,7 @@ test_error (void)
       '(', "error", "oops", ')',
       NULL);
   ret = gabble_message_util_parse_incoming_message (
-      msg, &from, &stamp, &type, &body, &state, &send_error);
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
   g_assert (ret == TRUE);
   g_assert (0 == strcmp (from, "foo at bar.com"));
   g_assert (stamp == 0);
@@ -125,6 +130,97 @@ test_error (void)
   g_assert (body == NULL);
   g_assert (state == -1);
   g_assert (send_error == TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN);
+  g_assert (delivery_status == TP_DELIVERY_STATUS_PERMANENTLY_FAILED);
+  lm_message_unref (msg);
+  return TRUE;
+}
+
+/* A more complicated error, described in XEP-0086 as a "simple error response".
+ */
+static gboolean
+test_another_error (void)
+{
+  LmMessage *msg;
+  gboolean ret;
+  const gchar *from;
+  time_t stamp;
+  TpChannelTextMessageType type;
+  TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
+  const gchar *body;
+  gint state;
+  const gchar *message = "Wherefore art thou, Romeo?";
+
+  msg = lm_message_build_with_sub_type (NULL, LM_MESSAGE_TYPE_MESSAGE,
+      LM_MESSAGE_SUB_TYPE_ERROR,
+      '@', "to", "juliet at capulet.com/balcony",
+      '@', "from", "romeo at montague.net/garden",
+      '@', "type", "error",
+      '(', "body", message, ')',
+      '(', "error", "",
+        '@', "code", "404",
+        '@', "type", "cancel",
+        '(', "item-not-found", "",
+          '@', "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas",
+        ')',
+      ')',
+      NULL);
+  ret = gabble_message_util_parse_incoming_message (
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
+  g_assert (ret == TRUE);
+  g_assert (0 == strcmp (from, "romeo at montague.net/garden"));
+  g_assert (stamp == 0);
+  g_assert (type == TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE);
+  g_assert (!tp_strdiff (body, message));
+  g_assert (state == -1);
+  g_assert (send_error == TP_CHANNEL_TEXT_SEND_ERROR_INVALID_CONTACT);
+  g_assert (delivery_status == TP_DELIVERY_STATUS_PERMANENTLY_FAILED);
+  lm_message_unref (msg);
+  return TRUE;
+}
+
+/* One million, seven hundred seventy-one thousand, five hundred sixty-one
+ * errors.
+ */
+static gboolean
+test_yet_another_error (void)
+{
+  LmMessage *msg;
+  gboolean ret;
+  const gchar *from;
+  time_t stamp;
+  TpChannelTextMessageType type;
+  TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
+  const gchar *body;
+  gint state;
+  const gchar *message = "Its trilling seems to have a tranquilizing effect on "
+                         "the human nervous system.";
+
+  msg = lm_message_build_with_sub_type (NULL, LM_MESSAGE_TYPE_MESSAGE,
+      LM_MESSAGE_SUB_TYPE_ERROR,
+      '@', "to", "spock at starfleet.us/Enterprise",
+      '@', "from", "other at starfleet.us/Enterprise",
+      '@', "type", "error",
+      '(', "body", message, ')',
+      '(', "error", "",
+        '@', "code", "404",
+        '@', "type", "wait",
+        '(', "recipient-unavailable", "",
+          '@', "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas",
+        ')',
+      ')',
+      NULL);
+  ret = gabble_message_util_parse_incoming_message (
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
+  g_assert (ret == TRUE);
+  g_assert (0 == strcmp (from, "other at starfleet.us/Enterprise"));
+  g_assert (stamp == 0);
+  g_assert (type == TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE);
+  g_assert (!tp_strdiff (body, message));
+  g_assert (state == -1);
+  g_assert (send_error == TP_CHANNEL_TEXT_SEND_ERROR_OFFLINE);
+  g_assert (delivery_status == TP_DELIVERY_STATUS_TEMPORARILY_FAILED);
   lm_message_unref (msg);
   return TRUE;
 }
@@ -138,6 +234,7 @@ test_google_offline (void)
   time_t stamp;
   TpChannelTextMessageType type;
   TpChannelTextSendError send_error;
+  TpDeliveryStatus delivery_status;
   const gchar *body;
   gint state;
 
@@ -154,7 +251,7 @@ test_google_offline (void)
       ')',
       NULL);
   ret = gabble_message_util_parse_incoming_message (
-      msg, &from, &stamp, &type, &body, &state, &send_error);
+      msg, &from, &stamp, &type, &body, &state, &send_error, &delivery_status);
   g_assert (ret == TRUE);
   g_assert (0 == strcmp (from, "foo at bar.com"));
   g_assert (stamp == 1190899454);
@@ -173,6 +270,8 @@ main (void)
   g_assert (test2 ());
   g_assert (test3 ());
   g_assert (test_error ());
+  g_assert (test_another_error ());
+  g_assert (test_yet_another_error ());
   g_assert (test_google_offline ());
 
   return 0;
-- 
1.5.6.5




More information about the telepathy-commits mailing list