From 320232f06729c54b07dea91f366e11d5bb88dd53 Mon Sep 17 00:00:00 2001 From: leechul Date: Fri, 20 May 2016 13:55:03 +0900 Subject: [PATCH] Update OTM's unit test to use the real resource servers during OTM test [Patch #1] Initial upload [Patch #2] Update to use the correct path for OTM unittest w/ sample server. [Patch #3] Remove the warnings in OTM unittest. [Patch #4] Update to use the default SVR DB. Change-Id: I806b1bd0ec860a91f3e9d762dbed0dc35b133cd6 Signed-off-by: leechul Reviewed-on: https://gerrit.iotivity.org/gerrit/8247 Tested-by: jenkins-iotivity Reviewed-by: Ashwini Kumar Reviewed-by: Jongsung Lee Reviewed-by: Randeep Singh --- .../csdk/security/provisioning/unittest/SConscript | 35 +- .../security/provisioning/unittest/otmunittest.cpp | 429 ++++++++++++++- .../provisioning/unittest/sampleserver1.cpp | 583 +++++++++++++++++++++ .../provisioning/unittest/sampleserver2.cpp | 583 +++++++++++++++++++++ 4 files changed, 1617 insertions(+), 13 deletions(-) create mode 100644 resource/csdk/security/provisioning/unittest/sampleserver1.cpp create mode 100644 resource/csdk/security/provisioning/unittest/sampleserver2.cpp diff --git a/resource/csdk/security/provisioning/unittest/SConscript b/resource/csdk/security/provisioning/unittest/SConscript index ee406d5..17ecefc 100644 --- a/resource/csdk/security/provisioning/unittest/SConscript +++ b/resource/csdk/security/provisioning/unittest/SConscript @@ -30,18 +30,27 @@ src_dir = sptest_env.get('SRC_DIR') # Build flags ###################################################################### sptest_env.PrependUnique(CPPPATH = [ - '../../../connectivity/inc', - '../../../connectivity/api', + '../include', '../../include', - '../../../../../extlibs/tinydtls', '../include/internal', - '../include/oxm', + '../../../stack/include', + '../../../ocrandom/include', '../../../logger/include', '../../../stack/include', + '../../../security/include', + '../../../security/include/internal', + '../../../security/provisioning/include/internal', '../../../../oc_logger/include', - '../../../../../extlibs/gtest/gtest-1.7.0/include', - '../include', - '../include/internal' + '../include/oxm', + '../../../../../extlibs/tinydtls', + '../../../../../extlibs/cjson', + '../../../../../extlibs/base64', + '../../../connectivity/inc', + '../../../connectivity/common/inc', + '../../../connectivity/lib/libcoap-4.1.1', + '../../../connectivity/api', + '../../../../../extlibs/tinydtls', + '../../../../../extlibs/gtest/gtest-1.7.0/include' ]) sptest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) sptest_env.AppendUnique(LIBS = ['-lpthread','-ldl']) @@ -69,12 +78,18 @@ if not env.get('RELEASE'): ###################################################################### # Source files and Targets ###################################################################### -unittest = sptest_env.Program('unittest', ['pmutilitytest.cpp', 'otmunittest.cpp', +unittest = sptest_env.Program('unittest', ['pmutilitytest.cpp', 'secureresourceprovider.cpp', 'provisioningdatabasemanager.cpp', - 'ocprovisioningmanager.cpp' ]) + 'ocprovisioningmanager.cpp','otmunittest.cpp' ]) + +sample_server1 = sptest_env.Program('sample_server1', ['sampleserver1.cpp']) +sample_server2 = sptest_env.Program('sample_server2', ['sampleserver2.cpp']) + +provisioning_unittest_src_dir = src_dir + '/resource/csdk/security/provisioning/unittest/' +provisioning_unittest_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/provisioning/unittest/' -Alias("test", [unittest]) +Alias("test", [unittest, sample_server1, sample_server2]) env.AppendTarget('test') if env.get('TEST') == '1': diff --git a/resource/csdk/security/provisioning/unittest/otmunittest.cpp b/resource/csdk/security/provisioning/unittest/otmunittest.cpp index f0a0eab..363f3a6 100644 --- a/resource/csdk/security/provisioning/unittest/otmunittest.cpp +++ b/resource/csdk/security/provisioning/unittest/otmunittest.cpp @@ -17,12 +17,24 @@ * limitations under the License. * * *****************************************************************/ +#include +#include +#include #include "gtest/gtest.h" -#include "oxmjustworks.h" -#include "oxmrandompin.h" -#include "ownershiptransfermanager.h" #include "ocstack.h" #include "utlist.h" +#include "logger.h" +#include "oic_malloc.h" +#include "oic_string.h" +#include "ocprovisioningmanager.h" +#include "oxmjustworks.h" +#include "oxmrandompin.h" +#include "securevirtualresourcetypes.h" +#include "provisioningdatabasemanager.h" +#include "srmutility.h" +#include "doxmresource.h" +#include "pmtypes.h" +#include "pmutility.h" using namespace std; @@ -99,3 +111,414 @@ TEST(RandomPinOxMTest, NullParam) res = CreatePinBasedOwnerTransferPayload(&otmCtx2, &payloadRes, &size); EXPECT_TRUE(OC_STACK_INVALID_PARAM == res); } + + +/**************************************** + * Test the OTM modules with sample server + ****************************************/ +#define TAG "JUSTWORKS_UNITTEST" +#define OTM_TIMEOUT 5 +#define DISCOVERY_TIMEOUT 3 + +#define SVR_DB_PATH "oic_svr_db_client.dat" +#define UT_PATH "resource/csdk/security/provisioning/unittest" +char pdb_path[1024]; +char svr_path[1024]; + +static uint8_t DEFAULT_SVR_DB[] = { + 0xBF, 0x63, 0x61, 0x63, 0x6C, 0x59, 0x01, 0x80, 0xA2, 0x66, 0x61, 0x63, 0x6C, 0x69, 0x73, 0x74, + 0xA1, 0x64, 0x61, 0x63, 0x65, 0x73, 0x82, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, + 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x86, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x68, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, + 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, + 0x69, 0x63, 0x2F, 0x70, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, + 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x70, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x2F, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, + 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x67, 0x2F, 0x6F, 0x69, 0x63, + 0x2F, 0x61, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, + 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, + 0x61, 0x6D, 0x61, 0x63, 0x6C, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, + 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0xA3, 0x6B, + 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, + 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x82, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, + 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x64, 0x6F, 0x78, 0x6D, 0x63, 0x72, 0x65, 0x6C, + 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6E, + 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x73, 0x74, 0x61, 0x74, 0x63, 0x72, + 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, + 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, + 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, + 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x65, 0x70, 0x73, 0x74, 0x61, 0x74, 0x58, 0x79, + 0xA7, 0x64, 0x69, 0x73, 0x6F, 0x70, 0xF5, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, + 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, + 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x62, 0x63, 0x6D, 0x00, 0x62, 0x74, 0x6D, 0x00, + 0x62, 0x6F, 0x6D, 0x03, 0x62, 0x73, 0x6D, 0x03, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, + 0x75, 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, + 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x64, 0x64, 0x6F, 0x78, 0x6D, 0x58, 0xB6, + 0xA8, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x81, 0x00, 0x66, 0x6F, 0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, + 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65, 0x64, 0xF5, 0x6A, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, + 0x2D, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x6C, 0x64, 0x65, + 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, + 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x2D, + 0x39, 0x39, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x63, 0x64, 0x70, 0x63, 0xF4, 0xFF +}; + +static bool g_doneCB; +static bool g_callbackResult; +static pid_t g_myPID1; +static pid_t g_myPID2; + +static const char* g_otmCtx = "Test User Context"; +static OCProvisionDev_t* g_unownedDevices = NULL; +static OCProvisionDev_t* g_ownedDevices = NULL; + +static void GetCurrentWorkingDirectory(char* buf, size_t bufsize) +{ + char cwd[1024] = {0}; + const char* unittest_path = "resource/csdk/security/provisioning/unittest"; + if(getcwd(cwd, sizeof(cwd)) != NULL) + { + if(strstr(cwd, unittest_path) == NULL) + { +#if defined __linux__ +#if __x86_64__ + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); +#else + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); +#endif //__x86_64__ +#endif //defined __linux__ + } + else + { + snprintf(buf, bufsize, "%s/", cwd); + } + } +} + +static FILE* fopen_prvnMng(const char* path, const char* mode) +{ + (void)path; // unused |path| parameter + + // input |g_svr_db_fname| internally by force, not using |path| parameter + // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally + // with its own |SVR_DB_FILE_NAME| + char cwd[1024] = {0}; + char svr_db_path[1024] = {0}; + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(svr_db_path, "%s%s", cwd, SVR_DB_PATH); + return fopen(svr_db_path, mode); +} + +// callback function(s) for provisioning client using C-level provisioning API +static void ownershipTransferCB(void* ctx, int UNUSED1, OCProvisionResult_t* UNUSED2, bool hasError) +{ + (void)UNUSED1; + (void)UNUSED2; + (void)ctx; + + if(!hasError) + { + OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx); + } + else + { + OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx); + } + g_callbackResult = !hasError; + g_doneCB = true; +} + + +// callback function(s) for provisioning client using C-level provisioning API +static void removeDeviceCB(void* ctx, int UNUSED1, OCProvisionResult_t* UNUSED2, bool hasError) +{ + (void)UNUSED1; + (void)UNUSED2; + (void)ctx; + + if(!hasError) + { + OIC_LOG_V(INFO, TAG, "Remove device request SUCCEEDED - ctx: %s", (char*) ctx); + } + else + { + OIC_LOG_V(ERROR, TAG, "Remove device request FAILED - ctx: %s", (char*) ctx); + } + g_callbackResult = !hasError; + g_doneCB = true; +} + + +static int waitCallbackRet(void) +{ + struct timespec timeout; + timeout.tv_sec = 0; + timeout.tv_nsec = 100000000L; + + for(long long i=0; !g_doneCB && OTM_TIMEOUT * 100000000L * 1000L > i; ++i) + { + nanosleep(&timeout, NULL); + if(OC_STACK_OK != OCProcess()) + { + OIC_LOG(ERROR, TAG, "OCStack process error"); + return -1; + } + } + + return 0; +} + +TEST(InitForOTM, NullParam) +{ + OCStackResult result = OC_STACK_ERROR; + + OTMCallbackData_t otmcb; + otmcb.loadSecretCB = LoadSecretJustWorksCallback; + otmcb.createSecureSessionCB = CreateSecureSessionJustWorksCallback; + otmcb.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload; + otmcb.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload; + + static OCPersistentStorage pstStr; + pstStr.open = fopen_prvnMng; + pstStr.read = fread; + pstStr.write = fwrite; + pstStr.close = fclose; + pstStr.unlink = unlink; + + //Get current path to execute the sample server. + char cwd[1024] = {0}; + char server1_path[1024] = {0}; + char server2_path[1024] = {0}; + char pdb_path[1024] = {0}; + char del_cmd[1024] = {0}; + char svrdb_path[1024] = {0}; + FILE* fp = NULL; + + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + EXPECT_TRUE(0 < strlen(cwd)); + + //Delete previous PDB, if exist. + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(del_cmd, "rm -rf %stest.db", cwd); + system(del_cmd); + + //Delete previous SVR DB, if exist. + sprintf(del_cmd, "rm -rf %s%s", cwd, SVR_DB_PATH); + system(del_cmd); + + //Generate default SVR DB. + sprintf(svrdb_path, "%s%s", cwd, SVR_DB_PATH); + fp = fopen(svrdb_path, "w"); + if(NULL != fp) + { + size_t numberItems = fwrite(DEFAULT_SVR_DB, 1, sizeof(DEFAULT_SVR_DB), fp); + ASSERT_TRUE(sizeof(DEFAULT_SVR_DB) == numberItems); + fclose(fp); + } + + //Execute sample server to perform ownership transfer + int status1 = 0; + int status2 = 0; + if(0 == (g_myPID1 = fork())) + { + sprintf(server1_path, "%ssample_server1", cwd); + status1 = system(server1_path); + (void)status1; + } + if(0 == (g_myPID2 = fork())) + { + sprintf(server2_path, "%ssample_server2", cwd); + status2= system(server2_path); + (void)status2; + } + + // register the persistent storage handler for SVR + result = OCRegisterPersistentStorageHandler(&pstStr); + EXPECT_EQ(OC_STACK_OK, result); + + // initialize OC stack and provisioning manager + result = OCInit(NULL, 0, OC_CLIENT_SERVER); + EXPECT_EQ(OC_STACK_OK, result); + + //initialize Provisioning DB Manager + + sprintf(pdb_path, "%stest.db", cwd); + result = OCInitPM(pdb_path); + EXPECT_EQ(OC_STACK_OK, result); + + // register callback function(s) for Justworks OxM + result = OCSetOwnerTransferCallbackData(OIC_JUST_WORKS, &otmcb); + EXPECT_EQ(OC_STACK_OK, result); + + g_doneCB = false; + g_callbackResult = false; +} + + +TEST(PerformUnownedDeviceDiscovery, NullParam) +{ + OCStackResult result = OC_STACK_ERROR; + + OIC_LOG(INFO, TAG, "Discovering Only Unowned Devices on Network..\n"); + result = OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unownedDevices); + EXPECT_EQ(OC_STACK_OK, result); + + int NumOfUnownDevice = 0; + OCProvisionDev_t* tempDev = g_unownedDevices; + while(tempDev) + { + NumOfUnownDevice++; + tempDev = tempDev->next; + } + EXPECT_EQ(2, NumOfUnownDevice); +} + +TEST(PerformJustWorksOxM, NullParam) +{ + OCStackResult result = OC_STACK_ERROR; + + OIC_LOG(INFO, TAG, "Try Ownership Transfer for Unowned Devices...\n"); + result = OCDoOwnershipTransfer((void*)g_otmCtx, g_unownedDevices, ownershipTransferCB); + EXPECT_EQ(OC_STACK_OK, result); + + if(waitCallbackRet()) // input |g_doneCB| flag implicitly + { + OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error"); + return; + } + OIC_LOG(INFO, TAG, "Registered Discovered Unowned Device...\n"); + + EXPECT_EQ(true, g_callbackResult); + EXPECT_EQ(true, g_doneCB); +} + + +TEST(PerformOwnedDeviceDiscovery, NullParam) +{ + OCStackResult result = OC_STACK_ERROR; + + OIC_LOG(INFO, TAG, "Discovering Only Owned Devices on Network..\n"); + result = OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_ownedDevices); + EXPECT_EQ(OC_STACK_OK, result); + + int NumOfOwnDevice = 0; + OCProvisionDev_t* tempDev = g_ownedDevices; + while(tempDev) + { + NumOfOwnDevice++; + tempDev = tempDev->next; + } + + EXPECT_EQ(2/*Server*/ + 1/*PT*/, NumOfOwnDevice); +} + +TEST(PerformLinkDevices, NullParam) +{ + OicUuid_t myUuid; + OCStackResult result = OC_STACK_ERROR; + result = GetDoxmDeviceID(&myUuid); + EXPECT_EQ(OC_STACK_OK, result); + + //Extract target device except PT to perform link devices. + OCProvisionDev_t* dev1 = NULL; + OCProvisionDev_t* dev2 = NULL; + OCProvisionDev_t* tempDev = g_ownedDevices; + + while(tempDev) + { + if(memcmp(tempDev->doxm->deviceID.id, myUuid.id, UUID_LENGTH) != 0) + { + if(NULL == dev1) + { + dev1 = tempDev; + } + else if(NULL == dev2) + { + dev2 = tempDev; + break; + } + else + { + break; + } + } + tempDev = tempDev->next; + } + EXPECT_TRUE(NULL != dev1); + EXPECT_TRUE(NULL != dev2); + + // TODO: Pairwise provisioning (Cred & ACL) + // TODO: This part will be updated after ACL and credential data-structure is updated. + + EXPECT_EQ(OC_STACK_OK, result); +} + +TEST(PerformUnlinkDevices, NullParam) +{ + OCStackResult result = OC_STACK_OK; + + // TODO: Unlink devices + // TODO: This part will be updated after ACL and credential data-structure is updated. + + EXPECT_EQ(OC_STACK_OK, result); +} + +TEST(PerformRemoveDevice, NullParam) +{ + OicUuid_t myUuid; + OCStackResult result = OC_STACK_ERROR; + result = GetDoxmDeviceID(&myUuid); + EXPECT_EQ(OC_STACK_OK, result); + + //Extract target device except PT to perform remove device. + OCProvisionDev_t* removeDev = g_ownedDevices; + while(removeDev) + { + if(memcmp(removeDev->doxm->deviceID.id, myUuid.id, UUID_LENGTH) != 0) + { + break; + } + removeDev = removeDev->next; + } + EXPECT_TRUE(NULL != removeDev); + + g_doneCB = false; + g_callbackResult = false; + + result = OCRemoveDevice((void*)g_otmCtx, DISCOVERY_TIMEOUT, removeDev, removeDeviceCB); + EXPECT_EQ(OC_STACK_OK, result); + EXPECT_EQ(true, g_callbackResult); + EXPECT_EQ(true, g_doneCB); +} + +TEST(FinalizeOTMTest, NullParam) +{ + OCStackResult result = OCStop(); + EXPECT_EQ(OC_STACK_OK, result); + + PMDeleteDeviceList(g_unownedDevices); + PMDeleteDeviceList(g_ownedDevices); + result = PDMClose(); + EXPECT_EQ(OC_STACK_OK, result); + + kill(g_myPID2, SIGKILL); + kill(g_myPID1, SIGKILL); + + int interpreter_res1 = system("pkill -f \"sample_server1\""); + EXPECT_TRUE(0 <= interpreter_res1); + int interpreter_res2 = system("pkill -f \"sample_server2\""); + EXPECT_TRUE(0 <= interpreter_res2); +} + diff --git a/resource/csdk/security/provisioning/unittest/sampleserver1.cpp b/resource/csdk/security/provisioning/unittest/sampleserver1.cpp new file mode 100644 index 0000000..29b0961 --- /dev/null +++ b/resource/csdk/security/provisioning/unittest/sampleserver1.cpp @@ -0,0 +1,583 @@ +/****************************************************************** +* +* 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. +* +******************************************************************/ +/////////////////////////////////////////////////////////////////////// +//NOTE : This sample server is generated based on ocserverbasicops.cpp +/////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include "ocstack.h" +#include "logger.h" +#include "ocpayload.h" +#include "oic_string.h" + +#define TAG "UNITTEST_SERVER_1" + +int gQuitFlag = 0; + +/* Structure to represent a LED resource */ +typedef struct LEDRESOURCE{ + OCResourceHandle handle; + bool state; + int power; +} LEDResource; + +static LEDResource LED; +// This variable determines instance number of the LED resource. +// Used by POST method to create a new instance of LED resource. +static int gCurrLedInstance = 0; +#define SAMPLE_MAX_NUM_POST_INSTANCE 2 +static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE]; + +char *gResourceUri= (char *)"/a/led"; + +//Secure Virtual Resource database for Iotivity Server +//It contains Server's Identity and the PSK credentials +//of other devices which the server trusts +static char CRED_FILE[] = "oic_svr_db_server1.dat"; + +static uint8_t DEFAULT_SVR_DB[] = { + 0xBF, 0x63, 0x61, 0x63, 0x6C, 0x59, 0x02, 0x76, 0xA2, 0x66, 0x61, 0x63, 0x6C, 0x69, 0x73, 0x74, + 0xA1, 0x64, 0x61, 0x63, 0x65, 0x73, 0x84, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, + 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x86, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x68, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, + 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, + 0x69, 0x63, 0x2F, 0x70, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, + 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6A, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, + 0x64, 0x68, 0x72, 0x65, 0x66, 0x70, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, 0x2F, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, + 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x63, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, + 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, + 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, + 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x84, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, + 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x64, 0x6F, 0x78, 0x6D, 0x63, 0x72, + 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, + 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x73, 0x74, 0x61, 0x74, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x61, 0x63, 0x6C, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x63, 0x72, 0x65, + 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, + 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, + 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x82, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, + 0x73, 0x65, 0x63, 0x2F, 0x70, 0x63, 0x6F, 0x6E, 0x66, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, + 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x71, 0x2F, 0x6F, 0x69, + 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x64, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x63, 0x72, + 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, + 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, + 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x81, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, + 0x2F, 0x76, 0x65, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, + 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0x6A, 0x72, 0x6F, + 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, + 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x65, 0x70, + 0x73, 0x74, 0x61, 0x74, 0x58, 0x79, 0xA7, 0x64, 0x69, 0x73, 0x6F, 0x70, 0xF4, 0x6A, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, + 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x62, 0x63, + 0x6D, 0x02, 0x62, 0x74, 0x6D, 0x00, 0x62, 0x6F, 0x6D, 0x03, 0x62, 0x73, 0x6D, 0x03, 0x6A, 0x72, + 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, + 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x64, + 0x64, 0x6F, 0x78, 0x6D, 0x58, 0xB6, 0xA8, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x81, 0x00, 0x66, 0x6F, + 0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65, + 0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, + 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, + 0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, + 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, + 0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, + 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x63, 0x64, 0x70, 0x63, 0xF5, 0xFF +}; + +/* Function that creates a new LED resource by calling the + * OCCreateResource() method. + */ +int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower); + +/* This method converts the payload to JSON format */ +OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest); + +/* Following methods process the PUT, GET, POST + * requests + */ +OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload); +OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload); +OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, + OCEntityHandlerResponse *response, + OCRepPayload **payload); + +/* Entity Handler callback functions */ +OCEntityHandlerResult +OCEntityHandlerCb (OCEntityHandlerFlag flag, + OCEntityHandlerRequest *entityHandlerRequest, + void* callbackParam); + +const char *getResult(OCStackResult result) { + switch (result) { + case OC_STACK_OK: + return "OC_STACK_OK"; + case OC_STACK_RESOURCE_CREATED: + return "OC_STACK_RESOURCE_CREATED"; + case OC_STACK_RESOURCE_DELETED: + return "OC_STACK_RESOURCE_DELETED"; + case OC_STACK_INVALID_URI: + return "OC_STACK_INVALID_URI"; + case OC_STACK_INVALID_QUERY: + return "OC_STACK_INVALID_QUERY"; + case OC_STACK_INVALID_IP: + return "OC_STACK_INVALID_IP"; + case OC_STACK_INVALID_PORT: + return "OC_STACK_INVALID_PORT"; + case OC_STACK_INVALID_CALLBACK: + return "OC_STACK_INVALID_CALLBACK"; + case OC_STACK_INVALID_METHOD: + return "OC_STACK_INVALID_METHOD"; + case OC_STACK_NO_MEMORY: + return "OC_STACK_NO_MEMORY"; + case OC_STACK_COMM_ERROR: + return "OC_STACK_COMM_ERROR"; + case OC_STACK_INVALID_PARAM: + return "OC_STACK_INVALID_PARAM"; + case OC_STACK_NOTIMPL: + return "OC_STACK_NOTIMPL"; + case OC_STACK_NO_RESOURCE: + return "OC_STACK_NO_RESOURCE"; + case OC_STACK_RESOURCE_ERROR: + return "OC_STACK_RESOURCE_ERROR"; + case OC_STACK_SLOW_RESOURCE: + return "OC_STACK_SLOW_RESOURCE"; + case OC_STACK_NO_OBSERVERS: + return "OC_STACK_NO_OBSERVERS"; + #ifdef WITH_PRESENCE + case OC_STACK_PRESENCE_STOPPED: + return "OC_STACK_PRESENCE_STOPPED"; + #endif + case OC_STACK_ERROR: + return "OC_STACK_ERROR"; + default: + return "UNKNOWN"; + } +} + +OCRepPayload* getPayload(const char* uri, int64_t power, bool state) +{ + OCRepPayload* payload = OCRepPayloadCreate(); + if(!payload) + { + OIC_LOG(ERROR, TAG, "Failed to allocate Payload"); + return NULL; + } + + OCRepPayloadSetUri(payload, uri); + OCRepPayloadSetPropBool(payload, "state", state); + OCRepPayloadSetPropInt(payload, "power", power); + + return payload; +} + +//This function takes the request as an input and returns the response +OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest) +{ + if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION) + { + OIC_LOG(ERROR, TAG, "Incoming payload not a representation"); + return NULL; + } + + OCRepPayload* input = (OCRepPayload*)(ehRequest->payload); + + LEDResource *currLEDResource = &LED; + + if (ehRequest->resource == gLedInstance[0].handle) + { + currLEDResource = &gLedInstance[0]; + gResourceUri = (char *) "/a/led/0"; + } + else if (ehRequest->resource == gLedInstance[1].handle) + { + currLEDResource = &gLedInstance[1]; + gResourceUri = (char *) "/a/led/1"; + } + + if(OC_REST_PUT == ehRequest->method) + { + // Get pointer to query + int64_t pow; + if(OCRepPayloadGetPropInt(input, "power", &pow)) + { + currLEDResource->power =pow; + } + + bool state; + if(OCRepPayloadGetPropBool(input, "state", &state)) + { + currLEDResource->state = state; + } + } + + return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state); +} + +OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload) +{ + OCEntityHandlerResult ehResult; + + OCRepPayload *getResp = constructResponse(ehRequest); + + if(getResp) + { + *payload = getResp; + ehResult = OC_EH_OK; + } + else + { + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload) +{ + OCEntityHandlerResult ehResult; + + OCRepPayload *putResp = constructResponse(ehRequest); + + if(putResp) + { + *payload = putResp; + ehResult = OC_EH_OK; + } + else + { + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, + OCEntityHandlerResponse *response, OCRepPayload **payload) +{ + OCRepPayload *respPLPost_led = NULL; + OCEntityHandlerResult ehResult = OC_EH_OK; + + /* + * The entity handler determines how to process a POST request. + * Per the REST paradigm, POST can also be used to update representation of existing + * resource or create a new resource. + * In the sample below, if the POST is for /a/led then a new instance of the LED + * resource is created with default representation (if representation is included in + * POST payload it can be used as initial values) as long as the instance is + * lesser than max new instance count. Once max instance count is reached, POST on + * /a/led updated the representation of /a/led (just like PUT) + */ + + if (ehRequest->resource == LED.handle) + { + if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE) + { + // Create new LED instance + char newLedUri[15] = "/a/led/"; + int newLedUriLength = strlen(newLedUri); + snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance); + + respPLPost_led = OCRepPayloadCreate(); + OCRepPayloadSetUri(respPLPost_led, gResourceUri); + OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri); + + if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0)) + { + OIC_LOG (INFO, TAG, "Created new LED instance"); + gLedInstance[gCurrLedInstance].state = 0; + gLedInstance[gCurrLedInstance].power = 0; + gCurrLedInstance++; + strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH); + ehResult = OC_EH_RESOURCE_CREATED; + } + } + else + { + respPLPost_led = constructResponse(ehRequest); + } + } + else + { + for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++) + { + if (ehRequest->resource == gLedInstance[i].handle) + { + if (i == 0) + { + respPLPost_led = constructResponse(ehRequest); + break; + } + else if (i == 1) + { + respPLPost_led = constructResponse(ehRequest); + } + } + } + } + + if (respPLPost_led != NULL) + { + *payload = respPLPost_led; + ehResult = OC_EH_OK; + } + else + { + OIC_LOG_V (INFO, TAG, "Payload was NULL"); + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult +OCEntityHandlerCb (OCEntityHandlerFlag flag, + OCEntityHandlerRequest *entityHandlerRequest, + void* callbackParam) +{ + OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag); + (void)callbackParam; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + OCEntityHandlerResponse response; + memset(&response, 0, sizeof(response)); + + // Validate pointer + if (!entityHandlerRequest) + { + OIC_LOG (ERROR, TAG, "Invalid request pointer"); + return OC_EH_ERROR; + } + + OCRepPayload* payload = NULL; + + if (flag & OC_REQUEST_FLAG) + { + OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG"); + if (entityHandlerRequest) + { + if (OC_REST_GET == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_GET from client"); + ehResult = ProcessGetRequest (entityHandlerRequest, &payload); + } + else if (OC_REST_PUT == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client"); + ehResult = ProcessPutRequest (entityHandlerRequest, &payload); + } + else if (OC_REST_POST == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_POST from client"); + ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload); + } + else + { + OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client", + entityHandlerRequest->method); + ehResult = OC_EH_ERROR; + } + + if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN) + { + // Format the response. Note this requires some info about the request + response.requestHandle = entityHandlerRequest->requestHandle; + response.resourceHandle = entityHandlerRequest->resource; + response.ehResult = ehResult; + response.payload = (OCPayload*)(payload); + response.numSendVendorSpecificHeaderOptions = 0; + memset(response.sendVendorSpecificHeaderOptions, 0, + sizeof(response.sendVendorSpecificHeaderOptions)); + memset(response.resourceUri, 0, sizeof(response.resourceUri)); + // Indicate that response is NOT in a persistent buffer + response.persistentBufferFlag = 0; + + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + ehResult = OC_EH_ERROR; + } + } + } + } + + OCPayloadDestroy(response.payload); + return ehResult; +} + +/* SIGINT handler: set gQuitFlag to 1 for graceful termination */ +void handleSigInt(int signum) +{ + if (signum == SIGINT) + { + gQuitFlag = 1; + } +} + +static void GetCurrentWorkingDirectory(char* buf, size_t bufsize) +{ + char cwd[1024] = {0}; + const char* unittest_path = "resource/csdk/security/provisioning/unittest"; + if(getcwd(cwd, sizeof(cwd)) != NULL) + { + if(strstr(cwd, unittest_path) == NULL) + { +#if defined __linux__ +#if __x86_64__ + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); +#else + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); +#endif //__x86_64__ +#endif //defined __linux__ + } + else + { + snprintf(buf, bufsize, "%s/", cwd); + } + } +} + +FILE* server_fopen(const char *path, const char *mode) +{ + (void)path; + char cwd[1024] = {0}; + char cred_path[1024] = {0}; + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(cred_path, "%s%s", cwd, CRED_FILE); + return fopen(cred_path, mode); +} + +int main() +{ + struct timespec timeout; + + //Delete previous SVR DB, if exist. + char cwd[1024] = {0}; + char cred_path[1024] = {0}; + char del_cmd[1024] = {0}; + FILE* fp = NULL; + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(del_cmd, "rm -rf %s%s", cwd, CRED_FILE); + system(del_cmd); + + //Generate default SVR DB. + sprintf(cred_path, "%s%s", cwd, CRED_FILE); + fp = fopen(cred_path, "w"); + if(NULL != fp) + { + size_t numberItems = fwrite(DEFAULT_SVR_DB, 1, sizeof(DEFAULT_SVR_DB), fp); + if(sizeof(DEFAULT_SVR_DB) != numberItems) + { + OIC_LOG_V(ERROR, TAG, "Failed to initialize SVR DB (%s)", cred_path); + fclose(fp); + return -1; + } + fclose(fp); + } + + OIC_LOG(DEBUG, TAG, "OCServer is starting..."); + + // Initialize Persistent Storage for SVR database + OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink}; + + OCRegisterPersistentStorageHandler(&ps); + + if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack init error"); + return 0; + } + + /* + * Declare and create the example resource: LED + */ + createLEDResource(gResourceUri, &LED, false, 0); + + timeout.tv_sec = 0; + timeout.tv_nsec = 100000000L; + + // Break from loop with Ctrl-C + OIC_LOG(INFO, TAG, "Entering ocserver main loop..."); + signal(SIGINT, handleSigInt); + while (!gQuitFlag) + { + if (OCProcess() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack process error"); + return 0; + } + nanosleep(&timeout, NULL); + } + + OIC_LOG(INFO, TAG, "Exiting ocserver main loop..."); + + if (OCStop() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack process error"); + } + + return 0; +} + +int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower) +{ + if (!uri) + { + OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL"); + return -1; + } + + ledResource->state = resourceState; + ledResource->power= resourcePower; + OCStackResult res = OCCreateResource(&(ledResource->handle), + "core.led", + OC_RSRVD_INTERFACE_DEFAULT, + uri, + OCEntityHandlerCb, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE); + OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res)); + + return 0; +} diff --git a/resource/csdk/security/provisioning/unittest/sampleserver2.cpp b/resource/csdk/security/provisioning/unittest/sampleserver2.cpp new file mode 100644 index 0000000..05f0f48 --- /dev/null +++ b/resource/csdk/security/provisioning/unittest/sampleserver2.cpp @@ -0,0 +1,583 @@ +/****************************************************************** +* +* 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. +* +******************************************************************/ +/////////////////////////////////////////////////////////////////////// +//NOTE : This sample server is generated based on ocserverbasicops.cpp +/////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include "ocstack.h" +#include "logger.h" +#include "ocpayload.h" +#include "oic_string.h" + +#define TAG "UNITTEST_SERVER_2" + +int gQuitFlag = 0; + +/* Structure to represent a LED resource */ +typedef struct LEDRESOURCE{ + OCResourceHandle handle; + bool state; + int power; +} LEDResource; + +static LEDResource LED; +// This variable determines instance number of the LED resource. +// Used by POST method to create a new instance of LED resource. +static int gCurrLedInstance = 0; +#define SAMPLE_MAX_NUM_POST_INSTANCE 2 +static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE]; + +char *gResourceUri= (char *)"/a/led"; + +//Secure Virtual Resource database for Iotivity Server +//It contains Server's Identity and the PSK credentials +//of other devices which the server trusts +static char CRED_FILE[] = "oic_svr_db_server2.dat"; + +static uint8_t DEFAULT_SVR_DB[] = { + 0xBF, 0x63, 0x61, 0x63, 0x6C, 0x59, 0x02, 0x76, 0xA2, 0x66, 0x61, 0x63, 0x6C, 0x69, 0x73, 0x74, + 0xA1, 0x64, 0x61, 0x63, 0x65, 0x73, 0x84, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, + 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x86, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x68, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, + 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, + 0x69, 0x63, 0x2F, 0x70, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, + 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6A, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, + 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, + 0x64, 0x68, 0x72, 0x65, 0x66, 0x70, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73, 0x2F, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2F, 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, + 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x63, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, + 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, + 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, + 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x84, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, + 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x64, 0x6F, 0x78, 0x6D, 0x63, 0x72, + 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, + 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x73, 0x74, 0x61, 0x74, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x61, 0x63, 0x6C, + 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, + 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x63, 0x72, 0x65, + 0x64, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, + 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, + 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x82, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, + 0x73, 0x65, 0x63, 0x2F, 0x70, 0x63, 0x6F, 0x6E, 0x66, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, + 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x71, 0x2F, 0x6F, 0x69, + 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x64, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x63, 0x72, + 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, + 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, + 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x81, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, + 0x2F, 0x76, 0x65, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x62, 0x72, 0x74, 0x60, 0x62, 0x69, 0x66, + 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0x6A, 0x72, 0x6F, + 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, + 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x65, 0x70, + 0x73, 0x74, 0x61, 0x74, 0x58, 0x79, 0xA7, 0x64, 0x69, 0x73, 0x6F, 0x70, 0xF4, 0x6A, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, + 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x62, 0x63, + 0x6D, 0x02, 0x62, 0x74, 0x6D, 0x00, 0x62, 0x6F, 0x6D, 0x03, 0x62, 0x73, 0x6D, 0x03, 0x6A, 0x72, + 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, + 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x64, + 0x64, 0x6F, 0x78, 0x6D, 0x58, 0xB6, 0xA8, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x81, 0x00, 0x66, 0x6F, + 0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65, + 0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, + 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, + 0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, + 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, + 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, + 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x63, 0x64, 0x70, 0x63, 0xF5, 0xFF +}; + +/* Function that creates a new LED resource by calling the + * OCCreateResource() method. + */ +int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower); + +/* This method converts the payload to JSON format */ +OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest); + +/* Following methods process the PUT, GET, POST + * requests + */ +OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload); +OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload); +OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, + OCEntityHandlerResponse *response, + OCRepPayload **payload); + +/* Entity Handler callback functions */ +OCEntityHandlerResult +OCEntityHandlerCb (OCEntityHandlerFlag flag, + OCEntityHandlerRequest *entityHandlerRequest, + void* callbackParam); + +const char *getResult(OCStackResult result) { + switch (result) { + case OC_STACK_OK: + return "OC_STACK_OK"; + case OC_STACK_RESOURCE_CREATED: + return "OC_STACK_RESOURCE_CREATED"; + case OC_STACK_RESOURCE_DELETED: + return "OC_STACK_RESOURCE_DELETED"; + case OC_STACK_INVALID_URI: + return "OC_STACK_INVALID_URI"; + case OC_STACK_INVALID_QUERY: + return "OC_STACK_INVALID_QUERY"; + case OC_STACK_INVALID_IP: + return "OC_STACK_INVALID_IP"; + case OC_STACK_INVALID_PORT: + return "OC_STACK_INVALID_PORT"; + case OC_STACK_INVALID_CALLBACK: + return "OC_STACK_INVALID_CALLBACK"; + case OC_STACK_INVALID_METHOD: + return "OC_STACK_INVALID_METHOD"; + case OC_STACK_NO_MEMORY: + return "OC_STACK_NO_MEMORY"; + case OC_STACK_COMM_ERROR: + return "OC_STACK_COMM_ERROR"; + case OC_STACK_INVALID_PARAM: + return "OC_STACK_INVALID_PARAM"; + case OC_STACK_NOTIMPL: + return "OC_STACK_NOTIMPL"; + case OC_STACK_NO_RESOURCE: + return "OC_STACK_NO_RESOURCE"; + case OC_STACK_RESOURCE_ERROR: + return "OC_STACK_RESOURCE_ERROR"; + case OC_STACK_SLOW_RESOURCE: + return "OC_STACK_SLOW_RESOURCE"; + case OC_STACK_NO_OBSERVERS: + return "OC_STACK_NO_OBSERVERS"; + #ifdef WITH_PRESENCE + case OC_STACK_PRESENCE_STOPPED: + return "OC_STACK_PRESENCE_STOPPED"; + #endif + case OC_STACK_ERROR: + return "OC_STACK_ERROR"; + default: + return "UNKNOWN"; + } +} + +OCRepPayload* getPayload(const char* uri, int64_t power, bool state) +{ + OCRepPayload* payload = OCRepPayloadCreate(); + if(!payload) + { + OIC_LOG(ERROR, TAG, "Failed to allocate Payload"); + return NULL; + } + + OCRepPayloadSetUri(payload, uri); + OCRepPayloadSetPropBool(payload, "state", state); + OCRepPayloadSetPropInt(payload, "power", power); + + return payload; +} + +//This function takes the request as an input and returns the response +OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest) +{ + if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION) + { + OIC_LOG(ERROR, TAG, "Incoming payload not a representation"); + return NULL; + } + + OCRepPayload* input = (OCRepPayload*)(ehRequest->payload); + + LEDResource *currLEDResource = &LED; + + if (ehRequest->resource == gLedInstance[0].handle) + { + currLEDResource = &gLedInstance[0]; + gResourceUri = (char *) "/a/led/0"; + } + else if (ehRequest->resource == gLedInstance[1].handle) + { + currLEDResource = &gLedInstance[1]; + gResourceUri = (char *) "/a/led/1"; + } + + if(OC_REST_PUT == ehRequest->method) + { + // Get pointer to query + int64_t pow; + if(OCRepPayloadGetPropInt(input, "power", &pow)) + { + currLEDResource->power =pow; + } + + bool state; + if(OCRepPayloadGetPropBool(input, "state", &state)) + { + currLEDResource->state = state; + } + } + + return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state); +} + +OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload) +{ + OCEntityHandlerResult ehResult; + + OCRepPayload *getResp = constructResponse(ehRequest); + + if(getResp) + { + *payload = getResp; + ehResult = OC_EH_OK; + } + else + { + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload) +{ + OCEntityHandlerResult ehResult; + + OCRepPayload *putResp = constructResponse(ehRequest); + + if(putResp) + { + *payload = putResp; + ehResult = OC_EH_OK; + } + else + { + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, + OCEntityHandlerResponse *response, OCRepPayload **payload) +{ + OCRepPayload *respPLPost_led = NULL; + OCEntityHandlerResult ehResult = OC_EH_OK; + + /* + * The entity handler determines how to process a POST request. + * Per the REST paradigm, POST can also be used to update representation of existing + * resource or create a new resource. + * In the sample below, if the POST is for /a/led then a new instance of the LED + * resource is created with default representation (if representation is included in + * POST payload it can be used as initial values) as long as the instance is + * lesser than max new instance count. Once max instance count is reached, POST on + * /a/led updated the representation of /a/led (just like PUT) + */ + + if (ehRequest->resource == LED.handle) + { + if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE) + { + // Create new LED instance + char newLedUri[15] = "/a/led/"; + int newLedUriLength = strlen(newLedUri); + snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance); + + respPLPost_led = OCRepPayloadCreate(); + OCRepPayloadSetUri(respPLPost_led, gResourceUri); + OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri); + + if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0)) + { + OIC_LOG (INFO, TAG, "Created new LED instance"); + gLedInstance[gCurrLedInstance].state = 0; + gLedInstance[gCurrLedInstance].power = 0; + gCurrLedInstance++; + strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH); + ehResult = OC_EH_RESOURCE_CREATED; + } + } + else + { + respPLPost_led = constructResponse(ehRequest); + } + } + else + { + for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++) + { + if (ehRequest->resource == gLedInstance[i].handle) + { + if (i == 0) + { + respPLPost_led = constructResponse(ehRequest); + break; + } + else if (i == 1) + { + respPLPost_led = constructResponse(ehRequest); + } + } + } + } + + if (respPLPost_led != NULL) + { + *payload = respPLPost_led; + ehResult = OC_EH_OK; + } + else + { + OIC_LOG_V (INFO, TAG, "Payload was NULL"); + ehResult = OC_EH_ERROR; + } + + return ehResult; +} + +OCEntityHandlerResult +OCEntityHandlerCb (OCEntityHandlerFlag flag, + OCEntityHandlerRequest *entityHandlerRequest, + void* callbackParam) +{ + OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag); + (void)callbackParam; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + OCEntityHandlerResponse response; + memset(&response, 0, sizeof(response)); + + // Validate pointer + if (!entityHandlerRequest) + { + OIC_LOG (ERROR, TAG, "Invalid request pointer"); + return OC_EH_ERROR; + } + + OCRepPayload* payload = NULL; + + if (flag & OC_REQUEST_FLAG) + { + OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG"); + if (entityHandlerRequest) + { + if (OC_REST_GET == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_GET from client"); + ehResult = ProcessGetRequest (entityHandlerRequest, &payload); + } + else if (OC_REST_PUT == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client"); + ehResult = ProcessPutRequest (entityHandlerRequest, &payload); + } + else if (OC_REST_POST == entityHandlerRequest->method) + { + OIC_LOG (INFO, TAG, "Received OC_REST_POST from client"); + ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload); + } + else + { + OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client", + entityHandlerRequest->method); + ehResult = OC_EH_ERROR; + } + + if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN) + { + // Format the response. Note this requires some info about the request + response.requestHandle = entityHandlerRequest->requestHandle; + response.resourceHandle = entityHandlerRequest->resource; + response.ehResult = ehResult; + response.payload = (OCPayload*)(payload); + response.numSendVendorSpecificHeaderOptions = 0; + memset(response.sendVendorSpecificHeaderOptions, 0, + sizeof(response.sendVendorSpecificHeaderOptions)); + memset(response.resourceUri, 0, sizeof(response.resourceUri)); + // Indicate that response is NOT in a persistent buffer + response.persistentBufferFlag = 0; + + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error sending response"); + ehResult = OC_EH_ERROR; + } + } + } + } + + OCPayloadDestroy(response.payload); + return ehResult; +} + +/* SIGINT handler: set gQuitFlag to 1 for graceful termination */ +void handleSigInt(int signum) +{ + if (signum == SIGINT) + { + gQuitFlag = 1; + } +} + +static void GetCurrentWorkingDirectory(char* buf, size_t bufsize) +{ + char cwd[1024] = {0}; + const char* unittest_path = "resource/csdk/security/provisioning/unittest"; + if(getcwd(cwd, sizeof(cwd)) != NULL) + { + if(strstr(cwd, unittest_path) == NULL) + { +#if defined __linux__ +#if __x86_64__ + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path); +#else + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); + snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path); +#endif //__x86_64__ +#endif //defined __linux__ + } + else + { + snprintf(buf, bufsize, "%s/", cwd); + } + } +} + +FILE* server_fopen(const char *path, const char *mode) +{ + (void)path; + char cwd[1024] = {0}; + char cred_path[1024] = {0}; + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(cred_path, "%s%s", cwd, CRED_FILE); + return fopen(cred_path, mode); +} + +int main() +{ + struct timespec timeout; + + //Delete previous SVR DB, if exist. + char cwd[1024] = {0}; + char cred_path[1024] = {0}; + char del_cmd[1024] = {0}; + FILE* fp = NULL; + GetCurrentWorkingDirectory(cwd, sizeof(cwd)); + sprintf(del_cmd, "rm -rf %s%s", cwd, CRED_FILE); + system(del_cmd); + + //Generate default SVR DB. + sprintf(cred_path, "%s%s", cwd, CRED_FILE); + fp = fopen(cred_path, "w"); + if(NULL != fp) + { + size_t numberItems = fwrite(DEFAULT_SVR_DB, 1, sizeof(DEFAULT_SVR_DB), fp); + if(sizeof(DEFAULT_SVR_DB) != numberItems) + { + OIC_LOG_V(ERROR, TAG, "Failed to initialize SVR DB (%s)", cred_path); + fclose(fp); + return -1; + } + fclose(fp); + } + + OIC_LOG(DEBUG, TAG, "OCServer is starting..."); + + // Initialize Persistent Storage for SVR database + OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink}; + + OCRegisterPersistentStorageHandler(&ps); + + if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack init error"); + return 0; + } + + /* + * Declare and create the example resource: LED + */ + createLEDResource(gResourceUri, &LED, false, 0); + + timeout.tv_sec = 0; + timeout.tv_nsec = 100000000L; + + // Break from loop with Ctrl-C + OIC_LOG(INFO, TAG, "Entering ocserver main loop..."); + signal(SIGINT, handleSigInt); + while (!gQuitFlag) + { + if (OCProcess() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack process error"); + return 0; + } + nanosleep(&timeout, NULL); + } + + OIC_LOG(INFO, TAG, "Exiting ocserver main loop..."); + + if (OCStop() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack process error"); + } + + return 0; +} + +int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower) +{ + if (!uri) + { + OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL"); + return -1; + } + + ledResource->state = resourceState; + ledResource->power= resourcePower; + OCStackResult res = OCCreateResource(&(ledResource->handle), + "core.led", + OC_RSRVD_INTERFACE_DEFAULT, + uri, + OCEntityHandlerCb, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE); + OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res)); + + return 0; +} -- 2.7.4