# For VS2013, MSVC_VERSION is '12.0'. For VS2015, MSVC_VERSION is '14.0'.
# Default value is None, meaning that SCons has to choose automatically a VS version.
help_vars.Add(EnumVariable('MSVC_VERSION', 'MSVC compiler version - Windows', None, allowed_values=('12.0', '14.0')))
+ help_vars.Add(EnumVariable('UWP_APP', 'Build for a Universal Windows Platform (UWP) Application', '0', allowed_values=('0', '1')))
help_vars.Add(BoolVariable('BUILD_JAVA', 'Build Java bindings', False))
help_vars.Add(PathVariable('JAVA_HOME', 'JDK directory', os.environ.get('JAVA_HOME'), PathVariable.PathAccept))
PREFIX = GetOption('prefix'),
LIB_INSTALL_DIR = ARGUMENTS.get('LIB_INSTALL_DIR') #for 64bit build
)
+
Help(help_vars.GenerateHelpText(env))
if env.get('WITH_ENV'):
# Set the source directory and build directory
# Source directory: 'dir'
# Build directory: 'dir'/out/<target_os>/<target_arch>/<release or debug>/
+# On windows, the build directory will be:
+# 'dir'/out/windows/<win32 or uwp>/<target_arch>/<release or debug>/
#
# You can get the directory as following:
# env.get('SRC_DIR')
''' % dir
Exit(1)
+ build_dir = dir + '/out/' + target_os + '/'
+
+ if target_os == 'windows':
+ if env.get('UWP_APP') == '1':
+ build_dir = build_dir + 'uwp/'
+ else:
+ build_dir = build_dir + 'win32/'
+
+ build_dir = build_dir + target_arch
+
if env.get('RELEASE'):
- build_dir = dir + '/out/' + target_os + '/' + target_arch + '/release/'
+ build_dir = build_dir + '/release/'
else:
- build_dir = dir + '/out/' + target_os + '/' + target_arch + '/debug/'
+ build_dir = build_dir + '/debug/'
+
env.VariantDir(build_dir, dir, duplicate=0)
env.Replace(BUILD_DIR = build_dir)
# Set common flags
if env['CC'] == 'cl':
+ if env.get('UWP_APP') == '1':
+ # Currently only supports VS2015 (14.0)
+ supported_uwp_msvc_versions = ['14.0']
+ # If MSVC_VERSION is not supported for UWP, exit on error
+ if env.get('MSVC_VERSION') not in supported_uwp_msvc_versions:
+ print '\nError: Trying to Build UWP binaries with unsupported Visual Studio version\n'
+ Exit(1)
+
# - warning C4133: incompatible type conversion
env.AppendUnique(CCFLAGS=['/we4133'])
env['PDB'] = '${TARGET.base}.pdb'
env.Append(LINKFLAGS=['/PDB:${TARGET.base}.pdb'])
- # Add Windows-specific libraries
- env.AppendUnique(LIBS = ['bcrypt', 'ws2_32', 'advapi32', 'iphlpapi', 'crypt32', 'kernel32'])
-
# Visual Studio compiler complains that functions like strncpy are unsafe. We
# are aware that it's possible to create a non-null terminated string using the
# strncpy function. However, the str*_s functions are not standard and thus
# See https://msdn.microsoft.com/en-us/library/ttcz0bys.aspx for more details.
env.AppendUnique(CPPDEFINES=['_CRT_SECURE_NO_WARNINGS', '_CRT_NONSTDC_NO_WARNINGS'])
+ if env.get('UWP_APP') != '1':
+ # Add Desktop specific libraries
+ env.AppendUnique(LIBS = ['bcrypt', 'ws2_32', 'advapi32', 'iphlpapi', 'crypt32', 'kernel32'])
+ else:
+ # Add Windows Universal Platform specific libraries and flags
+ # Note: We technically should set WINAPI_FAMILY=WINAPI_FAMILY_APP, but cannot
+ # due to [IOT-2312]. All APIs used are store/UWP compatible at this time.
+ env.AppendUnique(CPPDEFINES=['UWP_APP', '__WRL_NO_DEFAULT_LIB__'])
+ env.AppendUnique(LINKFLAGS=['/MANIFEST:NO', '/WINMD:NO', '/APPCONTAINER'])
+ env.AppendUnique(LIBS = ['WindowsApp', 'bcrypt', 'ws2_32', 'iphlpapi', 'crypt32'])
+
elif env['CC'] == 'gcc':
print "\nError: gcc not supported on Windows. Use Visual Studio!\n"
Exit(1);
''' % (str(target_os), str(target_arch))
- config_h_body = ''
-
config_h_footer = '''
/* Define to the full name of this package. */
''' % (str(lib_prefix + 'coap'), str(lib_prefix + 'coap ' + libcoap_version))
- cxx_headers = ['arpa/inet.h',
- 'assert.h',
- 'limits.h',
- 'netinet/in.h',
- 'stdio.h',
- 'strings.h',
- 'sys/select.h',
- 'sys/socket.h',
- 'sys/time.h',
- 'sys/types.h',
- 'sys/uio.h',
- 'sys/unistd.h',
- 'syslog.h',
- 'time.h',
- 'unistd.h',
- 'winsock2.h',
- 'ws2tcpip.h']
-
- cxx_functions = ['malloc',
- 'snprintf',
- 'strnlen',
- 'vprintf']
-
- if target_os == 'arduino':
- # Detection of headers on the Arduino platform is currently broken.
- cxx_headers = []
-
- def get_define_from_string(string):
- string_converted = string.replace("/","_").replace(".","_").upper()
- return "HAVE_" + string_converted
-
- for header_file_name in cxx_headers:
- if conf.CheckCXXHeader(header_file_name):
- config_h_body += "#define %s 1\n\n" % get_define_from_string(header_file_name)
-
- for function_name in cxx_functions:
- if conf.CheckFunc(function_name):
- config_h_body += "#define %s 1\n\n" % get_define_from_string(function_name)
-
- if conf.CheckCXXHeader('windows.h'):
- config_h_body += "#define ssize_t SSIZE_T\n\n"
- config_h_body += "#define in_port_t uint16_t\n\n"
-
- conf.Finish()
-
- # Autoconf feature doesn't work with Jenkins' arduino toolchain, so hardcode it here.
- if target_os == 'arduino':
- config_h_body += "#define HAVE_ARDUINO_TIME_H\n\n"
+ config_h_body = ''
+
+ if ((target_os == 'windows') and (libcoap_env.get('UWP_APP') == '1')):
+ # Workaround for libcoap config [Investigation in IOT-2234]:
+ # libcoap builds its config file by trying to create a small program to see if an API is
+ # available. However, when building with store libraries on windows, it doesn't seem
+ # to find malloc or strnlen APIs. On Windows, those APIs are guaranteed to be there,
+ # therefore, create the libcoap config_h_body with what is needed and expected to be
+ # there.
+ config_h_body = '''
+#define HAVE_ASSERT_H 1
+
+#define HAVE_LIMITS_H 1
+
+#define HAVE_STDIO_H 1
+
+#define HAVE_SYS_TYPES_H 1
+
+#define HAVE_TIME_H 1
+
+#define HAVE_WINSOCK2_H 1
+
+#define HAVE_WS2TCPIP_H 1
+
+#define HAVE_MALLOC 1
+
+#define HAVE_STRNLEN 1
+
+#define ssize_t SSIZE_T
+
+#define in_port_t uint16_t
+'''
+ else:
+ cxx_headers = ['arpa/inet.h',
+ 'assert.h',
+ 'limits.h',
+ 'netinet/in.h',
+ 'stdio.h',
+ 'strings.h',
+ 'sys/select.h',
+ 'sys/socket.h',
+ 'sys/time.h',
+ 'sys/types.h',
+ 'sys/uio.h',
+ 'sys/unistd.h',
+ 'syslog.h',
+ 'time.h',
+ 'unistd.h',
+ 'winsock2.h',
+ 'ws2tcpip.h']
+
+ cxx_functions = ['malloc',
+ 'snprintf',
+ 'strnlen',
+ 'vprintf']
+
+ if target_os == 'arduino':
+ # Detection of headers on the Arduino platform is currently broken.
+ cxx_headers = []
+
+ def get_define_from_string(string):
+ string_converted = string.replace("/","_").replace(".","_").upper()
+ return "HAVE_" + string_converted
+
+ for header_file_name in cxx_headers:
+ if conf.CheckCXXHeader(header_file_name):
+ config_h_body += "#define %s 1\n\n" % get_define_from_string(header_file_name)
+
+ for function_name in cxx_functions:
+ if conf.CheckFunc(function_name):
+ config_h_body += "#define %s 1\n\n" % get_define_from_string(function_name)
+
+ if conf.CheckCXXHeader('windows.h'):
+ config_h_body += "#define ssize_t SSIZE_T\n\n"
+ config_h_body += "#define in_port_t uint16_t\n\n"
+
+ conf.Finish()
+
+ # Autoconf feature doesn't work with Jenkins' arduino toolchain, so hardcode it here.
+ if target_os == 'arduino':
+ config_h_body += "#define HAVE_ARDUINO_TIME_H\n\n"
# Generate the file
if os.path.exists(config_h_file_path):
if target_os in ['windows']:
sqlite_env.AppendUnique(CCFLAGS = ['/W4', '/WX'])
+ if sqlite_env.get('UWP_APP') == '1':
+ sqlite_env.AppendUnique(CPPDEFINES=['SQLITE_OS_WINRT'])
libsqlite3 = sqlite_env.StaticLibrary('sqlite3', sqlite_c)
# In multi-threaded builds, SCons appears to proceed to using sqlite3.lib
# before finishing InstallTarget(libsqlite3, 'sqlite3') here. So, use the
if ipca_env['CC'] == 'cl':
ipca_env.AppendUnique(CCFLAGS=['/W4'])
+# c_common calls into mbedcrypto and ipca calls into c_common
+ipca_env.AppendUnique(LIBS = ['mbedcrypto'])
+
# Build ipca lib
SConscript('src/SConscript', 'ipca_env')
'oc'
])
-if ipca_env.get('SECURED') == '1':
+if ipca_lib_env.get('SECURED') == '1':
ipca_lib_env.PrependUnique(LIBS = [
'mbedtls',
'mbedx509',
- 'mbedcrypto',
'ocprovision'
])
using namespace std;
using namespace std::placeholders;
+#include <assert.h>
+#include <inttypes.h>
#include "oic_malloc.h"
#include "oic_time.h"
#include "OCApi.h"
#include "pinoxmcommon.h"
#include "srmutility.h"
#include "ocrandom.h"
+#include "oic_platform.h"
#define TAG "IPCA_OcfFramework"
#define DO_DEBUG 0
+#define PROVISIONING_DB "PDM.db"
+
const unsigned short c_discoveryTimeout = 5; // Max number of seconds to discover
// security information for a device
+// Path for Persistent Storage (Ends with backslash (\) or forward slash (/))
+std::string g_psPath;
+
// Initialize Persistent Storage for security database
FILE* server_fopen(const char *path, const char *mode)
{
- return fopen(path, mode);
+ // At this point, the persistent storage path should have been found, otherwise
+ // Start() should have failed.
+ std::string filePath(g_psPath);
+ // g_psPath ends with trailing backslash (\) or forward slash (/)
+ // so don't have to worry about adding it.
+ filePath.append(path);
+
+ return fopen(filePath.c_str(), mode);
}
OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
return IPCA_OK;
}
+ char* psPath = nullptr;
+ size_t psPathLen = 0;
+ OICPlatformResult_t ret = OICGetLocalAppDataPath(nullptr, &psPathLen);
+ if (ret == OIC_PLATFORM_OK)
+ {
+ psPath = static_cast<char*>(OICCalloc(1, psPathLen));
+ if (psPath == nullptr)
+ {
+ OIC_LOG(FATAL, TAG, "Could not allocate persistent storage path buffer");
+ return IPCA_OUT_OF_MEMORY;
+ }
+
+ ret = OICGetLocalAppDataPath(psPath, &psPathLen);
+ if (ret != OIC_PLATFORM_OK)
+ {
+ OIC_LOG_V(FATAL, TAG,
+ "Failed to get persistent storage path from OICGetLocalAppDataPath, ret: %"PRIuPTR,
+ static_cast<size_t>(ret));
+ OICFree(psPath);
+ return IPCA_FAIL;
+ }
+
+ g_psPath.assign(psPath);
+
+ OICFree(psPath);
+ psPath = nullptr;
+ }
+ else
+ {
+ // Continue if not implemented returned, g_psPath by default is an empty string.
+ // Otherwise, fail
+ if (ret != OIC_PLATFORM_NOTIMPL)
+ {
+ OIC_LOG_V(FATAL, TAG,
+ "Failed to get path length from OICGetLocalAppDataPath, ret: %"PRIuPTR,
+ static_cast<size_t>(ret));
+ // An error occurred, fail
+ return IPCA_FAIL;
+ }
+ }
+
PlatformConfig Configuration {
ServiceType::InProc,
ModeType::Both, // Server mode is required for security provisioning.
return IPCA_FAIL;
}
- // Initialize the database that will be used for provisioning
- if (OCSecure::provisionInit("") != OC_STACK_OK)
+
+ // Initialize the database that will be used for provisioning.
+ // Initialize it with the default PDM.db file name.
+ std::string pdmDbFile(g_psPath);
+ // g_psPath ends with trailing backslash (\) or forward slash (/)
+ // so don't have to worry about adding it.
+ pdmDbFile.append(PROVISIONING_DB);
+ if (OCSecure::provisionInit(pdmDbFile) != OC_STACK_OK)
{
OIC_LOG(FATAL, TAG, "Failed provisionInit()");
return IPCA_FAIL;
else:
common_src.append('ocatomic/src/others/ocatomic.c')
+if target_os in ['windows']:
+ common_src.append('oic_platform/src/windows/oic_winplatform.cpp')
+else:
+ common_src.append('oic_platform/src/others/oic_otherplatforms.c')
+
# C++ Arduino's <Timer.h> is included so use C++ compiler/flags
if target_os in ['arduino']:
octimer_env = common_env.Clone()
#define OIC_UUID_LENGTH 16
/**
+ * Declares OIC Platform Results & Errors.
+ */
+typedef enum
+{
+ /** Success status code.*/
+ OIC_PLATFORM_OK = 0,
+
+ /** Error status code - START HERE.*/
+ OIC_PLATFORM_INVALID_PARAM,
+ OIC_PLATFORM_NO_MEMORY,
+ OIC_PLATFORM_NOTIMPL,
+
+ /** Generic ERROR.*/
+ OIC_PLATFORM_ERROR = 255
+ /** Error status code - END HERE.*/
+} OICPlatformResult_t;
+
+/**
* Function returns a UUID that can be used for platform ID.
*
* @param[in] platformUuid The generated UUID.
*/
bool OICGetPlatformUuid(uint8_t platformUuid[OIC_UUID_LENGTH]);
+/**
+ * This function returns the platform and application specific local application data path.
+ * This path will be used to store the iotivity metadata. For example, the security databases.
+ * The path will contain the trailing backslash (\) or forward slash (/) and the null terminating
+ * character.
+ * To get the needed buffer size, call this function with buffer NULL.
+ *
+ * @param[out] buffer The buffer to store the path.
+ * @param[in,out] bufferLen The size of the buffer passed in. If buffer is NULL, the function will
+ * return the buffer size needed including the null character. If buffer
+ * passed in doesn't have sufficient size, then bufferLen will also be set
+ * to the buffer size needed.
+ *
+ * @return OIC_PLATFORM_OK on success, appropriate error code on failure.
+ */
+OICPlatformResult_t OICGetLocalAppDataPath(char* buffer, size_t* bufferLen);
+
+/**
+ * This function returns the platform and application specific data path for temporary files.
+ * This path will be used to store sqlite3 metadata that might need to be created temporarily.
+ * The path will contain the trailing backslash (\) or forward slash (/) and the null terminating
+ * character.
+ * To get the needed buffer size, call this function with buffer NULL.
+ *
+ * @param[out] buffer The buffer to store the path.
+ * @param[in,out] bufferLen The size of the buffer passed in. If buffer is NULL, the function will
+ * return the buffer size needed including the null character. If buffer
+ * passed in doesn't have sufficient size, then bufferLen will also be set
+ * to the buffer size needed.
+ *
+ * @return OIC_PLATFORM_OK on success, appropriate error code on failure.
+ */
+OICPlatformResult_t OICGetTempAppDataPath(char* buffer, size_t* bufferLen);
+
#ifdef __cplusplus
}
#endif // __cplusplus
--- /dev/null
+/* *****************************************************************
+*
+* Copyright 2017 Microsoft
+*
+*
+* 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 "iotivity_config.h"
+#include "iotivity_debug.h"
+#include "logger.h"
+#include "oic_platform.h"
+
+#define TAG "OIC_PLATFORM"
+
+OICPlatformResult_t OICGetLocalAppDataPath(char* buffer, size_t* bufferLen)
+{
+ OIC_LOG(WARNING, TAG, "Unsupported platform.");
+ OC_UNUSED(buffer);
+ OC_UNUSED(bufferLen);
+ return OIC_PLATFORM_NOTIMPL;
+}
+
+OICPlatformResult_t OICGetTempAppDataPath(char* buffer, size_t* bufferLen)
+{
+ OIC_LOG(WARNING, TAG, "Unsupported platform.");
+ OC_UNUSED(buffer);
+ OC_UNUSED(bufferLen);
+ return OIC_PLATFORM_NOTIMPL;
+}
--- /dev/null
+/* *****************************************************************
+*
+* Copyright 2017 Microsoft
+*
+*
+* 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 "iotivity_config.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <windows.h>
+#include <string>
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <inttypes.h>
+#include "logger.h"
+#include "iotivity_debug.h"
+#include "oic_platform.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+#ifdef UWP_APP
+#include <cstdint>
+#include <Windows.Foundation.h>
+#include <windows.storage.h>
+#include <wrl.h>
+
+using namespace ABI::Windows::Storage;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+#endif // UWP_APP
+
+#define TAG "OIC_PLATFORM"
+
+#define IOTIVITY_FOLDER_NAME "\\iotivity\\"
+
+using namespace std;
+
+#ifdef UWP_APP
+// This function converts a wide char string to a standard char string.
+static std::string ConvertWStrtoStr(PCWSTR wstr)
+{
+ std::string strRet;
+ char* str = nullptr;
+
+ int strLength = WideCharToMultiByte(
+ CP_UTF8,
+ WC_ERR_INVALID_CHARS,
+ wstr,
+ -1,
+ nullptr,
+ 0,
+ nullptr,
+ nullptr);
+
+ if (strLength == 0)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed WideCharToMultiByte(), GetLastError(): %u", GetLastError());
+ goto exit;
+ }
+
+ // strLength includes null char
+ str = static_cast<char*>(OICCalloc(1, strLength));
+ if (str == nullptr)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create str buffer");
+ goto exit;
+ }
+
+ int retLen = WideCharToMultiByte(
+ CP_UTF8,
+ 0,
+ wstr,
+ -1,
+ str,
+ strLength,
+ nullptr,
+ nullptr);
+
+ if (retLen != strLength)
+ {
+ OIC_LOG_V(ERROR, TAG, "WideCharToMultiByte failed to convert WSTR, GetLastError(): %u",
+ GetLastError());
+ goto exit;
+ }
+
+ strRet = str;
+
+exit:
+ if (str != nullptr)
+ {
+ OICFree(str);
+ }
+ return strRet;
+}
+#endif // UWP_APP
+
+static bool VerifyOrCreateDir(LPCSTR dir)
+{
+ if (!CreateDirectory(dir, nullptr))
+ {
+ DWORD err = GetLastError();
+ if (err != ERROR_ALREADY_EXISTS)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to CreateDirectory, GetLastError(): %u", err);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static OICPlatformResult_t GetSysLocalAppDataPath(std::string &path, size_t &sysPathLen, bool getTempDir)
+{
+ OICPlatformResult_t ret = OIC_PLATFORM_OK;
+
+#ifdef UWP_APP
+ HRESULT hr = S_OK;
+
+ // Since we are running in a UWP app, we don't need to initialize the Windows Runtime
+ // with RoInitialize
+ ComPtr<IApplicationDataStatics> appDataStatics;
+ hr = RoGetActivationFactory(HStringReference(L"Windows.Storage.ApplicationData").Get(),
+ __uuidof(appDataStatics), &appDataStatics);
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get the ActivationFactory, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+
+ ComPtr<IApplicationData> appData;
+ hr = appDataStatics->get_Current(&appData);
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get ApplicationData, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+
+ ComPtr<IStorageFolder> folder;
+ if (!getTempDir)
+ {
+ hr = appData->get_LocalFolder(&folder);
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get Local App StorageFolder, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+ }
+ else
+ {
+ hr = appData->get_TemporaryFolder(&folder);
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get Temp App StorageFolder, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+ }
+
+ ComPtr<IStorageItem> folderItem;
+ hr = folder.As(&folderItem);
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get StorageItem, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+
+ HString folderPathHString;
+ hr = folderItem->get_Path(folderPathHString.GetAddressOf());
+ if (FAILED(hr))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to get FolderPath, hr: %#x", hr);
+ return OIC_PLATFORM_ERROR;
+ }
+
+ uint32_t wstrPathLength;
+ PCWSTR folderPathWStr = folderPathHString.GetRawBuffer(&wstrPathLength);
+ path = ConvertWStrtoStr(folderPathWStr);
+ if (path.empty())
+ {
+ OIC_LOG(ERROR, TAG, "Failed to ConvertWStrtoStr");
+ return OIC_PLATFORM_ERROR;
+ }
+
+ // The length of the string that the system returned. All the folders up to this point
+ // should exist.
+ sysPathLen = path.length();
+#else // UWP_APP
+ // Unsupported for win32 apps
+ OIC_LOG(WARNING, TAG, "Unsupported platform.");
+ OC_UNUSED(path);
+ OC_UNUSED(sysPathLen);
+ OC_UNUSED(getTempDir);
+ ret = OIC_PLATFORM_NOTIMPL;
+#endif // UWP_APP
+
+ return ret;
+}
+
+// This function returns the platform and application specific local or temp application data path.
+// This path will be used to store the iotivity metadata.For example, the security databases.
+// The path will contain the trailing backslash(\) and the null terminating character.
+// To get the needed buffer size, call this function with buffer NULL.
+static OICPlatformResult_t GetLocalAppDataPath(std::string &path, bool getTempDir, char* buffer, size_t* bufferLen)
+{
+ if (bufferLen == nullptr)
+ {
+ OIC_LOG(ERROR, TAG, "bufferLen is NULL");
+ return OIC_PLATFORM_INVALID_PARAM;
+ }
+
+ if (path.empty())
+ {
+ // The length of the string that the system returned. All the folders up to this point
+ // should exist.
+ size_t sysPathLen;
+ OICPlatformResult_t ret = GetSysLocalAppDataPath(path, sysPathLen, getTempDir);
+ // Set path to the appropriate system local or temp application data path
+ if (ret != OIC_PLATFORM_OK)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to GetSysLocalAppDataPath, ret: %"PRIuPTR,
+ static_cast<size_t>(ret));
+ // On failure, path should be cleared in GetSysLocalAppDataPath
+ return ret;
+ }
+
+ // Append \iotivity\ for UWP and Win32
+ path.append(IOTIVITY_FOLDER_NAME);
+
+ if (path[path.length() - 1] != '\\')
+ {
+ path.append("\\");
+ }
+
+ // At this point, the path should end with backslash (\)
+ // Verify/Create all the folders in the path.
+ // Start searching from after the path retrieved from the system APIs
+ size_t prevSlashIdx = 0;
+ size_t slashIdx = path.find("\\", sysPathLen);
+ while (slashIdx != string::npos)
+ {
+ std::string dir = path.substr(0, slashIdx);
+ if (!VerifyOrCreateDir(dir.c_str()))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to VerifyOrCreateDir %s", dir.c_str());
+ // Revert path back to default state as we cannot create an
+ // intermediate folder
+ path.clear();
+ return OIC_PLATFORM_ERROR;
+ }
+ prevSlashIdx = slashIdx;
+ slashIdx = path.find("\\", slashIdx + 1);
+ }
+
+ if (prevSlashIdx != (path.length() - 1))
+ {
+ // Verify/Create the last folder
+ if (!VerifyOrCreateDir(path.c_str()))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to VerifyOrCreateDir %s", path.c_str());
+ // Revert path back to default state as we cannot create an
+ // intermediate folder
+ path.clear();
+ return OIC_PLATFORM_ERROR;
+ }
+ }
+ }
+
+ if (path.empty())
+ {
+ // Path shouldn't be empty at this point
+ OIC_LOG(ERROR, TAG, "Path is empty");
+ return OIC_PLATFORM_ERROR;
+ }
+
+ if (buffer != nullptr)
+ {
+ if (*bufferLen < (path.length() + 1))
+ {
+ // Insufficient buffer size for path string
+ OIC_LOG(ERROR, TAG, "Insufficient buffer size for path string");
+ *bufferLen = path.length() + 1; // + 1 for null-character
+ return OIC_PLATFORM_INVALID_PARAM;
+ }
+ OICStrcpy(buffer, *bufferLen, path.c_str());
+ *bufferLen = path.length() + 1; // + 1 for null-character
+ }
+ else
+ {
+ *bufferLen = path.length() + 1; // + 1 for null-character
+ }
+
+ return OIC_PLATFORM_OK;
+}
+
+// This function returns the platform and application specific local application data path.
+// This path will be used to store the iotivity metadata.For example, the security databases.
+// The path will contain the trailing backslash(\) and the null terminating character.
+// To get the needed buffer size, call this function with buffer NULL.
+OICPlatformResult_t OICGetLocalAppDataPath(char* buffer, size_t* bufferLen)
+{
+ static std::string localAppDataPath;
+ return GetLocalAppDataPath(localAppDataPath, false, buffer, bufferLen);
+}
+
+// This function returns the platform and application specific temp application data path.
+// This path will be used to store the iotivity metadata.For example, the security databases.
+// The path will contain the trailing backslash(\) and the null terminating character.
+// To get the needed buffer size, call this function with buffer NULL.
+OICPlatformResult_t OICGetTempAppDataPath(char* buffer, size_t* bufferLen)
+{
+ static std::string tempAppDataPath;
+ return GetLocalAppDataPath(tempAppDataPath, true, buffer, bufferLen);
+}
if target_os not in ['linux', 'tizen', 'windows']:
liboctbstack_src.append('#extlibs/sqlite3/sqlite3.c')
+if ((target_os in ['windows']) and (liboctbstack_env.get('UWP_APP') == '1')):
+ liboctbstack_src.append(OCTBSTACK_SRC + 'ocsqlite3helper.c')
+
internal_liboctbstack = liboctbstack_env.StaticLibrary('octbstack_internal', liboctbstack_src)
octbstack_libs = Flatten(internal_liboctbstack)
--- /dev/null
+/* *****************************************************************
+*
+* Copyright 2017 Microsoft
+*
+*
+* 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.
+*
+******************************************************************/
+
+#ifndef SQLITE3_HELPER_H__
+#define SQLITE3_HELPER_H__
+
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef UWP_APP
+OCStackResult InitSqlite3TempDir();
+#endif // UWP_APP
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SQLITE3_HELPER_H__
+
--- /dev/null
+/* *****************************************************************
+*
+* Copyright 2017 Microsoft
+*
+*
+* 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.
+*
+******************************************************************/
+
+#ifdef UWP_APP
+#include <inttypes.h>
+#include "ocsqlite3helper.h"
+#include "logger.h"
+#include "oic_platform.h"
+#include "oic_malloc.h"
+#include "sqlite3.h"
+
+OCStackResult InitSqlite3TempDir()
+{
+ OCStackResult result = OC_STACK_OK;
+
+ size_t tempSqlite3DirLen = 0;
+ char *tempSqlite3Dir = NULL;
+ OICPlatformResult_t ret = OICGetTempAppDataPath(NULL, &tempSqlite3DirLen);
+ if (ret == OIC_PLATFORM_OK)
+ {
+ tempSqlite3Dir = (char*)OICCalloc(1, tempSqlite3DirLen);
+ if (tempSqlite3Dir == NULL)
+ {
+ OIC_LOG(FATAL, TAG, "Could not allocate temp path buffer");
+ result = OC_STACK_NO_MEMORY;
+ goto exit;
+ }
+
+ ret = OICGetTempAppDataPath(tempSqlite3Dir, &tempSqlite3DirLen);
+ if (ret != OIC_PLATFORM_OK)
+ {
+ OIC_LOG_V(FATAL, TAG,
+ "Failed to get temp path from OICGetTempAppDataPath, ret: %"PRIuPTR, (size_t)ret);
+ result = OC_STACK_ERROR;
+ goto exit;
+ }
+
+ // Set the temp directory for sqlite3
+ sqlite3_temp_directory = sqlite3_mprintf("%s", tempSqlite3Dir);
+ }
+ else
+ {
+ // Return success if not implemented returned, otherwise, fail
+ if (ret != OIC_PLATFORM_NOTIMPL)
+ {
+ // An error occurred, fail
+ OIC_LOG_V(FATAL, TAG,
+ "Failed to get temp path length from OICGetTempAppDataPath, ret: %"PRIuPTR,
+ (size_t)ret);
+ result = OC_STACK_ERROR;
+ }
+ }
+
+exit:
+ if (tempSqlite3Dir != NULL)
+ {
+ OICFree(tempSqlite3Dir);
+ }
+
+ return result;
+}
+#endif // UWP_APP
#include "platform_features.h"
#include "oic_platform.h"
+#ifdef UWP_APP
+#include "ocsqlite3helper.h"
+#endif // UWP_APP
+
#if defined(TCP_ADAPTER) && defined(WITH_CLOUD)
#include "occonnectionmanager.h"
#endif
defaultDeviceHandler = NULL;
defaultDeviceHandlerCallbackParameter = NULL;
+#ifdef UWP_APP
+ result = InitSqlite3TempDir();
+ VERIFY_SUCCESS(result, OC_STACK_OK);
+#endif // UWP_APP
+
result = InitializeScheduleResourceList();
VERIFY_SUCCESS(result, OC_STACK_OK);
if target_os in ['msys_nt', 'windows']:
winUIClient = examples_env.Program('winUIClient', ['winuiclientgui.cpp', 'winuiclient.cpp'])
- mediaserver = examples_env.Program('mediaserver', 'mediaserver.cpp')
- examples += [winUIClient, mediaserver]
+ examples += [winUIClient]
+ # mediaserver uses GetVersionEx which is a windows native/desktop only API.
+ # Only build for Native/Win32
+ if env.get('UWP_APP') != '1':
+ mediaserver = examples_env.Program('mediaserver', 'mediaserver.cpp')
+ examples += [mediaserver]
Alias("examples", examples)
examples_env.AppendTarget('examples')
target_os = env.get('TARGET_OS')
-if target_os in ['linux', 'windows', 'darwin', 'msys_nt']:
+build_tests = False
+
+if target_os in ['windows']:
+ # gtest has a lot of windows native/desktop only APIs. As all unit tests depend on gtest,
+ # only enable unit tests if building for Win32.
+ if env.get('UWP_APP') != '1':
+ build_tests = True
+elif target_os in ['darwin', 'linux', 'msys_nt']:
+ build_tests = True
+
+if build_tests:
# Verify that 'google unit test' library is installed. If not,
# get it and install it
test_env = SConscript('#extlibs/gtest/SConscript')
set MULTIPLE_OWNER=1
)
+if "%UWP_APP%" == "" (
+ REM Set it to build Win32 app by default
+ set UWP_APP=0
+)
+
set THREAD_COUNT=%NUMBER_OF_PROCESSORS%
set ROUTING=EP
IF /I "%1"=="-automaticUpdate" (
set AUTOMATIC_UPDATE=1
)
+ IF /I "%1"=="-uwp" (
+ set UWP_APP=1
+ )
SHIFT
GOTO :processArgs
set BINDIR=release
)
+set BUILD_VARIANT=win32
+if "%UWP_APP%" == "1" (
+ set BUILD_VARIANT=uwp
+)
+
REM We need to append the "PATH" so the octbstack.dll can be found by executables
IF "%BUILD_MSYS%" == "" (
- set BUILD_DIR=out\windows\%TARGET_ARCH%\%BINDIR%
+ set BUILD_DIR=out\windows\%BUILD_VARIANT%\%TARGET_ARCH%\%BINDIR%
set PATH=!PATH!;!IOTIVITY_DIR!!BUILD_DIR!;
) ELSE (
set BUILD_DIR=out\msys_nt\x86_64\%BINDIR%
set PATH=!PATH!;!BUILD_DIR!;C:\msys64\mingw64\bin
)
-set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% TEST=%TEST% RD_MODE=%RD_MODE% ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP% MULTIPLE_OWNER=%MULTIPLE_OWNER% -j %THREAD_COUNT% AUTOMATIC_UPDATE=%AUTOMATIC_UPDATE%
+set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% UWP_APP=%UWP_APP% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% TEST=%TEST% RD_MODE=%RD_MODE% ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP% MULTIPLE_OWNER=%MULTIPLE_OWNER% -j %THREAD_COUNT% AUTOMATIC_UPDATE=%AUTOMATIC_UPDATE%
REM Use MSVC_VERSION=12.0 for VS2013, or MSVC_VERSION=14.0 for VS2015.
REM If MSVC_VERSION has not been defined here, SCons chooses automatically a VS version.
echo Starting IoTivity build with these options:
echo TARGET_OS=%TARGET_OS%
echo TARGET_ARCH=%TARGET_ARCH%
+ echo UWP_APP=%UWP_APP%
+ echo BUILD_DIR=%BUILD_DIR%
echo SECURED=%SECURED%
echo RELEASE=%RELEASE%
echo TEST=%TEST%
if ERRORLEVEL 1 (
echo SCons failed - exiting run.bat with code 3
exit /B 3
- )
+ )
) else if "!RUN_ARG!"=="clean" (
+ echo Cleaning IoTivity build
del /S *.ilk
call scons.bat VERBOSE=1 %BUILD_OPTIONS% -c
if ERRORLEVEL 1 (
echo SCons failed - exiting run.bat with code 2
exit /B 2
- )
+ )
) else if "!RUN_ARG!"=="cleangtest" (
rd /s /q extlibs\gtest\googletest-release-1.7.0
del extlibs\gtest\release-1.7.0.zip
) else (
- echo.%0 - Script requires a valid argument!
- echo Exiting run.bat with code 1
- exit /B 1
+ echo.%0 - Script requires a valid argument!
+ echo Exiting run.bat with code 1
+ exit /B 1
)
cd %IOTIVITY_DIR%
echo.
echo -automaticUpdate - Automatically update libcoap to required version.
echo.
+echo -uwp - Build for the Universal Windows Platform (UWP).
+echo.
echo.
echo. Usage examples:
echo.