2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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.
17 #ifdef __SUPPORTED_APP_CONTROL_SERVICE__
20 #include <bundle_internal.h>
21 #include <app_control_internal.h>
22 #include "RemoteAppControlServiceProvider.h"
23 #include "../ClientManager.h"
25 #include "../Server.h"
26 #if defined(_D2D_INTERNAL_ACL_)
27 #include "../access_control/ACLManager.h"
29 using namespace conv::acl_manager;
31 #include <rdm_iface.h>
36 struct app_control_cb_info_s {
38 iotcon_request_h request_handle;
41 struct response_cb_info_s {
43 conv::Request* requestObj;
46 static int get_req_id()
48 static int req_id = 0;
57 static std::map<long long, app_control_cb_info_s> app_control_cb_map;
58 static std::map<int, response_cb_info_s> response_cb_map;
59 static std::map<std::string, guint> dbus_listener_info_map;
61 static void vconf_update_cb(keynode_t *node, void* user_data)
63 conv::RemoteAppControlServiceProvider* instance = static_cast<conv::RemoteAppControlServiceProvider*>(user_data);
64 IF_FAIL_VOID_TAG(instance, _E, "static_cast failed");
66 instance->handleVconfUpdate(node);
69 conv::RemoteAppControlServiceProvider::RemoteAppControlServiceProvider()
71 __type = CONV_SERVICE_TYPE_REMOTE_APP_CONTROL;
72 __resourceType = CONV_RESOURCE_TYPE_REMOTE_APP_CONTROL;
73 __uri = CONV_URI_REMOTE_APP_CONTROL;
74 iotcon_resource = NULL;
76 if (conv::util::isServiceActivated()) {
77 __activationState = 1;
79 __activationState = 0;
82 vconf_notify_key_changed(VCONFKEY_SETAPPL_D2D_CONVERGENCE_SERVICE, vconf_update_cb, this);
83 #if !defined(_D2D_INTERNAL_ACL_)
84 int error = rdm_init();
85 if (error != RDM_ERROR_SUCCESS)
86 _E("rdm init error : %d", error);
90 conv::RemoteAppControlServiceProvider::~RemoteAppControlServiceProvider()
92 app_control_cb_map.clear();
93 response_cb_map.clear();
94 dbus_listener_info_map.clear();
96 #if !defined(_D2D_INTERNAL_ACL_)
97 int error = rdm_deinit();
98 if (error != RDM_ERROR_SUCCESS)
99 _E("rdm deinit error : %d", error);
103 int conv::RemoteAppControlServiceProvider::handleVconfUpdate(keynode_t *node)
105 int current_state = vconf_keynode_get_int(node);
107 if (current_state > 0) {
108 __activationState = 1;
111 __activationState = 0;
115 return CONV_ERROR_NONE;
118 static int _send_response(iotcon_request_h request, iotcon_representation_h repr,
119 iotcon_response_result_e result)
122 iotcon_response_h response;
124 ret = iotcon_response_create(request, &response);
125 if (IOTCON_ERROR_NONE != ret) {
126 _E("iotcon_response_create() Fail(%d)", ret);
127 return CONV_ERROR_INVALID_OPERATION;
130 ret = iotcon_response_set_result(response, result);
131 if (IOTCON_ERROR_NONE != ret) {
132 _E("iotcon_response_set_result() Fail(%d)", ret);
133 iotcon_response_destroy(response);
134 return CONV_ERROR_INVALID_OPERATION;
137 ret = iotcon_response_set_representation(response, repr);
138 if (IOTCON_ERROR_NONE != ret) {
139 _E("iotcon_response_set_representation() Fail(%d)", ret);
140 iotcon_response_destroy(response);
141 return CONV_ERROR_INVALID_OPERATION;
144 /* send Representation to the client */
145 ret = iotcon_response_send(response);
146 if (IOTCON_ERROR_NONE != ret) {
147 _E("iotcon_response_send() Fail(%d)", ret);
148 iotcon_response_destroy(response);
149 return CONV_ERROR_INVALID_OPERATION;
152 iotcon_response_destroy(response);
154 return CONV_ERROR_NONE;
157 static int sendResponse(conv::Json payload, const char* request_type, conv_error_e error, conv::Request* requestObj)
159 _D(RED("publishing_response"));
160 IF_FAIL_RETURN_TAG(requestObj != NULL, CONV_ERROR_INVALID_OPERATION, _E, "listener_cb is not registered");
163 conv::Json description = requestObj->getDescription();
165 payload.set(NULL, CONV_JSON_RESULT_TYPE, request_type);
167 result.set(NULL, CONV_JSON_DESCRIPTION, description);
168 result.set(NULL, CONV_JSON_PAYLOAD, payload);
169 requestObj->publish(error, result, 0, NULL);
171 return CONV_ERROR_NONE;
174 //callback function handles app control reply callback from callee application
175 static void _app_control_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
177 _D("app control reply received");
179 long long reply_id = (long long)user_data;
181 std::map<long long, app_control_cb_info_s>::iterator find_iter = app_control_cb_map.find(reply_id);
183 IF_FAIL_VOID_TAG(find_iter != app_control_cb_map.end(), _E, "No reply data");
185 app_control_cb_info_s cb_info = find_iter->second;
188 bundle* p_bundle_request;
189 iotcon_representation_h rep;
190 iotcon_representation_create(&rep);
191 iotcon_attributes_h attributes;
192 iotcon_attributes_create(&attributes);
194 app_control_export_as_bundle(reply, &p_bundle);
195 app_control_export_as_bundle(request, &p_bundle_request);
197 bundle_raw* p_bundle_raw;
198 bundle_raw* p_bundle_request_raw;
200 int len, len_request;
201 bundle_encode(p_bundle, &p_bundle_raw, &len);
202 char* bundle_raw = reinterpret_cast<char*>(p_bundle_raw);
204 bundle_encode(p_bundle_request, &p_bundle_request_raw, &len_request);
205 char* bundle_request_raw = reinterpret_cast<char*>(p_bundle_request_raw);
207 iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL_REPLY, bundle_raw);
208 iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL_REQUEST, bundle_request_raw);
209 iotcon_attributes_add_int(attributes, CONV_JSON_REQ_ID, cb_info.req_id);
210 iotcon_attributes_add_int(attributes, CONV_JSON_APP_CONTROL_RESULT, result);
212 iotcon_representation_set_attributes(rep, attributes);
214 _D("Send response to sender");
215 _send_response(cb_info.request_handle, rep, IOTCON_RESPONSE_OK);
218 iotcon_attributes_destroy(attributes);
219 iotcon_representation_destroy(rep);
221 bundle_free(p_bundle);
222 bundle_free(p_bundle_request);
223 app_control_cb_map.erase(find_iter);
226 #if !defined(_D2D_INTERNAL_ACL_)
227 static void __acl_state_callback(void *userdata, const rdm_device_s* pRdmDevice)
229 IF_FAIL_VOID_TAG(pRdmDevice, _E, "pRdmDevice is NULL");
230 _D("macAddress:%s aclState:%d", pRdmDevice->wifiMac, pRdmDevice->status);
232 conv::RemoteAppControlAclRequestInfo *aclInfo = reinterpret_cast<conv::RemoteAppControlAclRequestInfo*>(userdata);
235 IF_FAIL_VOID_TAG(aclInfo, _E, "aclInfo casting failed");
237 switch (pRdmDevice->status)
239 case RDM_STATUS_ALLOW: // permitted
241 policy = CONV_ACCESS_CONTROL_PERMITTED;
244 case RDM_STATUS_DENY: // denied
246 policy = CONV_ACCESS_CONTROL_DENIED;
249 case RDM_STATUS_UNDECIDED: // undecided
251 policy = CONV_ACCESS_CONTROL_DENIED;
254 case RDM_STATUS_REMOVED: // device removed
255 _D("Device Removed");
256 policy = CONV_ACCESS_CONTROL_DENIED;
260 policy = CONV_ACCESS_CONTROL_DENIED;
264 iotcon_response_result_e result;
265 result = IOTCON_RESPONSE_OK;
267 iotcon_representation_h representation;
268 iotcon_representation_create(&representation);
269 iotcon_attributes_h attributes;
270 iotcon_attributes_create(&attributes);
272 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_RESULT, (char*)policy.c_str());
274 iotcon_representation_set_attributes(representation, attributes);
276 _send_response(aclInfo->request, representation, result);
278 iotcon_attributes_destroy(attributes);
279 iotcon_representation_destroy(representation);
281 rdm_callback_deregister(aclInfo->aclHandler);
288 static int __access_control(iotcon_request_h request, iotcon_attributes_h attributes)
290 _D("Access Request Handling");
295 int ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_NAME, &deviceName);
296 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
299 ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_TYPE, &deviceType);
300 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
303 ret = iotcon_request_get_host_address(request, &hostAddress);
304 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_request_get_host_address() Fail(%d)", ret);
306 string hostAddressString(hostAddress);
307 string ip = conv::util::getIpAddress(hostAddressString);
309 char macAddress[127] = {0, };
311 IF_FAIL_RETURN_TAG(conv::util::getPeerMac(ip, -1, macAddress), CONV_ERROR_INVALID_PARAMETER, _E, "getPeerMac failed");
313 _D("Device Name : %s, Device IP : %s, Mac : %s, DeviceType : %s", deviceName, ip.c_str(), macAddress, deviceType);
315 char *access_request_type = NULL;
316 ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, &access_request_type);
317 _D("Access Request : %s", access_request_type);
318 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
320 if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, access_request_type)) {
321 #if defined(_D2D_INTERNAL_ACL_)
322 ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
323 #if defined(_TV_) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_TV)
324 _D("Internal ACL for Odroid.");
325 acManagerPolicy = ACMANAGER_POLICY_P;
327 _D("Internal ACL for Mobile & Wearable.");
328 IF_FAIL_RETURN_TAG(AddACLDevice(macAddress, deviceName, ip.c_str(), &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "AddACLDevice failed");
330 if (acManagerPolicy == ACMANAGER_POLICY_P) {
332 policy = CONV_ACCESS_CONTROL_PERMITTED;
333 } else if (acManagerPolicy == ACMANAGER_POLICY_D) {
335 policy = CONV_ACCESS_CONTROL_DENIED;
336 } else if (acManagerPolicy == ACMANAGER_POLICY_U) {
338 policy = CONV_ACCESS_CONTROL_DENIED;
339 } else if (acManagerPolicy == ACMANAGER_POLICY_U2) {
341 conv::acl_manager::LaunchPasskeyShowPopup(deviceName);
342 policy = CONV_ACCESS_CONTROL_PASSKEY_REQUEST;
344 _D("acManagerPolicy:%d", acManagerPolicy);
346 rdm_device_s rdmDevice;
347 IF_FAIL_RETURN_TAG(rdm_init_device(&rdmDevice, deviceName, NULL, macAddress, NULL, RDM_DEVICE_TYPE_PHONE, RDM_DEVICE_ICON_PHONE_DEFAULT) == RDM_ERROR_SUCCESS, CONV_ERROR_INVALID_OPERATION, _E, "rdm_init_device failed");
349 ret = rdm_request_access(&rdmDevice);
351 if (ret == RDM_ERROR_SUCCESS) {
353 policy = CONV_ACCESS_CONTROL_PERMITTED;
354 } else if (ret == RDM_ERROR_DEVICE_IS_DENIED) {
356 policy = CONV_ACCESS_CONTROL_DENIED;
357 } else if (ret == RDM_ERROR_INPROGRESS){
359 conv::RemoteAppControlAclRequestInfo *aclRequest = new(std::nothrow) conv::RemoteAppControlAclRequestInfo();
360 aclRequest->request = request;
361 if (rdm_callback_register(__acl_state_callback, aclRequest, &aclRequest->aclHandler) == RDM_ERROR_SUCCESS) {
362 _D("Register callback for ACL");
363 return CONV_ERROR_NONE;
365 _D("Register callback failed");
366 policy = CONV_ACCESS_CONTROL_DENIED;
369 _D("rdm_request_access:%d", ret);
371 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_RESPONSE, access_request_type)) {
372 #if defined(_D2D_INTERNAL_ACL_)
374 ret = iotcon_attributes_get_str(attributes, CONV_JSON_PASSKEY, &input_passkey);
375 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
377 ret = conv::acl_manager::PasskeyChecker(input_passkey);
378 if (ret == ACLResult_OK) {
379 policy = CONV_ACCESS_CONTROL_PASSKEY_RIGHT;
380 conv::acl_manager::SetDeviceInfoAndACL(macAddress, deviceType, deviceName, ip.c_str(), ACMANAGER_POLICY_P);
381 conv::acl_manager::LaunchAccessAllowedToast(deviceName);
382 } else if (ret == ACLResult_Error) {
383 policy = CONV_ACCESS_CONTROL_PASSKEY_WRONG;
384 } else if (ret == ACLResult_Close) {
385 policy = CONV_ACCESS_CONTROL_PASSKEY_REJECTED;
388 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_CANCEL, access_request_type)) {
389 #if defined(_D2D_INTERNAL_ACL_)
390 _D("Access Cancel Handling");
391 policy = CONV_ACCESS_CONTROL_DENIED;
392 conv::acl_manager::LaunchPopupCancelToast();
396 iotcon_response_result_e result;
397 result = IOTCON_RESPONSE_OK;
399 iotcon_representation_h representation;
400 iotcon_representation_create(&representation);
401 iotcon_attributes_h attributesReply;
402 iotcon_attributes_create(&attributesReply);
404 iotcon_attributes_add_str(attributesReply, CONV_JSON_ACCESS_REQUEST_RESULT, (char*)policy.c_str());
406 iotcon_representation_set_attributes(representation, attributesReply);
408 _send_response(request, representation, result);
410 iotcon_attributes_destroy(attributesReply);
411 iotcon_representation_destroy(representation);
413 return CONV_ERROR_NONE;
416 static int __app_control_launch(iotcon_request_h request, iotcon_attributes_h attributes)
420 int ret = iotcon_request_get_host_address(request, &hostAddress);
421 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_request_get_host_address() Fail(%d)", ret);
422 string hostAddressString(hostAddress);
423 string ip = conv::util::getIpAddress(hostAddressString);
425 char macAddress[127] = {0, };
426 IF_FAIL_RETURN_TAG(conv::util::getPeerMac(ip, -1, macAddress), CONV_ERROR_INVALID_PARAMETER, _E, "getPeerMac failed");
428 _D("Device IP : %s, Mac : %s", ip.c_str(), macAddress);
430 #if defined(_D2D_INTERNAL_ACL_)
431 ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
432 #if defined(_TV_) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_TV)
433 _D("Internal ACL for Odroid.");
434 acManagerPolicy = ACMANAGER_POLICY_P;
436 _D("Internal ACL for Mobile & Wearable.");
437 IF_FAIL_RETURN_TAG(GetACLState(macAddress, &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "ACL check failed");
439 if (acManagerPolicy == ACMANAGER_POLICY_P) {
442 _D("Device is not permitted %d", acManagerPolicy);
443 return CONV_ERROR_INVALID_OPERATION;
446 rdm_status_e eStatus = RDM_STATUS_NONE;
447 ret = rdm_get_status(macAddress, RDM_TECH_IND_WIFI, &eStatus);
449 if (ret == RDM_ERROR_SUCCESS) {
450 if (eStatus == RDM_STATUS_ALLOW) {
453 _D("Device is not permitted %d", eStatus);
454 return CONV_ERROR_INVALID_OPERATION;
456 } else if (ret == RDM_ERROR_DEVICE_NOT_FOUND) {
457 _D("Device is not found");
458 return CONV_ERROR_INVALID_OPERATION;
460 _D("rdm_get_status failed (%d)", ret);
461 return CONV_ERROR_INVALID_OPERATION;
464 iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
465 app_control_h app_control;
469 ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL, &appctl_char);
470 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
472 bundle_raw* encoded = reinterpret_cast<unsigned char*>(appctl_char);
473 bundle* appctl_bundle = bundle_decode(encoded, strlen(appctl_char));
475 app_control_create(&app_control);
476 app_control_import_from_bundle(app_control, appctl_bundle);
478 iotcon_attributes_get_int(attributes, CONV_JSON_REPLY, &reply);
481 bool waiting_reply = false;
483 // check if it's already launched and waiting for app_control response
484 for(std::map<long long, app_control_cb_info_s>::iterator it = app_control_cb_map.begin(); it != app_control_cb_map.end(); it++) {
485 app_control_cb_info_s found_cb_info = it->second;
486 if(found_cb_info.request_handle == request) {
487 waiting_reply = true;
488 _D("app_control_send_launch_request is already called...waiting reply");
493 if (!waiting_reply) {
494 long long reply_id = get_req_id();
496 app_control_cb_info_s cb_info;
497 cb_info.req_id = req_id;
498 cb_info.request_handle = request;
499 app_control_cb_map[reply_id] = cb_info;
501 ret = app_control_send_launch_request(app_control, _app_control_cb, (void*)reply_id);
502 _D("app_control_send_launch_request with callback");
504 if (ret != APP_CONTROL_ERROR_NONE) {
505 _E("Launch request failed(%d)", ret);
506 iotcon_response_result_e result = IOTCON_RESPONSE_ERROR;
507 iotcon_attributes_h attr;
508 iotcon_representation_h rep;
509 iotcon_attributes_create(&attr);
510 iotcon_attributes_add_int(attr, CONV_JSON_REQ_ID, req_id);
511 iotcon_representation_create(&rep);
512 iotcon_representation_set_attributes(rep, attr);
513 _send_response(request, rep, result);
514 iotcon_representation_destroy(rep);
515 iotcon_attributes_destroy(attr);
516 app_control_cb_map.erase(reply_id);
520 bundle_free(appctl_bundle);
521 app_control_destroy(app_control);
523 _D("no waiting for reply. send response immediately");
524 iotcon_response_result_e result;
525 ret = app_control_send_launch_request(app_control, NULL, NULL);
527 if (ret != APP_CONTROL_ERROR_NONE) {
528 _E("Launch request failed(%d)", ret);
529 result = IOTCON_RESPONSE_ERROR;
531 _D("Launch request succeeded");
532 result = IOTCON_RESPONSE_OK;
534 bundle_free(appctl_bundle);
535 app_control_destroy(app_control);
537 iotcon_attributes_h attr;
538 iotcon_representation_h rep;
539 iotcon_attributes_create(&attr);
540 iotcon_attributes_add_int(attr, CONV_JSON_REQ_ID, req_id);
541 iotcon_representation_create(&rep);
542 iotcon_representation_set_attributes(rep, attr);
543 _send_response(request, rep, result);
544 iotcon_representation_destroy(rep);
545 iotcon_attributes_destroy(attr);
548 return CONV_ERROR_NONE;
551 //callback function handles put command for remote-app-control resource
552 static int __handle_request(iotcon_representation_h rep, iotcon_request_h request)
554 iotcon_attributes_h attributes;
557 int ret = iotcon_representation_get_attributes(rep, &attributes);
558 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
560 // Handles Access Request
561 ret = iotcon_attributes_get_str(attributes, CONV_JSON_REQUEST_TYPE, &requestType);
562 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
564 if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, requestType)) {
565 return __access_control(request, attributes);
566 } else if (!strcmp(CONV_LAUNCH_REQUEST, requestType)) {
567 return __app_control_launch(request, attributes);
570 return CONV_ERROR_INVALID_PARAMETER;
573 //callback function handles requests for remote-app-control resource
574 void conv::RemoteAppControlServiceProvider::__iotcon_request_cb(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
576 _D("request cb called");
579 iotcon_request_type_e type;
582 iotcon_representation_h reqRep = NULL;
584 IF_FAIL_VOID_TAG(request, _E, "request is NULL");
586 ret = iotcon_request_get_representation(request, &reqRep);
587 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_representation() Failed(%d)", ret);
589 ret = iotcon_request_get_host_address(request, &hostAddress);
590 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_request_get_host_address() Failed(%d)", ret);
592 _I("host_address : %s", hostAddress);
594 ret = iotcon_request_get_request_type(request, &type);
595 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_request_get_request_type() Failed(%d)", ret);
596 _D("request type : %d", type);
598 if (IOTCON_REQUEST_PUT == type) {
600 IF_FAIL_CATCH_TAG(__handle_request(reqRep, request) == CONV_ERROR_NONE, _E, "__handle_request() Failed(%d)", ret);
604 iotcon_representation_destroy(reqRep);
611 iotcon_attributes_h attributes = NULL;
612 iotcon_representation_h responseRep = NULL;
613 iotcon_representation_create(&responseRep);
614 iotcon_attributes_h responseAttributes = NULL;
615 iotcon_attributes_create(&responseAttributes);
617 if (reqRep != NULL) {
618 ret = iotcon_representation_get_attributes(reqRep, &attributes);
619 if (ret == IOTCON_ERROR_NONE) {
620 iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
624 iotcon_attributes_add_int(responseAttributes, CONV_JSON_REQ_ID, req_id);
625 iotcon_representation_set_attributes(responseRep, responseAttributes);
627 _send_response(request, responseRep, IOTCON_RESPONSE_ERROR);
630 iotcon_attributes_destroy(attributes);
633 if (responseAttributes) {
634 iotcon_attributes_destroy(responseAttributes);
635 responseAttributes = NULL;
638 iotcon_representation_destroy(reqRep);
642 iotcon_representation_destroy(responseRep);
647 int conv::RemoteAppControlServiceProvider::init()
649 if (iotcon_resource == NULL) {
652 iotcon_resource_interfaces_h resource_ifaces = NULL;
653 iotcon_resource_types_h resource_types = NULL;
656 properties = IOTCON_RESOURCE_NO_POLICY;
658 error = iotcon_resource_types_create(&resource_types);
659 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "rt creation failed");
661 iotcon_resource_types_add(resource_types, __resourceType.c_str());
663 error = iotcon_resource_interfaces_create(&resource_ifaces);
664 IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
666 iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
668 error = iotcon_resource_create(CONV_URI_REMOTE_APP_CONTROL, resource_types, resource_ifaces, properties, __iotcon_request_cb, NULL, &iotcon_resource);
669 IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "resource creation failed");
671 _D("RemoteAppControlServiceProvider init done");
673 iotcon_resource_types_destroy(resource_types);
674 iotcon_resource_interfaces_destroy(resource_ifaces);
675 IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
678 _D("RemoteAppControlServiceProvider is already initiated");
681 return CONV_ERROR_NONE;
684 int conv::RemoteAppControlServiceProvider::release()
686 if (iotcon_resource == NULL) {
687 _D("RemoteAppControlServiceProvider is already released");
689 // unregister resource
690 int error = iotcon_resource_destroy(iotcon_resource);
691 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource destroy failed");
692 iotcon_resource = NULL;
693 _D("RemoteAppControlServiceProvider release done");
696 return CONV_ERROR_NONE;
699 static void passkey_popup_callback(void *user_data, int result, char *passkey);
701 //callback function handles reply from access control request
702 static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error_e err,
703 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
705 _D("__on_access_response called");
707 iotcon_response_result_e response_result;
708 iotcon_representation_h repr;
711 _D("response is NULL");
715 conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
717 ret = iotcon_response_get_result(response, &response_result);
718 if (IOTCON_ERROR_NONE != ret) {
719 _E("iotcon_response_get_result() Fail(%d)", ret);
721 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
725 if (IOTCON_RESPONSE_RESOURCE_CHANGED != response_result) {
726 _E("_on_response_observe Response error(%d)", response_result);
728 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
732 ret = iotcon_response_get_representation(response, &repr);
734 char* accessControlResult;
735 iotcon_attributes_h attributes;
736 iotcon_representation_get_attributes(repr, &attributes);
737 ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_RESULT, &accessControlResult);
738 if (IOTCON_ERROR_NONE != ret) {
739 _E("iotcon_attributes_get_str() Fail(%d)", ret);
741 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
745 if (!strcmp(CONV_ACCESS_CONTROL_PERMITTED, accessControlResult)) {
746 _D("__on_access_response PERMITTED");
748 svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED;
749 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
751 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_REQUEST, accessControlResult)) {
752 #if defined(_D2D_INTERNAL_ACL_)
753 _D("__on_access_response PASSKEY REQUEST");
754 conv::acl_manager::LaunchPasskeyInputPopup(passkey_popup_callback, svcInfo);
757 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_RIGHT, accessControlResult)) {
758 #if defined(_D2D_INTERNAL_ACL_)
759 _D("__on_access_response PASSKEY RIGHT");
760 conv::acl_manager::LaunchAccessAllowedToast((char*)svcInfo->deviceName.c_str());
762 svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED;
763 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
766 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_WRONG, accessControlResult)) {
767 #if defined(_D2D_INTERNAL_ACL_)
768 _D("__on_access_response PASSKEY WRONG");
769 conv::acl_manager::LaunchPasskeyWrongToast();
772 } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_REJECTED, accessControlResult)) {
773 #if defined(_D2D_INTERNAL_ACL_)
774 _D("__on_access_response PASSKEY REJECTED");
775 conv::acl_manager::LaunchAccessRejectedToast();
777 svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED;
778 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
782 _D("__on_access_response DENIED");
784 svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED;
785 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
790 #if defined(_D2D_INTERNAL_ACL_)
791 static void passkey_popup_callback(void *user_data, int result, char *passkey)
793 conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
795 iotcon_representation_h representation;
796 iotcon_representation_create(&representation);
798 iotcon_attributes_h attributes;
799 iotcon_attributes_create(&attributes);
801 if (result == ACLResult_Cancel) {
802 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
803 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSKEY_CANCEL);
804 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
805 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
807 } else if (result == ACLResult_Connect) {
808 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
809 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSKEY_RESPONSE);
810 iotcon_attributes_add_str(attributes, CONV_JSON_PASSKEY, passkey);
811 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
812 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
815 iotcon_representation_set_attributes(representation, attributes);
816 svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
817 iotcon_attributes_destroy(attributes);
819 iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo);
823 static int stop_request(conv::Request* requestObj);
825 static void _dbusDisconnectListenerFreeCallback(gpointer userData)
827 _D(RED("_dbusDisconnectListenerFreeCallback"));
829 conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
830 if (_requestObj == NULL) {
838 static void _dbusDisconnectListener(GDBusConnection* conn, const gchar* sender, const gchar* path, const gchar* iface, const gchar* name, GVariant* param, gpointer userData)
840 conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
842 char* disconnectName;
843 g_variant_get_child(param, 0, "&s", &disconnectName);
845 if (_requestObj == NULL) {
846 _E("requestObj is NULL");
850 if (!strcmp(disconnectName, _requestObj->getSender())) {
851 _D("Detected the dbus disconnection.");
852 _requestObj->setIsConnect(false);
854 conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(_requestObj->getServiceInfo());
856 if (svcInfo->registeredRequest != NULL) {
857 delete svcInfo->registeredRequest;
858 svcInfo->registeredRequest = NULL;
861 stop_request(_requestObj);
865 std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
866 iter = dbus_listener_info_map.find(_requestObj->getSender());
868 if (iter != dbus_listener_info_map.end()) {
869 guint listener_id = reinterpret_cast<guint>(iter->second);
870 dbus_listener_info_map.erase(iter);
872 if (_requestObj->getInvocation() != NULL) {
873 g_dbus_connection_signal_unsubscribe(conn, listener_id);
874 _D("Delete dbus disconnect listener.");
876 _E("requestObj invocation is NULL");
880 _D("Not found dbus disconnect listener.");
884 static void registDbusDisconnectListener(conv::Request* requestObj)
886 std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
887 iter = dbus_listener_info_map.find(requestObj->getSender());
889 if (iter != dbus_listener_info_map.end()) {
890 guint listener_id = reinterpret_cast<guint>(iter->second);
891 dbus_listener_info_map.erase(iter);
893 GDBusConnection *conn = g_dbus_method_invocation_get_connection(requestObj->getInvocation());
894 g_dbus_connection_signal_unsubscribe(conn, listener_id);
895 _D("Delete dbus disconnect listener.");
898 conv::Request *_requestObj = requestObj->clone();
899 GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
900 guint listener_id = g_dbus_connection_signal_subscribe(conn, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus",
901 _requestObj->getSender(), G_DBUS_SIGNAL_FLAGS_NONE, _dbusDisconnectListener, _requestObj, _dbusDisconnectListenerFreeCallback);
903 if (listener_id == 0) {
904 _E("Dbus signal listener registration failed.");
908 dbus_listener_info_map[_requestObj->getSender()] = listener_id;
909 _D("Subscribe the dbus signal. id = %d", listener_id);
913 int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
915 _D("communcation/start requested");
921 iotcon_resource_interfaces_h resource_ifaces = NULL;
922 iotcon_resource_types_h resource_types = NULL;
924 RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
926 if (svcInfo->iotconInfoObj.iotconResourceHandle != NULL) {
927 _D("already started");
928 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
929 return CONV_ERROR_INVALID_OPERATION;
932 properties = IOTCON_RESOURCE_NO_POLICY;
934 error = iotcon_resource_types_create(&resource_types);
935 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "rt creation failed");
937 iotcon_resource_types_add(resource_types, svcInfo->iotconInfoObj.resourceType.c_str());
939 error = iotcon_resource_interfaces_create(&resource_ifaces);
940 IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
942 iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
944 error = iotcon_remote_resource_create(svcInfo->iotconInfoObj.address.c_str(), IOTCON_CONNECTIVITY_IP, svcInfo->iotconInfoObj.uri.c_str(), properties, resource_types, resource_ifaces,
945 &(svcInfo->iotconInfoObj.iotconResourceHandle));
947 _D("remote resource created : %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
948 IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
950 registDbusDisconnectListener(requestObj);
953 iotcon_resource_types_destroy(resource_types);
954 iotcon_resource_interfaces_destroy(resource_ifaces);
955 IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
957 //send message for access request
958 iotcon_representation_h representation;
959 iotcon_representation_create(&representation);
960 iotcon_attributes_h attributes;
961 iotcon_attributes_create(&attributes);
963 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
964 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
965 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
966 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
968 iotcon_representation_set_attributes(representation, attributes);
969 svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
971 iotcon_attributes_destroy(attributes);
973 error = iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo);
975 return CONV_ERROR_NONE;
978 int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
980 _D("communcation/stop requested");
981 return stop_request(requestObj);
984 static int stop_request(conv::Request* requestObj)
987 conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
989 if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
990 _D("not even started");
991 sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
992 return CONV_ERROR_INVALID_OPERATION;
995 iotcon_remote_resource_destroy(svcInfo->iotconInfoObj.iotconResourceHandle);
996 svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
998 sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
999 return CONV_ERROR_NONE;
1002 int conv::RemoteAppControlServiceProvider::checkStateRequest(Request* requestObj)
1004 _D("communcation/check_state requested");
1006 RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
1008 if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
1010 return CONV_ERROR_INVALID_OPERATION;
1013 return CONV_ERROR_NONE;
1017 int conv::RemoteAppControlServiceProvider::readRequest(Request* requestObj)
1019 return CONV_ERROR_NONE;
1022 //callback function handles reply from publish request
1023 static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
1024 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
1027 int appcontrol_result = -1;
1028 iotcon_response_result_e response_result;
1029 iotcon_representation_h repr;
1030 char* appctl_char = NULL;
1031 char* appctl_request_char = NULL;
1032 int appctl_result = -1;
1034 iotcon_attributes_h attributes;
1035 std::map<int, response_cb_info_s>::iterator find_iter = response_cb_map.end();
1036 response_cb_info_s cb_info;
1037 cb_info.requestObj = NULL;
1040 _D("response is NULL");
1044 ret = iotcon_response_get_representation(response, &repr);
1045 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_representation() Failed(%d)", ret);
1047 iotcon_representation_get_attributes(repr, &attributes);
1048 ret = iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
1049 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_attributes_get_int() Failed(%d)", ret);
1051 find_iter = response_cb_map.find(req_id);
1052 IF_FAIL_CATCH_TAG(find_iter != response_cb_map.end(), _E, "No callback found for response");
1053 cb_info = find_iter->second;
1055 ret = iotcon_response_get_result(response, &response_result);
1056 IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_result() Failed(%d)", ret);
1057 IF_FAIL_CATCH_TAG(response_result == IOTCON_RESPONSE_RESOURCE_CHANGED, _E, "not response of PUT method(%d)", response_result);
1059 ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL_REPLY, &appctl_char);
1060 if (IOTCON_ERROR_NONE != ret) {
1061 _E("iotcon_attributes_get_str() Fail(%d)", ret);
1064 ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL_REQUEST, &appctl_request_char);
1065 if (IOTCON_ERROR_NONE != ret) {
1066 _E("iotcon_attributes_get_str() Fail(%d)", ret);
1069 appcontrol_result = iotcon_attributes_get_int(attributes, CONV_JSON_APP_CONTROL_RESULT, &appctl_result);
1070 if (IOTCON_ERROR_NONE != appcontrol_result) {
1071 _E("iotcon_attributes_get_int() Fail(%d)", appcontrol_result);
1074 _D(RED("publishing_response"));
1075 if (cb_info.requestObj) {
1078 conv::Json description;
1080 string resultStr = to_string(appctl_result);
1081 payload.set(NULL, CONV_JSON_RESULT_TYPE, CONV_JSON_ON_PUBLISH);
1083 payload.set(NULL, CONV_JSON_APP_CONTROL_REPLY, appctl_char);
1085 if (appctl_request_char) {
1086 payload.set(NULL, CONV_JSON_APP_CONTROL_REQUEST, appctl_request_char);
1088 if (appcontrol_result == IOTCON_ERROR_NONE) {
1089 payload.set(NULL, CONV_JSON_APP_CONTROL_RESULT, resultStr.c_str());
1091 description = cb_info.requestObj->getDescription();
1092 result.set(NULL, CONV_JSON_DESCRIPTION, description);
1093 result.set(NULL, CONV_JSON_PAYLOAD, payload);
1095 cb_info.requestObj->publish(CONV_ERROR_NONE, result, 0, NULL);
1096 _D("response published");
1098 _D("request obj is NULL");
1100 if (find_iter != response_cb_map.end()) {
1101 response_cb_map.erase(find_iter);
1105 if (cb_info.requestObj) {
1108 conv::Json description;
1110 string resultStr = to_string(appctl_result);
1111 payload.set(NULL, CONV_JSON_RESULT_TYPE, CONV_JSON_ON_PUBLISH);
1113 payload.set(NULL, CONV_JSON_APP_CONTROL_REPLY, appctl_char);
1115 if (appctl_request_char) {
1116 payload.set(NULL, CONV_JSON_APP_CONTROL_REQUEST, appctl_request_char);
1119 description = cb_info.requestObj->getDescription();
1120 result.set(NULL, CONV_JSON_DESCRIPTION, description);
1121 result.set(NULL, CONV_JSON_PAYLOAD, payload);
1123 cb_info.requestObj->publish(CONV_ERROR_INVALID_OPERATION, result, 0, NULL);
1124 _D("response error published");
1126 _D("request obj is NULL");
1128 if (find_iter != response_cb_map.end()) {
1129 response_cb_map.erase(find_iter);
1134 int conv::RemoteAppControlServiceProvider::publishRequest(Request* requestObj)
1136 RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
1139 IF_FAIL_RETURN_TAG(svcInfo->accessControlState == ACCESS_CONTROL_STATE_PERMITTED, CONV_ERROR_INVALID_OPERATION, _E, "Access to device is not permitted");
1141 requestObj->setCommunicationInfo(&(svcInfo->iotconInfoObj));
1143 iotcon_representation_h representation;
1144 iotcon_representation_create(&representation);
1147 requestObj->getPayloadFromDescription(&payload);
1152 payload.get(NULL, CONV_JSON_APP_CONTROL, &app_control);
1153 payload.get(NULL, CONV_JSON_REPLY, &reply);
1155 iotcon_attributes_h attributes;
1156 iotcon_attributes_create(&attributes);
1158 char* appControl = new char[app_control.size() + 1];
1160 memset(appControl, 0, app_control.size() + 1);
1161 strncpy(appControl, app_control.c_str(), app_control.size()+1);
1163 iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL, appControl);
1164 iotcon_attributes_add_int(attributes, CONV_JSON_REPLY, reply);
1165 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char *)CONV_LAUNCH_REQUEST);
1167 delete[] appControl;
1169 int req_id = get_req_id();
1170 iotcon_attributes_add_int(attributes, CONV_JSON_REQ_ID, req_id);
1172 response_cb_info_s cb_info;
1173 cb_info.req_id = req_id;
1174 cb_info.requestObj = svcInfo->registeredRequest;
1175 response_cb_map[req_id] = cb_info;
1177 iotcon_representation_set_attributes(representation, attributes);
1178 svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
1180 iotcon_attributes_destroy(attributes);
1182 error = iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_response, NULL);
1184 if (error != IOTCON_ERROR_NONE) {
1185 _E("iotcon_remote_resource_put failed");
1186 response_cb_map.erase(req_id);
1188 sendResponse(result, CONV_JSON_ON_PUBLISH, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
1189 return CONV_ERROR_INVALID_OPERATION;
1192 return CONV_ERROR_NONE;
1195 int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
1197 _D("communcation/recv requested");
1198 RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
1200 switch (requestObj->getType()) {
1202 if (svcInfo->registeredRequest != NULL) {
1203 for (std::map<int, response_cb_info_s>::iterator it = response_cb_map.begin(); it != response_cb_map.end(); ++it) {
1204 if (((response_cb_info_s)it->second).requestObj == svcInfo->registeredRequest) {
1205 response_cb_info_s cbInfo;
1206 cbInfo.req_id = ((response_cb_info_s)it->second).req_id;
1207 cbInfo.requestObj = requestObj;
1209 it->second = cbInfo;
1212 delete svcInfo->registeredRequest;
1214 svcInfo->registeredRequest = requestObj;
1215 requestObj->reply(CONV_ERROR_NONE);
1216 _D("subscribe requested");
1218 case REQ_UNSUBSCRIBE:
1219 for (std::map<int, response_cb_info_s>::iterator it = response_cb_map.begin(); it != response_cb_map.end(); ++it) {
1220 if (((response_cb_info_s)it->second).requestObj == svcInfo->registeredRequest) {
1221 response_cb_info_s cbInfo;
1222 cbInfo.req_id = ((response_cb_info_s)it->second).req_id;
1223 cbInfo.requestObj = NULL;
1225 it->second = cbInfo;
1228 delete svcInfo->registeredRequest;
1229 svcInfo->registeredRequest = NULL;
1230 requestObj->reply(CONV_ERROR_NONE);
1234 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
1236 return CONV_ERROR_INVALID_OPERATION;
1240 return CONV_ERROR_NONE;
1243 int conv::RemoteAppControlServiceProvider::loadServiceInfo(Request* requestObj)
1246 conv::ClientInfo* clientObj = NULL;
1248 client = requestObj->getSender();
1249 _D("client id : %s", client.c_str());
1250 clientObj = conv::client_manager::getClient(client);
1251 IF_FAIL_RETURN_TAG(clientObj, CONV_ERROR_OUT_OF_MEMORY, _E, "client info alloc failed");
1253 Json description = requestObj->getDescription();
1259 string deviceAddress;
1262 description.get(NULL, CONV_JSON_SERVICE, &service);
1263 description.get(NULL, CONV_JSON_DEVICE, &device);
1265 service.get(NULL, CONV_SERVICE_ID, &uri);
1267 device.get(NULL, CONV_DEVICE_ID, &deviceId);
1268 device.get(NULL, CONV_DEVICE_NAME, &deviceName);
1269 device.get(NULL, CONV_JSON_DEVICE_ADDRESS, &deviceAddress);
1271 RemoteAppControlServiceInfo *svcInfo = NULL;
1272 IServiceInfo* svcInfoBase = clientObj->getServiceInfo(__type, deviceId);
1274 if (svcInfoBase != NULL) {
1275 _D("service instance already exists");
1276 svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(svcInfoBase);
1278 _D("allocating new service instance");
1279 svcInfo = new(std::nothrow) RemoteAppControlServiceInfo();
1280 IF_FAIL_RETURN_TAG(svcInfo, CONV_ERROR_OUT_OF_MEMORY, _E, "svcInfo alloc failed");
1282 svcInfo->deviceId = deviceId;
1283 svcInfo->deviceName = deviceName;
1284 svcInfo->deviceAddress = deviceAddress;
1286 svcInfo->iotconInfoObj.address = deviceAddress;
1287 svcInfo->iotconInfoObj.uri = CONV_URI_REMOTE_APP_CONTROL;
1288 svcInfo->iotconInfoObj.resourceType = __resourceType;
1289 svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
1292 clientObj->addServiceInfo(__type, deviceId, (IServiceInfo*)svcInfo);
1294 _D("remote app control service is created");
1297 requestObj->setServiceInfo(svcInfo);
1298 return CONV_ERROR_NONE;
1301 int conv::RemoteAppControlServiceProvider::getServiceInfoForDiscovery(Json* jsonObj)
1303 jsonObj->set(NULL, CONV_JSON_DISCOVERY_SERVICE_TYPE, CONV_SERVICE_REMOTE_APP_CONTROL);
1305 // set data for service handle
1307 info.set(NULL, CONV_SERVICE_ID, __uri);
1308 info.set(NULL, CONV_SERVICE_VERSION, "1.0");
1310 jsonObj->set(NULL, CONV_JSON_DISCOVERY_SERVICE_INFO, info);
1312 return CONV_ERROR_NONE;