1 /*
2 * Copyright (c) 2021-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 "uds_client.h"
17
18 #include "util.h"
19
20 #undef MMI_LOG_TAG
21 #define MMI_LOG_TAG "UDSClient"
22
23 namespace OHOS {
24 namespace MMI {
UDSClient()25 UDSClient::UDSClient()
26 {
27 CALL_DEBUG_ENTER;
28 }
29
~UDSClient()30 UDSClient::~UDSClient()
31 {
32 CALL_DEBUG_ENTER;
33 }
34
ConnectTo()35 int32_t UDSClient::ConnectTo()
36 {
37 CALL_DEBUG_ENTER;
38 if (Socket() < 0) {
39 MMI_HILOGE("Socket failed");
40 return RET_ERR;
41 }
42 OnConnected();
43 return RET_OK;
44 }
45
SendMsg(const char * buf,size_t size) const46 bool UDSClient::SendMsg(const char *buf, size_t size) const
47 {
48 CHKPF(buf);
49 if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
50 MMI_HILOGE("Stream buffer size out of range");
51 return false;
52 }
53 if (fd_ < 0) {
54 MMI_HILOGE("The fd_ is less than 0");
55 return false;
56 }
57
58 int32_t idx = 0;
59 int32_t retryCount = 0;
60 const int32_t bufSize = static_cast<int32_t>(size);
61 int32_t remSize = bufSize;
62 while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
63 retryCount += 1;
64 auto count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
65 if (count < 0) {
66 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
67 MMI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno);
68 continue;
69 }
70 MMI_HILOGE("Send return failed,error:%{public}d fd:%{public}d", errno, fd_);
71 return false;
72 }
73 idx += count;
74 remSize -= count;
75 if (remSize > 0) {
76 MMI_HILOGW("Remsize:%{public}d", remSize);
77 usleep(SEND_RETRY_SLEEP_TIME);
78 }
79 }
80 if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
81 MMI_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 UDSClient::SendMsg(const NetPacket &pkt) const
89 {
90 if (pkt.ChkRWError()) {
91 MMI_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 UDSClient::StartClient(MsgClientFunCallback fun)
100 {
101 CALL_DEBUG_ENTER;
102 if (isRunning_ || isConnected_) {
103 MMI_HILOGE("Client is connected or started");
104 return false;
105 }
106 isExit = false;
107 recvFun_ = fun;
108 if (ConnectTo() < 0) {
109 MMI_HILOGW("Client connection failed, Try again later");
110 return false;
111 }
112 return true;
113 }
114
Stop()115 void UDSClient::Stop()
116 {
117 CALL_DEBUG_ENTER;
118 isExit = true;
119 isRunning_ = false;
120 Close();
121 }
122 } // namespace MMI
123 } // namespace OHOS