mISDNuser/tenovis/lib/tenovis_device.c

172 lines
3.4 KiB
C

/*
* Interface for Tenovis
* device functions
*
*/
#include "tenovis_int.h"
#include "tenovis.h"
/*
* int DL3open(void);
*
* DL3open() opens a device through which the D channel can be accessed.
*
* Returns a file descriptor on success or -1 in case of an error.
* The file descriptor is used in all other DL3* calls and for select().
*
*/
int
DL3open(void)
{
int fid, ret;
tenovisdev_t *dev;
if (0>(fid = mISDN_open()))
return(fid);
dev = get_tdevice(fid);
if (dev) {
fprintf(stderr, __FUNCTION__ " device %d (%p) has allready fid(%d)\n",
dev->fid, dev, fid);
close(fid);
errno = EBUSY;
return(-1);
}
dev = alloc_tdevice(fid);
if (!dev) {
return(-1);
}
ret = setup_tdevice(dev);
if (ret)
ret = -1;
else
ret = fid;
return(ret);
}
/*
*
* int DL3close(int DL3fd)
*
* DL3close(int DL3fd) closes the DL3fd previously opened DL3open().
*
* The file descriptor DL3fd must not be used after DL3close() was called !
*
* Parameter:
* DL3fd : file descriptor assigned by DL3open
*
* Returnvalue:
* 0 on success or -1 if the file descriptor was already closed or
* is not valid.
*
*/
int
DL3close(int DL3fd)
{
tenovisdev_t *dev;
int ret;
dev = get_tdevice(DL3fd);
if (!dev) {
errno = ENODEV;
return(-1);
}
shutdown_tdevice(dev);
ret = free_tdevice(dev);
return(ret);
}
/*
* int DL3write(int DL3fd, const void *buf, size_t count);
*
* Sends a message to the layer 3 of the D channel stack.
*
* Parameter:
* DL3fd : file descriptor assigned by DL3open
* buf : pointer to the message buffer
* count : the length of the message in bytes
*
* Returnvalue:
* 0 on success or -1 on error in which case errno is set.
*
*
*/
extern int DL3write(int DL3fd, const void *buf, size_t count)
{
tenovisdev_t *dev;
int ret;
dev = get_tdevice(DL3fd);
if (!dev) {
errno = ENODEV;
return(-1);
}
if (!count)
return(0);
ret = mISDN_write_frame(dev->fid, dev->buf.p, dev->tlid | IF_UP,
DL_DATA | INDICATION, 0, count, (void *)buf, TIMEOUT_1SEC);
return(ret);
}
/*
* size_t DL3read(int DL3fd, void *buf, size_t count);
*
* Reads a message from the Layer 3 of the D channel stack.
*
* Parameter:
* DL3fd : file descriptor assigned by DL3open
* buf : pointer to the message buffer
* count : the maximum message size which can read
*
* Returnvalue:
* the length of the message in bytes or -1 in case of an error
* -2 if it was an internal (not L3) message
*/
extern size_t DL3read(int DL3fd, void *buf, size_t count)
{
tenovisdev_t *dev;
int ret;
dev = get_tdevice(DL3fd);
if (!dev) {
errno = ENODEV;
return(-1);
}
if (!buf) {
errno = EINVAL;
return(-1);
}
if (!count)
return(0);
if (count > dev->size - IFRAME_HEAD_SIZE)
count = dev->size - IFRAME_HEAD_SIZE;
ret = mISDN_read(dev->fid, dev->buf.p, count + IFRAME_HEAD_SIZE,
TIMEOUT_10SEC);
#ifdef PRINTDEBUG
fprintf(stdout, __FUNCTION__": mISDN_read ret(%d) adr(%x) pr(%x) di(%x) l(%d)\n",
ret, dev->buf.f->addr, dev->buf.f->prim,
dev->buf.f->dinfo, dev->buf.f->len);
#endif
if (ret <= 0)
return(ret);
if (dev->buf.f->addr == (dev->tlid | IF_UP)) {
if (dev->buf.f->prim == (DL_DATA | REQUEST)) {
if (dev->buf.f->len > count) {
errno = ENOSPC;
return(-1);
}
ret = dev->buf.f->len;
memcpy(buf, &dev->buf.f->data.p, ret);
return(ret);
}
}
ret = intern_read(dev);
return(ret);
}