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.
21 #include "vine-constants.h"
22 #include "vine-disc.h"
23 #include "vine-service.h"
25 #include "vine-utils.h"
28 VINE_SERVICE_TYPE_PUBLISHED,
29 VINE_SERVICE_TYPE_DISCOVERED,
30 } vine_service_type_e;
33 vine_service_type_e type;
34 char service_type[VINE_MAX_SERVICE_TYPE_LEN + 1];
35 char service_name[VINE_MAX_SERVICE_NAME_LEN + 1];
36 char host_name[VINE_MAX_HOST_NAME_LEN + 1];
37 char ip[VINE_MAX_IP_LEN + 1];
38 vine_address_family_e family;
40 map<string, string> attributes;
41 char iface_name[IF_NAMESIZE + 1];
42 vine_service_state_e state;
45 void *disc_handle; // Used to resolve IP address
46 vine_session_h ip_resolving_session;
47 vine_session_ip_resolved_cb ip_resolved_cb;
48 void *ip_resolved_cb_data;
51 bool _vine_service_check_service_type(const char *service_type)
53 RET_VAL_IF(service_type == NULL, false, "service_type is NULL");
54 int len = strlen(service_type);
55 return len > 0 && len <= VINE_MAX_SERVICE_TYPE_LEN;
58 static bool _vine_service_check_service_name(const char *service_name)
60 RET_VAL_IF(service_name == NULL, false, "service_name is NULL");
61 int len = strlen(service_name);
62 return len > 0 && len <= VINE_MAX_SERVICE_NAME_LEN;
65 bool _is_discovered_service(vine_service_h service)
67 vine_service_s *s = (vine_service_s *)service;
68 return s->type == VINE_SERVICE_TYPE_DISCOVERED;
71 int _vine_service_create(vine_service_h *service, bool published)
73 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
75 vine_service_s *s = new vine_service_s;
76 s->type = published ? VINE_SERVICE_TYPE_PUBLISHED : VINE_SERVICE_TYPE_DISCOVERED;
77 memset(s->service_type, 0, VINE_MAX_SERVICE_TYPE_LEN + 1);
78 memset(s->service_name, 0, VINE_MAX_SERVICE_NAME_LEN + 1);
79 memset(s->host_name, 0, VINE_MAX_HOST_NAME_LEN + 1);
80 memset(s->iface_name, 0, IF_NAMESIZE + 1);
82 s->state = VINE_SERVICE_UNAVAILABLE;
84 s->disc_handle = NULL;
85 s->ip_resolving_session = NULL;
86 s->ip_resolved_cb = NULL;
87 s->ip_resolved_cb_data = NULL;
91 return VINE_ERROR_NONE;
94 int _vine_service_destroy(vine_service_h service)
96 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
97 vine_service_s *s = (vine_service_s *)service;
99 if (s->ip_resolving_session != NULL && s->ip_resolved_cb != NULL) {
100 vine_session_unset_ip_resolved_cb(s->ip_resolving_session, service);
102 s->attributes.clear();
104 return VINE_ERROR_NONE;
107 int _vine_service_clone(vine_service_h origin, vine_service_h *cloned)
109 RET_VAL_IF(origin == NULL, VINE_ERROR_INVALID_PARAMETER, "origin is NULL");
110 RET_VAL_IF(cloned == NULL, VINE_ERROR_INVALID_PARAMETER, "cloned is NULL");
112 vine_service_s *origin_service = (vine_service_s *)origin;
113 vine_service_s *cloned_service = new vine_service_s;
115 cloned_service->type = origin_service->type;
116 strncpy(cloned_service->service_type, origin_service->service_type, VINE_MAX_SERVICE_TYPE_LEN);
117 strncpy(cloned_service->service_name, origin_service->service_name, VINE_MAX_SERVICE_NAME_LEN);
118 strncpy(cloned_service->host_name, origin_service->host_name, VINE_MAX_HOST_NAME_LEN);
119 strncpy(cloned_service->ip, origin_service->ip, VINE_MAX_IP_LEN);
120 cloned_service->family = origin_service->family;
121 cloned_service->port = origin_service->port;
122 cloned_service->attributes = origin_service->attributes;
123 strncpy(cloned_service->iface_name, origin_service->iface_name, IF_NAMESIZE);
124 cloned_service->state = origin_service->state;
126 cloned_service->disc_handle = NULL;
127 cloned_service->ip_resolved_cb = NULL;
128 cloned_service->ip_resolved_cb_data = NULL;
130 *cloned = cloned_service;
131 VINE_LOGD("Cloned service[%p]", cloned_service);
133 return VINE_ERROR_NONE;
136 int _vine_service_set_type(
137 vine_service_h service, const char *service_type)
139 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
140 RET_VAL_IF(_vine_service_check_service_type(service_type) == false,
141 VINE_ERROR_INVALID_PARAMETER, "invalid length of service_type");
143 vine_service_s *s = (vine_service_s *)service;
144 strncpy(s->service_type, service_type, VINE_MAX_SERVICE_TYPE_LEN);
146 return VINE_ERROR_NONE;
149 const char *_vine_service_get_type(vine_service_h service)
151 RET_VAL_IF(service == NULL, NULL, "service is NULL");
153 vine_service_s *s = (vine_service_s *)service;
154 return s->service_type;
157 int _vine_service_set_name(
158 vine_service_h service, const char *service_name)
160 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
161 RET_VAL_IF(_vine_service_check_service_name(service_name) == false,
162 VINE_ERROR_INVALID_PARAMETER, "invalid length of service_name");
164 vine_service_s *s = (vine_service_s *)service;
165 strncpy(s->service_name, service_name, VINE_MAX_SERVICE_TYPE_LEN);
167 return VINE_ERROR_NONE;
170 const char *_vine_service_get_name(vine_service_h service)
172 RET_VAL_IF(service == NULL, NULL, "service is NULL");
174 vine_service_s *s = (vine_service_s *)service;
175 return s->service_name;
178 int _vine_service_set_host_name(
179 vine_service_h service, const char *host_name)
181 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
183 vine_service_s *s = (vine_service_s *)service;
184 strncpy(s->host_name, host_name, VINE_MAX_HOST_NAME_LEN);
186 return VINE_ERROR_NONE;
189 const char *_vine_service_get_host_name(vine_service_h service)
191 RET_VAL_IF(service == NULL, NULL, "service is NULL");
193 vine_service_s *s = (vine_service_s *)service;
197 static bool __check_len_key(const char *key)
199 RET_VAL_IF(key == NULL, false, "key is NULL");
200 int len = strlen(key);
201 return len > 0 && len <= VINE_MAX_KEY_LEN;
204 int _vine_service_add_attribute(vine_service_h service,
205 const char *key, const char *value)
207 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
208 RET_VAL_IF(__check_len_key(key) == false,
209 VINE_ERROR_INVALID_PARAMETER, "invalid length of key");
211 VINE_LOGD("Key[%s] value[%s]", key, value);
213 vine_service_s *s = (vine_service_s *)service;
215 if (s->attributes.find(key) != s->attributes.end()) {
216 VINE_LOGE("Key[%s] already exits", key);
217 return VINE_ERROR_INVALID_OPERATION;
220 // value can be NULL, which represents an empty string.
221 s->attributes[key] = value ? value : "";
223 return VINE_ERROR_NONE;
226 int _vine_service_remove_attribute(vine_service_h service, const char *key)
228 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
229 RET_VAL_IF(key == NULL, VINE_ERROR_INVALID_PARAMETER, "key is NULL");
231 vine_service_s *s = (vine_service_s *)service;
233 string attr_key(key);
234 if (s->attributes.find(attr_key) == s->attributes.end()) {
235 VINE_LOGE("No key[%s]", key);
236 return VINE_ERROR_INVALID_PARAMETER;
239 s->attributes.erase(attr_key);
240 return VINE_ERROR_NONE;
243 map<string, string> _vine_service_get_attributes(vine_service_h service)
245 if (service == NULL) {
246 VINE_LOGE("service is NULL");
247 return map<string, string>();
250 vine_service_s *s = (vine_service_s *)service;
251 return s->attributes;
254 int _vine_service_foreach_attribute(vine_service_h service,
255 vine_service_attribute_cb callback, void *user_data)
257 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
258 RET_VAL_IF(callback == NULL, VINE_ERROR_INVALID_PARAMETER, "callback is NULL");
260 vine_service_s *s = (vine_service_s *)service;
262 for (const auto &kv : s->attributes) {
263 if (!callback(kv.first.c_str(), kv.second.c_str(), user_data))
267 return VINE_ERROR_NONE;
270 int _vine_service_set_iface_name(vine_service_h service, const char *iface_name)
272 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
274 vine_service_s *s = (vine_service_s *)service;
275 strncpy(s->iface_name, iface_name, IF_NAMESIZE);
277 return VINE_ERROR_NONE;
280 const char *_vine_service_get_iface_name(vine_service_h service)
282 RET_VAL_IF(service == NULL, NULL, "service is NULL");
284 vine_service_s *s = (vine_service_s *)service;
285 return s->iface_name;
288 int _vine_service_get_disc_handle(vine_service_h service,
289 vine_discovery_method_e disc_method, void **disc_handle)
291 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
293 vine_service_s *s = (vine_service_s *)service;
294 if (s->disc_handle == NULL) {
295 int ret = vine_disc_create(disc_method, &s->disc_handle);
296 RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to vine_disc_create");
298 *disc_handle = s->disc_handle;
299 return VINE_ERROR_NONE;
302 int _vine_service_set_ip_resolved_cb(vine_service_h service, vine_session_h session,
303 vine_session_ip_resolved_cb callback, void *user_data)
305 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
306 RET_VAL_IF(session == NULL, VINE_ERROR_INVALID_PARAMETER, "session is NULL");
307 RET_VAL_IF(callback == NULL, VINE_ERROR_INVALID_PARAMETER, "callback is NULL");
309 RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
310 "only for discovered service");
312 vine_service_s *s = (vine_service_s *)service;
313 s->ip_resolving_session = session;
314 s->ip_resolved_cb = callback;
315 s->ip_resolved_cb_data = user_data;
317 return VINE_ERROR_NONE;
320 int _vine_service_unset_ip_resolved_cb(vine_service_h service)
322 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
324 RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
325 "only for discovered service");
327 vine_service_s *s = (vine_service_s *)service;
328 s->ip_resolving_session = NULL;
329 s->ip_resolved_cb = NULL;
330 s->ip_resolved_cb_data = NULL;
332 return VINE_ERROR_NONE;
335 vine_session_ip_resolved_cb _vine_service_ip_resolved_cb(vine_service_h service)
337 RET_VAL_IF(service == NULL, NULL, "service is NULL");
339 vine_service_s *s = (vine_service_s *)service;
340 return s->ip_resolved_cb;
343 void * _vine_service_ip_resolved_cb_data(vine_service_h service)
345 RET_VAL_IF(service == NULL, NULL, "service is NULL");
347 vine_service_s *s = (vine_service_s *)service;
348 return s->ip_resolved_cb_data;
351 static bool __check_port_number(int port)
353 return port >= 0 && port <= 65535;
356 int _vine_service_set_port(vine_service_h service, int port)
358 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
359 RET_VAL_IF(__check_port_number(port) == false,
360 VINE_ERROR_INVALID_PARAMETER, "A port number ranges from 0 to 65535");
362 vine_service_s *s = (vine_service_s *)service;
364 return VINE_ERROR_NONE;
367 int _vine_service_get_port(vine_service_h service)
369 RET_VAL_IF(service == NULL, 0, "service is NULL");
371 vine_service_s *s = (vine_service_s *)service;
375 int _vine_service_set_state(vine_service_h service, vine_service_state_e state)
377 RET_VAL_IF(service == NULL, 0, "service is NULL");
378 vine_service_s *s = (vine_service_s *)service;
380 return VINE_ERROR_NONE;
383 vine_service_state_e _vine_service_get_state(vine_service_h service)
385 RET_VAL_IF(service == NULL, VINE_SERVICE_UNAVAILABLE, "service is NULL");
386 vine_service_s *s = (vine_service_s *)service;
390 int _vine_service_set_disc_handle(vine_service_h service, void *disc_handle)
392 RET_VAL_IF(service == NULL, 0, "service is NULL");
393 vine_service_s *s = (vine_service_s *)service;
394 s->disc_handle = disc_handle;
395 return VINE_ERROR_NONE;