2 * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <dbus/dbus.h>
27 #include <dbus/dbus-glib-lowlevel.h>
29 static char * server = "vespa.holoscopio.com";
30 static char * username = "pubsub";
31 static char * password = "pubsub";
32 static char * pbservice = "pubsub.vespa.holoscopio.com";
33 static char * authed_jid = "vespa";
36 createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
41 snprintf (sid, 32, "ps%d", id++);
43 iks_insert_attrib (iq, "type", type);
44 iks_insert_attrib (iq, "to", to);
45 iks_insert_attrib (iq, "id", sid);
46 *query = iks_insert (iq, qnam);
47 iks_insert_attrib (*query, "xmlns", xmlns);
52 catnode (iksparser *parser, char *node)
56 iq = createiq ("get", pbservice, "query",
57 "http://jabber.org/protocol/disco#info", &query);
59 iks_insert_attrib (query, "node", node);
60 iks_send (parser, iq);
65 listnode (iksparser *parser, char *node)
69 iq = createiq ("get", pbservice, "query",
70 "http://jabber.org/protocol/disco#items", &query);
72 iks_insert_attrib (query, "node", node);
73 iks_send (parser, iq);
78 createnode (iksparser *parser, char *node)
82 iq = createiq ("set", pbservice, "pubsub",
83 "http://jabber.org/protocol/pubsub", &query);
84 iks_insert_attrib (iks_insert (query, "create"), "node", node);
85 iks_send (parser, iq);
90 getnode (iksparser *parser, char *node)
94 iq = createiq ("get", pbservice, "pubsub",
95 "http://jabber.org/protocol/pubsub", &query);
96 iks_insert_attrib (iks_insert (query, "items"), "node", node);
97 iks_send (parser, iq);
102 vcard (iksparser *parser)
106 iq = createiq ("get", pbservice, "vCard", "vcard-temp", &query);
107 iks_send (parser, iq);
112 createmood (char *line)
115 mood = iks_new ("mood");
116 iks_insert_attrib (mood, "xmlns", "http://jabber.org/protocol/mood");
117 iks_insert (mood, line);
122 pushmood (iksparser *parser, char *node, char *line)
129 iq = createiq ("set", pbservice, "pubsub",
130 "http://jabber.org/protocol/pubsub", &query);
131 publish = iks_insert (query, "publish");
132 iks_insert_attrib (publish, "node", node);
133 item = iks_insert (publish, "item");
134 mood = createmood (line);
135 iks_insert_node (item, mood);
136 iks_send (parser, iq);
141 createtune (char *line)
144 tune = iks_new ("tune");
145 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
146 iks_insert_cdata (iks_insert (tune, "artist"), line, 0);
151 pushtune (iksparser *parser, char *node, iks *tune)
157 iq = createiq ("set", pbservice, "pubsub",
158 "http://jabber.org/protocol/pubsub", &query);
159 publish = iks_insert (query, "publish");
160 iks_insert_attrib (publish, "node", node);
161 item = iks_insert (publish, "item");
162 iks_insert_node (item, tune);
163 printf ("debug: %s\n", iks_string (iks_stack (iq), iq));
164 iks_send (parser, iq);
170 process_mood (iksparser *parser, char *cmdline)
174 orig_cmdline = cmdline = strdup (cmdline);
175 cmd = strsep (&cmdline, " ");
176 if (!strcmp (cmd, "ls"))
177 listnode (parser, cmdline);
178 else if (!strcmp (cmd, "cat"))
179 catnode (parser, cmdline);
180 else if (!strcmp (cmd, "vcard"))
182 else if (!strcmp (cmd, "create"))
183 createnode (parser, cmdline);
184 else if (!strcmp (cmd, "get"))
185 getnode (parser, cmdline);
186 else if (!strcmp (cmd, "mood"))
189 node = "http://jabber.org/protocol/mood";
190 pushmood (parser, node, cmdline);
192 else if (!strcmp (cmd, "tune"))
196 node = "http://jabber.org/protocol/tune";
197 tune = createtune (cmdline);
198 pushtune (parser, node, tune);
204 xmpp_session_hook (iksparser *parser, iks *node)
208 iks_insert_attrib (iq, "type", "set");
209 iks_insert_attrib (iq, "id", "session1");
210 iks_insert_attrib (iks_insert (iq, "session"),
211 "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
212 iks_send (parser, iq);
218 xmpp_initial_presence_hook (iksparser *parser, iks *node)
221 pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!");
222 iks_send (parser, pres);
228 xmpp_id_hook (iksparser *parser, iks *node, char *id)
230 if (!iks_strcmp (id, "bind1"))
232 xmpp_session_hook (parser, node);
235 else if (!iks_strcmp (id, "session1"))
237 xmpp_initial_presence_hook (parser, node);
240 else if (!iks_strncmp (id, "ps", 2))
242 printf ("%s\n", iks_string (iks_stack (node), node));
248 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
254 xmpp_iq_error (iksparser *parser, iks *node)
259 if (!iks_strcmp (iks_find_attrib (node, "type"), "error"))
261 to = iks_find_attrib (node, "to");
262 from = iks_find_attrib (node, "from");
264 iks_insert_attrib (node, "from", to);
266 iks_insert_attrib (node, "from", NULL);
268 iks_insert_attrib (node, "to", from);
270 iks_insert_attrib (node, "to", NULL);
271 iks_insert_attrib (node, "type", "error");
272 enode = iks_insert (node, "error");
273 iks_insert_attrib (enode, "type", "cancel");
274 iks_insert_attrib (iks_insert (enode, "feature-not-implemented"),
275 "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
276 iks_send (parser, node);
281 xmpp_tls_hook (iksparser *parser, iks *node)
283 iks_start_tls (parser);
288 xmpp_sasl_hook (iksparser *parser, iks* node)
290 iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
295 xmpp_bind_hook (iksparser *parser, iks *node)
299 iks_insert_attrib (iq, "type", "set");
300 iks_insert_attrib (iq, "id", "bind1");
301 iks_insert_attrib (iks_insert (iq, "bind"),
302 "xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
303 iks_send (parser, iq);
309 xmpp_features_hook (iksparser *parser, iks *node)
313 for (feat = iks_child (node); feat != NULL; feat = iks_next (feat))
315 ns = iks_find_attrib (feat, "xmlns");
316 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-tls"))
318 xmpp_tls_hook (parser, node);
321 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
323 xmpp_sasl_hook (parser, node);
326 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-bind"))
328 xmpp_bind_hook (parser, node);
336 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
338 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
340 if (!iks_strcmp (iks_name (node), "success"))
341 iks_send_header (parser, server);
342 else if (!iks_strcmp (iks_name (node), "failure"))
343 printf ("failture to authenticate: %s\n",
344 iks_string (iks_stack (node), node));
352 hook (void *data, int type, iks *node)
359 parser = *(iksparser **) data;
360 name = iks_name (node);
361 id = iks_find_attrib (node, "id");
362 ns = iks_find_attrib (node, "xmlns");
363 iqns = iks_find_attrib (iks_child (node), "xmlns");
364 if (!iks_strcmp (name, "message"))
367 from = iks_find_attrib (node, "from");
368 if (!iks_strncmp (from, authed_jid, iks_strlen (authed_jid)))
370 char *body = iks_find_cdata (node, "body");
372 process_mood (parser, body);
376 printf ("%s is not authorized\n", from);
380 else if (!iks_strcmp (name, "presence"))
383 from = iks_find_attrib (node, "from");
384 printf ("I sense a disturbance in the force: %s!\n", from);
386 else if (!iks_strcmp (name, "iq"))
388 if (xmpp_id_hook (parser, node, id) == 0)
390 if (xmpp_ns_hook (parser, node, iqns) == 0)
392 xmpp_iq_error (parser, node);
394 else if (!iks_strcmp (name, "stream:features"))
396 if (xmpp_features_hook (parser, node) == 0)
399 else if (!iks_strcmp (name, "stream:error"))
401 printf ("streamerror: %s\n", iks_string (iks_stack (node), node));
405 if (xmpp_other_hook (parser, node, ns) == 0)
407 printf ("No no: %s\n", name);
413 handler (GIOChannel *channel, GIOCondition cond, gpointer data)
415 iksparser *parser = data;
416 iks_recv (parser, 0);
421 { char * key; char * val; } keymaps[] =
423 { "artist", "artist" },
424 { "duration", "length" },
425 { "album", "source" },
426 { "title", "title" },
427 { "track-number", "track" },
428 { "location", "uri" },
436 for (i = 0; keymaps[i].key != NULL; i++)
437 if (strcmp (orig, keymaps[i].key) == 0)
438 return keymaps[i].val;
443 tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
445 DBusMessageIter entry;
449 dbus_message_iter_recurse (args, &entry);
450 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_STRING)
452 dbus_message_iter_get_basic (&entry, &strkey);
453 dbus_message_iter_next (&entry);
454 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_VARIANT)
456 dbus_message_iter_recurse (&entry, &var);
457 if (dbus_message_iter_get_arg_type (&var) == DBUS_TYPE_STRING)
459 dbus_message_iter_get_basic (&var, &strval);
464 printf ("%c\n", dbus_message_iter_get_arg_type (&entry));
465 strkey = map_key (strkey);
466 if (strkey && strval)
468 iks_insert_cdata (iks_insert (tune, strkey), strval, 0);
473 tune_from_dbus (DBusMessage *msg)
475 DBusMessageIter args;
477 tune = iks_new ("tune");
478 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
479 dbus_message_iter_init (msg, &args);
480 if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_ARRAY)
482 DBusMessageIter dict;
483 dbus_message_iter_recurse (&args, &dict);
484 while (dbus_message_iter_get_arg_type (&dict) ==
485 DBUS_TYPE_DICT_ENTRY)
487 tune_add_dbus_arg (tune, &dict);
488 dbus_message_iter_next (&dict);
494 static DBusHandlerResult
495 gettune (DBusConnection *conn, DBusMessage *msg, void *data)
498 if (dbus_message_is_signal (msg, "org.MetaPlayer.tag", "playing"))
500 printf("publishing tune\n");
501 tune = tune_from_dbus (msg);
502 pushtune (data, "http://jabber.org/protocol/tune", tune);
503 return DBUS_HANDLER_RESULT_HANDLED;
506 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
510 prepare_dbus (gpointer parser)
512 DBusConnection *conn;
513 conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
514 dbus_bus_register (conn, NULL);
515 dbus_bus_add_match (conn,
516 "type='signal'", NULL);
517 dbus_connection_flush (conn);
518 dbus_connection_setup_with_g_main (conn, g_main_context_default ());
519 dbus_connection_add_filter (conn, gettune, parser, NULL);
523 loop (iksparser *parser)
526 channel = g_io_channel_unix_new (iks_fd (parser));
527 g_io_add_watch (channel, G_IO_IN, handler, parser);
528 prepare_dbus (parser);
529 g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE));
533 main (int argc, char **argv)
537 while ((c = getopt (argc, argv, "s:u:p:i:a:")) != -1)
558 parser = iks_stream_new ("jabber:client", &parser, hook);
559 iks_connect_tcp (parser, server, 5222);