# HG changeset patch # User Daniel Atallah # Date 1186684339 0 # Node ID 2283d5bfc24ba7c46a4b2ed025b36f533e8db792 # Parent 1787e601aafcae0a7291d1cde25b835aac16d003 Implement setting buddy icons for avahi implementation. Fix receiving status changes and some other fixes. diff -r 1787e601aafc -r 2283d5bfc24b libpurple/protocols/bonjour/mdns_avahi.c --- a/libpurple/protocols/bonjour/mdns_avahi.c Thu Aug 09 02:33:17 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_avahi.c Thu Aug 09 18:32:19 2007 +0000 @@ -44,10 +44,12 @@ AvahiGLibPoll *glib_poll; AvahiServiceBrowser *sb; AvahiEntryGroup *group; + AvahiEntryGroup *buddy_icon_group; } AvahiSessionImplData; typedef struct _avahi_buddy_impl_data { - AvahiRecordBrowser *record_browser; + AvahiServiceResolver *resolver; + AvahiRecordBrowser *buddy_icon_rec_browser; } AvahiBuddyImplData; static void @@ -69,11 +71,14 @@ case AVAHI_RESOLVER_FAILURE: purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n", avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); + avahi_service_resolver_free(r); break; case AVAHI_RESOLVER_FOUND: /* create a buddy record */ buddy = bonjour_buddy_new(name, account); + ((AvahiBuddyImplData *)buddy->mdns_impl_data)->resolver = r; + /* Get the ip as a string */ buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX); avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a); @@ -105,7 +110,6 @@ purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event); } - avahi_service_resolver_free(r); } static void @@ -155,6 +159,30 @@ } static void +_buddy_icon_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { + BonjourDnsSd *data = userdata; + AvahiSessionImplData *idata = data->mdns_impl_data; + + g_return_if_fail(g == idata->buddy_icon_group || idata->buddy_icon_group == NULL); + + switch(state) { + case AVAHI_ENTRY_GROUP_ESTABLISHED: + purple_debug_info("bonjour", "Successfully registered buddy icon data.\n"); + case AVAHI_ENTRY_GROUP_COLLISION: + purple_debug_error("bonjour", "Collision registering buddy icon data.\n"); + break; + case AVAHI_ENTRY_GROUP_FAILURE: + purple_debug_error("bonjour", "Error registering buddy icon data: %s\n.", + avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); + break; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + break; + } + +} + +static void _entry_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { AvahiSessionImplData *idata = userdata; @@ -187,11 +215,22 @@ BonjourBuddy *buddy = userdata; AvahiBuddyImplData *idata = buddy->mdns_impl_data; - purple_buddy_icons_set_for_user(buddy->account, buddy->name, - g_memdup(rdata, size), size, buddy->phsh); + switch (event) { + case AVAHI_BROWSER_NEW: + bonjour_buddy_got_buddy_icon(buddy, rdata, size); + break; + case AVAHI_BROWSER_REMOVE: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_FAILURE: + purple_debug_error("bonjour", "Error rerieving buddy icon record: %s\n", + avahi_strerror(avahi_client_errno(avahi_record_browser_get_client(b)))); + break; + } - avahi_record_browser_free(idata->record_browser); - idata->record_browser = NULL; + /* Stop listening */ + avahi_record_browser_free(idata->buddy_icon_rec_browser); + idata->buddy_icon_rec_browser = NULL; } /**************************** @@ -314,7 +353,8 @@ return FALSE; } - if ((publish_result = avahi_entry_group_commit(idata->group)) < 0) { + if (type == PUBLISH_START + && (publish_result = avahi_entry_group_commit(idata->group)) < 0) { purple_debug_error("bonjour", "Failed to commit " ICHAT_SERVICE " service. Error: %s\n", avahi_strerror(publish_result)); @@ -342,7 +382,70 @@ } gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) { - return FALSE; + AvahiSessionImplData *idata = data->mdns_impl_data; + + if (idata == NULL || idata->client == NULL) + return FALSE; + + if (avatar_data != NULL) { + gboolean new_group = FALSE; + gchar *svc_name; + int ret; + AvahiPublishFlags flags = 0; + + if (idata->buddy_icon_group == NULL) { + purple_debug_info("bonjour", "Setting new buddy icon.\n"); + new_group = TRUE; + + idata->buddy_icon_group = avahi_entry_group_new(idata->client, + _buddy_icon_group_cb, data); + } else { + purple_debug_info("bonjour", "Updating existing buddy icon.\n"); + flags |= AVAHI_PUBLISH_UPDATE; + } + + if (idata->buddy_icon_group == NULL) { + purple_debug_error("bonjour", + "Unable to initialize the buddy icon group (%s).\n", + avahi_strerror(avahi_client_errno(idata->client))); + return FALSE; + } + + svc_name = g_strdup_printf("%s." ICHAT_SERVICE "local", + purple_account_get_username(data->account)); + + ret = avahi_entry_group_add_record(idata->buddy_icon_group, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, flags, svc_name, + AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 120, avatar_data, avatar_len); + + g_free(svc_name); + + if (ret < 0) { + purple_debug_error("bonjour", + "Failed to register buddy icon. Error: %s\n", avahi_strerror(ret)); + if (new_group) { + avahi_entry_group_free(idata->buddy_icon_group); + idata->buddy_icon_group = NULL; + } + return FALSE; + } + + if (new_group && (ret = avahi_entry_group_commit(idata->buddy_icon_group)) < 0) { + purple_debug_error("bonjour", + "Failed to commit buddy icon group. Error: %s\n", avahi_strerror(ret)); + if (new_group) { + avahi_entry_group_free(idata->buddy_icon_group); + idata->buddy_icon_group = NULL; + } + return FALSE; + } + } else if (idata->buddy_icon_group != NULL) { + purple_debug_info("bonjour", "Removing existing buddy icon.\n"); + avahi_entry_group_free(idata->buddy_icon_group); + idata->buddy_icon_group = NULL; + } + + return TRUE; } void _mdns_stop(BonjourDnsSd *data) { @@ -371,8 +474,11 @@ g_return_if_fail(idata != NULL); - if (idata->record_browser != NULL) - avahi_record_browser_free(idata->record_browser); + if (idata->buddy_icon_rec_browser != NULL) + avahi_record_browser_free(idata->buddy_icon_rec_browser); + + if (idata->resolver != NULL) + avahi_service_resolver_free(idata->resolver); g_free(idata); @@ -388,20 +494,22 @@ g_return_if_fail(idata != NULL); - if (idata->record_browser != NULL) - avahi_record_browser_free(idata->record_browser); + if (idata->buddy_icon_rec_browser != NULL) + avahi_record_browser_free(idata->buddy_icon_rec_browser); + + purple_debug_info("bonjour", "Retrieving buddy icon for '%s'.\n", buddy->name); name = g_strdup_printf("%s." ICHAT_SERVICE "local", buddy->name); - idata->record_browser = avahi_record_browser_new(session_idata->client, AVAHI_IF_UNSPEC, + idata->buddy_icon_rec_browser = avahi_record_browser_new(session_idata->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 0, _buddy_icon_record_cb, buddy); g_free(name); - if (!idata->record_browser) { + if (!idata->buddy_icon_rec_browser) { purple_debug_error("bonjour", - "Unable to initialize record browser. Error: %s\n.", + "Unable to initialize buddy icon record browser. Error: %s\n.", avahi_strerror(avahi_client_errno(session_idata->client))); -} + } }