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;
44 void *disc_handle; // Used to resolve IP address
45 vine_session_ip_resolved_cb ip_resolved_cb;
46 void *ip_resolved_cb_data;
49 bool _vine_service_check_service_type(const char *service_type)
51 RET_VAL_IF(service_type == NULL, false, "service_type is NULL");
52 int len = strlen(service_type);
53 return len > 0 && len <= VINE_MAX_SERVICE_TYPE_LEN;
56 static bool _vine_service_check_service_name(const char *service_name)
58 RET_VAL_IF(service_name == NULL, false, "service_name is NULL");
59 int len = strlen(service_name);
60 return len > 0 && len <= VINE_MAX_SERVICE_NAME_LEN;
63 bool _is_discovered_service(vine_service_h service)
65 vine_service_s *s = (vine_service_s *)service;
66 return s->type == VINE_SERVICE_TYPE_DISCOVERED;
69 int _vine_service_create(vine_service_h *service, bool published)
71 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
73 vine_service_s *s = new vine_service_s;
74 memset(s->service_type, 0, VINE_MAX_SERVICE_TYPE_LEN + 1);
75 memset(s->service_name, 0, VINE_MAX_SERVICE_NAME_LEN + 1);
76 memset(s->host_name, 0, VINE_MAX_HOST_NAME_LEN + 1);
77 memset(s->iface_name, 0, IF_NAMESIZE + 1);
80 s->type = published ? VINE_SERVICE_TYPE_PUBLISHED : VINE_SERVICE_TYPE_DISCOVERED;
82 return VINE_ERROR_NONE;
85 int _vine_service_destroy(vine_service_h service)
87 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
88 vine_service_s *s = (vine_service_s *)service;
90 s->attributes.clear();
92 return VINE_ERROR_NONE;
95 int _vine_service_clone(vine_service_h origin, vine_service_h *cloned)
97 RET_VAL_IF(origin == NULL, VINE_ERROR_INVALID_PARAMETER, "origin is NULL");
98 RET_VAL_IF(cloned == NULL, VINE_ERROR_INVALID_PARAMETER, "cloned is NULL");
100 vine_service_s *origin_service = (vine_service_s *)origin;
101 vine_service_s *cloned_service = new vine_service_s;
103 memcpy(cloned_service, origin_service, sizeof(vine_service_s));
104 cloned_service->attributes = origin_service->attributes;
106 *cloned = cloned_service;
107 VINE_LOGD("Cloned service[%p]", cloned_service);
109 return VINE_ERROR_NONE;
112 int _vine_service_set_type(
113 vine_service_h service, const char *service_type)
115 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
116 RET_VAL_IF(_vine_service_check_service_type(service_type) == false,
117 VINE_ERROR_INVALID_PARAMETER, "invalid length of service_type");
119 vine_service_s *s = (vine_service_s *)service;
120 strncpy(s->service_type, service_type, VINE_MAX_SERVICE_TYPE_LEN);
122 return VINE_ERROR_NONE;
125 const char *_vine_service_get_type(vine_service_h service)
127 RET_VAL_IF(service == NULL, NULL, "service is NULL");
129 vine_service_s *s = (vine_service_s *)service;
130 return s->service_type;
133 int _vine_service_set_name(
134 vine_service_h service, const char *service_name)
136 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
137 RET_VAL_IF(_vine_service_check_service_name(service_name) == false,
138 VINE_ERROR_INVALID_PARAMETER, "invalid length of service_name");
140 vine_service_s *s = (vine_service_s *)service;
141 strncpy(s->service_name, service_name, VINE_MAX_SERVICE_TYPE_LEN);
143 return VINE_ERROR_NONE;
146 const char *_vine_service_get_name(vine_service_h service)
148 RET_VAL_IF(service == NULL, NULL, "service is NULL");
150 vine_service_s *s = (vine_service_s *)service;
151 return s->service_name;
154 int _vine_service_set_host_name(
155 vine_service_h service, const char *host_name)
157 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
159 vine_service_s *s = (vine_service_s *)service;
160 strncpy(s->host_name, host_name, VINE_MAX_HOST_NAME_LEN);
162 return VINE_ERROR_NONE;
165 const char *_vine_service_get_host_name(vine_service_h service)
167 RET_VAL_IF(service == NULL, NULL, "service is NULL");
169 vine_service_s *s = (vine_service_s *)service;
173 static bool __check_len_key(const char *key)
175 RET_VAL_IF(key == NULL, false, "key is NULL");
176 int len = strlen(key);
177 return len > 0 && len <= VINE_MAX_KEY_LEN;
180 int _vine_service_add_attribute(vine_service_h service,
181 const char *key, const char *value)
183 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
184 RET_VAL_IF(__check_len_key(key) == false,
185 VINE_ERROR_INVALID_PARAMETER, "invalid length of key");
187 VINE_LOGD("Key[%s] value[%s]", key, value);
189 vine_service_s *s = (vine_service_s *)service;
191 if (s->attributes.find(key) != s->attributes.end()) {
192 VINE_LOGE("Key[%s] already exits", key);
193 return VINE_ERROR_INVALID_OPERATION;
196 // value can be NULL, which represents an empty string.
197 s->attributes[key] = value ? value : "";
199 return VINE_ERROR_NONE;
202 int _vine_service_remove_attribute(vine_service_h service, const char *key)
204 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
205 RET_VAL_IF(key == NULL, VINE_ERROR_INVALID_PARAMETER, "key is NULL");
207 vine_service_s *s = (vine_service_s *)service;
209 string attr_key(key);
210 if (s->attributes.find(attr_key) == s->attributes.end()) {
211 VINE_LOGE("No key[%s]", key);
212 return VINE_ERROR_INVALID_PARAMETER;
215 s->attributes.erase(attr_key);
216 return VINE_ERROR_NONE;
219 map<string, string> _vine_service_get_attributes(vine_service_h service)
221 if (service == NULL) {
222 VINE_LOGE("service is NULL");
223 return map<string, string>();
226 vine_service_s *s = (vine_service_s *)service;
227 return s->attributes;
230 int _vine_service_foreach_attribute(vine_service_h service,
231 vine_service_attribute_cb callback, void *user_data)
233 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
234 RET_VAL_IF(callback == NULL, VINE_ERROR_INVALID_PARAMETER, "callback is NULL");
236 vine_service_s *s = (vine_service_s *)service;
238 for (const auto &kv : s->attributes) {
239 if (!callback(kv.first.c_str(), kv.second.c_str(), user_data))
243 return VINE_ERROR_NONE;
246 int _vine_service_set_iface_name(vine_service_h service, const char *iface_name)
248 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
250 vine_service_s *s = (vine_service_s *)service;
251 strncpy(s->iface_name, iface_name, IF_NAMESIZE);
253 return VINE_ERROR_NONE;
256 const char *_vine_service_get_iface_name(vine_service_h service)
258 RET_VAL_IF(service == NULL, NULL, "service is NULL");
260 vine_service_s *s = (vine_service_s *)service;
261 return s->iface_name;
264 int _vine_service_get_disc_handle(vine_service_h service,
265 vine_discovery_method_e disc_method, void **disc_handle)
267 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
269 vine_service_s *s = (vine_service_s *)service;
270 if (s->disc_handle == NULL) {
271 int ret = vine_disc_create(disc_method, &s->disc_handle);
272 RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to vine_disc_create");
274 *disc_handle = s->disc_handle;
275 return VINE_ERROR_NONE;
278 int _vine_service_set_ip_resolved_cb(vine_service_h service,
279 vine_session_ip_resolved_cb callback, void *user_data)
281 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
282 RET_VAL_IF(callback == NULL, VINE_ERROR_INVALID_PARAMETER, "callback is NULL");
284 RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
285 "only for discovered service");
287 vine_service_s *s = (vine_service_s *)service;
288 s->ip_resolved_cb = callback;
289 s->ip_resolved_cb_data = user_data;
291 return VINE_ERROR_NONE;
294 int _vine_service_unset_ip_resolved_cb(vine_service_h service)
296 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
298 RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
299 "only for discovered service");
301 vine_service_s *s = (vine_service_s *)service;
302 s->ip_resolved_cb = NULL;
303 s->ip_resolved_cb_data = NULL;
305 return VINE_ERROR_NONE;
308 vine_session_ip_resolved_cb _vine_service_ip_resolved_cb(vine_service_h service)
310 RET_VAL_IF(service == NULL, NULL, "service is NULL");
312 vine_service_s *s = (vine_service_s *)service;
313 return s->ip_resolved_cb;
316 void * _vine_service_ip_resolved_cb_data(vine_service_h service)
318 RET_VAL_IF(service == NULL, NULL, "service is NULL");
320 vine_service_s *s = (vine_service_s *)service;
321 return s->ip_resolved_cb_data;
324 static bool __check_port_number(int port)
326 return port >= 0 && port <= 65535;
329 int _vine_service_set_port(vine_service_h service, int port)
331 RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
332 RET_VAL_IF(__check_port_number(port) == false,
333 VINE_ERROR_INVALID_PARAMETER, "A port number ranges from 0 to 65535");
335 vine_service_s *s = (vine_service_s *)service;
337 return VINE_ERROR_NONE;
340 int _vine_service_get_port(vine_service_h service)
342 RET_VAL_IF(service == NULL, 0, "service is NULL");
344 vine_service_s *s = (vine_service_s *)service;
348 int _vine_service_set_state(vine_service_h service, vine_service_state_e state)
350 RET_VAL_IF(service == NULL, 0, "service is NULL");
351 vine_service_s *s = (vine_service_s *)service;
353 return VINE_ERROR_NONE;
356 vine_service_state_e _vine_service_get_state(vine_service_h service)
358 RET_VAL_IF(service == NULL, VINE_SERVICE_UNAVAILABLE, "service is NULL");
359 vine_service_s *s = (vine_service_s *)service;
363 int _vine_service_set_disc_handle(vine_service_h service, void *disc_handle)
365 RET_VAL_IF(service == NULL, 0, "service is NULL");
366 vine_service_s *s = (vine_service_s *)service;
367 s->disc_handle = disc_handle;
368 return VINE_ERROR_NONE;