2 * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include "vine-constants.h"
23 #include "vine-service.h"
24 #include "vine-disc.h"
25 #include "vine-disc-plugin.h"
27 #include "vine-utils.h"
32 } __vine_disc_plugins_info[] = {
33 [VINE_DISCOVERY_METHOD_DNS_SD] = {"DNS-SD", DNS_SD_PLUGIN_PATH},
35 [VINE_DISCOVERY_METHOD_BLE] = {"BLE", BLE_PLUGIN_PATH},
38 [VINE_DISCOVERY_METHOD_NAN] = {"NAN", NAN_PLUGIN_PATH},
44 vine_disc_plugin_fn fn;
45 vine_disc_plugin_callbacks callbacks;
46 vine_disc_error (*init)(vine_disc_plugin_fn *fn);
47 } __vine_disc_plugins[] = {
48 {{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
49 {NULL, NULL, NULL, NULL, NULL}, NULL},
50 {{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
51 {NULL, NULL, NULL, NULL, NULL}, NULL},
52 {{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
53 {NULL, NULL, NULL, NULL, NULL}, NULL},
54 {{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
55 {NULL, NULL, NULL, NULL, NULL}, NULL},
59 vine_discovery_method_e method;
60 vine_disc_plugin_fn *plugin_fn;
62 vine_disc_published_cb published_cb;
63 void *published_cb_data;
64 vine_disc_discovered_cb discovered_cb;
65 void *discovered_cb_data;
66 vine_disc_ip_resolved_cb ip_resolved_cb;
67 void *ip_resolved_cb_data;
68 vine_service_h service; // Used only for vine_disc_resolve_ip
70 void *plugin_handle; // Handle to be used in each plugin
71 vine_event_queue_h event_queue;
75 char service_name[VINE_MAX_SERVICE_NAME_LEN + 1];
76 vine_disc_error error;
77 } vine_published_event;
81 char service_type[VINE_MAX_SERVICE_TYPE_LEN + 1];
82 char service_name[VINE_MAX_SERVICE_NAME_LEN + 1];
83 char host_name[VINE_MAX_HOST_NAME_LEN + 1];
85 map<string, string> attributes;
86 char iface_name[IF_NAMESIZE + 1];
88 char mac[VINE_MAC_LEN + 1];
89 } vine_discovered_event;
93 vine_address_family_e address_family;
94 char ip[VINE_MAX_IP_LEN + 1];
95 vine_service_h service;
96 } vine_ip_resolved_event;
98 vine_error_e __convert_disc_error_to_vine_error(vine_disc_error error)
101 case VINE_DISC_ERROR_NONE:
102 return VINE_ERROR_NONE;
103 case VINE_DISC_ERROR_OUT_OF_MEMORY:
104 return VINE_ERROR_OUT_OF_MEMORY;
105 case VINE_DISC_ERROR_NAME_CONFLICT: // DNS-SD changed the service name
106 return VINE_ERROR_NAME_CONFLICT;
107 // TODO: To be determined if which vine error will be returned
108 case VINE_DISC_ERROR_SERVICE_DEREGISTERED:
109 return VINE_ERROR_SERVICE_DEREGISTERED;
110 case VINE_DISC_ERROR_NOT_SUPPORTED:
111 return VINE_ERROR_NOT_SUPPORTED;
112 case VINE_DISC_ERROR_SERVICE_NOT_RUNNING:
114 return VINE_ERROR_OPERATION_FAILED;
118 static void __invoke_published_user_cb(void *event, void *user_data)
120 VINE_LOGD("event[%p] user_data[%p]", event, user_data);
121 vine_published_event *pub_event = (vine_published_event *)event;
122 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
123 RET_IF(disc_handle == NULL, "Disc handle is NULL");
125 VINE_LOGD("Call session callback for published event");
126 if (disc_handle->published_cb)
127 disc_handle->published_cb(disc_handle,
128 pub_event->service_name,
129 __convert_disc_error_to_vine_error(pub_event->error),
130 disc_handle->published_cb_data);
133 static void __invoke_discovered_user_cb(void *event, void *user_data)
135 VINE_LOGD("event[%p] user_data[%p]", event, user_data);
136 vine_discovered_event *discovered_event = (vine_discovered_event *)event;
137 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
138 RET_IF(disc_handle == NULL, "Disc handle is NULL");
139 RET_IF(event == NULL, "Discovered event is NULL");
141 VINE_LOGD("Call session callback for discovered event");
143 if (disc_handle->discovered_cb)
144 disc_handle->discovered_cb(disc_handle,
145 discovered_event->available,
146 discovered_event->service_type,
147 discovered_event->service_name,
148 discovered_event->host_name,
149 discovered_event->mac,
150 discovered_event->port,
151 discovered_event->attributes,
152 discovered_event->iface_name,
153 discovered_event->more_coming,
154 disc_handle->discovered_cb_data);
157 static void __invoke_ip_resolved_user_cb(void *event, void *user_data)
159 VINE_LOGD("event[%p] user_data[%p]", event, user_data);
160 vine_ip_resolved_event *resolved_event = (vine_ip_resolved_event *)event;
161 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
162 RET_IF(disc_handle == NULL, "Disc handle is NULL");
163 RET_IF(event == NULL, "Discovered event is NULL");
165 VINE_LOGD("Call session callback for ip resolved event");
167 if (disc_handle->ip_resolved_cb)
168 disc_handle->ip_resolved_cb(disc_handle,
169 disc_handle->service,
172 resolved_event->address_family,
173 disc_handle->ip_resolved_cb_data);
176 static void __free_pub_event(void *data)
178 VINE_LOGD("Free pub_event[%p]", data);
182 static void __free_discovered_event(void *data)
184 VINE_LOGD("Free discovered_event[%p]", data);
185 vine_discovered_event *discovered_event = (vine_discovered_event *)data;
187 discovered_event->attributes.clear();
188 delete discovered_event;
191 static void __free_ip_resolved_event(void *data)
193 VINE_LOGD("Free ip_resolved_event[%p]", data);
194 delete (vine_ip_resolved_event *)data;
197 static void __published_cb(void *plugin_handle,
198 const char *service_name, vine_disc_error error, void *user_data)
200 VINE_LOGD("Published callback from plugin");
201 VINE_LOGD("service_name[%s] error [%d] user_data[%p]",
202 service_name, error, user_data);
204 vine_published_event *pub_event =
205 (vine_published_event *)calloc(1, sizeof(vine_published_event));
206 RET_IF(pub_event == NULL, "Out of memory");
207 strncpy(pub_event->service_name, service_name, VINE_MAX_SERVICE_NAME_LEN);
208 pub_event->error = error;
210 VINE_LOGD("Create a pub_event[%p]", pub_event);
212 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
214 vine_event_loop_add_event(disc_handle->event_queue, pub_event,
215 __invoke_published_user_cb, __free_pub_event, user_data);
218 static void __discovered_cb(void *plugin_handle, bool available,
219 const char *service_type, const char *service_name,
220 const char *host_name, const char *mac, int port, const map<string, string> &attr,
221 const char *iface_name, int more_coming, void *user_data)
223 RET_IF(service_type == NULL, "service type is NULL");
224 RET_IF(service_name == NULL, "service_name type is NULL");
226 VINE_LOGD("Discovered callback from plugin available[%d]", available);
227 VINE_LOGD("service type[%s] service_name[%s] host_name[%s] mac[%s] port[%d] iface[%s] user_data[%p]",
228 service_type, service_name, host_name, mac, port, iface_name, user_data);
230 vine_discovered_event *discovered_event = new vine_discovered_event;
232 discovered_event->available = available;
233 strncpy(discovered_event->service_type, service_type, VINE_MAX_SERVICE_TYPE_LEN);
234 discovered_event->service_type[VINE_MAX_SERVICE_TYPE_LEN] = 0;
235 strncpy(discovered_event->service_name, service_name, VINE_MAX_SERVICE_NAME_LEN);
236 discovered_event->service_type[VINE_MAX_SERVICE_NAME_LEN] = 0;
237 strncpy(discovered_event->iface_name, iface_name, IF_NAMESIZE);
238 discovered_event->iface_name[IF_NAMESIZE] = 0;
239 if (host_name != NULL) {
240 strncpy(discovered_event->host_name, host_name, VINE_MAX_HOST_NAME_LEN);
241 discovered_event->host_name[VINE_MAX_HOST_NAME_LEN] = 0;
244 memset(discovered_event->host_name, 0, VINE_MAX_HOST_NAME_LEN + 1);
247 strncpy(discovered_event->mac, mac, VINE_MAC_LEN);
248 discovered_event->mac[VINE_MAC_LEN] = 0;
251 memset(discovered_event->mac, 0, VINE_MAC_LEN + 1);
254 discovered_event->port = port;
255 discovered_event->attributes = attr;
256 discovered_event->more_coming = more_coming;
258 VINE_LOGD("Create a discovered_event[%p]", discovered_event);
260 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
262 if (vine_event_loop_add_event(disc_handle->event_queue, discovered_event,
263 __invoke_discovered_user_cb, __free_discovered_event, user_data) == VINE_ERROR_NONE)
266 __free_discovered_event(discovered_event);
269 static void __ip_resolved_cb(void *plugin_handle, bool add,
270 const char *ip, sa_family_t address_family, void *user_data)
272 VINE_LOGD("IP resolved callback from plugin Add[%d]", add);
273 VINE_LOGD("IP[%s] address family[%d] user_data[%p]",
274 ip, address_family, user_data);
276 vine_ip_resolved_event *resolved_event = new vine_ip_resolved_event;
278 resolved_event->add = add;
279 if (address_family == AF_INET)
280 resolved_event->address_family = VINE_ADDRESS_FAMILY_IPV4;
281 else if (address_family == AF_INET6)
282 resolved_event->address_family = VINE_ADDRESS_FAMILY_IPV6;
284 VINE_LOGE("Invalid address family %d", address_family);
286 strncpy(resolved_event->ip, ip, VINE_MAX_IP_LEN);
288 VINE_LOGD("Create a IP resolved event[%p]", resolved_event);
290 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
292 vine_event_loop_add_event(disc_handle->event_queue, resolved_event,
293 __invoke_ip_resolved_user_cb, __free_ip_resolved_event,
297 void __vine_disc_epoll_handler(int fd, int events, void *user_data)
299 VINE_LOGD("Process event for fd[%d] events[%d] disc_handle[%p]", fd, events, user_data);
300 vine_disc_s *disc_handle = (vine_disc_s *)user_data;
301 if (!disc_handle || !disc_handle->plugin_fn || disc_handle->plugin_fn->process_event == NULL) {
302 VINE_LOGE("No process_event() defined");
305 vine_disc_error err = disc_handle->plugin_fn->process_event(disc_handle->plugin_handle, fd);
306 if (err != VINE_DISC_ERROR_NONE) {
307 VINE_LOGE("Fail to process event %d", err);
308 vine_event_loop_del_io_handler(fd);
312 void __fd_added_cb(int fd, void *user_data)
314 RET_IF(fd < 0, "Invalid fd");
315 vine_disc_h disc = (vine_disc_h)user_data;
316 VINE_LOGD("New fd to be listened");
317 VINE_LOGD("Add epoll handler for fd[%d]. vine_disc_h[%p]", fd, disc);
319 vine_event_loop_add_io_handler(fd, VINE_POLLIN | VINE_POLLHUP,
320 __vine_disc_epoll_handler, disc);
323 void __fd_removed_cb(int fd, void *user_data)
325 VINE_LOGD("fd[%d] will be removed. vine_disc_h[%p]", fd, user_data);
326 RET_IF(fd < 0, "Invalid fd");
327 vine_event_loop_del_io_handler(fd);
330 static int __load_disc_plugins()
332 for (int i = 0; __vine_disc_plugins_info[i].path; ++i) {
333 void *handle = dlopen(__vine_disc_plugins_info[i].path, RTLD_LAZY | RTLD_NODELETE);
335 __vine_disc_plugins[i].init =
336 (vine_disc_error (*)(vine_disc_plugin_fn *))
337 dlsym(handle, "vine_disc_plugin_init");
339 VINE_LOGI("Loaded %s", __vine_disc_plugins_info[i].path);
341 VINE_LOGE("%s doesn't exist", __vine_disc_plugins_info[i].path);
342 if (i == VINE_DISCOVERY_METHOD_DNS_SD) {
343 VINE_LOGE("%s is a default plugins. It should be loaded.",
344 __vine_disc_plugins_info[i].name);
345 return VINE_ERROR_OPERATION_FAILED;
350 return VINE_ERROR_NONE;
353 static void __init_plugins()
355 for (int i = 0; __vine_disc_plugins[i].init; ++i) {
356 __vine_disc_plugins[i].init(&__vine_disc_plugins[i].fn);
357 __vine_disc_plugins[i].callbacks.published_cb = __published_cb;
358 __vine_disc_plugins[i].callbacks.discovered_cb = __discovered_cb;
359 __vine_disc_plugins[i].callbacks.ip_resolved_cb = __ip_resolved_cb;
360 __vine_disc_plugins[i].callbacks.fd_added_cb = __fd_added_cb;
361 __vine_disc_plugins[i].callbacks.fd_removed_cb = __fd_removed_cb;
362 __vine_disc_plugins[i].fn.register_callbacks(__vine_disc_plugins[i].callbacks);
368 int ret = __load_disc_plugins();
369 RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to load plugins");
373 return VINE_ERROR_NONE;
376 void vine_disc_deinit()
380 int vine_disc_create(vine_discovery_method_e disc_method, vine_disc_h *disc)
382 RET_VAL_IF(!vine_disc_is_plugin_loaded(disc_method), VINE_ERROR_OPERATION_FAILED,
383 "Plugin is not loaded");
385 vine_disc_s *disc_handle = (vine_disc_s *)calloc(1, sizeof(vine_disc_s));
386 RET_VAL_IF(disc_handle == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of Memory");
389 disc_handle->method = disc_method;
390 disc_handle->plugin_fn = &__vine_disc_plugins[disc_method].fn;
391 VINE_LOGD("New Discovery handle[%p] disc_method[%d]", disc_handle, disc_method);
393 return VINE_ERROR_NONE;
396 void vine_disc_destroy(vine_disc_h disc)
398 vine_disc_s *disc_handle = (vine_disc_s *)disc;
399 if (disc_handle && disc_handle->plugin_fn &&
400 disc_handle->plugin_fn->deinit && disc_handle->plugin_handle)
401 disc_handle->plugin_fn->deinit(disc_handle->plugin_handle);
405 static void __vine_disc_set_published_cb(vine_disc_h disc,
406 vine_disc_published_cb cb, void *user_data)
408 vine_disc_s *disc_handle = (vine_disc_s *)disc;
409 disc_handle->published_cb = cb;
410 disc_handle->published_cb_data = user_data;
413 static void __vine_disc_set_discovered_cb(vine_disc_h disc,
414 vine_disc_discovered_cb cb, void *user_data)
416 vine_disc_s *disc_handle = (vine_disc_s *)disc;
417 disc_handle->discovered_cb = cb;
418 disc_handle->discovered_cb_data = user_data;
421 static void __vine_disc_set_ip_resolved_cb(vine_disc_h disc,
422 vine_disc_ip_resolved_cb cb, void *user_data)
424 vine_disc_s *disc_handle = (vine_disc_s *)disc;
425 disc_handle->ip_resolved_cb = cb;
426 disc_handle->ip_resolved_cb_data = user_data;
429 vine_error_e __vine_disc_plugin_publish(vine_disc_h disc, vine_service_h service,
430 const char *iface_name)
432 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
434 VINE_LOGD("service[%p], disc handle[%p]", service, disc);
435 vine_disc_s *disc_handle = (vine_disc_s *)disc;
436 void *plugin_handle = NULL;
438 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
439 if (disc_handle->plugin_fn->init == NULL) {
440 VINE_LOGE("No init() defined");
441 return VINE_ERROR_OPERATION_FAILED;
444 vine_disc_error error = disc_handle->plugin_fn->init(&plugin_handle, disc);
445 RET_VAL_IF(error != VINE_DISC_ERROR_NONE,
446 __convert_disc_error_to_vine_error(error),
447 "Fail to init %d", error);
449 disc_handle->plugin_handle = plugin_handle;
450 VINE_LOGD("plugin handle[%p]", plugin_handle);
452 if (disc_handle->plugin_fn->publish == NULL) {
453 VINE_LOGE("No publish() defined");
454 disc_handle->plugin_fn->deinit(plugin_handle);
455 disc_handle->plugin_handle = NULL;
456 return VINE_ERROR_OPERATION_FAILED;
459 error = disc_handle->plugin_fn->publish(plugin_handle,
460 _vine_service_get_type(service), _vine_service_get_name(service),
461 _vine_service_get_port(service), _vine_service_get_attributes(service),
463 if (error != VINE_DISC_ERROR_NONE) {
464 VINE_LOGE("Fail to publish %d", error);
465 disc_handle->plugin_fn->deinit(plugin_handle);
466 disc_handle->plugin_handle = NULL;
467 return __convert_disc_error_to_vine_error(error);
470 return VINE_ERROR_NONE;
473 int vine_disc_publish(vine_disc_h disc,
474 vine_service_h service, const char *iface_name,
475 vine_disc_published_cb cb, void *user_data,
476 vine_event_queue_h event_queue)
478 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
479 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
481 VINE_LOGD("Publishevent_queue[%p]", event_queue);
482 VINE_LOGD("service[%p] disc[%p]", service, disc);
483 __vine_disc_set_published_cb(disc, cb, user_data);
485 vine_disc_s *disc_handle = (vine_disc_s *)disc;
486 disc_handle->event_queue = event_queue;
488 int ret = __vine_disc_plugin_publish(disc, service, iface_name);
489 if (ret != VINE_ERROR_NONE) {
490 VINE_LOGE("Fail to publish the service %d", ret);
494 return VINE_ERROR_NONE;
497 vine_error_e __vine_disc_plugin_stop_publish(vine_disc_h disc)
499 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
501 vine_disc_error error = VINE_DISC_ERROR_NONE;
502 vine_disc_s *disc_handle = (vine_disc_s *)disc;
504 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
505 if (disc_handle->plugin_fn->init == NULL) {
506 VINE_LOGE("No init() defined");
507 return VINE_ERROR_OPERATION_FAILED;
510 if (disc_handle->plugin_fn->stop_publish == NULL) {
511 VINE_LOGE("No stop_publish() defined");
512 return VINE_ERROR_OPERATION_FAILED;
515 error = disc_handle->plugin_fn->stop_publish(disc_handle->plugin_handle);
516 if (error != VINE_DISC_ERROR_NONE) {
517 VINE_LOGE("Fail to stop publish %d", error);
518 return __convert_disc_error_to_vine_error(error);
521 return VINE_ERROR_NONE;
524 int vine_disc_stop_publish(vine_disc_h disc)
526 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
528 int ret = __vine_disc_plugin_stop_publish(disc);
529 if (ret != VINE_ERROR_NONE) {
530 VINE_LOGE("Fail to stop publish %d", ret);
534 return VINE_ERROR_NONE;
537 vine_error_e __vine_disc_plugin_subscribe(vine_disc_h disc,
538 const char *service_type, const char *iface_name)
540 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
542 VINE_LOGD("service_type[%s], disc handle[%p]", service_type, disc);
543 vine_disc_s *disc_handle = (vine_disc_s *)disc;
544 void *plugin_handle = NULL;
546 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
547 if (disc_handle->plugin_fn->init == NULL) {
548 VINE_LOGE("No init() defined");
549 return VINE_ERROR_OPERATION_FAILED;
551 vine_disc_error error = disc_handle->plugin_fn->init(&plugin_handle, disc);
552 RET_VAL_IF(error != VINE_DISC_ERROR_NONE,
553 __convert_disc_error_to_vine_error(error),
554 "Fail to init %d", error);
556 disc_handle->plugin_handle = plugin_handle;
557 VINE_LOGD("plugin handle[%p]", plugin_handle);
559 if (disc_handle->plugin_fn->subscribe == NULL) {
560 VINE_LOGE("No subscribe() defined");
561 disc_handle->plugin_fn->deinit(plugin_handle);
562 disc_handle->plugin_handle = NULL;
563 return VINE_ERROR_OPERATION_FAILED;
565 error = disc_handle->plugin_fn->subscribe(plugin_handle, service_type, iface_name);
566 if (error != VINE_DISC_ERROR_NONE) {
567 VINE_LOGE("Fail to subscribe %d", error);
568 disc_handle->plugin_fn->deinit(plugin_handle);
569 disc_handle->plugin_handle = NULL;
570 return __convert_disc_error_to_vine_error(error);
573 return VINE_ERROR_NONE;
576 int vine_disc_subscribe(vine_disc_h disc,
577 const char *service_type, const char *iface_name,
578 vine_disc_discovered_cb cb, void *user_data,
579 vine_event_queue_h event_queue)
581 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
583 VINE_LOGD("Subscribe event_queue[%p]", event_queue);
584 VINE_LOGD("service_type[%s] disc[%p]", service_type, disc);
586 __vine_disc_set_discovered_cb(disc, cb, user_data);
588 vine_disc_s *disc_handle = (vine_disc_s *)disc;
589 disc_handle->event_queue = event_queue;
591 int ret = __vine_disc_plugin_subscribe(disc, service_type, iface_name);
592 if (ret != VINE_ERROR_NONE) {
593 VINE_LOGE("Fail to subscribe the service %d", ret);
597 return VINE_ERROR_NONE;
600 vine_error_e __vine_disc_plugin_stop_subscribe(vine_disc_h disc)
602 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
604 vine_disc_error error = VINE_DISC_ERROR_NONE;
605 vine_disc_s *disc_handle = (vine_disc_s *)disc;
607 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
608 if (disc_handle->plugin_fn->init == NULL) {
609 VINE_LOGE("No init() defined");
610 return VINE_ERROR_OPERATION_FAILED;
613 if (disc_handle->plugin_fn->stop_subscribe == NULL) {
614 VINE_LOGE("No stop_subscribe() defined");
615 return VINE_ERROR_OPERATION_FAILED;
618 error = disc_handle->plugin_fn->stop_subscribe(disc_handle->plugin_handle);
619 if (error != VINE_DISC_ERROR_NONE) {
620 VINE_LOGE("Fail to stop publish %d", error);
621 return __convert_disc_error_to_vine_error(error);
624 return VINE_ERROR_NONE;
627 int vine_disc_stop_subscribe(vine_disc_h disc)
629 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
631 int ret = __vine_disc_plugin_stop_subscribe(disc);
632 if (ret != VINE_ERROR_NONE) {
633 VINE_LOGE("Fail to stop subscribe %d", ret);
637 return VINE_ERROR_NONE;
640 vine_error_e __vine_disc_plugin_resolve_ip(vine_disc_h disc, vine_service_h service)
642 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
644 VINE_LOGD("service[%p], disc handle[%p]", service, disc);
645 vine_disc_s *disc_handle = (vine_disc_s *)disc;
646 void *plugin_handle = NULL;
648 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
649 if (disc_handle->plugin_fn->init == NULL) {
650 VINE_LOGE("No init() defined");
651 return VINE_ERROR_OPERATION_FAILED;
653 vine_disc_error error = disc_handle->plugin_fn->init(&plugin_handle, disc);
654 RET_VAL_IF(error != VINE_DISC_ERROR_NONE,
655 __convert_disc_error_to_vine_error(error),
656 "Fail to init %d", error);
658 disc_handle->plugin_handle = plugin_handle;
659 VINE_LOGD("plugin handle[%p]", plugin_handle);
661 if (disc_handle->plugin_fn->resolve_ip == NULL) {
662 VINE_LOGE("No resolve_ip() defined");
663 disc_handle->plugin_fn->deinit(plugin_handle);
664 disc_handle->plugin_handle = NULL;
665 return VINE_ERROR_OPERATION_FAILED;
667 error = disc_handle->plugin_fn->resolve_ip(plugin_handle,
668 _vine_service_get_type(service), _vine_service_get_name(service),
669 _vine_service_get_host_name(service), nullptr, _vine_service_get_iface_name(service),
670 (int)_vine_service_get_address_family(service));
671 if (error != VINE_DISC_ERROR_NONE) {
672 VINE_LOGE("Fail to resolve ip %d", error);
673 disc_handle->plugin_fn->deinit(plugin_handle);
674 disc_handle->plugin_handle = NULL;
675 return __convert_disc_error_to_vine_error(error);
678 return VINE_ERROR_NONE;
681 int vine_disc_resolve_ip(vine_disc_h disc,
682 vine_service_h service,
683 vine_disc_ip_resolved_cb cb, void *user_data,
684 vine_event_queue_h event_queue)
686 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
687 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
689 VINE_LOGD("Resolve IP for a service[%p] event_queue[%p]", service, event_queue);
691 __vine_disc_set_ip_resolved_cb(disc, cb, user_data);
693 vine_disc_s *disc_handle = (vine_disc_s *)disc;
694 disc_handle->event_queue = event_queue;
695 disc_handle->service = service;
697 int ret = __vine_disc_plugin_resolve_ip(disc, service);
698 if (ret != VINE_ERROR_NONE) {
699 VINE_LOGE("Fail to subscribe the service %d", ret);
703 return VINE_ERROR_NONE;
706 vine_error_e __vine_disc_plugin_cancel_resolve_ip(vine_disc_h disc, vine_service_h service)
708 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_OPERATION, "disc is NULL");
710 VINE_LOGD("service[%p], disc handle[%p]", service, disc);
711 vine_disc_s *disc_handle = (vine_disc_s *)disc;
712 void *plugin_handle = disc_handle->plugin_handle;
713 VINE_LOGD("plugin handle[%p]", plugin_handle);
715 RET_VAL_IF(disc_handle->plugin_fn == NULL, VINE_ERROR_INVALID_OPERATION, "plugin_fn is NULL");
716 if (disc_handle->plugin_fn->cancel_resolve_ip == NULL) {
717 VINE_LOGE("No resolve_ip() defined");
718 return VINE_ERROR_OPERATION_FAILED;
721 vine_disc_error error = disc_handle->plugin_fn->cancel_resolve_ip(plugin_handle);
722 if (error != VINE_DISC_ERROR_NONE)
723 VINE_LOGE("Fail to cancel_resolve_ip %d", error);
725 return __convert_disc_error_to_vine_error(error);
728 int vine_disc_cancel_resolve_ip(vine_disc_h disc, vine_service_h service)
730 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
731 RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
733 VINE_LOGD("Cancel resolving IP for a service[%p] disc_handle[%p]", service, disc);
735 int ret = __vine_disc_plugin_cancel_resolve_ip(disc, service);
736 if (ret != VINE_ERROR_NONE) {
737 VINE_LOGE("Fail to cancel resolving IP %d", ret);
741 vine_disc_s *disc_handle = (vine_disc_s *)disc;
742 disc_handle->event_queue = NULL;
743 disc_handle->service = NULL;
745 return VINE_ERROR_NONE;
748 bool vine_disc_is_plugin_loaded(vine_discovery_method_e disc_method)
750 return __vine_disc_plugins[(int)disc_method].init != NULL;