X-Git-Url: http://git.cascardo.info/?p=cascardo%2Ff2fchat.git;a=blobdiff_plain;f=friend.c;h=af5d5e3559b3faa0a1181a1c5d8d7fa77e868b6c;hp=e3d987fbe082a4736d0a6e2b58aa7cbc60a2ea4b;hb=2ce1e48602de964b8a12747b4a329fc082da7523;hpb=0b99a3303d0cb24d9b57a51ac0401f03be8c45ac diff --git a/friend.c b/friend.c index e3d987f..af5d5e3 100644 --- a/friend.c +++ b/friend.c @@ -26,12 +26,20 @@ #include #include #include "message.h" +#include "menu.h" + +enum { + STATE_OFFLINE, + STATE_PINGED, + STATE_ONLINE, +}; struct friend { char *name; char *address; uint16_t port; GInetSocketAddress *saddr; + int state; }; static GSocket *usock; @@ -40,14 +48,22 @@ int sock_init(void) { GSocketAddress *address; GInetAddress *any_addr; + GError *error; + int err = 0; any_addr = g_inet_address_new_any(G_SOCKET_FAMILY_IPV6); usock = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); address = g_inet_socket_address_new(any_addr, 17078); - g_socket_bind(usock, address, TRUE, NULL); - g_object_unref(any_addr); + if (!g_socket_bind(usock, address, TRUE, &error)) { + err = error->code; + g_error_free(error); + } g_object_unref(address); - message_init(usock); - return 0; + g_object_unref(any_addr); + if (!err) + message_init(usock); + else + g_object_unref(usock); + return err; } int friend_send_message(struct friend *friend, char *buffer, size_t len) @@ -56,18 +72,50 @@ int friend_send_message(struct friend *friend, char *buffer, size_t len) 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)) { + friend->state = STATE_ONLINE; + pong(friend); + } else if (len >= 4 && !strncmp(buffer, "PONG", 4)) { + friend->state = STATE_ONLINE; + } +} + +void friend_cmd(gchar **args, GSocketAddress *address) +{ + printf("%s\n", args[1]); +} + +void friend_init(void) +{ + struct menu_item *mi; + mi = g_malloc(sizeof(*mi)); + mi->cmd = "friend"; + mi->func = friend_cmd; + menu_add(mi); +} + struct cache { GList *friends; }; static struct cache *ucache; -struct friend *friend_get_by_address(GInetAddress *address) +struct friend *friend_get_by_address(GInetAddress *address, uint16_t port) { GList *l; for (l = g_list_first(ucache->friends); l != NULL; l = g_list_next(l)) { struct friend *friend = l->data; - if (g_inet_address_equal(g_inet_socket_address_get_address(friend->saddr), address)) + if (g_inet_address_equal(g_inet_socket_address_get_address(friend->saddr), address) && + friend->port == port) return friend; } return NULL; @@ -113,6 +161,8 @@ int cache_add_friend(struct cache *cache, char *name, char *address, uint16_t po friend->saddr = G_INET_SOCKET_ADDRESS(g_inet_socket_address_new(addr, friend->port)); g_object_unref(addr); cache->friends = g_list_append(cache->friends, friend); + ping(friend); + friend->state = STATE_PINGED; return 0; }