Merge branch 'easysetup'
authorlankamadan <lanka.madan@samsung.com>
Fri, 4 Mar 2016 09:41:03 +0000 (18:41 +0900)
committerlankamadan <lanka.madan@samsung.com>
Fri, 4 Mar 2016 09:41:03 +0000 (18:41 +0900)
Conflicts:
android/android_api/base/jni/Android.mk
resource/csdk/security/provisioning/SConscript
tools/tizen/iotivity.spec

Change-Id: I85b5e3daad5055a1f1c36f3951476e84d0a05285
Signed-off-by: lankamadan <lanka.madan@samsung.com>
13 files changed:
1  2 
android/android_api/base/jni/Android.mk
build_common/SConscript
resource/csdk/security/provisioning/SConscript
resource/provisioning/SConscript
resource/provisioning/examples/SConscript
service/SConscript
service/easy-setup/enrollee/src/onboarding.cpp
service/easy-setup/mediator/richsdk/SConscript
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp
service/resource-encapsulation/unittests/DiscoveryManagerTest.cpp
tools/tizen/.gbs.conf
tools/tizen/iotivity.spec

@@@ -26,20 -26,20 +26,20 @@@ LOCAL_MODULE := libandroid-c
  LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so\r
  include $(PREBUILT_SHARED_LIBRARY)\r
  \r
 -ifeq ($(SECURED), 1)
 -include $(CLEAR_VARS)
 -OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
 -LOCAL_MODULE := libandroid-ocprovision
 -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocprovision.so
 -include $(PREBUILT_SHARED_LIBRARY)
 -
 -include $(CLEAR_VARS)
 -OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
 -LOCAL_MODULE := libandroid-ocpmapi
 -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocpmapi.so
 -include $(PREBUILT_SHARED_LIBRARY)
 -endif
 -
 +ifeq ($(SECURED), 1)\r
 +include $(CLEAR_VARS)\r
 +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)\r
 +LOCAL_MODULE := libandroid-ocprovision\r
- LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocprovision.a\r
- include $(PREBUILT_STATIC_LIBRARY)\r
++LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocprovision.so\r
++include $(PREBUILT_SHARED_LIBRARY)\r
 +\r
 +include $(CLEAR_VARS)\r
 +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)\r
 +LOCAL_MODULE := libandroid-ocpmapi\r
- LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocpmapi.a\r
- include $(PREBUILT_STATIC_LIBRARY)\r
++LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocpmapi.so\r
++include $(PREBUILT_SHARED_LIBRARY)\r
 +endif\r
 +\r
  include $(CLEAR_VARS)\r
  OIC_SRC_PATH := ../../../resource\r
  LOCAL_MODULE := libca-interface\r
Simple merge
@@@ -76,10 -73,10 +76,11 @@@ provisioning_env.AppendUnique(LIBS = ['
  if env.get('DTLS_WITH_X509') == '1':
        provisioning_env.AppendUnique(LIBS = ['CKManger'])
  
- provisioning_env.ParseConfig('pkg-config --libs glib-2.0')
 -#TODO : Have to remove this comment after 1st level of review
 -#This change needs a review.
+ if target_os != 'android':
 -      provisioning_env.ParseConfig('pkg-config --libs glib-2.0');
++      provisioning_env.ParseConfig('pkg-config --libs glib-2.0')
 +
 +if target_os == 'tizen':
 +      provisioning_env.ParseConfig('pkg-config --cflags --libs sqlite3')
  
  if target_os == 'android':
        provisioning_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
@@@ -102,15 -99,11 +103,15 @@@ provisioning_src = 
        'src/ocprovisioningmanager.c',
        'src/oxmjustworks.c',
        'src/oxmrandompin.c',
 -      'src/provisioningdatabasemanager.c',
 -      root_dir+'/extlibs/sqlite3/sqlite3.c' ]
 +      'src/provisioningdatabasemanager.c' ]
 +
 +if target_os != 'tizen':
 +      provisioning_src = provisioning_src + [root_dir+'/extlibs/sqlite3/sqlite3.c' ]
 +
- provisioningserver = provisioning_env.StaticLibrary('ocpmapi', provisioning_src)
+ provisioningserver = provisioning_env.SharedLibrary('ocpmapi', provisioning_src)
  
  provisioning_env.InstallTarget(provisioningserver, 'libocpmapi')
 +provisioning_env.UserInstallTargetLib(provisioningserver, 'libocpmapi')
  
  if env.get('DTLS_WITH_X509') == '1':
        SConscript('ck_manager/SConscript')
