|
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ |
|
2 /* vim: set ts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef mozilla_ipc_UnixSocket_h |
|
8 #define mozilla_ipc_UnixSocket_h |
|
9 |
|
10 |
|
11 #include <stdlib.h> |
|
12 #include "nsAutoPtr.h" |
|
13 #include "nsString.h" |
|
14 #include "nsThreadUtils.h" |
|
15 #include "mozilla/ipc/UnixSocketWatcher.h" |
|
16 #include "mozilla/RefPtr.h" |
|
17 |
|
18 namespace mozilla { |
|
19 namespace ipc { |
|
20 |
|
21 class UnixSocketRawData |
|
22 { |
|
23 public: |
|
24 // Number of octets in mData. |
|
25 size_t mSize; |
|
26 size_t mCurrentWriteOffset; |
|
27 nsAutoArrayPtr<uint8_t> mData; |
|
28 |
|
29 /** |
|
30 * Constructor for situations where only size is known beforehand |
|
31 * (for example, when being assigned strings) |
|
32 */ |
|
33 UnixSocketRawData(size_t aSize) : |
|
34 mSize(aSize), |
|
35 mCurrentWriteOffset(0) |
|
36 { |
|
37 mData = new uint8_t[mSize]; |
|
38 } |
|
39 |
|
40 /** |
|
41 * Constructor for situations where size and data is known |
|
42 * beforehand (for example, when being assigned strings) |
|
43 */ |
|
44 UnixSocketRawData(const void* aData, size_t aSize) |
|
45 : mSize(aSize), |
|
46 mCurrentWriteOffset(0) |
|
47 { |
|
48 MOZ_ASSERT(aData || !mSize); |
|
49 mData = new uint8_t[mSize]; |
|
50 memcpy(mData, aData, mSize); |
|
51 } |
|
52 }; |
|
53 |
|
54 class UnixSocketImpl; |
|
55 |
|
56 /** |
|
57 * UnixSocketConnector defines the socket creation and connection/listening |
|
58 * functions for a UnixSocketConsumer. Due to the fact that socket setup can |
|
59 * vary between protocols (unix sockets, tcp sockets, bluetooth sockets, etc), |
|
60 * this allows the user to create whatever connection mechanism they need while |
|
61 * still depending on libevent for non-blocking communication handling. |
|
62 * |
|
63 * FIXME/Bug 793980: Currently only virtual, since we only support bluetooth. |
|
64 * Should make connection functions for other unix sockets so we can support |
|
65 * things like RIL. |
|
66 */ |
|
67 class UnixSocketConnector |
|
68 { |
|
69 public: |
|
70 UnixSocketConnector() |
|
71 {} |
|
72 |
|
73 virtual ~UnixSocketConnector() |
|
74 {} |
|
75 |
|
76 /** |
|
77 * Establishs a file descriptor for a socket. |
|
78 * |
|
79 * @return File descriptor for socket |
|
80 */ |
|
81 virtual int Create() = 0; |
|
82 |
|
83 /** |
|
84 * Since most socket specifics are related to address formation into a |
|
85 * sockaddr struct, this function is defined by subclasses and fills in the |
|
86 * structure as needed for whatever connection it is trying to build |
|
87 * |
|
88 * @param aIsServer True is we are acting as a server socket |
|
89 * @param aAddrSize Size of the struct |
|
90 * @param aAddr Struct to fill |
|
91 * @param aAddress If aIsServer is false, Address to connect to. nullptr otherwise. |
|
92 * |
|
93 * @return True if address is filled correctly, false otherwise |
|
94 */ |
|
95 virtual bool CreateAddr(bool aIsServer, |
|
96 socklen_t& aAddrSize, |
|
97 sockaddr_any& aAddr, |
|
98 const char* aAddress) = 0; |
|
99 |
|
100 /** |
|
101 * Does any socket type specific setup that may be needed, only for socket |
|
102 * created by ConnectSocket() |
|
103 * |
|
104 * @param aFd File descriptor for opened socket |
|
105 * |
|
106 * @return true is successful, false otherwise |
|
107 */ |
|
108 virtual bool SetUp(int aFd) = 0; |
|
109 |
|
110 /** |
|
111 * Perform socket setup for socket created by ListenSocket(), after listen(). |
|
112 * |
|
113 * @param aFd File descriptor for opened socket |
|
114 * |
|
115 * @return true is successful, false otherwise |
|
116 */ |
|
117 virtual bool SetUpListenSocket(int aFd) = 0; |
|
118 |
|
119 /** |
|
120 * Get address of socket we're currently connected to. Return null string if |
|
121 * not connected. |
|
122 * |
|
123 * @param aAddr Address struct |
|
124 * @param aAddrStr String to store address to |
|
125 */ |
|
126 virtual void GetSocketAddr(const sockaddr_any& aAddr, |
|
127 nsAString& aAddrStr) = 0; |
|
128 |
|
129 }; |
|
130 |
|
131 enum SocketConnectionStatus { |
|
132 SOCKET_DISCONNECTED = 0, |
|
133 SOCKET_LISTENING = 1, |
|
134 SOCKET_CONNECTING = 2, |
|
135 SOCKET_CONNECTED = 3 |
|
136 }; |
|
137 |
|
138 class UnixSocketConsumer |
|
139 { |
|
140 protected: |
|
141 virtual ~UnixSocketConsumer(); |
|
142 |
|
143 public: |
|
144 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UnixSocketConsumer) |
|
145 |
|
146 UnixSocketConsumer(); |
|
147 |
|
148 SocketConnectionStatus GetConnectionStatus() const |
|
149 { |
|
150 MOZ_ASSERT(NS_IsMainThread()); |
|
151 return mConnectionStatus; |
|
152 } |
|
153 |
|
154 int GetSuggestedConnectDelayMs() const |
|
155 { |
|
156 MOZ_ASSERT(NS_IsMainThread()); |
|
157 return mConnectDelayMs; |
|
158 } |
|
159 |
|
160 /** |
|
161 * Function to be called whenever data is received. This is only called on the |
|
162 * main thread. |
|
163 * |
|
164 * @param aMessage Data received from the socket. |
|
165 */ |
|
166 virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0; |
|
167 |
|
168 /** |
|
169 * Queue data to be sent to the socket on the IO thread. Can only be called on |
|
170 * originating thread. |
|
171 * |
|
172 * @param aMessage Data to be sent to socket |
|
173 * |
|
174 * @return true if data is queued, false otherwise (i.e. not connected) |
|
175 */ |
|
176 bool SendSocketData(UnixSocketRawData* aMessage); |
|
177 |
|
178 /** |
|
179 * Convenience function for sending strings to the socket (common in bluetooth |
|
180 * profile usage). Converts to a UnixSocketRawData struct. Can only be called |
|
181 * on originating thread. |
|
182 * |
|
183 * @param aMessage String to be sent to socket |
|
184 * |
|
185 * @return true if data is queued, false otherwise (i.e. not connected) |
|
186 */ |
|
187 bool SendSocketData(const nsACString& aMessage); |
|
188 |
|
189 /** |
|
190 * Starts a task on the socket that will try to connect to a socket in a |
|
191 * non-blocking manner. |
|
192 * |
|
193 * @param aConnector Connector object for socket type specific functions |
|
194 * @param aAddress Address to connect to. |
|
195 * @param aDelayMs Time delay in milli-seconds. |
|
196 * |
|
197 * @return true on connect task started, false otherwise. |
|
198 */ |
|
199 bool ConnectSocket(UnixSocketConnector* aConnector, |
|
200 const char* aAddress, |
|
201 int aDelayMs = 0); |
|
202 |
|
203 /** |
|
204 * Starts a task on the socket that will try to accept a new connection in a |
|
205 * non-blocking manner. |
|
206 * |
|
207 * @param aConnector Connector object for socket type specific functions |
|
208 * |
|
209 * @return true on listen started, false otherwise |
|
210 */ |
|
211 bool ListenSocket(UnixSocketConnector* aConnector); |
|
212 |
|
213 /** |
|
214 * Queues the internal representation of socket for deletion. Can be called |
|
215 * from main thread. |
|
216 */ |
|
217 void CloseSocket(); |
|
218 |
|
219 /** |
|
220 * Callback for socket connect/accept success. Called after connect/accept has |
|
221 * finished. Will be run on main thread, before any reads take place. |
|
222 */ |
|
223 virtual void OnConnectSuccess() = 0; |
|
224 |
|
225 /** |
|
226 * Callback for socket connect/accept error. Will be run on main thread. |
|
227 */ |
|
228 virtual void OnConnectError() = 0; |
|
229 |
|
230 /** |
|
231 * Callback for socket disconnect. Will be run on main thread. |
|
232 */ |
|
233 virtual void OnDisconnect() = 0; |
|
234 |
|
235 /** |
|
236 * Called by implementation to notify consumer of success. |
|
237 */ |
|
238 void NotifySuccess(); |
|
239 |
|
240 /** |
|
241 * Called by implementation to notify consumer of error. |
|
242 */ |
|
243 void NotifyError(); |
|
244 |
|
245 /** |
|
246 * Called by implementation to notify consumer of disconnect. |
|
247 */ |
|
248 void NotifyDisconnect(); |
|
249 |
|
250 /** |
|
251 * Get the current sockaddr for the socket |
|
252 */ |
|
253 void GetSocketAddr(nsAString& aAddrStr); |
|
254 |
|
255 private: |
|
256 uint32_t CalculateConnectDelayMs() const; |
|
257 |
|
258 UnixSocketImpl* mImpl; |
|
259 SocketConnectionStatus mConnectionStatus; |
|
260 PRIntervalTime mConnectTimestamp; |
|
261 uint32_t mConnectDelayMs; |
|
262 }; |
|
263 |
|
264 } // namespace ipc |
|
265 } // namepsace mozilla |
|
266 |
|
267 #endif // mozilla_ipc_Socket_h |