[En-Nut-Discussion] How to implement a stream
Harald Kipp
harald.kipp at egnite.de
Mon Sep 20 21:24:45 CEST 2004
Ole,
additional informations can be passed with the standard
fopen by using the filename parameter. The PPP driver
provides an example, where you can use
_open("ppp:uart0/user/passwd", _O_RDWR | _O_BINARY)
to pass the physical device (uart0), login name and password
as a path. _open(), which is a child of fopen(), splits
the filename into a device name and a path, if it contains
a colon. The path (the part after the colon) is passed to
the device driver.
However, TCP streams are different, because some additional
action is required before using the socket for a stream.
Like establishing a connection, optionally exchange some
binary data before streaming etc. Thus, Nut/OS uses a so
called NUTVIRTUALDEVICE.
I'll try to explain this too, but it's long time ago I wrote
that.
Because the socket already exisits, you must call fdopen()
instead of fopen(), which 'associates' an already existing
handle (the pointer to the connected socket) to a stream.
fdopen() allocates a FILE structure and stores the handle
in it (socket). Usually the NUTFILE pointer is stored at
this place. Here comes the tricky part. NUTFILE is
struct _NUTFILE {
NUTFILE *nf_next;
struct _NUTDEVICE *nf_dev;
void *nf_fcb;
};
TCPSOCKET starts with
struct tcp_socket {
TCPSOCKET *so_next;
void *so_device;
u_char so_devtype;
int (*so_devread) (TCPSOCKET *, void *, int);
int (*so_devwrite) (TCPSOCKET *, CONST void *, int);
int (*so_devwrite_P) (TCPSOCKET *, PGM_P, int);
int (*so_devioctl) (TCPSOCKET *, int, void *);
...
so_device is a dummy and always zero.
For I/O, Nut/OS stream functions will finally call _read()
and _write(). These routines retrieve the NUTFILE pointer
from FILE, which points to TCPSOCKET in out case. Then
it retrieves the pointer nf_dev to the NUTDEVICE, but will
get so_device, which is zero. Now _read() and _write()
'know' that this is no normal device, but a virtual.
The pointer to NUTFILE is now interpreted as a pointer
to NUTVIRTUALDEVICE.
struct _NUTVIRTUALDEVICE {
NUTVIRTUALDEVICE *vdv_next;
NUTVIRTUALDEVICE *vdv_zero;
u_char vdv_type;
int (*vdv_read) (void *, void *, int);
int (*vdv_write) (void *, CONST void *, int);
int (*vdv_write_P) (void *, PGM_P, int);
int (*vdv_ioctl) (void *, int, void *);
};
This perfectly fits to the TCPSOCKET structure and
offers vdv_read, vdv_write, vdv_write_P and vdv_ioctl,
actually pointing to the proper socket routines.
Sooooouuuu....
You need to create some kind of socket structure (BLUESOCKET?)
and make sure, that the beginning of the structure matches
NUTVIRTUALDEVICE.
Then you create your protocol specific routines to get a
connection, set all options etc. This "Bluetooth API" is
called by your application to establish a link.
Finally you implement the read, write and optional ioctl
funtions, which work similar to those in NUTDEVICE.
You application will call fdopen() with a pointer to BLUESOCKET
and receive a stream pointer in return.
Hope I got this right. I took several redesigns until I got
it that way. No idea, if there are better solutions. But this
one is portable and not limited to sockets.
Harald
At 18:32 20.09.2004 +0200, you wrote:
>Hi Harald,
>
> > a very short roadmap:
>
>Thanks! This will help alot. But one more thing I'm interested in:
>
>I would like to write my own fopen function where I coul pass some more
>information with. I need a framework similar to the socket functions of
>your IP stack since l2cap is quite similar to TCP.
>
>Next I would need some functions to wait on a filepointer until data has
>arrived... (This should work similar to a TCP deamon that waits until
>someone opens a connection on a dedicated port).
>
>Could you also give me a hint how to implement this?
>
>Thanks,
>
>Ole
>--
>kernel concepts Tel: +49-271-771091-14
>Dreisbachstr. 24 Fax: +49-271-771091-19
>D-57250 Netphen E+ : +49-177-7420433
>--
>
>
>_______________________________________________
>En-Nut-Discussion mailing list
>En-Nut-Discussion at egnite.de
>http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion
More information about the En-Nut-Discussion
mailing list