提交 d3d52ceb 编写于 作者: Y yangguangzhao

RPC version control and access token supportted

Signed-off-by: Nyangguangzhao <yangguangzhao1@huawei.com>
上级 ac22868e
......@@ -23,11 +23,13 @@ config("libipc_core_private_config") {
ohos_shared_library("ipc_core") {
include_dirs = [
"$IPC_CORE_ROOT/c/adapter/access_token/include",
"$IPC_CORE_ROOT/c/rpc/include",
"$SUBSYSTEM_DIR/utils/include",
"//base/hiviewdfx/hitrace/interfaces/native/innerkits/include",
]
sources = [
"$IPC_CORE_ROOT/c/adapter/access_token/src/access_token_adapter.c",
"$IPC_CORE_ROOT/c/rpc/src/rpc_feature_set.c",
"$IPC_CORE_ROOT/src/core/source/buffer_object.cpp",
"$IPC_CORE_ROOT/src/core/source/comm_auth_info.cpp",
"$IPC_CORE_ROOT/src/core/source/databus_session_callback.cpp",
......
......@@ -39,7 +39,10 @@ config("libdbinder_private_config") {
}
ohos_shared_library("libdbinder") {
include_dirs = [ "$SUBSYSTEM_DIR/utils/include" ]
include_dirs = [
"$SUBSYSTEM_DIR/ipc/native/c/rpc/include",
"$SUBSYSTEM_DIR/utils/include",
]
sources = [
"$DBINDER_ROOT/dbinder_service/src/dbinder_death_recipient.cpp",
"$DBINDER_ROOT/dbinder_service/src/dbinder_sa_death_recipient.cpp",
......
......@@ -54,8 +54,7 @@ struct DHandleEntryTxRx {
struct DHandleEntryHead head;
uint32_t transType;
uint32_t dBinderCode;
uint16_t fromPort;
uint16_t toPort;
uint32_t rpcFeatureSet;
uint64_t stubIndex;
uint32_t seqNumber;
binder_uintptr_t binderObject;
......@@ -70,8 +69,7 @@ struct DHandleEntryTxRx {
struct SessionInfo {
uint32_t seqNumber;
uint32_t type;
uint16_t toPort;
uint16_t fromPort;
uint32_t rpcFeatureSet;
uint64_t stubIndex;
uint32_t socketFd;
std::string serviceName;
......@@ -165,6 +163,8 @@ private:
bool RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder);
bool CheckSystemAbilityId(int32_t systemAbilityId);
bool IsSameSession(std::shared_ptr<struct SessionInfo> oldSession, std::shared_ptr<struct SessionInfo> nowSession);
bool HandleInvokeListenThread(IPCObjectProxy *proxy, uint64_t stubIndex, std::string serverSessionName,
struct DHandleEntryTxRx *replyMessage);
private:
DISALLOW_COPY_AND_MOVE(DBinderService);
......
/*
* 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.
*/
#ifndef OHOS_RPC_FEATURE_SET_H
#define OHOS_RPC_FEATURE_SET_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t magicNum;
uint32_t tag;
uint32_t tokenId;
} AccessTokenData;
typedef struct {
uint32_t featureSet;
uint32_t tokenId;
} FeatureSetData;
uint32_t GetFeatureMagicNumber(void);
uint32_t GetFeatureATTag(void);
uint32_t GetLocalRpcFeature(void);
uint32_t GetRpcFeatureAck(void);
bool IsATEnable(uint32_t featureSet);
bool IsFeatureAck(uint32_t featureSet);
size_t GetATSize(uint32_t featureSet);
uint32_t GetTokenIdSize(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_FEATURE_SET_H
\ No newline at end of file
/*
* 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 "rpc_feature_set.h"
#define RPC_FEATURE_LAST (43)
#define RPC_ACCESS_TOKEN_FLAG 0x1
static const uint32_t RPC_FEATURE_MAGIC_NUM = ('R' << 24) | ('F' << 16) | ('S' << 8) | RPC_FEATURE_LAST;
static const uint32_t RPC_ACCESS_TOKEN = 0;
static const uint32_t RpcFeatureFlag = 0x1;
static const uint32_t TokenIdSize = 4;
static const uint32_t RpcFeatureAck = 0x80000000;
uint32_t GetFeatureMagicNumber(void)
{
return RPC_FEATURE_MAGIC_NUM;
}
uint32_t GetFeatureATTag(void)
{
return RPC_ACCESS_TOKEN;
}
uint32_t GetLocalRpcFeature(void)
{
return RpcFeatureFlag;
}
uint32_t GetRpcFeatureAck(void)
{
return RpcFeatureAck;
}
bool IsATEnable(uint32_t featureSet)
{
return (featureSet & RPC_ACCESS_TOKEN_FLAG) > 0;
}
bool IsFeatureAck(uint32_t featureSet)
{
return (featureSet & RpcFeatureAck) > 0;
}
size_t GetATSize(uint32_t featureSet)
{
size_t atSize = 0;
if (IsATEnable(featureSet) == true) {
atSize += sizeof(AccessTokenData);
}
return atSize;
}
uint32_t GetTokenIdSize(void)
{
return TokenIdSize;
}
\ No newline at end of file
......@@ -18,22 +18,26 @@
#include "iremote_object.h"
#include "ipc_object_stub.h"
#include "rpc_feature_set.h"
namespace OHOS {
class CommAuthInfo {
public:
CommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId);
CommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId,
std::shared_ptr<FeatureSetData> featureSet);
virtual ~CommAuthInfo();
const IRemoteObject *GetStubObject() const;
int GetRemotePid() const;
int GetRemoteUid() const;
std::string GetRemoteDeviceId() const;
std::shared_ptr<FeatureSetData> GetFeatureSet() const;
private:
IRemoteObject *stub_;
int remotePid_;
int remoteUid_;
std::string deviceId_;
std::shared_ptr<FeatureSetData> featureSet_;
};
} // namespace OHOS
#endif // OHOS_IPC_COMMAUTHINFO_H
\ No newline at end of file
......@@ -19,12 +19,14 @@
#include <string>
#include "ipc_object_stub.h"
#include "rpc_feature_set.h"
namespace OHOS {
class DBinderCallbackStub : public IPCObjectStub {
public:
explicit DBinderCallbackStub(const std::string &serviceName, const std::string &peerDeviceID,
const std::string &localDeviceID, uint64_t stubIndex, uint32_t handle);
const std::string &localDeviceID, uint64_t stubIndex, uint32_t handle,
std::shared_ptr<FeatureSetData> feature);
~DBinderCallbackStub();
int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
......@@ -32,6 +34,10 @@ public:
const std::string &GetServiceName();
const std::string &GetDeviceID();
uint64_t GetStubIndex() const;
std::shared_ptr<FeatureSetData> GetFeatureSet() const;
private:
uint32_t ConstructAuthData(MessageParcel &authData, uint32_t featureSet);
private:
const std::string serviceName_;
......@@ -39,6 +45,7 @@ private:
const std::string localDeviceID_;
uint64_t stubIndex_;
uint32_t handle_;
std::shared_ptr<FeatureSetData> rpcFeatureSet_;
};
} // namespace OHOS
#endif // OHOS_IPC_DBINDER_CALLBACK_STUB_H
\ No newline at end of file
......@@ -21,6 +21,7 @@
#include "nocopyable.h"
#include "buffer_object.h"
#include "rpc_feature_set.h"
#include "Session.h"
#include "ISessionService.h"
......@@ -51,10 +52,12 @@ public:
void SetBusSession(std::shared_ptr<Session> session);
void SetServiceName(const std::string &serviceName);
void SetDeviceId(const std::string &serverDeviceId);
void SetFeatureSet(std::shared_ptr<FeatureSetData> rpcFeatureSet);
std::shared_ptr<BufferObject> GetSessionBuff();
std::shared_ptr<Session> GetBusSession() const;
std::string GetServiceName() const;
std::string GetDeviceId() const;
std::shared_ptr<FeatureSetData> GetFeatureSet() const;
uint32_t GetSessionHandle() const;
void CloseDatabusSession();
......@@ -66,6 +69,7 @@ private:
std::shared_ptr<BufferObject> buff_;
std::string serviceName_;
std::string serverDeviceId_;
std::shared_ptr<FeatureSetData> rpcFeatureSet_;
};
} // namespace OHOS
#endif // OHOS_IPC_DBINDER_SESSION_OBJECT_H
\ No newline at end of file
......@@ -33,6 +33,7 @@
#include "comm_auth_info.h"
#include "dbinder_callback_stub.h"
#include "dbinder_session_object.h"
#include "rpc_feature_set.h"
#include "ISessionService.h"
#include "Session.h"
#include "stub_refcount_object.h"
......@@ -169,10 +170,11 @@ public:
bool DecStubRefTimes(IRemoteObject *stub);
bool DetachStubRefTimes(IRemoteObject *stub);
bool AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId);
bool AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId,
std::shared_ptr<FeatureSetData> featureSet);
void DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId);
void DetachCommAuthInfoByStub(IRemoteObject *stub);
bool QueryIsAuth(int pid, int uid, const std::string &deviceId);
std::shared_ptr<FeatureSetData> QueryIsAuth(int pid, int uid, const std::string &deviceId);
bool AddDataThreadToIdle(const std::thread::id &threadId);
bool DeleteDataThreadFromIdle(const std::thread::id &threadId);
std::thread::id GetIdleDataThread();
......
......@@ -16,8 +16,9 @@
#include "comm_auth_info.h"
namespace OHOS {
CommAuthInfo::CommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId)
: stub_(stub), remotePid_(pid), remoteUid_(uid), deviceId_(deviceId)
CommAuthInfo::CommAuthInfo(IRemoteObject *stub, int pid, int uid,
const std::string &deviceId, std::shared_ptr<FeatureSetData> featureSet)
: stub_(stub), remotePid_(pid), remoteUid_(uid), deviceId_(deviceId), featureSet_(featureSet)
{}
CommAuthInfo::~CommAuthInfo()
......@@ -40,4 +41,9 @@ std::string CommAuthInfo::GetRemoteDeviceId() const
{
return deviceId_;
}
std::shared_ptr<FeatureSetData> CommAuthInfo::GetFeatureSet() const
{
return featureSet_;
}
} // namespace OHOS
......@@ -38,13 +38,14 @@ static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC,
(void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
DBinderCallbackStub::DBinderCallbackStub(const std::string &service, const std::string &device,
const std::string &localDevice, uint64_t stubIndex, uint32_t handle)
const std::string &localDevice, uint64_t stubIndex, uint32_t handle, std::shared_ptr<FeatureSetData> feature)
: IPCObjectStub(Str8ToStr16("DBinderCallback" + device + service)),
serviceName_(service),
deviceID_(device),
localDeviceID_(localDevice),
stubIndex_(stubIndex),
handle_(handle)
handle_(handle),
rpcFeatureSet_(feature)
{
DBINDER_LOGI("serviceName:%{public}s, deviceId:%{public}s, handle:%{public}u, stubIndex_:%{public}" PRIu64 "",
serviceName_.c_str(), deviceID_.c_str(), handle_, stubIndex_);
......@@ -70,6 +71,11 @@ uint64_t DBinderCallbackStub::GetStubIndex() const
return stubIndex_;
}
std::shared_ptr<FeatureSetData> DBinderCallbackStub::GetFeatureSet() const
{
return rpcFeatureSet_;
}
int32_t DBinderCallbackStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
......@@ -93,8 +99,9 @@ int32_t DBinderCallbackStub::ProcessProto(uint32_t code, MessageParcel &data, Me
MessageParcel authData, authReply;
MessageOption authOption;
uint32_t featureSet = rpcFeatureSet_->featureSet;
if (!authData.WriteUint32(pid) || !authData.WriteUint32(uid) || !authData.WriteString(localDeviceID_) ||
!authData.WriteUint64(stubIndex_)) {
!authData.WriteUint32(featureSet) || !authData.WriteUint64(stubIndex_)) {
DBINDER_LOGE("write to MessageParcel fail");
return ERR_INVALID_DATA;
}
......
......@@ -87,11 +87,21 @@ void DBinderSessionObject::SetDeviceId(const std::string &serverDeviceId)
serverDeviceId_ = serverDeviceId;
}
void DBinderSessionObject::SetFeatureSet(std::shared_ptr<FeatureSetData> rpcFeatureSet)
{
rpcFeatureSet_ = rpcFeatureSet;
}
std::string DBinderSessionObject::GetDeviceId() const
{
return serverDeviceId_;
}
std::shared_ptr<FeatureSetData> DBinderSessionObject::GetFeatureSet() const
{
return rpcFeatureSet_;
}
uint32_t DBinderSessionObject::GetFlatSessionLen()
{
return sizeof(struct FlatDBinderSession);
......
......@@ -24,7 +24,9 @@
#include "securec.h"
#ifndef CONFIG_IPC_SINGLE
#include "access_token_adapter.h"
#include "dbinder_databus_invoker.h"
#include "rpc_feature_set.h"
#endif
namespace OHOS {
......@@ -605,6 +607,19 @@ bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply
std::string peerID = reply.ReadString();
std::string localID = reply.ReadString();
std::string localBusName = reply.ReadString();
uint32_t rpcFeatureSet = reply.ReadUint32();
uint32_t tokenId = 0;
if (IsATEnable(rpcFeatureSet) == true) {
tokenId = RpcGetSelfTokenID();
}
std::shared_ptr<FeatureSetData> featureSet = nullptr;
featureSet.reset(reinterpret_cast<FeatureSetData *>(::operator new(sizeof(FeatureSetData))));
if (featureSet == nullptr) {
ZLOGE(LABEL, "%s: featureSet null", __func__);
return false;
}
featureSet->featureSet = rpcFeatureSet;
featureSet->tokenId = tokenId;
IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
if (current == nullptr) {
......@@ -620,6 +635,7 @@ bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply
return false;
}
}
connectSession->SetFeatureSet(featureSet);
if (!current->AttachHandleToIndex((uint32_t)handle, stubIndex)) {
ZLOGE(LABEL, "add stub index err stubIndex = %" PRIu64 ", handle = %d", stubIndex, handle);
......@@ -632,12 +648,7 @@ bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply
}
bool result = invoker->UpdateClientSession(handle, connectSession);
if (!result) {
ZLOGE(LABEL, "update server session object fail!");
return false;
}
return true;
return result;
}
void IPCObjectProxy::ReleaseDatabusProto()
......
......@@ -25,6 +25,7 @@
#ifndef CONFIG_IPC_SINGLE
#include "dbinder_databus_invoker.h"
#include "dbinder_error_code.h"
#include "rpc_feature_set.h"
#include "ISessionService.h"
#endif
......@@ -352,6 +353,16 @@ int32_t IPCObjectStub::InvokerDataBusThread(MessageParcel &data, MessageParcel &
uint32_t remoteUid = data.ReadUint32();
std::string remoteDeviceId = data.ReadString();
std::string sessionName = data.ReadString();
uint32_t featureSet = data.ReadUint32();
uint32_t tokenId = 0;
std::shared_ptr<FeatureSetData> feature = std::make_shared<FeatureSetData>();
if (feature == nullptr) {
ZLOGE(LABEL, "%s: feature null", __func__);
return IPC_STUB_INVALID_DATA_ERR;
}
feature->featureSet = featureSet;
feature->tokenId = tokenId;
if (IsDeviceIdIllegal(deviceId) || IsDeviceIdIllegal(remoteDeviceId) || sessionName.empty()) {
ZLOGE(LABEL, "%s: device ID is invalid or session name nil", __func__);
return IPC_STUB_INVALID_DATA_ERR;
......@@ -379,7 +390,7 @@ int32_t IPCObjectStub::InvokerDataBusThread(MessageParcel &data, MessageParcel &
if (!current->AttachAppInfoToStubIndex(remotePid, remoteUid, remoteDeviceId, stubIndex)) {
ZLOGE(LABEL, "fail to attach appinfo to stubIndex, maybe attach already");
}
if (!current->AttachCommAuthInfo(this, (int32_t)remotePid, (int32_t)remoteUid, remoteDeviceId)) {
if (!current->AttachCommAuthInfo(this, (int32_t)remotePid, (int32_t)remoteUid, remoteDeviceId, feature)) {
ZLOGE(LABEL, "fail to attach comm auth info");
}
......@@ -453,6 +464,17 @@ int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply, ui
uint32_t remotePid = data.ReadUint32();
uint32_t remoteUid = data.ReadUint32();
std::string remoteDeviceId = data.ReadString();
uint32_t remoteFeature = data.ReadUint32();
uint32_t tokenId = 0;
std::shared_ptr<FeatureSetData> feature = nullptr;
feature.reset(reinterpret_cast<FeatureSetData *>(::operator new(sizeof(FeatureSetData))));
if (feature == nullptr) {
ZLOGE(LABEL, "%s: feature null", __func__);
return IPC_STUB_INVALID_DATA_ERR;
}
feature->featureSet = remoteFeature;
feature->tokenId = tokenId;
if (IsDeviceIdIllegal(remoteDeviceId)) {
ZLOGE(LABEL, "%s: remote deviceId is null", __func__);
return IPC_STUB_INVALID_DATA_ERR;
......@@ -464,7 +486,7 @@ int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply, ui
return IPC_STUB_CURRENT_NULL_ERR;
}
if (!current->AttachCommAuthInfo(this, (int32_t)remotePid, (int32_t)remoteUid, remoteDeviceId)) {
if (!current->AttachCommAuthInfo(this, (int32_t)remotePid, (int32_t)remoteUid, remoteDeviceId, feature)) {
ZLOGE(LABEL, "fail to attach comm auth info fail");
return IPC_STUB_INVALID_DATA_ERR;
}
......
......@@ -1200,7 +1200,8 @@ bool IPCProcessSkeleton::IsSameRemoteObject(int pid, int uid, const std::string
}
}
bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId)
bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid,
const std::string &deviceId, std::shared_ptr<FeatureSetData> featureSet)
{
auto check = [&stub, &pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
return IsSameRemoteObject(stub, pid, uid, deviceId, auth);
......@@ -1213,7 +1214,7 @@ bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int ui
return true;
}
std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>(stub, pid, uid, deviceId);
std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>(stub, pid, uid, deviceId, featureSet);
commAuth_.push_front(authObject);
return true;
}
......@@ -1228,7 +1229,7 @@ void IPCProcessSkeleton::DetachCommAuthInfo(IRemoteObject *stub, int pid, int ui
commAuth_.remove_if(check);
}
bool IPCProcessSkeleton::QueryIsAuth(int pid, int uid, const std::string &deviceId)
std::shared_ptr<FeatureSetData> IPCProcessSkeleton::QueryIsAuth(int pid, int uid, const std::string &deviceId)
{
auto check = [&pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
return IsSameRemoteObject(pid, uid, deviceId, auth);
......@@ -1237,10 +1238,10 @@ bool IPCProcessSkeleton::QueryIsAuth(int pid, int uid, const std::string &device
std::shared_lock<std::shared_mutex> lockGuard(commAuthMutex_);
auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
if (it != commAuth_.end()) {
return true;
return (*it)->GetFeatureSet();
}
DBINDER_LOGE("Query Comm Auth Fail");
return false;
return nullptr;
}
void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub)
......
......@@ -22,6 +22,7 @@
#ifndef CONFIG_IPC_SINGLE
#include "dbinder_callback_stub.h"
#include "dbinder_session_object.h"
#include "rpc_feature_set.h"
#endif
#include "ipc_debug.h"
#include "ipc_file_descriptor.h"
......@@ -108,10 +109,16 @@ bool MessageParcel::WriteDBinderProxy(const sptr<IRemoteObject> &object, uint32_
std::string peerName = sessionOfPeer->GetServiceName();
std::string peerId = sessionOfPeer->GetDeviceId();
std::string localId = current->GetLocalDeviceID();
std::shared_ptr<FeatureSetData> feature = sessionOfPeer->GetFeatureSet();
if (feature == nullptr) {
DBINDER_LOGE("feature is nullptr");
return false;
}
sptr<DBinderCallbackStub> fakeStub = current->QueryDBinderCallbackStub(object);
if (fakeStub == nullptr) {
// note that cannot use this proxy's descriptor
fakeStub = new DBinderCallbackStub(peerName, peerId, localId, stubIndex, handle);
fakeStub = new DBinderCallbackStub(peerName, peerId, localId, stubIndex, handle, feature);
if (!current->AttachDBinderCallbackStub(object, fakeStub)) {
DBINDER_LOGE("save callback of fake stub failed");
return false;
......
......@@ -100,8 +100,10 @@ public:
virtual void SetCallerUid(pid_t uid) = 0;
virtual void SetStatus(uint32_t status) = 0;
virtual void SetCallerDeviceID(const std::string &deviceId) = 0;
virtual void SetCallerTokenID(const uint32_t tokenId) = 0;
virtual int CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex) = 0;
virtual int OnSendRawData(std::shared_ptr<T> session, const void *data, size_t size) = 0;
virtual bool SetTokenId(const dbinder_transaction_data *tr, uint32_t listenFd) = 0;
bool CheckTransactionData(const dbinder_transaction_data *tr) const;
private:
......@@ -447,6 +449,14 @@ std::shared_ptr<dbinder_transaction_data> DBinderBaseInvoker<T>::ProcessNormalDa
uint32_t sendSize = ((data.GetDataSize() > 0) ? data.GetDataSize() : sizeof(binder_size_t)) +
sizeof(struct dbinder_transaction_data) + data.GetOffsetsSize() * T::GetFlatSessionLen() +
data.GetOffsetsSize() * sizeof(binder_size_t);
std::shared_ptr<FeatureSetData> feature = sessionObject->GetFeatureSet();
if (feature == nullptr) {
DBINDER_BASE_LOGE("process normal data feature is null");
return nullptr;
}
if (IsATEnable(feature->featureSet) == true) {
sendSize += GetTokenIdSize();
}
std::shared_ptr<dbinder_transaction_data> transData = nullptr;
transData.reset(reinterpret_cast<dbinder_transaction_data *>(::operator new(sendSize)));
......@@ -464,6 +474,11 @@ std::shared_ptr<dbinder_transaction_data> DBinderBaseInvoker<T>::ProcessNormalDa
DBINDER_BASE_LOGE("move parcel to transData failed, handle = %{public}d", handle);
return nullptr;
}
if (IsATEnable(feature->featureSet) == true) {
uint32_t bufferUseSize = transData->buffer_size + transData->offsets_size;
uint32_t *tokenIdAddr = (uint32_t *)(transData->buffer + bufferUseSize);
*tokenIdAddr = feature->tokenId;
}
return transData;
}
......@@ -493,7 +508,7 @@ bool DBinderBaseInvoker<T>::MoveTransData2Buffer(std::shared_ptr<T> sessionObjec
DBINDER_BASE_LOGE("sender's data is large than idle buffer");
return false;
}
if (memcpy_s(sendBuffer + writeCursor, sendSize, transData.get(), sendSize)) {
if (memcpy_s(sendBuffer + writeCursor, sendSize, transData.get(), sendSize) != EOK) {
sessionBuff->ReleaseSendBufferLock();
DBINDER_BASE_LOGE("fail to copy from tr to sendBuffer, parcelSize = %{public}u", sendSize);
return false;
......@@ -841,10 +856,15 @@ template <class T> void DBinderBaseInvoker<T>::ProcessTransaction(dbinder_transa
const auto oldUid = static_cast<const uid_t>(GetCallerUid());
const std::string oldDeviceId = GetCallerDeviceID();
uint32_t oldStatus = GetStatus();
const uint32_t oldTokenId = GetCallerTokenID();
if (CheckAndSetCallerInfo(listenFd, tr->cookie) != ERR_NONE) {
DBINDER_BASE_LOGE("set user info error, maybe cookie is NOT belong to current caller");
return;
}
if (SetTokenId(tr, listenFd) != true) {
DBINDER_BASE_LOGE("set tokenid failed");
return;
}
SetStatus(IRemoteInvoker::ACTIVE_INVOKER);
const uint32_t flags = tr->flags;
......@@ -889,6 +909,7 @@ template <class T> void DBinderBaseInvoker<T>::ProcessTransaction(dbinder_transa
SetCallerUid(oldUid);
SetCallerDeviceID(oldDeviceId);
SetStatus(oldStatus);
SetCallerTokenID(oldTokenId);
}
template <class T> void DBinderBaseInvoker<T>::ProcessReply(dbinder_transaction_data *tr, uint32_t listenFd)
......@@ -1001,7 +1022,7 @@ template <class T> bool DBinderBaseInvoker<T>::CheckTransactionData(const dbinde
}
binder_size_t sessionSize =
tr->sizeOfSelf - tr->buffer_size - sizeof(dbinder_transaction_data) - tr->offsets_size;
if (sessionSize * sizeof(binder_size_t) != tr->offsets_size * T::GetFlatSessionLen()) {
if (sessionSize * sizeof(binder_size_t) < tr->offsets_size * T::GetFlatSessionLen()) {
return false;
}
}
......
......@@ -88,6 +88,7 @@ private:
void SetCallerUid(pid_t uid) override;
void SetStatus(uint32_t status) override;
void SetCallerDeviceID(const std::string &deviceId) override;
void SetCallerTokenID(const uint32_t tokenId) override;
int CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex) override;
uint32_t HasRawDataPackage(const char *data, ssize_t len);
uint32_t HasCompletePackage(const char *data, uint32_t readCursor, ssize_t len);
......@@ -97,6 +98,7 @@ private:
bool ConnectRemoteObject2Session(IRemoteObject *stubObject, uint64_t stubIndex,
const std::shared_ptr<DBinderSessionObject> sessionObject);
bool AuthSession2Proxy(uint32_t handle, const std::shared_ptr<DBinderSessionObject> Session);
bool SetTokenId(const dbinder_transaction_data *tr, uint32_t listenFd) override;
private:
DISALLOW_COPY_AND_MOVE(DBinderDatabusInvoker);
......
......@@ -26,6 +26,7 @@
#include "ipc_debug.h"
#include "log_tags.h"
#include "databus_session_callback.h"
#include "rpc_feature_set.h"
namespace OHOS {
using namespace OHOS::HiviewDFX;
......@@ -153,11 +154,17 @@ bool DBinderDatabusInvoker::AuthSession2Proxy(uint32_t handle,
return false;
}
std::shared_ptr<FeatureSetData> feature = databusSession->GetFeatureSet();
if (feature == nullptr) {
DBINDER_LOGE("get feature fail");
return false;
}
MessageParcel data, reply;
MessageOption option;
if (!data.WriteUint32((uint32_t)(session->GetPeerPid())) || !data.WriteUint32(session->GetPeerUid()) ||
!data.WriteString(session->GetPeerDeviceId())) {
!data.WriteString(session->GetPeerDeviceId()) || !data.WriteUint32(feature->featureSet)) {
DBINDER_LOGE("write to MessageParcel fail");
return false;
}
......@@ -225,13 +232,16 @@ bool DBinderDatabusInvoker::OnReceiveNewConnection(std::shared_ptr<Session> sess
return false;
}
if (!current->QueryIsAuth(session->GetPeerPid(), (int32_t)(session->GetPeerUid()), session->GetPeerDeviceId())) {
DBINDER_LOGE("remote device is not auth");
auto featureSet = current->QueryIsAuth(session->GetPeerPid(), (int32_t)(session->GetPeerUid()),
session->GetPeerDeviceId());
if (featureSet == nullptr) {
DBINDER_LOGE("query auth failed, remote device featureSet is null");
return false;
}
std::shared_ptr<DBinderSessionObject> sessionObject =
std::make_shared<DBinderSessionObject>(session, session->GetPeerSessionName(), session->GetPeerDeviceId());
sessionObject->SetFeatureSet(featureSet);
if (!current->StubAttachDBinderSession(handle, sessionObject)) {
DBINDER_LOGE("attach session to process skeleton failed, handle =%u", handle);
......@@ -662,11 +672,40 @@ void DBinderDatabusInvoker::SetCallerDeviceID(const std::string &deviceId)
callerDeviceID_ = deviceId;
}
void DBinderDatabusInvoker::SetCallerTokenID(const uint32_t tokenId)
{
callerTokenID_ = tokenId;
}
bool DBinderDatabusInvoker::IsLocalCalling()
{
return false;
}
bool DBinderDatabusInvoker::SetTokenId(const dbinder_transaction_data *tr, uint32_t listenFd)
{
if (tr == nullptr) {
DBINDER_LOGE("set tokenid tr is null");
return false;
}
std::shared_ptr<DBinderSessionObject> sessionObject = QueryClientSessionObject(listenFd);
if (sessionObject == nullptr) {
DBINDER_LOGE("session is not exist for listenFd = %u", listenFd);
return false;
}
std::shared_ptr<FeatureSetData> feature = sessionObject->GetFeatureSet();
if (feature == nullptr) {
DBINDER_LOGE("feature is null");
return false;
}
if (IsATEnable(feature->featureSet) == true) {
uint32_t bufferUseSize = tr->buffer_size + tr->offsets_size;
uint32_t tokenId = *(uint32_t *)(tr->buffer + bufferUseSize);
SetCallerTokenID(tokenId);
}
return true;
}
int DBinderDatabusInvoker::CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex)
{
std::shared_ptr<DBinderSessionObject> sessionObject = QueryClientSessionObject(listenFd);
......@@ -788,7 +827,8 @@ bool DBinderDatabusInvoker::ConnectRemoteObject2Session(IRemoteObject *stubObjec
DBINDER_LOGI("fail to attach appinfo to stub index, when proxy call we check appinfo");
// attempt attach again, if failed, do nothing
}
if (!current->AttachCommAuthInfo(stubObject, peerPid, peerUid, deviceId)) {
if (!current->AttachCommAuthInfo(stubObject, peerPid, peerUid, deviceId, sessionObject->GetFeatureSet())) {
DBINDER_LOGI("fail to attach comm auth info, maybe attached already");
// attempt attach again, if failed, do nothing
}
......
......@@ -28,6 +28,9 @@ config("ipc_test_config") {
#################################group#########################################
group("moduletest") {
testonly = true
deps = [ "moduletest/native:moduletest" ]
deps = [
"$SUBSYSTEM_DIR/services/dbinder/test:moduletest",
"moduletest/native:moduletest",
]
}
###############################################################################
......@@ -30,6 +30,7 @@
#include "dbinder_error_code.h"
#include "softbus_bus_center.h"
#include "dbinder_sa_death_recipient.h"
#include "rpc_feature_set.h"
namespace OHOS {
using namespace Communication;
......@@ -293,9 +294,8 @@ bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint
message->head.version = VERSION_NUM;
message->dBinderCode = MESSAGE_AS_INVOKER;
message->transType = GetRemoteTransType();
message->fromPort = 0;
message->toPort = 0;
message->stubIndex = static_cast<uint64_t>(std::stoi(stub->GetServiceName().c_str()));
message->rpcFeatureSet = GetLocalRpcFeature();
message->stubIndex = static_cast<uint64_t>(std::atoi(stub->GetServiceName().c_str()));
message->seqNumber = seqNumber;
message->binderObject = stub->GetBinderObject();
message->stub = reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr());
......@@ -486,6 +486,29 @@ std::string DBinderService::CreateDatabusName(int uid, int pid)
return sessionName;
}
bool DBinderService::HandleInvokeListenThread(IPCObjectProxy *proxy, uint64_t stubIndex,
std::string serverSessionName, struct DHandleEntryTxRx *replyMessage)
{
if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
DBINDER_LOGE("stubindex or session name invalid");
return false;
}
replyMessage->dBinderCode = MESSAGE_AS_REPLY;
replyMessage->stubIndex = stubIndex;
replyMessage->serviceNameLength = serverSessionName.length();
if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
replyMessage->serviceNameLength) != 0) {
DBINDER_LOGE("fail to copy memory");
return false;
}
replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
replyMessage->rpcFeatureSet = GetLocalRpcFeature() | GetRpcFeatureAck();
(void)AttachBusNameObject(proxy, serverSessionName);
return true;
}
bool DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage,
std::string &remoteDeviceId, int pid, int uid)
{
......@@ -499,11 +522,12 @@ bool DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct
return false;
}
uint32_t featureSet = replyMessage->rpcFeatureSet & GetLocalRpcFeature();
MessageParcel data;
MessageParcel reply;
if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) ||
!data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) ||
!data.WriteString(sessionName)) {
!data.WriteString(sessionName) || !data.WriteUint32(featureSet)) {
DBINDER_LOGE("write to parcel fail");
return false;
}
......@@ -514,23 +538,7 @@ bool DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct
}
uint64_t stubIndex = reply.ReadUint64();
std::string serverSessionName = reply.ReadString();
if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
DBINDER_LOGE("stubindex or session name invalid");
return false;
}
replyMessage->dBinderCode = MESSAGE_AS_REPLY;
replyMessage->stubIndex = stubIndex;
replyMessage->serviceNameLength = serverSessionName.length();
if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
replyMessage->serviceNameLength) != 0) {
DBINDER_LOGE("fail to copy memory");
return false;
}
replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
(void)AttachBusNameObject(proxy, serverSessionName);
return true;
return HandleInvokeListenThread(proxy, stubIndex, serverSessionName, replyMessage);
}
std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject)
......@@ -652,8 +660,10 @@ void DBinderService::MakeSessionByReplyMessage(const struct DHandleEntryTxRx *re
session->seqNumber = replyMessage->seqNumber;
session->socketFd = 0;
session->stubIndex = replyMessage->stubIndex;
session->toPort = replyMessage->toPort;
session->fromPort = replyMessage->fromPort;
session->rpcFeatureSet = 0;
if (IsFeatureAck(replyMessage->rpcFeatureSet) == true) {
session->rpcFeatureSet = replyMessage->rpcFeatureSet & GetLocalRpcFeature();
}
session->type = replyMessage->transType;
session->serviceName = replyMessage->serviceName;
......
......@@ -85,7 +85,8 @@ int32_t DBinderServiceStub::ProcessProto(uint32_t code, MessageParcel &data, Mes
case IRemoteObject::DATABUS_TYPE: {
if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(session->stubIndex) ||
!reply.WriteString(session->serviceName) || !reply.WriteString(session->deviceIdInfo.toDeviceId) ||
!reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName)) {
!reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName) ||
!reply.WriteUint32(session->rpcFeatureSet)) {
DBINDER_LOGE("write to parcel fail");
return DBINDER_SERVICE_PROCESS_PROTO_ERR;
}
......
# Copyright (C) 2021 Huawei Device Co., Ltd.
# 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
......@@ -162,3 +162,8 @@ group("distributedtest") {
":dbindertest_py",
]
}
group("moduletest") {
testonly = true
deps = [ "moduletest" ]
}
# 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.
import("//build/test.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
# DBINDER_TEST_ROOT = "//foundation/communication/ipc/services/dbinder/test"
MODULE_OUTPUT_PATH = "ipc/services/dbinder"
ohos_moduletest("RPCCLIENTTEST") {
module_out_path = MODULE_OUTPUT_PATH
include_dirs = [
"include",
"${SUBSYSTEM_DIR}/utils/include",
"${SUBSYSTEM_DIR}/ipc/native/c/adapter/access_token/include",
]
sources = [
"src/rpc_client_test.cpp",
"src/rpc_test.cpp",
]
configs = [ "$SUBSYSTEM_DIR:ipc_util_config" ]
deps = [
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"dsoftbus_standard:softbus_client",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
]
}
ohos_moduletest("RPCSERVERTEST") {
module_out_path = MODULE_OUTPUT_PATH
include_dirs = [
"include",
"${SUBSYSTEM_DIR}/utils/include",
]
sources = [
"src/rpc_server_test.cpp",
"src/rpc_test.cpp",
]
configs = [ "$SUBSYSTEM_DIR:ipc_util_config" ]
deps = [
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"dsoftbus_standard:softbus_client",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
]
}
###############################################################################
group("moduletest") {
testonly = true
deps = [
":RPCCLIENTTEST",
":RPCSERVERTEST",
]
}
###############################################################################
/*
* 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.
*/
#ifndef OHOS_RPC_FOO_TEST_H
#define OHOS_RPC_FOO_TEST_H
#include <mutex>
#include <condition_variable>
#include "iremote_broker.h"
#include "iremote_proxy.h"
#include "iremote_stub.h"
#include "hilog/log.h"
#include "log_tags.h"
namespace OHOS {
class IFoo : public IRemoteBroker {
public:
enum FooInterFaceId {
GET_FOO_NAME = 0,
SEND_ASYNC_REPLY = 1,
SEND_WRONG_REPLY = 2,
GET_TOKENID = 3,
};
virtual std::string GetFooName() = 0;
virtual void SendAsyncReply(int &reply) = 0;
virtual int TestNestingSend(int sendCode) = 0;
virtual uint32_t TestAccessToken(void) = 0;
public:
DECLARE_INTERFACE_DESCRIPTOR(u"test.ipc.IFoo");
};
class FooStub : public IRemoteStub<IFoo> {
public:
virtual ~FooStub();
int OnRemoteRequest(uint32_t code,
MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
std::string GetFooName() override;
void SendAsyncReply(int &reply) override;
int WaitForAsyncReply(int timeout);
static void CleanDecTimes();
static int GetDecTimes();
int TestNestingSend(int sendCode) override;
uint32_t TestAccessToken(void) override;
public:
static std::mutex decTimeMutex_;
static int decTimes_;
private:
int asyncReply_ = { 0 };
std::mutex mutex_;
std::condition_variable cv_;
static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "FooStub" };
};
class FooProxy : public IRemoteProxy<IFoo> {
public:
explicit FooProxy(const sptr<IRemoteObject> &impl);
~FooProxy() = default;
std::string GetFooName() override;
void SendAsyncReply(int &reply) override;
int TestNestingSend(int sendCode) override;
uint32_t TestAccessToken(void) override;
private:
static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "FooProxy" };
static inline BrokerDelegator<FooProxy> delegator_;
};
} // namespace OHOS
#endif // OHOS_RPC_FOO_TEST_H
/*
* 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 <gtest/gtest.h>
#include "system_ability_definition.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "softbus_bus_center.h"
#include "ipc_skeleton.h"
#include "ipc_object_proxy.h"
#include "rpc_test.h"
#include "access_token_adapter.h"
#include "log_tags.h"
namespace OHOS {
#ifndef TITLE
#define TITLE __PRETTY_FUNCTION__
#endif
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "RPCClientTest" };
#define DBINDER_LOGE(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
#define DBINDER_LOGI(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
static std::string g_deviceId;
class RPCClientTest : public testing::Test {
public:
static constexpr int saId = RPC_TEST_SERVICE;
static constexpr char DBINDER_PKG_NAME[] = "DBinderService";
static constexpr int NODE_NUM = 4;
static void SetUpTestCase(void);
static void TearDownTestCase(void);
};
void RPCClientTest::SetUpTestCase()
{
NodeBasicInfo *nodeInfo[NODE_NUM];
int32_t infoNum = NODE_NUM;
int32_t ret = GetAllNodeDeviceInfo(DBINDER_PKG_NAME, nodeInfo, &infoNum);
if (ret != 0) {
DBINDER_LOGE("get local node ret %{public}d", ret);
return;
}
if (infoNum == 0) {
DBINDER_LOGE("get no online nodes");
return;
}
g_deviceId = nodeInfo[0]->networkId;
DBINDER_LOGI("get deviceid %{public}s", g_deviceId.c_str());
}
void RPCClientTest::TearDownTestCase() {}
HWTEST_F(RPCClientTest, function_test_001, TestSize.Level1)
{
DBINDER_LOGI("Start RPCClient Testcase001");
// service instance
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
EXPECT_TRUE(saMgr != nullptr);
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE, g_deviceId);
ASSERT_TRUE(object != nullptr);
sptr<IFoo> testService = iface_cast<IFoo>(object);
ASSERT_TRUE(testService != nullptr);
uint32_t tokenId = RpcGetSelfTokenID();
uint32_t getTokenId = testService->TestAccessToken();
ASSERT_EQ(tokenId, getTokenId);
}
}
\ No newline at end of file
/*
* 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 <gtest/gtest.h>
#include "system_ability_definition.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "ipc_skeleton.h"
#include "rpc_test.h"
#include "log_tags.h"
namespace OHOS {
#ifndef TITLE
#define TITLE __PRETTY_FUNCTION__
#endif
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "RPCServerTest" };
#define DBINDER_LOGE(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
#define DBINDER_LOGI(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
class RPCServerTest : public testing::Test {
public:
static constexpr int saId = RPC_TEST_SERVICE;
static void SetUpTestCase(void);
static void TearDownTestCase(void);
};
void RPCServerTest::SetUpTestCase() {}
void RPCServerTest::TearDownTestCase() {}
HWTEST_F(RPCServerTest, function_test_001, TestSize.Level1)
{
DBINDER_LOGI("Start RPCServer Testcase001");
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
EXPECT_TRUE(saMgr != nullptr);
ISystemAbilityManager::SAExtraProp saExtra;
saExtra.isDistributed = true; // 设置为分布式SA
int result = saMgr->AddSystemAbility(saId, new FooStub(), saExtra);
ASSERT_EQ(result, 0);
IPCSkeleton::JoinWorkThread();
}
}
\ No newline at end of file
/*
* Copyright (C) 2021 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 "rpc_test.h"
#include "ipc_skeleton.h"
#include "ipc_debug.h"
#include "ipc_types.h"
namespace OHOS {
std::mutex FooStub::decTimeMutex_;
int FooStub::decTimes_ = 0;
int FooStub::OnRemoteRequest(uint32_t code,
MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
int result = ERR_NONE;
switch (code) {
case GET_FOO_NAME: {
ZLOGI(LABEL, "%{public}s:called\n", __func__);
reply.WriteString(GetFooName());
break;
}
case SEND_ASYNC_REPLY: {
int32_t replyData = data.ReadInt32();
SendAsyncReply(replyData);
break;
}
case SEND_WRONG_REPLY: {
return TestNestingSend(data.ReadInt32());
}
case GET_TOKENID: {
uint32_t tokenId = TestAccessToken();
reply.WriteUint32(tokenId);
break;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return result;
}
std::string FooStub::GetFooName()
{
return "ReallFoo";
}
int FooStub::WaitForAsyncReply(int timeout)
{
asyncReply_ = 0;
std::unique_lock<std::mutex> lck(mutex_);
cv_.wait_for(lck, std::chrono::milliseconds(timeout), [&]() {
return asyncReply_ != 0;
});
return asyncReply_;
}
void FooStub::SendAsyncReply(int &replyValue)
{
std::unique_lock<std::mutex> lck(mutex_);
asyncReply_ = replyValue;
cv_.notify_all();
}
FooStub::~FooStub()
{
std::unique_lock<std::mutex> lck(decTimeMutex_);
decTimes_++;
}
void FooStub::CleanDecTimes()
{
std::unique_lock<std::mutex> lck(decTimeMutex_);
decTimes_ = 0;
}
int FooStub::GetDecTimes()
{
std::unique_lock<std::mutex> lck(decTimeMutex_);
return decTimes_;
}
int FooStub::TestNestingSend(int sendCode)
{
return sendCode;
}
uint32_t FooStub::TestAccessToken(void)
{
uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
return tokenId;
}
FooProxy::FooProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<IFoo>(impl)
{
}
std::string FooProxy::GetFooName()
{
ZLOGI(LABEL, "%{public}s:called\n", __func__);
MessageParcel data, reply;
MessageOption option;
Remote()->SendRequest(GET_FOO_NAME, data, reply, option);
return reply.ReadString();
}
void FooProxy::SendAsyncReply(int &replyValue)
{
ZLOGI(LABEL, "%{public}s:called\n", __func__);
MessageParcel data, reply;
MessageOption option = { MessageOption::TF_ASYNC };
data.WriteInt32(replyValue);
Remote()->SendRequest(SEND_ASYNC_REPLY, data, reply, option);
}
int FooProxy::TestNestingSend(int sendCode)
{
MessageOption option;
MessageParcel dataParcel, replyParcel;
if (!dataParcel.WriteInt32(sendCode)) {
return -1;
}
int error = Remote()->SendRequest(SEND_WRONG_REPLY, dataParcel, replyParcel, option);
ZLOGE(LABEL, "send foo result = %{public}d", error);
return error;
}
uint32_t FooProxy::TestAccessToken(void)
{
MessageOption option;
MessageParcel dataParcel, replyParcel;
int err = Remote()->SendRequest(GET_TOKENID, dataParcel, replyParcel, option);
if (err != 0) {
ZLOGE(LABEL, "get tokenid failed %{public}d", err);
return 0;
}
return replyParcel.ReadUint32();
}
} // namespace OHOS
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册