4 This file is part of avahi.
6 avahi is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 avahi is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14 Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with avahi; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include <dbus/dbus.h>
32 #include <avahi-client/client.h>
33 #include <avahi-common/dbus.h>
34 #include <avahi-common/llist.h>
35 #include <avahi-common/error.h>
36 #include <avahi-common/malloc.h>
41 AvahiDomainBrowser* avahi_domain_browser_new(
43 AvahiIfIndex interface,
44 AvahiProtocol protocol,
46 AvahiDomainBrowserType btype,
47 AvahiLookupFlags flags,
48 AvahiDomainBrowserCallback callback,
51 AvahiDomainBrowser *db = NULL;
52 DBusMessage *message = NULL, *reply = NULL;
55 int32_t i_interface, i_protocol, bt;
61 dbus_error_init (&error);
63 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
64 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
71 if (!(db = avahi_new (AvahiDomainBrowser, 1))) {
72 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
77 db->callback = callback;
78 db->userdata = userdata;
81 AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db);
83 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew"))) {
84 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
88 i_interface = (int32_t) interface;
89 i_protocol = (int32_t) protocol;
90 u_flags = (uint32_t) flags;
93 if (!(dbus_message_append_args(
95 DBUS_TYPE_INT32, &i_interface,
96 DBUS_TYPE_INT32, &i_protocol,
97 DBUS_TYPE_STRING, &domain,
99 DBUS_TYPE_UINT32, &flags,
100 DBUS_TYPE_INVALID))) {
101 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
105 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
106 dbus_error_is_set(&error)) {
107 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
111 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
112 dbus_error_is_set(&error) ||
114 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
118 if (!(db->path = avahi_strdup(path))) {
120 /* FIXME: We don't remove the object on the server side */
122 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
126 dbus_message_unref(message);
127 dbus_message_unref(reply);
133 if (dbus_error_is_set(&error)) {
134 avahi_client_set_dbus_error(client, &error);
135 dbus_error_free(&error);
139 avahi_domain_browser_free(db);
142 dbus_message_unref(message);
145 dbus_message_unref(reply);
150 AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *b)
156 int avahi_domain_browser_free (AvahiDomainBrowser *b) {
163 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
164 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free");
166 AVAHI_LLIST_REMOVE(AvahiDomainBrowser, domain_browsers, client->domain_browsers, b);
174 DBusHandlerResult avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
175 AvahiDomainBrowser *db = NULL;
179 int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
185 dbus_error_init (&error);
187 if (!(path = dbus_message_get_path(message)))
190 for (db = client->domain_browsers; db; db = db->domain_browsers_next)
191 if (strcmp (db->path, path) == 0)
198 case AVAHI_BROWSER_NEW:
199 case AVAHI_BROWSER_REMOVE:
201 if (!dbus_message_get_args(
203 DBUS_TYPE_INT32, &interface,
204 DBUS_TYPE_INT32, &protocol,
205 DBUS_TYPE_STRING, &domain,
206 DBUS_TYPE_UINT32, &flags,
207 DBUS_TYPE_INVALID) ||
208 dbus_error_is_set (&error)) {
209 fprintf(stderr, "Failed to parse browser event.\n");
215 case AVAHI_BROWSER_CACHE_EXHAUSTED:
216 case AVAHI_BROWSER_ALL_FOR_NOW:
219 case AVAHI_BROWSER_FAILURE: {
222 if (!dbus_message_get_args(
224 DBUS_TYPE_STRING, &etxt,
225 DBUS_TYPE_INVALID) ||
226 dbus_error_is_set (&error)) {
227 fprintf(stderr, "Failed to parse browser event.\n");
231 avahi_client_set_errno(db->client, avahi_error_dbus_to_number(etxt));
236 db->callback(db, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, domain, (AvahiLookupResultFlags) flags, db->userdata);
238 return DBUS_HANDLER_RESULT_HANDLED;
241 dbus_error_free (&error);
242 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
245 /* AvahiServiceTypeBrowser */
246 AvahiServiceTypeBrowser* avahi_service_type_browser_new(
248 AvahiIfIndex interface,
249 AvahiProtocol protocol,
251 AvahiLookupFlags flags,
252 AvahiServiceTypeBrowserCallback callback,
255 AvahiServiceTypeBrowser *b = NULL;
256 DBusMessage *message = NULL, *reply = NULL;
259 int32_t i_interface, i_protocol;
265 dbus_error_init(&error);
267 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
268 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
275 if (!(b = avahi_new(AvahiServiceTypeBrowser, 1))) {
276 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
281 b->callback = callback;
282 b->userdata = userdata;
285 AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, service_type_browsers, client->service_type_browsers, b);
287 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew"))) {
288 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
292 i_interface = (int32_t) interface;
293 i_protocol = (int32_t) protocol;
294 u_flags = (uint32_t) flags;
296 if (!dbus_message_append_args(
298 DBUS_TYPE_INT32, &i_interface,
299 DBUS_TYPE_INT32, &i_protocol,
300 DBUS_TYPE_STRING, &domain,
301 DBUS_TYPE_UINT32, &u_flags,
302 DBUS_TYPE_INVALID)) {
303 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
307 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
308 dbus_error_is_set(&error)) {
309 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
313 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
314 dbus_error_is_set(&error) ||
316 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
320 if (!(b->path = avahi_strdup(path))) {
322 /* FIXME: We don't remove the object on the server side */
324 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
328 dbus_message_unref(message);
329 dbus_message_unref(reply);
335 if (dbus_error_is_set(&error)) {
336 avahi_client_set_dbus_error(client, &error);
337 dbus_error_free(&error);
341 avahi_service_type_browser_free(b);
344 dbus_message_unref(message);
347 dbus_message_unref(reply);
352 AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *b)
358 int avahi_service_type_browser_free (AvahiServiceTypeBrowser *b) {
365 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
366 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free");
368 AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b);
375 DBusHandlerResult avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
376 AvahiServiceTypeBrowser *b = NULL;
379 char *domain = NULL, *type = NULL;
380 int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
386 dbus_error_init (&error);
388 if (!(path = dbus_message_get_path(message)))
391 for (b = client->service_type_browsers; b; b = b->service_type_browsers_next)
392 if (strcmp (b->path, path) == 0)
398 case AVAHI_BROWSER_NEW:
399 case AVAHI_BROWSER_REMOVE:
400 if (!dbus_message_get_args(
402 DBUS_TYPE_INT32, &interface,
403 DBUS_TYPE_INT32, &protocol,
404 DBUS_TYPE_STRING, &type,
405 DBUS_TYPE_STRING, &domain,
406 DBUS_TYPE_UINT32, &flags,
407 DBUS_TYPE_INVALID) ||
408 dbus_error_is_set(&error)) {
409 fprintf(stderr, "Failed to parse browser event.\n");
414 case AVAHI_BROWSER_CACHE_EXHAUSTED:
415 case AVAHI_BROWSER_ALL_FOR_NOW:
418 case AVAHI_BROWSER_FAILURE: {
421 if (!dbus_message_get_args(
423 DBUS_TYPE_STRING, &etxt,
424 DBUS_TYPE_INVALID) ||
425 dbus_error_is_set (&error)) {
426 fprintf(stderr, "Failed to parse browser event.\n");
430 avahi_client_set_errno(b->client, avahi_error_dbus_to_number(etxt));
435 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
437 return DBUS_HANDLER_RESULT_HANDLED;
440 dbus_error_free (&error);
441 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
444 /* AvahiServiceBrowser */
446 AvahiServiceBrowser* avahi_service_browser_new(
448 AvahiIfIndex interface,
449 AvahiProtocol protocol,
452 AvahiLookupFlags flags,
453 AvahiServiceBrowserCallback callback,
456 AvahiServiceBrowser *b = NULL;
457 DBusMessage *message = NULL, *reply = NULL;
460 int32_t i_protocol, i_interface;
467 dbus_error_init(&error);
469 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
470 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
477 if (!(b = avahi_new(AvahiServiceBrowser, 1))) {
478 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
483 b->callback = callback;
484 b->userdata = userdata;
487 AVAHI_LLIST_PREPEND(AvahiServiceBrowser, service_browsers, client->service_browsers, b);
489 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew"))) {
490 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
494 i_interface = (int32_t) interface;
495 i_protocol = (int32_t) protocol;
496 u_flags = (uint32_t) flags;
498 if (!dbus_message_append_args(
500 DBUS_TYPE_INT32, &i_interface,
501 DBUS_TYPE_INT32, &i_protocol,
502 DBUS_TYPE_STRING, &type,
503 DBUS_TYPE_STRING, &domain,
504 DBUS_TYPE_UINT32, &u_flags,
505 DBUS_TYPE_INVALID)) {
506 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
510 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
511 dbus_error_is_set(&error)) {
512 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
516 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
517 dbus_error_is_set(&error) ||
519 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
523 if (!(b->path = avahi_strdup(path))) {
525 /* FIXME: We don't remove the object on the server side */
527 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
531 dbus_message_unref(message);
532 dbus_message_unref(reply);
537 if (dbus_error_is_set(&error)) {
538 avahi_client_set_dbus_error(client, &error);
539 dbus_error_free(&error);
543 avahi_service_browser_free(b);
546 dbus_message_unref(message);
549 dbus_message_unref(reply);
554 AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *b)
560 int avahi_service_browser_free (AvahiServiceBrowser *b) {
567 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
568 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free");
570 AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b);
578 DBusHandlerResult avahi_service_browser_event(AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
579 AvahiServiceBrowser *b = NULL;
582 char *name = NULL, *type = NULL, *domain = NULL;
583 int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
586 dbus_error_init (&error);
588 if (!(path = dbus_message_get_path(message)))
591 for (b = client->service_browsers; b; b = b->service_browsers_next)
592 if (strcmp (b->path, path) == 0)
599 case AVAHI_BROWSER_NEW:
600 case AVAHI_BROWSER_REMOVE:
602 if (!dbus_message_get_args (
604 DBUS_TYPE_INT32, &interface,
605 DBUS_TYPE_INT32, &protocol,
606 DBUS_TYPE_STRING, &name,
607 DBUS_TYPE_STRING, &type,
608 DBUS_TYPE_STRING, &domain,
609 DBUS_TYPE_UINT32, &flags,
610 DBUS_TYPE_INVALID) ||
611 dbus_error_is_set(&error)) {
612 fprintf(stderr, "Failed to parse browser event.\n");
617 case AVAHI_BROWSER_CACHE_EXHAUSTED:
618 case AVAHI_BROWSER_ALL_FOR_NOW:
621 case AVAHI_BROWSER_FAILURE: {
624 if (!dbus_message_get_args(
626 DBUS_TYPE_STRING, &etxt,
627 DBUS_TYPE_INVALID) ||
628 dbus_error_is_set (&error)) {
629 fprintf(stderr, "Failed to parse browser event.\n");
633 avahi_client_set_errno(b->client, avahi_error_dbus_to_number(etxt));
638 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, name, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
640 return DBUS_HANDLER_RESULT_HANDLED;
643 dbus_error_free (&error);
644 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;