aboutsummaryrefslogtreecommitdiff
path: root/include/libtio/stream.h
blob: ffa33334b1de16adfa27d5ba44ce9c44f30c7994 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#ifndef  LIBTIO_STREAM_H
# define LIBTIO_STREAM_H 20180710
# include "cdefs.h"
# include "error.h"

/* Include the I/O specific structures and utilities. */

# include "io/generic.h"
# include "io/serial.h"
# include "io/usb.h"
# include "io/scsi.h"

TIO_BEGIN_NAMESPACE

/* libtio is centered around its streams, which are opaque objects that
 * allow you to interact with other devices such as generic streams (for
 * local files, etc), serial bridges, USB devices and SCSI devices.
 *
 * Notice that in case of "partial success" (e.g. parts of the buffer were
 * written, but not all of it), you shall return an error, because there
 * is no partial success. */

TIO_STRUCT(tio_stream,           tio_stream_t)
TIO_STRUCT(tio_timeouts,         tio_timeouts_t)

TIO_STRUCT(tio_functions,        tio_functions_t)
TIO_STRUCT(tio_serial_functions, tio_serial_functions_t)
TIO_STRUCT(tio_usb_functions,    tio_usb_functions_t)
TIO_STRUCT(tio_scsi_functions,   tio_scsi_functions_t)

/* Timeouts. */

struct tio_timeouts {
	/* The three timeout types:
	 * - total timeout.
	 * - before the first block.
	 * - between blocks.
	 *
	 * All timeouts are in microseconds, and considered only if non zero. */

	unsigned long tio_timeouts_total;
	unsigned long tio_timeouts_blocks;
	unsigned long tio_timeouts_within;
};

/* In this section, the callbacks for all the stream types are defined
 * (some are common to several types of stream). All the structures have
 * the `close` callback first. */

typedef TIO_HOOK_TYPE(void) tio_close_t
	OF((void *));

typedef TIO_HOOK_TYPE(int) tio_read_t
	OF((void *, unsigned char *, size_t));
typedef TIO_HOOK_TYPE(int) tio_read_tm_t
	OF((void *, unsigned char *, size_t,
		tio_timeouts_t const *));

typedef TIO_HOOK_TYPE(int) tio_write_t
	OF((void *, unsigned char const *, size_t));
typedef TIO_HOOK_TYPE(int) tio_write_tm_t
	OF((void *, unsigned char const *, size_t,
		tio_timeouts_t const *));

typedef TIO_HOOK_TYPE(int) tio_set_tm_t
	OF((void *,
		tio_timeouts_t const * /* read */,
		tio_timeouts_t const * /* write */));

typedef TIO_HOOK_TYPE(int) tio_seek_t
	OF((void *, tio_off_t *, tio_whence_t));

typedef TIO_HOOK_TYPE(int) tio_set_serial_attrs_t
	OF((void *, tio_serial_attrs_t const *, unsigned long));

typedef TIO_HOOK_TYPE(int) tio_scsi_t
	OF((void *, tio_scsi_request_t *));

typedef TIO_HOOK_TYPE(int) tio_usb_send_bulk_t
	OF((void *, unsigned char const *, size_t,
		unsigned int /* total timeout in ms */));
typedef TIO_HOOK_TYPE(int) tio_usb_recv_bulk_t
	OF((void *, unsigned char *, size_t *,
		unsigned int /* total timeout in ms */));

/* Generic stream definitions. */

# define TIO_TYPE_GENERIC 1

# define TIO_OPENFLAG_READ             1
# define TIO_OPENFLAG_WRITE            2
# define TIO_OPENFLAG_SEEK             4

struct tio_functions {
	tio_close_t *tio_functions_close;

	tio_read_t  *tio_functions_read;
	tio_write_t *tio_functions_write;
	tio_seek_t  *tio_functions_seek;
};

/* Serial stream definitions. */

# define TIO_TYPE_SERIAL 2

# define TIO_OPENFLAG_SERIAL_READ             1
# define TIO_OPENFLAG_SERIAL_WRITE            2
# define TIO_OPENFLAG_SERIAL_SETATTRS         4

