1/*
2 * Copyright (C) 2010 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/*
18 * Contains helper routines dealing with syncronous access to a non-blocking
19 * sokets.
20 */
21
22#ifndef ANDROID_SYNC_UTILS_H
23#define ANDROID_SYNC_UTILS_H
24
25#include "android/android.h"
26#include "android/sockets.h"
27
28/* Descriptor for a connected non-blocking socket providing synchronous I/O */
29typedef struct SyncSocket SyncSocket;
30
31/*
32 * Connect to a non-blocking socket for further synchronous I/O.
33 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
34 * to this routine.
35 * Param:
36 *  fd - File descriptor for the socket, created with socket_create_xxx routine.
37 *  sockaddr - Address of the socket to connect to.
38 *  timeout - Time out (in milliseconds) to wait for the connection to occur.
39 * Return:
40 *  Initialized SyncSocket descriptor on success, or NULL on failure.
41 */
42SyncSocket* syncsocket_connect(int fd, SockAddress* sockaddr, int timeout);
43
44/*
45 * Initializes a non-blocking socket for further synchronous I/O.
46 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
47 * to this routine.
48 * Param:
49 *  fd - File descriptor for the already connected socket.
50 * Return:
51 *  Initialized SyncSocket descriptor on success, or NULL on failure.
52 */
53SyncSocket* syncsocket_init(int fd);
54
55/*
56 * Closes SyncSocket descriptor obtained from syncsocket_connect routine.
57 * Param:
58 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
59 */
60void syncsocket_close(SyncSocket* ssocket);
61
62/*
63 * Frees memory allocated for SyncSocket descriptor obtained from
64 * syncsocket_connect routine. Note that this routine will also close socket
65 * connection.
66 * Param:
67 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
68 */
69void syncsocket_free(SyncSocket* ssocket);
70
71/*
72 * Prepares the socket for read.
73 * Note: this routine must be called before calling into syncsocket_read_xxx
74 * routines.
75 * Param:
76 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
77 * Return:
78 *  0 on success, or -1 on failure.
79 */
80int syncsocket_start_read(SyncSocket* ssocket);
81
82/*
83 * Clears the socket after reading.
84 * Note: this routine must be called after all expected data has been read from
85 * the socket.
86 * Param:
87 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
88 * Return:
89 *  0 on success, or -1 on failure.
90 */
91int syncsocket_stop_read(SyncSocket* ssocket);
92
93/*
94 * Prepares the socket for write.
95 * Note: this routine must be called before calling into syncsocket_write_xxx
96 * routines.
97 * Param:
98 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
99 * Return:
100 *  0 on success, or -1 on failure.
101 */
102int syncsocket_start_write(SyncSocket* ssocket);
103
104/*
105 * Clears the socket after writing.
106 * Note: this routine must be called after all data has been written to the
107 * socket.
108 * Param:
109 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
110 * Return:
111 *  0 on success, or -1 on failure.
112 */
113int syncsocket_stop_write(SyncSocket* ssocket);
114
115/*
116 * Synchronously reads from the socket.
117 * Note: syncsocket_start_read must be called before first call to this routine.
118 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
119 * be called to read all necessary data from the socket. When all necessary data
120 * has been read, syncsocket_stop_read must be called.
121 * Param:
122 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
123 *  buf - Buffer where to read data.
124 *  size - Number of bytes to read.
125 *  deadline - Absoulte deadline time to complete the reading.
126 * Return:
127 *  Number of bytes read on success, or -1 on failure.
128 */
129ssize_t syncsocket_read_absolute(SyncSocket* ssocket,
130                                 void* buf,
131                                 size_t size,
132                                 int64_t deadline);
133
134/*
135 * Synchronously reads from the socket.
136 * Note: syncsocket_start_read must be called before first call to this routine.
137 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
138 * be called to read all necessary data from the socket. When all necessary data
139 * has been read, syncsocket_stop_read must be called.
140 * Param:
141 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
142 *  buf - Buffer where to read data.
143 *  size - Number of bytes to read.
144 *  timeout - Timeout (in milliseconds) to complete the reading.
145 * Return:
146 *  Number of bytes read on success, or -1 on failure.
147 */
148ssize_t syncsocket_read(SyncSocket* ssocket, void* buf, size_t size, int timeout);
149
150/*
151 * Synchronously writes to the socket.
152 * Note: syncsocket_start_write must be called before first call to this routine.
153 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
154 * be called to write all necessary data to the socket. When all necessary data
155 * has been written, syncsocket_stop_write must be called.
156 * Param:
157 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
158 *  buf - Buffer containing data to write.
159 *  size - Number of bytes to write.
160 *  deadline - Absoulte deadline time to complete the writing.
161 * Return:
162 *  Number of bytes written on success,or -1 on failure.
163 */
164ssize_t syncsocket_write_absolute(SyncSocket* ssocket,
165                                  const void* buf,
166                                  size_t size,
167                                  int64_t deadline);
168
169/*
170 * Synchronously writes to the socket.
171 * Note: syncsocket_start_write must be called before first call to this routine.
172 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
173 * be called to write all necessary data to the socket. When all necessary data
174 * has been written, syncsocket_stop_write must be called.
175 * Param:
176 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
177 *  buf - Buffer containing data to write.
178 *  size - Number of bytes to write.
179 *  timeout - Timeout (in milliseconds) to complete the writing.
180 * Return:
181 *  Number of bytes written on success, or -1 on failure.
182 */
183ssize_t syncsocket_write(SyncSocket* ssocket,
184                         const void* buf,
185                         size_t size,
186                         int timeout);
187
188/*
189 * Synchronously reads a line terminated with '\n' from the socket.
190 * Note: syncsocket_start_read must be called before first call to this routine.
191 * Param:
192 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
193 *  buffer - Buffer where to read line.
194 *  size - Number of characters the buffer can contain.
195 *  deadline - Absoulte deadline time to complete the reading.
196 * Return:
197 *  Number of chracters read on success, 0 on deadline expiration,
198 *  or -1 on failure.
199 */
200ssize_t syncsocket_read_line_absolute(SyncSocket* ssocket,
201                                      char* buffer,
202                                      size_t size,
203                                      int64_t deadline);
204
205/*
206 * Synchronously reads a line terminated with '\n' from the socket.
207 * Note: syncsocket_start_read must be called before first call to this routine.
208 * Param:
209 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
210 *  buffer - Buffer where to read line.
211 *  size - Number of characters the buffer can contain.
212 *  timeout - Timeout (in milliseconds) to complete the reading.
213 * Return:
214 *  Number of chracters read on success, 0 on deadline expiration,
215 *  or -1 on failure.
216 */
217ssize_t syncsocket_read_line(SyncSocket* ssocket,
218                             char* buffer,
219                             size_t size,
220                             int timeout);
221
222/* Gets socket descriptor associated with the sync socket.
223 * Param:
224 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
225 * Return
226 *  Socket descriptor associated with the sync socket.
227 */
228int syncsocket_get_socket(SyncSocket* ssocket);
229
230/* Converts syncsocket_xxx operation status into success / failure result.
231 * Param:
232 *  status - syncsocket_xxx operation status to convert.
233 * Return:
234 *  0 if status passed to this routine indicated a success, or < 0 if status
235 *  indicated a failure.
236 */
237static inline int
238syncsocket_result(int status)
239{
240    if (status == 0) {
241        // Status 0 returned from syncsocket_xxx means "disconnection", which is
242        // a failure.
243        status = -1;
244    } else if (status > 0) {
245        // Status > 0 means success.
246        status = 0;
247    }
248    return status;
249}
250
251#endif  // ANDROID_SYNC_UTILS_H
252