Merge "Modified resource properties for /tizen/d2d-service" into tizen
[platform/core/convergence/d2d-conv-manager.git] / daemon / ServiceManager.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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 "ServiceManager.h"
18 #include "service_provider/AppCommServiceProvider.h"
19 #include "service_provider/RemoteAppControlServiceProvider.h"
20 #include "access_control/Privilege.h"
21 #include "Util.h"
22 #include <iotcon.h>
23
24 static conv::ServiceManager *_instance;
25 static iotcon_resource_h iotcon_resource = NULL;
26
27 using namespace std;
28
29 conv::ServiceManager::ServiceManager()
30 {
31         __activationState = 1;
32 }
33
34 conv::ServiceManager::~ServiceManager()
35 {
36 }
37
38 int conv::ServiceManager::handleVconfUpdate(keynode_t *node)
39 {
40         __activationState = vconf_keynode_get_int(node);
41
42         if ( __activationState == 1 ) {
43                 registerDiscoveryInfo();
44         } else {
45                 unregisterDiscoveryInfo();
46         }
47
48         return CONV_ERROR_NONE;
49 }
50
51 static void vconf_update_cb(keynode_t *node, void* user_data)
52 {
53         conv::ServiceManager* instance = static_cast<conv::ServiceManager*>(user_data);
54         IF_FAIL_VOID_TAG(instance, _E, "static_cast failed");
55
56         instance->handleVconfUpdate(node);
57 }
58
59 int conv::ServiceManager::init()
60 {
61         registerProvider(new(std::nothrow) conv::AppCommServiceProvider());
62         registerProvider(new(std::nothrow) conv::RemoteAppControlServiceProvider());
63
64         if (conv::util::isServiceActivated()) {
65                 __activationState = 1;
66                 registerDiscoveryInfo();
67         } else {
68                 __activationState = 0;
69                 unregisterDiscoveryInfo();
70         }
71
72         int error = vconf_notify_key_changed(VCONFKEY_SETAPPL_D2D_CONVERGENCE_SERVICE, vconf_update_cb, this);
73
74         IF_FAIL_RETURN_TAG(error >= 0, CONV_ERROR_INVALID_OPERATION, _E, "vconf error (%d)", error);
75
76         return CONV_ERROR_NONE;
77 }
78
79 int conv::ServiceManager::release()
80 {
81         unregisterDiscoveryInfo();
82
83         for (ServiceProviderList::iterator it = __providerList.begin(); it != __providerList.end(); ++it) {
84                 (*it)->release();
85         }
86
87         for (ServiceProviderList::iterator it = __providerList.begin(); it != __providerList.end(); ++it) {
88                 delete *it;
89         }
90
91         __providerList.clear();
92
93         return CONV_ERROR_NONE;
94 }
95
96 int conv::ServiceManager::handleRequest(Request* requestObj)
97 {
98         _D("handle_request called");
99         string type;
100         int error = CONV_ERROR_INVALID_OPERATION;
101         bool result;
102
103         Json description = requestObj->getDescription();
104         result = description.get(NULL, CONV_JSON_TYPE, &type);
105
106         IF_FAIL_CATCH_TAG(result, _E, "json parse error : no type info");
107
108         for (ServiceProviderList::iterator it = __providerList.begin(); it != __providerList.end(); ++it) {
109                 if ( (*it)->getType().compare(type) == 0 )
110                 {
111                         _D("found service provider");
112                         error = (*it)->checkActivationState();
113                         IF_FAIL_CATCH_TAG(error == CONV_ERROR_NONE, _E, "service provider is not activated");
114
115                         error = (*it)->loadServiceInfo(requestObj);
116                         IF_FAIL_CATCH_TAG(error == CONV_ERROR_NONE, _E, "%d, service_info load error", error);
117
118                         if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_START)) {
119                                 if ( !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_INTERNET) ||
120                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_BLUETOOTH) ||
121                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_D2D_DATA_SHARING) )
122                                 {
123                                         _E("permission denied");
124                                         requestObj->reply(CONV_ERROR_PERMISSION_DENIED);
125                                         delete requestObj;
126                                         return CONV_ERROR_PERMISSION_DENIED;
127                                 }
128                                 if ( !conv::util::isApiActivated()) {
129                                         _E("API is not activated");
130                                         requestObj->reply(CONV_ERROR_INVALID_OPERATION);
131                                         delete requestObj;
132                                         return CONV_ERROR_INVALID_OPERATION;
133                                 }
134
135                                 error = (*it)->startRequest(requestObj);
136                         } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_STOP)) {
137                                 if ( !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_INTERNET) ||
138                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_BLUETOOTH) )
139                                 {
140                                         _E("permission denied");
141                                         requestObj->reply(CONV_ERROR_PERMISSION_DENIED);
142                                         delete requestObj;
143                                         return CONV_ERROR_PERMISSION_DENIED;
144                                 }
145                                 if ( !conv::util::isApiActivated()) {
146                                         _E("API is not activated");
147                                         requestObj->reply(CONV_ERROR_INVALID_OPERATION);
148                                         delete requestObj;
149                                         return CONV_ERROR_INVALID_OPERATION;
150                                 }
151
152                                 error = (*it)->stopRequest(requestObj);
153                         } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_GET))   {
154                                 if ( !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_INTERNET) ||
155                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_BLUETOOTH) )
156                                 {
157                                         _E("permission denied");
158                                         requestObj->reply(CONV_ERROR_PERMISSION_DENIED);
159                                         delete requestObj;
160                                         return CONV_ERROR_PERMISSION_DENIED;
161                                 }
162                                 if ( !conv::util::isApiActivated()) {
163                                         _E("API is not activated");
164                                         requestObj->reply(CONV_ERROR_INVALID_OPERATION);
165                                         delete requestObj;
166                                         return CONV_ERROR_INVALID_OPERATION;
167                                 }
168
169                                 error = (*it)->readRequest(requestObj);
170                         } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_SET)) {
171                                 if ( !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_INTERNET) ||
172                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_BLUETOOTH) ||
173                                                 !conv::privilege_manager::isAllowed(requestObj->getCreds(), CONV_PRIVILEGE_D2D_DATA_SHARING) )
174                                 {
175                                         _E("permission denied");
176                                         requestObj->reply(CONV_ERROR_PERMISSION_DENIED);
177                                         delete requestObj;
178                                         return CONV_ERROR_PERMISSION_DENIED;
179                                 }
180                                 if ( !conv::util::isApiActivated()) {
181                                         _E("API is not activated");
182                                         requestObj->reply(CONV_ERROR_INVALID_OPERATION);
183                                         delete requestObj;
184                                         return CONV_ERROR_INVALID_OPERATION;
185                                 }
186
187                                 error = (*it)->publishRequest(requestObj);
188                         } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_RECV)) {
189                                 return (*it)->registerRequest(requestObj);
190                         } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_CHECK_STATE)) {
191                                 error = (*it)->checkStateRequest(requestObj);
192                         }
193                         IF_FAIL_CATCH_TAG(error == CONV_ERROR_NONE, _E, "service manager request handle error");
194                 }
195         }
196
197         requestObj->reply(CONV_ERROR_NONE);
198         delete requestObj;
199         _D("requestObj deleted");
200         return CONV_ERROR_NONE;
201
202 CATCH:
203         requestObj->reply(error);
204         delete requestObj;
205
206         return error;
207 }
208
209 void conv::service_manager::setInstance(conv::ServiceManager* mgr)
210 {
211         _instance = mgr;
212 }
213
214 int conv::service_manager::handleRequest(Request* requestObj)
215 {
216         IF_FAIL_RETURN_TAG(_instance, CONV_ERROR_INVALID_PARAMETER, _E, "Not initialized");
217         _instance->handleRequest(requestObj);
218
219         return CONV_ERROR_NONE;
220 }
221
222 int conv::ServiceManager::registerProvider(conv::IServiceProvider *provider)
223 {
224         if (!provider) {
225                 _E("Provider NULL");
226                 return CONV_ERROR_INVALID_PARAMETER;
227         }
228
229         if (provider->checkActivationState() == CONV_ERROR_NONE) {
230                 if (provider->init() != CONV_ERROR_NONE) {
231                         _E("Provider initialization failed");
232                         delete provider;
233                         return CONV_ERROR_INVALID_OPERATION;
234                 }
235         } else {
236                 _D("provider is not activated. init pending");
237         }
238
239         __providerList.push_back(provider);
240
241         return CONV_ERROR_NONE;
242 }
243
244
245
246 static int _send_response(iotcon_request_h request, iotcon_representation_h repr,
247                 iotcon_response_result_e result)
248 {
249         int ret;
250         iotcon_response_h response;
251
252         ret = iotcon_response_create(request, &response);
253         if (IOTCON_ERROR_NONE != ret) {
254                 _E("iotcon_response_create() Fail(%d)", ret);
255                 return CONV_ERROR_INVALID_OPERATION;
256         }
257
258         ret = iotcon_response_set_result(response, result);
259         if (IOTCON_ERROR_NONE != ret) {
260                 _E("iotcon_response_set_result() Fail(%d)", ret);
261                 iotcon_response_destroy(response);
262                 return CONV_ERROR_INVALID_OPERATION;
263         }
264
265         ret = iotcon_response_set_representation(response, repr);
266         if (IOTCON_ERROR_NONE != ret) {
267                 _E("iotcon_response_set_representation() Fail(%d)", ret);
268                 iotcon_response_destroy(response);
269                 return CONV_ERROR_INVALID_OPERATION;
270         }
271
272         /* send Representation to the client */
273         ret = iotcon_response_send(response);
274         if (IOTCON_ERROR_NONE != ret) {
275                 _E("iotcon_response_send() Fail(%d)", ret);
276                 iotcon_response_destroy(response);
277                 return CONV_ERROR_INVALID_OPERATION;
278         }
279
280         iotcon_response_destroy(response);
281
282         return CONV_ERROR_NONE;
283 }
284
285
286 static iotcon_representation_h _get_d2d_service_representation(conv::ServiceManager* instance)
287 {
288         int ret;
289         iotcon_attributes_h attributes;
290         iotcon_representation_h repr;
291
292         ret = iotcon_representation_create(&repr);
293         if (IOTCON_ERROR_NONE != ret) {
294                 _E("iotcon_representation_create() Fail(%d)", ret);
295                 return NULL;
296         }
297
298         ret = iotcon_attributes_create(&attributes);
299         if (IOTCON_ERROR_NONE != ret) {
300                 _E("iotcon_attributes_create() Fail(%d)", ret);
301                 iotcon_representation_destroy(repr);
302                 return NULL;
303         }
304
305         string deviceIdStr = conv::util::getDeviceId();
306         string deviceNameStr = conv::util::getDeviceName();
307         char* deviceId = new char[deviceIdStr.size() + 1];
308         char* deviceName = new char[deviceNameStr.size() + 1];
309
310         memset(deviceId, 0, deviceIdStr.size() + 1);
311         memset(deviceName, 0, deviceNameStr.size() + 1);
312
313         strncpy(deviceId, deviceIdStr.c_str(), deviceIdStr.size()+1);
314         strncpy(deviceName, deviceNameStr.c_str(), deviceNameStr.size()+1);
315
316         _D("device name : %s", deviceName);
317         iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_ID, deviceId);
318         iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, deviceName);
319 #if defined(_TV_)
320         _D("device type : TV");
321         string deviceTypeStr(CONV_DEVICE_TYPE_TV);
322 #elif defined(_MOBILE_)
323         _D("device type : MOBILE");
324         string deviceTypeStr(CONV_DEVICE_TYPE_MOBILE);
325 #elif defined(_WEARABLE_)
326         _D("device type : WEARABLE");
327         string deviceTypeStr(CONV_DEVICE_TYPE_WEARABLE);
328 #else
329         _D("device type : UNKNOWN");
330         string deviceTypeStr(CONV_DEVICE_TYPE_UNKNOWN);
331 #endif
332         char* deviceType = new char[deviceTypeStr.size() + 1];
333
334         memset(deviceType, 0, deviceTypeStr.size() + 1);
335         strncpy(deviceType, deviceTypeStr.c_str(), deviceTypeStr.size()+1);
336
337         iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, deviceType);
338
339         delete[] deviceId;
340         delete[] deviceName;
341         delete[] deviceType;
342
343         conv::Json serviceJson;
344         instance->getServiceInfoForDiscovery(&serviceJson);
345         char* service_json_char = serviceJson.dupCstr();
346
347         iotcon_attributes_add_str(attributes, "serviceJson", service_json_char);
348
349         ret = iotcon_representation_set_attributes(repr, attributes);
350         g_free(service_json_char);
351         if (IOTCON_ERROR_NONE != ret) {
352                 _E("iotcon_representation_set_attributes() Fail(%d)", ret);
353                 iotcon_attributes_destroy(attributes);
354                 iotcon_representation_destroy(repr);
355                 return NULL;
356         }
357
358         iotcon_attributes_destroy(attributes);
359
360         return repr;
361 }
362
363 int conv::ServiceManager::getServiceInfoForDiscovery(Json* serviceJson)
364 {
365         IF_FAIL_RETURN_TAG(serviceJson, CONV_ERROR_INVALID_OPERATION, _E, "serviceJson is NULL");
366
367         for (ServiceProviderList::iterator it = __providerList.begin(); it != __providerList.end(); ++it) {
368                 Json serviceInfo;
369                 if ((*it)->getServiceInfoForDiscovery(&serviceInfo) == CONV_ERROR_NONE) {
370                         serviceJson->appendArray(NULL, "service_list", serviceInfo);
371                 }
372         }
373
374         _D("service_info : %s", serviceJson->str().c_str());
375
376         return CONV_ERROR_NONE;
377 }
378
379 static void iotcon_request_cb(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
380 {
381         _D("request cb called");
382
383         int ret;
384         iotcon_request_type_e type;
385         char *host_address;
386
387         conv::ServiceManager *instance = (conv::ServiceManager*)user_data;
388
389         IF_FAIL_VOID_TAG(request, _E, "request is NULL");
390
391         ret = iotcon_request_get_host_address(request, &host_address);
392         if (IOTCON_ERROR_NONE != ret) {
393                 _E("iotcon_request_get_host_address() Fail(%d)", ret);
394                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
395                 return;
396         }
397         _I("host_address : %s", host_address);
398
399         ret = iotcon_request_get_request_type(request, &type);
400         if (IOTCON_ERROR_NONE != ret) {
401                 _E("iotcon_request_get_types() Fail(%d)", ret);
402                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
403                 return;
404         }
405
406         if (IOTCON_REQUEST_GET == type) {
407                 iotcon_representation_h resp_repr;
408                 _I("GET request");
409
410                 resp_repr = _get_d2d_service_representation(instance);
411                 if (resp_repr == NULL) {
412                         _I("_get_d2d_service_representation() Fail");
413                         ret = CONV_ERROR_INVALID_OPERATION;
414                 } else {
415                         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_OK);
416                         if (ret != IOTCON_ERROR_NONE) {
417                                 _E("_send_response() Fail(%d)", ret);
418                                 iotcon_representation_destroy(resp_repr);
419                                 return;
420                         }
421
422                         iotcon_representation_destroy(resp_repr);
423                 }
424         }
425
426         if (IOTCON_ERROR_NONE != ret) {
427                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
428                 return;
429         }
430 }
431
432 int conv::ServiceManager::registerDiscoveryInfo()
433 {
434         IF_FAIL_RETURN_TAG(iotcon_resource == NULL, CONV_ERROR_INVALID_PARAMETER, _E, "resource for discovery is already registered");
435
436         // register resource
437         int properties;
438         iotcon_resource_interfaces_h resource_ifaces = NULL;
439         iotcon_resource_types_h resource_types = NULL;
440         int error;
441
442         properties = IOTCON_RESOURCE_DISCOVERABLE;
443
444         error = iotcon_resource_types_create(&resource_types);
445         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "rt creation failed");
446
447         iotcon_resource_types_add(resource_types, CONV_RESOURCE_TYPE_TIZEN_D2D_SERVICE);
448
449         error = iotcon_resource_interfaces_create(&resource_ifaces);
450
451         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
452
453         iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
454
455         error = iotcon_resource_create(CONV_URI_TIZEN_D2D_SERVICE, resource_types, resource_ifaces, properties, iotcon_request_cb, this, &iotcon_resource);
456         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource creation failed");
457
458         _D("device info registered as resource");
459         iotcon_resource_types_destroy(resource_types);
460         iotcon_resource_interfaces_destroy(resource_ifaces);
461
462         return CONV_ERROR_NONE;
463 }
464
465 int conv::ServiceManager::unregisterDiscoveryInfo()
466 {
467         IF_FAIL_RETURN_TAG(iotcon_resource != NULL, CONV_ERROR_INVALID_PARAMETER, _E, "resource for discovery is already unregistered");
468
469         int error = iotcon_resource_destroy(iotcon_resource);
470         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource destroy failed");
471         iotcon_resource = NULL;
472
473
474         _D("device info unregistered");
475         return CONV_ERROR_NONE;
476 }
477