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_session.h"
17
18 #include <cinttypes>
19 #include <sstream>
20
21 #include <fcntl.h>
22 #include <sys/types.h>
23 #include <sys/un.h>
24 #include <unistd.h>
25
26 #include "devicestatus_define.h"
27 #include "devicestatus_proto.h"
28 #include "stream_socket.h"
29
30 #undef LOG_TAG
31 #define LOG_TAG "StreamSession"
32
33 namespace OHOS {
34 namespace Msdp {
35 namespace DeviceStatus {
36 namespace {
37 const std::string FOUNDATION { "foundation" };
38 } // namespace
39
StreamSession(const std::string & programName,int32_t moduleType,int32_t fd,int32_t uid,int32_t pid)40 StreamSession::StreamSession(const std::string &programName, int32_t moduleType, int32_t fd, int32_t uid, int32_t pid)
41 : fd_(fd), pid_(pid)
42 {}
43
SendMsg(const char * buf,size_t size) const44 bool StreamSession::SendMsg(const char *buf, size_t size) const
45 {
46 CHKPF(buf);
47 if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
48 FI_HILOGE("buf size:%{public}zu", size);
49 return false;
50 }
51 if (fd_ < 0) {
52 FI_HILOGE("The fd_ is less than 0");
53 return false;
54 }
55
56 int32_t idx = 0;
57 int32_t retryCount = 0;
58 const int32_t bufSize = static_cast<int32_t>(size);
59 int32_t remSize = bufSize;
60 while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
61 retryCount += 1;
62 ssize_t count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
63 if (count < 0) {
64 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
65 usleep(SEND_RETRY_SLEEP_TIME);
66 FI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno);
67 continue;
68 }
69 FI_HILOGE("Send return failed, error:%{public}d, fd:%{public}d", errno, fd_);
70 return false;
71 }
72 idx += count;
73 remSize -= count;
74 if (remSize > 0) {
75 usleep(SEND_RETRY_SLEEP_TIME);
76 }
77 }
78 if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
79 FI_HILOGE("Send too many times:%{public}d/%{public}d, size:%{public}d/%{public}d, fd:%{public}d",
80 retryCount, SEND_RETRY_LIMIT, idx, bufSize, fd_);
81 return false;
82 }
83 return true;
84 }
85
Close()86 void StreamSession::Close()
87 {
88 CALL_DEBUG_ENTER;
89 FI_HILOGD("Enter fd_:%{public}d", fd_);
90 if (fd_ >= 0) {
91 if (close(fd_) < 0) {
92 FI_HILOGE("Close fd failed, error:%{public}s, fd_:%{public}d", strerror(errno), fd_);
93 }
94 fd_ = -1;
95 }
96 }
97
SendMsg(NetPacket & pkt) const98 bool StreamSession::SendMsg(NetPacket &pkt) const
99 {
100 if (pkt.ChkRWError()) {
101 FI_HILOGE("Read and write status is error");
102 return false;
103 }
104 StreamBuffer buf;
105 if (!pkt.MakeData(buf)) {
106 FI_HILOGE("Failed to buffer packet");
107 return false;
108 }
109 return SendMsg(buf.Data(), buf.Size());
110 }
111 } // namespace DeviceStatus
112 } // namespace Msdp
113 } // namespace OHOS