diff -rN -u old-telepathy-gabble/src/capabilities.c new-telepathy-gabble/src/capabilities.c --- old-telepathy-gabble/src/capabilities.c 2007-07-22 19:25:55.000000000 +0200 +++ new-telepathy-gabble/src/capabilities.c 2007-07-22 19:25:55.000000000 +0200 @@ -34,6 +34,7 @@ { VERSION, NS_CHAT_STATES, PRESENCE_CAP_CHAT_STATES}, { VERSION, NS_NICK, 0}, { VERSION, NS_NICK "+notify", 0}, + { VERSION, NS_LAST, 0}, { VERSION, NS_OLPC_BUDDY_PROPS, 0}, { VERSION, NS_OLPC_BUDDY_PROPS "+notify", 0}, { VERSION, NS_OLPC_ACTIVITIES, 0}, diff -rN -u old-telepathy-gabble/src/gabble-connection.c new-telepathy-gabble/src/gabble-connection.c --- old-telepathy-gabble/src/gabble-connection.c 2007-07-22 19:25:55.000000000 +0200 +++ new-telepathy-gabble/src/gabble-connection.c 2007-07-22 19:25:55.000000000 +0200 @@ -134,6 +134,7 @@ struct _GabbleConnectionPrivate { LmMessageHandler *iq_disco_cb; + LmMessageHandler *iq_last_cb; LmMessageHandler *iq_unknown_cb; LmMessageHandler *stream_error_cb; LmMessageHandler *msg_cb; @@ -142,6 +143,7 @@ gchar *connect_server; guint port; gboolean old_ssl; + gdouble iq_last_time; gboolean ignore_ssl_errors; TpConnectionStatusReason ssl_error; @@ -263,6 +265,7 @@ priv->resource = g_strdup (GABBLE_PARAMS_DEFAULT_RESOURCE); priv->caps_serial = 1; + priv->iq_last_time = time (NULL); } static void @@ -729,6 +732,7 @@ g_assert (!lm_connection_is_open (self->lmconn)); g_assert (priv->iq_disco_cb == NULL); + g_assert (priv->iq_last_cb == NULL); g_assert (priv->iq_unknown_cb == NULL); g_assert (priv->stream_error_cb == NULL); g_assert (priv->msg_cb == NULL); @@ -858,6 +862,33 @@ return TRUE; } + +void +_gabble_connection_update_last_use (GabbleConnection *conn) +{ + GabbleConnectionPrivate *priv; + + g_assert (GABBLE_IS_CONNECTION (conn)); + + priv = GABBLE_CONNECTION_GET_PRIVATE (conn); + + priv->iq_last_time = time (NULL); +} + + +gdouble +gabble_connection_get_last_use (GabbleConnection *conn) +{ + GabbleConnectionPrivate *priv; + + g_assert (GABBLE_IS_CONNECTION (conn)); + + priv = GABBLE_CONNECTION_GET_PRIVATE (conn); + + return difftime (time (NULL), priv->iq_last_time); +} + + typedef struct { GabbleConnectionMsgReplyFunc reply_func; @@ -994,6 +1025,8 @@ static LmHandlerResult connection_iq_disco_cb (LmMessageHandler *, LmConnection *, LmMessage *, gpointer); +static LmHandlerResult connection_iq_last_cb (LmMessageHandler *, + LmConnection *, LmMessage *, gpointer); static LmHandlerResult connection_iq_unknown_cb (LmMessageHandler *, LmConnection *, LmMessage *, gpointer); static LmHandlerResult connection_stream_error_cb (LmMessageHandler *, @@ -1037,6 +1070,7 @@ GabbleConnectionPrivate *priv = GABBLE_CONNECTION_GET_PRIVATE (conn); g_assert (priv->iq_disco_cb == NULL); + g_assert (priv->iq_last_cb == NULL); g_assert (priv->iq_unknown_cb == NULL); g_assert (priv->stream_error_cb == NULL); g_assert (priv->msg_cb == NULL); @@ -1047,6 +1081,12 @@ LM_MESSAGE_TYPE_IQ, LM_HANDLER_PRIORITY_NORMAL); + priv->iq_last_cb = lm_message_handler_new (connection_iq_last_cb, + conn, NULL); + lm_connection_register_message_handler (conn->lmconn, priv->iq_last_cb, + LM_MESSAGE_TYPE_IQ, + LM_HANDLER_PRIORITY_NORMAL); + priv->iq_unknown_cb = lm_message_handler_new (connection_iq_unknown_cb, conn, NULL); lm_connection_register_message_handler (conn->lmconn, priv->iq_unknown_cb, @@ -1073,6 +1113,7 @@ GabbleConnectionPrivate *priv = GABBLE_CONNECTION_GET_PRIVATE (conn); g_assert (priv->iq_disco_cb != NULL); + g_assert (priv->iq_last_cb != NULL); g_assert (priv->iq_unknown_cb != NULL); g_assert (priv->stream_error_cb != NULL); g_assert (priv->msg_cb != NULL); @@ -1082,6 +1123,11 @@ lm_message_handler_unref (priv->iq_disco_cb); priv->iq_disco_cb = NULL; + lm_connection_unregister_message_handler (conn->lmconn, priv->iq_last_cb, + LM_MESSAGE_TYPE_IQ); + lm_message_handler_unref (priv->iq_last_cb); + priv->iq_last_cb = NULL; + lm_connection_unregister_message_handler (conn->lmconn, priv->iq_unknown_cb, LM_MESSAGE_TYPE_IQ); lm_message_handler_unref (priv->iq_unknown_cb); @@ -1657,6 +1703,60 @@ return LM_HANDLER_RESULT_REMOVE_MESSAGE; } + +/** + * connection_iq_last_cb + * + * Called by loudmouth when we get an incoming . This handler handles + * jabber:last:iq related IQs (XEP 0012). + */ +static LmHandlerResult +connection_iq_last_cb (LmMessageHandler *handler, + LmConnection *connection, + LmMessage *message, + gpointer user_data) +{ + GabbleConnection *self = GABBLE_CONNECTION (user_data); + const gchar *id; + LmMessage *result; + LmMessageNode *iq; + char *seconds; + + if (lm_message_get_sub_type (message) != LM_MESSAGE_SUB_TYPE_GET) + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + + iq = lm_message_get_node (message); + + if (! lm_message_node_get_child_with_namespace (iq, "query", NS_LAST)) + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + id = lm_message_node_get_attribute (iq, "id"); + if (id == NULL) + { + NODE_DEBUG (iq, "can't acknowledge IQ with no id"); + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + } + seconds = g_strdup_printf ("%.0f", gabble_connection_get_last_use (self)); + result = lm_message_build (lm_message_node_get_attribute (iq, "from"), + LM_MESSAGE_TYPE_IQ, + '@', "type", "result", + '@', "id", id, + '(', "query", "", + '@', "xmlns", NS_LAST, + '@', "seconds", seconds, ')', + ')', NULL); + + g_free( seconds); + if (! lm_connection_send (self->lmconn, result, NULL)) + { + DEBUG ("sending last response failed"); + } + + lm_message_unref (result); + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + + /** * connection_iq_unknown_cb * diff -rN -u old-telepathy-gabble/src/gabble-connection.h new-telepathy-gabble/src/gabble-connection.h --- old-telepathy-gabble/src/gabble-connection.h 2007-07-22 19:25:55.000000000 +0200 +++ new-telepathy-gabble/src/gabble-connection.h 2007-07-22 19:25:55.000000000 +0200 @@ -166,6 +166,7 @@ LmMessage *iq); void _gabble_connection_send_iq_error (GabbleConnection *conn, LmMessage *message, GabbleXmppError error, const gchar *errmsg); +void _gabble_connection_update_last_use (GabbleConnection *conn); GabbleConnectionAliasSource _gabble_connection_get_cached_alias ( GabbleConnection *, TpHandle, gchar **); diff -rN -u old-telepathy-gabble/src/namespaces.h new-telepathy-gabble/src/namespaces.h --- old-telepathy-gabble/src/namespaces.h 2007-07-22 19:25:55.000000000 +0200 +++ new-telepathy-gabble/src/namespaces.h 2007-07-22 19:25:55.000000000 +0200 @@ -42,6 +42,7 @@ #define NS_JINGLE_ERRORS "http://jabber.org/protocol/jingle#errors" #define NS_JINGLE_TRANSPORT_ICE \ "http://jabber.org/protocol/jingle/transport/ice" +#define NS_LAST "jabber:iq:last" #define NS_MUC "http://jabber.org/protocol/muc" #define NS_MUC_USER "http://jabber.org/protocol/muc#user" #define NS_MUC_ADMIN "http://jabber.org/protocol/muc#admin" diff -rN -u old-telepathy-gabble/src/text-mixin.c new-telepathy-gabble/src/text-mixin.c --- old-telepathy-gabble/src/text-mixin.c 2007-07-22 19:25:55.000000000 +0200 +++ new-telepathy-gabble/src/text-mixin.c 2007-07-22 19:25:55.000000000 +0200 @@ -188,6 +188,7 @@ tp_svc_channel_type_text_emit_sent (obj, timestamp, type, text); } + _gabble_connection_update_last_use (conn); return TRUE; }