# HG changeset patch # User Mikael Hallendal # Date 1177848962 -7200 # Node ID d372a2b61b1d4d82b7f14be9247c83c80bc707be # Parent 703c5734ec61d95dc4db94149a80a18d478e3b72 Added disconnect error for resource conflict. Fixes LM-55. Added a disconnection reason for resource conflict (when another client connects with the same resourc). Patch from Martyn Russell. diff -r 703c5734ec61 -r d372a2b61b1d loudmouth/lm-connection.c --- a/loudmouth/lm-connection.c Sun Apr 29 13:22:36 2007 +0200 +++ b/loudmouth/lm-connection.c Sun Apr 29 14:16:02 2007 +0200 @@ -100,6 +100,8 @@ LmConnectData *connect_data; + LmDisconnectReason disconnect_reason; + gint ref_count; }; @@ -156,6 +158,8 @@ LmMessage *m, gpointer user_data); +static void connection_stream_error (LmConnection *connection, + LmMessage *m); static void connection_stream_received (LmConnection *connection, LmMessage *m); @@ -279,6 +283,10 @@ connection_stream_received (connection, m); goto out; } + else if (lm_message_get_type (m) == LM_MESSAGE_TYPE_STREAM_ERROR) { + connection_stream_error (connection, m); + goto out; + } id = lm_message_node_get_attribute (m->node, "id"); @@ -591,6 +599,9 @@ _lm_connection_succeeded (connect_data); } + /* set the default disconnect reason to unknown */ + connection->disconnect_reason = LM_DISCONNECT_REASON_UNKNOWN; + return TRUE; } @@ -1108,16 +1119,23 @@ switch (status) { case G_IO_STATUS_EOF: reason = LM_DISCONNECT_REASON_HUP; + lm_verbose ("Disconnect reason: %d\n", reason); break; case G_IO_STATUS_AGAIN: /* No data readable but we didn't hangup */ return FALSE; break; case G_IO_STATUS_ERROR: - reason = LM_DISCONNECT_REASON_ERROR; - break; + /* If no reason set, we set it to ERROR here, + * otherwise it might already have been set by + * the stream error handler. + */ + if (connection->disconnect_reason == LM_DISCONNECT_REASON_UNKNOWN) { + connection->disconnect_reason = LM_DISCONNECT_REASON_ERROR; + } default: - reason = LM_DISCONNECT_REASON_UNKNOWN; + reason = connection->disconnect_reason; + lm_verbose ("Disconnect reason: %d\n", reason); } connection_do_close (connection); @@ -1440,6 +1458,35 @@ return LM_HANDLER_RESULT_REMOVE_MESSAGE; } +static void +connection_stream_error (LmConnection *connection, LmMessage *m) +{ + LmMessageNode *node; + + g_return_if_fail (connection != NULL); + g_return_if_fail (m != NULL); + + node = m->node; + + /* Resource conflict */ + node = lm_message_node_get_child (node, "conflict"); + if (node) { + lm_verbose ("Stream error: Conflict (resource connected elsewhere)\n"); + connection->disconnect_reason = LM_DISCONNECT_REASON_RESOURCE_CONFLICT; + return; + } + + /* XML is crack */ + node = lm_message_node_get_child (node, "xml-not-well-formed"); + if (node) { + lm_verbose ("Stream error: XML not well formed\n"); + connection->disconnect_reason = LM_DISCONNECT_REASON_INVALID_XML; + return; + } + + lm_verbose ("Stream error: Unrecognised error\n"); + connection->disconnect_reason = LM_DISCONNECT_REASON_ERROR; +} static void connection_stream_received (LmConnection *connection, LmMessage *m) @@ -1585,6 +1632,7 @@ g_str_equal, g_free, (GDestroyNotify) lm_message_handler_unref); + connection->disconnect_reason = LM_DISCONNECT_REASON_UNKNOWN; connection->ref_count = 1; for (i = 0; i < LM_MESSAGE_TYPE_UNKNOWN; ++i) { diff -r 703c5734ec61 -r d372a2b61b1d loudmouth/lm-connection.h --- a/loudmouth/lm-connection.h Sun Apr 29 13:22:36 2007 +0200 +++ b/loudmouth/lm-connection.h Sun Apr 29 14:16:02 2007 +0200 @@ -56,7 +56,9 @@ LM_DISCONNECT_REASON_PING_TIME_OUT, LM_DISCONNECT_REASON_HUP, LM_DISCONNECT_REASON_ERROR, - LM_DISCONNECT_REASON_UNKNOWN + LM_DISCONNECT_REASON_UNKNOWN, + LM_DISCONNECT_REASON_RESOURCE_CONFLICT, + LM_DISCONNECT_REASON_INVALID_XML } LmDisconnectReason; typedef enum {