Files
2026-09-22 09:38:26 +08:00

215 lines
5.6 KiB
C++

/*
* SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
* Copyright 2016-2023 Unisoc (Shanghai) Technologies Co., Ltd
* Licensed under the Unisoc General Software License, version 1.0 (the License);
* you may not use this file except in compliance with the License. You may obtain a copy of the License at
* https://www.unisoc.com/en_us/license/UNISOC_GENERAL_LICENSE_V1.0-EN_US
* Software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, either express or implied.
* See the Unisoc General Software License, version 1.0 for more details.
*/
#include <Debug.h>
#include <Interface.h>
#include <Pendingcall.h>
#include <Util.h>
#include <Message.h>
#include "InternalError.h"
using namespace UDBus;
Interface::Interface(const std::string &name)
: mName(name)
{}
Interface::~Interface()
{}
UDbusInterfaceAdaptor *UDbusAdaptorBase::FindInterface(const std::string &name)
{
UDbusInterfaceAdaptorTable::const_iterator ii = mInterfaces.find(name);
return ii != mInterfaces.end() ? ii->second : nullptr;
}
UDbusInterfaceAdaptor::UDbusInterfaceAdaptor(const std::string &name)
: Interface(name)
{
DEBUG("adding interface %s", name.c_str());
mInterfaces[name] = this;
}
Message UDbusInterfaceAdaptor::DispatchMethod(const CallMessage &msg)
{
const char *name = msg.GetMember();
MethodTable::iterator methodIter = mMethods.find(name);
if (methodIter != mMethods.end()) {
return methodIter->second.Call(msg);
} else {
return UDbusErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
}
}
void UDbusInterfaceAdaptor::ConfigSignal(SignalMessage &sig)
{
}
void UDbusInterfaceAdaptor::EmitSignal(const SignalMessage &sig)
{
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
if(GetName().empty())
{
return;
}
if (sig2.GetInterface() == nullptr)
sig2.SetInterface(GetName().c_str());
EmitSignalInternal(sig2);
}
UDbusVariant *UDbusInterfaceAdaptor::GetProperty(const std::string &name)
{
UDbusPropertyTable::iterator pti = mProperties.find(name);
if (pti != mProperties.end()) {
if (!pti->second.read)
throw ErrorAccessDenied("property is not readable");
return &(pti->second.value);
}
return nullptr;
}
void UDbusInterfaceAdaptor::SetProperty(const std::string &name, UDbusVariant &value)
{
UDbusPropertyTable::iterator propertyIter = mProperties.find(name);
if (propertyIter != mProperties.end()) {
if (!propertyIter->second.write)
throw ErrorAccessDenied("property is not writeable");
Signature sig = value.Signature();
if (propertyIter->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type");
propertyIter->second.value = value;
return;
}
throw ErrorFailed("requested property not found");
}
UDbusPropertyDict *UDbusInterfaceAdaptor::GetAllProperties()
{
UDbusPropertyTable::iterator propertyIter;
UDbusPropertyDict *propertyDict = new UDbusPropertyDict();
for (propertyIter = mProperties.begin(); propertyIter != mProperties.end();
++propertyIter)
{
if (!propertyIter->second.read)
continue;
UDbusVariant variant = propertyIter->second.value;
if (variant.Signature().empty())
continue;
std::string key = propertyIter->first;
(*propertyDict)[key] = variant;
}
return propertyDict;
}
InterfaceProxy *UDbusProxyBase::FindInterface(const std::string &name)
{
InterfaceProxyTable::const_iterator ii = mInterfaces.find(name);
return ii != mInterfaces.end() ? ii->second : nullptr;
}
InterfaceProxy::InterfaceProxy(const std::string &name)
: Interface(name)
{
DEBUG("adding interface %s", name.c_str());
mInterfaces[name] = this;
}
bool InterfaceProxy::DispatchSignal(const SignalMessage &msg)
{
const char *name = msg.GetMember();
SignalTable::iterator si = mSignals.find(name);
if (si != mSignals.end()) {
si->second.Call(msg);
return true;
} else {
return false;
}
}
Message InterfaceProxy::InvokeMethod(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.GetInterface() == nullptr)
call2.SetInterface(GetName().c_str());
return _InvokeMethod(call2);
}
Message InterfaceProxy::InvokeMethodWaitTime(const CallMessage &call, int timeout)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.GetInterface() == nullptr)
call2.SetInterface(GetName().c_str());
return _InvokeMethodWaitTime(call2, timeout);
}
bool InterfaceProxy::InvokeMethodNoReply(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.GetInterface() == nullptr)
call2.SetInterface(GetName().c_str());
return _InvokeMethodNoReply(call2);
}
PendingCall *InterfaceProxy::InvokeMethodAsync(const CallMessage &call, int timeout)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.GetInterface() == nullptr)
call2.SetInterface(GetName().c_str());
return _InvokeMethodAsync(call2, timeout);
}
void InterfaceProxy::RemovePendingCall(PendingCall *pending)
{
_RemovePendingCall(pending);
}
void InterfaceProxy::ReplyHandler(PendingCall *call)
{
PendingCallData *CallData = static_cast<PendingCallData *>(call->Data());
try
{
Message reply = call->StealReply();
CallData->Call(reply);
}
catch (const UDBusError &e)
{
DEBUG("%s", e.what());
}
delete CallData;
RemovePendingCall(call);
return;
}