• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "stream_client.h"
16 
17 #include "util.h"
18 
19 namespace OHOS {
20 namespace Msdp {
21 namespace DeviceStatus {
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "StreamClient" };
24 } // namespace
25 
StreamClient()26 StreamClient::StreamClient()
27 {
28     CALL_DEBUG_ENTER;
29 }
30 
~StreamClient()31 StreamClient::~StreamClient()
32 {
33     CALL_DEBUG_ENTER;
34 }
35 
ConnectTo()36 int32_t StreamClient::ConnectTo()
37 {
38     CALL_DEBUG_ENTER;
39     if (Socket() < 0) {
40         FI_HILOGE("Socket failed");
41         return RET_ERR;
42     }
43     OnConnected();
44     return RET_OK;
45 }
46 
SendMsg(const char * buf,size_t size) const47 bool StreamClient::SendMsg(const char *buf, size_t size) const
48 {
49     CHKPF(buf);
50     if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
51         FI_HILOGE("Stream buffer size out of range");
52         return false;
53     }
54     if (fd_ < 0) {
55         FI_HILOGE("The fd_ is less than 0");
56         return false;
57     }
58 
59     int32_t idx = 0;
60     int32_t retryCount = 0;
61     const int32_t bufSize = static_cast<int32_t>(size);
62     int32_t remSize = bufSize;
63     while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
64         retryCount += 1;
65         ssize_t count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
66         if (count < 0) {
67             if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
68                 FI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno);
69                 continue;
70             }
71             FI_HILOGE("Send return failed, error:%{public}d, fd:%{public}d", errno, fd_);
72             return false;
73         }
74         idx += count;
75         remSize -= count;
76         if (remSize > 0) {
77             usleep(SEND_RETRY_SLEEP_TIME);
78         }
79     }
80     if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
81         FI_HILOGE("Send too many times:%{public}d/%{public}d, size:%{public}d/%{public}d, fd:%{public}d",
82             retryCount, SEND_RETRY_LIMIT, idx, bufSize, fd_);
83         return false;
84     }
85     return true;
86 }
87 
SendMsg(const NetPacket & pkt) const88 bool StreamClient::SendMsg(const NetPacket &pkt) const
89 {
90     if (pkt.ChkRWError()) {
91         FI_HILOGE("Read and write status is error");
92         return false;
93     }
94     StreamBuffer buf;
95     pkt.MakeData(buf);
96     return SendMsg(buf.Data(), buf.Size());
97 }
98 
StartClient(MsgClientFunCallback fun)99 bool StreamClient::StartClient(MsgClientFunCallback fun)
100 {
101     CALL_DEBUG_ENTER;
102     if (isRunning_ || isConnected_) {
103         FI_HILOGE("Client is connected or started");
104         return false;
105     }
106     hasClient_ = true;
107     recvFun_ = fun;
108     if (ConnectTo() < 0) {
109         FI_HILOGW("Client connection failed, Try again later");
110     }
111     return true;
112 }
113 
Stop()114 void StreamClient::Stop()
115 {
116     CALL_DEBUG_ENTER;
117     hasClient_ = false;
118     Close();
119 }
120 } // namespace DeviceStatus
121 } // namespace Msdp
122 } // namespace OHOS