#include <stdio.h>
#include "message.h"
+enum {
+ STATE_OFFLINE,
+ STATE_PINGED,
+ STATE_ONLINE,
+};
+
struct friend {
char *name;
char *address;
uint16_t port;
GInetSocketAddress *saddr;
+ int state;
};
static GSocket *usock;
return 0;
}
+void friend_timeout(struct friend *friend)
+{
+ if (friend->state == STATE_PINGED) {
+ friend->state = STATE_OFFLINE;
+ }
+}
+
+void friend_got_message(struct friend *friend, char *buffer, size_t len)
+{
+ if (len >= 4 && !strncmp(buffer, "PING", 4)) {
+ pong(friend);
+ } else if (len >= 4 && !strncmp(buffer, "PONG", 4)) {
+ friend->state = STATE_ONLINE;
+ }
+}
+
struct cache {
GList *friends;
};
g_object_unref(addr);
cache->friends = g_list_append(cache->friends, friend);
ping(friend);
+ friend->state = STATE_PINGED;
return 0;
}
char *friend_get_name();
+void friend_timeout(struct friend *friend);
+void friend_got_message(struct friend *friend, char *buffer, size_t len);
+
#endif
gboolean ping_timeout(gpointer data)
{
struct friend *friend = data;
+ friend_timeout(friend);
return G_SOURCE_REMOVE;
}
friend = friend_get_by_address(iaddress, port);
if (friend) {
printf("got message from %s\n", friend_get_name(friend));
- g_source_remove_by_user_data(friend);
+ friend_got_message(friend, buffer, len);
} else {
printf("could not find friend from address %s\n", g_inet_address_to_string(iaddress));
}
int ping(struct friend *friend)
{
+ int err;
char ping[5] = "PING";
- friend_send_message(friend, ping, 4);
- g_timeout_add(2000, ping_timeout, friend);
+ err = friend_send_message(friend, ping, 4);
+ if (!err)
+ g_timeout_add(2000, ping_timeout, friend);
+ return err;
+}
+
+int pong(struct friend *friend)
+{
+ char pong[5] = "PONG";
+ return friend_send_message(friend, pong, 4);
}