# define TIO_OPENFLAG_SERIAL_READ_TIMEOUTS    8
# define TIO_OPENFLAG_SERIAL_WRITE_TIMEOUTS  16
# define TIO_OPENFLAG_SERIAL_SET_TIMEOUTS    32

struct tio_serial_functions {
	tio_close_t            *tio_serial_functions_close;

	tio_read_t             *tio_serial_functions_read;
	tio_write_t            *tio_serial_functions_write;
	tio_set_serial_attrs_t *tio_serial_functions_set_attrs;

	tio_read_tm_t          *tio_serial_functions_read_tm;
	tio_write_tm_t         *tio_serial_functions_write_tm;
	tio_set_tm_t           *tio_serial_functions_set_tm;
};

/* USB stream definitions. */

# define TIO_TYPE_USB 3

# define TIO_OPENFLAG_USB_SEND_BULK    1
# define TIO_OPENFLAG_USB_RECV_BULK    2

struct tio_usb_functions {
	tio_close_t         *tio_usb_functions_close;

	tio_usb_send_bulk_t *tio_usb_functions_send_bulk;
	tio_usb_recv_bulk_t *tio_usb_functions_recv_bulk;
};

/* SCSI stream definitions. */

# define TIO_TYPE_SCSI 4

# define TIO_OPENFLAG_SCSI_REQUEST     1

struct tio_scsi_functions {
	tio_close_t *tio_scsi_functions_close;

	tio_scsi_t  *tio_scsi_functions_request;
};

/* ---
 * Basic stream interactions.
 * --- */

TIO_BEGIN_DECLS

/* Open and close a stream.
 *
 * Functions that the stream does not override (by not setting the
 * corresponding flag, setting the callback pointer to NULL, or
 * not being of the same stream category) will be transmitted to the
 * `tio__over` stream if present, so that you can still access USB
 * functions behind an SCSI stream for example. */

TIO_EXTERN(int) tio_open
	OF((tio_stream_t **tio__streamp, tio_stream_t *tio__parent,
		void *tio__cookie, unsigned int tio__flags,
		tio_functions_t const *tio__functions, tio_off_t tio__offset));

TIO_EXTERN(int) tio_open_serial
	OF((tio_stream_t **tio__streamp, tio_stream_t *tio__parent,
		void *tio__cookie, unsigned int tio__flags,
		tio_serial_functions_t const *tio__functions,
		tio_serial_attrs_t const *tio__attrs,
		unsigned long tio__attrs_flags));

TIO_EXTERN(int) tio_open_usb
	OF((tio_stream_t **tio__streamp, tio_stream_t *tio__parent,
		void *tio__cookie, unsigned int tio__flags,
		tio_usb_functions_t const *tio__functions));

TIO_EXTERN(int) tio_open_scsi
	OF((tio_stream_t **tio__streamp, tio_stream_t *tio__parent,
		void *tio__cookie, unsigned int tio__flags,
		tio_scsi_functions_t const *tio__functions));

#define tio_close(STREAM) tio_free(STREAM)

/* Get various stream data. */

TIO_EXTERN(int) tio_isreadable
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(int) tio_iswritable
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(int) tio_isseekable
	OF((tio_stream_t *tio__stream));

# define tio_is_readable(TIO__STREAM) \
	tio_isreadable(TIO__STREAM)
# define tio_is_writable(TIO__STREAM) \
	tio_iswritable(TIO__STREAM)
# define tio_is_seekable(TIO__STREAM) \
	tio_isseekable(TIO__STREAM)

TIO_EXTERN(int) tio_has_read_timeouts
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(int) tio_has_write_timeouts
	OF((tio_stream_t *tio__stream));

TIO_EXTERN(int)    tio_get_type
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(void *) tio_get_cookie
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(int)    tio_get_lasterr
	OF((tio_stream_t *tio__stream));
TIO_EXTERN(int)    tio_get_parent
	OF((tio_stream_t *tio__stream, tio_stream_t **tio__parent));

/* Read and write data from and to a stream.
 * Timeouts are in milliseconds (ms). */

