1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mmi_fd_listener.h"
17
18 #include <cinttypes>
19
20 #include "config_multimodal.h"
21 #include "mmi_log.h"
22 #include "stream_buffer.h"
23 #include "uds_socket.h"
24
25 #undef MMI_LOG_TAG
26 #define MMI_LOG_TAG "MMIFdListener"
27
28 namespace OHOS {
29 namespace MMI {
30 using namespace AppExecFwk;
MMIFdListener(MMIClientPtr client)31 MMIFdListener::MMIFdListener(MMIClientPtr client) : mmiClient_(client)
32 {
33 CALL_DEBUG_ENTER;
34 }
35
OnReadable(int32_t fd)36 void MMIFdListener::OnReadable(int32_t fd)
37 {
38 if (fd < 0) {
39 MMI_HILOGE("Invalid fd:%{public}d", fd);
40 return;
41 }
42 CHKPV(mmiClient_);
43 char szBuf[MAX_PACKET_BUF_SIZE] = {};
44 ssize_t recvSize = 0;
45 bool shouldTry = true;
46 while (shouldTry) {
47 ssize_t oneRecvSize = 0;
48 while (oneRecvSize < MAX_PACKET_BUF_SIZE) {
49 ssize_t size = recv(fd, szBuf + oneRecvSize, MAX_PACKET_BUF_SIZE - oneRecvSize,
50 MSG_DONTWAIT | MSG_NOSIGNAL);
51 if (size > 0) {
52 recvSize += size;
53 oneRecvSize += size;
54 continue;
55 }
56
57 // size 0 means it the fd may be closed.
58 if (size == 0) {
59 shouldTry = false;
60 MMI_HILOGE("received %{public}zu, now received 0 from fd %{public}d, wait for next readable", recvSize,
61 fd);
62 break;
63 }
64
65 // size < 0 means there is an error occurred, need to handle the error.
66 int32_t recvError = errno;
67 if (recvError == EAGAIN || recvError == EWOULDBLOCK) {
68 shouldTry = false;
69 break;
70 } else if (recvError == EINTR) {
71 MMI_HILOGW("received %{public}zu, fd %{public}d is interrupted by signal, continue to recv", recvSize,
72 fd);
73 continue;
74 } else {
75 shouldTry = false;
76 MMI_HILOGE("received %{public}zu, unexpected errno %{public}d on fd %{public}d, wait for next readable",
77 recvSize, recvError, fd);
78 break;
79 }
80 }
81 if (oneRecvSize > 0) {
82 mmiClient_->OnRecvMsg(szBuf, oneRecvSize);
83 }
84 }
85 }
86
OnShutdown(int32_t fd)87 void MMIFdListener::OnShutdown(int32_t fd)
88 {
89 CHK_PID_AND_TID();
90 if (fd < 0) {
91 MMI_HILOGE("Invalid fd:%{public}d", fd);
92 }
93 CHKPV(mmiClient_);
94 mmiClient_->OnDisconnect();
95 }
96
OnException(int32_t fd)97 void MMIFdListener::OnException(int32_t fd)
98 {
99 CHK_PID_AND_TID();
100 if (fd < 0) {
101 MMI_HILOGE("Invalid fd:%{public}d", fd);
102 }
103 CHKPV(mmiClient_);
104 mmiClient_->OnDisconnect();
105 }
106 } // namespace MMI
107 } // namespace OHOS
108