215 lines
5.6 KiB
C++
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;
|
|
} |