/* * 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 #include #include #include #include #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(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(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(call); if (call.GetInterface() == nullptr) call2.SetInterface(GetName().c_str()); return _InvokeMethodWaitTime(call2, timeout); } bool InterfaceProxy::InvokeMethodNoReply(const CallMessage &call) { CallMessage &call2 = const_cast(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(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(call->Data()); try { Message reply = call->StealReply(); CallData->Call(reply); } catch (const UDBusError &e) { DEBUG("%s", e.what()); } delete CallData; RemovePendingCall(call); return; }