Release Vine 1.0.0
[platform/core/api/vine.git] / src / vine-service.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdbool.h>
18 #include <net/if.h>
19
20 #include "vine.h"
21 #include "vine-constants.h"
22 #include "vine-disc.h"
23 #include "vine-service.h"
24 #include "vine-log.h"
25 #include "vine-utils.h"
26
27 typedef enum {
28         VINE_SERVICE_TYPE_PUBLISHED,
29         VINE_SERVICE_TYPE_DISCOVERED,
30 } vine_service_type_e;
31
32 typedef struct {
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;
39         int port;
40         map<string, string> attributes;
41         char iface_name[IF_NAMESIZE + 1];
42         vine_service_state_e state;
43
44         void *disc_handle;      // Used to resolve IP address
45         vine_session_ip_resolved_cb ip_resolved_cb;
46         void *ip_resolved_cb_data;
47 } vine_service_s;
48
49 bool _vine_service_check_service_type(const char *service_type)
50 {
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;
54 }
55
56 static bool _vine_service_check_service_name(const char *service_name)
57 {
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;
61 }
62
63 bool _is_discovered_service(vine_service_h service)
64 {
65         vine_service_s *s = (vine_service_s *)service;
66         return s->type == VINE_SERVICE_TYPE_DISCOVERED;
67 }
68
69 int _vine_service_create(vine_service_h *service, bool published)
70 {
71         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
72
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);
78         s->port = -1;
79         *service = s;
80         s->type = published ? VINE_SERVICE_TYPE_PUBLISHED : VINE_SERVICE_TYPE_DISCOVERED;
81
82         return VINE_ERROR_NONE;
83 }
84
85 int _vine_service_destroy(vine_service_h service)
86 {
87         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
88         vine_service_s *s = (vine_service_s *)service;
89
90         s->attributes.clear();
91         delete s;
92         return VINE_ERROR_NONE;
93 }
94
95 int _vine_service_clone(vine_service_h origin, vine_service_h *cloned)
96 {
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");
99
100         vine_service_s *origin_service = (vine_service_s *)origin;
101         vine_service_s *cloned_service = new vine_service_s;
102
103         memcpy(cloned_service, origin_service, sizeof(vine_service_s));
104         cloned_service->attributes = origin_service->attributes;
105
106         *cloned = cloned_service;
107         VINE_LOGD("Cloned service[%p]", cloned_service);
108
109         return VINE_ERROR_NONE;
110 }
111
112 int _vine_service_set_type(
113         vine_service_h service, const char *service_type)
114 {
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");
118
119         vine_service_s *s = (vine_service_s *)service;
120         strncpy(s->service_type, service_type, VINE_MAX_SERVICE_TYPE_LEN);
121
122         return VINE_ERROR_NONE;
123 }
124
125 const char *_vine_service_get_type(vine_service_h service)
126 {
127         RET_VAL_IF(service == NULL, NULL, "service is NULL");
128
129         vine_service_s *s = (vine_service_s *)service;
130         return s->service_type;
131 }
132
133 int _vine_service_set_name(
134         vine_service_h service, const char *service_name)
135 {
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");
139
140         vine_service_s *s = (vine_service_s *)service;
141         strncpy(s->service_name, service_name, VINE_MAX_SERVICE_TYPE_LEN);
142
143         return VINE_ERROR_NONE;
144 }
145
146 const char *_vine_service_get_name(vine_service_h service)
147 {
148         RET_VAL_IF(service == NULL, NULL, "service is NULL");
149
150         vine_service_s *s = (vine_service_s *)service;
151         return s->service_name;
152 }
153
154 int _vine_service_set_host_name(
155         vine_service_h service, const char *host_name)
156 {
157         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
158
159         vine_service_s *s = (vine_service_s *)service;
160         strncpy(s->host_name, host_name, VINE_MAX_HOST_NAME_LEN);
161
162         return VINE_ERROR_NONE;
163 }
164
165 const char *_vine_service_get_host_name(vine_service_h service)
166 {
167         RET_VAL_IF(service == NULL, NULL, "service is NULL");
168
169         vine_service_s *s = (vine_service_s *)service;
170         return s->host_name;
171 }
172
173 static bool __check_len_key(const char *key)
174 {
175         RET_VAL_IF(key == NULL, false, "key is NULL");
176         int len = strlen(key);
177         return len > 0 && len <= VINE_MAX_KEY_LEN;
178 }
179
180 int _vine_service_add_attribute(vine_service_h service,
181         const char *key, const char *value)
182 {
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");
186
187         VINE_LOGD("Key[%s] value[%s]", key, value);
188
189         vine_service_s *s = (vine_service_s *)service;
190
191         if (s->attributes.find(key) != s->attributes.end()) {
192                 VINE_LOGE("Key[%s] already exits", key);
193                 return VINE_ERROR_INVALID_OPERATION;
194         }
195
196         // value can be NULL, which represents an empty string.
197         s->attributes[key] = value ? value : "";
198
199         return VINE_ERROR_NONE;
200 }
201
202 int _vine_service_remove_attribute(vine_service_h service, const char *key)
203 {
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");
206
207         vine_service_s *s = (vine_service_s *)service;
208
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;
213         }
214
215         s->attributes.erase(attr_key);
216         return VINE_ERROR_NONE;
217 }
218
219 map<string, string> _vine_service_get_attributes(vine_service_h service)
220 {
221         if (service == NULL) {
222                 VINE_LOGE("service is NULL");
223                 return map<string, string>();
224         }
225
226         vine_service_s *s = (vine_service_s *)service;
227         return s->attributes;
228 }
229
230 int _vine_service_foreach_attribute(vine_service_h service,
231         vine_service_attribute_cb callback, void *user_data)
232 {
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");
235
236         vine_service_s *s = (vine_service_s *)service;
237
238         for (const auto &kv : s->attributes) {
239                 if (!callback(kv.first.c_str(), kv.second.c_str(), user_data))
240                         break;
241         }
242
243         return VINE_ERROR_NONE;
244 }
245
246 int _vine_service_set_iface_name(vine_service_h service, const char *iface_name)
247 {
248         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
249
250         vine_service_s *s = (vine_service_s *)service;
251         strncpy(s->iface_name, iface_name, IF_NAMESIZE);
252
253         return VINE_ERROR_NONE;
254 }
255
256 const char *_vine_service_get_iface_name(vine_service_h service)
257 {
258         RET_VAL_IF(service == NULL, NULL, "service is NULL");
259
260         vine_service_s *s = (vine_service_s *)service;
261         return s->iface_name;
262 }
263
264 int _vine_service_get_disc_handle(vine_service_h service,
265         vine_discovery_method_e disc_method, void **disc_handle)
266 {
267         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
268
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");
273         }
274         *disc_handle = s->disc_handle;
275         return VINE_ERROR_NONE;
276 }
277
278 int _vine_service_set_ip_resolved_cb(vine_service_h service,
279         vine_session_ip_resolved_cb callback, void *user_data)
280 {
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");
283
284         RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
285                         "only for discovered service");
286
287         vine_service_s *s = (vine_service_s *)service;
288         s->ip_resolved_cb = callback;
289         s->ip_resolved_cb_data = user_data;
290
291         return VINE_ERROR_NONE;
292 }
293
294 int _vine_service_unset_ip_resolved_cb(vine_service_h service)
295 {
296         RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
297
298         RET_VAL_IF(!_is_discovered_service(service), VINE_ERROR_INVALID_OPERATION,
299                         "only for discovered service");
300
301         vine_service_s *s = (vine_service_s *)service;
302         s->ip_resolved_cb = NULL;
303         s->ip_resolved_cb_data = NULL;
304
305         return VINE_ERROR_NONE;
306 }
307
308 vine_session_ip_resolved_cb _vine_service_ip_resolved_cb(vine_service_h service)
309 {
310         RET_VAL_IF(service == NULL, NULL, "service is NULL");
311
312         vine_service_s *s = (vine_service_s *)service;
313         return s->ip_resolved_cb;
314 }
315
316 void * _vine_service_ip_resolved_cb_data(vine_service_h service)
317 {
318         RET_VAL_IF(service == NULL, NULL, "service is NULL");
319
320         vine_service_s *s = (vine_service_s *)service;
321         return s->ip_resolved_cb_data;
322 }
323
324 static bool __check_port_number(int port)
325 {
326         return port >= 0 && port <= 65535;
327 }
328
329 int _vine_service_set_port(vine_service_h service, int port)
330 {
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");
334
335         vine_service_s *s = (vine_service_s *)service;
336         s->port = port;
337         return VINE_ERROR_NONE;
338 }
339
340 int _vine_service_get_port(vine_service_h service)
341 {
342         RET_VAL_IF(service == NULL, 0, "service is NULL");
343
344         vine_service_s *s = (vine_service_s *)service;
345         return s->port;
346 }
347
348 int _vine_service_set_state(vine_service_h service, vine_service_state_e state)
349 {
350         RET_VAL_IF(service == NULL, 0, "service is NULL");
351         vine_service_s *s = (vine_service_s *)service;
352         s->state = state;
353         return VINE_ERROR_NONE;
354 }
355
356 vine_service_state_e _vine_service_get_state(vine_service_h service)
357 {
358         RET_VAL_IF(service == NULL, VINE_SERVICE_UNAVAILABLE, "service is NULL");
359         vine_service_s *s = (vine_service_s *)service;
360         return s->state;
361 }
362
363 int _vine_service_set_disc_handle(vine_service_h service, void *disc_handle)
364 {
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;
369 }