Applied access request steps for remote-app-control 82/85982/2
authorkmook <kmook.choi@samsung.com>
Tue, 30 Aug 2016 04:49:14 +0000 (13:49 +0900)
committerkmook <kmook.choi@samsung.com>
Tue, 30 Aug 2016 06:10:11 +0000 (15:10 +0900)
Change-Id: Ia1d7e524549bf9264294d2dc3c38dddee0ffa3fa
Signed-off-by: kmook <kmook.choi@samsung.com>
common/Types.h
daemon/CMakeLists.txt
daemon/ServiceManager.cpp
daemon/Util.cpp
daemon/Util.h
daemon/service_provider/AppCommServiceApplication.h
daemon/service_provider/RemoteAppControlServiceInfo.h
daemon/service_provider/RemoteAppControlServiceProvider.cpp
daemon/service_provider/RemoteAppControlServiceProvider.h
packaging/d2d-conv-manager.spec

index e9b4fd6..beeac6e 100644 (file)
@@ -135,13 +135,20 @@ enum request_type {
 #define CONV_JSON_DEVICE_TYPE                  CONV_DEVICE_TYPE
 #define CONV_JSON_DEVICE_ADDRESS               "host_address"
 
-enum application_state {
+enum ApplicationState {
        APP_COMM_STATE_NONE = 0,
        APP_COMM_STATE_STARTED,
        APP_COMM_STATE_STARTING,
        APP_COMM_STATE_FAILED,
 };
 
+enum AccessControlState {
+       ACCESS_CONTROL_STATE_NONE = 0,
+       ACCESS_CONTROL_STATE_REQUESTED,
+       ACCESS_CONTROL_STATE_PERMITTED,
+       ACCESS_CONTROL_STATE_DENIED,
+};
+
 // smartview app to app communication service
 #define CONV_JSON_CHANNEL_ID                   "channel_id"
 #define CONV_JSON_URI                                  "uri"
@@ -180,8 +187,15 @@ enum application_state {
 // remote app control service
 #define CONV_JSON_APP_CONTROL                  "app_control"
 #define CONV_JSON_REPLY                                        "reply"
+#define CONV_JSON_REQUEST_TYPE                 "request_type"
+#define CONV_JSON_ACCESS_REQUEST_RESULT        "access_request_result"
 #define CONV_JSON_APP_CONTROL_REPLY            "app_control_reply"
 #define CONV_JSON_APP_CONTROL_REQUEST  "app_control_request"
 #define CONV_JSON_APP_CONTROL_RESULT   "app_control_result"
 
+#define CONV_LAUNCH_REQUEST                            "LAUNCH_REQUEST"
+#define CONV_ACCESS_CONTROL_REQUEST            "ACL_REQUEST"
+#define CONV_ACCESS_CONTROL_PERMITTED  "PERMITTED"
+#define CONV_ACCESS_CONTROL_DENIED             "DENIED"
+
 #endif
index 95417d6..87f2af3 100755 (executable)
@@ -15,7 +15,6 @@ FILE(GLOB DAEMON_SRCS ${DAEMON_SRCS} ../msf_tizen_client/src/*.cpp)
 
 SET(provider_deps "glib-2.0 dlog json-glib-1.0 iotcon capi-appfw-app-manager iotcon vconf capi-network-bluetooth capi-network-wifi-direct capi-appfw-application bundle capi-network-connection cynara-creds-gdbus cynara-client cynara-session capi-appfw-package-manager")
 SET(provider_deps "${provider_deps} openssl libwebsockets libcurl nsd-dns-sd")
-#      SET(provider_deps "${provider_deps} security-server")
 # Mobile profile
 IF("${PROFILE}" STREQUAL "mobile")
        ADD_DEFINITIONS("-D_MOBILE_")
index 6676dff..971aaa1 100755 (executable)
@@ -28,6 +28,7 @@ using namespace std;
 
 conv::ServiceManager::ServiceManager()
 {
+       __activationState = 1;
 }
 
 conv::ServiceManager::~ServiceManager()
@@ -64,8 +65,6 @@ int conv::ServiceManager::init()
 
        if ( error < 0 ) {
                _E("vconf error (%d)", error);
-//             temporary code for binary without vconf
-               __activationState = 1;
        }
 
        if ( __activationState == 1 ) {
@@ -75,8 +74,8 @@ int conv::ServiceManager::init()
        }
 
        error = vconf_notify_key_changed(VCONFKEY_SETAPPL_D2D_CONVERGENCE, vconf_update_cb, this);
-//     temporarily commented out for binary without vconf
-//     IF_FAIL_RETURN_TAG(error >= 0, CONV_ERROR_INVALID_OPERATION, _E, "vconf error (%d)", error);
+
+       IF_FAIL_RETURN_TAG(error >= 0, CONV_ERROR_INVALID_OPERATION, _E, "vconf error (%d)", error);
 
        return CONV_ERROR_NONE;
 }
@@ -288,9 +287,10 @@ static iotcon_representation_h _get_d2d_service_representation(conv::ServiceMana
        strncpy(deviceId, deviceIdStr.c_str(), deviceIdStr.size()+1);
        strncpy(deviceName, deviceNameStr.c_str(), deviceNameStr.size()+1);
 
+       _D("device name : %s", deviceName);
        iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_ID, deviceId);
        iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, deviceName);
-#if defined(_TV_) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_TV) || defined(TIZEN_TV_PRODUCT)
+#if defined(_TV_)
        _D("device type : TV");
        string deviceTypeStr("TV");
 #else
index fc83b42..5907178 100755 (executable)
 #include <bluetooth_internal.h>
 #include <vconf.h>
 #include "Log.h"
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
 
 #include <glib.h>
 #include <pthread.h>
@@ -171,9 +177,7 @@ bool conv::util::isServiceActivated(int serviceValue)
 
        if (error != 0) {
                _D("vconf_get_int failed %d", error);
-//             return false;
-//             temporary code for binary without vconf
-               return true;
+               return false;
        }
 
        if ((serviceValue & currentState) > 0) {
@@ -182,3 +186,63 @@ bool conv::util::isServiceActivated(int serviceValue)
                return false;
        }
 }
+
+bool conv::util::getPeerMac(const string &remoteIP, const int remotePort, char *buf)
+{
+#ifdef _WIN32
+        return false;
+#else
+       sockaddr_in ClientAddress;
+       memset(&ClientAddress, 0, sizeof(ClientAddress));
+       ClientAddress.sin_family = AF_INET;
+       if(remotePort != -1) {
+               ClientAddress.sin_port = htons(remotePort);
+       }
+       ClientAddress.sin_addr.s_addr = inet_addr(remoteIP.c_str());
+
+       // create socket
+       int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+       struct if_nameindex* interface = if_nameindex();
+       struct if_nameindex* head = interface;
+       if(interface != NULL) {
+               while(interface->if_index != 0 && interface->if_name != NULL) {
+                       struct arpreq myarp;
+                       memset(&myarp, 0, sizeof(myarp));
+                       memcpy(&myarp.arp_pa, &ClientAddress, sizeof(myarp.arp_pa));
+                       strncpy(myarp.arp_dev, interface->if_name, sizeof(myarp.arp_dev) - 1);
+                       myarp.arp_dev[sizeof(myarp.arp_dev) - 1] = 0;
+                       if(ioctl(sockfd, SIOCGARP, &myarp) != -1) {
+                               unsigned char *ptr = (unsigned char*)(&myarp.arp_ha.sa_data[0]);
+                               snprintf(buf, 18,"%02X-%02X-%02X-%02X-%02X-%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
+                               _D("%s MAC = %s\n", myarp.arp_dev, buf);
+                               if_freenameindex(head);
+                               if(sockfd >= 0)
+                                       close(sockfd);
+                               return true;
+                       } else {
+                               _D( "Device:%s error ioctl %d", myarp.arp_dev, errno);
+                       }
+                       interface++;
+               }
+               if_freenameindex(head);
+       }
+
+       if(sockfd >= 0)
+               close(sockfd);
+
+       return false;
+#endif
+}
+
+std::string conv::util::getIpAddress(std::string hostAddress)
+{
+       if (hostAddress.empty())
+               return "";
+
+       std::string::size_type pos  = hostAddress.find(":", 0);
+
+       std::string sub = hostAddress.substr(0, pos);
+
+       return sub;
+}
index 1a083a7..50e32e3 100644 (file)
@@ -18,8 +18,6 @@
 #define __D2D_SERVICE_UTIL_H__
 #include <string>
 
-using namespace std;
-
 #define MAC_ADDR_STR_LEN 18
 
 namespace conv {
@@ -33,6 +31,8 @@ namespace conv {
                typedef void (*timer_function)(void *data);
                void* miscStartTimer(timer_function function, unsigned int interval, void *data);
                void miscStopTimer(void *timer);
+               bool getPeerMac(const std::string &remoteIP, const int remotePort, char *buf);
+               std::string getIpAddress(std::string hostAddress);
        }
 }
 #endif
index c2bc4c4..07dbe51 100644 (file)
@@ -36,7 +36,7 @@ namespace conv {
                        string channelId;
                        Service localService;
                        bool isLocal;
-                       application_state state;
+                       ApplicationState state;
 
                        void onStart(bool start_result);
                        void onStop(bool start_result);
index 2c15e4e..c128b89 100644 (file)
 namespace conv {
        class RemoteAppControlServiceInfo : public IServiceInfo {
                public:
+                       RemoteAppControlServiceInfo()
+                       {
+                                       accessControlState = ACCESS_CONTROL_STATE_NONE;
+                                       registeredRequest = NULL;
+                       }
+
                        ~RemoteAppControlServiceInfo()
                        {
                                if ( registeredRequest != NULL )
@@ -49,6 +55,7 @@ namespace conv {
                        std::string deviceAddress;
                        Request* registeredRequest;
                        IotconCommunicationInfo iotconInfoObj;
+                       AccessControlState accessControlState;
        };
 
 }
index 432f7c1..9fa3f26 100755 (executable)
@@ -129,6 +129,24 @@ static int _send_response(iotcon_request_h request, iotcon_representation_h repr
        return CONV_ERROR_NONE;
 }
 
+static int sendResponse(conv::Json payload, const char* request_type, conv_error_e error, conv::Request* requestObj)
+{
+       _D(RED("publishing_response"));
+       IF_FAIL_RETURN_TAG(requestObj != NULL, CONV_ERROR_INVALID_OPERATION, _E, "listener_cb is not registered");
+
+       conv::Json result;
+       conv::Json description = requestObj->getDescription();
+
+       payload.set(NULL, CONV_JSON_RESULT_TYPE, request_type);
+
+       result.set(NULL, CONV_JSON_DESCRIPTION, description);
+       result.set(NULL, CONV_JSON_PAYLOAD, payload);
+       requestObj->publish(error, result);
+
+       return CONV_ERROR_NONE;
+}
+
+//callback function handles app control reply callback from callee application
 static void _app_control_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
 {
        _D("app control reply received");
@@ -177,24 +195,57 @@ static void _app_control_cb(app_control_h request, app_control_h reply, app_cont
        app_control_cb_map.erase(find_iter);
 }
 
-static int handle_request(iotcon_representation_h rep, iotcon_request_h request)
+static int __access_control(iotcon_request_h request, iotcon_attributes_h attributes)
+{
+       string policy;
+       char *deviceName;
+
+       _D("Access Request Handling");
+       int ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_NAME, &deviceName);
+       IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
+
+#if defined(_TV_)
+       _D("TV:Always returns PERMITTED");
+       policy = CONV_ACCESS_CONTROL_PERMITTED;
+#else
+       _D("Always returns PERMITTED");
+       policy = CONV_ACCESS_CONTROL_PERMITTED;
+#endif
+       iotcon_response_result_e result;
+       result = IOTCON_RESPONSE_OK;
+
+       iotcon_representation_h representation;
+       iotcon_representation_create(&representation);
+       iotcon_attributes_h attributesReply;
+       iotcon_attributes_create(&attributesReply);
+
+       iotcon_attributes_add_str(attributesReply, CONV_JSON_ACCESS_REQUEST_RESULT, (char*)policy.c_str());
+
+       iotcon_representation_set_attributes(representation, attributesReply);
+
+       _send_response(request, representation, result);
+
+       iotcon_attributes_destroy(attributesReply);
+       iotcon_representation_destroy(representation);
+
+       return CONV_ERROR_NONE;
+}
+
+static int __app_control_launch(iotcon_request_h request, iotcon_attributes_h attributes)
 {
-       iotcon_attributes_h attributes;
-       char* appctl_char;
        app_control_h app_control;
        int reply = 0;
+       char *appctl_char;
 
-       int ret = iotcon_representation_get_attributes(rep, &attributes);
-       if (IOTCON_ERROR_NONE != ret) {
-               _E("iotcon_representation_get_attributes() Fail(%d)", ret);
-               return CONV_ERROR_INVALID_PARAMETER;
-       }
+// Check if it's permitted device
+#if defined(_TV_)
+       _D("TV:Always PERMITTED");
+#else
+       _D("Always PERMITTED");
+#endif
 
-       ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL, &appctl_char);
-       if (IOTCON_ERROR_NONE != ret) {
-               _E("iotcon_attributes_get_str() Fail(%d)", ret);
-               return CONV_ERROR_INVALID_PARAMETER;
-       }
+       int ret = iotcon_attributes_get_str(attributes, CONV_JSON_APP_CONTROL, &appctl_char);
+       IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
 
        bundle_raw* encoded = reinterpret_cast<unsigned char*>(appctl_char);
        bundle* appctl_bundle = bundle_decode(encoded, strlen(appctl_char));
@@ -261,6 +312,29 @@ static int handle_request(iotcon_representation_h rep, iotcon_request_h request)
        return CONV_ERROR_NONE;
 }
 
+//callback function handles put command for remote-app-control resource
+static int __handle_request(iotcon_representation_h rep, iotcon_request_h request)
+{
+       iotcon_attributes_h attributes;
+       char *requestType;
+
+       int ret = iotcon_representation_get_attributes(rep, &attributes);
+       IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret);
+
+       // Handles Access Request
+       ret = iotcon_attributes_get_str(attributes, CONV_JSON_REQUEST_TYPE, &requestType);
+       IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret);
+
+       if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, requestType)) {
+               return __access_control(request, attributes);
+       } else if (!strcmp(CONV_LAUNCH_REQUEST, requestType)) {
+               return __app_control_launch(request, attributes);
+       }
+
+       return CONV_ERROR_INVALID_PARAMETER;
+}
+
+//callback function handles requests for remote-app-control resource
 void conv::RemoteAppControlServiceProvider::__iotcon_request_cb(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
 {
        _D("request cb called");
@@ -299,8 +373,8 @@ void conv::RemoteAppControlServiceProvider::__iotcon_request_cb(iotcon_resource_
                        return;
                }
 
-               if (handle_request(req_repr, request) != CONV_ERROR_NONE) {
-                       _E("handle_request() Fail");
+               if (__handle_request(req_repr, request) != CONV_ERROR_NONE) {
+                       _E("__handle_request() Fail");
                        _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
                }
 
@@ -359,6 +433,60 @@ int conv::RemoteAppControlServiceProvider::release()
        return CONV_ERROR_NONE;
 }
 
+//callback function handles reply from access control request
+static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error_e err,
+               iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
+{
+       _D("__on_access_response called");
+       int ret;
+       iotcon_response_result_e response_result;
+       iotcon_representation_h repr;
+
+       conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
+
+       ret = iotcon_response_get_result(response, &response_result);
+       if (IOTCON_ERROR_NONE != ret) {
+               _E("iotcon_response_get_result() Fail(%d)", ret);
+               conv::Json result;
+               sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
+               return;
+       }
+
+       if (IOTCON_RESPONSE_RESOURCE_CHANGED != response_result) {
+               _E("_on_response_observe Response error(%d)", response_result);
+               conv::Json result;
+               sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
+               return;
+       }
+
+       ret = iotcon_response_get_representation(response, &repr);
+
+       char* accessControlResult;
+       iotcon_attributes_h attributes;
+       iotcon_representation_get_attributes(repr, &attributes);
+       ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_RESULT, &accessControlResult);
+       if (IOTCON_ERROR_NONE != ret) {
+               _E("iotcon_attributes_get_str() Fail(%d)", ret);
+               conv::Json result;
+               sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
+               return;
+       }
+
+       if (!strcmp(CONV_ACCESS_CONTROL_PERMITTED, accessControlResult)) {
+               conv::Json result;
+               svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED;
+               _D("__on_access_response PERMITTED");
+               sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
+               return;
+       } else {
+               conv::Json result;
+               svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED;
+               _D("__on_access_response DENIED");
+               sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest);
+               return;
+       }
+}
+
 int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
 {
        IF_FAIL_RETURN_TAG(__activationState == 1, CONV_ERROR_INVALID_OPERATION, _E, "service provider is not activated");
@@ -402,24 +530,21 @@ int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
        iotcon_resource_types_destroy(resource_types);
        iotcon_resource_interfaces_destroy(resource_ifaces);
 
-       sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest);
-
-       return CONV_ERROR_NONE;
-}
+       //send message for access request
+       iotcon_representation_h representation;
+       iotcon_representation_create(&representation);
+       iotcon_attributes_h attributes;
+       iotcon_attributes_create(&attributes);
 
-int conv::RemoteAppControlServiceProvider::sendResponse(Json payload, const char* request_type, conv_error_e error, Request* requestObj)
-{
-       _D(RED("publishing_response"));
-       IF_FAIL_RETURN_TAG(requestObj != NULL, CONV_ERROR_INVALID_OPERATION, _E, "listener_cb is not registered");
+       iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, CONV_ACCESS_CONTROL_REQUEST);
+       iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)svcInfo->deviceName.c_str());
 
-       Json result;
-       Json description = requestObj->getDescription();
+       iotcon_representation_set_attributes(representation, attributes);
+       svcInfo->iotconInfoObj.iotconRepresentationHandle = representation;
 
-       payload.set(NULL, CONV_JSON_RESULT_TYPE, request_type);
+       iotcon_attributes_destroy(attributes);
 
-       result.set(NULL, CONV_JSON_DESCRIPTION, description);
-       result.set(NULL, CONV_JSON_PAYLOAD, payload);
-       requestObj->publish(error, result);
+       error = iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo);
 
        return CONV_ERROR_NONE;
 }
@@ -453,6 +578,7 @@ int conv::RemoteAppControlServiceProvider::readRequest(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
+//callback function handles reply from publish request
 static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
                iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
 {
@@ -537,6 +663,8 @@ int conv::RemoteAppControlServiceProvider::publishRequest(Request* requestObj)
        RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
        int error;
 
+       IF_FAIL_RETURN_TAG(svcInfo->accessControlState == ACCESS_CONTROL_STATE_PERMITTED, CONV_ERROR_INVALID_OPERATION, _E, "Access to device is not permitted");
+
        requestObj->setCommunicationInfo(&(svcInfo->iotconInfoObj));
 
        iotcon_representation_h representation;
@@ -562,6 +690,7 @@ int conv::RemoteAppControlServiceProvider::publishRequest(Request* requestObj)
 
        iotcon_attributes_add_str(attributes, CONV_JSON_APP_CONTROL, appControl);
        iotcon_attributes_add_int(attributes, CONV_JSON_REPLY, reply);
+       iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, CONV_LAUNCH_REQUEST);
 
        delete[] appControl;
 
index 8f18f32..0c21ed4 100644 (file)
@@ -44,7 +44,6 @@ namespace conv {
 
                private:
                        iotcon_resource_h iotcon_resource;
-                       int sendResponse(Json payload, const char* request_type, conv_error_e error, Request* requestObj);
 
                        static void __iotcon_request_cb(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
        };
index 740bca6..ea64a95 100755 (executable)
@@ -44,7 +44,7 @@ BuildRequires: openssl-devel
 BuildRequires: curl
 BuildRequires: libcurl-devel
 
-%if "%{?BUILD_PROFILE}" == "mobile"
+%if "%{?BUILD_PROFILE}" == "tv"
 
 %endif