summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kostyra <l.kostyra@samsung.com>2017-09-21 17:52:41 +0200
committerLukasz Kostyra <l.kostyra@samsung.com>2017-10-18 12:36:01 +0200
commit34e134bae726d863ae6a83071823c777204ff576 (patch)
tree048516aef69d5e7c9d8f22fc37d738e3404269b6
parent658273d768e61bd8a7c5900b6452dc0a13b63644 (diff)
downloadlibteec-34e134bae726d863ae6a83071823c777204ff576.tar.gz
libteec-34e134bae726d863ae6a83071823c777204ff576.tar.bz2
libteec-34e134bae726d863ae6a83071823c777204ff576.zip
Change-Id: I44e6c174493e92024cd031cbfebf15c4073482c8
-rw-r--r--packaging/webapi-plugins-teec.spec2
-rw-r--r--src/teec/TeecContext.cc117
-rw-r--r--src/teec/TeecContext.h69
-rw-r--r--src/teec/TeecManager.cc74
-rw-r--r--src/teec/TeecManager.h68
-rw-r--r--src/teec/TeecSession.cc84
-rw-r--r--src/teec/TeecSession.h51
-rw-r--r--src/teec/TeecSharedMemory.cc93
-rw-r--r--src/teec/TeecSharedMemory.h54
-rw-r--r--src/teec/TeecTempMemoryAllocator.cc39
-rw-r--r--src/teec/TeecTempMemoryAllocator.h52
-rw-r--r--src/teec/TeecTranslations.cc379
-rw-r--r--src/teec/TeecTranslations.h52
-rw-r--r--src/teec/libteec_api.js269
-rw-r--r--src/teec/libteec_extension.cc5
-rw-r--r--src/teec/libteec_extension.h5
-rw-r--r--src/teec/libteec_instance.cc415
-rw-r--r--src/teec/libteec_instance.h31
-rw-r--r--src/teec/teec.gyp14
19 files changed, 1635 insertions, 238 deletions
diff --git a/packaging/webapi-plugins-teec.spec b/packaging/webapi-plugins-teec.spec
index 4a0ea10..04ae34b 100644
--- a/packaging/webapi-plugins-teec.spec
+++ b/packaging/webapi-plugins-teec.spec
@@ -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
index 0000000..280db24
--- /dev/null
+++ b/src/teec/TeecContext.cc
@@ -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
index 0000000..2a5f73f
--- /dev/null
+++ b/src/teec/TeecContext.h
@@ -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
index 0000000..826f20b
--- /dev/null
+++ b/src/teec/TeecManager.cc
@@ -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
index 0000000..c7cc768
--- /dev/null
+++ b/src/teec/TeecManager.h
@@ -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
index 0000000..8917652
--- /dev/null
+++ b/src/teec/TeecSession.cc
@@ -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
index 0000000..141c427
--- /dev/null
+++ b/src/teec/TeecSession.h
@@ -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
index 0000000..438bb79
--- /dev/null
+++ b/src/teec/TeecSharedMemory.cc
@@ -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
index 0000000..9af881c
--- /dev/null
+++ b/src/teec/TeecSharedMemory.h
@@ -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
index 0000000..65f8929
--- /dev/null
+++ b/src/teec/TeecTempMemoryAllocator.cc
@@ -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
index 0000000..84523b4
--- /dev/null
+++ b/src/teec/TeecTempMemoryAllocator.h
@@ -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
index 0000000..e6316cb
--- /dev/null
+++ b/src/teec/TeecTranslations.cc
@@ -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
index 0000000..c8b3b3b
--- /dev/null
+++ b/src/teec/TeecTranslations.h
@@ -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_
diff --git a/src/teec/libteec_api.js b/src/teec/libteec_api.js
index 68811dd..92e3e04 100644
--- a/src/teec/libteec_api.js
+++ b/src/teec/libteec_api.js
@@ -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;
-
diff --git a/src/teec/libteec_extension.cc b/src/teec/libteec_extension.cc
index 48953b1..1d48506 100644
--- a/src/teec/libteec_extension.cc
+++ b/src/teec/libteec_extension.cc
@@ -13,6 +13,11 @@
* 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"
diff --git a/src/teec/libteec_extension.h b/src/teec/libteec_extension.h
index 52188a9..f1f94b3 100644
--- a/src/teec/libteec_extension.h
+++ b/src/teec/libteec_extension.h
@@ -13,6 +13,11 @@
* 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_
diff --git a/src/teec/libteec_instance.cc b/src/teec/libteec_instance.cc
index 5ac689c..6cbfbbb 100644
--- a/src/teec/libteec_instance.cc
+++ b/src/teec/libteec_instance.cc
@@ -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.
@@ -13,24 +13,38 @@
* 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
diff --git a/src/teec/libteec_instance.h b/src/teec/libteec_instance.h
index 48c7b7d..1e20757 100644
--- a/src/teec/libteec_instance.h
+++ b/src/teec/libteec_instance.h
@@ -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.
@@ -13,6 +13,11 @@
* 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
diff --git a/src/teec/teec.gyp b/src/teec/teec.gyp
index a6ab469..3d2bb02 100644
--- a/src/teec/teec.gyp
+++ b/src/teec/teec.gyp
@@ -12,14 +12,28 @@
'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',
],
},
},