1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CHRE_HOST_SOCKET_SERVER_H_ 18 #define CHRE_HOST_SOCKET_SERVER_H_ 19 20 #include <poll.h> 21 22 #include <atomic> 23 #include <functional> 24 #include <map> 25 #include <mutex> 26 #include <vector> 27 28 #include <android-base/macros.h> 29 #include <cutils/sockets.h> 30 31 namespace android::chre { 32 33 class SocketServer { 34 public: 35 SocketServer(); 36 37 /** 38 * Defines the function signature of the callback given to run() which 39 * receives message data sent in by a client. 40 * 41 * @param clientId A unique identifier for the client that sent this request 42 * (assigned locally) 43 * @param data Pointer to buffer containing the raw message data 44 * @param len Number of bytes of data received 45 */ 46 typedef std::function<void(uint16_t clientId, void *data, size_t len)> 47 ClientMessageCallback; 48 49 /** 50 * Opens the socket, and runs the receive loop until an error is encountered, 51 * or SIGINT/SIGTERM is received. Masks off all other signals. 52 * 53 * @param socketName Android socket name to use when listening 54 * @param allowSocketCreation If true, allow creation of the socket rather 55 * than strictly inheriting it from init (used primarily for 56 * development purposes) 57 * @param clientMessageCallback Callback to be invoked when a message is 58 * received from a client 59 */ 60 void run(const char *socketName, bool allowSocketCreation, 61 ClientMessageCallback clientMessageCallback); 62 63 /** 64 * Delivers data to all connected clients. This method is thread-safe. 65 * 66 * @param data Pointer to buffer containing message data 67 * @param length Number of bytes of data to send 68 */ 69 void sendToAllClients(const void *data, size_t length); 70 71 /** 72 * Sends a message to one client, specified via its unique client ID. This 73 * method is thread-safe. 74 * 75 * @param data 76 * @param length 77 * @param clientId 78 * 79 * @return true if the message was successfully sent to the specified client 80 */ 81 bool sendToClientById(const void *data, size_t length, uint16_t clientId); 82 shutdownServer()83 static void shutdownServer() { 84 sSignalReceived = true; 85 } 86 87 private: 88 DISALLOW_COPY_AND_ASSIGN(SocketServer); 89 90 static constexpr size_t kMaxActiveClients = 8; 91 static constexpr int kMaxPendingConnectionRequests = 92 static_cast<int>(kMaxActiveClients); 93 static constexpr size_t kMaxPacketSize = 1024 * 1024; 94 95 // This is the same value as defined in 96 // host/hal_generic/common/hal_client_id.h. It is redefined here to avoid 97 // adding dependency path at multiple places for such a temporary change, 98 // which will be removed after migrating generic HAL to multiclient HAL. 99 static constexpr uint16_t kMaxHalClientId = 0x1ff; 100 101 int mSockFd = INVALID_SOCKET; 102 // Socket client id and Hal client id are using the same field in the fbs 103 // message. To keep their id range disjoint enables message routing for both 104 // at the same time. There are 0xffff - 0x01ff = 0xfe00 (65024) socket 105 // client ids to use, which should be more than enough. 106 uint16_t mNextClientId = kMaxHalClientId + 1; 107 // TODO: std::vector-ify this 108 struct pollfd mPollFds[1 + kMaxActiveClients] = {}; 109 110 struct ClientData { 111 uint16_t clientId; 112 }; 113 114 // Maps from socket FD to ClientData 115 std::map<int, ClientData> mClients; 116 117 // A buffer to read packets into. Allocated here to prevent a large object on 118 // the stack. 119 std::vector<uint8_t> mRecvBuffer = std::vector<uint8_t>(kMaxPacketSize); 120 121 // Ensures that mClients can be safely iterated over from other threads 122 // without worrying about potential modification from the RX thread 123 std::mutex mClientsMutex; 124 125 ClientMessageCallback mClientMessageCallback; 126 127 void acceptClientConnection(); 128 129 void disconnectClient(int clientSocket); 130 131 void handleClientData(int clientSocket); 132 133 bool sendToClientSocket(const void *data, size_t length, int clientSocket, 134 uint16_t clientId); 135 136 void serviceSocket(); 137 138 static std::atomic<bool> sSignalReceived; 139 }; 140 141 } // namespace android::chre 142 143 #endif // CHRE_HOST_SOCKET_SERVER_H_ 144