TIO_EXTERN(int) tio_read
	OF((tio_stream_t *tio__stream, void *tio__dest,
		size_t tio__count));
TIO_EXTERN(int) tio_read_tm
	OF((tio_stream_t *tio__stream, void *tio__dest,
		size_t tio__count, tio_timeouts_t const *tio__tm));

TIO_EXTERN(int) tio_write
	OF((tio_stream_t *tio__stream, void const *tio__data,
		size_t tio__count));
TIO_EXTERN(int) tio_write_tm
	OF((tio_stream_t *tio__stream, void const *tio__data,
		size_t tio__count, tio_timeouts_t const *tio__tm));

TIO_EXTERN(int) tio_write_char
	OF((tio_stream_t *tio__stream, int tio__char));

/* Move within a stream. */

TIO_EXTERN(int)       tio_seek
	OF((tio_stream_t *tio__stream,
		tio_off_t tio__offset, tio_whence_t tio__whence));
TIO_EXTERN(tio_off_t) tio_tell
	OF((tio_stream_t *tio__stream));

TIO_EXTERN(int) tio_skip
	OF((tio_stream_t *tio__stream, tio_off_t  tio__size));
TIO_EXTERN(int) tio_get_size
	OF((tio_stream_t *tio__stream, tio_off_t *tio__size));

/* Set and get the serial attributes of a stream. */

TIO_EXTERN(int) tio_set_serial_attrs
	OF((tio_stream_t *tio__stream, tio_serial_attrs_t const *tio__attrs,
		unsigned long tio__attrs_flags));
TIO_EXTERN(int) tio_get_serial_attrs
	OF((tio_stream_t *tio__stream, tio_serial_attrs_t *tio__attrs,
		unsigned long tio__attrs_flags));

/* Set the timeouts of a stream. */

TIO_EXTERN(int) tio_set_timeouts
	OF((tio_stream_t *tio__stream,
		tio_timeouts_t const *tio__read,
		tio_timeouts_t const *tio__write));

/* Make USB-related operations. */

TIO_EXTERN(int) tio_send_usb_bulk
	OF((tio_stream_t *tio__stream, unsigned char const *tio__data,
		size_t tio__size, unsigned int tio__timeout));
TIO_EXTERN(int) tio_recv_usb_bulk
	OF((tio_stream_t *tio__stream, unsigned char *tio__buf,
		size_t *tio__sizep, unsigned int tio__timeout));

/* Make an SCSI request. */

TIO_EXTERN(int) tio_scsi_request
	OF((tio_stream_t *tio__stream, tio_scsi_request_t *tio__request));

/* ---
 * Built-in and native.
 * --- */

/* Make a stream out of memory. */

TIO_EXTERN(int) tio_open_memory
	OF((tio_stream_t **tio__streamp,
		void *tio__zone, size_t tio__size));
TIO_EXTERN(int) tio_open_readonly_memory
	OF((tio_stream_t **tio__stream,
		void const *tio__zone, size_t tio__size));

/* Make a stream out of another, with a limit (and empty it). */

TIO_EXTERN(int) tio_open_limited
	OF((tio_stream_t **tio__streamp,
		tio_stream_t *tio__original, size_t tio__limit));
TIO_EXTERN(int) tio_empty_limited
	OF((tio_stream_t *tio__stream));

/* Open a native serial or USB stream. */

TIO_EXTERN(int) tio_open_native_serial
	OF((tio_stream_t **tio__streamp,
		char const *tio__path));
TIO_EXTERN(int) tio_open_native_usb
	OF((tio_stream_t **tio__streamp,
		int tio__bus, int tio__addr));

/* Make a generic stream over USB using bulk-only transport. */

TIO_EXTERN(int) tio_open_bulk_usb_over_stream
	OF((tio_stream_t **tio__streamp,
		tio_stream_t *tio__usb_stream));
TIO_EXTERN(int) tio_open_bulk_usb
	OF((tio_stream_t **tio__streamp,
		int tio__bus, int tio__addr));

TIO_END_DECLS
TIO_END_NAMESPACE

# include "native.h"
#endif /* LIBTIO_H */