Implement JS to TEEC binding 00/156200/3 accepted/tizen_5.5_unified accepted/tizen_5.5_unified_mobile_hotfix accepted/tizen_5.5_unified_wearable_hotfix tizen_5.5 tizen_5.5_mobile_hotfix tizen_5.5_tv tizen_5.5_wearable_hotfix accepted/tizen/4.0/unified/20171018.232143 accepted/tizen/5.0/unified/20181102.023041 accepted/tizen/5.5/unified/20191031.005603 accepted/tizen/5.5/unified/mobile/hotfix/20201027.062512 accepted/tizen/5.5/unified/wearable/hotfix/20201027.102707 accepted/tizen/unified/20171019.061041 accepted/tizen/unified/20171020.092055 submit/tizen/20171018.120842 submit/tizen/20171020.061629 submit/tizen/20171020.082002 submit/tizen_4.0/20171018.121104 submit/tizen_5.0/20181101.000005 submit/tizen_5.5/20191031.000006 submit/tizen_5.5_mobile_hotfix/20201026.185106 submit/tizen_5.5_wearable_hotfix/20201026.184306 tizen_4.0.IoT.p2_release tizen_4.0.m2_release tizen_5.5.m2_release
authorLukasz Kostyra <l.kostyra@samsung.com>
Thu, 21 Sep 2017 15:52:41 +0000 (17:52 +0200)
committerLukasz Kostyra <l.kostyra@samsung.com>
Wed, 18 Oct 2017 10:36:01 +0000 (12:36 +0200)
Change-Id: I44e6c174493e92024cd031cbfebf15c4073482c8

19 files changed:
packaging/webapi-plugins-teec.spec
src/teec/TeecContext.cc [new file with mode: 0644]
src/teec/TeecContext.h [new file with mode: 0644]
src/teec/TeecManager.cc [new file with mode: 0644]
src/teec/TeecManager.h [new file with mode: 0644]
src/teec/TeecSession.cc [new file with mode: 0644]
src/teec/TeecSession.h [new file with mode: 0644]
src/teec/TeecSharedMemory.cc [new file with mode: 0644]
src/teec/TeecSharedMemory.h [new file with mode: 0644]
src/teec/TeecTempMemoryAllocator.cc [new file with mode: 0644]
src/teec/TeecTempMemoryAllocator.h [new file with mode: 0644]
src/teec/TeecTranslations.cc [new file with mode: 0644]
src/teec/TeecTranslations.h [new file with mode: 0644]
src/teec/libteec_api.js
src/teec/libteec_extension.cc
src/teec/libteec_extension.h
src/teec/libteec_instance.cc
src/teec/libteec_instance.h
src/teec/teec.gyp

index 4a0ea10..04ae34b 100644 (file)
@@ -25,7 +25,7 @@ Source0:    %{name}-%{version}.tar.gz
 
 BuildRequires: ninja
 BuildRequires: pkgconfig(webapi-plugins)
-BuildRequires: tef-libteec
+BuildRequires: pkgconfig(tef-libteec)
 
 %description
 Tizen TEF Framework Client API plugin
