/*
* Copyright © 2011 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* .
*
* Authored by: Rob Staudinger
*/
#include
#include
#include
#include
#define CLIENT_UID "org.freedesktop.ytstenut.EchoExampleClient"
#define SERVER_UID "org.freedesktop.ytstenut.EchoExampleServer"
/*
* Client
*/
static void
_client_authenticated (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_client_ready (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_client_disconnected (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_client_message (YtsClient *client,
YtsMessage *msg,
void *data)
{
char const *text;
g_debug ("%s()", __FUNCTION__);
g_return_if_fail (YTS_IS_MESSAGE (msg));
text = yts_metadata_get_attribute (YTS_METADATA (msg), "message");
g_debug ("Message is \"%s\"", text);
}
static gboolean
_client_incoming_file (YtsClient *client,
const char *from,
const char *name,
guint64 size,
guint64 offset,
TpChannel *channel)
{
g_debug ("%s()", __FUNCTION__);
return false;
}
static void
_client_roster_service_added (YtsRoster *roster,
YtsService *service,
void *data)
{
char const *uid;
char const *jid;
uid = yts_service_get_uid (service);
jid = yts_service_get_jid (service);
if (0 == g_strcmp0 (uid, SERVER_UID)) {
const char *payload[] = {
"message", "hello world",
NULL
};
YtsMetadata *message = (YtsMetadata*)yts_message_new ((const char**)&payload);
g_debug ("%s() %s %s", __FUNCTION__, uid, jid);
g_debug ("Sending message \"%s\"", payload[1]);
yts_metadata_service_send_metadata ((YtsMetadataService *)service,
message);
}
}
static int
run_client (void)
{
YtsClient *client;
YtsRoster *roster;
GMainLoop *mainloop;
client = yts_client_new (YTS_PROTOCOL_LOCAL_XMPP, CLIENT_UID);
g_signal_connect (client, "authenticated",
G_CALLBACK (_client_authenticated), NULL);
g_signal_connect (client, "ready",
G_CALLBACK (_client_ready), NULL);
g_signal_connect (client, "disconnected",
G_CALLBACK (_client_disconnected), NULL);
g_signal_connect (client, "message",
G_CALLBACK (_client_message), NULL);
g_signal_connect (client, "incoming-file",
G_CALLBACK (_client_incoming_file), NULL);
roster = yts_client_get_roster (client);
g_signal_connect (roster, "service-added",
G_CALLBACK (_client_roster_service_added), NULL);
yts_client_connect (client);
mainloop = g_main_loop_new (NULL, false);
g_main_loop_run (mainloop);
g_main_loop_unref (mainloop);
return EXIT_SUCCESS;
}
/*
* Server
*/
typedef struct {
YtsMetadataService *service;
} ServerData;
static void
_server_authenticated (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_server_ready (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_server_disconnected (YtsClient *client,
void *data)
{
g_debug ("%s()", __FUNCTION__);
}
static void
_server_message (YtsClient *client,
YtsMessage *msg,
ServerData *self)
{
g_debug ("%s() know client: %s", __FUNCTION__,
self->service ? "yes" : "no");
g_return_if_fail (YTS_IS_MESSAGE (msg));
if (self->service) {
YtsMetadata *message;
char const *payload[] = {
"message", "foo",
NULL
};
char const *text = yts_metadata_get_attribute (YTS_METADATA (msg),
"message");
g_debug ("%s() echoing \"%s\"", __FUNCTION__, text);
payload[1] = text;
message = (YtsMetadata*)yts_message_new ((const char**)&payload);
yts_metadata_service_send_metadata ((YtsMetadataService *)self->service,
message);
}
}
static gboolean
_server_incoming_file (YtsClient *client,
const char *from,
const char *name,
guint64 size,
guint64 offset,
TpChannel *channel)
{
g_debug ("%s()", __FUNCTION__);
return false;
}
static void
_server_roster_service_added (YtsRoster *roster,
YtsService *service,
ServerData *self)
{
char const *uid;
char const *jid;
uid = yts_service_get_uid (service);
jid = yts_service_get_jid (service);
g_debug ("%s() %s %s", __FUNCTION__, uid, jid);
/* FIXME, possible race condition when client sends message before
* it shows up in our roster? */
if (0 == g_strcmp0 (uid, CLIENT_UID)) {
/* Should probably take a weak ref here. */
self->service = YTS_METADATA_SERVICE (service);
}
}
static int
run_server (void)
{
YtsClient *client;
YtsRoster *roster;
GMainLoop *mainloop;
ServerData self = { NULL, };
client = yts_client_new (YTS_PROTOCOL_LOCAL_XMPP, SERVER_UID);
g_signal_connect (client, "authenticated",
G_CALLBACK (_server_authenticated), NULL);
g_signal_connect (client, "ready",
G_CALLBACK (_server_ready), NULL);
g_signal_connect (client, "disconnected",
G_CALLBACK (_server_disconnected), NULL);
g_signal_connect (client, "message",
G_CALLBACK (_server_message), &self);
g_signal_connect (client, "incoming-file",
G_CALLBACK (_server_incoming_file), NULL);
roster = yts_client_get_roster (client);
g_signal_connect (roster, "service-added",
G_CALLBACK (_server_roster_service_added), &self);
yts_client_connect (client);
mainloop = g_main_loop_new (NULL, false);
g_main_loop_run (mainloop);
g_main_loop_unref (mainloop);
return EXIT_SUCCESS;
}
int
main (int argc,
char **argv)
{
bool client = false;
bool server = true;
GOptionEntry entries[] = {
{ "client", 'c', 0, G_OPTION_ARG_NONE, &client, "Run as client", NULL },
{ "server", 's', 0, G_OPTION_ARG_NONE, &server, "Run as server (default)", NULL },
{ NULL, }
};
GError *error = NULL;
GOptionContext *context;
int ret;
context = g_option_context_new ("- Ytstenut echo example");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_add_group (context, yts_get_option_group ());
g_option_context_parse (context, &argc, &argv, &error);
if (error) {
g_warning ("%s : %s", G_STRLOC, error->message);
g_clear_error (&error);
}
if (client) {
g_message ("Running as client ...");
ret = run_client ();
} else if (server) {
g_message ("Running as server ...");
ret = run_server ();
} else {
g_warning ("%s : Not running as server or client, quitting", G_STRLOC);
ret = -1;
}
return ret;
}