1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/unixsocket/UnixSocket.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,267 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_ipc_UnixSocket_h 1.11 +#define mozilla_ipc_UnixSocket_h 1.12 + 1.13 + 1.14 +#include <stdlib.h> 1.15 +#include "nsAutoPtr.h" 1.16 +#include "nsString.h" 1.17 +#include "nsThreadUtils.h" 1.18 +#include "mozilla/ipc/UnixSocketWatcher.h" 1.19 +#include "mozilla/RefPtr.h" 1.20 + 1.21 +namespace mozilla { 1.22 +namespace ipc { 1.23 + 1.24 +class UnixSocketRawData 1.25 +{ 1.26 +public: 1.27 + // Number of octets in mData. 1.28 + size_t mSize; 1.29 + size_t mCurrentWriteOffset; 1.30 + nsAutoArrayPtr<uint8_t> mData; 1.31 + 1.32 + /** 1.33 + * Constructor for situations where only size is known beforehand 1.34 + * (for example, when being assigned strings) 1.35 + */ 1.36 + UnixSocketRawData(size_t aSize) : 1.37 + mSize(aSize), 1.38 + mCurrentWriteOffset(0) 1.39 + { 1.40 + mData = new uint8_t[mSize]; 1.41 + } 1.42 + 1.43 + /** 1.44 + * Constructor for situations where size and data is known 1.45 + * beforehand (for example, when being assigned strings) 1.46 + */ 1.47 + UnixSocketRawData(const void* aData, size_t aSize) 1.48 + : mSize(aSize), 1.49 + mCurrentWriteOffset(0) 1.50 + { 1.51 + MOZ_ASSERT(aData || !mSize); 1.52 + mData = new uint8_t[mSize]; 1.53 + memcpy(mData, aData, mSize); 1.54 + } 1.55 +}; 1.56 + 1.57 +class UnixSocketImpl; 1.58 + 1.59 +/** 1.60 + * UnixSocketConnector defines the socket creation and connection/listening 1.61 + * functions for a UnixSocketConsumer. Due to the fact that socket setup can 1.62 + * vary between protocols (unix sockets, tcp sockets, bluetooth sockets, etc), 1.63 + * this allows the user to create whatever connection mechanism they need while 1.64 + * still depending on libevent for non-blocking communication handling. 1.65 + * 1.66 + * FIXME/Bug 793980: Currently only virtual, since we only support bluetooth. 1.67 + * Should make connection functions for other unix sockets so we can support 1.68 + * things like RIL. 1.69 + */ 1.70 +class UnixSocketConnector 1.71 +{ 1.72 +public: 1.73 + UnixSocketConnector() 1.74 + {} 1.75 + 1.76 + virtual ~UnixSocketConnector() 1.77 + {} 1.78 + 1.79 + /** 1.80 + * Establishs a file descriptor for a socket. 1.81 + * 1.82 + * @return File descriptor for socket 1.83 + */ 1.84 + virtual int Create() = 0; 1.85 + 1.86 + /** 1.87 + * Since most socket specifics are related to address formation into a 1.88 + * sockaddr struct, this function is defined by subclasses and fills in the 1.89 + * structure as needed for whatever connection it is trying to build 1.90 + * 1.91 + * @param aIsServer True is we are acting as a server socket 1.92 + * @param aAddrSize Size of the struct 1.93 + * @param aAddr Struct to fill 1.94 + * @param aAddress If aIsServer is false, Address to connect to. nullptr otherwise. 1.95 + * 1.96 + * @return True if address is filled correctly, false otherwise 1.97 + */ 1.98 + virtual bool CreateAddr(bool aIsServer, 1.99 + socklen_t& aAddrSize, 1.100 + sockaddr_any& aAddr, 1.101 + const char* aAddress) = 0; 1.102 + 1.103 + /** 1.104 + * Does any socket type specific setup that may be needed, only for socket 1.105 + * created by ConnectSocket() 1.106 + * 1.107 + * @param aFd File descriptor for opened socket 1.108 + * 1.109 + * @return true is successful, false otherwise 1.110 + */ 1.111 + virtual bool SetUp(int aFd) = 0; 1.112 + 1.113 + /** 1.114 + * Perform socket setup for socket created by ListenSocket(), after listen(). 1.115 + * 1.116 + * @param aFd File descriptor for opened socket 1.117 + * 1.118 + * @return true is successful, false otherwise 1.119 + */ 1.120 + virtual bool SetUpListenSocket(int aFd) = 0; 1.121 + 1.122 + /** 1.123 + * Get address of socket we're currently connected to. Return null string if 1.124 + * not connected. 1.125 + * 1.126 + * @param aAddr Address struct 1.127 + * @param aAddrStr String to store address to 1.128 + */ 1.129 + virtual void GetSocketAddr(const sockaddr_any& aAddr, 1.130 + nsAString& aAddrStr) = 0; 1.131 + 1.132 +}; 1.133 + 1.134 +enum SocketConnectionStatus { 1.135 + SOCKET_DISCONNECTED = 0, 1.136 + SOCKET_LISTENING = 1, 1.137 + SOCKET_CONNECTING = 2, 1.138 + SOCKET_CONNECTED = 3 1.139 +}; 1.140 + 1.141 +class UnixSocketConsumer 1.142 +{ 1.143 +protected: 1.144 + virtual ~UnixSocketConsumer(); 1.145 + 1.146 +public: 1.147 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UnixSocketConsumer) 1.148 + 1.149 + UnixSocketConsumer(); 1.150 + 1.151 + SocketConnectionStatus GetConnectionStatus() const 1.152 + { 1.153 + MOZ_ASSERT(NS_IsMainThread()); 1.154 + return mConnectionStatus; 1.155 + } 1.156 + 1.157 + int GetSuggestedConnectDelayMs() const 1.158 + { 1.159 + MOZ_ASSERT(NS_IsMainThread()); 1.160 + return mConnectDelayMs; 1.161 + } 1.162 + 1.163 + /** 1.164 + * Function to be called whenever data is received. This is only called on the 1.165 + * main thread. 1.166 + * 1.167 + * @param aMessage Data received from the socket. 1.168 + */ 1.169 + virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0; 1.170 + 1.171 + /** 1.172 + * Queue data to be sent to the socket on the IO thread. Can only be called on 1.173 + * originating thread. 1.174 + * 1.175 + * @param aMessage Data to be sent to socket 1.176 + * 1.177 + * @return true if data is queued, false otherwise (i.e. not connected) 1.178 + */ 1.179 + bool SendSocketData(UnixSocketRawData* aMessage); 1.180 + 1.181 + /** 1.182 + * Convenience function for sending strings to the socket (common in bluetooth 1.183 + * profile usage). Converts to a UnixSocketRawData struct. Can only be called 1.184 + * on originating thread. 1.185 + * 1.186 + * @param aMessage String to be sent to socket 1.187 + * 1.188 + * @return true if data is queued, false otherwise (i.e. not connected) 1.189 + */ 1.190 + bool SendSocketData(const nsACString& aMessage); 1.191 + 1.192 + /** 1.193 + * Starts a task on the socket that will try to connect to a socket in a 1.194 + * non-blocking manner. 1.195 + * 1.196 + * @param aConnector Connector object for socket type specific functions 1.197 + * @param aAddress Address to connect to. 1.198 + * @param aDelayMs Time delay in milli-seconds. 1.199 + * 1.200 + * @return true on connect task started, false otherwise. 1.201 + */ 1.202 + bool ConnectSocket(UnixSocketConnector* aConnector, 1.203 + const char* aAddress, 1.204 + int aDelayMs = 0); 1.205 + 1.206 + /** 1.207 + * Starts a task on the socket that will try to accept a new connection in a 1.208 + * non-blocking manner. 1.209 + * 1.210 + * @param aConnector Connector object for socket type specific functions 1.211 + * 1.212 + * @return true on listen started, false otherwise 1.213 + */ 1.214 + bool ListenSocket(UnixSocketConnector* aConnector); 1.215 + 1.216 + /** 1.217 + * Queues the internal representation of socket for deletion. Can be called 1.218 + * from main thread. 1.219 + */ 1.220 + void CloseSocket(); 1.221 + 1.222 + /** 1.223 + * Callback for socket connect/accept success. Called after connect/accept has 1.224 + * finished. Will be run on main thread, before any reads take place. 1.225 + */ 1.226 + virtual void OnConnectSuccess() = 0; 1.227 + 1.228 + /** 1.229 + * Callback for socket connect/accept error. Will be run on main thread. 1.230 + */ 1.231 + virtual void OnConnectError() = 0; 1.232 + 1.233 + /** 1.234 + * Callback for socket disconnect. Will be run on main thread. 1.235 + */ 1.236 + virtual void OnDisconnect() = 0; 1.237 + 1.238 + /** 1.239 + * Called by implementation to notify consumer of success. 1.240 + */ 1.241 + void NotifySuccess(); 1.242 + 1.243 + /** 1.244 + * Called by implementation to notify consumer of error. 1.245 + */ 1.246 + void NotifyError(); 1.247 + 1.248 + /** 1.249 + * Called by implementation to notify consumer of disconnect. 1.250 + */ 1.251 + void NotifyDisconnect(); 1.252 + 1.253 + /** 1.254 + * Get the current sockaddr for the socket 1.255 + */ 1.256 + void GetSocketAddr(nsAString& aAddrStr); 1.257 + 1.258 +private: 1.259 + uint32_t CalculateConnectDelayMs() const; 1.260 + 1.261 + UnixSocketImpl* mImpl; 1.262 + SocketConnectionStatus mConnectionStatus; 1.263 + PRIntervalTime mConnectTimestamp; 1.264 + uint32_t mConnectDelayMs; 1.265 +}; 1.266 + 1.267 +} // namespace ipc 1.268 +} // namepsace mozilla 1.269 + 1.270 +#endif // mozilla_ipc_Socket_h