comparison libpurple/protocols/bonjour/mdns_avahi.c @ 18850:2283d5bfc24b

Implement setting buddy icons for avahi implementation. Fix receiving status changes and some other fixes.
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 09 Aug 2007 18:32:19 +0000
parents 1787e601aafc
children f773aa054dca
comparison
equal deleted inserted replaced
18849:1787e601aafc 18850:2283d5bfc24b
42 typedef struct _avahi_session_impl_data { 42 typedef struct _avahi_session_impl_data {
43 AvahiClient *client; 43 AvahiClient *client;
44 AvahiGLibPoll *glib_poll; 44 AvahiGLibPoll *glib_poll;
45 AvahiServiceBrowser *sb; 45 AvahiServiceBrowser *sb;
46 AvahiEntryGroup *group; 46 AvahiEntryGroup *group;
47 AvahiEntryGroup *buddy_icon_group;
47 } AvahiSessionImplData; 48 } AvahiSessionImplData;
48 49
49 typedef struct _avahi_buddy_impl_data { 50 typedef struct _avahi_buddy_impl_data {
50 AvahiRecordBrowser *record_browser; 51 AvahiServiceResolver *resolver;
52 AvahiRecordBrowser *buddy_icon_rec_browser;
51 } AvahiBuddyImplData; 53 } AvahiBuddyImplData;
52 54
53 static void 55 static void
54 _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, 56 _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol,
55 AvahiResolverEvent event, const char *name, const char *type, const char *domain, 57 AvahiResolverEvent event, const char *name, const char *type, const char *domain,
67 69
68 switch (event) { 70 switch (event) {
69 case AVAHI_RESOLVER_FAILURE: 71 case AVAHI_RESOLVER_FAILURE:
70 purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n", 72 purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n",
71 avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); 73 avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
74 avahi_service_resolver_free(r);
72 break; 75 break;
73 case AVAHI_RESOLVER_FOUND: 76 case AVAHI_RESOLVER_FOUND:
74 /* create a buddy record */ 77 /* create a buddy record */
75 buddy = bonjour_buddy_new(name, account); 78 buddy = bonjour_buddy_new(name, account);
79
80 ((AvahiBuddyImplData *)buddy->mdns_impl_data)->resolver = r;
76 81
77 /* Get the ip as a string */ 82 /* Get the ip as a string */
78 buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX); 83 buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX);
79 avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a); 84 avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a);
80 85
103 break; 108 break;
104 default: 109 default:
105 purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event); 110 purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event);
106 } 111 }
107 112
108 avahi_service_resolver_free(r);
109 } 113 }
110 114
111 static void 115 static void
112 _browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, 116 _browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface,
113 AvahiProtocol protocol, AvahiBrowserEvent event, 117 AvahiProtocol protocol, AvahiBrowserEvent event,
153 purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event); 157 purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event);
154 } 158 }
155 } 159 }
156 160
157 static void 161 static void
162 _buddy_icon_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
163 BonjourDnsSd *data = userdata;
164 AvahiSessionImplData *idata = data->mdns_impl_data;
165
166 g_return_if_fail(g == idata->buddy_icon_group || idata->buddy_icon_group == NULL);
167
168 switch(state) {
169 case AVAHI_ENTRY_GROUP_ESTABLISHED:
170 purple_debug_info("bonjour", "Successfully registered buddy icon data.\n");
171 case AVAHI_ENTRY_GROUP_COLLISION:
172 purple_debug_error("bonjour", "Collision registering buddy icon data.\n");
173 break;
174 case AVAHI_ENTRY_GROUP_FAILURE:
175 purple_debug_error("bonjour", "Error registering buddy icon data: %s\n.",
176 avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
177 break;
178 case AVAHI_ENTRY_GROUP_UNCOMMITED:
179 case AVAHI_ENTRY_GROUP_REGISTERING:
180 break;
181 }
182
183 }
184
185 static void
158 _entry_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { 186 _entry_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
159 AvahiSessionImplData *idata = userdata; 187 AvahiSessionImplData *idata = userdata;
160 188
161 g_return_if_fail(g == idata->group || idata->group == NULL); 189 g_return_if_fail(g == idata->group || idata->group == NULL);
162 190
185 AvahiBrowserEvent event, const char *name, uint16_t clazz, uint16_t type, 213 AvahiBrowserEvent event, const char *name, uint16_t clazz, uint16_t type,
186 const void *rdata, size_t size, AvahiLookupResultFlags flags, void *userdata) { 214 const void *rdata, size_t size, AvahiLookupResultFlags flags, void *userdata) {
187 BonjourBuddy *buddy = userdata; 215 BonjourBuddy *buddy = userdata;
188 AvahiBuddyImplData *idata = buddy->mdns_impl_data; 216 AvahiBuddyImplData *idata = buddy->mdns_impl_data;
189 217
190 purple_buddy_icons_set_for_user(buddy->account, buddy->name, 218 switch (event) {
191 g_memdup(rdata, size), size, buddy->phsh); 219 case AVAHI_BROWSER_NEW:
192 220 bonjour_buddy_got_buddy_icon(buddy, rdata, size);
193 avahi_record_browser_free(idata->record_browser); 221 break;
194 idata->record_browser = NULL; 222 case AVAHI_BROWSER_REMOVE:
223 case AVAHI_BROWSER_CACHE_EXHAUSTED:
224 case AVAHI_BROWSER_ALL_FOR_NOW:
225 case AVAHI_BROWSER_FAILURE:
226 purple_debug_error("bonjour", "Error rerieving buddy icon record: %s\n",
227 avahi_strerror(avahi_client_errno(avahi_record_browser_get_client(b))));
228 break;
229 }
230
231 /* Stop listening */
232 avahi_record_browser_free(idata->buddy_icon_rec_browser);
233 idata->buddy_icon_rec_browser = NULL;
195 } 234 }
196 235
197 /**************************** 236 /****************************
198 * mdns_interface functions * 237 * mdns_interface functions *
199 ****************************/ 238 ****************************/
312 "Failed to add the " ICHAT_SERVICE " service. Error: %s\n", 351 "Failed to add the " ICHAT_SERVICE " service. Error: %s\n",
313 avahi_strerror(publish_result)); 352 avahi_strerror(publish_result));
314 return FALSE; 353 return FALSE;
315 } 354 }
316 355
317 if ((publish_result = avahi_entry_group_commit(idata->group)) < 0) { 356 if (type == PUBLISH_START
357 && (publish_result = avahi_entry_group_commit(idata->group)) < 0) {
318 purple_debug_error("bonjour", 358 purple_debug_error("bonjour",
319 "Failed to commit " ICHAT_SERVICE " service. Error: %s\n", 359 "Failed to commit " ICHAT_SERVICE " service. Error: %s\n",
320 avahi_strerror(publish_result)); 360 avahi_strerror(publish_result));
321 return FALSE; 361 return FALSE;
322 } 362 }
340 380
341 return TRUE; 381 return TRUE;
342 } 382 }
343 383
344 gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) { 384 gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) {
345 return FALSE; 385 AvahiSessionImplData *idata = data->mdns_impl_data;
386
387 if (idata == NULL || idata->client == NULL)
388 return FALSE;
389
390 if (avatar_data != NULL) {
391 gboolean new_group = FALSE;
392 gchar *svc_name;
393 int ret;
394 AvahiPublishFlags flags = 0;
395
396 if (idata->buddy_icon_group == NULL) {
397 purple_debug_info("bonjour", "Setting new buddy icon.\n");
398 new_group = TRUE;
399
400 idata->buddy_icon_group = avahi_entry_group_new(idata->client,
401 _buddy_icon_group_cb, data);
402 } else {
403 purple_debug_info("bonjour", "Updating existing buddy icon.\n");
404 flags |= AVAHI_PUBLISH_UPDATE;
405 }
406
407 if (idata->buddy_icon_group == NULL) {
408 purple_debug_error("bonjour",
409 "Unable to initialize the buddy icon group (%s).\n",
410 avahi_strerror(avahi_client_errno(idata->client)));
411 return FALSE;
412 }
413
414 svc_name = g_strdup_printf("%s." ICHAT_SERVICE "local",
415 purple_account_get_username(data->account));
416
417 ret = avahi_entry_group_add_record(idata->buddy_icon_group, AVAHI_IF_UNSPEC,
418 AVAHI_PROTO_UNSPEC, flags, svc_name,
419 AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 120, avatar_data, avatar_len);
420
421 g_free(svc_name);
422
423 if (ret < 0) {
424 purple_debug_error("bonjour",
425 "Failed to register buddy icon. Error: %s\n", avahi_strerror(ret));
426 if (new_group) {
427 avahi_entry_group_free(idata->buddy_icon_group);
428 idata->buddy_icon_group = NULL;
429 }
430 return FALSE;
431 }
432
433 if (new_group && (ret = avahi_entry_group_commit(idata->buddy_icon_group)) < 0) {
434 purple_debug_error("bonjour",
435 "Failed to commit buddy icon group. Error: %s\n", avahi_strerror(ret));
436 if (new_group) {
437 avahi_entry_group_free(idata->buddy_icon_group);
438 idata->buddy_icon_group = NULL;
439 }
440 return FALSE;
441 }
442 } else if (idata->buddy_icon_group != NULL) {
443 purple_debug_info("bonjour", "Removing existing buddy icon.\n");
444 avahi_entry_group_free(idata->buddy_icon_group);
445 idata->buddy_icon_group = NULL;
446 }
447
448 return TRUE;
346 } 449 }
347 450
348 void _mdns_stop(BonjourDnsSd *data) { 451 void _mdns_stop(BonjourDnsSd *data) {
349 AvahiSessionImplData *idata = data->mdns_impl_data; 452 AvahiSessionImplData *idata = data->mdns_impl_data;
350 453
369 void _mdns_delete_buddy(BonjourBuddy *buddy) { 472 void _mdns_delete_buddy(BonjourBuddy *buddy) {
370 AvahiBuddyImplData *idata = buddy->mdns_impl_data; 473 AvahiBuddyImplData *idata = buddy->mdns_impl_data;
371 474
372 g_return_if_fail(idata != NULL); 475 g_return_if_fail(idata != NULL);
373 476
374 if (idata->record_browser != NULL) 477 if (idata->buddy_icon_rec_browser != NULL)
375 avahi_record_browser_free(idata->record_browser); 478 avahi_record_browser_free(idata->buddy_icon_rec_browser);
479
480 if (idata->resolver != NULL)
481 avahi_service_resolver_free(idata->resolver);
376 482
377 g_free(idata); 483 g_free(idata);
378 484
379 buddy->mdns_impl_data = NULL; 485 buddy->mdns_impl_data = NULL;
380 } 486 }
386 AvahiBuddyImplData *idata = buddy->mdns_impl_data; 492 AvahiBuddyImplData *idata = buddy->mdns_impl_data;
387 gchar *name; 493 gchar *name;
388 494
389 g_return_if_fail(idata != NULL); 495 g_return_if_fail(idata != NULL);
390 496
391 if (idata->record_browser != NULL) 497 if (idata->buddy_icon_rec_browser != NULL)
392 avahi_record_browser_free(idata->record_browser); 498 avahi_record_browser_free(idata->buddy_icon_rec_browser);
499
500 purple_debug_info("bonjour", "Retrieving buddy icon for '%s'.\n", buddy->name);
393 501
394 name = g_strdup_printf("%s." ICHAT_SERVICE "local", buddy->name); 502 name = g_strdup_printf("%s." ICHAT_SERVICE "local", buddy->name);
395 idata->record_browser = avahi_record_browser_new(session_idata->client, AVAHI_IF_UNSPEC, 503 idata->buddy_icon_rec_browser = avahi_record_browser_new(session_idata->client, AVAHI_IF_UNSPEC,
396 AVAHI_PROTO_UNSPEC, name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 0, 504 AVAHI_PROTO_UNSPEC, name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 0,
397 _buddy_icon_record_cb, buddy); 505 _buddy_icon_record_cb, buddy);
398 g_free(name); 506 g_free(name);
399 507
400 if (!idata->record_browser) { 508 if (!idata->buddy_icon_rec_browser) {
401 purple_debug_error("bonjour", 509 purple_debug_error("bonjour",
402 "Unable to initialize record browser. Error: %s\n.", 510 "Unable to initialize buddy icon record browser. Error: %s\n.",
403 avahi_strerror(avahi_client_errno(session_idata->client))); 511 avahi_strerror(avahi_client_errno(session_idata->client)));
404 } 512 }
405 513
406 } 514 }
407 515