112636162Sopenharmony_ci/* 212636162Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 312636162Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 412636162Sopenharmony_ci * you may not use this file except in compliance with the License. 512636162Sopenharmony_ci * You may obtain a copy of the License at 612636162Sopenharmony_ci * 712636162Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 812636162Sopenharmony_ci * 912636162Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1012636162Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1112636162Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1212636162Sopenharmony_ci * See the License for the specific language governing permissions and 1312636162Sopenharmony_ci * limitations under the License. 1412636162Sopenharmony_ci */ 1512636162Sopenharmony_ci 1612636162Sopenharmony_ci#include <cerrno> 1712636162Sopenharmony_ci#include <ashmem.h> 1812636162Sopenharmony_ci#include <unordered_map> 1912636162Sopenharmony_ci#include <mutex> 2012636162Sopenharmony_ci#include "ddk_api.h" 2112636162Sopenharmony_ci#include "ddk_types.h" 2212636162Sopenharmony_ci#include "hilog_wrapper.h" 2312636162Sopenharmony_ci 2412636162Sopenharmony_ci#define PORT_MAX 7 2512636162Sopenharmony_ci 2612636162Sopenharmony_ciusing namespace OHOS::ExternalDeviceManager; 2712636162Sopenharmony_cinamespace { 2812636162Sopenharmony_cistatic std::unordered_map<int32_t, OHOS::sptr<OHOS::Ashmem>> g_shareMemoryMap; 2912636162Sopenharmony_cistd::mutex g_mutex; 3012636162Sopenharmony_ci} 3112636162Sopenharmony_ci 3212636162Sopenharmony_ciDDK_RetCode OH_DDK_CreateAshmem(const uint8_t *name, uint32_t size, DDK_Ashmem **ashmem) 3312636162Sopenharmony_ci{ 3412636162Sopenharmony_ci if (name == nullptr) { 3512636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "invalid buffer name!"); 3612636162Sopenharmony_ci return DDK_INVALID_PARAMETER; 3712636162Sopenharmony_ci } 3812636162Sopenharmony_ci 3912636162Sopenharmony_ci if (size == 0) { 4012636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "invalid buffer size!, size = %{public}d", size); 4112636162Sopenharmony_ci return DDK_INVALID_PARAMETER; 4212636162Sopenharmony_ci } 4312636162Sopenharmony_ci 4412636162Sopenharmony_ci if (ashmem == nullptr) { 4512636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "invalid pointer of ashmem!"); 4612636162Sopenharmony_ci return DDK_INVALID_PARAMETER; 4712636162Sopenharmony_ci } 4812636162Sopenharmony_ci 4912636162Sopenharmony_ci OHOS::sptr<OHOS::Ashmem> shareMemory = OHOS::Ashmem::CreateAshmem(reinterpret_cast<const char*>(name), size); 5012636162Sopenharmony_ci if (shareMemory == nullptr) { 5112636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "create ashmem failed! errno = %{public}d", errno); 5212636162Sopenharmony_ci return DDK_FAILURE; 5312636162Sopenharmony_ci } 5412636162Sopenharmony_ci 5512636162Sopenharmony_ci int32_t fd = shareMemory->GetAshmemFd(); 5612636162Sopenharmony_ci DDK_Ashmem *ddkAshmem = new DDK_Ashmem({fd, nullptr, size, 0, size, 0}); 5712636162Sopenharmony_ci if (ddkAshmem == nullptr) { 5812636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "alloc ddk ashmem failed! errno = %{public}d", errno); 5912636162Sopenharmony_ci return DDK_FAILURE; 6012636162Sopenharmony_ci } 6112636162Sopenharmony_ci *ashmem = ddkAshmem; 6212636162Sopenharmony_ci 6312636162Sopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 6412636162Sopenharmony_ci g_shareMemoryMap[ddkAshmem->ashmemFd] = shareMemory; 6512636162Sopenharmony_ci return DDK_SUCCESS; 6612636162Sopenharmony_ci} 6712636162Sopenharmony_ci 6812636162Sopenharmony_cistatic DDK_RetCode AshmemValidityCheck(DDK_Ashmem *ashmem) 6912636162Sopenharmony_ci{ 7012636162Sopenharmony_ci if (ashmem == nullptr) { 7112636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "ashmem is nullptr!"); 7212636162Sopenharmony_ci return DDK_NULL_PTR; 7312636162Sopenharmony_ci } 7412636162Sopenharmony_ci 7512636162Sopenharmony_ci if (g_shareMemoryMap.find(ashmem->ashmemFd) == g_shareMemoryMap.end()) { 7612636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "ashmemFd dose not exist! error fd = %{public}d", ashmem->ashmemFd); 7712636162Sopenharmony_ci return DDK_FAILURE; 7812636162Sopenharmony_ci } 7912636162Sopenharmony_ci 8012636162Sopenharmony_ci if (g_shareMemoryMap[ashmem->ashmemFd] == nullptr) { 8112636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "share memory dose not create!"); 8212636162Sopenharmony_ci return DDK_FAILURE; 8312636162Sopenharmony_ci } 8412636162Sopenharmony_ci 8512636162Sopenharmony_ci return DDK_SUCCESS; 8612636162Sopenharmony_ci} 8712636162Sopenharmony_ci 8812636162Sopenharmony_ciDDK_RetCode OH_DDK_MapAshmem(DDK_Ashmem *ashmem, const uint8_t ashmemMapType) 8912636162Sopenharmony_ci{ 9012636162Sopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 9112636162Sopenharmony_ci DDK_RetCode ret = AshmemValidityCheck(ashmem); 9212636162Sopenharmony_ci if (ret != DDK_SUCCESS) { 9312636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "%{public}s: check the validity of ashmem fail!", __func__); 9412636162Sopenharmony_ci return ret; 9512636162Sopenharmony_ci } 9612636162Sopenharmony_ci 9712636162Sopenharmony_ci if (ashmemMapType > PORT_MAX) { 9812636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "%{public}s: the ashmemMapType is illegal ,ashmemMapType = %{public}u", 9912636162Sopenharmony_ci __func__, ashmemMapType); 10012636162Sopenharmony_ci return DDK_INVALID_OPERATION; 10112636162Sopenharmony_ci } 10212636162Sopenharmony_ci 10312636162Sopenharmony_ci if (!g_shareMemoryMap[ashmem->ashmemFd]->MapAshmem(ashmemMapType)) { 10412636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "MapAshmem fail! errno = %{public}d", errno); 10512636162Sopenharmony_ci return DDK_INVALID_OPERATION; 10612636162Sopenharmony_ci } 10712636162Sopenharmony_ci 10812636162Sopenharmony_ci ashmem->address = 10912636162Sopenharmony_ci reinterpret_cast<const uint8_t *>(g_shareMemoryMap[ashmem->ashmemFd]->ReadFromAshmem(ashmem->size, 0)); 11012636162Sopenharmony_ci return DDK_SUCCESS; 11112636162Sopenharmony_ci} 11212636162Sopenharmony_ci 11312636162Sopenharmony_ciDDK_RetCode OH_DDK_UnmapAshmem(DDK_Ashmem *ashmem) 11412636162Sopenharmony_ci{ 11512636162Sopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 11612636162Sopenharmony_ci DDK_RetCode ret = AshmemValidityCheck(ashmem); 11712636162Sopenharmony_ci if (ret != DDK_SUCCESS) { 11812636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "%{public}s: check the validity of ashmem fail!", __func__); 11912636162Sopenharmony_ci return ret; 12012636162Sopenharmony_ci } 12112636162Sopenharmony_ci 12212636162Sopenharmony_ci g_shareMemoryMap[ashmem->ashmemFd]->UnmapAshmem(); 12312636162Sopenharmony_ci ashmem->address = nullptr; 12412636162Sopenharmony_ci return DDK_SUCCESS; 12512636162Sopenharmony_ci} 12612636162Sopenharmony_ci 12712636162Sopenharmony_ciDDK_RetCode OH_DDK_DestroyAshmem(DDK_Ashmem *ashmem) 12812636162Sopenharmony_ci{ 12912636162Sopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 13012636162Sopenharmony_ci DDK_RetCode ret = AshmemValidityCheck(ashmem); 13112636162Sopenharmony_ci if (ret != DDK_SUCCESS) { 13212636162Sopenharmony_ci EDM_LOGE(MODULE_BASE_DDK, "%{public}s: check the validity of ashmem fail!", __func__); 13312636162Sopenharmony_ci return ret; 13412636162Sopenharmony_ci } 13512636162Sopenharmony_ci 13612636162Sopenharmony_ci g_shareMemoryMap.erase(ashmem->ashmemFd); 13712636162Sopenharmony_ci ashmem->address = nullptr; 13812636162Sopenharmony_ci delete ashmem; 13912636162Sopenharmony_ci ashmem = nullptr; 14012636162Sopenharmony_ci return DDK_SUCCESS; 14112636162Sopenharmony_ci} 142