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)
197 if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) {
198 if (!dbus_message_get_args(
200 DBUS_TYPE_INT32, &interface,
201 DBUS_TYPE_INT32, &protocol,
202 DBUS_TYPE_STRING, &domain,
203 DBUS_TYPE_UINT32, &flags,
204 DBUS_TYPE_INVALID) ||
205 dbus_error_is_set (&error)) {
206 fprintf(stderr, "Failed to parse browser event.\n");
211 db->callback(db, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, domain, (AvahiLookupResultFlags) flags, db->userdata);
213 return DBUS_HANDLER_RESULT_HANDLED;
216 dbus_error_free (&error);
217 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
220 /* AvahiServiceTypeBrowser */
221 AvahiServiceTypeBrowser* avahi_service_type_browser_new(
223 AvahiIfIndex interface,
224 AvahiProtocol protocol,
226 AvahiLookupFlags flags,
227 AvahiServiceTypeBrowserCallback callback,
230 AvahiServiceTypeBrowser *b = NULL;
231 DBusMessage *message = NULL, *reply = NULL;
234 int32_t i_interface, i_protocol;
240 dbus_error_init(&error);
242 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
243 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
250 if (!(b = avahi_new(AvahiServiceTypeBrowser, 1))) {
251 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
256 b->callback = callback;
257 b->userdata = userdata;
260 AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, service_type_browsers, client->service_type_browsers, b);
262 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew"))) {
263 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
267 i_interface = (int32_t) interface;
268 i_protocol = (int32_t) protocol;
269 u_flags = (uint32_t) flags;
271 if (!dbus_message_append_args(
273 DBUS_TYPE_INT32, &i_interface,
274 DBUS_TYPE_INT32, &i_protocol,
275 DBUS_TYPE_STRING, &domain,
276 DBUS_TYPE_UINT32, &u_flags,
277 DBUS_TYPE_INVALID)) {
278 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
282 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
283 dbus_error_is_set(&error)) {
284 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
288 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
289 dbus_error_is_set(&error) ||
291 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
295 if (!(b->path = avahi_strdup(path))) {
297 /* FIXME: We don't remove the object on the server side */
299 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
303 dbus_message_unref(message);
304 dbus_message_unref(reply);
310 if (dbus_error_is_set(&error)) {
311 avahi_client_set_dbus_error(client, &error);
312 dbus_error_free(&error);
316 avahi_service_type_browser_free(b);
319 dbus_message_unref(message);
322 dbus_message_unref(reply);
327 AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *b)
333 int avahi_service_type_browser_free (AvahiServiceTypeBrowser *b) {
340 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
341 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free");
343 AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b);
350 DBusHandlerResult avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
351 AvahiServiceTypeBrowser *b = NULL;
354 char *domain = NULL, *type = NULL;
355 int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
361 dbus_error_init (&error);
363 if (!(path = dbus_message_get_path(message)))
366 for (b = client->service_type_browsers; b; b = b->service_type_browsers_next)
367 if (strcmp (b->path, path) == 0)
373 if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) {
374 if (!dbus_message_get_args(
376 DBUS_TYPE_INT32, &interface,
377 DBUS_TYPE_INT32, &protocol,
378 DBUS_TYPE_STRING, &type,
379 DBUS_TYPE_STRING, &domain,
380 DBUS_TYPE_UINT32, &flags,
381 DBUS_TYPE_INVALID) ||
382 dbus_error_is_set(&error)) {
383 fprintf(stderr, "Failed to parse browser event.\n");
388 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
390 return DBUS_HANDLER_RESULT_HANDLED;
393 dbus_error_free (&error);
394 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
397 /* AvahiServiceBrowser */
399 AvahiServiceBrowser* avahi_service_browser_new(
401 AvahiIfIndex interface,
402 AvahiProtocol protocol,
405 AvahiLookupFlags flags,
406 AvahiServiceBrowserCallback callback,
409 AvahiServiceBrowser *b = NULL;
410 DBusMessage *message = NULL, *reply = NULL;
413 int32_t i_protocol, i_interface;
420 dbus_error_init(&error);
422 if (client->state == AVAHI_CLIENT_DISCONNECTED) {
423 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
430 if (!(b = avahi_new(AvahiServiceBrowser, 1))) {
431 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
436 b->callback = callback;
437 b->userdata = userdata;
440 AVAHI_LLIST_PREPEND(AvahiServiceBrowser, service_browsers, client->service_browsers, b);
442 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew"))) {
443 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
447 i_interface = (int32_t) interface;
448 i_protocol = (int32_t) protocol;
449 u_flags = (uint32_t) flags;
451 if (!dbus_message_append_args(
453 DBUS_TYPE_INT32, &i_interface,
454 DBUS_TYPE_INT32, &i_protocol,
455 DBUS_TYPE_STRING, &type,
456 DBUS_TYPE_STRING, &domain,
457 DBUS_TYPE_UINT32, &u_flags,
458 DBUS_TYPE_INVALID)) {
459 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
463 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
464 dbus_error_is_set(&error)) {
465 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
469 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
470 dbus_error_is_set(&error) ||
472 avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
476 if (!(b->path = avahi_strdup(path))) {
478 /* FIXME: We don't remove the object on the server side */
480 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
484 dbus_message_unref(message);
485 dbus_message_unref(reply);
490 if (dbus_error_is_set(&error)) {
491 avahi_client_set_dbus_error(client, &error);
492 dbus_error_free(&error);
496 avahi_service_browser_free(b);
499 dbus_message_unref(message);
502 dbus_message_unref(reply);
507 AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *b)
513 int avahi_service_browser_free (AvahiServiceBrowser *b) {
520 if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED)
521 r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free");
523 AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b);
531 DBusHandlerResult avahi_service_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
532 AvahiServiceBrowser *b = NULL;
535 char *name = NULL, *type = NULL, *domain = NULL;
536 int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
539 dbus_error_init (&error);
541 if (!(path = dbus_message_get_path(message)))
544 for (b = client->service_browsers; b; b = b->service_browsers_next)
545 if (strcmp (b->path, path) == 0)
551 if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) {
552 if (!dbus_message_get_args (
554 DBUS_TYPE_INT32, &interface,
555 DBUS_TYPE_INT32, &protocol,
556 DBUS_TYPE_STRING, &name,
557 DBUS_TYPE_STRING, &type,
558 DBUS_TYPE_STRING, &domain,
559 DBUS_TYPE_UINT32, &flags,
560 DBUS_TYPE_INVALID) ||
561 dbus_error_is_set(&error)) {
562 fprintf(stderr, "Failed to parse browser event.\n");
567 b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, name, type, domain, (AvahiLookupResultFlags) flags, b->userdata);
569 return DBUS_HANDLER_RESULT_HANDLED;
572 dbus_error_free (&error);
573 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;