未验证 提交 78d7e61d 编写于 作者: O openharmony_ci 提交者: Gitee

!98 RPC支持跨设备收发及死亡通知

Merge pull request !98 from pilipala195/master
......@@ -14,10 +14,18 @@
import("//build/lite/config/component/lite_component.gni")
lite_component("rpc") {
features = [ "ipc:ipc_single" ]
features = [
"ipc:rpc_manager",
"dbinder:dbinder",
]
if (ohos_kernel_type != "liteos_m") {
features += [ "ipc:ipc_single" ]
}
if (ohos_build_type == "debug") {
features += [
"//foundation/communication/ipc/ipc/test/unittest/ipc:ipc_test_gtest",
"//foundation/communication/ipc/ipc/test/rpc:rpc_test",
]
}
}
# Copyright (c) 2020 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/lite/config/component/lite_component.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
DBINDER_ROOT = "$SUBSYSTEM_DIR/services/dbinder/c"
config("ipc_rpc_interface") {
include_dirs = [
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/dbinder/include",
]
}
if (ohos_kernel_type == "linux") {
SYSTEM_LEVEL = "small"
shared_library("dbinder") {
sources = [
"$DBINDER_ROOT/ipc_adapter/${SYSTEM_LEVEL}/dbinder_ipc_adapter.c",
"$DBINDER_ROOT/src/dbinder_service.c",
"$DBINDER_ROOT/src/dbinder_stub.c",
"$DBINDER_ROOT/src/dbinder_trans_callback.c",
]
public_configs = [ ":ipc_rpc_interface" ]
include_dirs = [
"$DBINDER_ROOT/include",
"$DBINDER_ROOT/ipc_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/ipc/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/ipc_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/manager/include",
"//third_party/bounds_checking_function/include",
"//utils/native/lite/include",
]
ldflags = [
"-lstdc++",
"-lpthread",
]
public_deps = [
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc:rpc_log",
"//third_party/bounds_checking_function/:libsec_shared",
]
}
} else if (ohos_kernel_type == "liteos_m") {
SYSTEM_LEVEL = "mini"
static_library("dbinder") {
sources = [
"$DBINDER_ROOT/ipc_adapter/${SYSTEM_LEVEL}/dbinder_ipc_adapter.c",
"$DBINDER_ROOT/src/dbinder_service.c",
"$DBINDER_ROOT/src/dbinder_stub.c",
"$DBINDER_ROOT/src/dbinder_trans_callback.c",
]
public_configs = [ ":ipc_rpc_interface" ]
include_dirs = [
"$DBINDER_ROOT/include",
"$DBINDER_ROOT/ipc_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/ipc/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/ipc_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/ipc/native/c/manager/include",
"$SUBSYSTEM_DIR/ipc/test/rpc/include",
"//third_party/bounds_checking_function/include",
"//utils/native/lite/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
]
ldflags = [ "-lpthread" ]
deps = [ "//foundation/communication/ipc/ipc/native/c/adapter:rpc_adapter" ]
}
}
/*
* 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 DBINDER_SERVICE_H
#define DBINDER_SERVICE_H
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "dbinder_types.h"
#include "utils_list.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct {
struct DHandleEntryHead head;
uint32_t transType;
uint32_t dBinderCode;
uint16_t fromPort;
uint16_t toPort;
uint64_t stubIndex;
uint32_t seqNumber;
uintptr_t binderObject;
struct DeviceIdInfo deviceIdInfo;
uintptr_t stub;
uint16_t serviceNameLength;
char serviceName[SERVICENAME_LENGTH + 1];
uint32_t pid;
uint32_t uid;
} DHandleEntryTxRx;
int32_t StartDBinderService(void);
int32_t RegisterRemoteProxy(const void *name, uint32_t len, int32_t systemAbility);
int32_t MakeRemoteBinder(const void *serviceName, uint32_t nameLen, const char *deviceID, uint32_t idLen,
uintptr_t binderObject, uint64_t pid, void *remoteObject);
int32_t OnRemoteMessageTask(const DHandleEntryTxRx *message);
SessionInfo *QuerySessionObject(uintptr_t stub);
void DetachProxyObject(ProxyObject *proxy);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* DBINDER_SERVICE_H */
\ No newline at end of file
......@@ -17,7 +17,10 @@ SUBSYSTEM_DIR = "//foundation/communication/ipc"
IPC_CORE_ROOT = "$SUBSYSTEM_DIR/ipc/native/c"
config("ipc_rpc_interface") {
include_dirs = [ "$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include" ]
include_dirs = [
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/dbinder/include",
]
}
if (ohos_kernel_type == "liteos_m") {
......@@ -45,14 +48,40 @@ ipc_common_src = [
]
if (ohos_kernel_type == "liteos_m") {
static_library("ipc_single") {
SYSTEM_LEVEL = "mini"
static_library("rpc_manager") {
sources = ipc_common_src
sources += [
"$IPC_CORE_ROOT/ipc/src/binder_invoker_virtual.c",
"$IPC_CORE_ROOT/manager/src/rpc_log.c",
"$IPC_CORE_ROOT/rpc/ipc_adapter/${SYSTEM_LEVEL}/ipc_proxy_inner.c",
"$IPC_CORE_ROOT/rpc/ipc_adapter/${SYSTEM_LEVEL}/ipc_stub_inner.c",
"$IPC_CORE_ROOT/rpc/src/dbinder_invoker.c",
"$IPC_CORE_ROOT/rpc/src/rpc_process_skeleton.c",
"$IPC_CORE_ROOT/rpc/src/rpc_trans_callback.c",
"$IPC_CORE_ROOT/rpc/trans_adapter/src/rpc_trans.c",
]
include_dirs = ipc_common_include
public_configs = [ ":ipc_rpc_interface" ]
include_dirs = ipc_common_include
include_dirs += [
"$IPC_CORE_ROOT/rpc/include",
"$IPC_CORE_ROOT/rpc/ipc_adapter/include",
"$IPC_CORE_ROOT/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
]
if (ohos_build_type == "debug") {
sources += [
"$SUBSYSTEM_DIR/ipc/test/rpc/samgr/rpc_mini_samgr.c",
"$SUBSYSTEM_DIR/ipc/test/rpc/socket_trans/src/rpc_${SYSTEM_LEVEL}_socket_trans.c",
]
include_dirs += [
"$SUBSYSTEM_DIR/ipc/test/rpc/include",
"$SUBSYSTEM_DIR/ipc/test/rpc/socket_trans/include",
"//third_party/lwip/src/include",
]
defines = [ "RPC_SOCKET_TRANS" ]
}
ldflags = [ "-lpthread" ]
deps = [ "//foundation/communication/ipc/ipc/native/c/adapter:rpc_adapter" ]
}
} else if (ohos_kernel_type == "liteos_a") {
......@@ -85,6 +114,9 @@ if (ohos_kernel_type == "liteos_m") {
"//third_party/bounds_checking_function/:libsec_shared",
]
}
shared_library("rpc_manager") {
}
} else {
shared_library("rpc_log") {
sources = [ "$IPC_CORE_ROOT/manager/src/rpc_log.c" ]
......@@ -100,9 +132,17 @@ if (ohos_kernel_type == "liteos_m") {
shared_library("ipc_single") {
sources = ipc_common_src
sources += [ "$IPC_CORE_ROOT/ipc/src/binder_invoker.c" ]
sources += [
"$IPC_CORE_ROOT/ipc/src/binder_invoker.c",
"$IPC_CORE_ROOT/rpc/src/rpc_process_skeleton_virtual.c",
]
public_configs = [ ":ipc_rpc_interface" ]
include_dirs = ipc_common_include
include_dirs += [
"$IPC_CORE_ROOT/rpc/include",
"$IPC_CORE_ROOT/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
]
ldflags = [
"-lstdc++",
"-lpthread",
......@@ -116,4 +156,45 @@ if (ohos_kernel_type == "liteos_m") {
]
configs -= [ "//build/lite/config:clang_opt" ]
}
SYSTEM_LEVEL = "small"
shared_library("rpc_manager") {
sources = ipc_common_src
sources += [
"$IPC_CORE_ROOT/ipc/src/binder_invoker.c",
"$IPC_CORE_ROOT/rpc/ipc_adapter/${SYSTEM_LEVEL}/ipc_proxy_inner.c",
"$IPC_CORE_ROOT/rpc/ipc_adapter/${SYSTEM_LEVEL}/ipc_stub_inner.c",
"$IPC_CORE_ROOT/rpc/src/dbinder_invoker.c",
"$IPC_CORE_ROOT/rpc/src/rpc_process_skeleton.c",
"$IPC_CORE_ROOT/rpc/src/rpc_trans_callback.c",
"$IPC_CORE_ROOT/rpc/trans_adapter/src/rpc_trans.c",
]
public_configs = [ ":ipc_rpc_interface" ]
include_dirs = ipc_common_include
include_dirs += [
"$IPC_CORE_ROOT/rpc/include",
"$IPC_CORE_ROOT/rpc/ipc_adapter/include",
"$IPC_CORE_ROOT/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
"//third_party/bounds_checking_function/include",
]
ldflags = [
"-lstdc++",
"-lpthread",
]
cflags = [ "-fPIC" ]
cflags_cc = cflags
public_deps = [
":rpc_log",
"//foundation/communication/ipc/ipc/native/c/adapter:rpc_adapter",
"//third_party/bounds_checking_function/:libsec_shared",
]
if (ohos_build_type == "debug") {
sources +=
[ "$SUBSYSTEM_DIR/ipc/test/rpc/socket_trans/src/rpc_socket_trans.c" ]
include_dirs += [ "$SUBSYSTEM_DIR/ipc/test/rpc/socket_trans/include" ]
defines = [ "RPC_SOCKET_TRANS" ]
}
}
}
......@@ -22,6 +22,7 @@
#include "ipc_skeleton.h"
#include "iremote_invoker.h"
#include "dbinder_types.h"
#ifdef __cplusplus
#if __cplusplus
......@@ -43,7 +44,7 @@ typedef struct {
IpcObjectStub *objectStub;
pid_t callerPid;
pid_t callerUid;
char callerDeviceID[64];
char callerDeviceID[DEVICEID_LENGTH + 1];
bool stopWorkThread;
uint64_t seqNumber;
uint32_t clientFd;
......
......@@ -20,6 +20,7 @@
#include "rpc_errno.h"
#include "rpc_log.h"
#include "rpc_os_adapter.h"
#include "rpc_process_skeleton.h"
#include "rpc_types.h"
#include "securec.h"
#include "utils_list.h"
......@@ -81,6 +82,10 @@ IpcSkeleton *GetCurrentSkeleton(void)
return NULL;
}
g_ipcSkeleton = temp;
int32_t ret = RpcProcessSkeleton();
if (ret != ERR_NONE) {
RPC_LOG_ERROR("rpc process skeleton init failed");
}
}
pthread_mutex_unlock(&g_ipcSkeletonMutex);
}
......@@ -265,7 +270,7 @@ static uint32_t SetDeathHandlerPair(DeathCallback *node, uint32_t index, OnRemot
int32_t ProcessAddDeathRecipient(int32_t handle, OnRemoteDead deathFunc, void *args, uint32_t *cbId)
{
int32_t ret = ERR_INVALID_PARAM;
int32_t ret = ERR_NONE;
if (g_ipcSkeleton == NULL) {
return ERR_IPC_SKELETON_NOT_INIT;
}
......@@ -359,6 +364,7 @@ int32_t ProcessRemoveDeathRecipient(int32_t handle, uint32_t cbId)
int32_t OnRemoteRequestInner(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option, IpcObjectStub *objectStub)
{
int32_t result = ERR_NOT_RPC;
result = RpcOnRemoteRequestInner(code, data, reply, option, objectStub);
if (result == ERR_NOT_RPC) {
if (objectStub != NULL && objectStub->func != NULL) {
result = (OnRemoteRequest)(objectStub->func)(code, data, reply, option);
......@@ -417,4 +423,5 @@ void WaitForProxyInit(int32_t handle)
{
RPC_LOG_INFO("ipc skeleton wait for proxy init");
OnFirstStrongRef(handle);
UpdateProtoIfNeed(handle);
}
\ No newline at end of file
......@@ -16,6 +16,7 @@
#include "iremote_invoker.h"
#include "binder_invoker.h"
#include "dbinder_invoker.h"
#include "rpc_types.h"
RemoteInvoker *InitRemoteInvoker(int32_t proto)
......@@ -23,6 +24,8 @@ RemoteInvoker *InitRemoteInvoker(int32_t proto)
RemoteInvoker *remoteInvoker = NULL;
if (proto == IF_PROT_BINDER) {
remoteInvoker = GetIpcInvoker();
} else {
remoteInvoker = GetRpcInvoker();
}
return remoteInvoker;
}
\ 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.
*/
#ifndef OHOS_RPC_INVOKER_H
#define OHOS_RPC_INVOKER_H
#include <stdbool.h>
#include <stdint.h>
#include "rpc_process_skeleton.h"
#include "iremote_invoker.h"
#ifdef __cplusplus
extern "C" {
#endif
RemoteInvoker *GetRpcInvoker(void);
void DeleteRpcInvoker(RemoteInvoker *remoteInvoker);
void RpcStopWorkThread(void);
int32_t OnReceiveNewConnection(int sessionId);
void OnDatabusSessionClosed(int sessionId);
void OnMessageAvailable(int sessionId, const void *data, unsigned int len);
void UpdateClientSession(int32_t handle, HandleSessionList *sessionObject, const char *sessionName,
const char *serviceName, const char *deviceId);
int32_t CreateTransServer(const char *sessionName);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_INVOKER_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.
*/
#ifndef OHOS_RPC_PROCESS_SKELETON_H
#define OHOS_RPC_PROCESS_SKELETON_H
#include <stdint.h>
#include <pthread.h>
#include "ipc_skeleton.h"
#include "rpc_trans.h"
#include "utils_list.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
pthread_mutex_t lock;
uint64_t stubIndex;
char *sessionName;
uint64_t seqNumber;
TransInterface *rpcTrans;
int32_t isServerCreated;
} RpcSkeleton;
typedef struct {
UTILS_DL_LIST list;
uint64_t stubIndex;
OnRemoteRequest func;
} StubObject;
typedef struct {
UTILS_DL_LIST stubObjects;
pthread_mutex_t mutex;
} StubObjectList;
typedef struct {
UTILS_DL_LIST list;
pthread_t threadId;
uint32_t listenFd;
uint32_t packageSize;
char *buffer;
} ThreadProcessInfo;
typedef struct {
UTILS_DL_LIST processInfo;
pthread_mutex_t mutex;
} ThreadProcessInfoList;
typedef struct {
UTILS_DL_LIST list;
pthread_t threadId;
pthread_mutex_t mutex;
pthread_cond_t condition;
} SocketThreadLockInfo;
typedef struct {
UTILS_DL_LIST socketLockInfo;
pthread_mutex_t mutex;
} SocketThreadLockInfoList;
typedef struct {
UTILS_DL_LIST list;
pthread_t threadId;
} IdleDataThread;
typedef struct {
UTILS_DL_LIST idleDataThread;
pthread_mutex_t mutex;
} IdleDataThreadsList;
typedef struct {
UTILS_DL_LIST list;
uint32_t handle;
uint32_t sessionId;
char *buffer;
uint32_t len;
} HandleSessionList;
typedef struct {
UTILS_DL_LIST list;
uint32_t handle;
uint64_t index;
} HandleToIndexList;
typedef struct {
UTILS_DL_LIST list;
pthread_t threadId;
uint64_t seqNumber;
uint32_t flags;
size_t bufferSize;
size_t offsetsSize;
uintptr_t offsets;
uint32_t socketId;
void *buffer;
} ThreadMessageInfo;
int32_t RpcProcessSkeleton(void);
RpcSkeleton *GetCurrentRpcSkeleton(void);
int32_t AddStubByIndex(StubObject *stubObject);
StubObject *QueryStubByIndex(uint64_t stubIndex);
void AddDataThreadInWait(pthread_t threadId);
IdleDataThread *GetIdleDataThread(void);
void AddDataInfoToThread(ThreadProcessInfo *processInfo);
ThreadProcessInfo *PopDataInfoFromThread(pthread_t threadId);
uint32_t ConvertChannelID2Int(int64_t databusChannelId);
int32_t AttachStubSession(HandleSessionList *handleSession);
void DetachStubSession(HandleSessionList *handleSession);
HandleSessionList *QueryStubSession(uint32_t handle);
int32_t AttachProxySession(HandleSessionList *handleSession);
void DetachProxySession(HandleSessionList *handleSession);
HandleSessionList *QueryProxySession(uint32_t handle);
HandleSessionList *QueryProxySessionBySessionId(uint32_t sessionId);
uint64_t ProcessGetSeqNumber(void);
int32_t AttachHandleToIndex(HandleToIndexList *handleToIndex);
void DetachHandleToIndex(HandleToIndexList *handleToIndex);
HandleToIndexList *QueryHandleToIndex(uint32_t handle);
int32_t AddSendThreadInWait(uint64_t seqNumber, ThreadMessageInfo *messageInfo, int userWaitTime);
void EraseThreadBySeqNumber(ThreadMessageInfo *messageInfo);
ThreadMessageInfo *QueryThreadBySeqNumber(uint64_t seqNumber);
void WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle);
int32_t RpcOnRemoteRequestInner(uint32_t code, IpcIo *data, IpcIo *reply,
MessageOption option, IpcObjectStub *objectStub);
void UpdateProtoIfNeed(int32_t handle);
void WakeUpDataThread(pthread_t threadId);
uint64_t GetNewStubIndex(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_PROCESS_SKELETON_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.
*/
#ifndef OHOS_RPC_TRANS_CALLBACK_H
#define OHOS_RPC_TRANS_CALLBACK_H
#include "rpc_trans.h"
#ifdef __cplusplus
extern "C" {
#endif
TransCallback *GetRpcTransCallback(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_TRANS_CALLBACK_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.
*/
#ifndef OHOS_IPC_PROXY_INNER_H
#define OHOS_IPC_PROXY_INNER_H
#include <stdint.h>
#include "dbinder_types.h"
#include "serializer.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t InvokerListenThread(ProxyObject *proxyObject, const char *localDeviceID,
const char *remoteDeviceID, uint32_t pid, uint32_t uid, IpcIo *reply, uintptr_t *ptr);
int32_t GetPidAndUidInfo(ProxyObject *proxy);
char *GetDataBusName(void);
void UpdateProto(int32_t handle);
#ifdef __cplusplus
}
#endif
#endif // OHOS_IPC_PROXY_INNER_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.
*/
#ifndef OHOS_IPC_STUB_INNER_H
#define OHOS_IPC_STUB_INNER_H
#include <stdint.h>
#include "serializer.h"
#include "ipc_skeleton.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t InvokerListenThreadStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option, OnRemoteRequest *func);
int32_t GetPidAndUidInfoStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option);
int32_t GrantDataBusNameStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option);
#ifdef __cplusplus
}
#endif
#endif // OHOS_IPC_STUB_INNER_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 "ipc_proxy_inner.h"
#include <stddef.h>
#include <string.h>
#include <securec.h>
#include "ipc_thread_pool.h"
#include "rpc_process_skeleton.h"
#include "dbinder_invoker.h"
#include "dbinder_types.h"
#include "rpc_errno.h"
#include "rpc_log.h"
static int32_t GetDigits(int32_t number)
{
int32_t n = 0;
while (number > 0) {
n++;
number /= ID_DIGITS;
}
if (n == 0) {
n++;
}
return n;
}
static int32_t MakeInvokerListenReply(ProxyObject *proxyObject, uint64_t stubIndex, IpcIo *reply, uintptr_t *ptr)
{
ptr = (uintptr_t *)calloc(1, RPC_IPC_LENGTH);
if (ptr == NULL) {
RPC_LOG_ERROR("InvokerListenThread ptr calloc failed");
return ERR_FAILED;
}
IpcIoInit(reply, (void *)ptr, RPC_IPC_LENGTH, 0);
if (!WriteUint64(reply, stubIndex)) {
RPC_LOG_ERROR("InvokerListenThread WriteUint64 failed");
free((void *)ptr);
return ERR_FAILED;
}
if (!WriteString(reply, proxyObject->sessionName)) {
RPC_LOG_ERROR("InvokerListenThread WriteString failed");
free((void *)ptr);
return ERR_FAILED;
}
((IpcIo *)reply)->bufferCur = ((IpcIo *)reply)->bufferBase;
return ERR_NONE;
}
int32_t InvokerListenThread(ProxyObject *proxyObject, const char *localDeviceID, const char *remoteDeviceID,
uint32_t pid, uint32_t uid, IpcIo *reply, uintptr_t *ptr)
{
if (proxyObject == NULL) {
RPC_LOG_ERROR("InvokerListenThread proxy is null");
return ERR_FAILED;
}
int32_t sessionNameLen = strlen(proxyObject->sessionName);
RpcSkeleton *current = GetCurrentRpcSkeleton();
if (current == NULL) {
RPC_LOG_ERROR("GetCurrentSkeleton failed");
return ERR_FAILED;
}
if (CreateTransServer(proxyObject->sessionName) != ERR_NONE) {
return ERR_FAILED;
}
if (current->sessionName != NULL) {
free(current->sessionName);
}
if (sessionNameLen == 0 || sessionNameLen > SERVICENAME_LENGTH) {
RPC_LOG_ERROR("sessionNameLen invalid");
return ERR_FAILED;
}
current->sessionName = (char *)malloc(sessionNameLen + 1);
if (current->sessionName == NULL) {
return ERR_FAILED;
}
if (sessionNameLen == 0 || sessionNameLen > SERVICENAME_LENGTH) {
RPC_LOG_ERROR("sessionNameLen invalid");
return ERR_FAILED;
}
if (strcpy_s(current->sessionName, sessionNameLen + 1, proxyObject->sessionName) != EOK) {
free(current->sessionName);
return ERR_FAILED;
}
StubObject *stubObject = (StubObject *)malloc(sizeof(StubObject));
if (stubObject == NULL) {
return ERR_FAILED;
}
uint64_t stubIndex = GetNewStubIndex();
stubObject->stubIndex = stubIndex;
IpcObjectStub *cookie = (IpcObjectStub *)(proxyObject->proxy->cookie);
stubObject->func = cookie->func;
if (AddStubByIndex(stubObject) != ERR_NONE) {
free(stubObject);
return ERR_FAILED;
}
return MakeInvokerListenReply(proxyObject, stubIndex, reply, ptr);
}
int32_t GetPidAndUidInfo(ProxyObject *proxyObject)
{
if (proxyObject == NULL) {
RPC_LOG_ERROR("GetPidAndUidInfo proxy is null");
return ERR_FAILED;
}
int32_t pid = (int32_t)GetCallingPid();
int32_t pidLen = GetDigits(pid);
int32_t uid = (int32_t)GetCallingUid();
int32_t uidLen = GetDigits(uid);
uint32_t sessionNameLen = SESSION_NAME_LEGNTH + pidLen + uidLen;
proxyObject->sessionName = (char *)malloc(sessionNameLen + 1);
if (proxyObject->sessionName == NULL) {
RPC_LOG_ERROR("sessionName mallo failed");
return ERR_FAILED;
}
if (sprintf_s(proxyObject->sessionName, sessionNameLen + 1, "DBinder%d_%d", uid, pid) == -1) {
RPC_LOG_ERROR("sessionName sprintf failed");
free(proxyObject->sessionName);
return ERR_FAILED;
}
return ERR_NONE;
}
char *GetDataBusName(void)
{
return NULL;
}
static char *CreateDatabusName(void)
{
int32_t pid = (int32_t)GetCallingPid();
int32_t pidLen = GetDigits(pid);
int32_t uid = (int32_t)GetCallingUid();
int32_t uidLen = GetDigits(uid);
uint32_t sessionNameLen = SESSION_NAME_LEGNTH + pidLen + uidLen;
char *sessionName = (char *)malloc(sessionNameLen + 1);
if (sessionName == NULL) {
RPC_LOG_ERROR("sessionName mallo failed");
return NULL;
}
if (sprintf_s(sessionName, sessionNameLen + 1, "DBinder%d_%d", uid, pid) == -1) {
RPC_LOG_ERROR("sessionName sprintf failed");
free(sessionName);
return NULL;
}
return sessionName;
}
static int GetSessionFromDBinderService(uint32_t handle)
{
RPC_LOG_INFO("GetSessionFromDBinderService start");
int32_t proto = IF_PROT_DATABUS;
SessionInfo *session = QuerySessionObject((uintptr_t)handle);
if (session == NULL) {
RPC_LOG_ERROR("client find session is null");
return proto;
}
const char *localBusName = CreateDatabusName();
if (localBusName == NULL) {
RPC_LOG_ERROR("ProcessProto CreateDatabusName failed");
return proto;
}
HandleSessionList *sessionObject = (HandleSessionList *)malloc(sizeof(HandleSessionList));
if (sessionObject == NULL) {
RPC_LOG_ERROR("UpdateDatabusClientSession sessionObject malloc failed");
return proto;
}
HandleToIndexList *handleToIndex = (HandleToIndexList *)malloc(sizeof(HandleToIndexList));
if (handleToIndex == NULL) {
RPC_LOG_ERROR("UpdateDatabusClientSession handleToIndex malloc failed");
free(sessionObject);
return proto;
}
handleToIndex->handle = handle;
handleToIndex->index = session->stubIndex;
if (AttachHandleToIndex(handleToIndex) != ERR_NONE) {
RPC_LOG_ERROR("AttachHandleToIndex failed");
free(sessionObject);
free(handleToIndex);
return proto;
}
if (CreateTransServer(localBusName) != ERR_NONE) {
RPC_LOG_ERROR("create bus server fail name = %s, localID = %s",
localBusName, session->deviceIdInfo.fromDeviceId);
DetachHandleToIndex(handleToIndex);
free(sessionObject);
free(handleToIndex);
return proto;
}
UpdateClientSession(handle, sessionObject, localBusName, session->serviceName, session->deviceIdInfo.toDeviceId);
return proto;
}
void UpdateProto(int32_t handle)
{
if (handle < 0) {
RPC_LOG_ERROR("UpdateProto handle invalid");
return;
}
ThreadContext *threadContext = GetCurrentThreadContext();
if (threadContext == NULL) {
RPC_LOG_ERROR("UpdateProto threadContext is null");
return;
}
HandleSessionList *sessionObject = QueryProxySession(handle);
if (sessionObject != NULL) {
threadContext->proto = IF_PROT_DATABUS;
return;
}
threadContext->proto = GetSessionFromDBinderService(handle);
RPC_LOG_INFO("UpdateProto get proto: %d", threadContext->proto);
}
\ 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 "ipc_stub_inner.h"
#include "rpc_errno.h"
int32_t InvokerListenThreadStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option, OnRemoteRequest *func)
{
return ERR_NONE;
}
int32_t GetPidAndUidInfoStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option)
{
return ERR_NONE;
}
int32_t GrantDataBusNameStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option)
{
return ERR_NONE;
}
\ 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 "ipc_proxy_inner.h"
#include "securec.h"
#include "serializer.h"
#include "rpc_log.h"
#include "rpc_errno.h"
#include "ipc_process_skeleton.h"
#include "ipc_thread_pool.h"
#include "dbinder_invoker.h"
#include "dbinder_types.h"
#include "rpc_process_skeleton.h"
static void UpdateDatabusClientSession(int32_t handle, IpcIo *reply)
{
uint64_t stubIndex;
if (!ReadUint64(reply, &stubIndex)) {
return;
}
size_t len;
char *serviceName = (char *)ReadString(reply, &len);
char *peerID = (char *)ReadString(reply, &len);
char *localID = (char *)ReadString(reply, &len);
char *localBusName = (char *)ReadString(reply, &len);
HandleSessionList *sessionObject = (HandleSessionList *)malloc(sizeof(HandleSessionList));
if (sessionObject == NULL) {
RPC_LOG_ERROR("UpdateDatabusClientSession sessionObject malloc failed");
return;
}
HandleToIndexList *handleToIndex = (HandleToIndexList *)malloc(sizeof(HandleToIndexList));
if (handleToIndex == NULL) {
RPC_LOG_ERROR("UpdateDatabusClientSession handleToIndex malloc failed");
free(sessionObject);
return;
}
handleToIndex->handle = handle;
handleToIndex->index = stubIndex;
if (AttachHandleToIndex(handleToIndex) != ERR_NONE) {
RPC_LOG_ERROR("AttachHandleToIndex failed");
free(sessionObject);
free(handleToIndex);
return;
}
if (CreateTransServer(localBusName) != ERR_NONE) {
RPC_LOG_ERROR("create bus server fail name = %s, localID = %s", localBusName, localID);
DetachHandleToIndex(handleToIndex);
free(sessionObject);
free(handleToIndex);
return;
}
UpdateClientSession(handle, sessionObject, localBusName, serviceName, peerID);
}
static int GetSessionFromDBinderService(uint32_t handle)
{
RPC_LOG_INFO("GetSessionFromDBinderService start");
IpcIo data;
IpcIo reply;
uint8_t dataAlloc[RPC_IPC_LENGTH_LONG];
IpcIoInit(&data, dataAlloc, RPC_IPC_LENGTH_LONG, 0);
MessageOption option = TF_OP_SYNC;
SvcIdentity target = {
.handle = handle
};
uintptr_t ptr;
int32_t ret = ProcessSendRequest(target, GET_PROTO_INFO, &data, &reply, option, &ptr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("sendrequest GET_PROTO_INFO failed, error %d", ret);
FreeBuffer((void *)ptr);
return IF_PROT_BINDER;
}
uint32_t proto;
if (!ReadUint32(&reply, &proto)) {
FreeBuffer((void *)ptr);
return IF_PROT_BINDER;
}
switch (proto) {
case IF_PROT_BINDER:
break;
case IF_PROT_DATABUS: {
UpdateDatabusClientSession(handle, &reply);
proto = IF_PROT_DATABUS;
break;
}
default:
break;
}
FreeBuffer((void *)ptr);
return proto;
}
int32_t InvokerListenThread(ProxyObject *proxyObject, const char *localDeviceID, const char *remoteDeviceID,
uint32_t pid, uint32_t uid, IpcIo *reply, uintptr_t *ptr)
{
if (proxyObject == NULL || localDeviceID == NULL || remoteDeviceID == NULL) {
return ERR_FAILED;
}
IpcIo *ipcReply = (IpcIo *)reply;
IpcIo data;
uint8_t dataAlloc[RPC_IPC_LENGTH_LONG];
IpcIoInit(&data, dataAlloc, RPC_IPC_LENGTH_LONG, 0);
WriteUint16(&data, DATABUS_TYPE);
WriteString(&data, localDeviceID);
WriteUint32(&data, pid);
WriteUint32(&data, uid);
WriteString(&data, remoteDeviceID);
WriteString(&data, proxyObject->sessionName);
MessageOption option = TF_OP_SYNC;
int32_t ret = SendRequest(*proxyObject->proxy, INVOKE_LISTEN_THREAD, &data, ipcReply, option, ptr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("INVOKE_LISTEN_THREAD failed");
}
return ret;
}
int32_t GetPidAndUidInfo(ProxyObject *proxyObject)
{
if (proxyObject == NULL) {
RPC_LOG_ERROR("GetPidAndUidInfo proxy is null");
return ERR_FAILED;
}
IpcIo data;
IpcIo reply;
uint8_t dataAlloc[RPC_IPC_LENGTH];
IpcIoInit(&data, dataAlloc, RPC_IPC_LENGTH, 0);
MessageOption option = TF_OP_SYNC;
uintptr_t ptr;
int32_t ret = SendRequest(*proxyObject->proxy, GET_UIDPID_INFO, &data, &reply, option, &ptr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("sendrequest GET_UIDPID_INFO failed, error %d", ret);
FreeBuffer((void *)ptr);
return ERR_FAILED;
}
size_t len;
char *sessionName = (char *)ReadString(&reply, &len);
proxyObject->sessionName = (char *)malloc(len + 1);
if (proxyObject->sessionName == NULL) {
RPC_LOG_ERROR("GetPidAndUidInfo proxy name malloc failed");
FreeBuffer((void *)ptr);
return ERR_FAILED;
}
if (strcpy_s(proxyObject->sessionName, len + 1, sessionName) != 0) {
RPC_LOG_ERROR("GetPidAndUidInfo proxy name copy failed");
free(proxyObject->sessionName);
FreeBuffer((void *)ptr);
return ERR_FAILED;
}
FreeBuffer((void *)ptr);
return ERR_NONE;
}
char *GetDataBusName(void)
{
IpcIo data;
IpcIo reply;
uint8_t dataAlloc[RPC_IPC_LENGTH];
IpcIoInit(&data, dataAlloc, RPC_IPC_LENGTH, 0);
MessageOption option = TF_OP_SYNC;
uintptr_t ptr;
int32_t ret = ProcessSendRequest(*GetContextObject(), GRANT_DATABUS_NAME, &data, &reply, option, &ptr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("sendrequest GRANT_DATABUS_NAME failed, error %d", ret);
FreeBuffer((void *)ptr);
return NULL;
}
int32_t proto;
if (!ReadInt32(&reply, &proto)) {
FreeBuffer((void *)ptr);
return NULL;
}
if (proto != IF_PROT_DATABUS) {
RPC_LOG_INFO("GetDataBusName normal binder");
FreeBuffer((void *)ptr);
return NULL;
}
size_t len;
const char *name = (const char *)ReadString(&reply, &len);
RPC_LOG_INFO("GetDataBusName name %s, len %d", name, len);
char *sessionName = (char *)malloc(len + 1);
if (sessionName == NULL) {
RPC_LOG_ERROR("GetDataBusName sessionName malloc failed");
FreeBuffer((void *)ptr);
return NULL;
}
if (strcpy_s(sessionName, len + 1, name) != EOK) {
RPC_LOG_ERROR("GetDataBusName sessionName copy failed");
free(sessionName);
FreeBuffer((void *)ptr);
return NULL;
}
FreeBuffer((void *)ptr);
return sessionName;
}
void UpdateProto(int32_t handle)
{
if (handle < 0) {
RPC_LOG_ERROR("UpdateProto handle invalid");
return;
}
ThreadContext *threadContext = GetCurrentThreadContext();
if (threadContext == NULL) {
RPC_LOG_ERROR("UpdateProto threadContext is null");
return;
}
HandleSessionList *sessionObject = QueryProxySession(handle);
if (sessionObject != NULL) {
threadContext->proto = IF_PROT_DATABUS;
return;
}
threadContext->proto = GetSessionFromDBinderService(handle);
RPC_LOG_INFO("UpdateProto get proto: %d", threadContext->proto);
}
\ 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 "ipc_stub_inner.h"
#include "securec.h"
#include "dbinder_types.h"
#include "dbinder_invoker.h"
#include "rpc_process_skeleton.h"
#include "rpc_types.h"
#include "rpc_errno.h"
#include "rpc_log.h"
#include "ipc_proxy_inner.h"
#include "ipc_thread_pool.h"
static int32_t IsDeviceIdIllegal(const char *deviceID, uint32_t len)
{
if (deviceID == NULL || len > DEVICEID_LENGTH) {
return ERR_FAILED;
}
return ERR_NONE;
}
static int32_t MakeStubCached(IpcIo *reply, OnRemoteRequest func,
const char *sessionName, const char *deviceID)
{
RpcSkeleton *current = GetCurrentRpcSkeleton();
if (current == NULL) {
RPC_LOG_ERROR("GetCurrentSkeleton failed");
return ERR_FAILED;
}
StubObject *stubObject = (StubObject *)malloc(sizeof(StubObject));
if (stubObject == NULL) {
return ERR_FAILED;
}
uint64_t stubIndex = GetNewStubIndex();
stubObject->stubIndex = stubIndex;
stubObject->func = func;
if (AddStubByIndex(stubObject) != ERR_NONE) {
free(stubObject);
return ERR_FAILED;
}
WriteUint64(reply, stubIndex);
WriteString(reply, sessionName);
WriteString(reply, deviceID);
return ERR_NONE;
}
static int32_t InvokerDataBusThread(IpcIo *data, IpcIo *reply, OnRemoteRequest func)
{
size_t deviceIDLen;
const char *deviceID = (const char*)ReadString(data, &deviceIDLen);
uint32_t remotePid;
if (!ReadUint32(data, &remotePid)) {
return ERR_FAILED;
}
uint32_t remoteUid;
if (!ReadUint32(data, &remoteUid)) {
return ERR_FAILED;
}
size_t remoteDeviceIDLen;
const char *remoteDeviceID = (const char*)ReadString(data, &remoteDeviceIDLen);
size_t sessionNameLen;
const char *sessionName = (const char*)ReadString(data, &sessionNameLen);
if (IsDeviceIdIllegal(deviceID, deviceIDLen) != ERR_NONE ||
IsDeviceIdIllegal(remoteDeviceID, remoteDeviceIDLen) != ERR_NONE || sessionName == NULL) {
RPC_LOG_ERROR("deviceID invalid or session name is null");
return ERR_FAILED;
}
RpcSkeleton *current = GetCurrentRpcSkeleton();
if (current == NULL) {
RPC_LOG_ERROR("GetCurrentSkeleton failed");
return ERR_FAILED;
}
if (CreateTransServer(sessionName) != ERR_NONE) {
return ERR_FAILED;
}
if (current->sessionName != NULL) {
free(current->sessionName);
}
if (sessionNameLen == 0 || sessionNameLen > SERVICENAME_LENGTH) {
RPC_LOG_ERROR("sessionNameLen invalid");
return ERR_FAILED;
}
current->sessionName = (char *)malloc(sessionNameLen + 1);
if (current->sessionName == NULL) {
return ERR_FAILED;
}
if (strcpy_s(current->sessionName, sessionNameLen + 1, sessionName) != EOK) {
free(current->sessionName);
return ERR_FAILED;
}
return MakeStubCached(reply, func, sessionName, deviceID);
}
int32_t InvokerListenThreadStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option, OnRemoteRequest *func)
{
uint16_t type;
if (!ReadUint16(data, &type)) {
return ERR_FAILED;
}
switch (type) {
case DATABUS_TYPE: {
if (InvokerDataBusThread(data, reply, func) != 0) {
RPC_LOG_ERROR("Invoker databus thread fail");
return ERR_FAILED;
}
break;
}
default: {
RPC_LOG_ERROR("InvokerThread Invalid Type");
return ERR_FAILED;
}
}
return ERR_NONE;
}
int32_t GetPidAndUidInfoStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option)
{
int32_t result = ERR_NONE;
char *sessionName = GetDataBusName();
if (sessionName == NULL || strlen(sessionName) == 0) {
RPC_LOG_ERROR("GetDataBusName failed");
result = ERR_FAILED;
} else {
WriteString(reply, sessionName);
free(sessionName);
result = ERR_NONE;
}
return result;
}
static int32_t GetDigits(int32_t number)
{
int32_t n = 0;
while (number > 0) {
n++;
number /= ID_DIGITS;
}
if (n == 0) {
n++;
}
return n;
}
int32_t GrantDataBusNameStub(uint32_t code, IpcIo *data, IpcIo *reply, int32_t option)
{
int32_t pid = (int32_t)GetCallingPid();
int32_t pidLen = GetDigits(pid);
int32_t uid = (int32_t)GetCallingUid();
int32_t uidLen = GetDigits(uid);
uint32_t sessionNameLen = SESSION_NAME_LEGNTH + pidLen + uidLen;
char *sessionName = (char *)malloc(sessionNameLen + 1);
if (sessionName == NULL) {
RPC_LOG_ERROR("sessionName mallo failed");
return ERR_FAILED;
}
if (sprintf_s(sessionName, sessionNameLen + 1, "DBinder%d_%d", uid, pid) == -1) {
RPC_LOG_ERROR("sessionName sprintf failed");
free(sessionName);
return ERR_FAILED;
}
WriteInt32(reply, IF_PROT_DATABUS);
WriteString(reply, sessionName);
free(sessionName);
return ERR_NONE;
}
\ 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_process_skeleton.h"
#include <stdlib.h>
#include <sys/time.h>
#include <errno.h>
#include "ipc_proxy_inner.h"
#include "ipc_stub_inner.h"
#include "dbinder_types.h"
#include "rpc_trans_callback.h"
#include "rpc_types.h"
#include "rpc_errno.h"
#include "rpc_log.h"
#define USECTONSEC 1000
static RpcSkeleton g_rpcSkeleton = {
.lock = PTHREAD_MUTEX_INITIALIZER,
.isServerCreated = -1
};
static pthread_mutex_t g_rpcSkeletonMutex = PTHREAD_MUTEX_INITIALIZER;
// rpc data cache
static StubObjectList g_stubObjectList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static ThreadProcessInfoList g_processInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static SocketThreadLockInfoList g_socketLockInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static IdleDataThreadsList g_idleDataThreadsList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static HandleSessionList g_stubSessionList;
static pthread_mutex_t g_stubSessionMutex = PTHREAD_MUTEX_INITIALIZER;
static HandleSessionList g_proxySessionList;
static pthread_mutex_t g_proxySessionMutex = PTHREAD_MUTEX_INITIALIZER;
static HandleToIndexList g_handleToIndexList;
static pthread_mutex_t g_handleToIndexMutex = PTHREAD_MUTEX_INITIALIZER;
static ThreadMessageInfo g_seqNumberToThread;
static pthread_mutex_t g_seqNumberToThreadMutex = PTHREAD_MUTEX_INITIALIZER;
int32_t RpcProcessSkeleton(void)
{
pthread_mutex_lock(&g_rpcSkeletonMutex);
UtilsListInit(&g_stubObjectList.stubObjects);
UtilsListInit(&g_processInfoList.processInfo);
UtilsListInit(&g_socketLockInfoList.socketLockInfo);
UtilsListInit(&g_idleDataThreadsList.idleDataThread);
UtilsListInit(&g_stubSessionList.list);
UtilsListInit(&g_proxySessionList.list);
UtilsListInit(&g_handleToIndexList.list);
UtilsListInit(&g_seqNumberToThread.list);
g_rpcSkeleton.seqNumber = 0;
g_rpcSkeleton.rpcTrans = GetRpcTrans();
pthread_mutex_unlock(&g_rpcSkeletonMutex);
return ERR_NONE;
}
RpcSkeleton *GetCurrentRpcSkeleton(void)
{
return &g_rpcSkeleton;
}
int32_t AddStubByIndex(StubObject *stubObject)
{
pthread_mutex_lock(&g_stubObjectList.mutex);
UtilsListAdd(&g_stubObjectList.stubObjects, &stubObject->list);
pthread_mutex_unlock(&g_stubObjectList.mutex);
return ERR_NONE;
}
StubObject *QueryStubByIndex(uint64_t stubIndex)
{
StubObject *node = NULL;
pthread_mutex_lock(&g_stubObjectList.mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_stubObjectList.stubObjects, StubObject, list)
{
if (node->stubIndex == stubIndex) {
pthread_mutex_unlock(&g_stubObjectList.mutex);
return node;
}
}
pthread_mutex_unlock(&g_stubObjectList.mutex);
return NULL;
}
static int32_t AttachThreadLockInfo(SocketThreadLockInfo *threadLockInfo)
{
pthread_mutex_lock(&g_socketLockInfoList.mutex);
UtilsListAdd(&g_socketLockInfoList.socketLockInfo, &threadLockInfo->list);
pthread_mutex_unlock(&g_socketLockInfoList.mutex);
return ERR_NONE;
}
static SocketThreadLockInfo *QueryThreadLockInfo(pthread_t threadId)
{
SocketThreadLockInfo *node = NULL;
pthread_mutex_lock(&g_socketLockInfoList.mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_socketLockInfoList.socketLockInfo, SocketThreadLockInfo, list)
{
if (pthread_equal(node->threadId, threadId) != 0) {
pthread_mutex_unlock(&g_socketLockInfoList.mutex);
return node;
}
}
pthread_mutex_unlock(&g_socketLockInfoList.mutex);
return NULL;
}
static int32_t AddDataThreadToIdle(IdleDataThread *idleDataThread)
{
pthread_mutex_lock(&g_idleDataThreadsList.mutex);
UtilsListAdd(&g_idleDataThreadsList.idleDataThread, &idleDataThread->list);
pthread_mutex_unlock(&g_idleDataThreadsList.mutex);
return ERR_NONE;
}
static void DeleteDataThreadFromIdle(IdleDataThread *idleDataThread)
{
pthread_mutex_lock(&g_idleDataThreadsList.mutex);
UtilsListDelete(&idleDataThread->list);
pthread_mutex_unlock(&g_idleDataThreadsList.mutex);
}
void AddDataThreadInWait(pthread_t threadId)
{
SocketThreadLockInfo *threadLockInfo = QueryThreadLockInfo(threadId);
if (threadLockInfo == NULL) {
threadLockInfo = (SocketThreadLockInfo *)malloc(sizeof(SocketThreadLockInfo));
if (threadLockInfo == NULL) {
RPC_LOG_ERROR("SocketThreadLockInfo malloc failed");
return;
}
threadLockInfo->threadId = threadId;
if (pthread_mutex_init(&threadLockInfo->mutex, NULL) != 0) {
RPC_LOG_ERROR("SocketThreadLockInfo mutex init failed");
free(threadLockInfo);
return;
}
if (pthread_cond_init(&threadLockInfo->condition, NULL) != 0) {
RPC_LOG_ERROR("SocketThreadLockInfo cond init failed");
free(threadLockInfo);
return;
}
if (AttachThreadLockInfo(threadLockInfo) != ERR_NONE) {
free(threadLockInfo);
return;
}
}
pthread_mutex_lock(&threadLockInfo->mutex);
IdleDataThread idleDataThread = {.threadId = threadId};
if (AddDataThreadToIdle(&idleDataThread) != ERR_NONE) {
RPC_LOG_ERROR("AddDataThreadToIdle failed");
pthread_mutex_unlock(&threadLockInfo->mutex);
return;
}
pthread_cond_wait(&threadLockInfo->condition, &threadLockInfo->mutex);
DeleteDataThreadFromIdle(&idleDataThread);
pthread_mutex_unlock(&threadLockInfo->mutex);
}
void WakeUpDataThread(pthread_t threadId)
{
SocketThreadLockInfo *threadLockInfo = QueryThreadLockInfo(threadId);
if (threadLockInfo != NULL) {
pthread_mutex_lock(&threadLockInfo->mutex);
pthread_cond_signal(&threadLockInfo->condition);
pthread_mutex_unlock(&threadLockInfo->mutex);
}
}
IdleDataThread *GetIdleDataThread(void)
{
IdleDataThread *node = NULL;
pthread_mutex_lock(&g_idleDataThreadsList.mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_idleDataThreadsList.idleDataThread, IdleDataThread, list)
{
pthread_mutex_unlock(&g_idleDataThreadsList.mutex);
return node;
}
pthread_mutex_unlock(&g_idleDataThreadsList.mutex);
return NULL;
}
void AddDataInfoToThread(ThreadProcessInfo *processInfo)
{
pthread_mutex_lock(&g_processInfoList.mutex);
UtilsListAdd(&g_processInfoList.processInfo, &processInfo->list);
pthread_mutex_unlock(&g_processInfoList.mutex);
}
ThreadProcessInfo *PopDataInfoFromThread(pthread_t threadId)
{
ThreadProcessInfo *node = NULL;
pthread_mutex_lock(&g_processInfoList.mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_processInfoList.processInfo, ThreadProcessInfo, list)
{
if (pthread_equal(node->threadId, threadId) != 0) {
UtilsListDelete(&node->list);
pthread_mutex_unlock(&g_processInfoList.mutex);
return node;
}
}
pthread_mutex_unlock(&g_processInfoList.mutex);
return NULL;
}
uint32_t ConvertChannelID2Int(int64_t databusChannelId)
{
if (databusChannelId < 0) {
return 0;
}
uint32_t channelType = (uint32_t)((databusChannelId >> 8) & 0X00000000FF000000ULL);
uint32_t channelID = (uint32_t)(databusChannelId & 0X0000000000FFFFFFULL);
return (channelType | channelID);
}
int32_t AttachStubSession(HandleSessionList *handleSession)
{
pthread_mutex_lock(&g_stubSessionMutex);
UtilsListAdd(&g_stubSessionList.list, &handleSession->list);
pthread_mutex_unlock(&g_stubSessionMutex);
return ERR_NONE;
}
void DetachStubSession(HandleSessionList *handleSession)
{
pthread_mutex_lock(&g_stubSessionMutex);
UtilsListDelete(&handleSession->list);
pthread_mutex_unlock(&g_stubSessionMutex);
}
HandleSessionList *QueryStubSession(uint32_t handle)
{
HandleSessionList *node = NULL;
pthread_mutex_lock(&g_stubSessionMutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_stubSessionList.list, HandleSessionList, list)
{
if (node->handle == handle) {
pthread_mutex_unlock(&g_stubSessionMutex);
return node;
}
}
pthread_mutex_unlock(&g_stubSessionMutex);
return NULL;
}
int32_t AttachProxySession(HandleSessionList *handleSession)
{
pthread_mutex_lock(&g_proxySessionMutex);
UtilsListAdd(&g_proxySessionList.list, &handleSession->list);
pthread_mutex_unlock(&g_proxySessionMutex);
return ERR_NONE;
}
void DetachProxySession(HandleSessionList *handleSession)
{
pthread_mutex_lock(&g_proxySessionMutex);
UtilsListDelete(&handleSession->list);
pthread_mutex_unlock(&g_proxySessionMutex);
}
HandleSessionList *QueryProxySession(uint32_t handle)
{
HandleSessionList *node = NULL;
pthread_mutex_lock(&g_proxySessionMutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_proxySessionList.list, HandleSessionList, list)
{
if (node->handle == handle) {
pthread_mutex_unlock(&g_proxySessionMutex);
return node;
}
}
pthread_mutex_unlock(&g_proxySessionMutex);
return NULL;
}
HandleSessionList *QueryProxySessionBySessionId(uint32_t sessionId)
{
HandleSessionList *node = NULL;
pthread_mutex_lock(&g_proxySessionMutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_proxySessionList.list, HandleSessionList, list)
{
if (node->sessionId == sessionId) {
pthread_mutex_unlock(&g_proxySessionMutex);
return node;
}
}
pthread_mutex_unlock(&g_proxySessionMutex);
return NULL;
}
uint64_t ProcessGetSeqNumber()
{
pthread_mutex_lock(&g_rpcSkeleton.lock);
++g_rpcSkeleton.seqNumber; // can be overflow, and seqNumber do not use 0
if (g_rpcSkeleton.seqNumber == 0) {
++g_rpcSkeleton.seqNumber;
}
pthread_mutex_unlock(&g_rpcSkeleton.lock);
return g_rpcSkeleton.seqNumber;
}
int32_t AttachHandleToIndex(HandleToIndexList *handleToIndex)
{
pthread_mutex_lock(&g_handleToIndexMutex);
UtilsListAdd(&g_handleToIndexList.list, &handleToIndex->list);
pthread_mutex_unlock(&g_handleToIndexMutex);
return ERR_NONE;
}
void DetachHandleToIndex(HandleToIndexList *handleToIndex)
{
pthread_mutex_lock(&g_handleToIndexMutex);
UtilsListDelete(&handleToIndex->list);
pthread_mutex_unlock(&g_handleToIndexMutex);
}
HandleToIndexList *QueryHandleToIndex(uint32_t handle)
{
HandleToIndexList *node = NULL;
pthread_mutex_lock(&g_handleToIndexMutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_handleToIndexList.list, HandleToIndexList, list)
{
if (node->handle == handle) {
pthread_mutex_unlock(&g_handleToIndexMutex);
return node;
}
}
pthread_mutex_unlock(&g_handleToIndexMutex);
return NULL;
}
static int32_t AddThreadBySeqNumber(ThreadMessageInfo *messageInfo)
{
pthread_mutex_lock(&g_seqNumberToThreadMutex);
UtilsListAdd(&g_seqNumberToThread.list, &messageInfo->list);
pthread_mutex_unlock(&g_seqNumberToThreadMutex);
return ERR_NONE;
}
int32_t AddSendThreadInWait(uint64_t seqNumber, ThreadMessageInfo *messageInfo, int userWaitTime)
{
if (AddThreadBySeqNumber(messageInfo) != ERR_NONE) {
RPC_LOG_ERROR("add seqNumber = %llu failed", seqNumber);
free(messageInfo);
return ERR_FAILED;
}
SocketThreadLockInfo *threadLockInfo = QueryThreadLockInfo(messageInfo->threadId);
if (threadLockInfo == NULL) {
threadLockInfo = (SocketThreadLockInfo *)malloc(sizeof(SocketThreadLockInfo));
if (threadLockInfo == NULL) {
RPC_LOG_ERROR("threadLockInfo malloc failed");
return ERR_FAILED;
}
pthread_mutex_init(&threadLockInfo->mutex, NULL);
pthread_cond_init(&threadLockInfo->condition, NULL);
threadLockInfo->threadId = messageInfo->threadId;
int32_t ret = AttachThreadLockInfo(threadLockInfo);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("AttachThreadLockInfo fail");
free(threadLockInfo);
return ERR_FAILED;
}
}
pthread_mutex_lock(&threadLockInfo->mutex);
if (userWaitTime < 0) {
pthread_cond_wait(&threadLockInfo->condition, &threadLockInfo->mutex);
} else {
struct timespec waitTime;
struct timeval now;
if (gettimeofday(&now, NULL) != 0) {
RPC_LOG_ERROR("gettimeofday failed");
pthread_mutex_unlock(&threadLockInfo->mutex);
return ERR_FAILED;
}
waitTime.tv_sec = now.tv_sec + DEFAULT_SEND_WAIT_TIME;
waitTime.tv_nsec = now.tv_usec * USECTONSEC;
int ret = pthread_cond_timedwait(&threadLockInfo->condition, &threadLockInfo->mutex, &waitTime);
pthread_mutex_unlock(&threadLockInfo->mutex);
if (ret == ETIMEDOUT) {
RPC_LOG_ERROR("send thread wait for reply timeout");
return ERR_FAILED;
}
}
return ERR_NONE;
}
void EraseThreadBySeqNumber(ThreadMessageInfo *messageInfo)
{
pthread_mutex_lock(&g_seqNumberToThreadMutex);
UtilsListDelete(&messageInfo->list);
pthread_mutex_unlock(&g_seqNumberToThreadMutex);
}
ThreadMessageInfo *QueryThreadBySeqNumber(uint64_t seqNumber)
{
ThreadMessageInfo *node = NULL;
pthread_mutex_lock(&g_seqNumberToThreadMutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_seqNumberToThread.list, ThreadMessageInfo, list)
{
if (node->seqNumber == seqNumber) {
pthread_mutex_unlock(&g_seqNumberToThreadMutex);
return node;
}
}
pthread_mutex_unlock(&g_seqNumberToThreadMutex);
return NULL;
}
void WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle)
{
ThreadMessageInfo *messageInfo = QueryThreadBySeqNumber(seqNumber);
if (messageInfo == NULL) {
RPC_LOG_ERROR("error! messageInfo is nullptr");
return;
}
if (handle != messageInfo->socketId) {
RPC_LOG_ERROR("error! handle is not equal messageInfo, handle = %d, messageFd = %u", handle,
messageInfo->socketId);
return;
}
if (pthread_equal(messageInfo->threadId, pthread_self()) == 0) {
SocketThreadLockInfo *threadLockInfo = QueryThreadLockInfo(messageInfo->threadId);
if (threadLockInfo != NULL) {
/* wake up this IO thread to process socket stream
* Wake up the client processing thread
*/
pthread_mutex_lock(&threadLockInfo->mutex);
pthread_cond_signal(&threadLockInfo->condition);
pthread_mutex_unlock(&threadLockInfo->mutex);
}
}
}
int32_t RpcOnRemoteRequestInner(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option,
IpcObjectStub *objectStub)
{
int32_t result = ERR_FAILED;
switch (code) {
case INVOKE_LISTEN_THREAD: {
result = InvokerListenThreadStub(code, data, reply, option, objectStub->func);
break;
}
case GET_UIDPID_INFO: {
result = GetPidAndUidInfoStub(code, data, reply, option);
break;
}
case GRANT_DATABUS_NAME: {
result = GrantDataBusNameStub(code, data, reply, option);
break;
}
default:
result = ERR_NOT_RPC;
break;
}
return result;
}
void UpdateProtoIfNeed(int32_t handle)
{
RPC_LOG_INFO("rpc manager update proto, handle %d", handle);
UpdateProto(handle);
}
uint64_t GetNewStubIndex(void)
{
pthread_mutex_lock(&g_rpcSkeleton.lock);
uint64_t stubIndex = ++g_rpcSkeleton.stubIndex;
pthread_mutex_unlock(&g_rpcSkeleton.lock);
return stubIndex;
}
\ 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_process_skeleton.h"
#include "dbinder_invoker.h"
#include "rpc_errno.h"
int32_t RpcProcessSkeleton(void)
{
return ERR_NONE;
}
RpcSkeleton *GetCurrentRpcSkeleton(void)
{
return NULL;
}
int32_t RpcOnRemoteRequestInner(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option,
IpcObjectStub *objectStub)
{
return ERR_NOT_RPC;
}
void UpdateProtoIfNeed(int32_t handle)
{
return;
}
RemoteInvoker *GetRpcInvoker(void)
{
return NULL;
}
\ 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_trans_callback.h"
#include "rpc_log.h"
#include "rpc_errno.h"
#include "dbinder_invoker.h"
static int32_t OnConnected(int32_t sessionId, int32_t result)
{
if (sessionId < 0 || result != 0) {
RPC_LOG_ERROR("fail to open session because of wrong channel ID");
return ERR_FAILED;
}
RPC_LOG_INFO("rpc OnConnected callback, receive sessionId: %d", sessionId);
return OnReceiveNewConnection(sessionId);
}
static int32_t OnDisconnected(int32_t sessionId)
{
RPC_LOG_INFO("rpc OnDisconnected callback, receive sessionId: %d", sessionId);
OnDatabusSessionClosed(sessionId);
return ERR_NONE;
}
static int32_t OnRecieved(int32_t sessionId, const void *data, uint32_t len)
{
RPC_LOG_INFO("rpc OnRecieved callback, receive sessionId: %d", sessionId);
OnMessageAvailable(sessionId, data, len);
return ERR_NONE;
}
static TransCallback g_sessionListener = {
.OnConnected = OnConnected,
.OnDisconnected = OnDisconnected,
.OnRecieved = OnRecieved
};
TransCallback *GetRpcTransCallback(void)
{
RPC_LOG_INFO("GetTransCallback rpc");
return &g_sessionListener;
}
\ 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.
*/
#ifndef OHOS_RPC_TRANS_H
#define OHOS_RPC_TRANS_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int32_t (*OnConnected)(int32_t sessionId, int32_t result);
int32_t (*OnDisconnected)(int32_t sessionId);
int32_t (*OnRecieved)(int32_t sessionId, const void *data, uint32_t len);
} TransCallback;
typedef struct {
int32_t (*StartListen)(const char *SaSessionName, void *cb);
int32_t (*StopListen)(const char *SaSessionName);
int32_t (*Connect)(const char *SaSessionName, const char *peerDeviceId, void *args);
int32_t (*Disconnect)(int32_t sessionId);
int32_t (*Send)(int32_t sessionId, const void *data, uint32_t len);
} TransInterface;
TransInterface *GetRpcTrans(void);
char *GetLocalDeviceID(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_TRANS_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_trans.h"
#include <stddef.h>
#if defined(RPC_SOCKET_TRANS)
#include "rpc_socket_trans.h"
#endif
TransInterface *GetRpcTrans(void)
{
#if defined(RPC_SOCKET_TRANS)
return GetSocketTrans();
#endif
return NULL;
}
char *GetLocalDeviceID(void)
{
#if defined(RPC_SOCKET_TRANS)
return GetSocketLocalDeviceID();
#endif
return NULL;
}
\ 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.
import("//build/lite/config/component/lite_component.gni")
lite_component("rpc_test") {
features = []
if (ohos_kernel_type == "linux") {
features += [
"client:rpc_client",
"server:rpc_server",
"samgr:rpc_samgr",
]
}
}
# Copyright (c) 2020 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/lite/config/component/lite_component.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
IPC_CORE_ROOT = "${SUBSYSTEM_DIR}/ipc/native/c"
executable("rpc_client") {
sources = [ "$SUBSYSTEM_DIR/ipc/test/rpc/client/rpc_client.c" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"//utils/native/lite/include",
"$IPC_CORE_ROOT/manager/include",
"$IPC_CORE_ROOT/rpc/trans_adapter/include",
"$IPC_CORE_ROOT/rpc/ipc_adapter/include",
"$IPC_CORE_ROOT/rpc/include",
"$IPC_CORE_ROOT/ipc/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/dbinder/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",
]
ldflags = [ "-lstdc++" ]
deps = [
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/dbinder:dbinder",
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/ipc:rpc_manager",
]
configs -= [ "//build/lite/config:clang_opt" ]
}
/*
* 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 <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "rpc_log.h"
#include "rpc_errno.h"
#include "rpc_trans.h"
#include "dbinder_service.h"
#include "ipc_skeleton.h"
#include "ipc_process_skeleton.h"
#include "rpc_process_skeleton.h"
#include "serializer.h"
#define IPC_LENGTH 64
#define NUMBER_A 12
#define NUMBER_B 17
enum {
OP_ADD = 1,
OP_SUB = 2,
OP_MULTI = 3,
OP_ADD_SERVICE = 4,
OP_DBINDER_CONNECT = 5,
OP_DBINDER_RECEIVED = 6,
};
enum {
GET_REMOTE_SYSTEM_ABILITY_TRANSACTION = 3,
ADD_REMOTE_SYSTEM_ABILITY_TRANSACTION = 4,
};
static const int32_t g_saID = 16;
static void ServerDead1(void)
{
RPC_LOG_INFO("#### rpc server dead callback11 called");
}
static void RpcClientTestOne(SvcIdentity sid, MessageOption option)
{
IpcIo data2;
uint8_t tmpData2[IPC_LENGTH];
IpcIoInit(&data2, tmpData2, IPC_LENGTH, 0);
WriteInt32(&data2, NUMBER_A);
WriteInt32(&data2, NUMBER_B);
IpcIo reply2;
uintptr_t ptr2 = 0;
int32_t ret = SendRequest(sid, OP_ADD, &data2, &reply2, option, &ptr2);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("SendRequest OP_ADD failed, error = %d", ret);
FreeBuffer((void *)ptr2);
return;
}
int32_t sum;
ReadInt32(&reply2, &sum);
RPC_LOG_INFO("%d + %d = %d", NUMBER_A, NUMBER_B, sum);
FreeBuffer((void *)ptr2);
}
static void RpcClientTestTwo(SvcIdentity sid, MessageOption option)
{
IpcIo data3;
uint8_t tmpData3[IPC_LENGTH];
IpcIoInit(&data3, tmpData3, IPC_LENGTH, 0);
WriteInt32(&data3, NUMBER_A);
WriteInt32(&data3, NUMBER_B);
IpcIo reply3;
uintptr_t ptr3 = 0;
int32_t ret = SendRequest(sid, OP_MULTI, &data3, &reply3, option, &ptr3);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("SendRequest OP_MULTI failed, error = %d", ret);
FreeBuffer((void *)ptr3);
return;
}
int32_t mutil;
ReadInt32(&reply3, &mutil);
RPC_LOG_INFO("%d * %d = %d", NUMBER_A, NUMBER_B, mutil);
FreeBuffer((void *)ptr3);
}
int main(int argc, char *argv[])
{
RPC_LOG_INFO("Enter System Ability Client .... ");
if (argc == 1) {
RPC_LOG_INFO("input deviceid please");
return -1;
}
RPC_LOG_INFO("argv 1 is %s", argv[1]);
if (strcmp(argv[1], "deviceId") == 0) {
RPC_LOG_INFO("local deviceId is %s", GetLocalDeviceID());
return 0;
}
const char *deviceId = argv[1];
IpcIo data1;
uint8_t tmpData1[IPC_LENGTH];
IpcIoInit(&data1, tmpData1, IPC_LENGTH, 0);
WriteInt32(&data1, g_saID);
WriteString(&data1, deviceId);
IpcIo reply1;
MessageOption option = TF_OP_SYNC;
SvcIdentity target = {
.handle = 0
};
RPC_LOG_INFO("get remote system ability from samgr.");
uintptr_t ptr = 0;
int32_t ret = SendRequest(target, GET_REMOTE_SYSTEM_ABILITY_TRANSACTION, &data1, &reply1, option, &ptr);
SvcIdentity sid;
ReadRemoteObject(&reply1, &sid);
RPC_LOG_INFO("call server add func server handle = %d.", sid.handle);
FreeBuffer((void *)ptr);
uint32_t cbId1 = 0;
ret = AddDeathRecipient(sid, ServerDead1, NULL, &cbId1);
RPC_LOG_INFO("add death callback cbid1 = %d", ret);
RpcClientTestOne(sid, option);
RpcClientTestTwo(sid, option);
JoinWorkThread();
return 0;
}
\ 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.
*/
#ifndef OHOS_RPC_RPC_MINI_SAMGR_H
#define OHOS_RPC_RPC_MINI_SAMGR_H
#include "serializer.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void RpcStartSamgr(void);
int32_t AddSystemAbility(int32_t saId, SvcIdentity *sid);
SvcIdentity *GetSystemAbilityById(int32_t systemAbility);
int32_t AddRemoteSystemAbility(int32_t saId, SvcIdentity *sid);
int32_t GetRemoteSystemAbility(int32_t saId, const char* deviceId, SvcIdentity *sid);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_RPC_MINI_SAMGR_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.
import("//build/lite/config/component/lite_component.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
IPC_CORE_ROOT = "${SUBSYSTEM_DIR}/ipc/native/c"
executable("rpc_samgr") {
sources = [ "$SUBSYSTEM_DIR/ipc/test/rpc/samgr/rpc_samgr.c" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"//utils/native/lite/include",
"$IPC_CORE_ROOT/manager/include",
"$IPC_CORE_ROOT/ipc/include",
"//foundation/communication/ipc/services/dbinder/c/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/dbinder/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
]
ldflags = [
"-lstdc++",
"-lpthread",
]
deps = [
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/dbinder:dbinder",
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/ipc:rpc_manager",
]
configs -= [ "//build/lite/config:clang_opt" ]
}
/*
* 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_mini_samgr.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "rpc_log.h"
#include "rpc_errno.h"
#include "ipc_skeleton.h"
#include "serializer.h"
#include "utils_list.h"
#include "securec.h"
#include "dbinder_service.h"
typedef struct {
UTILS_DL_LIST list;
int32_t saId;
SvcIdentity *sid;
} SvcInfo;
static UTILS_DL_LIST *g_saList = NULL;
static pthread_mutex_t g_handleMutex = PTHREAD_MUTEX_INITIALIZER;
static int32_t g_handle = 0;
int32_t AddSystemAbility(int32_t saId, SvcIdentity *sid)
{
RPC_LOG_INFO("AddSystemAbility called.... handle = %d", sid->handle);
RPC_LOG_INFO("AddSystemAbility called.... cookie = %u, said = %d", sid->cookie, saId);
if (g_saList == NULL) {
return ERR_FAILED;
}
SvcInfo* node = (SvcInfo *)calloc(1, sizeof(SvcInfo));
if (node == NULL) {
RPC_LOG_ERROR("AddSystemAbility node calloc failed");
return ERR_FAILED;
}
node->saId = saId;
node->sid = (SvcIdentity *)calloc(1, sizeof(SvcIdentity));
if (memcpy_s(node->sid, sizeof(SvcIdentity), sid, sizeof(SvcIdentity)) != EOK) {
RPC_LOG_INFO("AddSystemAbility memcpy failed");
free(node->sid);
free(node);
return ERR_FAILED;
}
pthread_mutex_lock(&g_handleMutex);
node->sid->handle = ++g_handle;
pthread_mutex_unlock(&g_handleMutex);
UtilsListAdd(g_saList, &node->list);
return ERR_NONE;
}
SvcIdentity *GetSystemAbilityById(int32_t systemAbility)
{
SvcInfo* node = NULL;
SvcInfo* next = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, g_saList, SvcInfo, list)
{
RPC_LOG_INFO("GetSystemAbilityById %d", node->saId);
if (node->saId == systemAbility) {
return node->sid;
}
}
return NULL;
}
int32_t AddRemoteSystemAbility(int32_t saId, SvcIdentity *sid)
{
if (AddSystemAbility(saId, sid) == ERR_FAILED) {
RPC_LOG_ERROR("AddSystemAbility failed");
return ERR_FAILED;
}
const char *name = "16";
if (RegisterRemoteProxy(name, strlen(name), saId) != ERR_NONE) {
RPC_LOG_ERROR("RegisterRemoteProxy failed");
return ERR_FAILED;
}
return ERR_NONE;
}
int32_t GetRemoteSystemAbility(int32_t saId, const char* deviceId, SvcIdentity *sid)
{
RPC_LOG_INFO("GetRemoteSystemAbility start");
const char *name = "16";
uint32_t idLen = (uint32_t)strlen(deviceId);
int32_t ret = MakeRemoteBinder(name, 2, deviceId, idLen, (uintptr_t)saId, 0, (void *)sid);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("MakeRemoteBinder failed");
}
return ret;
}
void RpcStartSamgr(void)
{
RPC_LOG_INFO("RpcStartSamgr start");
g_saList = (UTILS_DL_LIST *)calloc(1, sizeof(UTILS_DL_LIST));
UtilsListInit(g_saList);
StartDBinderService();
RPC_LOG_INFO("StartDBinderService finished");
return;
}
\ 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 <stdlib.h>
#include <string.h>
#include "rpc_log.h"
#include "rpc_errno.h"
#include "ipc_skeleton.h"
#include "serializer.h"
#include "utils_list.h"
#include "dbinder_service.h"
typedef struct {
UTILS_DL_LIST list;
int32_t saId;
SvcIdentity *sid;
} SvcInfo;
static UTILS_DL_LIST *g_saList = NULL;
enum {
ADD_SYSTEM_ABILITY_TRANSACTION = 2,
GET_REMOTE_SYSTEM_ABILITY_TRANSACTION = 3,
ADD_REMOTE_SYSTEM_ABILITY_TRANSACTION = 4,
};
int32_t AddSystemAbility(int32_t saId, SvcIdentity *sid)
{
RPC_LOG_INFO("AddSystemAbility called.... handle = %d", sid->handle);
RPC_LOG_INFO("AddSystemAbility called.... cookie = %u", sid->cookie);
if (g_saList == NULL) {
return ERR_FAILED;
}
SvcInfo* node = (SvcInfo *)calloc(1, sizeof(SvcInfo));
if (node == NULL) {
RPC_LOG_ERROR("AddSystemAbility node calloc failed");
return ERR_FAILED;
}
node->saId = saId;
node->sid = sid;
UtilsListAdd(g_saList, &node->list);
return ERR_NONE;
}
int32_t GetSystemAbility(int32_t saId, const char* deviceId, SvcIdentity *sid)
{
SvcInfo* node = NULL;
SvcInfo* next = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, g_saList, SvcInfo, list)
{
if (node->saId == saId) {
sid->handle = node->sid->handle;
sid->token = node->sid->token;
sid->cookie = node->sid->cookie;
RPC_LOG_INFO("find sa, said = %d, handle = %d, cookie = %u", saId, sid->handle, sid->cookie);
return ERR_NONE;
}
}
return ERR_FAILED;
}
int32_t AddRemoteSystemAbility(int32_t saId, SvcIdentity *sid)
{
if (AddSystemAbility(saId, sid) == ERR_FAILED) {
RPC_LOG_ERROR("AddSystemAbility failed");
return ERR_FAILED;
}
const char *name = "16";
if (RegisterRemoteProxy(name, strlen(name), saId) != ERR_NONE) {
RPC_LOG_ERROR("RegisterRemoteProxy failed");
return ERR_FAILED;
}
return ERR_NONE;
}
int32_t GetRemoteSystemAbility(IpcIo *data, SvcIdentity *sid)
{
int32_t saId;
ReadInt32(data, &saId);
size_t len;
const char *deviceId = (const char *)ReadString(data, &len);
const char *name = "16";
uint32_t idLen = (uint32_t)strlen(deviceId);
RPC_LOG_INFO("GetRemoteSystemAbility start");
int32_t ret = MakeRemoteBinder(name, 2, deviceId, idLen, (uintptr_t)saId, 0, (void *)sid);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("MakeRemoteBinder failed");
}
RPC_LOG_INFO("GetRemoteSystemAbility handle=%d, cookie=%u", sid->handle, sid->cookie);
return ret;
}
int32_t RemoteRequest(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
{
int32_t result = ERR_NONE;
RPC_LOG_INFO("OnRemoteRequest called.... code = %d", code);
switch (code) {
case GET_SYSTEM_ABILITY_TRANSACTION: {
int32_t saId;
ReadInt32(data, &saId);
SvcIdentity sid;
result = GetSystemAbility(saId, "", &sid);
WriteRemoteObject(reply, &sid);
break;
}
case ADD_SYSTEM_ABILITY_TRANSACTION: {
int32_t saId;
ReadInt32(data, &saId);
SvcIdentity *sid = (SvcIdentity *)malloc(sizeof(SvcIdentity));
if (sid == NULL) {
result = ERR_FAILED;
break;
}
ReadRemoteObject(data, sid);
result = AddSystemAbility(saId, sid);
break;
}
case GET_REMOTE_SYSTEM_ABILITY_TRANSACTION: {
SvcIdentity sid;
result = GetRemoteSystemAbility(data, &sid);
WriteRemoteObject(reply, &sid);
break;
}
case ADD_REMOTE_SYSTEM_ABILITY_TRANSACTION: {
int32_t saId;
ReadInt32(data, &saId);
SvcIdentity *sid = (SvcIdentity *)malloc(sizeof(SvcIdentity));
if (sid == NULL) {
result = ERR_FAILED;
break;
}
ReadRemoteObject(data, sid);
result = AddRemoteSystemAbility(saId, sid);
break;
}
default:
RPC_LOG_ERROR("unknown code %d", code);
break;
}
return result;
}
int main(int argc, char *argv[])
{
RPC_LOG_INFO("Enter System Ability Manager .... ");
g_saList = (UTILS_DL_LIST *)calloc(1, sizeof(UTILS_DL_LIST));
UtilsListInit(g_saList);
IpcObjectStub objectStub = {
.func = RemoteRequest,
.isRemote = false
};
SvcIdentity target = {
.handle = 0,
.cookie = (uintptr_t)&objectStub
};
if (SetContextObject(target) != ERR_NONE) {
RPC_LOG_ERROR("SAMGR register samgr failed");
return -1;
}
StartDBinderService();
RPC_LOG_INFO("StartDBinderService finished");
JoinWorkThread();
return -1;
}
\ 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.
import("//build/lite/config/component/lite_component.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
IPC_CORE_ROOT = "${SUBSYSTEM_DIR}/ipc/native/c"
executable("rpc_server") {
sources = [ "$SUBSYSTEM_DIR/ipc/test/rpc/server/rpc_server.c" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"//utils/native/lite/include",
"$IPC_CORE_ROOT/ipc/include",
"$IPC_CORE_ROOT/manager/include",
"$IPC_CORE_ROOT/rpc/include",
"$IPC_CORE_ROOT/rpc/ipc_adapter/include",
"$IPC_CORE_ROOT/rpc/trans_adapter/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/dbinder/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/c/ipc/include",
"$SUBSYSTEM_DIR/services/dbinder/c/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",
]
ldflags = [ "-lstdc++" ]
deps = [
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/dbinder:dbinder",
"${SUBSYSTEM_DIR}/interfaces/innerkits/c/ipc:rpc_manager",
]
configs -= [ "//build/lite/config:clang_opt" ]
}
/*
* 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 <stdlib.h>
#include <securec.h>
#include "rpc_log.h"
#include "rpc_errno.h"
#include "ipc_skeleton.h"
#include "serializer.h"
#include "dbinder_invoker.h"
#include "dbinder_types.h"
enum {
OP_ADD = 1,
OP_SUB = 2,
OP_MULTI = 3,
OP_ADD_SERVICE = 4,
};
enum {
ADD_SYSTEM_ABILITY_TRANSACTION = 2,
GET_REMOTE_SYSTEM_ABILITY_TRANSACTION = 3,
ADD_REMOTE_SYSTEM_ABILITY_TRANSACTION = 4,
};
static const int32_t g_saID = 16;
static const uint32_t IPC_LENGTH = 128;
int32_t RemoteRequestOne(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
{
int32_t result = ERR_NONE;
RPC_LOG_INFO("server OnRemoteRequestOne called....");
switch (code) {
case OP_ADD: {
int32_t a;
ReadInt32(data, &a);
int32_t b;
ReadInt32(data, &b);
RPC_LOG_INFO("RemoteRequestOne add called a = %d, b = %d", a, b);
WriteInt32(reply, a + b);
break;
}
case OP_SUB: {
int32_t a;
ReadInt32(data, &a);
int32_t b;
ReadInt32(data, &b);
RPC_LOG_INFO("RemoteRequestOne sub called a = %d, b = %d", a, b);
WriteInt32(reply, a - b);
break;
}
case OP_MULTI: {
int32_t a;
ReadInt32(data, &a);
int32_t b;
ReadInt32(data, &b);
RPC_LOG_INFO("RemoteRequestOne mulit called a = %d, b = %d", a, b);
WriteInt32(reply, a * b);
break;
}
default:
RPC_LOG_ERROR("unknown code %d", code);
break;
}
return result;
}
int main(int argc, char *argv[])
{
RPC_LOG_INFO("Enter System Ability Server .... ");
IpcObjectStub objectStubOne = {
.func = RemoteRequestOne,
.isRemote = false
};
SvcIdentity svcOne = {
.handle = -1,
.token = (uintptr_t)&objectStubOne,
.cookie = (uintptr_t)&objectStubOne
};
IpcIo data;
uint8_t tmpData1[IPC_LENGTH];
IpcIoInit(&data, tmpData1, IPC_LENGTH, 1);
WriteInt32(&data, g_saID);
WriteRemoteObject(&data, &svcOne);
IpcIo reply;
MessageOption option = TF_OP_SYNC;
SvcIdentity target = {
.handle = 0
};
RPC_LOG_INFO("====== add ability one to samgr ======");
uintptr_t ptr = 0;
SendRequest(target, ADD_REMOTE_SYSTEM_ABILITY_TRANSACTION, &data, &reply, option, &ptr);
int32_t ret;
ReadInt32(&reply, &ret);
RPC_LOG_INFO("send request one ret = %d .... ", ret);
FreeBuffer((void *)ptr);
JoinWorkThread();
return -1;
}
\ 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.
*/
#ifndef OHOS_RPC_SOCKET_TRANS_H
#define OHOS_RPC_SOCKET_TRANS_H
#include <stdint.h>
#include "utils_list.h"
#include "rpc_trans.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEFAULT_BACKLOG 4
#define DEFAULT_PACKET_SIZE 1024
#define DEFAULT_HASH_OFFSET 3
static char const *SOCKET_SERVER_ADDR = "0.0.0.0";
static char const *DEFAULT_NET_INTERFACE = "eth0";
static const uint16_t DEFAULT_HASH_SEED = 5381;
static const uint16_t DEFAULT_PORT_MIN = 10000;
TransInterface *GetSocketTrans(void);
char *GetSocketLocalDeviceID(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_SOCKET_TRANS_H
\ 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_socket_trans.h"
#include <string.h>
#include <stddef.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "lwip/def.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "utils_list.h"
#include "securec.h"
#include "rpc_errno.h"
#include "rpc_log.h"
#define DEVICEID_LENGTH 64
#define SERVICENAME_LENGTH 200
#define DEFAULT_LOCAL_DEVICEID "192.168.1.74"
#define DEFAULT_THREAD_STACK_SIZE 8192
typedef struct {
UTILS_DL_LIST list;
char *saSessionName;
char *deviceId;
TransCallback cb;
} SocketNode;
typedef struct {
UTILS_DL_LIST list;
pthread_mutex_t mutex;
} SocketNodeList;
static SocketNodeList g_socketNodeList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static int32_t g_init = -1;
static int32_t g_serverCreated = -1;
static TransCallback g_callback;
static char *g_localDeviceId = NULL;
static uint16_t Hash(const char *name)
{
if (name == NULL) {
return 0;
}
RPC_LOG_INFO("Hash called %s", name);
sleep(1);
uint16_t hash = DEFAULT_HASH_SEED;
uint16_t c;
while (c = *name++)
hash = ((hash << DEFAULT_HASH_OFFSET) + hash) + c;
return hash % DEFAULT_PORT_MIN + DEFAULT_PORT_MIN;
}
static int32_t BindLocalIP(int fd, const char *localIP, uint16_t port, struct sockaddr_in *addr)
{
if (memset_s(addr, sizeof(struct sockaddr_in), 0, sizeof(*addr)) != EOK) {
RPC_LOG_ERROR("sockaddr_in memset failed");
return ERR_FAILED;
}
addr->sin_family = AF_INET;
int rc = inet_pton(AF_INET, localIP, &addr->sin_addr);
if (rc <= 0) {
RPC_LOG_ERROR("inet_pton rc=%d", rc);
return ERR_FAILED;
}
addr->sin_port = lwip_htons(port);
errno = 0;
rc = bind(fd, (struct sockaddr *)addr, sizeof(*addr));
if (rc < 0) {
RPC_LOG_ERROR("bind fd=%d,rc=%d", fd, rc);
return ERR_FAILED;
}
return ERR_NONE;
}
static void TcpShutDown(int fd)
{
if (fd >= 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
}
}
static void *HandleAccept(void *args)
{
if (args == NULL) {
return NULL;
}
int32_t clientFd = *(int32_t *)args;
int32_t ret;
if (g_callback.OnConnected != NULL) {
ret = g_callback.OnConnected(clientFd, 0);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("g_callback OnConnected failed");
return NULL;
}
}
char buf[DEFAULT_PACKET_SIZE];
if (g_callback.OnRecieved != NULL) {
for (;;) {
ssize_t readLen = read(clientFd, buf, DEFAULT_PACKET_SIZE);
if (readLen == 0) {
RPC_LOG_INFO("client socket close");
g_callback.OnDisconnected(clientFd);
TcpShutDown(clientFd);
return NULL;
}
if (readLen < 0) {
RPC_LOG_ERROR("socket read error=%d", readLen);
TcpShutDown(clientFd);
return NULL;
}
ret = g_callback.OnRecieved(clientFd, (void *)buf, (uint32_t)readLen);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("g_callback OnRecieved failed");
return NULL;
}
}
}
return NULL;
}
static void *OpenTcpServerSocket(void *args)
{
printf("OpenTcpServerSocket %d\n", strlen((char *)args));
sleep(1);
if (args == NULL) {
return NULL;
}
char *ip = (char *)SOCKET_SERVER_ADDR;
uint16_t port = Hash((char *)args);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
RPC_LOG_ERROR("fd=%d", fd);
return NULL;
}
struct sockaddr_in addr;
int32_t ret = BindLocalIP(fd, ip, port, &addr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("BindLocalIP ret=%d", ret);
TcpShutDown(fd);
return NULL;
}
if (listen(fd, DEFAULT_BACKLOG) != 0) {
RPC_LOG_ERROR("listen failed");
TcpShutDown(fd);
return NULL;
}
g_serverCreated = 0;
for (;;) {
socklen_t len = sizeof(addr);
int32_t clientFd = accept(fd, (struct sockaddr *)&addr, &len);
RPC_LOG_INFO("accept get fd %d", clientFd);
pthread_t threadId;
pthread_attr_t threadAttr;
ret = pthread_attr_init(&threadAttr);
if (ret != 0) {
RPC_LOG_ERROR("pthread_attr_init failed %d", ret);
return ERR_FAILED;
}
if (pthread_attr_setstacksize(&threadAttr, DEFAULT_THREAD_STACK_SIZE) != 0) {
RPC_LOG_ERROR("pthread_attr_setstacksize failed");
return ERR_FAILED;
}
ret = pthread_create(&threadId, &threadAttr, HandleAccept, (void *)&clientFd);
if (ret != 0) {
RPC_LOG_ERROR("pthread_create failed %d", ret);
return ERR_FAILED;
}
pthread_detach(threadId);
}
return NULL;
}
static int32_t StartListen(const char *SaSessionName, void *cb)
{
printf("StartListen called %s, %d\n", SaSessionName, strlen(SaSessionName));
if (SaSessionName == NULL) {
RPC_LOG_ERROR("SaSessionName is null");
return ERR_FAILED;
}
if (memcpy_s(&g_callback, sizeof(TransCallback), cb, sizeof(TransCallback)) != EOK) {
RPC_LOG_ERROR("g_callback memcpy_s failed");
return ERR_FAILED;
}
pthread_t threadId;
pthread_attr_t threadAttr;
int ret = pthread_attr_init(&threadAttr);
if (ret != 0) {
RPC_LOG_ERROR("pthread_attr_init failed %d", ret);
return ERR_FAILED;
}
if (pthread_attr_setstacksize(&threadAttr, DEFAULT_THREAD_STACK_SIZE) != 0) {
RPC_LOG_ERROR("pthread_attr_setstacksize failed");
return ERR_FAILED;
}
ret = pthread_create(&threadId, &threadAttr, OpenTcpServerSocket, (void *)SaSessionName);
if (ret != 0) {
RPC_LOG_ERROR("pthread_create failed %d", ret);
return ERR_FAILED;
}
pthread_detach(threadId);
return ERR_NONE;
}
static int32_t StopListen(const char *SaSessionName)
{
return ERR_NONE;
}
static void *HandleSendReply(void *args)
{
if (args == NULL) {
RPC_LOG_ERROR("HandleSendReply args is null");
return NULL;
}
int32_t fd = *(int32_t *)args;
free(args);
char buf[DEFAULT_PACKET_SIZE];
if (g_callback.OnRecieved != NULL) {
for (;;) {
ssize_t readLen = read(fd, buf, DEFAULT_PACKET_SIZE);
if (readLen == 0) {
RPC_LOG_INFO("HandleSendReply received len %d", readLen);
g_callback.OnDisconnected(fd);
TcpShutDown(fd);
return NULL;
}
if (readLen < 0) {
RPC_LOG_ERROR("HandleSendReply received len %d", readLen);
TcpShutDown(fd);
return NULL;
}
g_callback.OnRecieved(fd, buf, readLen);
}
}
return NULL;
}
static int32_t Connect(const char *SaSessionName, const char *peerDeviceId, void *args)
{
if (SaSessionName == NULL) {
RPC_LOG_INFO("SaSessionName is null");
return ERR_FAILED;
}
uint16_t port = Hash(SaSessionName);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
RPC_LOG_ERROR("%s:%d:fd=%d", __func__, __LINE__, fd);
return ERR_FAILED;
}
struct sockaddr_in addr;
if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
RPC_LOG_ERROR("memset failed");
}
addr.sin_family = AF_INET;
inet_pton(AF_INET, peerDeviceId, &addr.sin_addr);
addr.sin_port = lwip_htons(port);
errno = 0;
int rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
if ((rc == -1) && (errno != EINPROGRESS)) {
RPC_LOG_ERROR("fd=%d,connect rc=%d, errno=%d", fd, rc, errno);
TcpShutDown(fd);
return ERR_FAILED;
}
int32_t *sessionId = (int32_t *)malloc(sizeof(int32_t));
if (sessionId == NULL) {
return ERR_FAILED;
}
*sessionId = fd;
pthread_t threadId;
pthread_attr_t threadAttr;
int ret = pthread_attr_init(&threadAttr);
if (ret != 0) {
RPC_LOG_ERROR("pthread_attr_init failed %d", ret);
return ERR_FAILED;
}
if (pthread_attr_setstacksize(&threadAttr, DEFAULT_THREAD_STACK_SIZE) != 0) {
RPC_LOG_ERROR("pthread_attr_setstacksize failed");
return ERR_FAILED;
}
ret = pthread_create(&threadId, &threadAttr, HandleSendReply, (void *)sessionId);
if (ret != 0) {
RPC_LOG_ERROR("pthread_create failed %d", ret);
return ERR_FAILED;
}
pthread_detach(threadId);
return fd;
}
static int32_t Disconnect(int32_t sessionId)
{
return ERR_NONE;
}
static int32_t Send(int32_t sessionId, const void *data, uint32_t len)
{
if (sessionId < 0 || data == NULL || len <= 0) {
RPC_LOG_ERROR("send invail params");
return ERR_FAILED;
}
ssize_t ret = write(sessionId, data, len);
if (ret < 0) {
RPC_LOG_ERROR("send error=%d", ret);
return ERR_FAILED;
}
return ERR_NONE;
}
static TransInterface g_socketTrans = {
.StartListen = StartListen,
.StopListen = StopListen,
.Connect = Connect,
.Disconnect = Disconnect,
.Send = Send
};
TransInterface *GetSocketTrans(void)
{
if (g_init == -1) {
pthread_mutex_lock(&g_socketNodeList.mutex);
UtilsListInit(&g_socketNodeList.list);
g_init = 0;
printf("g_socketTrans %x\n", g_socketTrans.StartListen);
pthread_mutex_unlock(&g_socketNodeList.mutex);
}
return &g_socketTrans;
}
char *GetSocketLocalDeviceID(void)
{
extern struct netif if_wifi;
uint32_t ip = ((ip4_addr_t *)&if_wifi.ip_addr)->addr;
char *localDeviceId = inet_ntoa(ip);
if (localDeviceId == NULL) {
RPC_LOG_ERROR("GetSocketLocalDeviceID inet_ntoa return null");
return NULL;
}
RPC_LOG_INFO("GetSocketLocalDeviceID %s\n", localDeviceId);
return localDeviceId;
}
\ 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_socket_trans.h"
#include <string.h>
#include <stddef.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include "utils_list.h"
#include "securec.h"
#include "rpc_errno.h"
#include "rpc_log.h"
#define DEVICEID_LENGTH 64
#define SERVICENAME_LENGTH 200
typedef struct {
UTILS_DL_LIST list;
char *saSessionName;
char *deviceId;
TransCallback cb;
} SocketNode;
typedef struct {
UTILS_DL_LIST list;
pthread_mutex_t mutex;
} SocketNodeList;
static SocketNodeList g_socketNodeList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
static int32_t g_init = -1;
static int32_t g_serverCreated = -1;
static TransCallback g_callback;
static char *g_localDeviceId = NULL;
static uint16_t Hash(const char *name)
{
if (name == NULL) {
return 0;
}
uint16_t hash = DEFAULT_HASH_SEED;
uint16_t c;
while (c = *name++)
hash = ((hash << DEFAULT_HASH_OFFSET) + hash) + c;
return hash % DEFAULT_PORT_MIN + DEFAULT_PORT_MIN;
}
static int32_t BindLocalIP(int fd, const char *localIP, uint16_t port, struct sockaddr_in *addr)
{
if (memset_s(addr, sizeof(struct sockaddr_in), 0, sizeof(*addr)) != EOK) {
RPC_LOG_ERROR("sockaddr_in memset failed");
return ERR_FAILED;
}
addr->sin_family = AF_INET;
int rc = inet_pton(AF_INET, localIP, &addr->sin_addr);
if (rc <= 0) {
RPC_LOG_ERROR("inet_pton rc=%d", rc);
return ERR_FAILED;
}
addr->sin_port = htons(port);
errno = 0;
rc = bind(fd, (struct sockaddr *)addr, sizeof(*addr));
if (rc < 0) {
RPC_LOG_ERROR("bind fd=%d,rc=%d", fd, rc);
return ERR_FAILED;
}
return ERR_NONE;
}
static void TcpShutDown(int fd)
{
if (fd >= 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
}
}
static void HandleAccept(void *args)
{
if (args == NULL) {
return;
}
int32_t clientFd = *(int32_t *)args;
int32_t ret;
if (g_callback.OnConnected != NULL) {
ret = g_callback.OnConnected(clientFd, 0);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("g_callback OnConnected failed");
return;
}
}
char buf[DEFAULT_PACKET_SIZE];
if (g_callback.OnRecieved != NULL) {
for (;;) {
ssize_t readLen = read(clientFd, buf, DEFAULT_PACKET_SIZE);
if (readLen == 0) {
RPC_LOG_INFO("client socket close");
g_callback.OnDisconnected(clientFd);
TcpShutDown(clientFd);
return;
}
if (readLen < 0) {
RPC_LOG_ERROR("socket read error=%d", readLen);
TcpShutDown(clientFd);
return;
}
ret = g_callback.OnRecieved(clientFd, (void *)buf, (uint32_t)readLen);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("g_callback OnRecieved failed");
return;
}
}
}
}
static void OpenTcpServerSocket(void *args)
{
if (args == NULL) {
return;
}
char *ip = (char *)SOCKET_SERVER_ADDR;
uint16_t port = Hash((char *)args);
errno = 0;
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
RPC_LOG_ERROR("fd=%d", fd);
return;
}
struct sockaddr_in addr;
int32_t ret = BindLocalIP(fd, ip, port, &addr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("BindLocalIP ret=%d", ret);
TcpShutDown(fd);
return;
}
if (listen(fd, DEFAULT_BACKLOG) != 0) {
RPC_LOG_ERROR("listen failed");
TcpShutDown(fd);
return;
}
g_serverCreated = 0;
for (;;) {
socklen_t len = sizeof(addr);
int32_t clientFd = accept(fd, (struct sockaddr *)&addr, &len);
pthread_t threadId;
pthread_create(&threadId, NULL, HandleAccept, (void *)&clientFd);
pthread_detach(threadId);
}
}
static int32_t StartListen(const char *SaSessionName, void *cb)
{
if (g_serverCreated == 0) {
return ERR_NONE;
}
RPC_LOG_INFO("StartListen called");
if (SaSessionName == NULL) {
RPC_LOG_ERROR("SaSessionName is null");
return ERR_FAILED;
}
if (memcpy_s(&g_callback, sizeof(TransCallback), cb, sizeof(TransCallback)) != EOK) {
RPC_LOG_ERROR("g_callback memcpy_s failed");
return ERR_FAILED;
}
pthread_t threadId;
pthread_create(&threadId, NULL, OpenTcpServerSocket, (void *)SaSessionName);
pthread_detach(threadId);
return ERR_NONE;
}
static int32_t StopListen(const char *SaSessionName)
{
return ERR_NONE;
}
static void HandleSendReply(void *args)
{
if (args == NULL) {
RPC_LOG_ERROR("HandleSendReply args is null");
return;
}
int32_t fd = *(int32_t *)args;
free(args);
char buf[DEFAULT_PACKET_SIZE];
if (g_callback.OnRecieved != NULL) {
for (;;) {
ssize_t readLen = read(fd, buf, DEFAULT_PACKET_SIZE);
if (readLen == 0) {
RPC_LOG_INFO("HandleSendReply received len %d", readLen);
g_callback.OnDisconnected(fd);
TcpShutDown(fd);
return;
}
if (readLen < 0) {
RPC_LOG_ERROR("HandleSendReply received len %d", readLen);
TcpShutDown(fd);
return;
}
g_callback.OnRecieved(fd, buf, readLen);
}
}
}
static int32_t Connect(const char *SaSessionName, const char *peerDeviceId, void *args)
{
if (SaSessionName == NULL) {
RPC_LOG_INFO("SaSessionName is null");
return ERR_FAILED;
}
uint16_t port = Hash(SaSessionName);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
RPC_LOG_ERROR("%s:%d:fd=%d", __func__, __LINE__, fd);
return ERR_FAILED;
}
struct sockaddr_in addr;
if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
RPC_LOG_ERROR("memset failed");
}
addr.sin_family = AF_INET;
inet_pton(AF_INET, peerDeviceId, &addr.sin_addr);
addr.sin_port = htons(port);
errno = 0;
int rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
if ((rc == -1) && (errno != EINPROGRESS)) {
RPC_LOG_ERROR("fd=%d,connect rc=%d, errno=%d", fd, rc, errno);
TcpShutDown(fd);
return ERR_FAILED;
}
int32_t *sessionId = (int32_t *)malloc(sizeof(int32_t));
if (sessionId == NULL) {
return ERR_FAILED;
}
*sessionId = fd;
pthread_t threadId;
pthread_create(&threadId, NULL, HandleSendReply, (void *)sessionId);
pthread_detach(threadId);
return fd;
}
static int32_t Disconnect(int32_t sessionId)
{
return ERR_NONE;
}
static int32_t Send(int32_t sessionId, const void *data, uint32_t len)
{
if (sessionId < 0 || data == NULL || len <= 0) {
RPC_LOG_ERROR("send invail params");
return ERR_FAILED;
}
ssize_t ret = write(sessionId, data, len);
if (ret < 0) {
RPC_LOG_ERROR("send error=%d", ret);
return ERR_FAILED;
}
return ERR_NONE;
}
static TransInterface g_socketTrans = {
.StartListen = StartListen,
.StopListen = StopListen,
.Connect = Connect,
.Disconnect = Disconnect,
.Send = Send
};
TransInterface *GetSocketTrans(void)
{
if (g_init == -1) {
pthread_mutex_lock(&g_socketNodeList.mutex);
UtilsListInit(&g_socketNodeList.list);
g_init = 0;
pthread_mutex_unlock(&g_socketNodeList.mutex);
}
return &g_socketTrans;
}
char *GetSocketLocalDeviceID(void)
{
if (g_localDeviceId != NULL) {
return g_localDeviceId;
}
struct ifaddrs *ifaddr;
struct ifaddrs *ifa;
int family;
if (getifaddrs(&ifaddr) == -1) {
RPC_LOG_ERROR("getifaddrs failed");
freeifaddrs(ifaddr);
return NULL;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr != NULL) {
family = ifa->ifa_addr->sa_family;
if (family != AF_INET || strcmp(ifa->ifa_name, DEFAULT_NET_INTERFACE) != 0) {
continue;
}
char *localDeviceId = inet_ntoa(((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
if (localDeviceId == NULL) {
RPC_LOG_ERROR("GetSocketLocalDeviceID inet_ntoa get null");
break;
}
size_t deviceIdLen = strlen(localDeviceId);
if (deviceIdLen == 0 || deviceIdLen > DEVICEID_LENGTH) {
RPC_LOG_ERROR("deviceIdLen invalid");
break;
}
g_localDeviceId = (char *)malloc(deviceIdLen + 1);
if (g_localDeviceId == NULL) {
RPC_LOG_ERROR("g_localDeviceId malloc failed");
break;
}
if (strcpy_s(g_localDeviceId, deviceIdLen + 1, localDeviceId) != EOK) {
RPC_LOG_ERROR("g_localDeviceId strcpy failed");
} else {
RPC_LOG_INFO("GetSocketLocalDeviceID %s", g_localDeviceId);
}
break;
}
}
freeifaddrs(ifaddr);
return g_localDeviceId;
}
\ 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.
*/
#ifndef OHOS_RPC_DBINDER_STUB_H
#define OHOS_RPC_DBINDER_STUB_H
#include <stdint.h>
#include <stdlib.h>
#include "dbinder_types.h"
#include "serializer.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
UTILS_DL_LIST list;
char serviceName[SERVICENAME_LENGTH + 1];
char deviceID[DEVICEID_LENGTH + 1];
uintptr_t binderObject;
SvcIdentity svc;
} DBinderServiceStub;
int32_t GetDBinderStub(const char *serviceName, const char *deviceID,
uintptr_t binderObject, DBinderServiceStub *dBinderServiceStub);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_DBINDER_STUB_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.
*/
#ifndef OHOS_RPC_DBINDER_RTANS_CALLBACK_H
#define OHOS_RPC_DBINDER_RTANS_CALLBACK_H
#include <stdint.h>
#include <stdlib.h>
#include "rpc_trans.h"
#include "dbinder_service.h"
#ifdef __cplusplus
extern "C" {
#endif
TransCallback *GetDBinderTransCallback(void);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_DBINDER_RTANS_CALLBACK_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.
*/
#ifndef OHOS_RPC_DBINDER_TYPES_H
#define OHOS_RPC_DBINDER_TYPES_H
#include <stdint.h>
#include "utils_list.h"
#include "serializer.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEVICEID_LENGTH 64
#define SERVICENAME_LENGTH 200
#define VERSION_NUM 1
#define SESSION_NAME_LEGNTH 8
#define RPC_IPC_LENGTH 128
#define RPC_IPC_LENGTH_LONG 256
#define GET_SYSTEM_ABILITY_TRANSACTION 1
#define ID_DIGITS 10
#define DEFAULT_SEND_WAIT_TIME 4
enum DBinderCode {
MESSAGE_AS_INVOKER = 1,
MESSAGE_AS_REPLY = 2,
MESSAGE_AS_OBITUARY = 3,
};
enum AfType {
IPV4_TYPE = 1,
IPV6_TYPE = 2,
DATABBUS_TYPE = 3,
};
enum {
DATABUS_TYPE
};
struct DeviceIdInfo {
uint16_t afType;
uint16_t reserved;
char fromDeviceId[DEVICEID_LENGTH + 1];
char toDeviceId[DEVICEID_LENGTH + 1];
};
struct DHandleEntryHead {
uint32_t len;
uint32_t version;
};
typedef struct {
UTILS_DL_LIST list;
uint32_t type;
uint16_t toPort;
uint16_t fromPort;
uint64_t stubIndex;
uint32_t socketFd;
char serviceName[SERVICENAME_LENGTH + 1];
struct DeviceIdInfo deviceIdInfo;
uintptr_t stub;
} SessionInfo;
typedef struct {
UTILS_DL_LIST list;
uintptr_t binderObject;
SvcIdentity *proxy;
char *sessionName;
uint32_t cbId;
} ProxyObject;
typedef struct {
uint32_t sizeOfSelf;
uint32_t magic;
uint32_t version;
int cmd;
uint32_t code;
uint32_t flags;
uint64_t cookie;
uint64_t seqNumber;
size_t buffer_size;
size_t offsets_size;
uintptr_t offsets;
char *buffer;
} dbinder_transaction_data;
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_DBINDER_TYPES_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.
*/
#ifndef OHOS_RPC_DBINDER_IPC_ADAPTER_H
#define OHOS_RPC_DBINDER_IPC_ADAPTER_H
#include <stdint.h>
#include <stdbool.h>
#include "dbinder_stub.h"
#include "dbinder_types.h"
#ifdef __cplusplus
extern "C" {
#endif
bool IsSameStub(DBinderServiceStub *stub, const char *serviceName,
const char *deviceID, uintptr_t binderObject);
int32_t GetDBinderHandle(uintptr_t stubAddr);
int32_t UpdateSessionIfNeed(uintptr_t stubAddr);
ProxyObject *RpcGetSystemAbility(int32_t systemAbility);
#ifdef __cplusplus
}
#endif
#endif // OHOS_RPC_DBINDER_IPC_ADAPTER_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 "dbinder_ipc_adapter.h"
#include "securec.h"
#include "ipc_proxy_inner.h"
#include "rpc_errno.h"
#include "rpc_log.h"
#include "rpc_mini_samgr.h" // samgr refactory needed in mini system
bool IsSameStub(DBinderServiceStub *stub, const char *serviceName,
const char *deviceID, uintptr_t binderObject)
{
return false;
}
int32_t GetDBinderHandle(uintptr_t stubAddr)
{
return (int32_t)stubAddr;
}
int32_t UpdateSessionIfNeed(uintptr_t stubAddr)
{
UpdateProto((int32_t)stubAddr);
return ERR_NONE;
}
ProxyObject *RpcGetSystemAbility(int32_t systemAbility)
{
SvcIdentity *target = GetSystemAbilityById(systemAbility);
if (target == NULL) {
RPC_LOG_ERROR("GetSystemAbilityById return null");
return NULL;
}
ProxyObject *proxyObject = (ProxyObject *)calloc(1, sizeof(ProxyObject));
if (proxyObject == NULL) {
return NULL;
}
proxyObject->proxy = (SvcIdentity *)malloc(sizeof(SvcIdentity));
if (proxyObject->proxy == NULL) {
free(proxyObject);
return NULL;
}
if (memcpy_s(proxyObject->proxy, sizeof(SvcIdentity), target, sizeof(SvcIdentity)) != EOK) {
free(proxyObject->proxy);
free(proxyObject);
return NULL;
}
return proxyObject;
}
\ 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 "dbinder_ipc_adapter.h"
#include <pthread.h>
#include <string.h>
#include "securec.h"
#include "ipc_skeleton.h"
#include "rpc_log.h"
#include "rpc_errno.h"
#define IPC_STUB_HANDLE (-1)
bool IsSameStub(DBinderServiceStub *stub, const char *serviceName,
const char *deviceID, uintptr_t binderObject)
{
if (stub == NULL) {
return false;
}
return (strcmp(stub->serviceName, serviceName) == 0 && strcmp(stub->deviceID, deviceID) == 0
&& stub->binderObject == binderObject);
}
int32_t GetDBinderHandle(uintptr_t stubAddr)
{
return IPC_STUB_HANDLE;
}
int32_t UpdateSessionIfNeed(uintptr_t stubAddr)
{
return ERR_NONE;
}
ProxyObject *RpcGetSystemAbility(int32_t systemAbility)
{
IpcIo data;
uint8_t tmpData[RPC_IPC_LENGTH];
IpcIoInit(&data, tmpData, RPC_IPC_LENGTH, 0);
RPC_LOG_INFO("GetSystemAbility systemAbility %d", systemAbility);
WriteInt32(&data, systemAbility);
IpcIo reply;
MessageOption option = TF_OP_SYNC;
RPC_LOG_INFO("get system ability from samgr");
uintptr_t ptr;
int32_t ret = SendRequest(*GetContextObject(), GET_SYSTEM_ABILITY_TRANSACTION, &data, &reply, option, &ptr);
if (ret != ERR_NONE) {
RPC_LOG_ERROR("GetSystemAbility failed");
FreeBuffer((void *)ptr);
return NULL;
}
SvcIdentity svc;
ReadRemoteObject(&reply, &svc);
ProxyObject *proxyObject = (ProxyObject *)malloc(sizeof(ProxyObject));
if (proxyObject == NULL) {
FreeBuffer((void *)ptr);
return NULL;
}
proxyObject->proxy = (SvcIdentity *)malloc(sizeof(SvcIdentity));
if (proxyObject->proxy == NULL) {
free(proxyObject);
FreeBuffer((void *)ptr);
return NULL;
}
if (memcpy_s(proxyObject->proxy, sizeof(SvcIdentity), &svc, sizeof(SvcIdentity)) != EOK) {
free(proxyObject->proxy);
free(proxyObject);
FreeBuffer((void *)ptr);
return NULL;
}
FreeBuffer((void *)ptr);
return proxyObject;
}
\ 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 "dbinder_stub.h"
#include <stdbool.h>
#include <pthread.h>
#include "rpc_log.h"
#include "rpc_errno.h"
#include "securec.h"
#include "ipc_thread_pool.h"
#include "ipc_skeleton.h"
#include "ipc_process_skeleton.h"
#include "dbinder_service.h"
#include "dbinder_ipc_adapter.h"
static int32_t GetDigits(int32_t number)
{
int32_t n = 0;
while (number > 0) {
n++;
number /= ID_DIGITS;
}
if (n == 0) {
n++;
}
return n;
}
static char *CreateDatabusName(void)
{
int32_t pid = (int32_t)GetCallingPid();
int32_t pidLen = GetDigits(pid);
int32_t uid = (int32_t)GetCallingUid();
int32_t uidLen = GetDigits(uid);
uint32_t sessionNameLen = SESSION_NAME_LEGNTH + pidLen + uidLen;
char *sessionName = (char *)malloc(sessionNameLen + 1);
if (sessionName == NULL) {
RPC_LOG_ERROR("sessionName mallo failed");
return NULL;
}
if (sprintf_s(sessionName, sessionNameLen + 1, "DBinder%d_%d", uid, pid) == -1) {
RPC_LOG_ERROR("sessionName sprintf failed");
free(sessionName);
return NULL;
}
return sessionName;
}
static int32_t ProcessProto(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption *option)
{
int32_t result = ERR_NONE;
ThreadContext *threadContext = GetCurrentThreadContext();
if (threadContext == NULL) {
RPC_LOG_ERROR("ProcessProto threadContext is null");
return ERR_FAILED;
}
SessionInfo *session = QuerySessionObject((uintptr_t)threadContext->objectStub);
if (session == NULL) {
RPC_LOG_ERROR("client find session is null");
return ERR_FAILED;
}
const char *localBusName = CreateDatabusName();
if (localBusName == NULL) {
RPC_LOG_ERROR("ProcessProto CreateDatabusName failed");
return ERR_FAILED;
}
switch (session->type) {
case DATABUS_TYPE: {
WriteUint32(reply, IF_PROT_DATABUS);
WriteUint64(reply, session->stubIndex);
WriteString(reply, session->serviceName);
WriteString(reply, session->deviceIdInfo.toDeviceId);
WriteString(reply, session->deviceIdInfo.fromDeviceId);
WriteString(reply, localBusName);
free((void *)localBusName);
break;
}
default: {
result = ERR_FAILED;
break;
}
}
return result;
}
static int32_t DBinderRemoteRequest(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption *option)
{
int32_t ret = 0;
switch (code) {
case GET_PROTO_INFO: {
ret = ProcessProto(code, data, reply, option);
break;
}
default: {
RPC_LOG_ERROR("unknown dbinder code %{public}d", code);
ret = -1;
break;
}
}
return ret;
}
int32_t GetDBinderStub(const char *serviceName, const char *deviceID,
uintptr_t binderObject, DBinderServiceStub *dBinderServiceStub)
{
if (strcpy_s(dBinderServiceStub->serviceName, SERVICENAME_LENGTH, serviceName) != EOK
|| strcpy_s(dBinderServiceStub->deviceID, DEVICEID_LENGTH, deviceID) != EOK) {
RPC_LOG_ERROR("dBinderServiceStub string copy failed");
return ERR_FAILED;
}
IpcObjectStub *objectStub = (IpcObjectStub *)malloc(sizeof(IpcObjectStub));
if (objectStub == NULL) {
RPC_LOG_ERROR("objectStub malloc failed");
return ERR_FAILED;
}
objectStub->func = (OnRemoteRequest)DBinderRemoteRequest;
objectStub->isRemote = true;
dBinderServiceStub->binderObject = binderObject;
dBinderServiceStub->svc.handle = GetDBinderHandle((uintptr_t)objectStub);
dBinderServiceStub->svc.token = (uintptr_t)objectStub;
dBinderServiceStub->svc.cookie = (uintptr_t)objectStub;
return ERR_NONE;
}
\ No newline at end of file
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册