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_connection.h" 17 18#include <sys/socket.h> 19#include <unistd.h> 20 21#include "devicestatus_define.h" 22#include "include/util.h" 23 24#undef LOG_TAG 25#define LOG_TAG "SocketConnection" 26 27namespace OHOS { 28namespace Msdp { 29namespace DeviceStatus { 30 31SocketConnection::SocketConnection(int32_t socketFd, 32 std::function<void(NetPacket&)> recv, 33 std::function<void()> onDisconnected) 34 : socketFd_(socketFd), recv_(recv), onDisconnected_(onDisconnected) 35{} 36 37SocketConnection::~SocketConnection() 38{ 39 if ((socketFd_ >= 0) && (::close(socketFd_) != 0)) { 40 FI_HILOGE("close(%{public}d) failed:%{public}s", socketFd_, ::strerror(errno)); 41 } 42} 43 44std::shared_ptr<SocketConnection> SocketConnection::Connect(std::function<int32_t()> socket, 45 std::function<void(NetPacket&)> recv, std::function<void()> onDisconnected) 46{ 47 CALL_DEBUG_ENTER; 48 CHKPP(socket); 49 int32_t sockFd = socket(); 50 if (sockFd < 0) { 51 return nullptr; 52 } 53 return std::make_shared<SocketConnection>(sockFd, recv, onDisconnected); 54} 55 56void SocketConnection::OnReadable(int32_t fd) 57{ 58 CALL_DEBUG_ENTER; 59 char buf[MAX_PACKET_BUF_SIZE] {}; 60 ssize_t numRead; 61 62 do { 63 numRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT); 64 if (numRead > 0) { 65 buffer_.Write(buf, numRead); 66 OnReadPackets(buffer_, recv_); 67 } else if (numRead < 0) { 68 if (errno == EINTR) { 69 FI_HILOGD("recv was interrupted, read again"); 70 continue; 71 } 72 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { 73 FI_HILOGW("No available data"); 74 } else { 75 FI_HILOGE("recv failed:%{public}s", ::strerror(errno)); 76 } 77 break; 78 } else { 79 FI_HILOGE("EOF happened"); 80 OnShutdown(fd); 81 break; 82 } 83 } while (numRead == sizeof(buf)); 84} 85 86void SocketConnection::OnShutdown(int32_t fd) 87{ 88 if (onDisconnected_) { 89 onDisconnected_(); 90 } 91} 92 93void SocketConnection::OnException(int32_t fd) 94{ 95 OnShutdown(fd); 96} 97} // namespace DeviceStatus 98} // namespace Msdp 99} // namespace OHOS