diff --git a/src/teec/TeecContext.cc b/src/teec/TeecContext.cc
new file mode 100644 (file)
index 0000000..280db24
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecContext class methods definition
+ */
+
+#include "TeecContext.h"
+#include "TeecTranslations.h"
+
+#include <algorithm>
+#include <common/platform_exception.h>
+
+
+namespace {
+
+// removes all dashes from UUID string to unify it (if there are any)
+std::string UnifyUUID(const std::string& uuid) {
+    std::string result = uuid;
+    result.erase(std::remove(result.begin(), result.end(), '-'), result.end());
+    return result;
+}
+
+// generates new ID for shared memory
+std::string GenerateShmemID() {
+    static uint64_t counter = 0;
+    return "shmem-" + std::to_string(counter++);
+}
+
+} // namespace
+
+namespace extension {
+namespace libteec {
+
+TeecContext::TeecContext(const std::string& name) {
+    TEEC_Result ret = TEEC_InitializeContext(name.empty() ? NULL : name.c_str(), &mContext);
+    if (ret != TEEC_SUCCESS) {
+        throw common::NotSupportedException("Failed to initialize context: " +
+                                            translations::TeecResultToString(ret));
+    }
+}
+
+TeecContext::~TeecContext() {
+    mSessions.clear();
+    mSharedMemories.clear();
+    TEEC_FinalizeContext(&mContext);
+}
+
+std::string TeecContext::OpenSession(const std::string& uuidstr, uint32_t connectionMethod,
+                                     const void* connectionData, TEEC_Operation* operation,
+                                     uint32_t* returnOrigin) {
+    std::string uuid = UnifyUUID(uuidstr);
+    auto it = mSessions.find(uuid);
+    if (it == mSessions.end()) {
+        mSessions.emplace(uuid, std::make_shared<TeecSession>(&mContext, uuid, connectionMethod,
+                                                              connectionData, operation, returnOrigin));
+        return uuid;
+    } else {
+        throw common::InvalidValuesException("Session for TA " + uuidstr + " already exists");
+    }
+}
+
+TeecSessionPtr TeecContext::GetSession(const std::string& id) const {
+    std::string uuid = UnifyUUID(id);
+    auto it = mSessions.find(uuid);
+    if (it == mSessions.end()) {
+        throw common::InvalidValuesException("Session for TA " + id + " does not exist");
+    }
+
+    return it->second;
+}
+
+void TeecContext::CloseSession(const std::string& id) {
+    std::string uuid = UnifyUUID(id);
+    mSessions.erase(uuid);
+}
+
+std::string TeecContext::CreateSharedMemory(size_t size, uint32_t flags) {
+    std::string id = GenerateShmemID();
+    mSharedMemories.emplace(id, std::make_shared<TeecSharedMemory>(&mContext, size, flags));
+    return id;
+}
+
+std::string TeecContext::CreateSharedMemory(void* buffer, size_t size, uint32_t flags) {
+    std::string id = GenerateShmemID();
+    mSharedMemories.emplace(id, std::make_shared<TeecSharedMemory>(&mContext, buffer, size, flags));
+    return id;
+}
+
+TeecSharedMemoryPtr TeecContext::GetSharedMemory(const std::string& memId) const {
+    auto it = mSharedMemories.find(memId);
+    if (it == mSharedMemories.end()) {
+        throw common::InvalidValuesException("Shared memory " + memId + " does not exist");
+    }
+    return it->second;
+}
+
+void TeecContext::ReleaseSharedMemory(const std::string& memId) {
+    mSharedMemories.erase(memId);
+}
+
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecContext.h b/src/teec/TeecContext.h
new file mode 100644 (file)
index 0000000..2a5f73f
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecContext class declaration
+ */
+
+#ifndef LIBTEEC_TEEC_CONTEXT_H_
+#define LIBTEEC_TEEC_CONTEXT_H_
+
+#include "TeecSession.h"
+#include "TeecSharedMemory.h"
+
+#include <unordered_map>
+#include <string>
+#include <tee_client_api.h>
+
+
+namespace extension {
+namespace libteec {
+
+using TeecSessionMap = std::unordered_map<std::string, TeecSessionPtr>;
+using TeecSharedMemoryMap = std::unordered_map<std::string, TeecSharedMemoryPtr>;
+
+class TeecContext final
+{
+public:
+    TeecContext(const std::string& id);
+    ~TeecContext();
+
+    // returns session ID used to recognize sessions in GetSession and CloseSession
+    std::string OpenSession(const std::string& uuidstr, uint32_t connectionMethod,
+                            const void* connectionData, TEEC_Operation* operation,
+                            uint32_t* returnOrigin);
+    TeecSessionPtr GetSession(const std::string& id) const;
+    void CloseSession(const std::string& id);
+
+    // returns memory ID used to recognise the memory further down the road
+    std::string CreateSharedMemory(size_t size, uint32_t flags);
+    std::string CreateSharedMemory(void* buffer, size_t size, uint32_t flags);
+    TeecSharedMemoryPtr GetSharedMemory(const std::string& memId) const;
+    void ReleaseSharedMemory(const std::string& memId);
+
+private:
+    TEEC_Context mContext;
+    TeecSessionMap mSessions;
+    TeecSharedMemoryMap mSharedMemories;
+};
+
+using TeecContextPtr = std::shared_ptr<TeecContext>;
+
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_CONTEXT_H_
\ No newline at end of file
diff --git a/src/teec/TeecManager.cc b/src/teec/TeecManager.cc
new file mode 100644 (file)
index 0000000..826f20b
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecManager singleton class methods definition
+ */
+
+#include "TeecManager.h"
+
+#include <common/platform_exception.h>
+
+
+namespace {
+
+static uint32_t opIDCounter = 0;
+
+} // namespace
+
+namespace extension {
+namespace libteec {
+
+TeecManager& TeecManager::Instance() {
+    static TeecManager manager;
+    return manager;
+}
+
+TeecContextPtr TeecManager::GetContext(const std::string& contextName) {
+    auto it = mContexts.find(contextName);
+    if (it == mContexts.end()) {
+        // no context - create new
+        TeecContextPtr context = std::make_shared<TeecContext>(contextName);
+        it = mContexts.insert(std::make_pair(contextName, context)).first;
+    }
+
+    return it->second;
+}
+
+uint32_t TeecManager::CreateOperation() {
+    std::lock_guard<std::mutex> lock(mOperationListMutex);
+    opIDCounter++;
+    mOperations.emplace(opIDCounter, TEEC_Operation());
+    return opIDCounter;
+}
+
+TEEC_Operation TeecManager::GetOperation(uint32_t id) const {
+    std::lock_guard<std::mutex> lock(mOperationListMutex);
+    auto it = mOperations.find(id);
+    if (it == mOperations.end()) {
+        throw common::InvalidValuesException("Operation " + std::to_string(id) + " not found");
+    }
+    return it->second;
+}
+
+void TeecManager::RemoveOperation(uint32_t id) {
+    std::lock_guard<std::mutex> lock(mOperationListMutex);
+    mOperations.erase(id);
+}
+
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecManager.h b/src/teec/TeecManager.h
new file mode 100644 (file)
index 0000000..c7cc768
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecManager singleton class declaration
+ */
+
+#ifndef LIBTEEC_TEEC_MANAGER_H_
+#define LIBTEEC_TEEC_MANAGER_H_
+
+#include <unordered_map>
+#include <list>
+#include <string>
+#include <memory>
+#include <mutex>
+#include <tee_client_api.h>
+
+#include "TeecContext.h"
+
+
+namespace extension {
+namespace libteec {
+
+using TeecContextMap = std::unordered_map<std::string, TeecContextPtr>;
+using TeecOperationMap = std::unordered_map<uint32_t, TEEC_Operation>;
+
+class TeecManager final
+{
+public:
+    static TeecManager& Instance();
+
+    TeecContextPtr GetContext(const std::string& contextName);
+
+    uint32_t CreateOperation();
+    TEEC_Operation GetOperation(uint32_t id) const;
+    void RemoveOperation(uint32_t id);
+
+private:
+    TeecManager() = default;
+    ~TeecManager() = default;
+    TeecManager(const TeecManager&) = delete;
+    TeecManager(TeecManager&&) = delete;
+    TeecManager& operator=(const TeecManager&) = delete;
+    TeecManager& operator=(TeecManager&&) = delete;
+
+    TeecContextMap mContexts;
+    TeecOperationMap mOperations;
+    mutable std::mutex mOperationListMutex;
+};
+
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_MANAGER_H_
\ No newline at end of file
diff --git a/src/teec/TeecSession.cc b/src/teec/TeecSession.cc
new file mode 100644 (file)
index 0000000..8917652
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecSession class methods definition
+ */
+
+#include "TeecSession.h"
+#include "TeecTranslations.h"
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+
+namespace {
+
+const uint32_t UUID_UNIFIED_LENGTH = 32;
+
+// assumes UUID already was unified by TeecContext
+TEEC_UUID StringToUUID(const std::string& uuidstr) {
+    if (uuidstr.size() != UUID_UNIFIED_LENGTH) {
+        throw common::InvalidValuesException("Bad UUID provided: " + uuidstr);
+    }
+
+    TEEC_UUID uuid;
+    uuid.timeLow = std::stoul(uuidstr.substr(0, 8), 0, 16);
+    uuid.timeMid = static_cast<uint16_t>(std::stoul(uuidstr.substr(8, 4), 0, 16));
+    uuid.timeHiAndVersion = static_cast<uint16_t>(std::stoul(uuidstr.substr(12, 4), 0, 16));
+
+    uint32_t stringPos = 16;
+    for (uint32_t i = 0; i < 8; ++i) {
+        uuid.clockSeqAndNode[i] = static_cast<uint8_t>(std::stoul(uuidstr.substr(stringPos, 2), 0, 16));
+        stringPos += 2;
+    }
+
+    return uuid;
+}
+
+} // namespace
+
+namespace extension {
+namespace libteec {
+
+TeecSession::TeecSession(TEEC_Context* ctx, const std::string& uuidstr,
+                        uint32_t connectionMethod, const void* connectionData,
+                        TEEC_Operation* operation, uint32_t* returnOrigin) {
+    TEEC_UUID uuid = StringToUUID(uuidstr);
+    TEEC_Result result = TEEC_OpenSession(ctx, &mSession, &uuid, connectionMethod,
+                                          connectionData, operation, returnOrigin);
+    if (result != TEEC_SUCCESS) {
+        throw common::InvalidValuesException("TEEC Session failed to open: " +
+                                             translations::TeecResultToString(result));
+    }
+}
+
+TeecSession::~TeecSession() {
+    TEEC_CloseSession(&mSession);
+}
+
+void TeecSession::InvokeCommand(uint32_t cmd, TEEC_Operation* op, uint32_t* returnOrigin) {
+    TEEC_Result result = TEEC_InvokeCommand(&mSession, cmd, op, returnOrigin);
+    if (result != TEEC_SUCCESS) {
+        throw common::InvalidValuesException("Failure while invoking command " +
+                                             std::to_string(cmd) + ": " +
+                                             translations::TeecResultToString(result));
+    }
+}
+
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecSession.h b/src/teec/TeecSession.h
new file mode 100644 (file)
index 0000000..141c427
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecSession class declaration
+ */
+
+#ifndef LIBTEEC_TEEC_SESSION_H_
+#define LIBTEEC_TEEC_SESSION_H_
+
+#include <string>
+#include <memory>
+#include <tee_client_api.h>
+
+namespace extension {
+namespace libteec {
+
+class TeecSession final
+{
+public:
+    TeecSession(TEEC_Context* ctx, const std::string& uuidstr,
+                uint32_t connectionMethod, const void* connectionData,
+                TEEC_Operation* operation, uint32_t* returnOrigin);
+    ~TeecSession();
+
+    void InvokeCommand(uint32_t cmd, TEEC_Operation* op, uint32_t* returnOrigin);
+
+private:
+    TEEC_Session mSession;
+};
+
+using TeecSessionPtr = std::shared_ptr<TeecSession>;
+
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_SESSION_H_
\ No newline at end of file
diff --git a/src/teec/TeecSharedMemory.cc b/src/teec/TeecSharedMemory.cc
new file mode 100644 (file)
index 0000000..438bb79
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecSharedMemory class methods definition
+ */
+
+#include "TeecSharedMemory.h"
+#include "TeecTranslations.h"
+
+#include <string>
+#include "common/platform_exception.h"
+
+
+namespace extension {
+namespace libteec {
+
+TeecSharedMemory::TeecSharedMemory(TEEC_Context* ctx, size_t size, uint32_t flags) {
+    mMemory.buffer = nullptr;
+    mMemory.size = size;
+    mMemory.flags = flags;
+    TEEC_Result result = TEEC_AllocateSharedMemory(ctx, &mMemory);
+    if (result != TEEC_SUCCESS) {
+        throw common::InvalidValuesException("Failed to allocate shared memory: " +
+                                             translations::TeecResultToString(result) +
+                                             " (size " + std::to_string(size) +
+                                             ", flags: " + std::to_string(flags));
+    }
+}
+
+TeecSharedMemory::TeecSharedMemory(TEEC_Context* ctx, void* buffer, size_t size, uint32_t flags) {
+    mMemory.buffer = buffer;
+    mMemory.size = size;
+    mMemory.flags = flags;
+    TEEC_Result result = TEEC_RegisterSharedMemory(ctx, &mMemory);
+    if (result != TEEC_SUCCESS) {
+        throw common::InvalidValuesException("Failed to allocate shared memory: " +
+                                             translations::TeecResultToString(result) +
+                                             " (size " + std::to_string(size) +
+                                             ", flags: " + std::to_string(flags));
+    }
+}
+
+TeecSharedMemory::~TeecSharedMemory() {
+    TEEC_ReleaseSharedMemory(&mMemory);
+}
+
+void TeecSharedMemory::SetData(const DataBuffer& data, size_t offset) {
+    if (data.size() > (mMemory.size - offset)) {
+        throw common::TypeMismatchException("Not enough memory to set data: " +
+                                            std::to_string(data.size()) +
+                                            " requested, available " +
+                                            std::to_string(mMemory.size - offset) +
+                                            " at offset " + std::to_string(offset));
+    }
+
+    char* sharedBuffer = reinterpret_cast<char*>(mMemory.buffer);
+    memcpy(sharedBuffer + offset, data.data(), data.size());
+}
+
+void TeecSharedMemory::GetData(DataBuffer& data, size_t offset) const {
+    if (data.size() > (mMemory.size - offset)) {
+        throw common::TypeMismatchException("Not enough memory to get data: " +
+                                            std::to_string(data.size()) +
+                                            " requested, available " +
+                                            std::to_string(mMemory.size - offset) +
+                                            " at offset " + std::to_string(offset));
+    }
+
+    char* sharedBuffer = reinterpret_cast<char*>(mMemory.buffer);
+    memcpy(data.data(), sharedBuffer + offset, data.size());
+}
+
+TEEC_SharedMemory* TeecSharedMemory::GetMemoryPointer() {
+    return &mMemory;
+}
+
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecSharedMemory.h b/src/teec/TeecSharedMemory.h
new file mode 100644 (file)
index 0000000..9af881c
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecSharedMemory class declaration
+ */
+
+#ifndef LIBTEEC_TEEC_SHARED_MEMORY_H_
+#define LIBTEEC_TEEC_SHARED_MEMORY_H_
+
+#include <memory>
+#include <vector>
+#include <tee_client_api.h>
+
+namespace extension {
+namespace libteec {
+
+using DataBuffer = std::vector<uint8_t>;
+
+class TeecSharedMemory final
+{
+public:
+    TeecSharedMemory(TEEC_Context* ctx, size_t size, uint32_t flags);
+    TeecSharedMemory(TEEC_Context* ctx, void* buffer, size_t size, uint32_t flags);
+    ~TeecSharedMemory();
+
+    void SetData(const DataBuffer& data, size_t offset);
+    void GetData(DataBuffer& data, size_t offset) const;
+
+    TEEC_SharedMemory* GetMemoryPointer();
+private:
+    TEEC_SharedMemory mMemory;
+};
+
+using TeecSharedMemoryPtr = std::shared_ptr<TeecSharedMemory>;
+
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_SHARED_MEMORY_H_
\ No newline at end of file
diff --git a/src/teec/TeecTempMemoryAllocator.cc b/src/teec/TeecTempMemoryAllocator.cc
new file mode 100644 (file)
index 0000000..65f8929
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecTempMemoryAllocator class definition
+ */
+
+#include "TeecTempMemoryAllocator.h"
+
+
+namespace extension {
+namespace libteec {
+
+void* TeecTempMemoryAllocator::AllocateTempMemory(const picojson::array& array) {
+    mMemories.emplace_back(array.size());
+    TempMemoryBuffer& memory = mMemories.back();
+
+    for (size_t i = 0; i < array.size(); ++i)
+        memory[i] = static_cast<uint8_t>(array[i].get<double>());
+
+    return memory.data();
+}
+
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecTempMemoryAllocator.h b/src/teec/TeecTempMemoryAllocator.h
new file mode 100644 (file)
index 0000000..84523b4
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  TeecTempMemoryAllocator class declaration
+ */
+
+#ifndef LIBTEEC_TEEC_TEMP_MEMORY_ALLOCATOR_H_
+#define LIBTEEC_TEEC_TEMP_MEMORY_ALLOCATOR_H_
+
+#include <vector>
+#include <list>
+#include <common/picojson.h>
+
+
+namespace extension {
+namespace libteec {
+
+using TempMemoryBuffer = std::vector<uint8_t>;
+using TempMemoryList = std::list<TempMemoryBuffer>;
+
+// An object used during OpenSession and InvokeCommand calls
+// It's purpose is to temporarily allocate buffers on C++ side
+// and keep them in memory until above calls end
+class TeecTempMemoryAllocator final
+{
+public:
+    // returns pointer for temp memory
+    void* AllocateTempMemory(const picojson::array& array);
+
+private:
+    TempMemoryList mMemories;
+};
+
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_TEMP_MEMORY_ALLOCATOR_H_
\ No newline at end of file
diff --git a/src/teec/TeecTranslations.cc b/src/teec/TeecTranslations.cc
new file mode 100644 (file)
index 0000000..e6316cb
--- /dev/null
@@ -0,0 +1,379 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Teec to/from JSON translation function definitions
+ */
+
+#include "TeecTranslations.h"
+#include "TeecManager.h"
+#include "TeecContext.h"
+#include "TeecSharedMemory.h"
+#include <tee_client_api.h>
+
+#define CASE_RESULT_TO_STRING(x) case x: return #x
+
+namespace {
+
+// JSON TEEC_Parameter parsing tokens
+const std::string PARAM_TYPE_KEY = "type";
+const std::string PARAM_TYPE_NONE = "NONE";
+const std::string PARAM_TYPE_VALUE = "VALUE";
+const std::string PARAM_TYPE_MEMREF = "MEMREF";
+const std::string PARAM_TYPE_TMPREF = "TMPREF";
+const std::string PARAM_FLAG_KEY = "flag";
+const std::string PARAM_FLAG_NONE = "NONE";
+const std::string PARAM_FLAG_INPUT = "INPUT";
+const std::string PARAM_FLAG_OUTPUT = "OUTPUT";
+const std::string PARAM_FLAG_INOUT = "INOUT";
+const std::string PARAM_FLAG_WHOLE = "WHOLE";
+const std::string PARAM_FLAG_PARTIAL_INPUT = "PARTIAL_INPUT";
+const std::string PARAM_FLAG_PARTIAL_OUTPUT = "PARTIAL_OUTPUT";
+const std::string PARAM_FLAG_PARTIAL_INOUT = "PARTIAL_INOUT";
+const std::string PARAM_VALUE_A = "a";
+const std::string PARAM_VALUE_B = "a";
+const std::string PARAM_MEMREF_SIZE = "size";
+const std::string PARAM_MEMREF_OFFSET = "offset";
+const std::string PARAM_MEMREF_SHM = "shm";
+const std::string PARAM_TMPREF_MEM = "mem";
+
+const uint32_t TEEC_OPERATION_COUNT = 4;
+
+} // namespace
+
+namespace extension {
+namespace libteec {
+namespace translations {
+
+std::string TeecResultToString(TEEC_Result result) {
+    switch (result) {
+    CASE_RESULT_TO_STRING(TEEC_SUCCESS);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_GENERIC);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_ACCESS_DENIED);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_CANCEL);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_ACCESS_CONFLICT);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_EXCESS_DATA);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_BAD_FORMAT);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_BAD_PARAMETERS);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_BAD_STATE);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_ITEM_NOT_FOUND);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_NOT_IMPLEMENTED);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_NOT_SUPPORTED);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_NO_DATA);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_OUT_OF_MEMORY);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_BUSY);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_COMMUNICATION);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_SECURITY);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_SHORT_BUFFER);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_EXTERNAL_CANCEL);
+    CASE_RESULT_TO_STRING(TEEC_ERROR_TARGET_DEAD);
+    // not throwing here, there are TEE internal error not known from
+    // TEEC header, moreover this function is usually used in throws anyway
+    default: return "TEEC_ERROR_UNKNOWN";
+    }
+}
+
+uint32_t StringToTeecLoginMethod(const std::string& str) {
+    if (str == "PUBLIC") return TEEC_LOGIN_PUBLIC;
+    if (str == "USER") return TEEC_LOGIN_USER;
+    if (str == "GROUP") return TEEC_LOGIN_GROUP;
+    if (str == "APPLICATION") return TEEC_LOGIN_APPLICATION;
+    throw common::InvalidValuesException("Invalid login type: " + str);
+}
+
+uint32_t ParamTypeFromJSON(const picojson::object& obj) {
+    auto typeVal = obj.find(PARAM_TYPE_KEY);
+    if (typeVal == obj.end()) {
+        throw common::InvalidValuesException("Missing parameter type info");
+    }
+
+    auto flagVal = obj.find(PARAM_FLAG_KEY);
+    if (flagVal == obj.end()) {
+        throw common::InvalidValuesException("Flag parameter not added to operation");
+    }
+
+    const std::string& typeStr = typeVal->second.get<std::string>();
+    const std::string& flagStr = flagVal->second.get<std::string>();
+
+    if (typeStr == PARAM_TYPE_VALUE) {
+        if (flagStr == PARAM_FLAG_INPUT) {
+            return TEEC_VALUE_INPUT;
+        } else if (flagStr == PARAM_FLAG_OUTPUT) {
+            return TEEC_VALUE_OUTPUT;
+        } else if (flagStr == PARAM_FLAG_INOUT) {
+            return TEEC_VALUE_INOUT;
+        } else {
+            throw common::InvalidValuesException("Invalid parameter flag info: "
+                                                 + flagStr);
+        }
+    } else if (typeStr == PARAM_TYPE_MEMREF) {
+        if (flagStr == PARAM_FLAG_WHOLE) {
+            return TEEC_MEMREF_WHOLE;
+        } else if (flagStr == PARAM_FLAG_PARTIAL_INPUT) {
+            return TEEC_MEMREF_PARTIAL_INPUT;
+        } else if (flagStr == PARAM_FLAG_PARTIAL_OUTPUT) {
+            return TEEC_MEMREF_PARTIAL_OUTPUT;
+        } else if (flagStr == PARAM_FLAG_PARTIAL_INOUT) {
+            return TEEC_MEMREF_PARTIAL_INOUT;
+        } else {
+            throw common::InvalidValuesException("Invalid parameter flag info: "
+                                                 + flagStr);
+        }
+    } else if (typeStr == PARAM_TYPE_TMPREF) {
+        if (flagStr == PARAM_FLAG_INPUT) {
+            return TEEC_MEMREF_TEMP_INPUT;
+        } else if (flagStr == PARAM_FLAG_OUTPUT) {
+            return TEEC_MEMREF_TEMP_OUTPUT;
+        } else if (flagStr == PARAM_FLAG_INOUT) {
+            return TEEC_MEMREF_TEMP_INOUT;
+        } else {
+            throw common::InvalidValuesException("Invalid parameter flag info: "
+                                                 + flagStr);
+        }
+    }
+
+    throw common::InvalidValuesException("Invalid parameter type info: "
+                                         + typeVal->second.get<std::string>());
+}
+
+TEEC_SharedMemory* SharedMemoryFromJSON(const picojson::object& object) {
+    auto cID = object.find("contextId");
+    auto mID = object.find("memId");
+
+    if (cID == object.end() || mID == object.end()) {
+        throw common::InvalidValuesException("Invalid shared memory object provided as param");
+    }
+
+    const std::string& contextId = cID->second.get<std::string>();
+    const std::string& memId = mID->second.get<std::string>();
+    TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+    TeecSharedMemoryPtr mem = context->GetSharedMemory(memId);
+    return mem->GetMemoryPointer();
+}
+
+TEEC_Operation OperationFromJSON(const picojson::value& value, TeecTempMemoryAllocator& allocator) {
+    TEEC_Operation result;
+    result.started = 0;
+    result.paramTypes = 0;
+
+    if (!value.is<picojson::array>()) {
+        return result;
+    }
+
+    std::vector<uint32_t> paramTypes(TEEC_OPERATION_COUNT);
+    for (auto& p: paramTypes) {
+        p = TEEC_NONE;
+    }
+
+    const picojson::array& array = value.get<picojson::array>();
+    if (array.size() > TEEC_OPERATION_COUNT) {
+        throw common::InvalidValuesException("Too many operation parameters");
+    }
+
+    for (uint32_t i = 0; i < array.size(); ++i) {
+        const picojson::object& paramObject = array[i].get<picojson::object>();
+
+        auto type = paramObject.find(PARAM_TYPE_KEY);
+        if (type != paramObject.end()) {
+            paramTypes[i] = ParamTypeFromJSON(paramObject);
+            const std::string& paramTypeStr = type->second.get<std::string>();
+            if (paramTypeStr == PARAM_TYPE_VALUE) {
+                auto valA = paramObject.find(PARAM_VALUE_A);
+                auto valB = paramObject.find(PARAM_VALUE_B);
+                if (valA != paramObject.end() && valB != paramObject.end()) {
+                    result.params[i].value.a = static_cast<uint32_t>(valA->second.get<double>());
+                    result.params[i].value.b = static_cast<uint32_t>(valB->second.get<double>());
+                }
+            } else if (paramTypeStr == PARAM_TYPE_MEMREF) {
+                auto size = paramObject.find(PARAM_MEMREF_SIZE);
+                auto offset = paramObject.find(PARAM_MEMREF_OFFSET);
+                auto shm = paramObject.find(PARAM_MEMREF_SHM);
+                if (size != paramObject.end() &&
+                    offset != paramObject.end() &&
+                    shm != paramObject.end()) {
+                    result.params[i].memref.size = static_cast<size_t>(size->second.get<double>());
+                    result.params[i].memref.offset = static_cast<size_t>(offset->second.get<double>());
+                    result.params[i].memref.parent = SharedMemoryFromJSON(shm->second.get<picojson::object>());
+                }
+            } else if (paramTypeStr == PARAM_TYPE_TMPREF) {
+                auto mem = paramObject.find(PARAM_TMPREF_MEM);
+                if (mem != paramObject.end()) {
+                    const picojson::array& tmpMem = mem->second.get<picojson::array>();
+                    result.params[i].tmpref.size = tmpMem.size();
+                    result.params[i].tmpref.buffer = allocator.AllocateTempMemory(tmpMem);
+                }
+            } else {
+                throw common::InvalidValuesException("Invalid parameter type provided: "
+                                                     + type->second.get<std::string>());
+            }
+        }
+    }
+
+    result.paramTypes = TEEC_PARAM_TYPES(paramTypes[0], paramTypes[1], paramTypes[2], paramTypes[3]);
+    return result;
+}
+
+uint32_t SharedMemoryFlagsFromJSON(const picojson::value& value) {
+    if (!value.is<std::string>()) {
+        throw common::InvalidValuesException("Attempted to acquire shared memory flag from non-string object");
+    }
+
+    const std::string& flagStr = value.get<std::string>();
+    if (flagStr == PARAM_FLAG_INPUT) {
+        return TEEC_MEM_INPUT;
+    } else if (flagStr == PARAM_FLAG_OUTPUT) {
+        return TEEC_MEM_OUTPUT;
+    } else if (flagStr == PARAM_FLAG_INOUT) {
+        return TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
+    }
+
+    throw common::InvalidValuesException("Invalid flag provided: " + flagStr);
+}
+
+DataBuffer DataBufferFromJSON(const picojson::value& value) {
+    if (!value.is<picojson::array>()) {
+        throw common::InvalidValuesException("Attempted to acquire data array from non-array object");
+    }
+
+    const picojson::array& array = value.get<picojson::array>();
+    DataBuffer buffer(array.size());
+
+    for (size_t i = 0; i < array.size(); ++i) {
+        buffer[i] = static_cast<uint8_t>(array[i].get<double>());
+    }
+
+    return buffer;
+}
+
+std::string JSONFromParamType(uint32_t paramType) {
+    switch (paramType) {
+    case TEEC_NONE:
+        return PARAM_TYPE_NONE;
+    case TEEC_VALUE_INPUT:
+    case TEEC_VALUE_OUTPUT:
+    case TEEC_VALUE_INOUT:
+        return PARAM_TYPE_VALUE;
+    case TEEC_MEMREF_TEMP_INPUT:
+    case TEEC_MEMREF_TEMP_OUTPUT:
+    case TEEC_MEMREF_TEMP_INOUT:
+        return PARAM_TYPE_TMPREF;
+    case TEEC_MEMREF_WHOLE:
+    case TEEC_MEMREF_PARTIAL_INPUT:
+    case TEEC_MEMREF_PARTIAL_OUTPUT:
+    case TEEC_MEMREF_PARTIAL_INOUT:
+        return PARAM_TYPE_MEMREF;
+    default:
+        throw common::InvalidValuesException("Unknown TEEC parameter type: " + std::to_string(paramType));
+    };
+}
+
+std::string JSONFromParamFlag(uint32_t paramType) {
+    switch (paramType) {
+    case TEEC_NONE:
+        return PARAM_FLAG_NONE;
+    case TEEC_VALUE_INPUT:
+    case TEEC_MEMREF_TEMP_INPUT:
+        return PARAM_FLAG_INPUT;
+    case TEEC_VALUE_OUTPUT:
+    case TEEC_MEMREF_TEMP_OUTPUT:
+        return PARAM_FLAG_OUTPUT;
+    case TEEC_VALUE_INOUT:
+    case TEEC_MEMREF_TEMP_INOUT:
+        return PARAM_FLAG_INOUT;
+    case TEEC_MEMREF_WHOLE:
+        return PARAM_FLAG_WHOLE;
+    case TEEC_MEMREF_PARTIAL_INPUT:
+        return PARAM_FLAG_PARTIAL_INPUT;
+    case TEEC_MEMREF_PARTIAL_OUTPUT:
+        return PARAM_FLAG_PARTIAL_OUTPUT;
+    case TEEC_MEMREF_PARTIAL_INOUT:
+        return PARAM_FLAG_PARTIAL_INOUT;
+    default:
+        throw common::InvalidValuesException("Unknown TEEC parameter type: " + std::to_string(paramType));
+    };
+}
+
+picojson::value UpdateJSONParams(const picojson::value& json, TEEC_Operation op) {
+    const picojson::array& inParamArray = json.get<picojson::array>();
+    picojson::array outParamArray;
+
+    uint32_t paramTypes[4] = {
+        TEEC_PARAM_TYPE_GET(op.paramTypes, 0),
+        TEEC_PARAM_TYPE_GET(op.paramTypes, 1),
+        TEEC_PARAM_TYPE_GET(op.paramTypes, 2),
+        TEEC_PARAM_TYPE_GET(op.paramTypes, 3),
+    };
+
+    for (uint32_t i = 0; i < 4; ++i) {
+        picojson::object param;
+
+        std::string paramTypeStr = JSONFromParamType(paramTypes[i]);
+        param.insert(std::make_pair(
+            PARAM_TYPE_KEY, picojson::value(paramTypeStr)));
+        param.insert(std::make_pair(
+            PARAM_FLAG_KEY, picojson::value(JSONFromParamFlag(paramTypes[i]))));
+
+        if (paramTypeStr == PARAM_TYPE_VALUE) {
+            // value type can be completely overwritten
+            param.insert(std::make_pair(PARAM_VALUE_A,
+                picojson::value(static_cast<double>(op.params[i].value.a))));
+            param.insert(std::make_pair(PARAM_VALUE_B,
+                picojson::value(static_cast<double>(op.params[i].value.b))));
+        } else if (paramTypeStr == PARAM_TYPE_MEMREF) {
+            const picojson::object& memref = inParamArray[i].get<picojson::object>();
+            auto shm = memref.find("shm");
+            if (shm == memref.end()) {
+                throw common::InvalidValuesException("Invalid shm object");
+            }
+
+            // memref type copies shm from source, rest parameters from TA
+            param.insert(std::make_pair(PARAM_MEMREF_SIZE,
+                picojson::value(static_cast<double>(op.params[i].memref.size))));
+            param.insert(std::make_pair(PARAM_MEMREF_OFFSET,
+                picojson::value(static_cast<double>(op.params[i].memref.offset))));
+            param.insert(std::make_pair(PARAM_MEMREF_SHM, shm->second));
+        } else if (paramTypeStr == PARAM_TYPE_TMPREF) {
+            picojson::array buf(op.params[i].tmpref.size);
+            uint8_t* opBuf = reinterpret_cast<uint8_t*>(op.params[i].tmpref.buffer);
+            for (size_t i = 0; i < buf.size(); ++i)
+                buf[i] = picojson::value(static_cast<double>(opBuf[i]));
+
+            param.insert(std::make_pair(PARAM_TMPREF_MEM, picojson::value(buf)));
+        } else if (paramTypeStr != PARAM_TYPE_NONE) {
+            throw common::InvalidValuesException(
+                "Invalid parameter type read from operation: " + paramTypeStr);
+        }
+
+        outParamArray.push_back(picojson::value(param));
+    }
+
+    return picojson::value(outParamArray);
+}
+
+picojson::value JSONFromDataBuffer(const DataBuffer& buffer) {
+    picojson::array result(buffer.size());
+
+    for (uint32_t i = 0; i < buffer.size(); ++i) {
+        result[i] = picojson::value(static_cast<double>(buffer[i]));
+    }
+
+    return picojson::value(result);
+}
+
+} // namespace translations
+} // namespace libteec
+} // namespace extension
diff --git a/src/teec/TeecTranslations.h b/src/teec/TeecTranslations.h
new file mode 100644 (file)
index 0000000..c8b3b3b
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Teec to/from JSON translation function declarations
+ */
+
+#ifndef LIBTEEC_TEEC_TRANSLATIONS_H_
+#define LIBTEEC_TEEC_TRANSLATIONS_H_
+
+#include "TeecSharedMemory.h"
+
+#include "TeecTempMemoryAllocator.h"
+
+#include <tee_client_api.h>
+#include <string>
+
+#include <common/picojson.h>
+#include <common/platform_exception.h>
+
+
+namespace extension {
+namespace libteec {
+namespace translations {
+
+std::string TeecResultToString(TEEC_Result result);
+uint32_t StringToTeecLoginMethod(const std::string& str);
+TEEC_Operation OperationFromJSON(const picojson::value& value, TeecTempMemoryAllocator& allocator);
+DataBuffer DataBufferFromJSON(const picojson::value& value);
+uint32_t SharedMemoryFlagsFromJSON(const picojson::value& value);
+picojson::value UpdateJSONParams(const picojson::value& json, TEEC_Operation op);
+picojson::value JSONFromDataBuffer(const DataBuffer& buffer);
+
+} // namespace translations
+} // namespace libteec
+} // namespace extension
+
+#endif // LIBTEEC_TEEC_TRANSLATIONS_H_
index 68811dd..92e3e04 100644 (file)
@@ -28,7 +28,7 @@ function ListenerManager(native, listenerName, handle) {
     this.nativeSet = false;
     this.native = native;
     this.listenerName = listenerName;
-    this.handle = handle || function(msg, listener, watchId) {};
+    this.handle = handle || function() {};
 }
 
 ListenerManager.prototype.addListener = function(callback, nativeCall, data) {
@@ -60,17 +60,13 @@ ListenerManager.prototype.removeListener = function(watchId, nativeCall) {
     }
 
     if (this.nativeSet && type_.isEmptyObject(this.listeners)) {
-            this.native.callSync(nativeCall);
-            this.native.removeListener(this.listenerName);
-            this.nativeSet = false;
+        this.native.callSync(nativeCall);
+        this.native.removeListener(this.listenerName);
+        this.nativeSet = false;
     }
 };
 
 
-function SetReadOnlyProperty(obj, n, v) {
-    Object.defineProperty(obj, n, {value: v, writable: false});
-}
-
 var TeecLoginMethod = {
     PUBLIC: 'PUBLIC',
     USER: 'USER',
@@ -98,15 +94,21 @@ var TeecSharedMemoryFlags = {
     OUTPUT: 'OUTPUT',
     INOUT: 'INOUT'
 };
+var TEEC_MAX_OPERATION_LENGTH = 4;
+var TEEC_PARAMETER_TYPE_VALUE = 'VALUE';
+var TEEC_PARAMETER_TYPE_MEMREF = 'MEMREF';
+var TEEC_PARAMETER_TYPE_TMPREF = 'TMPREF';
 
 
-function LibTeecManager() {
-    // constructor of LibTeecManager
-
+function TeecParameter() {
 }
 
 
-LibTeecManager.prototype.getContext = function(name) {
+
+function LibTeecManager() {
+}
+
+LibTeecManager.prototype.getContext = function() {
     var args = validator_.validateArgs(arguments, [
         {name: 'name', type: types_.STRING, optional: true, nullable: true}
     ]);
@@ -115,58 +117,149 @@ LibTeecManager.prototype.getContext = function(name) {
         name: args.name
     };
 
-
     var result = native_.callSync('LibTeecManager_getContext', data);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
+
     return new TeecContext(native_.getResultObject(result));
+};
+
+
 
+function TeecSession(contextId, sessionId) {
+    this.contextId = contextId;
+    this.sessionId = sessionId;
+}
+
+TeecSession.prototype.close = function() {
+    var data = {
+        contextId: this.contextId,
+        sessionId: this.sessionId
+    };
+
+    var result = native_.callSync('TeecSession_close', data);
+
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 };
 
+TeecSession.prototype.invokeCommand =
+    function(cmd, params, successCallback, errorCallback) {
+    var args = validator_.validateArgs(arguments, [
+        {name: 'cmd', type: types_.LONG},
+        {name: 'params', type: types_.ARRAY, values: TeecParameter,
+            nullable: true},
+        {name: 'successCallback', type: types_.FUNCTION},
+        {name: 'errorCallback', type: types_.FUNCTION, optional: true,
+            nullable: true}
+    ]);
 
+    if (params.length > TEEC_MAX_OPERATION_LENGTH) {
+        throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+            'Input array params has too high length');
+    }
 
-function TeecContext() {
-    // constructor of TeecContext
+    var data = {
+        contextId: this.contextId,
+        sessionId: this.sessionId,
+        cmd: args.cmd,
+        params: args.params,
+        successCallback: args.successCallback,
+        errorCallback: args.errorCallback
+    };
 
-}
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback,
+                                   native_.getErrorObject(result));
+            return;
+        }
+
+        var retArgs = native_.getResultObject(result);
+
+        // update parameters after call
+        // to avoid losing TeecSharedMemory's functions, we copy MEMREF
+        // attributes via a function, instead of a typical substitution
+        for (var i = 0; i < params.length; ++i) {
+            switch (params[i].type) {
+            case TEEC_PARAMETER_TYPE_VALUE:
+                params[i] = retArgs.params[i];
+                break;
+            case TEEC_PARAMETER_TYPE_MEMREF:
+                params[i].copyParams(retArgs.params[i]);
+                break;
+            case TEEC_PARAMETER_TYPE_TMPREF:
+                params[i] = retArgs.params[i];
+                break;
+            default:
+                throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+                    'Received incorrect param object from plugin');
+            };
+        }
 
+        native_.callIfPossible(args.successCallback, retArgs.cmd, params);
+    };
+
+    var result = native_.call('TeecSession_invokeCommand', data, callback);
 
-TeecContext.prototype.openSession = function(taUUID, loginMethod, connectionData, params, successCallback, errorCallback) {
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
+
+    return native_.getResultObject(result);
+};
+
+
+
+function TeecContext(id) {
+    // constructor of TeecContext
+    this.contextId = id;
+}
+
+TeecContext.prototype.openSession =
+    function(taUUID, loginMethod, connectionData, params, successCallback,
+             errorCallback) {
     var args = validator_.validateArgs(arguments, [
         {name: 'taUUID', type: types_.STRING},
-        {name: 'loginMethod', type: types_.ENUM, values: ['PUBLIC', 'USER', 'GROUP', 'APPLICATION']},
-        {name: 'connectionData', type: types_.BYTE},
-        {name: 'params', type: types_.PLATFORM_OBJECT, values: tizen.TeecParameter},
+        {name: 'loginMethod', type: types_.ENUM,
+            values: ['PUBLIC', 'USER', 'GROUP', 'APPLICATION']},
+        {name: 'connectionData', type: types_.UNSIGNED_LONG, nullable: true},
+        {name: 'params', type: types_.ARRAY, values: TeecParameter,
+            nullable: true},
         {name: 'successCallback', type: types_.FUNCTION},
-        {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
+        {name: 'errorCallback', type: types_.FUNCTION, optional: true,
+            nullable: true}
     ]);
 
     var data = {
+        contextId: this.contextId,
         taUUID: args.taUUID,
         loginMethod: args.loginMethod,
         connectionData: args.connectionData,
         params: args.params
     };
 
-
-
-
-
-
+    var cId = this.contextId;
     var callback = function(result) {
         if (native_.isFailure(result)) {
             native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
             return;
         }
-        native_.callIfPossible(args.successCallback);
-    };
 
-    native_.call('TeecContext_openSession', data, callback);
+        var session = new TeecSession(cId, native_.getResultObject(result));
+        native_.callIfPossible(args.successCallback, session);
+    };
 
+    var result = native_.call('TeecContext_openSession', data, callback);
 
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 
+    return native_.getResultObject(result);
 };
 
 TeecContext.prototype.revokeCommand = function(id) {
@@ -178,13 +271,11 @@ TeecContext.prototype.revokeCommand = function(id) {
         id: args.id
     };
 
-
     var result = native_.callSync('TeecContext_revokeCommand', data);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
-
 };
 
 TeecContext.prototype.allocateSharedMemory = function(size, flags) {
@@ -194,18 +285,18 @@ TeecContext.prototype.allocateSharedMemory = function(size, flags) {
     ]);
 
     var data = {
+        contextId: this.contextId,
         size: args.size,
         flags: args.flags
     };
 
-
     var result = native_.callSync('TeecContext_allocateSharedMemory', data);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
-    return new TeecSharedMemory(native_.getResultObject(result));
 
+    return new TeecSharedMemory(this.contextId, native_.getResultObject(result));
 };
 
 TeecContext.prototype.registerSharedMemory = function(addr, size, flags) {
@@ -221,14 +312,13 @@ TeecContext.prototype.registerSharedMemory = function(addr, size, flags) {
         flags: args.flags
     };
 
-
     var result = native_.callSync('TeecContext_registerSharedMemory', data);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
-    return new TeecSharedMemory(native_.getResultObject(result));
 
+    return new TeecSharedMemory(this.contextId, native_.getResultObject(result));
 };
 
 TeecContext.prototype.releaseSharedMemory = function(shm) {
@@ -237,88 +327,133 @@ TeecContext.prototype.releaseSharedMemory = function(shm) {
     ]);
 
     var data = {
-        shm: args.shm
+        contextId: this.contextId,
+        memId: args.shm.memId
     };
 
