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