WiFi C代码Rpc调用
communication\wifi\services\wifi_standard\wifi_framework\wifi_manage\idl_client\idl_interface\i_wifi_sta_iface.c
WifiErrorNo GetSupportFeature(long *feature)
{
RpcClient *client = GetStaRpcClient();
LockRpcClient(client);
Context *context = client->context;
WriteBegin(context, 0);
WriteFunc(context, "GetSupportFeature");
WriteEnd(context);
if (RpcClientCall(client, "GetSupportFeature") != WIFI_IDL_OPT_OK) {
return WIFI_IDL_OPT_FAILED;
}
int result = WIFI_IDL_OPT_FAILED;
ReadInt(context, &result);
if (result == WIFI_IDL_OPT_OK) {
ReadLong(context, feature);
}
ReadClientEnd(client);
UnlockRpcClient(client);
return result;
}
RpcClient* 指针获取
RpcClient *GetStaRpcClient(void)
{
return OHOS::Wifi::WifiStaHalInterface::GetInstance().mIdlClient->pRpcClient;
}
int WifiIdlClient::InitClient(void)
{
const std::string idlSockPath = "/data/misc/wifi/unix_sock.sock";
pRpcClient = CreateRpcClient(idlSockPath.c_str()); // 注:call CreateRpcClient
if (pRpcClient == nullptr) {
LOGE("init rpc client failed!");
return -1;
}
return 0;
}
RpcClient *CreateRpcClient(const char *path)
{
int fd = ConnectUnixServer(path); // 注:call ConnectUnixServer
if (fd < 0) {
return NULL;
}
SetNonBlock(fd, 1);
RpcClient *client = (RpcClient *)calloc(1, sizeof(RpcClient));
if (client == NULL) {
close(fd);
return NULL;
}
client->context = CreateContext(CONTEXT_BUFFER_MIN_SIZE);
if (client->context == NULL) {
close(fd);
free(client);
return NULL;
}
client->context->fd = fd;
client->threadRunFlag = 1;
client->threadId = 0;
client->waitReply = CLIENT_STATE_IDLE;
client->callLockFlag = 0;
pthread_mutex_init(&client->mutex, NULL);
pthread_cond_init(&client->condW, NULL);
pthread_mutex_init(&client->lockMutex, NULL);
pthread_cond_init(&client->lockCond, NULL);
int ret = pthread_create(&client->threadId, NULL, RpcClientThreadDeal, client);
if (ret) {
pthread_cond_destroy(&client->condW);
pthread_mutex_destroy(&client->mutex);
pthread_cond_destroy(&client->lockCond);
pthread_mutex_destroy(&client->lockMutex);
ReleaseContext(client->context);
close(fd);
free(client);
return NULL;
}
signal(SIGPIPE, SIG_IGN);
return client;
}
int ConnectUnixServer(const char *path)
{
struct sockaddr_un sockAddr;
if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
return -1;
}
sockAddr.sun_family = AF_LOCAL;
if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
return -1;
}
int sock = CreateSocket(AF_LOCAL);
if (sock < 0) {
return -1;
}
if (connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) {
LOGE("connect failed!");
close(sock);
return -1;
}
return sock;
}
可见Rpc的调用,本质上是创建了一个socket。
int RemoteCall(RpcClient *client)
{
if (client == NULL) {
return -1;
}
if (client->waitReply == CLIENT_STATE_EXIT) {
return -1;
}
int ret = 0;
Context *context = client->context;
while (context->wBegin != context->wEnd && ret >= 0) {
ret = ContextWriteNet(context); // 注:call ContextWriteNet
}
if (ret < 0) {
return ret;
}
ret = 0; /* reset ret value */
pthread_mutex_lock(&client->mutex);
while (client->waitReply != CLIENT_STATE_DEAL_REPLY && client->waitReply != CLIENT_STATE_EXIT) {
pthread_cond_wait(&client->condW, &client->mutex);
}
if (client->waitReply == CLIENT_STATE_EXIT) {
ret = -1;
}
pthread_mutex_unlock(&client->mutex);
return ret;
}
int ContextWriteNet(Context *context)
{
if (context == NULL) {
return -1;
}
if (context->wBegin == context->wEnd) {
return 0;
}
if (context->wBegin < context->wEnd) {
int ret = MyWrite(context->fd, context->szWrite + context->wBegin, context->wEnd - context->wBegin);
if (ret > 0) {
context->wBegin += ret;
}
return ret;
}
int len = context->wCapacity - context->wBegin;
int ret = MyWrite(context->fd, context->szWrite + context->wBegin, len); // 注:call MyWrite
if (ret < 0) {
return ret;
}
if (ret < len) {
context->wBegin += ret;
return ret;
}
context->wBegin = 0;
ret = MyWrite(context->fd, context->szWrite, context->wEnd);
if (ret > 0) {
context->wBegin = ret;
}
return ret;
}
int MyWrite(int fd, const char *buf, int count)
{
int pos = 0;
while (count > 0) {
int ret = write(fd, buf + pos, count);
if (ret == 0) {
return SOCK_CLOSE;
} else if (ret < 0) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
break;
} else {
LOGE("write failed! error is %{public}d", errno);
return SOCK_ERR;
}
}
#ifdef DEBUG
int tmpSize = ret + 1;
char *szTmp = (char *)calloc(tmpSize, sizeof(char));
if (szTmp != NULL) {
if (strncpy_s(szTmp, tmpSize, buf + pos, ret) == EOK) {
LOGD("write: %{private}s", szTmp);
}
free(szTmp);
}
#endif
pos += ret;
count -= ret;
}
return pos;
}
可见Rpc调用就是写socket。
int main(void)
{
char rpcSockPath[] = "/data/misc/wifi/unix_sock.sock";
if (access(rpcSockPath, 0) == 0) {
unlink(rpcSockPath);
}
if (InitRpcFunc() < 0) { // 注:初始化Rpc函数表
LOGE("Init Rpc Function failed!");
return -1;
}
RpcServer *server = CreateRpcServer(rpcSockPath); // 注:创建Rpc服务
if (server == NULL) {
LOGE("Create RPC Server by %{public}s failed!", rpcSockPath);
return -1;
}
SetRpcServerInited(server);
setvbuf(stdout, NULL, _IOLBF, 0);
signal(SIGINT, SignalExit);
signal(SIGTERM, SignalExit);
signal(SIGPIPE, SIG_IGN);
RunRpcLoop(server); // 注:进入Rpc消息循环
/* stop wpa_supplicant, hostapd, and other resources */
ForceStop();
StopSoftAp();
P2pForceStop();
ReleaseWifiHalVendorInterface();
/* clear RPC Server */
SetRpcServerInited(NULL);
ReleaseRpcServer(server);
ReleaseRpcFunc();
LOGI("hal service exists!");
return 0;
}
从代码逻辑看,wifi_hal进程起来后初始化函数表,然后建立socket连接,并进入消息循环,处理接收到的Rpc socket消息
一、初始化函数表
int InitRpcFunc(void)
{
if (g_rpcFuncHandle != NULL) {
return 0;
}
g_rpcFuncHandle = (WifiHalRpcFunc *)calloc(RPC_FUNC_NUM, sizeof(WifiHalRpcFunc));
if (g_rpcFuncHandle == NULL) {
return -1;
}
int ret = 0;
ret += InitRpcFuncMapBase();
ret += InitRpcFuncMapChip();
ret += InitRpcFuncMapSupplicant();
ret += InitRpcFuncMapSta();
ret += InitRpcFuncMapAp();
ret += InitRpcFuncMapCommon();
ret += InitRpcFuncMapP2p();
if (ret < 0) {
return -1;
}
if (InitCallbackMsg() < 0) {
return -1;
}
return 0;
}
static int InitRpcFuncMapSta(void)
{
int ret = 0;
ret += PushRpcFunc("Start", RpcStart);
ret += PushRpcFunc("Stop", RpcStop);
ret += PushRpcFunc("StartScan", RpcStartScan);
ret += PushRpcFunc("GetScanInfos", RpcGetScanInfos);
ret += PushRpcFunc("StartPnoScan", RpcStartPnoScan);
ret += PushRpcFunc("StopPnoScan", RpcStopPnoScan);
ret += PushRpcFunc("Connect", RpcConnect);
ret += PushRpcFunc("Reconnect", RpcReconnect);
ret += PushRpcFunc("Reassociate", RpcReassociate);
ret += PushRpcFunc("Disconnect", RpcDisconnect);
ret += PushRpcFunc("GetStaCapabilities", RpcGetStaCapabilities);
ret += PushRpcFunc("GetDeviceMacAddress", RpcGetDeviceMacAddress);
ret += PushRpcFunc("GetFrequencies", RpcGetFrequencies);
ret += PushRpcFunc("SetAssocMacAddr", RpcSetAssocMacAddr);
ret += PushRpcFunc("SetScanningMacAddress", RpcSetScanningMacAddress);
ret += PushRpcFunc("DeauthLastRoamingBssid", RpcDeauthLastRoamingBssid);
ret += PushRpcFunc("GetSupportFeature", RpcGetSupportFeature);
ret += PushRpcFunc("RunCmd", RpcRunCmd);
ret += PushRpcFunc("SetWifiTxPower", RpcSetWifiTxPower);
ret += PushRpcFunc("RemoveNetwork", RpcRemoveNetwork);
ret += PushRpcFunc("AddNetwork", RpcAddNetwork);
ret += PushRpcFunc("EnableNetwork", RpcEnableNetwork);
ret += PushRpcFunc("DisableNetwork", RpcDisableNetwork);
ret += PushRpcFunc("SetNetwork", RpcSetNetwork);
ret += PushRpcFunc("SaveNetworkConfig", RpcSaveNetworkConfig);
ret += PushRpcFunc("StartWpsPbcMode", RpcStartWpsPbcMode);
ret += PushRpcFunc("StartWpsPinMode", RpcStartWpsPinMode);
ret += PushRpcFunc("StopWps", RpcStopWps);
ret += PushRpcFunc("GetRoamingCapabilities", RpcGetRoamingCapabilities);
ret += PushRpcFunc("SetRoamConfig", RpcSetRoamConfig);
ret += PushRpcFunc("WpaGetNetwork", RpcWpaGetNetwork);
ret += PushRpcFunc("WpaAutoConnect", RpcWpaAutoConnect);
ret += PushRpcFunc("WpaBlocklistClear", RpcWpaBlocklistClear);
ret += PushRpcFunc("GetNetworkList", RpcGetNetworkList);
ret += PushRpcFunc("GetConnectSignalInfo", RpcGetConnectSignalInfo);
return ret;
}
二、建立Socket通信
RpcServer *CreateRpcServer(const char *path)
{
if (path == NULL) {
return NULL;
}
RpcServer *server = (RpcServer *)calloc(1, sizeof(RpcServer));
if (server == NULL) {
return NULL;
}
int flag = 1;
do {
int ret = CreateUnixServer(path, DEFAULT_LISTEN_QUEUE_SIZE); // 注: call CreateUnixServer,建立socket通信
if (ret < 0) {
break;
}
server->listenFd = ret;
server->loop = CreateEventLoop(MAX_SUPPORT_CLIENT_FD_SIZE);
if (server->loop == NULL) {
break;
}
server->clients = InitHashTable(DEFAULT_HASHTABLE_SLOTS);
if (server->clients == NULL) {
break;
}
if (AddFdEvent(server->loop, server->listenFd, READ_EVENT) < 0) {
break;
}
pthread_mutex_init(&server->mutex, NULL);
flag = 0;
} while (0);
if (flag) {
ReleaseRpcServer(server);
return NULL;
}
return server;
}
int CreateUnixServer(const char *path, int backlog)
{
struct sockaddr_un sockAddr;
if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
return -1;
}
sockAddr.sun_family = AF_LOCAL;
if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
return -1;
}
int sock = CreateSocket(AF_LOCAL);
if (sock < 0) {
return -1;
}
int keepAlive = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
int reuseaddr = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, sizeof(reuseaddr));
if (bind(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) {
LOGE("bind failed!");
close(sock);
return -1;
}
if (SetNonBlock(sock, 1) != 0) {
LOGE("set socket non block failed!");
close(sock);
return -1;
}
fcntl(sock, F_SETFD, FD_CLOEXEC);
if (listen(sock, backlog) < 0) {
LOGE("listen failed!");
close(sock);
return -1;
}
return sock;
}
三、进行事件循环
int RunRpcLoop(RpcServer *server)
{
if (server == NULL) {
return -1;
}
EventLoop *loop = server->loop;
while (!loop->stop) {
BeforeLoop(server);
int retval = epoll_wait(loop->epfd, loop->epEvents, loop->setSize, 1); /* wait 1ms */
for (int i = 0; i < retval; ++i) {
struct epoll_event *e = loop->epEvents + i;
int fd = e->data.fd;
unsigned int mask = CheckEventMask(e);
if (fd == server->listenFd) {
OnAccept(server, mask);
} else {
DealFdEvents(server, fd, mask);
}
}
}
return 0;
}
int RpcGetSupportFeature(RpcServer *server, Context *context)
{
if (server == NULL || context == NULL) {
return -1;
}
long feature = 0;
WifiErrorNo err = GetSupportFeature(&feature);
WriteBegin(context, 0);
WriteInt(context, err);
if (err == WIFI_HAL_SUCCESS) {
WriteLong(context, feature);
}
WriteEnd(context);
return 0;
}
因此,Rpc正是依靠socket实现了跨进程收发,发送方将数据打包进数据包,然后写入和目标方建立的socket通道,目标方在进程启动时进入消息循环读取数据,如果有数据过来,读取到数据解析后转发给对应的函数进行处理。
学到了,感谢分享
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
06-20 10:09:32.693 1041 1041 E 01560/WifiHalService: Create RPC Server by /data/misc/wifi/unix_sock.sock failed!
06-20 10:09:34.011 1106 1106 E 00000/WifiRpcNet: bind failed!
06-20 10:09:34.011 1106 1106 E 01560/WifiHalService: Create RPC Server by /data/misc/wifi/unix_sock.sock failed!
这种socket创建fail可能是啥原因呢?
一般是权限原因的可能性大一些。比如目录权限等,进程启动账号等
登录 后才可以发表评论