1 /*
2 * Copyright (c) 2022-2023 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 #include "fd_listener.h"
16
17 #include <cinttypes>
18
19 #include "fi_log.h"
20 #include "stream_buffer.h"
21 #include "stream_socket.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "FdListener"
25
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29
30 using namespace AppExecFwk;
FdListener(IClientPtr client)31 FdListener::FdListener(IClientPtr client) : iClient_(client) {}
32
OnReadable(int32_t fd)33 void FdListener::OnReadable(int32_t fd)
34 {
35 if (fd < 0) {
36 FI_HILOGE("Invalid fd:%{public}d", fd);
37 return;
38 }
39 CHKPV(iClient_);
40 char szBuf[MAX_PACKET_BUF_SIZE] = { 0 };
41 for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) {
42 ssize_t size = recv(fd, szBuf, MAX_PACKET_BUF_SIZE, MSG_DONTWAIT | MSG_NOSIGNAL);
43 if (size > 0) {
44 iClient_->OnRecvMsg(szBuf, size);
45 } else if (size < 0) {
46 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
47 FI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, size:%{public}zd, errno:%{public}d",
48 size, errno);
49 continue;
50 }
51 FI_HILOGE("Recv return %{public}zd, errno:%{public}d", size, errno);
52 break;
53 } else {
54 FI_HILOGD("[Do nothing here]The service side disconnect with the client, size:0, count:%{public}d, "
55 "errno:%{public}d", i, errno);
56 break;
57 }
58 if (static_cast<size_t>(size) < MAX_PACKET_BUF_SIZE) {
59 break;
60 }
61 }
62 }
63
OnShutdown(int32_t fd)64 void FdListener::OnShutdown(int32_t fd)
65 {
66 CHK_PID_AND_TID();
67 if (fd < 0) {
68 FI_HILOGE("Invalid fd:%{public}d", fd);
69 }
70 CHKPV(iClient_);
71 iClient_->OnDisconnect();
72 }
73
OnException(int32_t fd)74 void FdListener::OnException(int32_t fd)
75 {
76 CHK_PID_AND_TID();
77 if (fd < 0) {
78 FI_HILOGE("Invalid fd:%{public}d", fd);
79 }
80 CHKPV(iClient_);
81 iClient_->OnDisconnect();
82 }
83 } // namespace DeviceStatus
84 } // namespace Msdp
85 } // namespace OHOS
86