* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "agnss_interface_impl.h"
#include <hdf_base.h>
#include <iproxy_broker.h>
#include <mutex>
#include <unordered_map>
#include "agnss_hdf_log.h"
#include "idevmgr_hdi.h"
#include "securec.h"
#include "location_vendor_interface.h"
#include "location_vendor_lib.h"
namespace OHOS {
namespace HDI {
namespace Location {
namespace Agnss {
namespace V2_1 {
namespace {
using AgnssCallBackMap = std::unordered_map<IRemoteObject*, sptr<IAGnssCallback>>;
using AgnssDeathRecipientMap = std::unordered_map<IRemoteObject*, sptr<IRemoteObject::DeathRecipient>>;
using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
AgnssCallBackMap g_agnssCallBackMap;
AgnssDeathRecipientMap g_agnssCallBackDeathRecipientMap;
std::mutex g_mutex;
std::mutex g_deathMutex;
uint32_t g_refInfoType;
const int MAC_LEN = 6;
}
extern "C" IAGnssInterface* AGnssInterfaceImplGetInstance(void)
{
return new (std::nothrow) AGnssInterfaceImpl();
}
void RequestSetupAgnssDataConnection(const AgnssDataConnectionRequest* status)
{
if (status == nullptr) {
HDF_LOGE("%{public}s:status is nullptr.", __func__);
return;
}
HDF_LOGI("%{public}s.", __func__);
AGnssDataLinkRequest agnssStatus;
agnssStatus.agnssType = static_cast<AGnssUserPlaneProtocol>(status->agnssCategory);
agnssStatus.setUpType = static_cast<DataLinkSetUpType>(status->requestCategory);
std::unique_lock<std::mutex> lock(g_mutex);
for (const auto& iter : g_agnssCallBackMap) {
auto& callback = iter.second;
if (callback != nullptr) {
callback->RequestSetUpAgnssDataLink(agnssStatus);
}
}
}
void GetSetidCb(uint16_t type)
{
HDF_LOGI("%{public}s.", __func__);
std::unique_lock<std::mutex> lock(g_mutex);
for (const auto& iter : g_agnssCallBackMap) {
auto& callback = iter.second;
if (callback != nullptr) {
callback->RequestSubscriberSetId(static_cast<SubscriberSetIdType>(type));
}
}
}
void GetRefLocationidCb(uint32_t type)
{
HDF_LOGI("%{public}s, type=%{public}d", __func__, type);
std::unique_lock<std::mutex> lock(g_mutex);
g_refInfoType = type;
for (const auto& iter : g_agnssCallBackMap) {
auto& callback = iter.second;
if (callback != nullptr) {
callback->RequestAgnssRefInfo(static_cast<AGnssRefInfoType>(type));
}
}
}
void GetAGnssCallbackMethods(AgnssCallbackIfaces* device)
{
if (device == nullptr) {
return;
}
device->size = sizeof(AgnssCallbackIfaces);
device->requestSetupDataLink = RequestSetupAgnssDataConnection;
device->requestSetid = GetSetidCb;
device->requestRefInfo = GetRefLocationidCb;
}
AGnssInterfaceImpl::AGnssInterfaceImpl()
{
g_refInfoType = 0;
}
AGnssInterfaceImpl::~AGnssInterfaceImpl()
{
ResetAgnssDeathRecipient();
}
int32_t AGnssInterfaceImpl::SetAgnssCallback(const sptr<IAGnssCallback>& callbackObj)
{
HDF_LOGI("%{public}s.", __func__);
if (callbackObj == nullptr) {
HDF_LOGE("%{public}s:invalid callbackObj", __func__);
return HDF_ERR_INVALID_PARAM;
}
const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
if (remote == nullptr) {
HDF_LOGE("%{public}s:invalid remote", __func__);
return HDF_ERR_INVALID_PARAM;
}
std::unique_lock<std::mutex> lock(g_mutex);
auto callBackIter = g_agnssCallBackMap.find(remote.GetRefPtr());
if (callBackIter != g_agnssCallBackMap.end()) {
const sptr<IRemoteObject>& lhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
const sptr<IRemoteObject>& rhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callBackIter->second);
return lhs == rhs ? HDF_SUCCESS : HDF_FAILURE;
}
static AgnssCallbackIfaces agnsscallback;
GetAGnssCallbackMethods(&agnsscallback);
int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
auto agnssInterface =
static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
if (agnssInterface == nullptr) {
HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
return HDF_ERR_INVALID_PARAM;
}
bool ret = agnssInterface->setAgnssCallback(&agnsscallback);
if (!ret) {
HDF_LOGE("setAgnssCallback failed.");
}
AddAgnssDeathRecipient(callbackObj);
g_agnssCallBackMap[remote.GetRefPtr()] = callbackObj;
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::SetAgnssServer(const AGnssServerInfo& server)
{
HDF_LOGI("%{public}s.", __func__);
int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
auto agnssInterface =
static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
if (agnssInterface == nullptr) {
HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
return HDF_ERR_INVALID_PARAM;
}
uint16_t type = static_cast<uint16_t>(server.type);
bool ret = agnssInterface->setAgnssServer(type, server.server.c_str(), server.server.length(), server.port);
if (!ret) {
HDF_LOGE("setAgnssServer failed.");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::SetAgnssRefInfo(const AGnssRefInfo& refInfo)
{
int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
auto agnssInterface =
static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
if (agnssInterface == nullptr) {
HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
return HDF_ERR_INVALID_PARAM;
}
HDF_LOGI("%{public}s, g_refInfoType=%{public}d", __func__, refInfo.type);
AgnssReferenceInfo loc;
loc.category = g_refInfoType;
if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_MAC)) {
for (size_t i = 0; i < MAC_LEN; i++) {
loc.u.mac.mac[i] = refInfo.mac.mac[i];
}
loc.u.mac.size = MAC_LEN;
} else if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_CELLID)) {
switch (refInfo.cellId.type) {
case CELLID_TYPE_GSM:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_GSM);
break;
case CELLID_TYPE_UMTS:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_UMTS);
break;
case CELLID_TYPE_LTE:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_LTE);
break;
case CELLID_TYPE_NR:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_NR);
break;
default:
HDF_LOGE("%{public}s wrong cellType.", __func__);
return HDF_ERR_INVALID_PARAM;
}
loc.u.cellId.mcc = refInfo.cellId.mcc;
loc.u.cellId.mnc = refInfo.cellId.mnc;
loc.u.cellId.lac = refInfo.cellId.lac;
loc.u.cellId.cid = refInfo.cellId.cid;
loc.u.cellId.tac = refInfo.cellId.tac;
loc.u.cellId.pcid = refInfo.cellId.pcid;
loc.u.cellId.nci = refInfo.cellId.nci;
}
bool ret = agnssInterface->setAgnssReferenceInfo(&loc);
if (!ret) {
HDF_LOGE("setAgnssReferenceInfo failed.");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::SetAgnssReferenceInfo(const AGnssReferenceInfo& refInfo)
{
int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
auto agnssInterface =
static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
if (agnssInterface == nullptr) {
HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
return HDF_ERR_INVALID_PARAM;
}
HDF_LOGI("%{public}s, g_refInfoType=%{public}d", __func__, refInfo.type);
AgnssReferenceInfo2_1 loc;
loc.category = g_refInfoType;
if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_MAC)) {
for (size_t i = 0; i < MAC_LEN; i++) {
loc.u.mac.mac[i] = refInfo.mac.mac[i];
}
loc.u.mac.size = MAC_LEN;
} else if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_CELLID)) {
switch (refInfo.cellId.type) {
case CELLID_TYPE_GSM:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_GSM);
break;
case CELLID_TYPE_UMTS:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_UMTS);
break;
case CELLID_TYPE_LTE:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_LTE);
break;
case CELLID_TYPE_NR:
loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_NR);
break;
default:
HDF_LOGE("%{public}s wrong cellType.", __func__);
return HDF_ERR_INVALID_PARAM;
}
loc.u.cellId.mcc = refInfo.cellId.mcc;
loc.u.cellId.mnc = refInfo.cellId.mnc;
loc.u.cellId.lac = refInfo.cellId.lac;
loc.u.cellId.cid = refInfo.cellId.cid;
loc.u.cellId.tac = refInfo.cellId.tac;
loc.u.cellId.pcid = refInfo.cellId.pcid;
loc.u.cellId.nci = refInfo.cellId.nci;
}
bool ret = agnssInterface->setAgnssReferenceInfo2_1(&loc);
if (!ret) {
HDF_LOGE("setAgnssReferenceInfo failed.");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::SetSubscriberSetId(const SubscriberSetId& id)
{
HDF_LOGI("%{public}s.", __func__);
int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
auto agnssInterface =
static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
if (agnssInterface == nullptr) {
HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
return HDF_ERR_INVALID_PARAM;
}
uint16_t type = static_cast<uint16_t>(id.type);
int ret = agnssInterface->setSetid(type, id.id.c_str(), id.id.length());
if (!ret) {
HDF_LOGE("setSetid failed.");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::AddAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
{
sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) AgnssCallBackDeathRecipient(this));
const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
bool result = remote->AddDeathRecipient(death);
if (!result) {
HDF_LOGE("%{public}s: AGnssInterfaceImpl add deathRecipient fail", __func__);
return HDF_FAILURE;
}
std::unique_lock<std::mutex> lock(g_deathMutex);
g_agnssCallBackDeathRecipientMap[remote.GetRefPtr()] = death;
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::RemoveAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
{
std::unique_lock<std::mutex> lock(g_deathMutex);
const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
auto iter = g_agnssCallBackDeathRecipientMap.find(remote.GetRefPtr());
if (iter == g_agnssCallBackDeathRecipientMap.end()) {
HDF_LOGE("%{public}s: AgnssInterfaceImpl can not find deathRecipient", __func__);
return HDF_FAILURE;
}
auto recipient = iter->second;
bool result = remote->RemoveDeathRecipient(recipient);
g_agnssCallBackDeathRecipientMap.erase(iter);
if (!result) {
HDF_LOGE("%{public}s: AgnssInterfaceImpl remove deathRecipient fail", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AGnssInterfaceImpl::SendNetworkState(const NetworkState& state)
{
return HDF_SUCCESS;
}
void AGnssInterfaceImpl::ResetAgnssDeathRecipient()
{
std::unique_lock<std::mutex> lock(g_mutex);
for (const auto& iter : g_agnssCallBackMap) {
const auto& callback = iter.second;
if (callback != nullptr) {
RemoveAgnssDeathRecipient(callback);
}
}
}
void AGnssInterfaceImpl::ResetAgnss()
{
HDF_LOGI("%{public}s called.", __func__);
ResetAgnssDeathRecipient();
std::unique_lock<std::mutex> lock(g_mutex);
g_agnssCallBackMap.clear();
}
}
}
}
}
}