-
     var result = native_.callSync('TeecContext_releaseSharedMemory', data);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
-
 };
 
 
 
-function TeecSharedMemory() {
+function TeecSharedMemory(contextId, memId) {
     // constructor of TeecSharedMemory
-
-    SetReadOnlyProperty(this, 'size', null); // read only property
+    this.contextId = contextId;
+    this.memId = memId;
 }
 
-
 TeecSharedMemory.prototype.setData = function(data, offset) {
     var args = validator_.validateArgs(arguments, [
-        {name: 'data', type: types_.BYTE},
-        {name: 'offset', type: types_.LONG_LONG}
+        {name: 'data', type: types_.ARRAY, values: types_.BYTE },
+        {name: 'offset', type: types_.LONG_LONG }
     ]);
 
-    var data = {
+    var packed = {
+        contextId: this.contextId,
+        memId: this.memId,
         data: args.data,
         offset: args.offset
     };
 
-
-    var result = native_.callSync('TeecSharedMemory_setData', data);
+    var result = native_.callSync('TeecSharedMemory_setData', packed);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
-
 };
 
 TeecSharedMemory.prototype.getData = function(data, offset) {
     var args = validator_.validateArgs(arguments, [
-        {name: 'data', type: types_.BYTE},
+        {name: 'data', type: types_.ARRAY, values: types_.BYTE },
         {name: 'offset', type: types_.LONG_LONG}
     ]);
 
-    var data = {
+    var packed = {
+        contextId: this.contextId,
+        memId: this.memId,
         data: args.data,
         offset: args.offset
     };
 
-
-    var result = native_.callSync('TeecSharedMemory_getData', data);
+    var result = native_.callSync('TeecSharedMemory_getData', packed);
 
     if (native_.isFailure(result)) {
         throw native_.getErrorObject(result);
     }
 
+    var out = native_.getResultObject(result);
+    for (var i = 0; i < data.length; ++i)
+        data[i] = out[i];
+};
+
+TeecSharedMemory.prototype.copyParams = function(src) {
+    this.contextId = src.contextId;
+    this.memId = src.memId;
 };
 
 
 
-function TeecRegisteredMemory(memory, offset, size) {
+function TeecValue(a, b, flag) {
+    // constructor of TeecValue
+    validator_.isConstructorCall(this, TeecValue);
+    var args = validator_.validateArgs(arguments, [
+        {name: 'a', type: types_.UNSIGNED_LONG},
+        {name: 'b', type: types_.UNSIGNED_LONG},
+        {name: 'flag', type: types_.ENUM, values: ['INPUT', 'OUTPUT', 'INOUT']}
+    ]);
+
+    this.type = TEEC_PARAMETER_TYPE_VALUE;
+    this.flag = args.flag;
+    this.a = args.a;
+    this.b = args.b;
+}
+
+TeecValue.prototype = new TeecParameter();
+TeecValue.prototype.constructor = TeecValue;
+
+function TeecRegisteredMemory(memory, offset, size, flag) {
     // constructor of TeecRegisteredMemory
     validator_.isConstructorCall(this, TeecRegisteredMemory);
+    var args = validator_.validateArgs(arguments, [
+        {name: 'memory', type: types_.PLATFORM_OBJECT, values: TeecSharedMemory },
+        {name: 'offset', type: types_.UNSIGNED_LONG_LONG },
+        {name: 'size', type: types_.UNSIGNED_LONG_LONG },
+        {name: 'flag', type: types_.ENUM, values: ['WHOLE', 'PARTIAL_INPUT', 'PARTIAL_OUTPUT', 'PARTIAL_INOUT']}
+    ]);
 
-    this.shm = null;
-    this.offset = offset;
-    this.size = memory.size;
+    this.type = TEEC_PARAMETER_TYPE_MEMREF;
+    this.flag = args.flag;
+    this.shm = memory;
+    this.size = args.size;
+    this.offset = args.offset;
 }
 
 TeecRegisteredMemory.prototype = new TeecParameter();
 TeecRegisteredMemory.prototype.constructor = TeecRegisteredMemory;
+TeecRegisteredMemory.prototype.copyParams = function(src) {
+    this.type = src.type;
+    this.flag = src.flag;
+    this.size = src.size;
+    this.offset = src.offset;
+    this.shm.copyParams(src.shm);
+};
 
 
-
-function TeecTempMemory(mem) {
+function TeecTempMemory(mem, flag) {
     // constructor of TeecTempMemory
     validator_.isConstructorCall(this, TeecTempMemory);
+    var args = validator_.validateArgs(arguments, [
+        {name: 'mem', type: types_.ARRAY, values: types_.BYTE },
+        {name: 'flag', type: types_.ENUM, values: ['INPUT', 'OUTPUT', 'INOUT']}
+    ]);
 
-    this.mem = mem;
+    this.type = TEEC_PARAMETER_TYPE_TMPREF;
+    this.mem = args.mem;
+    this.flag = args.flag;
 }
 
 TeecTempMemory.prototype = new TeecParameter();
@@ -326,23 +461,7 @@ TeecTempMemory.prototype.constructor = TeecTempMemory;
 
 
 
-function TeecValue(a, b) {
-    // constructor of TeecValue
-    validator_.isConstructorCall(this, TeecValue);
-
-    this.a = a;
-    this.b = b;
-}
-
-TeecValue.prototype = new TeecParameter();
-TeecValue.prototype.constructor = TeecValue;
-
-
-
 exports = new LibTeecManager();
-tizen.TeecContext = TeecContext;
-tizen.TeecSharedMemory = TeecSharedMemory;
 tizen.TeecRegisteredMemory = TeecRegisteredMemory;
 tizen.TeecTempMemory = TeecTempMemory;
 tizen.TeecValue = TeecValue;
-
index 48953b1..1d48506 100644 (file)
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+/**
+ * @file
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Libteec extension definitions
+ */
 
 #include "teec/libteec_extension.h"
 
index 52188a9..f1f94b3 100644 (file)
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+/**
+ * @file
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Libteec extension declaration
+ */
 
 #ifndef LIBTEEC_LIBTEEC_EXTENSION_H_
 #define LIBTEEC_LIBTEEC_EXTENSION_H_
index 5ac689c..6cbfbbb 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+/**
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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.
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+/**
+ * @file
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Libteec instance definitions
+ */
 
-#include "teec/libteec_instance.h"
+#include "libteec_instance.h"
+#include "TeecManager.h"
+#include "TeecContext.h"
+#include "TeecTranslations.h"
+#include "TeecTempMemoryAllocator.h"
 
 #include <functional>
 
-#include "common/picojson.h"
-#include "common/logger.h"
-#include "common/platform_exception.h"
+#include <common/picojson.h>
+#include <common/logger.h>
+#include <common/platform_exception.h>
+#include <common/task-queue.h>
+#include <common/converter.h>
+#include <common/tools.h>
 
-namespace extension {
-namespace libteec {
 
 namespace {
-// The privileges that required in Libteec API
-const std::string kPrivilegeLibteec = "";
+
+// The privilege required in Libteec API
+const std::string kPrivilegeLibteec = "http://tizen.org/privilege/tee.client";
 
 } // namespace
 
+namespace extension {
+namespace libteec {
+
 using namespace common;
 using namespace extension::libteec;
 
@@ -39,79 +53,20 @@ LibteecInstance::LibteecInstance() {
     #define REGISTER_SYNC(c,x) \
         RegisterSyncHandler(c, std::bind(&LibteecInstance::x, this, _1, _2));
     REGISTER_SYNC("LibTeecManager_getContext", LibTeecManagerGetContext);
+    REGISTER_SYNC("TeecSharedMemory_getData", TeecSharedMemoryGetData);
     REGISTER_SYNC("TeecSharedMemory_setData", TeecSharedMemorySetData);
     REGISTER_SYNC("TeecContext_releaseSharedMemory", TeecContextReleaseSharedMemory);
-    REGISTER_SYNC("TeecContext_openSession", TeecContextOpenSession);
     REGISTER_SYNC("TeecContext_registerSharedMemory", TeecContextRegisterSharedMemory);
     REGISTER_SYNC("TeecContext_allocateSharedMemory", TeecContextAllocateSharedMemory);
-    REGISTER_SYNC("TeecSharedMemory_getData", TeecSharedMemoryGetData);
     REGISTER_SYNC("TeecContext_revokeCommand", TeecContextRevokeCommand);
+    REGISTER_SYNC("TeecSession_close", TeecSessionClose);
     #undef REGISTER_SYNC
-}
-
-LibteecInstance::~LibteecInstance() {
-}
-
-
-enum LibteecCallbacks {
-    LibTeecManagerGetContextCallback,
-    TeecSharedMemorySetDataCallback,
-    TeecContextReleaseSharedMemoryCallback,
-    TeecContextOpenSessionCallback,
-    TeecContextRegisterSharedMemoryCallback,
-    TeecContextAllocateSharedMemoryCallback,
-    TeecSharedMemoryGetDataCallback,
-    TeecContextRevokeCommandCallback
-};
-
-static void ReplyAsync(LibteecInstance* instance, LibteecCallbacks cbfunc,
-                                             int callbackId, bool isSuccess, picojson::object& param) {
-    param["callbackId"] = picojson::value(static_cast<double>(callbackId));
-    param["status"] = picojson::value(isSuccess ? "success" : "error");
-
-    // insert result for async callback to param
-    switch(cbfunc) {
-        case LibTeecManagerGetContextCallback: {
-            // do something...
-            break;
-        }
-        case TeecContextOpenSessionCallback: {
-            // do something...
-            break;
-        }
-        case TeecContextRevokeCommandCallback: {
-            // do something...
-            break;
-        }
-        case TeecContextAllocateSharedMemoryCallback: {
-            // do something...
-            break;
-        }
-        case TeecContextRegisterSharedMemoryCallback: {
-            // do something...
-            break;
-        }
-        case TeecContextReleaseSharedMemoryCallback: {
-            // do something...
-            break;
-        }
-        case TeecSharedMemorySetDataCallback: {
-            // do something...
-            break;
-        }
-        case TeecSharedMemoryGetDataCallback: {
-            // do something...
-            break;
-        }
-        default: {
-            LoggerE("Invalid Callback Type");
-            return;
-        }
-    }
-
-    picojson::value result = picojson::value(param);
 
-    instance->PostMessage(result.serialize().c_str());
+    #define REGISTER_ASYNC(c,x) \
+        RegisterSyncHandler(c, std::bind(&LibteecInstance::x, this, _1, _2));
+    REGISTER_ASYNC("TeecContext_openSession", TeecContextOpenSession);
+    REGISTER_ASYNC("TeecSession_invokeCommand", TeecSessionInvokeCommand);
+    #undef REGISTER_ASYNC
 }
 
 #define CHECK_EXIST(args, name, out) \
@@ -120,116 +75,270 @@ static void ReplyAsync(LibteecInstance* instance, LibteecCallbacks cbfunc,
             return;\
         }
 
+void LibteecInstance::LibTeecManagerGetContext(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
 
-void LibteecInstance::LibTeecManagerGetContext(const picojson::value& args, picojson::object& out) {
-
-    const std::string& name = args.get("name").get<std::string>();
-
-    // implement it
+    const picojson::value& name = args.get("name");
+    std::string contextName;
 
+    if (name.is<std::string>()) {
+        contextName = name.get<std::string>();
+    }
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+    try {
+        TeecManager::Instance().GetContext(contextName);
+        ReportSuccess(picojson::value(contextName), out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 }
+
 void LibteecInstance::TeecContextOpenSession(const picojson::value& args, picojson::object& out) {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
     CHECK_EXIST(args, "callbackId", out)
-    CHECK_EXIST(args, "connectionData", out)
-
-    int callbackId = static_cast<int>(args.get("callbackId").get<double>());
-    int connectionData = args.get("connectionData").get<int>();
-
-    // implement it
+    CHECK_EXIST(args, "contextId", out)
+    CHECK_EXIST(args, "taUUID", out)
+    CHECK_EXIST(args, "loginMethod", out)
+
+    double callbackId = args.get("callbackId").get<double>();
+    std::string contextId = args.get("contextId").get<std::string>();
+    std::string uuid = args.get("taUUID").get<std::string>();
+    const uint32_t loginMethod = translations::StringToTeecLoginMethod(args.get("loginMethod").get<std::string>());
+
+    TeecContextPtr context;
+    uint32_t connectionData = 0;
+    uint32_t* connectionDataPtr = nullptr;
+    uint32_t opId = 0;
+
+    try {
+        context = TeecManager::Instance().GetContext(contextId);
+
+        if (args.get("connectionData").is<double>()) {
+            connectionData = static_cast<uint32_t>(args.get("connectionData").get<double>());
+            connectionDataPtr = &connectionData;
+        }
 
-    // call ReplyAsync in later (Asynchronously)
+        opId = TeecManager::Instance().CreateOperation();
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
-}
-void LibteecInstance::TeecContextRevokeCommand(const picojson::value& args, picojson::object& out) {
+    auto openSession = [=](const std::shared_ptr<picojson::value>& response) -> void {
+        try {
+            TeecTempMemoryAllocator allocator;
+
+            TEEC_Operation op = TeecManager::Instance().GetOperation(opId);
+            op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
+            if (args.get("params").is<picojson::array>()) {
+                op = translations::OperationFromJSON(args.get("params"), allocator);
+            }
+
+            std::string sid = context->OpenSession(uuid, loginMethod, connectionDataPtr, &op, nullptr);
+            TeecManager::Instance().RemoveOperation(opId);
+            ReportSuccess(picojson::value(sid), response->get<picojson::object>());
+        } catch (const PlatformException& e) {
+            ReportError(e, response->get<picojson::object>());
+        }
+    };
 
+    auto openSessionResponse =
+        [callbackId, this](const std::shared_ptr<picojson::value>& response) -> void {
+        picojson::object& obj = response->get<picojson::object>();
+        obj.insert(std::make_pair("callbackId", picojson::value(callbackId)));
+        Instance::PostMessage(this, response->serialize().c_str());
+    };
 
-    // implement it
+    auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
 
+    TaskQueue::GetInstance().Queue<picojson::value>(openSession, openSessionResponse, data);
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+    ReportSuccess(picojson::value(static_cast<double>(opId)), out);
 }
-void LibteecInstance::TeecContextAllocateSharedMemory(const picojson::value& args, picojson::object& out) {
-    CHECK_EXIST(args, "size", out)
-
-    double size = args.get("size").get<double>();
-
-    // implement it
 
-
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+void LibteecInstance::TeecContextRevokeCommand(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "id", out);
+
+    try {
+        uint32_t id = static_cast<uint32_t>(args.get("id").get<double>());
+        TEEC_Operation op = TeecManager::Instance().GetOperation(id);
+        TEEC_RequestCancellation(&op);
+        ReportSuccess(out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 }
-void LibteecInstance::TeecContextRegisterSharedMemory(const picojson::value& args, picojson::object& out) {
-    CHECK_EXIST(args, "addr", out)
-    CHECK_EXIST(args, "size", out)
-
-    double addr = args.get("addr").get<double>();
-    double size = args.get("size").get<double>();
-
-    // implement it
 
+void LibteecInstance::TeecContextAllocateSharedMemory(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "contextId", out);
+    CHECK_EXIST(args, "size", out);
+    CHECK_EXIST(args, "flags", out);
+
+    size_t size = static_cast<size_t>(args.get("size").get<double>());
+    uint32_t flags = translations::SharedMemoryFlagsFromJSON(args.get("flags"));
+    std::string contextId = args.get("contextId").get<std::string>();
+
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        std::string memId = context->CreateSharedMemory(size, flags);
+        ReportSuccess(picojson::value(memId), out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
+}
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+void LibteecInstance::TeecContextRegisterSharedMemory(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "contextId", out);
+    CHECK_EXIST(args, "buffer", out);
+    CHECK_EXIST(args, "size", out);
+    CHECK_EXIST(args, "flags", out);
+
+    void* buffer = reinterpret_cast<void*>(static_cast<size_t>(args.get("buffer").get<double>()));
+    size_t size = static_cast<size_t>(args.get("size").get<double>());
+    uint32_t flags = static_cast<uint32_t>(args.get("flags").get<double>());
+    std::string contextId = args.get("contextId").get<std::string>();
+
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        std::string memId = context->CreateSharedMemory(buffer, size, flags);
+        ReportSuccess(picojson::value(memId), out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 }
-void LibteecInstance::TeecContextReleaseSharedMemory(const picojson::value& args, picojson::object& out) {
 
+void LibteecInstance::TeecContextReleaseSharedMemory(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "contextId", out);
+    CHECK_EXIST(args, "memId", out);
 
-    // implement it
+    std::string contextId = args.get("contextId").get<std::string>();
+    std::string memId = args.get("memId").get<std::string>();
 
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        context->ReleaseSharedMemory(memId);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
+}
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+void LibteecInstance::TeecSharedMemorySetData(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "data", out);
+    CHECK_EXIST(args, "offset", out);
+
+    std::string contextId = args.get("contextId").get<std::string>();
+    std::string memId = args.get("memId").get<std::string>();
+    DataBuffer data = translations::DataBufferFromJSON(args.get("data"));
+    size_t offset = static_cast<size_t>(args.get("offset").get<double>());
+
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        TeecSharedMemoryPtr shmem = context->GetSharedMemory(memId);
+        shmem->SetData(data, offset);
+        ReportSuccess(out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 }
-void LibteecInstance::TeecSharedMemorySetData(const picojson::value& args, picojson::object& out) {
-    CHECK_EXIST(args, "data", out)
-    CHECK_EXIST(args, "offset", out)
 
-    int data = args.get("data").get<int>();
-    double offset = args.get("offset").get<double>();
+void LibteecInstance::TeecSharedMemoryGetData(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "data", out);
+    CHECK_EXIST(args, "offset", out);
+
+    std::string contextId = args.get("contextId").get<std::string>();
+    std::string memId = args.get("memId").get<std::string>();
+    DataBuffer data = translations::DataBufferFromJSON(args.get("data"));
+    size_t offset = static_cast<size_t>(args.get("offset").get<double>());
+
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        TeecSharedMemoryPtr shmem = context->GetSharedMemory(memId);
+        shmem->GetData(data, offset);
+        ReportSuccess(translations::JSONFromDataBuffer(data), out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
+}
 
-    // implement it
+void LibteecInstance::TeecSessionClose(const picojson::value& args, picojson::object& out) const {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "contextId", out);
+    CHECK_EXIST(args, "sessionId", out);
 
+    const std::string contextId = args.get("contextId").get<std::string>();
+    const std::string sessionId = args.get("sessionId").get<std::string>();
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
+    try {
+        TeecContextPtr context = TeecManager::Instance().GetContext(contextId);
+        context->CloseSession(sessionId);
+        ReportSuccess(out);
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 }
-void LibteecInstance::TeecSharedMemoryGetData(const picojson::value& args, picojson::object& out) {
-    CHECK_EXIST(args, "data", out)
-    CHECK_EXIST(args, "offset", out)
 
-    int data = args.get("data").get<int>();
-    double offset = args.get("offset").get<double>();
+void LibteecInstance::TeecSessionInvokeCommand(const picojson::value& args, picojson::object& out) {
+    CHECK_PRIVILEGE_ACCESS(kPrivilegeLibteec, &out);
+    CHECK_EXIST(args, "callbackId", out);
+    CHECK_EXIST(args, "contextId", out);
+    CHECK_EXIST(args, "sessionId", out);
+    CHECK_EXIST(args, "cmd", out);
+
+    const double callbackId = args.get("callbackId").get<double>();
+    const std::string contextId = args.get("contextId").get<std::string>();
+    const std::string sessionId = args.get("sessionId").get<std::string>();
+    const uint32_t cmd = static_cast<uint32_t>(args.get("cmd").get<double>());
+
+    TeecContextPtr context;
+    TeecSessionPtr session;
+    uint32_t opId = 0;
+
+    try {
+        context = TeecManager::Instance().GetContext(contextId);
+        session = context->GetSession(sessionId);
+        opId = TeecManager::Instance().CreateOperation();
+    } catch (const PlatformException& e) {
+        ReportError(e, out);
+    }
 
-    // implement it
+    auto invoke = [=](const std::shared_ptr<picojson::value>& response) -> void {
+        try {
+            TeecTempMemoryAllocator allocator;
+            TEEC_Operation op = TeecManager::Instance().GetOperation(opId);
+            op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
+            if (args.get("params").is<picojson::array>()) {
+                op = translations::OperationFromJSON(args.get("params"), allocator);
+            }
+
+            session->InvokeCommand(cmd, &op, NULL);
+            TeecManager::Instance().RemoveOperation(opId);
+
+            picojson::object result;
+            result.insert(std::make_pair("cmd", picojson::value(static_cast<double>(cmd))));
+            result.insert(std::make_pair("params", translations::UpdateJSONParams(args.get("params"), op)));
+            ReportSuccess(picojson::value(result), response->get<picojson::object>());
+        } catch (const PlatformException& e) {
+            ReportError(e, response->get<picojson::object>());
+        }
+    };
 
+    auto invokeResponse =
+        [callbackId, this](const std::shared_ptr<picojson::value>& response) -> void {
+        picojson::object& obj = response->get<picojson::object>();
+        obj.insert(std::make_pair("callbackId", picojson::value(callbackId)));
+        Instance::PostMessage(this, response->serialize().c_str());
+    };
 
-    // if success
-    // ReportSuccess(out);
-    // if error
-    // ReportError(out);
-}
+    auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
 
+    TaskQueue::GetInstance().Queue<picojson::value>(invoke, invokeResponse, data);
+    ReportSuccess(picojson::value(static_cast<double>(opId)), out);
+}
 
 #undef CHECK_EXIST
 
index 48c7b7d..1e20757 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd 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.
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+/**
+ * @file
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief  Libteec instance declaration
+ */
 
 #ifndef LIBTEEC_LIBTEEC_INSTANCE_H_
 #define LIBTEEC_LIBTEEC_INSTANCE_H_
@@ -25,17 +30,25 @@ namespace libteec {
 class LibteecInstance : public common::ParsedInstance {
 public:
     LibteecInstance();
-    virtual ~LibteecInstance();
+    virtual ~LibteecInstance() = default;
 
 private:
-    void LibTeecManagerGetContext(const picojson::value& args, picojson::object& out);
-    void TeecSharedMemorySetData(const picojson::value& args, picojson::object& out);
-    void TeecContextReleaseSharedMemory(const picojson::value& args, picojson::object& out);
+    void LibTeecManagerGetContext(const picojson::value& args, picojson::object& out) const;
+
+    // SharedMemory
+    void TeecSharedMemorySetData(const picojson::value& args, picojson::object& out) const;
+    void TeecSharedMemoryGetData(const picojson::value& args, picojson::object& out) const;
+
+    // Context
+    void TeecContextReleaseSharedMemory(const picojson::value& args, picojson::object& out) const;
     void TeecContextOpenSession(const picojson::value& args, picojson::object& out);
-    void TeecContextRegisterSharedMemory(const picojson::value& args, picojson::object& out);
-    void TeecContextAllocateSharedMemory(const picojson::value& args, picojson::object& out);
-    void TeecSharedMemoryGetData(const picojson::value& args, picojson::object& out);
-    void TeecContextRevokeCommand(const picojson::value& args, picojson::object& out);
+    void TeecContextRegisterSharedMemory(const picojson::value& args, picojson::object& out) const;
+    void TeecContextAllocateSharedMemory(const picojson::value& args, picojson::object& out) const;
+    void TeecContextRevokeCommand(const picojson::value& args, picojson::object& out) const;
+
+    // Session
+    void TeecSessionClose(const picojson::value& args, picojson::object& out) const;
+    void TeecSessionInvokeCommand(const picojson::value& args, picojson::object& out);
 };
 
 } // namespace libteec
index a6ab469..3d2bb02 100644 (file)
         'libteec_extension.h',
         'libteec_instance.cc',
         'libteec_instance.h',
+        'TeecManager.cc',
+        'TeecManager.h',
+        'TeecTranslations.cc',
+        'TeecTranslations.h',
+        'TeecContext.cc',
+        'TeecContext.h',
+        'TeecSession.cc',
+        'TeecSession.h',
+        'TeecSharedMemory.cc',
+        'TeecSharedMemory.h',
+        'TeecTempMemoryAllocator.cc',
+        'TeecTempMemoryAllocator.h'
       ],
       'include_dirs': [
         '../',
         '<(SHARED_INTERMEDIATE_DIR)',
       ],
       'variables': {
+        'pkg-config': 'pkg-config',
         'packages': [
           'webapi-plugins',
+          'tef-libteec',
         ],
       },
     },