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;
80 db->interface = interface;
81 db->protocol = protocol;
83 AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db);
85 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew"))) {
86 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
90 i_interface = (int32_t) interface;
91 i_protocol = (int32_t) protocol;
92 u_flags = (uint32_t) flags;
95 if (!(dbus_message_append_args(
97 DBUS_TYPE_INT32, &i_interface,
98 DBUS_TYPE_INT32, &i_protocol,
99 DBUS_TYPE_STRING, &domain,
100 DBUS_TYPE_INT32, &bt,
101 DBUS_TYPE_UINT32, &flags,
102 DBUS_TYPE_INVALID))) {
103 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
107 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
108 dbus_error_is_set(&error)) {
109 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
113 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
114 dbus_error_is_set(&error) ||
116 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
120 if (!(db->path = avahi_strdup(path))) {
122 /* FIXME: We don't remove the object on the server side */
124 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
128 dbus_message_unref(message);
129 dbus_message_unref(reply);
135 if (dbus_error_is_set(&error)) {
136 avahi_client_set_dbus_error(client, &error);
137 dbus_error_free(&error);
141 avahi_domain_browser_free(db);
144 dbus_message_unref(message);
147 dbus_message_unref(reply);
152 AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *b) {
157 int avahi_domain_browser_free (AvahiDomainBrowser *b) {
164 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
165 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free");
167 AVAHI_LLIST_REMOVE(AvahiDomainBrowser, domain_browsers, client->domain_browsers, b);
175 DBusHandlerResult avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
176 AvahiDomainBrowser *db = NULL;
180 int32_t interface, protocol;
186 dbus_error_init (&error);
188 if (!(path = dbus_message_get_path(message)))
191 for (db = client->domain_browsers; db; db = db->domain_browsers_next)
192 if (strcmp (db->path, path) == 0)
198 interface = db->interface;
199 protocol = db->protocol;
202 case AVAHI_BROWSER_NEW:
203 case AVAHI_BROWSER_REMOVE:
205 if (!dbus_message_get_args(
207 DBUS_TYPE_INT32, &interface,
208 DBUS_TYPE_INT32, &protocol,
209 DBUS_TYPE_STRING, &domain,
210 DBUS_TYPE_UINT32, &flags,
211 DBUS_TYPE_INVALID) ||
212 dbus_error_is_set (&error)) {
213 fprintf(stderr, "Failed to parse browser event.\n");
219 case AVAHI_BROWSER_CACHE_EXHAUSTED:
220 case AVAHI_BROWSER_ALL_FOR_NOW:
223 case AVAHI_BROWSER_FAILURE: {
226 if (!dbus_message_get_args(
228 DBUS_TYPE_STRING, &etxt,
229 DBUS_TYPE_INVALID) ||
230 dbus_error_is_set (&error)) {
231 fprintf(stderr, "Failed to parse browser event.\n");
235 avahi_client_set_errno(db->client, avahi_error_dbus_to_number(etxt));
240 db->callback(db, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, domain, (AvahiLookupResultFlags) flags, db->userdata);
242 return DBUS_HANDLER_RESULT_HANDLED;
245 dbus_error_free (&error);
246 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
249 /* AvahiServiceTypeBrowser */
250 AvahiServiceTypeBrowser* avahi_service_type_browser_new(
252 AvahiIfIndex interface,
253 AvahiProtocol protocol,
255 AvahiLookupFlags flags,
256 AvahiServiceTypeBrowserCallback callback,
259 AvahiServiceTypeBrowser *b = NULL;
260 DBusMessage *message = NULL, *reply = NULL;
263 int32_t i_interface, i_protocol;
269 dbus_error_init(&error);
271 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
272 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
279 if (!(b = avahi_new(AvahiServiceTypeBrowser, 1))) {
280 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
285 b->callback = callback;
286 b->userdata = userdata;
289 b->interface = interface;
290 b->protocol = protocol;
292 AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, service_type_browsers, client->service_type_browsers, b);
295 if (!(b->domain = avahi_strdup(domain))) {
296 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
300 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew"))) {
301 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
305 i_interface = (int32_t) interface;
306 i_protocol = (int32_t) protocol;
307 u_flags = (uint32_t) flags;
309 if (!dbus_message_append_args(
311 DBUS_TYPE_INT32, &i_interface,
312 DBUS_TYPE_INT32, &i_protocol,
313 DBUS_TYPE_STRING, &domain,
314 DBUS_TYPE_UINT32, &u_flags,
315 DBUS_TYPE_INVALID)) {
316 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
320 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
321 dbus_error_is_set(&error)) {
322 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
326 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
327 dbus_error_is_set(&error) ||
329 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
333 if (!(b->path = avahi_strdup(path))) {
335 /* FIXME: We don't remove the object on the server side */
337 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
341 dbus_message_unref(message);
342 dbus_message_unref(reply);
348 if (dbus_error_is_set(&error)) {
349 avahi_client_set_dbus_error(client, &error);
350 dbus_error_free(&error);
354 avahi_service_type_browser_free(b);
357 dbus_message_unref(message);
360 dbus_message_unref(reply);
365 AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *b) {
370 int avahi_service_type_browser_free (AvahiServiceTypeBrowser *b) {
377 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
378 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free");
380 AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b);
383 avahi_free(b->domain);
388 DBusHandlerResult avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
389 AvahiServiceTypeBrowser *b = NULL;
392 char *domain, *type = NULL;
393 int32_t interface, protocol;
399 dbus_error_init (&error);
401 if (!(path = dbus_message_get_path(message)))
404 for (b = client->service_type_browsers; b; b = b->service_type_browsers_next)
405 if (strcmp (b->path, path) == 0)
412 interface = b->interface;
413 protocol = b->protocol;
416 case AVAHI_BROWSER_NEW:
417 case AVAHI_BROWSER_REMOVE:
418 if (!dbus_message_get_args(
420 DBUS_TYPE_INT32, &interface,
421 DBUS_TYPE_INT32, &protocol,
422 DBUS_TYPE_STRING, &type,
423 DBUS_TYPE_STRING, &domain,
424 DBUS_TYPE_UINT32, &flags,
425 DBUS_TYPE_INVALID) ||
426 dbus_error_is_set(&error)) {
427 fprintf(stderr, "Failed to parse browser event.\n");
432 case AVAHI_BROWSER_CACHE_EXHAUSTED:
433 case AVAHI_BROWSER_ALL_FOR_NOW:
436 case AVAHI_BROWSER_FAILURE: {
439 if (!dbus_message_get_args(
441 DBUS_TYPE_STRING, &etxt,
442 DBUS_TYPE_INVALID) ||
443 dbus_error_is_set (&error)) {
444 fprintf(stderr, "Failed to parse browser event.\n");
448 avahi_client_set_errno(b->client, avahi_error_dbus_to_number(etxt));
453 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
455 return DBUS_HANDLER_RESULT_HANDLED;
458 dbus_error_free (&error);
459 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
462 /* AvahiServiceBrowser */
464 AvahiServiceBrowser* avahi_service_browser_new(
466 AvahiIfIndex interface,
467 AvahiProtocol protocol,
470 AvahiLookupFlags flags,
471 AvahiServiceBrowserCallback callback,
474 AvahiServiceBrowser *b = NULL;
475 DBusMessage *message = NULL, *reply = NULL;
478 int32_t i_protocol, i_interface;
485 dbus_error_init(&error);
487 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
488 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
495 if (!(b = avahi_new(AvahiServiceBrowser, 1))) {
496 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
501 b->callback = callback;
502 b->userdata = userdata;
504 b->type = b->domain = NULL;
505 b->interface = interface;
506 b->protocol = protocol;
508 AVAHI_LLIST_PREPEND(AvahiServiceBrowser, service_browsers, client->service_browsers, b);
510 if (!(b->type = avahi_strdup(type))) {
511 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
515 if (domain && domain[0])
516 if (!(b->domain = avahi_strdup(domain))) {
517 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
521 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew"))) {
522 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
526 i_interface = (int32_t) interface;
527 i_protocol = (int32_t) protocol;
528 u_flags = (uint32_t) flags;
530 if (!dbus_message_append_args(
532 DBUS_TYPE_INT32, &i_interface,
533 DBUS_TYPE_INT32, &i_protocol,
534 DBUS_TYPE_STRING, &type,
535 DBUS_TYPE_STRING, &domain,
536 DBUS_TYPE_UINT32, &u_flags,
537 DBUS_TYPE_INVALID)) {
538 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
542 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
543 dbus_error_is_set(&error)) {
544 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
548 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
549 dbus_error_is_set(&error) ||
551 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
555 if (!(b->path = avahi_strdup(path))) {
557 /* FIXME: We don't remove the object on the server side */
559 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
563 dbus_message_unref(message);
564 dbus_message_unref(reply);
569 if (dbus_error_is_set(&error)) {
570 avahi_client_set_dbus_error(client, &error);
571 dbus_error_free(&error);
575 avahi_service_browser_free(b);
578 dbus_message_unref(message);
581 dbus_message_unref(reply);
586 AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *b) {
591 int avahi_service_browser_free (AvahiServiceBrowser *b) {
598 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
599 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free");
601 AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b);
605 avahi_free(b->domain);
610 DBusHandlerResult avahi_service_browser_event(AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
611 AvahiServiceBrowser *b = NULL;
614 char *name = NULL, *type, *domain;
615 int32_t interface, protocol;
618 dbus_error_init (&error);
620 if (!(path = dbus_message_get_path(message)))
623 for (b = client->service_browsers; b; b = b->service_browsers_next)
624 if (strcmp (b->path, path) == 0)
632 interface = b->interface;
633 protocol = b->protocol;
636 case AVAHI_BROWSER_NEW:
637 case AVAHI_BROWSER_REMOVE:
639 if (!dbus_message_get_args (
641 DBUS_TYPE_INT32, &interface,
642 DBUS_TYPE_INT32, &protocol,
643 DBUS_TYPE_STRING, &name,
644 DBUS_TYPE_STRING, &type,
645 DBUS_TYPE_STRING, &domain,
646 DBUS_TYPE_UINT32, &flags,
647 DBUS_TYPE_INVALID) ||
648 dbus_error_is_set(&error)) {
649 fprintf(stderr, "Failed to parse browser event.\n");
654 case AVAHI_BROWSER_CACHE_EXHAUSTED:
655 case AVAHI_BROWSER_ALL_FOR_NOW:
658 case AVAHI_BROWSER_FAILURE: {
661 if (!dbus_message_get_args(
663 DBUS_TYPE_STRING, &etxt,
664 DBUS_TYPE_INVALID) ||
665 dbus_error_is_set (&error)) {
666 fprintf(stderr, "Failed to parse browser event.\n");
670 avahi_client_set_errno(b->client, avahi_error_dbus_to_number(etxt));
675 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, name, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
677 return DBUS_HANDLER_RESULT_HANDLED;
680 dbus_error_free (&error);
681 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;