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