index fb1cd7f,50fd899..2e6e25f
mode 100644,100755..100755
index 0000000,f5d1c34..42551d7
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,94 +1,94 @@@
 -            OC_LOG(DEBUG, ES_ENROLLEE_TAG, "Create SoftAp at enrollee");
+ //******************************************************************
+ //
+ // Copyright 2015 Samsung Electronics All Rights Reserved.
+ //
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ //      http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+ //
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ /**
+  * @file
+  *
+  * This file has methods for on-boarding the Enrollee device.
+  * This will contain template methods that will have core business logic & negotiation algorithm
+  * on various on-boarding methods.
+  */
+ #include "easysetup.h"
+ #include "softap.h"
+ #include "onboarding.h"
+ #include "logger.h"
+ #include "resourcehandler.h"
+ /**
+  * @var ES_ENROLLEE_TAG
+  * @brief Logging tag for module name.
+  */
+ #define ES_ENROLLEE_TAG "ES_SOFTAP"
+ /**
+  * It will return true on-boarding type is soft AP
+  */
+ bool ESSoftapOnboarding()
+ {
+     // TODO: To be changed based on user config. Current version, hardcoded to SoftAp onboarding
+     return true;
+ }
+ /**
+  * It will return true on-boarding type is BLE
+  */
+ bool ESBleOnboarding()
+ {
+     //BLE onboarding is not supported with current version.
+     return false;
+ }
+ /**
+  * It will do onboarding based on the user's configuration.
+  */
+ bool ESOnboard(const char * ssid, const char* passwd, NetworkEventCallback cb)
+ {
+     OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "ESOnboard IN");
+     if (ESSoftapOnboarding())
+     {
+         if (ESSoftapAtEnrollee())
+         {
 -            OC_LOG(DEBUG, ES_ENROLLEE_TAG, "Connecting to Mediator SoftAp");
++            OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "Create SoftAp at enrollee");
+             ESCreateSoftap(ssid, passwd, cb);
+         }
+         else
+         {
++            OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "Connecting to Mediator SoftAp");
+             ConnectToWiFiNetwork(ssid, passwd, cb);
+         }
+         return true;
+     }
+     else if (ESBleOnboarding())
+     {
+         OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESOnboard::Ble onboarding is not supported");
+         // TODO:
+         return false;
+     }
+     else
+     {
+         // TODO:
+         OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESOnboard::Invalid onboarding option");
+         return false;
+     }
+ }
index 0000000,c5d2317..f631761
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,142 +1,143 @@@
+ #******************************************************************
+ #
+ # Copyright 2016 Samsung Electronics All Rights Reserved.
+ #
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ #      http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ #
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ ######################################################################
+ # easy-setup Mediator C++[Rich] SDK build script
+ ######################################################################
+ import os.path
+ Import('env')
+ easysetup_path = os.curdir
+ if env.get('RELEASE'):
+     env.AppendUnique(CCFLAGS = ['-Os'])
+     env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+ else:
+     env.AppendUnique(CCFLAGS = ['-g'])
+ if env.get('LOGGING'):
+     env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+ # Easysetup provides reference implemenation of Arduino Enrollee.
+ # Mediator applications developed on different platforms will be default defining the
+ # flag 'REMOTE_ARDUINO_ENROLEE'. If the target Enrollee is not Arduino, the below commented
+ # modifications must be enabled instead (and the existing define must be commented).
+ #
+ ##### The following lines must be uncommented, if target Enrollee is not Arduino
+ target_enrollee = env.get('ES_TARGET_ENROLLEE')
+ if target_enrollee == 'arduino':
+       print "REMOTE_ARDUINO_ENROLEE flag is defined."
+       print "The Mediator application will be working only with Arduino Enrollee."
+       env.AppendUnique(CPPDEFINES = ['REMOTE_ARDUINO_ENROLEE'])
+ # Add third party libraries
+ lib_env = env.Clone()
+ SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+ easy_setup_env = lib_env.Clone()
+ target_os = env.get('TARGET_OS')
+ ######################################################################
+ # Build flags
+ ######################################################################
+ easy_setup_env.AppendUnique(CPPPATH = ['inc', 'src', '../../inc'])
+ if target_os not in ['windows', 'winrt']:
+     easy_setup_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
+ if target_os in ['linux']:
+    easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl'])
+ if target_os in ['android']:
+       easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+       if env.get('SECURED') == '1':
+               easy_setup_env.AppendUnique(LIBPATH = [env.get('SRC_DIR')+'/android/android_api/base/libs/armeabi'])
+       easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+       easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+       easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared'])
+       if env.get('SECURED') == '1':
+               easy_setup_env.AppendUnique(LIBS = ['ocpmapi','ocprovision'])
+       if not env.get('RELEASE'):
+               easy_setup_env.AppendUnique(LIBS = ['log'])
+ if target_os in ['linux']:
+       easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+       easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+       easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
+       easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction'])
+       if env.get('SECURED') == '1':
+               easy_setup_env.AppendUnique(LIBS = ['ocpmapi', 'ocprovision'])
+ if target_os in ['android','linux']:
+       easy_setup_env.PrependUnique(CPPPATH = [
+               env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include',
+               env.get('SRC_DIR') + '/resource/include',
+               env.get('SRC_DIR') + '/resource/csdk/logger/include',
+               env.get('SRC_DIR') + '/resource/csdk/stack/include',
+               env.get('SRC_DIR') + '/resource/csdk/logger/include',
+               env.get('SRC_DIR') + '/resource/csdk/security/include',
+               env.get('SRC_DIR') + '/extlibs/cjson',
+               env.get('SRC_DIR') + '/extlibs/sqlite3',
+               env.get('SRC_DIR') + '/service/easy-setup/inc',
+               'inc'])
+       if env.get('SECURED') == '1':
+               easy_setup_env.AppendUnique(CPPPATH = [
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include',
++                      env.get('SRC_DIR') + '/resource/csdk/connectivity/api/',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/oxm'])
+ ######################################################################
+ # Source files and Targets
+ ######################################################################
+ print"easysetup_path %s" % easysetup_path
+ es_src = None
+ if target_os in ['android','linux']:
+       if env.get('SECURED') == '1':
+               env.AppendUnique(es_src = [os.path.join(easysetup_path, 'src/EnrolleeSecurity.cpp')])
+       es_common_src = ['src/RemoteEnrollee.cpp',
+               'src/RemoteEnrolleeResource.cpp',
+               'src/EasySetup.cpp',
+               'src/ESException.cpp']
+       env.AppendUnique(es_src = es_common_src)
+       es_sdk_shared = easy_setup_env.SharedLibrary('ESMediatorRich', env.get('es_src'))
+       easy_setup_env.InstallTarget(es_sdk_shared, 'libESMediatorRich')
+ print "Files path is %s" % env.get('es_src')
+ ######################################################################
+ # Build RichSDK Mediator Sample App
+ ################################################ ######################
+ if target_os == 'linux':
+       SConscript('../../sampleapp/mediator/linux/richsdk_sample/SConscript')
+ ######################################################################
+ #Build UnitTestcases for Mediator[RichSDK]
+ ################################################ ######################
+ if target_os == 'linux':
+     SConscript('unittests/SConscript')
index 0000000,086651e..ef24ed2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,69 +1,70 @@@
+ #******************************************************************
+ #
+ # Copyright 2016 Samsung Electronics All Rights Reserved.
+ #
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ #      http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ #
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ Import('env')
+ mediator_env = env.Clone()
+ target_os = env.get('TARGET_OS')
+ ######################################################################
+ # Build flags
+ ######################################################################
+ mediator_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+ if env.get('RELEASE'):
+     mediator_env.AppendUnique(CCFLAGS = ['-Os'])
+     mediator_env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+ else:
+     mediator_env.AppendUnique(CCFLAGS = ['-g'])
+ if env.get('LOGGING'):
+     env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+ env.AppendUnique(CPPDEFINES = ['CPP_MEDIATOR'])
+ if target_os not in ['windows', 'winrt']:
+     mediator_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
+       
+ mediator_env.PrependUnique(CPPPATH = [
+             env.get('SRC_DIR') + '/resource/include',
+             env.get('SRC_DIR') + '/resource/oc_logger/include',
+                       env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',         
+                       env.get('SRC_DIR') + '/resource/csdk/stack/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal',
+                       env.get('SRC_DIR') + '/resource/csdk/logger/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/include',
++                      env.get('SRC_DIR') + '/resource/csdk/connectivity/api',
+                       env.get('SRC_DIR') + '/extlibs/cjson',
+                       env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/inc',
+                       env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/src',
+                       env.get('SRC_DIR') + '/service/easy-setup/inc'])
+ mediator_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction', 'coap', 'ESMediatorRich'])
+ if env.get('SECURED') == '1':
+       mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
+ mediator = mediator_env.Program('mediator_rich', 'mediator_cpp.cpp')
+ i_mediator = mediator_env.Install(env.get('BUILD_DIR'), mediator)
+ Alias('mediator_rich', i_mediator)
+ env.AppendTarget('mediator_rich')
index 0000000,32adbd3..ff41ecc
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,207 +1,207 @@@
 -    OC_LOG_V(DEBUG, ES_SAMPLE_APP_TAG, "easySetupStatusCallback status is Status = %d",
+ //******************************************************************
+ //
+ // Copyright 2015 Samsung Electronics All Rights Reserved.
+ //
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ //      http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+ //
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ #include <iostream>
+ #include<stdio.h>
+ #include "oic_string.h"
+ #include "EasySetup.h"
+ #include "OCPlatform.h"
+ #include "logger.h"
+ #include "OCProvisioningManager.h"
+ #define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
+ #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
+ #define JSON_DB_PATH "./oic_svr_db_client.json"
+ using namespace OC;
+ using namespace OIC::Service;
+ static EasySetup *easySetupIntance = nullptr;
+ static ProvConfig netInfo;
+ static WiFiOnboadingConnection onboardingConn;
+ static RemoteEnrollee::shared_ptr remoteEnrollee = nullptr;
+ static std::string ipaddress, ssid, pwd;
+ struct CloseApp
+ {
+ };
+ typedef void (*Runner)();
+ Runner g_currentRun;
+ int processUserInput(int min, int max)
+ {
+     assert(min <= max);
+     int input;
+     std::cin >> input;
+     if (!std::cin.fail())
+     {
+         if(input == max + 1) throw CloseApp();
+         if(min <= input && input <= max) return input;
+     }
+     std::cin.clear();
+     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+     throw std::runtime_error("Invalid Input, please try again");
+ }
+ void easySetupStatusCallback (std::shared_ptr< EasySetupStatus > easySetupStatus)
+ {
++    OIC_LOG_V(DEBUG, ES_SAMPLE_APP_TAG, "easySetupStatusCallback status is Status = %d",
+             easySetupStatus->getEasySetupState());
+ }
+ void startProvisioning()
+ {
+     try
+     {
+         remoteEnrollee->startProvisioning();
+     }
+     catch(OCException &exception)
+     {
+         std::cout << "Exception : " << exception.reason();
+     }
+ }
+ void initEasySetup()
+ {
+     easySetupIntance = EasySetup::getInstance();
+     ipaddress = "192.168.1.104";
+     ssid = "hub2.4G";
+     pwd = "22221111";
+     netInfo.connType = CT_ADAPTER_IP;
+     OICStrcpy(netInfo.provData.WIFI.ssid, NET_WIFI_SSID_SIZE - 1, ssid.c_str());
+     OICStrcpy(netInfo.provData.WIFI.pwd, NET_WIFI_PWD_SIZE - 1, pwd.c_str());
+     onboardingConn.isSecured = false;
+     OICStrcpy(onboardingConn.ipAddress, IPV4_ADDR_SIZE - 1, ipaddress.c_str());
+     try
+     {
+         remoteEnrollee = easySetupIntance->createEnrolleeDevice(netInfo,onboardingConn);
+     }
+     catch (OCException &e)
+     {
+         std::cout << "Exception during createEnrolleeDevice call" << e.reason();
+         return;
+     }
+     remoteEnrollee->registerEasySetupStatusHandler(&easySetupStatusCallback);
+ }
+ void runEasySetupMenu()
+ {
+     constexpr int EASY_SETUP_INIT = 1;
+     constexpr int START_PROVISIONING = 2;
+     constexpr int STOP_PROVISIONING = 3;
+     constexpr int STOP_EASY_SETUP = 4;
+     std::cout << "========================================================\n";
+     std::cout << EASY_SETUP_INIT << ". Easy Setup Init                    \n";
+     std::cout << START_PROVISIONING << ". Start Provisioning              \n";
+     std::cout << STOP_PROVISIONING << ". Stop Provisioning                \n";
+     std::cout << STOP_EASY_SETUP << ". Stop Easy Setup                    \n";
+     std::cout << STOP_EASY_SETUP + 1 << ". Quit                           \n";
+     std::cout << "========================================================\n";
+     int selection = processUserInput(EASY_SETUP_INIT, STOP_EASY_SETUP);
+     switch (selection)
+     {
+         case EASY_SETUP_INIT:
+             initEasySetup();
+             break;
+         case START_PROVISIONING:
+             startProvisioning();
+             break;
+         case STOP_PROVISIONING:
+             //stopProvisioning();
+             break;
+         case STOP_EASY_SETUP:
+             //stopEasySetup();
+             break;
+         default:
+             break;
+     };
+ }
+ static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
+ {
+     (void)UNUSED_PARAM;
+     return fopen(JSON_DB_PATH, mode);
+ }
+ int main()
+ {
+     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+     PlatformConfig config
+     {
+         OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps
+     };
+     OCPlatform::Configure(config);
+ #ifdef __WITH_DTLS__
+     //Initializing the provisioning client stack using the db path provided by the application.
+     OCStackResult result = OCSecure::provisionInit("");
+     if (result != OC_STACK_OK)
+     {
+         return -1;
+     }
+ #endif
+     g_currentRun = runEasySetupMenu;
+     while (true)
+     {
+         try
+         {
+             g_currentRun();
+         }
+         catch (const std::exception& e)
+         {
+             std::cout << "Exception caught in main " << e.what() << std::endl;
+         }
+         catch (const CloseApp&)
+         {
+             break;
+         }
+     }
+     std::cout << "Stopping the client" << std::endl;
+     return 0;
+ }
  
  #include "OCPlatform.h"
  
 -#include <condition_variable>
 -#include <mutex>
 -
  using namespace OIC::Service;
 +using namespace OC;
  using namespace OC::OCPlatform;
  
 -constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
 -constexpr char SECOND_RESOURCEURI[]{ "/a/Light" };
 -constexpr char RESOURCETYPE[]{ "resource.type" };
 +typedef std::unique_ptr< RCSDiscoveryManager::DiscoveryTask > DiscoveryTaskPtr;
 +
 +typedef OCStackResult (*OCFindResource)(const std::string&, const std::string&,
 +            OCConnectivityType, FindCallback);
 +
 +constexpr char RESOURCE_URI[]{ "/a/TemperatureSensor" };
 +constexpr char RESOURCE_TYPE[]{ "resource.type" };
  constexpr char SECOND_RESOURCETYPE[]{ "resource.type.second" };
 -constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
 -constexpr int DEFAULT_DISCOVERYTASK_DELAYTIME = 3000;
  
 -void resourceDiscoveredForTwoTimesCall(RCSRemoteResourceObject::Ptr) {}
 -void resourceDiscoveredForCall(RCSRemoteResourceObject::Ptr) {}
 -void resourceDiscoveredForNeverCall(RCSRemoteResourceObject::Ptr) {}
 +void onResourceDiscovered(RCSRemoteResourceObject::Ptr) {}
  
 -class DiscoveryManagerTest: public TestWithMock
 +class ScopedTask
  {
  public:
 -
 -    typedef std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> DiscoveryTaskPtr;
 -    typedef std::function< void(std::shared_ptr< RCSRemoteResourceObject >) >
 -                                       ResourceDiscoveredCallback;
 -public:
 -
 -    static DiscoveryTaskPtr discoverResource(ResourceDiscoveredCallback cb)
 +    ScopedTask(DiscoveryTaskPtr task) :
 +        m_task{ std::move(task) }
      {
 -        const std::string uri  = "/oic/res";
 -        return RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(),
 -                 uri, RESOURCETYPE, cb);
      }
  
 -    void startDiscovery()
 +    ~ScopedTask()
      {
 -        discoveryTask = discoverResource(resourceDiscoveredForCall);
 +        if (m_task) m_task->cancel();
      }
  
 -    void cancelDiscovery()
 +    RCSDiscoveryManager::DiscoveryTask* operator->()
      {
 -        discoveryTask->cancel();
 +        return m_task.get();
      }
  
 -    bool isCanceled()
 -    {
 -        return discoveryTask->isCanceled();
 -    }
 -
 -    void createResource()
 -    {
 -        server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
 -    }
 -
 -    void createSecondResource()
 -    {
 -        secondServer = RCSResourceObject::Builder(SECOND_RESOURCEURI, SECOND_RESOURCETYPE, RESOURCEINTERFACE).build();
 -    }
 -
 -    void proceed()
 -    {
 -        cond.notify_all();
 -    }
 -
 -    void waitForDiscoveryTask(int waitingTime = DEFAULT_DISCOVERYTASK_DELAYTIME)
 -    {
 -        std::unique_lock< std::mutex > lock{ mutex };
 -        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
 -    }
++    ScopedTask(ScopedTask&&) = default;
++    ScopedTask& operator=(ScopedTask&&) = default;
  private:
 -
 -    std::condition_variable cond;
 -    std::mutex mutex;
 -    RCSResourceObject::Ptr server;
 -    RCSResourceObject::Ptr secondServer;
 -    RCSRemoteResourceObject::Ptr object;
 -    DiscoveryTaskPtr discoveryTask;
 +    DiscoveryTaskPtr m_task;
  };
  
 -TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceBeforeDiscovering)
 -{
 -    createResource();
 -
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 -
 -    startDiscovery();
 -    waitForDiscoveryTask();
 -}
 -
 -TEST_F(DiscoveryManagerTest, resourceIsSupportedPresenceBeforeDiscovering)
 +TEST(DiscoveryManagerTest, ThrowIfDiscoverWithEmptyCallback)
  {
 -    startPresence(10);
 -    createResource();
 -
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 -
 -    startDiscovery();
 -    waitForDiscoveryTask();
 -    stopPresence();
 -}
 -
 -TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceAfterDiscovering)
 -{
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 -
 -    startDiscovery();
 -    createResource();
 -    waitForDiscoveryTask();
 +    EXPECT_THROW(RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(), { }),
 +            RCSInvalidParameterException);
  }
  
 -TEST_F(DiscoveryManagerTest, resourceIsSupportedPresenceAndAfterDiscovering)
 +TEST(DiscoveryManagerTest, ThrowIfDiscoverWithMultipleTypesThatContainEmptyString)
  {
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 -
 -    startPresence(10);
 -    startDiscovery();
 -    createResource();
 -    waitForDiscoveryTask();
 -    stopPresence();
 +    EXPECT_THROW(RCSDiscoveryManager::getInstance()->discoverResourceByTypes(
 +            RCSAddress::multicast(), { "a", "" }, onResourceDiscovered), RCSBadRequestException);
  }
  
 -TEST_F(DiscoveryManagerTest, discoveryRequestByMultipleResourceTypesAndFindResourceOfOneResourceType)
 +TEST(DiscoveryManagerTest, DiscoverInvokesFindResource)
  {
 -    std::vector<std::string> resourceTypes{RESOURCETYPE, SECOND_RESOURCETYPE};
 -    const std::string uri  = "/oic/res";
 -
 -    createSecondResource();
 -
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 -
 -    RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
 -            uri, resourceTypes, resourceDiscoveredForCall);
 -
 -    waitForDiscoveryTask();
 -}
 -
 -TEST_F(DiscoveryManagerTest, discoveryRequestByMultipleResourceTypesAndFindResourcesOfTwoResourceTypes)
 -{
 -    std::vector<std::string> resourceTypes{RESOURCETYPE, SECOND_RESOURCETYPE};
 -    const std::string uri  = "/oic/res";
 -    unsigned int callTimes = 0;
 -
 -    createResource();
 -    createSecondResource();
 -
 -    mocks.OnCallFunc(resourceDiscoveredForTwoTimesCall).Do(
 -        [this, &callTimes](RCSRemoteResourceObject::Ptr){ 
 -            callTimes++;
 -            if (callTimes == 2) proceed();
 +    MockRepository mocks;
 +    mocks.ExpectCallFuncOverload(static_cast<OCFindResource>(findResource)).Match(
 +        [](const std::string& host, const std::string& resourceURI, OCConnectivityType, FindCallback)
 +        {
 +            return host.empty() && resourceURI == (std::string(RESOURCE_URI) + "?rt=" + RESOURCE_TYPE);
          }
 -    );
 +    ).Return(OC_STACK_OK);
  
 -    RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
 -            uri, resourceTypes, resourceDiscoveredForTwoTimesCall);
 -
 -    waitForDiscoveryTask();
 -
 -    EXPECT_EQ(resourceTypes.size(), callTimes);
 +    ScopedTask task = RCSDiscoveryManager::getInstance()->discoverResourceByType(
 +            RCSAddress::multicast(), RESOURCE_URI, RESOURCE_TYPE, onResourceDiscovered);
  }
  
 -TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskAfterDiscoveryResource)
 +TEST(DiscoveryManagerTest, DiscoverWithMultipleTypesInvokesFindResourceMultipleTimes)
  {
 -    startDiscovery();
 -    cancelDiscovery();
 +    MockRepository mocks;
 +    const std::vector< std::string > resourceTypes{ RESOURCE_TYPE, SECOND_RESOURCETYPE };
 +    size_t counter = 0;
 +
 +    mocks.OnCallFuncOverload(static_cast<OCFindResource>(findResource)).Do(
 +        [&counter](const std::string&, const std::string&, OCConnectivityType, FindCallback)
 +        {
 +            ++counter;
 +            return OC_STACK_OK;
 +        }
 +    ).Return(OC_STACK_OK);
  
 -    mocks.NeverCallFunc(resourceDiscoveredForCall);
 +    ScopedTask task = RCSDiscoveryManager::getInstance()->discoverResourceByTypes(
 +            RCSAddress::multicast(), resourceTypes, onResourceDiscovered);
  
 -    waitForDiscoveryTask();
 -    createResource();
 +    EXPECT_EQ(counter, resourceTypes.size());
  }
  
 -TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskNotStartDiscoveryResource)
 +TEST(DiscoveryManagerTest, TaskCanBeCanceled)
  {
 -    startDiscovery();
 -    cancelDiscovery();
 -    cancelDiscovery();
 -}
 +    ScopedTask aTask =  RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(),
 +            onResourceDiscovered);
 +    ScopedTask aTaskToBeCanceled = RCSDiscoveryManager::getInstance()->discoverResource(
 +            RCSAddress::multicast(), onResourceDiscovered);
  
 -TEST_F(DiscoveryManagerTest, isCanceledAfterCancelDiscoveryTask)
 -{
 -    startDiscovery();
 -    cancelDiscovery();
 +    aTaskToBeCanceled->cancel();
  
 -    ASSERT_TRUE(isCanceled());
 +    ASSERT_FALSE(aTask->isCanceled());
 +    ASSERT_TRUE(aTaskToBeCanceled->isCanceled());
  }
  
 -TEST_F(DiscoveryManagerTest, multipleDiscoveryRequestAndCancelJustOneDiscoveryRequest)
 -{
 -    DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForCall);
 -    DiscoveryTaskPtr notCanceledTask_1 = discoverResource(resourceDiscoveredForCall);
 -    DiscoveryTaskPtr notCanceledTask_2 = discoverResource(resourceDiscoveredForCall);
 -
 -    canceledTask->cancel();
 +TEST(DiscoveryManagerTest, CallbackWouldNotBeCalledForSameRemoteResource) {
 +    FindCallback callback;
  
 -    ASSERT_TRUE(canceledTask->isCanceled());
 -    ASSERT_FALSE(notCanceledTask_1->isCanceled());
 -    ASSERT_FALSE(notCanceledTask_2->isCanceled());
 -}
 +    MockRepository mocks;
 +    mocks.OnCallFuncOverload(static_cast<OCFindResource>(findResource)).Do(
 +       [&callback](const std::string&, const std::string&, OCConnectivityType, FindCallback cb)
 +       {
 +           callback = cb;
 +           return OC_STACK_OK;
 +       }
 +   ).Return(OC_STACK_OK);
  
 -TEST_F(DiscoveryManagerTest, equalDiscoveryRequestsAndCancelJustOneRequest)
 -{
 -    mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
 -        [this](RCSRemoteResourceObject::Ptr){ proceed();});
 +    ScopedTask aTask =  RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(),
 +            onResourceDiscovered);
  
 -    mocks.NeverCallFunc(resourceDiscoveredForNeverCall);
 +    std::vector< std::string > interfaces{ "interface" };
 +    std::vector< std::string > resourceTypes{ "resource.type" };
 +    constexpr char fakeHost[] { "coap://127.0.0.1:1" };
  
 -    DiscoveryTaskPtr notCanceledTask = discoverResource(resourceDiscoveredForCall);
 -    DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForNeverCall);
 -    canceledTask->cancel();
 +    mocks.ExpectCallFunc(onResourceDiscovered);
 +    callback(OCPlatform::constructResourceObject(fakeHost, "/uri", OCConnectivityType::CT_ADAPTER_IP,
 +            true, interfaces, resourceTypes));
  
 -    createResource();
 -    waitForDiscoveryTask();
 +    mocks.NeverCallFunc(onResourceDiscovered);
 +    callback(OCPlatform::constructResourceObject(fakeHost, "/uri", OCConnectivityType::CT_ADAPTER_IP,
 +            true, interfaces, resourceTypes));
  }
