Mercurial > hg
comparison mcabber/mcabber/xmpp_iqrequest.c @ 1705:ac881b5f9248
Add /request ping (XEP-0199), by merging isbear's module
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Mon, 08 Feb 2010 21:23:05 +0100 |
parents | 65ba89949252 |
children | a5263e93c5d7 |
comparison
equal
deleted
inserted
replaced
1704:ab502d645378 | 1705:ac881b5f9248 |
---|---|
20 * USA | 20 * USA |
21 */ | 21 */ |
22 | 22 |
23 #include <string.h> | 23 #include <string.h> |
24 #include <stdlib.h> | 24 #include <stdlib.h> |
25 #include <sys/time.h> | |
25 | 26 |
26 #include "xmpp_helper.h" | 27 #include "xmpp_helper.h" |
27 #include "xmpp_iq.h" | 28 #include "xmpp_iq.h" |
28 #include "screen.h" | 29 #include "screen.h" |
29 #include "utils.h" | 30 #include "utils.h" |
40 LmMessage *m, gpointer user_data); | 41 LmMessage *m, gpointer user_data); |
41 static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c, | 42 static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c, |
42 LmMessage *m, gpointer user_data); | 43 LmMessage *m, gpointer user_data); |
43 static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c, | 44 static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c, |
44 LmMessage *m, gpointer user_data); | 45 LmMessage *m, gpointer user_data); |
46 static LmHandlerResult cb_ping(LmMessageHandler *h, LmConnection *c, | |
47 LmMessage *m, gpointer user_data); | |
45 static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c, | 48 static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c, |
46 LmMessage *m, gpointer user_data); | 49 LmMessage *m, gpointer user_data); |
47 | 50 |
48 static struct IqRequestHandlers | 51 static struct IqRequestHandlers |
49 { | 52 { |
53 } iq_request_handlers[] = { | 56 } iq_request_handlers[] = { |
54 {NS_ROSTER, "query", &cb_roster}, | 57 {NS_ROSTER, "query", &cb_roster}, |
55 {NS_VERSION,"query", &cb_version}, | 58 {NS_VERSION,"query", &cb_version}, |
56 {NS_TIME, "query", &cb_time}, | 59 {NS_TIME, "query", &cb_time}, |
57 {NS_LAST, "query", &cb_last}, | 60 {NS_LAST, "query", &cb_last}, |
61 {NS_PING, "ping", &cb_ping}, | |
58 {NS_VCARD, "vCard", &cb_vcard}, | 62 {NS_VCARD, "vCard", &cb_vcard}, |
59 {NULL, NULL, NULL} | 63 {NULL, NULL, NULL} |
60 }; | 64 }; |
61 | 65 |
62 // Enum for vCard attributes | 66 // Enum for vCard attributes |
69 vcard_cell = 1<<5, | 73 vcard_cell = 1<<5, |
70 vcard_inet = 1<<6, | 74 vcard_inet = 1<<6, |
71 vcard_pref = 1<<7, | 75 vcard_pref = 1<<7, |
72 }; | 76 }; |
73 | 77 |
74 // xmlns has to be a namespace from iq_request_handlers[].xmlns | 78 static LmHandlerResult cb_ping(LmMessageHandler *h, LmConnection *c, |
79 LmMessage *message, gpointer udata) | |
80 { | |
81 struct timeval *timestamp = (struct timeval *) udata; | |
82 struct timeval now; | |
83 time_t dsec; | |
84 suseconds_t dusec; | |
85 | |
86 gettimeofday(&now, NULL); | |
87 dsec = now.tv_sec - timestamp->tv_sec; | |
88 if (now.tv_usec < timestamp->tv_usec) { | |
89 dusec = now.tv_usec + 1000000 - timestamp->tv_usec; | |
90 --dsec; | |
91 } else | |
92 dusec = now.tv_usec - timestamp->tv_usec; | |
93 | |
94 switch (lm_message_get_sub_type(message)) { | |
95 case LM_MESSAGE_SUB_TYPE_RESULT: | |
96 { // print to buddy's buffer | |
97 LmMessageNode *node = lm_message_get_node(message); | |
98 gchar *jid = jidtodisp(lm_message_node_get_attribute(node, "from")); | |
99 gchar *mesg = g_strdup_printf("Pong: %d second%s %d ms.", | |
100 (int)dsec, | |
101 dsec > 1 ? "s" : "", | |
102 (int)(dusec/1000L)); | |
103 | |
104 scr_WriteIncomingMessage(jid, mesg, 0, HBB_PREFIX_INFO, 0); | |
105 | |
106 g_free(mesg); | |
107 g_free(jid); | |
108 } | |
109 break; | |
110 | |
111 case LM_MESSAGE_SUB_TYPE_ERROR: | |
112 { | |
113 LmMessageNode *node = lm_message_get_node(message); | |
114 const gchar *from = lm_message_node_get_attribute(node, "from"); | |
115 const gchar *type; | |
116 const gchar *reason; | |
117 | |
118 node = lm_message_node_get_child(node, "error"); | |
119 type = lm_message_node_get_attribute(node, "type"); | |
120 if (node->children) | |
121 reason = node->children->name; | |
122 else | |
123 reason = "undefined"; | |
124 | |
125 { // print to buddy's buffer | |
126 gchar *jid = jidtodisp(from); | |
127 gchar *mesg = g_strdup_printf("Ping to %s failed: %s - %s (response time %d second%s %d microseconds)", | |
128 from, type, reason, | |
129 (int)dsec, | |
130 dsec > 1 ? "s" : "", | |
131 (int)(dusec/1000L)); | |
132 | |
133 scr_WriteIncomingMessage(jid, mesg, 0, HBB_PREFIX_INFO, 0); | |
134 | |
135 g_free(mesg); | |
136 g_free(jid); | |
137 } | |
138 } | |
139 break; | |
140 | |
141 default: | |
142 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
143 break; | |
144 } | |
145 | |
146 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
147 } | |
148 | |
149 // Warning!! xmlns has to be a namespace from iq_request_handlers[].xmlns | |
75 void xmpp_iq_request(const char *fulljid, const char *xmlns) | 150 void xmpp_iq_request(const char *fulljid, const char *xmlns) |
76 { | 151 { |
77 LmMessage *iq; | 152 LmMessage *iq; |
78 LmMessageNode *query; | 153 LmMessageNode *query; |
79 LmMessageHandler *handler; | 154 LmMessageHandler *handler; |
155 gpointer data = NULL; | |
156 GDestroyNotify notifier = NULL; | |
157 GError *error = NULL; | |
80 int i; | 158 int i; |
81 | 159 |
82 iq = lm_message_new_with_sub_type(fulljid, LM_MESSAGE_TYPE_IQ, | 160 iq = lm_message_new_with_sub_type(fulljid, LM_MESSAGE_TYPE_IQ, |
83 LM_MESSAGE_SUB_TYPE_GET); | 161 LM_MESSAGE_SUB_TYPE_GET); |
84 for (i = 0; strcmp(iq_request_handlers[i].xmlns, xmlns) != 0 ; ++i) | 162 for (i = 0; strcmp(iq_request_handlers[i].xmlns, xmlns) != 0 ; ++i) |
85 ; | 163 ; |
86 query = lm_message_node_add_child(iq->node, | 164 query = lm_message_node_add_child(iq->node, |
87 iq_request_handlers[i].querytag, | 165 iq_request_handlers[i].querytag, |
88 NULL); | 166 NULL); |
89 lm_message_node_set_attribute(query, "xmlns", xmlns); | 167 lm_message_node_set_attribute(query, "xmlns", xmlns); |
168 | |
169 if (!g_strcmp0(xmlns, NS_PING)) { // Create handler for ping queries | |
170 struct timeval *now = g_new(struct timeval, 1); | |
171 gettimeofday(now, NULL); | |
172 data = (gpointer)now; | |
173 notifier = g_free; | |
174 } | |
175 | |
90 handler = lm_message_handler_new(iq_request_handlers[i].handler, | 176 handler = lm_message_handler_new(iq_request_handlers[i].handler, |
91 NULL, FALSE); | 177 data, notifier); |
92 lm_connection_send_with_reply(lconnection, iq, handler, NULL); | 178 |
179 lm_connection_send_with_reply(lconnection, iq, handler, &error); | |
93 lm_message_handler_unref(handler); | 180 lm_message_handler_unref(handler); |
94 lm_message_unref(iq); | 181 lm_message_unref(iq); |
182 | |
183 if (error) { | |
184 scr_LogPrint(LPRINT_LOGNORM, "Error sending IQ request: %s.", error->message); | |
185 g_error_free(error); | |
186 } | |
95 } | 187 } |
96 | 188 |
97 // This callback is reached when mcabber receives the first roster update | 189 // This callback is reached when mcabber receives the first roster update |
98 // after the connection. | 190 // after the connection. |
99 static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c, | 191 static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c, |