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
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
|
/* ****************************************************************************
* libcasio/stream.h -- libcasio stream definition.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
*
* The libcasio stream abstraction is there so that the core code can be more
* platform-agnostic (althrough platform-specific helpers are built-in for
* popular platforms like Microsoft Windows or GNU/Linux distributions).
* A stream is basically what separates libcasio from the calculator.
* When data is read from the stream, what is expected is what the calculator
* has sent, and when data is written to the stream, it is what the calculator
* shall receive.
* ************************************************************************* */
#ifndef LIBCASIO_STREAM_H
# define LIBCASIO_STREAM_H
# include "cdefs.h"
CASIO_BEGIN_NAMESPACE
/* forward structure declarations (don't mind) */
struct casio_stream_s;
typedef struct casio_stream_s casio_stream_t;
struct casio_streamfuncs_s;
typedef struct casio_streamfuncs_s casio_streamfuncs_t;
struct casio_streamattrs_s;
typedef struct casio_streamattrs_s casio_streamattrs_t;
struct casio_timeouts_s;
typedef struct casio_timeouts_s casio_timeouts_t;
struct casio_scsi_s;
typedef struct casio_scsi_s casio_scsi_t;
/* ************************************************************************* */
/* Stream */
/* ************************************************************************* */
/* The stream is a private structure that has more or less all of the features
* that the libc FILE interface has, but has more and is cross-platform.
* It is basically what libcasio uses to communicate with the calculator.
*
* 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.
*
* An open mode represents the type of operations you will be able to
* make with a stream. Available open mode flags are:
*
* `READ`: the stream is readable.
* `WRITE`: the stream is writable.
* `TRUNC`: the file will be truncated.
* `APPEND`: will append to the file.
*
* `SEEK`: the stream is seekable.
* `SERIAL`: serial operations are available.
* `SCSI`: SCSI operations are available.
* `USB`: USB operations are available. */
typedef unsigned int casio_openmode_t;
# define CASIO_OPENMODE_READ 0x0001
# define CASIO_OPENMODE_WRITE 0x0002
# define CASIO_OPENMODE_TRUNC 0x0004
# define CASIO_OPENMODE_APPEND 0x0008
# define CASIO_OPENMODE_SEEK 0x0010
# define CASIO_OPENMODE_SERIAL 0x0020
# define CASIO_OPENMODE_SCSI 0x0040
# define CASIO_OPENMODE_USB 0x0080
/* Offset types, to move within a stream, are the following:
* `SET`: set the current position to the offset.
* `CUR`: add the offset to the current position.
* `END`: set the current position to the end minus the offset. */
typedef long casio_off_t;
typedef int casio_whence_t;
# define CASIO_SEEK_SET 1
# define CASIO_SEEK_CUR 2
# define CASIO_SEEK_END 4
/* Here are the callback types: */
typedef int casio_stream_close_t OF((void *));
typedef int casio_stream_setattrs_t
OF((void *, const casio_streamattrs_t *));
typedef int casio_stream_settm_t
OF((void *, const casio_timeouts_t *));
typedef int casio_stream_read_t
OF((void *, unsigned char *, size_t));
typedef int casio_stream_write_t
OF((void *, const unsigned char *, size_t));
typedef int casio_stream_seek_t
OF((void *, casio_off_t *, casio_whence_t));
typedef int casio_stream_scsi_t
OF((void *, casio_scsi_t*));
/* Here is the callbacks structure: */
struct casio_streamfuncs_s {
/* Main callbacks. */
casio_stream_close_t *casio_streamfuncs_close;
casio_stream_settm_t *casio_streamfuncs_settm;
/* Read & Write callbacks. */
casio_stream_read_t *casio_streamfuncs_read;
casio_stream_write_t *casio_streamfuncs_write;
casio_stream_seek_t *casio_streamfuncs_seek;
/* Serial callbacks. */
casio_stream_setattrs_t *casio_streamfuncs_setattrs;
/* SCSI callbacks. */
casio_stream_scsi_t *casio_streamfuncs_scsi;
};
/* And here are some macros, for better API compatibility */
# define casio_stream_callbacks_for_serial(CASIO__CLOSE, CASIO__SETCOMM, \
CASIO__SETTM, CASIO__READ, CASIO__WRITE) \
{(casio_stream_close_t*)(CASIO__CLOSE), \
(casio_stream_settm_t*)(CASIO__SETTM), \
(casio_stream_read_t*)(CASIO__READ), \
(casio_stream_write_t*)(CASIO__WRITE), NULL, \
(casio_stream_setattrs_t*)(CASIO__SETCOMM), \
NULL}
# define casio_stream_callbacks_for_virtual(CASIO__CLOSE, \
CASIO__READ, CASIO__WRITE, CASIO__SEEK) \
{(casio_stream_close_t*)(CASIO__CLOSE), NULL, \
(casio_stream_read_t*)(CASIO__READ), \
(casio_stream_write_t*)(CASIO__WRITE), \
(casio_stream_seek_t*)(CASIO__SEEK), NULL, NULL}
/* ************************************************************************* */
/* Stream settings values and flags */
/* ************************************************************************* */
/* Here are the different baud speeds you can encounter, in bauds.
* Note that one speed is not supported by all models. */
# define CASIO_B1200 1200 /* old models */
# define CASIO_B2400 2400 /* old models */
# define CASIO_B4800 4800 /* old models */
# define CASIO_B9600 9600 /* protocol seven default speed */
# define CASIO_B19200 19200 /* seven alternative speed */
# define CASIO_B38400 38400 /* algebrafx default speed */
# define CASIO_B57600 57600 /* seven alternative speed */
# define CASIO_B115200 115200 /* seven alternative speed */
/* Here are the control characters and other values you have in the
* stream settings. */
# define CASIO_NCCS 0x02 /* number of control characters */
# define CASIO_XON 0x00 /* XON character: re-enable transm. */
# define CASIO_XOFF 0x01 /* XOFF character: disable transm. */
/* From here, those are all in the stream settings flags.
* Here are the stop bits settings: */
# define CASIO_STOPBITSMASK 0x0001
# define CASIO_ONESTOPBIT 0x0000 /* one stop bit */
# define CASIO_TWOSTOPBITS 0x0001 /* two stop bits */
/* Here are the parity settings: */
# define CASIO_PARMASK 0x0006
# define CASIO_PARDIS 0x0000 /* disable parity checking */
# define CASIO_PARENB 0x0002 /* enable parity checking */
# define CASIO_PAREVEN 0x0000 /* even parity */
# define CASIO_PARODD 0x0004 /* odd parity */
/* Here are the DTR/RTS settings.
* Notice that not all platforms implement this. Just do as you can. */
# define CASIO_DTRMASK 0x0018
# define CASIO_DTRCTL_DISABLE 0x0000 /* disable DTR */
# define CASIO_DTRCTL_ENABLE 0x0008 /* enable DTR */
# define CASIO_DTRCTL_HANDSHAKE 0x0010 /* enable DTR and handshake */
# define CASIO_RTSMASK 0x0060
# define CASIO_RTSCTL_DISABLE 0x0000 /* disable RTS */
# define CASIO_RTSCTL_ENABLE 0x0020 /* enable RTS */
# define CASIO_RTSCTL_HANDSHAKE 0x0040 /* enable RTS and handshake */
/* Here are the XON/XOFF software control settings.
* XOFF disables the transmission temporarily, usually because the device at
* the other end can't manage too much data too quickly. */
# define CASIO_XONMASK 0x0080
# define CASIO_XONCTL_DISABLE 0x0000 /* disable XON */
# define CASIO_XONCTL_ENABLE 0x0080 /* enable XON */
/* XON re-enables the transmission, probably because the device at the end
* has finished processing the data you sent and is ready to process more. */
# define CASIO_XOFFMASK 0x0100
# define CASIO_XOFFCTL_DISABLE 0x0000 /* disable XOFF */
# define CASIO_XOFFCTL_ENABLE 0x0100 /* enable XOFF */
/* ************************************************************************* */
/* Stream settings */
/* ************************************************************************* */
/* Here is the stream settings structure: */
struct casio_streamattrs_s {
/* flags - see the above section */
unsigned int casio_streamattrs_flags;
/* speed: one of the CASIO_B* constants */
unsigned int casio_streamattrs_speed;
/* characters */
unsigned char casio_streamattrs_cc[CASIO_NCCS];
};
/* This structure will be sent to your `setcomm` callback to set serial
* communication settings.
* And here is the stream timeouts structure: */
struct casio_timeouts_s {
/* Initial read timeout */
unsigned int casio_timeouts_read;
/* In-between bytes read timeout */
unsigned int casio_timeouts_read_bw;
/* Total write timeout */
unsigned int casio_timeouts_write;
};
/* This structure will be sent to your `settm` callback, usually after a state
* change in the communication. Also, all timeouts are in milliseconds (ms). */
/* ************************************************************************* */
/* SCSI request */
/* ************************************************************************* */
/* CASIO's fx-CG devices, also known as Prizms or Graph 90+E, use SCSI along
* with Protocol 7.00 to communicate with the PC for things like file
* transferring or screenstreaming (which use vendor-specific command slots).
* As systems usually have some standard methods for SCSI, it is worth it
* to implement an SCSI interface into libcasio streams.
*
* This is libcasio's SCSI request structure, inspired from Linux's
* `sg_io_hdr_t` structure, except this structure tries to be cross-platform
* and is just there to fulfill the library's needs.
*
* Here is the different values for the data direction:
*
* `NONE`: no content.
* `TO_DEV`: outgoing data.
* `FROM_DEV`: incoming data. */
# define CASIO_SCSI_DIREC_NONE (-1)
# define CASIO_SCSI_DIREC_TO_DEV (-2)
# define CASIO_SCSI_DIREC_FROM_DEV (-3)
/* And here is the request structure:
*
* `cmd` is the raw command buffer (of 6, 10, 12 or 16 bytes).
* `cmd_len` is the command length (6, 10, 12 or 16).
* `direction` is the data transfer direction.
* `data` is the data to transfer (send or receive buffer).
* `data_len` is the data length.
* `status` is the status byte returned by the device. */
struct casio_scsi_s {
void *casio_scsi_cmd;
unsigned int casio_scsi_cmd_len;
int casio_scsi_direction;
void *casio_scsi_data;
int casio_scsi_data_len;
int casio_scsi_status;
};
/* It will be sent to the `scsi` callback of the stream. */
/* ---
* Public stream functions.
* --- */
CASIO_BEGIN_DECLS
/* Default stream serial settings utilities. */
CASIO_EXTERN int CASIO_EXPORT casio_make_attrs
OF((casio_streamattrs_t *casio__attrs, const char *casio__raw));
/* List serial devices (platform agnostic). */
typedef void CASIO_EXPORT casio_list_com_t
OF((void *casio__cookie, const char *casio__str));
CASIO_EXTERN int CASIO_EXPORT casio_comlist
OF((casio_list_com_t *casio__callback, void *casio__cookie));
/* Open and close a stream. */
CASIO_EXTERN int CASIO_EXPORT casio_open_stream
OF((casio_stream_t **casio__stream, casio_openmode_t mode,
void *casio__cookie, const casio_streamfuncs_t *casio__callbacks,
casio_off_t casio__initial_offset));
CASIO_EXTERN int CASIO_EXPORT casio_close
OF((casio_stream_t *casio__stream));
/* Get stream various data. */
CASIO_EXTERN int CASIO_EXPORT casio_isreadable
OF((casio_stream_t *casio__stream));
CASIO_EXTERN int CASIO_EXPORT casio_iswritable
OF((casio_stream_t *casio__stream));
CASIO_EXTERN int CASIO_EXPORT casio_isseekable
OF((casio_stream_t *casio__stream));
# define casio_isreadable(CASIO__STREAM) \
(casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_READ)
# define casio_iswritable(CASIO__STREAM) \
(casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_WRITE)
# define casio_isseekable(CASIO__STREAM) \
(casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_SEEK)
# define casio_is_readable(CASIO__STREAM) \
casio_isreadable(CASIO__STREAM)
# define casio_is_writable(CASIO__STREAM) \
casio_iswritable(CASIO__STREAM)
# define casio_is_seekable(CASIO__STREAM) \
casio_isseekable(CASIO__STREAM)
CASIO_EXTERN casio_openmode_t CASIO_EXPORT casio_get_openmode
OF((casio_stream_t *casio__stream));
CASIO_EXTERN const casio_streamfuncs_t* CASIO_EXPORT casio_get_streamfuncs
OF((casio_stream_t *casio__stream));
CASIO_EXTERN void* CASIO_EXPORT casio_get_cookie
OF((casio_stream_t *casio__stream));
CASIO_EXTERN int CASIO_EXPORT casio_get_lasterr
OF((casio_stream_t *casio__stream));
/* Read and write data from and to a stream. */
CASIO_EXTERN int CASIO_EXPORT casio_read
OF((casio_stream_t *casio__stream,
void *casio__dest, size_t casio__size));
CASIO_EXTERN int CASIO_EXPORT casio_write
OF((casio_stream_t *casio__stream,
const void *casio__data, size_t casio__size));
CASIO_EXTERN int CASIO_EXPORT casio_write_char
OF((casio_stream_t *casio__stream, int casio__char));
/* Skip bytes from a stream. */
CASIO_EXTERN int CASIO_EXPORT casio_skip
OF((casio_stream_t *casio__stream, size_t casio__size));
/* Set and get the attributes of a stream. */
CASIO_EXTERN int CASIO_EXPORT casio_init_attrs
OF((casio_stream_t *stream));
CASIO_EXTERN int CASIO_EXPORT casio_set_attrs
OF((casio_stream_t *casio__stream,
const casio_streamattrs_t *casio__attrs));
CASIO_EXTERN int CASIO_EXPORT casio_get_attrs
OF((casio_stream_t *casio__stream, casio_streamattrs_t *casio__attrs));
/* Set and get the timeouts of a stream. */
CASIO_EXTERN int CASIO_EXPORT casio_init_timeouts
OF((casio_stream_t *casio__stream));
CASIO_EXTERN int CASIO_EXPORT casio_set_timeouts
OF((casio_stream_t *casio__stream,
const casio_timeouts_t *casio__timeouts));
CASIO_EXTERN int CASIO_EXPORT casio_get_timeouts
OF((casio_stream_t *casio__stream, casio_timeouts_t *casio__timeouts));
/* Move in a file. */
CASIO_EXTERN int CASIO_EXPORT casio_seek
OF((casio_stream_t *casio__stream,
casio_off_t casio__offset, casio_whence_t casio__whence));
CASIO_EXTERN casio_off_t CASIO_EXPORT casio_tell
OF((casio_stream_t *casio__stream));
/* Make out the size of a file (shortcut for making out the size). */
CASIO_EXTERN int CASIO_EXPORT casio_getsize
OF((casio_stream_t *casio__stream, casio_off_t *casio__size));
/* Make a SCSI request. */
CASIO_EXTERN int CASIO_EXPORT casio_scsi_request
OF((casio_stream_t *casio__stream, casio_scsi_t *casio__request));
/* Make a stream out of memory. */
CASIO_EXTERN int CASIO_EXPORT casio_open_memory
OF((casio_stream_t **casio__stream,
const void *casio__memory, size_t casio__size));
/* Make a stream out of another, with a limit (and empty it). */
CASIO_EXTERN int CASIO_EXPORT casio_open_limited
OF((casio_stream_t **casio__stream,
casio_stream_t *casio__original, size_t casio__size));
CASIO_EXTERN int CASIO_EXPORT casio_empty_limited
OF((casio_stream_t *casio__stream));
/* Make a stream out of another, while calculating a 32-bit checksum. */
CASIO_EXTERN int CASIO_EXPORT casio_open_csum32
OF((casio_stream_t **casio__stream, casio_stream_t *casio__original,
casio_uint32_t *casio__csum));
/* ---
* USB and serial stream utilities.
* --- */
/* For platforms whose the utilities aren't built-in, here is a way to add
* your defaults, that will be used with the default functions!
*
* Communication port listing. */
typedef int CASIO_EXPORT casio_comlist_t
OF((casio_list_com_t *casio__callback, void *casio__cookie));
CASIO_EXTERN int CASIO_EXPORT casio_add_default_comlist
OF((casio_comlist_t *casio__function));
/* Serial communication stream opening. */
typedef int casio_opencomstream_t
OF((casio_stream_t **casio__stream, const char *casio__path));
CASIO_EXTERN int CASIO_EXPORT casio_add_default_com_stream
OF((casio_opencomstream_t *casio__function));
CASIO_EXTERN int CASIO_EXPORT casio_open_com_stream
OF((casio_stream_t **casio__stream,
const char *casio__path));
/* USB stream opening.
* The `bus` argument is set to -1 if we ought to find the first appropriate
* argument.
* The `address` argument is set to -1 if we ought to find any device on
* the given bus. */
typedef int CASIO_EXPORT casio_openusbstream_t
OF((casio_stream_t **casio__stream,
int casio__bus, int casio__address));
CASIO_EXTERN int CASIO_EXPORT casio_add_default_usb_stream
OF((casio_openusbstream_t *casio__function));
CASIO_EXTERN int CASIO_EXPORT casio_open_usb_stream
OF((casio_stream_t **casio__stream,
int casio__bus, int casio__address));
CASIO_END_DECLS
CASIO_END_NAMESPACE
# include "builtin.h"
#endif /* LIBCASIO_STREAM_H */
|