@@@ -125,53 -109,66 +125,59 @@@ scons install --install-sandbox=%{build
  %else
  %define build_mode debug
  %endif
 +%define ex_install_dir %{buildroot}%{_bindir}
 +mkdir -p %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_server.json %{ex_install_dir}
 +cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_client.json %{ex_install_dir}
 +%if 0%{?SECURED} == 1
 +mkdir -p %{ex_install_dir}/provisioning
 +cp out/tizen/*/%{build_mode}/resource/provisioning/examples/oic_svr_db_client.json %{ex_install_dir}/provisioning/
 +cp out/tizen/*/%{build_mode}/resource/provisioning/examples/provisioningclient %{ex_install_dir}/provisioning/
 +
 +cp ./resource/csdk/security/include/pinoxmcommon.h %{buildroot}%{_includedir}
 +cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir}
 +cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir}
 +cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir}
 +
 +cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/provisioningclient %{ex_install_dir}/provision-sample/
 +cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_justworks %{ex_install_dir}/provision-sample/
 +cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{ex_install_dir}/provision-sample/
 +cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/*.json %{ex_install_dir}/provision-sample/
 +%endif
  
 -cp out/tizen/*/%{build_mode}/resource/examples/devicediscoveryclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/devicediscoveryserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/fridgeclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/fridgeserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/garageclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/garageserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/groupclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/groupserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/lightserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/presenceclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/presenceserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/roomclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/roomserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/simpleclient %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/simpleclientHQ %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/simpleclientserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/simpleserver %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/simpleserverHQ %{buildroot}%{_bindir}
 -cp out/tizen/*/%{build_mode}/resource/examples/threadingsample %{buildroot}%{_bindir}
 -if echo %{secure_mode}|grep -qi '1'; then
 -      cp out/tizen/*/%{build_mode}/libocpmapi.a %{buildroot}%{_libdir}
 -      cp resource/c_common/*.h %{buildroot}%{_includedir}
 -      cp resource/csdk/connectivity/api/*.h %{buildroot}%{_includedir}
 -      cp extlibs/tinycbor/tinycbor/src/*.h %{buildroot}%{_includedir}
 -      cp ./extlibs/cjson/*.h %{buildroot}%{_includedir}
 -      cp ./resource/c_common/oic_string/include/*.h %{buildroot}%{_includedir}
 -      cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir}
 -      cp ./resource/csdk/security/include/*.h %{buildroot}%{_includedir}
 -      cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir}
 -      cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir}
 -      cp ./resource/csdk/connectivity/lib/libcoap-4.1.1/*.h %{buildroot}%{_includedir}
 -
 -      cp out/tizen/*/%{build_mode}/resource/csdk/stack/samples/linux/secure/occlientbasicops %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/stack/samples/linux/secure/ocserverbasicops %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/stack/samples/linux/secure/ocamsservice %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/examples/*.json %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/stack/samples/linux/secure/*.json %{buildroot}%{_bindir}
 -
 -      cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/provisioningclient %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_justworks %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{buildroot}%{_bindir}
 -      cp out/tizen/*/%{build_mode}/resource/csdk/security/provisioning/sample/*.json %{buildroot}%{_bindir}
 -fi
 -cp out/tizen/*/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
 -cp out/tizen/*/%{build_mode}/lib*.so %{buildroot}%{_libdir}
 -
 -cp resource/csdk/stack/include/*.h %{buildroot}%{_includedir}
 -cp resource/csdk/logger/include/*.h %{buildroot}%{_includedir}
 -cp resource/c_common/ocrandom/include/*.h %{buildroot}%{_includedir}
 -cp -r resource/oc_logger/include/* %{buildroot}%{_includedir}
 -cp resource/include/*.h %{buildroot}%{_includedir}
  
 -cp service/things-manager/sdk/inc/*.h %{buildroot}%{_includedir}
 +%if 0%{?tizen_version_major} < 3
 +mkdir -p %{buildroot}/%{_datadir}/license
 +cp LICENSE.APLv2 %{buildroot}/%{_datadir}/license/%{name}
 +cp LICENSE.APLv2 %{buildroot}/%{_datadir}/license/%{name}-service
 +cp LICENSE.APLv2 %{buildroot}/%{_datadir}/license/%{name}-test
 +%endif
+ cp resource/c_common/*.h %{buildroot}%{_includedir}
+ cp service/things-manager/sdk/inc/*.h %{buildroot}%{_includedir}
+ cp service/easy-setup/inc/*.h %{buildroot}%{_includedir}
+ cp service/easy-setup/enrollee/inc/*.h %{buildroot}%{_includedir}
  
  %post -p /sbin/ldconfig