059b7fe2c5ee2232489dad081f7418a9cb14a875
[platform/core/convergence/d2d-conv-manager.git] / daemon / service_provider / RemoteAppControlServiceProvider.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 <bundle.h>
18 #include <bundle_internal.h>
19 #include <app_control_internal.h>
20 #include "RemoteAppControlServiceProvider.h"
21 #include "../ClientManager.h"
22 #include "../Util.h"
23 #if defined(_D2D_INTERNAL_ACL_)
24 #include "../access_control/ACLManager.h"
25
26 using namespace conv::acl_manager;
27 #else
28 #include <rdm_iface.h>
29 #endif
30
31 using namespace std;
32
33 struct app_control_cb_info_s {
34         int req_id;
35         iotcon_request_h request_handle;
36 };
37
38 struct response_cb_info_s {
39         int req_id;
40         conv::Request* requestObj;
41 };
42
43 static int get_req_id()
44 {
45         static int req_id = 0;
46
47         if (++req_id < 0) {
48                 req_id = 1;
49         }
50
51         return req_id;
52 }
53
54 static std::map<long long, app_control_cb_info_s> app_control_cb_map;
55 static std::map<int, response_cb_info_s> response_cb_map;
56
57 static void vconf_update_cb(keynode_t *node, void* user_data)
58 {
59         conv::RemoteAppControlServiceProvider* instance = static_cast<conv::RemoteAppControlServiceProvider*>(user_data);
60         IF_FAIL_VOID_TAG(instance, _E, "static_cast failed");
61
62         instance->handleVconfUpdate(node);
63 }
64
65 conv::RemoteAppControlServiceProvider::RemoteAppControlServiceProvider()
66 {
67         __type = CONV_SERVICE_TYPE_REMOTE_APP_CONTROL;
68         __resourceType = CONV_RESOURCE_TYPE_REMOTE_APP_CONTROL;
69         __uri = CONV_URI_REMOTE_APP_CONTROL;
70         iotcon_resource = NULL;
71
72         if (conv::util::isServiceActivated()) {
73                 __activationState = 1;
74         } else {
75                 __activationState = 0;
76         }
77
78         vconf_notify_key_changed(VCONFKEY_SETAPPL_D2D_CONVERGENCE_SERVICE, vconf_update_cb, this);
79 #if !defined(_D2D_INTERNAL_ACL_)
80         int error = rdm_init();
81         if (error != RDM_ERROR_SUCCESS)
82                 _E("rdm init error : %d", error);
83 #endif
84 }
85
86 conv::RemoteAppControlServiceProvider::~RemoteAppControlServiceProvider()
87 {
88         app_control_cb_map.clear();
89         response_cb_map.clear();
90
91 #if !defined(_D2D_INTERNAL_ACL_)
92         int error = rdm_deinit();
93         if (error != RDM_ERROR_SUCCESS)
94                 _E("rdm deinit error : %d", error);
95 #endif
96 }
97
98 int conv::RemoteAppControlServiceProvider::handleVconfUpdate(keynode_t *node)
99 {
100         int current_state = vconf_keynode_get_int(node);
101
102         if (current_state > 0) {
103                 __activationState = 1;
104                 init();
105         } else {
106                 __activationState = 0;
107                 release();
108         }
109
110         return CONV_ERROR_NONE;
111 }
112
113 static int _send_response(iotcon_request_h request, iotcon_representation_h repr,
114                 iotcon_response_result_e result)
115 {
116         int ret;
117         iotcon_response_h response;
118
119         ret = iotcon_response_create(request, &response);
120         if (IOTCON_ERROR_NONE != ret) {
121                 _E("iotcon_response_create() Fail(%d)", ret);
122                 return CONV_ERROR_INVALID_OPERATION;
123         }
124
125         ret = iotcon_response_set_result(response, result);
126         if (IOTCON_ERROR_NONE != ret) {
127                 _E("iotcon_response_set_result() Fail(%d)", ret);
128                 iotcon_response_destroy(response);
129                 return CONV_ERROR_INVALID_OPERATION;
130         }
131
132         ret = iotcon_response_set_representation(response, repr);
133         if (IOTCON_ERROR_NONE != ret) {
134                 _E("iotcon_response_set_representation() Fail(%d)", ret);
135                 iotcon_response_destroy(response);
136                 return CONV_ERROR_INVALID_OPERATION;
137         }
138
139         /* send Representation to the client */
140         ret = iotcon_response_send(response);
141         if (IOTCON_ERROR_NONE != ret) {
142                 _E("iotcon_response_send() Fail(%d)", ret);
143                 iotcon_response_destroy(response);
144                 return CONV_ERROR_INVALID_OPERATION;
145         }
146
147         iotcon_response_destroy(response);
148
149         return CONV_ERROR_NONE;
150 }
151
152 static int sendResponse(conv::Json payload, const char* request_type, conv_error_e error, conv::Request* requestObj)
153 {
154         _D(RED("publishing_response"));
155         IF_FAIL_RETURN_TAG(requestObj != NULL, CONV_ERROR_INVALID_OPERATION, _E, "listener_cb is not registered");
156
157         conv::Json result;
158         conv::Json description = requestObj->getDescription();
159
160         payload.set(NULL, CONV_JSON_RESULT_TYPE, request_type);
161
162         result.set(NULL, CONV_JSON_DESCRIPTION, description);
163         result.set(NULL, CONV_JSON_PAYLOAD, payload);
164         requestObj->publish(error, result, 0, NULL);
165
166         return CONV_ERROR_NONE;
167 }
168
169 //callback function handles app control reply callback from callee application
170 static void _app_control_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
171 {
172         _D("app control reply received");
173
174         long long reply_id = (long long)user_data;
175
176         std::map<long long, app_control_cb_info_s>::iterator find_iter = app_control_cb_map.find(reply_id);
177
178         IF_FAIL_VOID_TAG(find_iter != app_control_cb_map.end(), _E, "No reply data");
179
180         app_control_cb_info_s cb_info = find_iter->second;
181
182         bundle* p_bundle;
183         bundle* p_bundle_request;
184         iotcon_representation_h rep;
185         iotcon_representation_create(&rep);
186         iotcon_attributes_h attributes;
187         iotcon_attributes_create(&attributes);
188
189         app_control_export_as_bundle(reply, &p_bundle);
190         app_control_export_as_bundle(request, &p_bundle_request);
191
192         bundle_raw* p_bundle_raw;
193         bundle_raw* p_bundle_request_raw;
194
195         int len, len_request;
196         bundle_encode(p_bundle, &p_bundle_raw, &len);
197         char* bundle_raw = reinterpret_cast<char*>(p_bundle_raw);
198
199         bundle_encode(p_bundle_request, &p_bundle_request_raw, &len_request);
200         char* bundle_request_raw = reinterpret_cast<char*>(p_bundle_request_raw);
201
202         iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL_REPLY, bundle_raw);
203         iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL_REQUEST, bundle_request_raw);
204         iotcon_attributes_add_int(attributes, CONV_JSON_REQ_ID, cb_info.req_id);
205         iotcon_attributes_add_int(attributes, CONV_JSON_APP_CONTROL_RESULT,  result);
206
207         iotcon_representation_set_attributes(rep, attributes);
208
209         _D("Send response to sender");
210         _send_response(cb_info.request_handle, rep, IOTCON_RESPONSE_OK);
211         _D("Response sent");
212
213         bundle_free(p_bundle);
214         bundle_free(p_bundle_request);
215         app_control_cb_map.erase(find_iter);
216 }
217
218 #if !defined(_D2D_INTERNAL_ACL_)
219 static void __acl_state_callback(void *userdata, const rdm_device_s* pRdmDevice)
220 {
221         IF_FAIL_VOID_TAG(pRdmDevice, _E, "pRdmDevice is NULL");
222     _D("macAddress:%s aclState:%d", pRdmDevice->wifiMac, pRdmDevice->status);
223
224     conv::RemoteAppControlAclRequestInfo *aclInfo = reinterpret_cast<conv::RemoteAppControlAclRequestInfo*>(userdata);
225     string policy;
226
227         IF_FAIL_VOID_TAG(aclInfo, _E, "aclInfo casting failed");
228
229     switch (pRdmDevice->status)
230     {
231         case RDM_STATUS_ALLOW: // permitted
232                 _D("Permitted");
233                 policy = CONV_ACCESS_CONTROL_PERMITTED;
234                 break;
235
236         case RDM_STATUS_DENY: // denied
237                 _D("Denied");
238                 policy = CONV_ACCESS_CONTROL_DENIED;
239                 break;
240
241         case RDM_STATUS_UNDECIDED: // undecided
242                 _D("Undecided");
243                 policy = CONV_ACCESS_CONTROL_DENIED;
244                 break;
245
246         case RDM_STATUS_REMOVED: // device removed
247                 _D("Device Removed");
248                 policy = CONV_ACCESS_CONTROL_DENIED;
249                 break;
250         default:
251                 _D("Unknown State");
252                 policy = CONV_ACCESS_CONTROL_DENIED;
253                 break;
254     }
255
256         iotcon_response_result_e result;
257         result = IOTCON_RESPONSE_OK;
258
259         iotcon_representation_h representation;
260         iotcon_representation_create(&representation);
261         iotcon_attributes_h attributes;
262         iotcon_attributes_create(&attributes);
263
264         iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_RESULT, (char*)policy.c_str());
265
266         iotcon_representation_set_attributes(representation, attributes);
267
268         _send_response(aclInfo->request, representation, result);
269
270         iotcon_attributes_destroy(attributes);
271         iotcon_representation_destroy(representation);
272
273         rdm_callback_deregister(aclInfo->aclHandler);
274
275         delete aclInfo;
276 }
277 #endif
278
279
280 static int __access_control(iotcon_request_h request, iotcon_attributes_h attributes)
281 {
282         _D("Access Request Handling");
283
284         string policy;
285
286         char *deviceName;
287         int ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_NAME, &deviceName);
288         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
289
290         char *deviceType;
291         ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_TYPE, &deviceType);
292         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
293
294         char *hostAddress;
295         ret = iotcon_request_get_host_address(request, &hostAddress);
296         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_request_get_host_address() Fail(%d)", ret);
297
298         string hostAddressString(hostAddress);
299         string ip = conv::util::getIpAddress(hostAddressString);
300
301         char macAddress[127] = {0, };
302
303         IF_FAIL_RETURN_TAG(conv::util::getPeerMac(ip, -1, macAddress), CONV_ERROR_INVALID_PARAMETER, _E, "getPeerMac failed");
304
305         _D("Device Name : %s, Device IP : %s, Mac : %s, DeviceType : %s", deviceName, ip.c_str(), macAddress, deviceType);
306
307         char *access_request_type = NULL;
308         ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, &access_request_type);
309         _D("Access Request : %s", access_request_type);
310         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
311
312         if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, access_request_type)) {
313 #if defined(_D2D_INTERNAL_ACL_)
314                 ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
315                 IF_FAIL_RETURN_TAG(AddACLDevice(macAddress, deviceName, ip.c_str(), &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "AddACLDevice failed");
316
317                 if (acManagerPolicy == ACMANAGER_POLICY_P) {
318                         _D("PERMITTED");
319                         policy = CONV_ACCESS_CONTROL_PERMITTED;
320                 } else if (acManagerPolicy == ACMANAGER_POLICY_D) {
321                         _D("DENIED");
322                         policy = CONV_ACCESS_CONTROL_DENIED;
323                 } else if (acManagerPolicy == ACMANAGER_POLICY_U) {
324                         _D("UNDECIDED");
325                         policy = CONV_ACCESS_CONTROL_DENIED;
326                 } else if (acManagerPolicy == ACMANAGER_POLICY_U2) {
327                         _D("UNDECIDED");
328                         conv::acl_manager::LaunchPasskeyShowPopup(deviceName);
329                         policy = CONV_ACCESS_CONTROL_PASSKEY_REQUEST;
330                 }
331                 _D("acManagerPolicy:%d", acManagerPolicy);
332 #else
333                 rdm_device_s rdmDevice;
334                 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");
335
336                 ret = rdm_request_access(&rdmDevice);
337
338                 if (ret == RDM_ERROR_SUCCESS) {
339                         _D("PERMITTED");
340                         policy = CONV_ACCESS_CONTROL_PERMITTED;
341                 } else if (ret == RDM_ERROR_DEVICE_IS_DENIED) {
342                         _D("DENIED");
343                         policy = CONV_ACCESS_CONTROL_DENIED;
344                 } else if (ret == RDM_ERROR_INPROGRESS){
345                         _D("UNDECIDED");
346                         conv::RemoteAppControlAclRequestInfo *aclRequest = new(std::nothrow) conv::RemoteAppControlAclRequestInfo();
347                         aclRequest->request = request;
348                         if (rdm_callback_register(__acl_state_callback, aclRequest, &aclRequest->aclHandler) == RDM_ERROR_SUCCESS) {
349                                 _D("Register callback for ACL");
350                                 return CONV_ERROR_NONE;
351                         } else {
352                                 _D("Register callback failed");
353                                 policy = CONV_ACCESS_CONTROL_DENIED;
354                         }
355                 }
356                 _D("rdm_request_access:%d", ret);
357 #endif
358         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_RESPONSE, access_request_type)) {
359 #if defined(_D2D_INTERNAL_ACL_)
360                 char *input_passkey;
361                 ret = iotcon_attributes_get_str(attributes, CONV_JSON_PASSKEY, &input_passkey);
362                 IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
363
364                 ret = conv::acl_manager::PasskeyChecker(input_passkey);
365                 if (ret == ACLResult_OK) {
366                         policy = CONV_ACCESS_CONTROL_PASSKEY_RIGHT;
367                         conv::acl_manager::SetDeviceInfoAndACL(macAddress, deviceType, deviceName, ip.c_str(), ACMANAGER_POLICY_P);
368                         conv::acl_manager::LaunchAccessAllowedToast(deviceName);
369                 } else if (ret == ACLResult_Error) {
370                         policy = CONV_ACCESS_CONTROL_PASSKEY_WRONG;
371                 } else if (ret == ACLResult_Close) {
372                         policy = CONV_ACCESS_CONTROL_PASSKEY_REJECTED;
373                 }
374 #endif
375         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_CANCEL, access_request_type)) {
376 #if defined(_D2D_INTERNAL_ACL_)
377                 _D("Access Cancel Handling");
378                 policy = CONV_ACCESS_CONTROL_DENIED;
379                 conv::acl_manager::LaunchPopupCancelToast();
380 #endif
381         }
382
383         iotcon_response_result_e result;
384         result = IOTCON_RESPONSE_OK;
385
386         iotcon_representation_h representation;
387         iotcon_representation_create(&representation);
388         iotcon_attributes_h attributesReply;
389         iotcon_attributes_create(&attributesReply);
390
391         iotcon_attributes_add_str(attributesReply, CONV_JSON_ACCESS_REQUEST_RESULT, (char*)policy.c_str());
392
393         iotcon_representation_set_attributes(representation, attributesReply);
394
395         _send_response(request, representation, result);
396
397         iotcon_attributes_destroy(attributesReply);
398         iotcon_representation_destroy(representation);
399
400         return CONV_ERROR_NONE;
401 }
402
403 static int __app_control_launch(iotcon_request_h request, iotcon_attributes_h attributes)
404 {
405         char *hostAddress;
406         int req_id = -1;
407         int ret = iotcon_request_get_host_address(request, &hostAddress);
408         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_request_get_host_address() Fail(%d)", ret);
409         string hostAddressString(hostAddress);
410         string ip = conv::util::getIpAddress(hostAddressString);
411
412         char macAddress[127] = {0, };
413         IF_FAIL_RETURN_TAG(conv::util::getPeerMac(ip, -1, macAddress), CONV_ERROR_INVALID_PARAMETER, _E, "getPeerMac failed");
414
415         _D("Device IP : %s, Mac : %s", ip.c_str(), macAddress);
416
417 #if defined(_D2D_INTERNAL_ACL_)
418         ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
419
420         IF_FAIL_RETURN_TAG(GetACLState(macAddress, &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "ACL check failed");
421         if (acManagerPolicy == ACMANAGER_POLICY_P) {
422                 _D("PERMITTED");
423         } else {
424                 _D("Device is not permitted %d", acManagerPolicy);
425                 return CONV_ERROR_INVALID_OPERATION;
426         }
427 #else
428         rdm_status_e eStatus = RDM_STATUS_NONE;
429         ret = rdm_get_status(macAddress, RDM_TECH_IND_WIFI, &eStatus);
430
431         if (ret == RDM_ERROR_SUCCESS) {
432             if (eStatus == RDM_STATUS_ALLOW) {
433                 _D("PERMITTED");
434             } else {
435                 _D("Device is not permitted %d", eStatus);
436                 return CONV_ERROR_INVALID_OPERATION;
437             }
438         } else if (ret == RDM_ERROR_DEVICE_NOT_FOUND) {
439             _D("Device is not found");
440         return CONV_ERROR_INVALID_OPERATION;
441         } else {
442             _D("rdm_get_status failed (%d)", ret);
443             return CONV_ERROR_INVALID_OPERATION;
444         }
445 #endif
446         iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
447         app_control_h app_control;
448         int reply = 0;
449         char *appctl_char;
450
451         ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL, &appctl_char);
452         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
453
454         bundle_raw* encoded = reinterpret_cast<unsigned char*>(appctl_char);
455         bundle* appctl_bundle = bundle_decode(encoded, strlen(appctl_char));
456
457         app_control_create(&app_control);
458         app_control_import_from_bundle(app_control, appctl_bundle);
459
460         iotcon_attributes_get_int(attributes, CONV_JSON_REPLY, &reply);
461
462         if (reply == 1) {
463                 bool waiting_reply = false;
464
465                 // check if it's already launched and waiting for app_control response
466                 for(std::map<long long, app_control_cb_info_s>::iterator it = app_control_cb_map.begin(); it != app_control_cb_map.end(); it++) {
467                         app_control_cb_info_s found_cb_info = it->second;
468                         if(found_cb_info.request_handle == request) {
469                                 waiting_reply = true;
470                                 _D("app_control_send_launch_request is already called...waiting reply");
471                                 break;
472                         }
473                 }
474
475                 if (!waiting_reply) {
476                         long long reply_id = get_req_id();
477
478                         app_control_cb_info_s cb_info;
479                         cb_info.req_id = req_id;
480                         cb_info.request_handle = request;
481                         app_control_cb_map[reply_id] = cb_info;
482
483                         ret = app_control_send_launch_request(app_control, _app_control_cb, (void*)reply_id);
484                         _D("app_control_send_launch_request with callback");
485
486                         if (ret != APP_CONTROL_ERROR_NONE) {
487                                 _E("Launch request failed(%d)", ret);
488                                 iotcon_response_result_e result = IOTCON_RESPONSE_ERROR;
489                                 iotcon_attributes_h attr;
490                                 iotcon_representation_h rep;
491                                 iotcon_attributes_create(&attr);
492                                 iotcon_attributes_add_int(attr, CONV_JSON_REQ_ID, req_id);
493                                 iotcon_representation_create(&rep);
494                                 iotcon_representation_set_attributes(rep, attr);
495                                 _send_response(request, rep, result);
496                                 iotcon_representation_destroy(rep);
497                                 iotcon_attributes_destroy(attr);
498                                 app_control_cb_map.erase(reply_id);
499                         }
500                 }
501
502                 bundle_free(appctl_bundle);
503                 app_control_destroy(app_control);
504         } else {
505                 _D("no waiting for reply. send response immediately");
506                 iotcon_response_result_e result;
507                 ret = app_control_send_launch_request(app_control, NULL, NULL);
508
509                 if (ret != APP_CONTROL_ERROR_NONE) {
510                         _E("Launch request failed(%d)", ret);
511                         result = IOTCON_RESPONSE_ERROR;
512                 } else {
513                         _D("Launch request succeeded");
514                         result = IOTCON_RESPONSE_OK;
515                 }
516                 bundle_free(appctl_bundle);
517                 app_control_destroy(app_control);
518
519                 iotcon_attributes_h attr;
520                 iotcon_representation_h rep;
521                 iotcon_attributes_create(&attr);
522                 iotcon_attributes_add_int(attr, CONV_JSON_REQ_ID, req_id);
523                 iotcon_representation_create(&rep);
524                 iotcon_representation_set_attributes(rep, attr);
525                 _send_response(request, rep, result);
526                 iotcon_representation_destroy(rep);
527                 iotcon_attributes_destroy(attr);
528         }
529
530         return CONV_ERROR_NONE;
531 }
532
533 //callback function handles put command for remote-app-control resource
534 static int __handle_request(iotcon_representation_h rep, iotcon_request_h request)
535 {
536         iotcon_attributes_h attributes;
537         char *requestType;
538
539         int ret = iotcon_representation_get_attributes(rep, &attributes);
540         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
541
542         // Handles Access Request
543         ret = iotcon_attributes_get_str(attributes, CONV_JSON_REQUEST_TYPE, &requestType);
544         IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
545
546         if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, requestType)) {
547                 return __access_control(request, attributes);
548         } else if (!strcmp(CONV_LAUNCH_REQUEST, requestType)) {
549                 return __app_control_launch(request, attributes);
550         }
551
552         return CONV_ERROR_INVALID_PARAMETER;
553 }
554
555 //callback function handles requests for remote-app-control resource
556 void conv::RemoteAppControlServiceProvider::__iotcon_request_cb(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
557 {
558         _D("request cb called");
559
560         int ret;
561         iotcon_request_type_e type;
562         char *hostAddress;
563         int req_id = -1;
564         iotcon_representation_h reqRep = NULL;
565
566         IF_FAIL_VOID_TAG(request, _E, "request is NULL");
567
568         ret = iotcon_request_get_representation(request, &reqRep);
569         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_representation() Failed(%d)", ret);
570
571         ret = iotcon_request_get_host_address(request, &hostAddress);
572         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_request_get_host_address() Failed(%d)", ret);
573
574         _I("host_address : %s", hostAddress);
575
576         ret = iotcon_request_get_request_type(request, &type);
577         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_request_get_request_type() Failed(%d)", ret);
578         _D("request type : %d", type);
579
580         if (IOTCON_REQUEST_PUT == type) {
581                 _I("PUT request");
582                 IF_FAIL_CATCH_TAG(__handle_request(reqRep, request) == CONV_ERROR_NONE, _E, "__handle_request() Failed(%d)", ret);
583         }
584
585         if (reqRep) {
586                 iotcon_representation_destroy(reqRep);
587                 reqRep = NULL;
588         }
589
590         return;
591
592 CATCH:
593         iotcon_attributes_h attributes;
594         iotcon_representation_h responseRep;
595         iotcon_representation_create(&responseRep);
596         iotcon_attributes_h responseAttributes;
597         iotcon_attributes_create(&responseAttributes);
598
599         if (reqRep != NULL) {
600                 ret = iotcon_representation_get_attributes(reqRep, &attributes);
601                 if (ret == IOTCON_ERROR_NONE) {
602                         iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
603                 }
604         }
605
606         iotcon_attributes_add_int(responseAttributes, CONV_JSON_REQ_ID, req_id);
607         iotcon_representation_set_attributes(responseRep, responseAttributes);
608
609         _send_response(request, responseRep, IOTCON_RESPONSE_ERROR);
610
611         if (attributes) {
612                 iotcon_attributes_destroy(attributes);
613                 attributes = NULL;
614         }
615         if (responseAttributes) {
616                 iotcon_attributes_destroy(responseAttributes);
617                 responseAttributes = NULL;
618         }
619         if (reqRep) {
620                 iotcon_representation_destroy(reqRep);
621                 reqRep = NULL;
622         }
623         if (responseRep) {
624                 iotcon_representation_destroy(responseRep);
625                 reqRep = NULL;
626         }
627 }
628
629 int conv::RemoteAppControlServiceProvider::init()
630 {
631         if (iotcon_resource == NULL) {
632                 // register resource
633                 int properties;
634                 iotcon_resource_interfaces_h resource_ifaces = NULL;
635                 iotcon_resource_types_h resource_types = NULL;
636                 int error;
637
638                 properties = IOTCON_RESOURCE_DISCOVERABLE | IOTCON_RESOURCE_OBSERVABLE;
639
640                 error = iotcon_resource_types_create(&resource_types);
641                 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "rt creation failed");
642
643                 iotcon_resource_types_add(resource_types, __resourceType.c_str());
644
645                 error = iotcon_resource_interfaces_create(&resource_ifaces);
646
647                 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
648
649                 iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
650
651
652                 error = iotcon_resource_create(CONV_URI_REMOTE_APP_CONTROL, resource_types, resource_ifaces, properties, __iotcon_request_cb, NULL, &iotcon_resource);
653                 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource creation failed");
654
655                 iotcon_resource_types_destroy(resource_types);
656                 iotcon_resource_interfaces_destroy(resource_ifaces);
657
658                 _D("RemoteAppControlServiceProvider init done");
659         } else {
660                 _D("RemoteAppControlServiceProvider is already initiated");
661         }
662
663         return CONV_ERROR_NONE;
664 }
665
666 int conv::RemoteAppControlServiceProvider::release()
667 {
668         if (iotcon_resource == NULL) {
669                 _D("RemoteAppControlServiceProvider is already released");
670         } else {
671                 // unregister resource
672                 int error = iotcon_resource_destroy(iotcon_resource);
673                 IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource destroy failed");
674                 iotcon_resource = NULL;
675                 _D("RemoteAppControlServiceProvider release done");
676         }
677
678         return CONV_ERROR_NONE;
679 }
680
681 static void passkey_popup_callback(void *user_data, int result, char *passkey);
682
683 //callback function handles reply from access control request
684 static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error_e err,
685                 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
686 {
687         _D("__on_access_response called");
688         int ret;
689         iotcon_response_result_e response_result;
690         iotcon_representation_h repr;
691
692         conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
693
694         ret = iotcon_response_get_result(response, &response_result);
695         if (IOTCON_ERROR_NONE != ret) {
696                 _E("iotcon_response_get_result() Fail(%d)", ret);
697                 conv::Json result;
698                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
699                 return;
700         }
701
702         if (IOTCON_RESPONSE_RESOURCE_CHANGED != response_result) {
703                 _E("_on_response_observe Response error(%d)", response_result);
704                 conv::Json result;
705                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
706                 return;
707         }
708
709         ret = iotcon_response_get_representation(response, &repr);
710
711         char* accessControlResult;
712         iotcon_attributes_h attributes;
713         iotcon_representation_get_attributes(repr, &attributes);
714         ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_RESULT, &accessControlResult);
715         if (IOTCON_ERROR_NONE != ret) {
716                 _E("iotcon_attributes_get_str() Fail(%d)", ret);
717                 conv::Json result;
718                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
719                 return;
720         }
721
722         if (!strcmp(CONV_ACCESS_CONTROL_PERMITTED, accessControlResult)) {
723                 _D("__on_access_response PERMITTED");
724                 conv::Json result;
725                 svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED;
726                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
727                 return;
728         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_REQUEST, accessControlResult)) {
729 #if defined(_D2D_INTERNAL_ACL_)
730                 _D("__on_access_response PASSKEY REQUEST");
731                 conv::acl_manager::LaunchPasskeyInputPopup(passkey_popup_callback, svcInfo);
732                 return;
733 #endif
734         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_RIGHT, accessControlResult)) {
735 #if defined(_D2D_INTERNAL_ACL_)
736                 _D("__on_access_response PASSKEY RIGHT");
737                 conv::acl_manager::LaunchAccessAllowedToast((char*)svcInfo->deviceName.c_str());
738                 conv::Json result;
739                 svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED;
740                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
741                 return;
742 #endif
743         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_WRONG, accessControlResult)) {
744 #if defined(_D2D_INTERNAL_ACL_)
745                 _D("__on_access_response PASSKEY WRONG");
746                 conv::acl_manager::LaunchPasskeyWrongToast();
747                 return;
748 #endif
749         } else if (!strcmp(CONV_ACCESS_CONTROL_PASSKEY_REJECTED, accessControlResult)) {
750 #if defined(_D2D_INTERNAL_ACL_)
751                 _D("__on_access_response PASSKEY REJECTED");
752                 conv::acl_manager::LaunchAccessRejectedToast();
753                 conv::Json result;
754                 svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED;
755                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
756                 return;
757 #endif
758         } else {
759                 _D("__on_access_response DENIED");
760                 conv::Json result;
761                 svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED;
762                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
763                 return;
764         }
765 }
766
767 #if defined(_D2D_INTERNAL_ACL_)
768 static void passkey_popup_callback(void *user_data, int result, char *passkey)
769 {
770         conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
771
772         iotcon_representation_h representation;
773         iotcon_representation_create(&representation);
774
775         iotcon_attributes_h attributes;
776         iotcon_attributes_create(&attributes);
777
778         if (result == ACLResult_Cancel) {
779                 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
780                 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSKEY_CANCEL);
781                 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
782                 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
783
784         } else if (result == ACLResult_Connect) {
785                 iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
786                 iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSKEY_RESPONSE);
787                 iotcon_attributes_add_str(attributes, CONV_JSON_PASSKEY, passkey);
788                 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
789                 iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
790         }
791
792         iotcon_representation_set_attributes(representation, attributes);
793         svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
794         iotcon_attributes_destroy(attributes);
795
796         iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo);
797 }
798 #endif
799
800 int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
801 {
802         _D("communcation/start requested");
803         int error;
804         Json result;
805
806         int properties;
807         iotcon_resource_interfaces_h resource_ifaces = NULL;
808         iotcon_resource_types_h resource_types = NULL;
809
810         RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
811
812         if (svcInfo->iotconInfoObj.iotconResourceHandle != NULL) {
813                 _D("already started");
814                 sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
815                 return CONV_ERROR_INVALID_OPERATION;
816         }
817
818         properties = IOTCON_RESOURCE_DISCOVERABLE | IOTCON_RESOURCE_OBSERVABLE;
819
820         error = iotcon_resource_types_create(&resource_types);
821         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "rt creation failed");
822
823         iotcon_resource_types_add(resource_types, svcInfo->iotconInfoObj.resourceType.c_str());
824
825         error = iotcon_resource_interfaces_create(&resource_ifaces);
826
827         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
828
829         iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
830
831         error = iotcon_remote_resource_create(svcInfo->iotconInfoObj.address.c_str(), IOTCON_CONNECTIVITY_IP, svcInfo->iotconInfoObj.uri.c_str(), properties, resource_types, resource_ifaces,
832                         &(svcInfo->iotconInfoObj.iotconResourceHandle));
833
834         _D("remote resource created : %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
835
836         IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
837
838         iotcon_resource_types_destroy(resource_types);
839         iotcon_resource_interfaces_destroy(resource_ifaces);
840
841         //send message for access request
842         iotcon_representation_h representation;
843         iotcon_representation_create(&representation);
844         iotcon_attributes_h attributes;
845         iotcon_attributes_create(&attributes);
846
847         iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
848         iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST);
849         iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)conv::util::getDeviceName().c_str());
850         iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_TYPE, (char*)conv::util::getDeviceType().c_str());
851
852         iotcon_representation_set_attributes(representation, attributes);
853         svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
854
855         iotcon_attributes_destroy(attributes);
856
857         error = iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo);
858
859         return CONV_ERROR_NONE;
860 }
861
862 int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
863 {
864         _D("communcation/stop requested");
865         Json result;
866
867         RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
868
869         if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
870                 _D("not even started");
871                 sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
872                 return CONV_ERROR_INVALID_OPERATION;
873         }
874
875         iotcon_remote_resource_destroy(svcInfo->iotconInfoObj.iotconResourceHandle);
876         svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
877         sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
878
879         return CONV_ERROR_NONE;
880 }
881
882 int conv::RemoteAppControlServiceProvider::readRequest(Request* requestObj)
883 {
884         return CONV_ERROR_NONE;
885 }
886
887 //callback function handles reply from publish request
888 static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
889                 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
890 {
891         int ret;
892         int appcontrol_result = -1;
893         iotcon_response_result_e response_result;
894         iotcon_representation_h repr;
895         char* appctl_char = NULL;
896         char* appctl_request_char = NULL;
897         int appctl_result = -1;
898         int req_id = -1;
899         iotcon_attributes_h attributes;
900         std::map<int, response_cb_info_s>::iterator find_iter = response_cb_map.end();
901         response_cb_info_s cb_info;
902         cb_info.requestObj = NULL;
903
904         ret = iotcon_response_get_representation(response, &repr);
905         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_representation() Failed(%d)", ret);
906
907         iotcon_representation_get_attributes(repr, &attributes);
908         ret = iotcon_attributes_get_int(attributes, CONV_JSON_REQ_ID, &req_id);
909         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_attributes_get_int() Failed(%d)", ret);
910
911         find_iter = response_cb_map.find(req_id);
912         IF_FAIL_CATCH_TAG(find_iter != response_cb_map.end(), _E, "No callback found for response");
913         cb_info = find_iter->second;
914
915         ret = iotcon_response_get_result(response, &response_result);
916         IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_result() Failed(%d)", ret);
917         IF_FAIL_CATCH_TAG(response_result == IOTCON_RESPONSE_RESOURCE_CHANGED, _E, "not response of PUT method(%d)", response_result);
918
919         ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL_REPLY, &appctl_char);
920         if (IOTCON_ERROR_NONE != ret) {
921                 _E("iotcon_attributes_get_str() Fail(%d)", ret);
922         }
923
924         ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL_REQUEST, &appctl_request_char);
925         if (IOTCON_ERROR_NONE != ret) {
926                 _E("iotcon_attributes_get_str() Fail(%d)", ret);
927         }
928
929         appcontrol_result = iotcon_attributes_get_int(attributes, CONV_JSON_APP_CONTROL_RESULT, &appctl_result);
930         if (IOTCON_ERROR_NONE != appcontrol_result) {
931                 _E("iotcon_attributes_get_int() Fail(%d)", appcontrol_result);
932         }
933
934         _D(RED("publishing_response"));
935         if (cb_info.requestObj) {
936                 conv::Json result;
937                 conv::Json payload;
938                 conv::Json description;
939
940                 string resultStr = to_string(appctl_result);
941                 payload.set(NULL, CONV_JSON_RESULT_TYPE, CONV_JSON_ON_PUBLISH);
942                 if (appctl_char) {
943                         payload.set(NULL, CONV_JSON_APP_CONTROL_REPLY, appctl_char);
944                 }
945                 if (appctl_request_char) {
946                         payload.set(NULL, CONV_JSON_APP_CONTROL_REQUEST, appctl_request_char);
947                 }
948                 if (appcontrol_result == IOTCON_ERROR_NONE) {
949                         payload.set(NULL, CONV_JSON_APP_CONTROL_RESULT, resultStr.c_str());
950                 }
951                 result.set(NULL, CONV_JSON_DESCRIPTION, cb_info.requestObj->getDescription());
952                 result.set(NULL, CONV_JSON_PAYLOAD, payload);
953
954                 cb_info.requestObj->publish(CONV_ERROR_NONE, result, 0, NULL);
955                 _D("response published");
956         } else {
957                 _D("request obj is NULL");
958         }
959         if (find_iter != response_cb_map.end()) {
960                 response_cb_map.erase(find_iter);
961         }
962         return;
963 CATCH:
964         if (cb_info.requestObj) {
965                 conv::Json result;
966                 conv::Json payload;
967                 conv::Json description;
968
969                 string resultStr = to_string(appctl_result);
970                 payload.set(NULL, CONV_JSON_RESULT_TYPE, CONV_JSON_ON_PUBLISH);
971                 if (appctl_char) {
972                         payload.set(NULL, CONV_JSON_APP_CONTROL_REPLY, appctl_char);
973                 }
974                 if (appctl_request_char) {
975                         payload.set(NULL, CONV_JSON_APP_CONTROL_REQUEST, appctl_request_char);
976                 }
977                 if (appcontrol_result == IOTCON_ERROR_NONE) {
978                         payload.set(NULL, CONV_JSON_APP_CONTROL_RESULT, resultStr.c_str());
979                 }
980                 payload.set(NULL, CONV_JSON_APP_CONTROL_RESULT, resultStr.c_str());
981                 result.set(NULL, CONV_JSON_DESCRIPTION, cb_info.requestObj->getDescription());
982                 result.set(NULL, CONV_JSON_PAYLOAD, payload);
983
984                 cb_info.requestObj->publish(CONV_ERROR_INVALID_OPERATION, result, 0, NULL);
985                 _D("response error published");
986         } else {
987                 _D("request obj is NULL");
988         }
989         if (find_iter != response_cb_map.end()) {
990                 response_cb_map.erase(find_iter);
991         }
992         return;
993 }
994
995 int conv::RemoteAppControlServiceProvider::publishRequest(Request* requestObj)
996 {
997         RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
998         int error;
999
1000         IF_FAIL_RETURN_TAG(svcInfo->accessControlState == ACCESS_CONTROL_STATE_PERMITTED, CONV_ERROR_INVALID_OPERATION, _E, "Access to device is not permitted");
1001
1002         requestObj->setCommunicationInfo(&(svcInfo->iotconInfoObj));
1003
1004         iotcon_representation_h representation;
1005         iotcon_representation_create(&representation);
1006
1007         Json payload;
1008         requestObj->getPayloadFromDescription(&payload);
1009
1010         string app_control;
1011         int reply;
1012
1013         payload.get(NULL, CONV_JSON_APP_CONTROL, &app_control);
1014         payload.get(NULL, CONV_JSON_REPLY, &reply);
1015
1016         iotcon_attributes_h attributes;
1017         iotcon_attributes_create(&attributes);
1018
1019         char* appControl = new char[app_control.size() + 1];
1020
1021         memset(appControl, 0, app_control.size() + 1);
1022         strncpy(appControl, app_control.c_str(), app_control.size()+1);
1023
1024         iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL, appControl);
1025         iotcon_attributes_add_int(attributes, CONV_JSON_REPLY, reply);
1026         iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char *)CONV_LAUNCH_REQUEST);
1027
1028         delete[] appControl;
1029
1030         int req_id = get_req_id();
1031         iotcon_attributes_add_int(attributes, CONV_JSON_REQ_ID, req_id);
1032
1033         response_cb_info_s cb_info;
1034         cb_info.req_id = req_id;
1035         cb_info.requestObj = svcInfo->registeredRequest;
1036         response_cb_map[req_id] = cb_info;
1037
1038         iotcon_representation_set_attributes(representation, attributes);
1039         svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
1040
1041         iotcon_attributes_destroy(attributes);
1042
1043         error = iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_response, NULL);
1044
1045         if (error != IOTCON_ERROR_NONE) {
1046                 _E("iotcon_remote_resource_put failed");
1047                 response_cb_map.erase(req_id);
1048                 Json result;
1049                 sendResponse(result, CONV_JSON_ON_PUBLISH, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
1050                 return CONV_ERROR_INVALID_OPERATION;
1051         }
1052
1053         return CONV_ERROR_NONE;
1054 }
1055
1056 int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
1057 {
1058         _D("communcation/recv requested");
1059         RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
1060
1061         switch (requestObj->getType()) {
1062         case REQ_SUBSCRIBE:
1063                 if (svcInfo->registeredRequest != NULL) {
1064                         delete svcInfo->registeredRequest;
1065                 }
1066                 svcInfo->registeredRequest = requestObj;
1067                 requestObj->reply(CONV_ERROR_NONE);
1068                 _D("subscribe requested");
1069                 break;
1070         case REQ_UNSUBSCRIBE:
1071                 svcInfo->registeredRequest = NULL;
1072                 requestObj->reply(CONV_ERROR_NONE);
1073                 delete requestObj;
1074                 break;
1075         default:
1076                 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
1077                 delete requestObj;
1078                 return CONV_ERROR_INVALID_OPERATION;
1079                 break;
1080         }
1081
1082         return CONV_ERROR_NONE;
1083 }
1084
1085
1086 int conv::RemoteAppControlServiceProvider::loadServiceInfo(Request* requestObj)
1087 {
1088         string client;
1089         conv::ClientInfo* clientObj = NULL;
1090
1091         client = requestObj->getSender();
1092         _D("client id : %s", client.c_str());
1093         clientObj = conv::client_manager::getClient(client);
1094         IF_FAIL_RETURN_TAG(clientObj, CONV_ERROR_OUT_OF_MEMORY, _E, "client info alloc failed");
1095
1096         Json description = requestObj->getDescription();
1097         Json service;
1098         Json device;
1099
1100         string deviceId;
1101         string deviceName;
1102         string deviceAddress;
1103         string uri;
1104
1105         description.get(NULL, CONV_JSON_SERVICE, &service);
1106         description.get(NULL, CONV_JSON_DEVICE, &device);
1107
1108         service.get(NULL, CONV_SERVICE_ID, &uri);
1109
1110         device.get(NULL, CONV_DEVICE_ID, &deviceId);
1111         device.get(NULL, CONV_DEVICE_NAME, &deviceName);
1112         device.get(NULL, CONV_JSON_DEVICE_ADDRESS, &deviceAddress);
1113
1114         RemoteAppControlServiceInfo *svcInfo = NULL;
1115         IServiceInfo* svcInfoBase = clientObj->getServiceInfo(__type, deviceId);
1116
1117         if (svcInfoBase != NULL) {
1118                 _D("service instance already exists");
1119                 svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(svcInfoBase);
1120         } else {
1121                 _D("allocating new service instance");
1122                 svcInfo = new(std::nothrow) RemoteAppControlServiceInfo();
1123                 IF_FAIL_RETURN_TAG(svcInfo, CONV_ERROR_OUT_OF_MEMORY, _E, "svcInfo alloc failed");
1124
1125                 svcInfo->deviceId = deviceId;
1126                 svcInfo->deviceName = deviceName;
1127                 svcInfo->deviceAddress = deviceAddress;
1128
1129                 svcInfo->iotconInfoObj.address = deviceAddress;
1130                 svcInfo->iotconInfoObj.uri = CONV_URI_REMOTE_APP_CONTROL;
1131                 svcInfo->iotconInfoObj.resourceType = __resourceType;
1132                 svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
1133
1134                 //save service info
1135                 clientObj->addServiceInfo(__type, deviceId, (IServiceInfo*)svcInfo);
1136
1137                 _D("remote app control service is created");
1138         }
1139
1140         requestObj->setServiceInfo(svcInfo);
1141         return CONV_ERROR_NONE;
1142 }
1143
1144 int conv::RemoteAppControlServiceProvider::getServiceInfoForDiscovery(Json* jsonObj)
1145 {
1146         jsonObj->set(NULL, CONV_JSON_DISCOVERY_SERVICE_TYPE, CONV_SERVICE_REMOTE_APP_CONTROL);
1147
1148         // set data for service handle
1149         Json info;
1150         info.set(NULL, CONV_SERVICE_ID, __uri);
1151         info.set(NULL, CONV_SERVICE_VERSION, "1.0");
1152
1153         jsonObj->set(NULL, CONV_JSON_DISCOVERY_SERVICE_INFO, info);
1154
1155         return CONV_ERROR_NONE;
1156 }