• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "socket_session.h"
17 
18 #include <sstream>
19 
20 #include <sys/socket.h>
21 #include <unistd.h>
22 
23 #include "devicestatus_define.h"
24 #include "devicestatus_proto.h"
25 
26 #undef LOG_TAG
27 #define LOG_TAG "SocketSession"
28 
29 namespace OHOS {
30 namespace Msdp {
31 namespace DeviceStatus {
32 
SocketSession(const std::string & programName,int32_t moduleType,int32_t tokenType,int32_t fd,int32_t uid,int32_t pid)33 SocketSession::SocketSession(const std::string &programName, int32_t moduleType,
34                              int32_t tokenType, int32_t fd, int32_t uid, int32_t pid)
35     : fd_(fd), uid_(uid), pid_(pid), tokenType_(tokenType), programName_(programName)
36 {}
37 
~SocketSession()38 SocketSession::~SocketSession()
39 {
40     if ((fd_ >= 0) && (::close(fd_) != 0)) {
41         FI_HILOGE("close(%{public}d) failed:%{public}s", fd_, ::strerror(errno));
42     }
43 }
44 
SendMsg(NetPacket & pkt) const45 bool SocketSession::SendMsg(NetPacket &pkt) const
46 {
47     if (pkt.ChkRWError()) {
48         FI_HILOGE("Read and write status is error");
49         return false;
50     }
51     StreamBuffer buf;
52     if (!pkt.MakeData(buf)) {
53         FI_HILOGE("Failed to buffer packet");
54         return false;
55     }
56     return SendMsg(buf.Data(), buf.Size());
57 }
58 
SendMsg(const char * buf,size_t size) const59 bool SocketSession::SendMsg(const char *buf, size_t size) const
60 {
61     CHKPF(buf);
62     if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
63         FI_HILOGE("buf size:%{public}zu", size);
64         return false;
65     }
66     if (fd_ < 0) {
67         FI_HILOGE("The fd_ is less than 0");
68         return false;
69     }
70 
71     int32_t idx = 0;
72     int32_t retryCount = 0;
73     const int32_t bufSize = static_cast<int32_t>(size);
74     int32_t remSize = bufSize;
75     FI_HILOGD("Rem size:%{public}d", remSize);
76     while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
77         retryCount += 1;
78         FI_HILOGD("Send message to client (%{public}d, %{public}d)", fd_, pid_);
79         ssize_t count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
80         if (count < 0) {
81             if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
82                 usleep(SEND_RETRY_SLEEP_TIME);
83                 FI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, pid:%{public}d", errno, pid_);
84                 continue;
85             }
86             FI_HILOGE("Send return failed, error:%{public}d, fd:%{public}d, pid:%{public}d", errno, fd_, pid_);
87             return false;
88         }
89         idx += count;
90         remSize -= count;
91         if (remSize > 0) {
92             usleep(SEND_RETRY_SLEEP_TIME);
93         }
94     }
95     if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
96         FI_HILOGE("Send too many times:%{public}d/%{public}d, size:%{public}d/%{public}d, fd:%{public}d,"
97             "pid:%{public}d", retryCount, SEND_RETRY_LIMIT, idx, bufSize, fd_, pid_);
98         return false;
99     }
100     return true;
101 }
102 
ToString() const103 std::string SocketSession::ToString() const
104 {
105     std::ostringstream oss;
106     oss << "fd = " << fd_
107         << ((fd_ < 0) ? ", closed" : ", opened")
108         << ", pid = " << pid_
109         << ", tokenType = " << tokenType_
110         << std::endl;
111     return oss.str();
112 }
113 
Dispatch(const struct epoll_event & ev)114 void SocketSession::Dispatch(const struct epoll_event &ev)
115 {
116     if ((ev.events & EPOLLIN) == EPOLLIN) {
117         FI_HILOGD("Data received (%{public}d)", fd_);
118     } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) {
119         FI_HILOGE("Epoll hangup:%{public}s", ::strerror(errno));
120     }
121 }
122 } // namespace DeviceStatus
123 } // namespace Msdp
124 } // namespace OHOS