mISDNuser/tenovis/lib/tenovis_intern.c

294 lines
7.9 KiB
C

/*
* Internal functions for Tenovis lib
*
*/
#include "tenovis_int.h"
#include "tenovis.h"
static tenovisdev_t *tdevlist = NULL;
static pthread_mutex_t tdevlist_lock = PTHREAD_MUTEX_INITIALIZER;
tenovisdev_t *
alloc_tdevice(int fid)
{
tenovisdev_t *dev;
dev = malloc(sizeof(tenovisdev_t));
if (!dev) {
close(fid);
errno = ENODEV;
return(NULL);
}
memset(dev, 0, sizeof(tenovisdev_t));
dev->fid = fid;
dev->size = TN_INBUFFER_SIZE;
dev->buf.p = malloc(dev->size);
if (!dev->buf.p) {
close(fid);
free(dev);
errno = ENODEV;
return(NULL);
}
pthread_mutex_init(&dev->mutex, NULL);
pthread_mutex_lock(&tdevlist_lock);
dev->prev = tdevlist;
while(dev->prev && dev->prev->next)
dev->prev = dev->prev->next;
if (tdevlist)
dev->prev->next = dev;
else
tdevlist = dev;
pthread_mutex_unlock(&tdevlist_lock);
return(dev);
}
tenovisdev_t *
get_tdevice(int fid)
{
tenovisdev_t *dev;
pthread_mutex_lock(&tdevlist_lock);
dev = tdevlist;
while(dev) {
if (dev->fid==fid)
break;
dev = dev->next;
}
pthread_mutex_unlock(&tdevlist_lock);
return(dev);
}
int
free_tdevice(tenovisdev_t *dev)
{
int ret;
if (dev->prev)
dev->prev->next = dev->next;
if (dev->next)
dev->next->prev = dev->prev;
if (tdevlist==dev)
tdevlist=dev->next;
pthread_mutex_lock(&dev->mutex);
if (dev->buf.p)
free(dev->buf.p);
dev->buf.p = NULL;
pthread_mutex_unlock(&dev->mutex);
ret = pthread_mutex_destroy(&dev->mutex);
if (ret)
fprintf(stderr, __FUNCTION__ "mutex destroy returns %d\n",
ret);
ret = mISDN_close(dev->fid);
free(dev);
return(ret);
}
int
setup_tdevice(tenovisdev_t *dev)
{
int ret;
stack_info_t *stinf;
layer_info_t linf;
interface_info_t iinf;
ret = mISDN_write_frame(dev->fid, dev->buf.p, 0,
MGR_SETDEVOPT | REQUEST, FLG_mISDNPORT_ONEFRAME,
0, NULL, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "MGR_SETDEVOPT ret(%d)\n", ret);
#endif
ret = mISDN_read(dev->fid, dev->buf.p, 1024, TIMEOUT_10SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_read ret(%d) pr(%x) di(%x) l(%d)\n",
ret, dev->buf.f->prim, dev->buf.f->dinfo, dev->buf.f->len);
#endif
ret = mISDN_get_stack_count(dev->fid);
#ifdef PRINTDEBUG
fprintf(stdout, "stackcnt %d\n", ret);
#endif
if (ret <= 0) {
free_tdevice(dev);
errno = ENODEV;
return(-1);
}
ret = mISDN_get_stack_info(dev->fid, 1, dev->buf.p, dev->size);
stinf = (stack_info_t *)&dev->buf.f->data.p;
#ifdef PRINTDEBUG
mISDNprint_stack_info(stdout, stinf);
fprintf(stdout, "ext(%x) instcnt(%d) childcnt(%d)\n",
stinf->extentions, stinf->instcnt, stinf->childcnt);
#endif
dev->dstid = stinf->id;
dev->dl0id = mISDN_get_layerid(dev->fid, dev->dstid, 0);
dev->dl1id = mISDN_get_layerid(dev->fid, dev->dstid, 1);
dev->dl2id = mISDN_get_layerid(dev->fid, dev->dstid, 2);
dev->dl3id = mISDN_get_layerid(dev->fid, dev->dstid, 3);
dev->dl4id = mISDN_get_layerid(dev->fid, dev->dstid, 4);
#ifdef PRINTDEBUG
fprintf(stdout, " dl0id = %08x\n", dev->dl0id);
fprintf(stdout, " dl1id = %08x\n", dev->dl1id);
fprintf(stdout, " dl2id = %08x\n", dev->dl2id);
fprintf(stdout, " dl3id = %08x\n", dev->dl3id);
fprintf(stdout, " dl4id = %08x\n", dev->dl4id);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl2id;
iinf.stat = IF_UP;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l2 up own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl2id;
iinf.stat = IF_DOWN;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l2 down own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl3id;
iinf.stat = IF_UP;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l3 up own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl3id;
iinf.stat = IF_DOWN;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l3 down own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
#endif
memset(&linf, 0, sizeof(layer_info_t));
strcpy(&linf.name[0], "tenovis L2");
linf.object_id = -1;
linf.extentions = EXT_INST_MIDDLE;
linf.pid.protocol[stinf->instcnt] = ISDN_PID_ANY;
linf.pid.layermask = ISDN_LAYER(stinf->instcnt);
linf.st = dev->dstid;
dev->tlid = mISDN_new_layer(dev->fid, &linf);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_new_layer ret(%x)\n", dev->tlid);
ret = mISDN_get_stack_info(dev->fid, 1, dev->buf.p, dev->size);
stinf = (stack_info_t *)&dev->buf.f->data.p;
mISDNprint_stack_info(stdout, stinf);
#endif
memset(&iinf, 0, sizeof(interface_info_t));
iinf.extentions = EXT_INST_MIDDLE;
iinf.owner = dev->tlid;
iinf.peer = dev->dl3id;
iinf.stat = IF_UP;
ret = mISDN_write_frame(dev->fid, dev->buf.p, dev->tlid,
MGR_SETIF | REQUEST, 0, sizeof(interface_info_t),
&iinf, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_write_frame ret(%d)\n", ret);
#endif
ret = mISDN_read(dev->fid, dev->buf.p, 1024, TIMEOUT_10SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_read ret(%d) pr(%x) di(%x) l(%d)\n",
ret, dev->buf.f->prim, dev->buf.f->dinfo,
dev->buf.f->len);
#endif
memset(&iinf, 0, sizeof(interface_info_t));
iinf.extentions = EXT_INST_MIDDLE;
iinf.owner = dev->tlid;
iinf.peer = dev->dl2id;
iinf.stat = IF_DOWN;
ret = mISDN_write_frame(dev->fid, dev->buf.p, dev->tlid,
MGR_SETIF | REQUEST, 0, sizeof(interface_info_t),
&iinf, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_write_frame ret(%d)\n", ret);
#endif
ret = mISDN_read(dev->fid, dev->buf.p, 1024, TIMEOUT_10SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_read ret(%d) pr(%x) di(%x) l(%d)\n",
ret, dev->buf.f->prim, dev->buf.f->dinfo,
dev->buf.f->len);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl2id;
iinf.stat = IF_UP;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l2 up own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl2id;
iinf.stat = IF_DOWN;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l2 down own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl3id;
iinf.stat = IF_UP;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l3 up own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
memset(&iinf, 0, sizeof(interface_info_t));
iinf.owner = dev->dl3id;
iinf.stat = IF_DOWN;
ret = mISDN_get_interface_info(dev->fid, &iinf);
fprintf(stdout, "l3 down own(%x) -> peer(%x)\n",
iinf.owner, iinf.peer);
#endif
return(0);
}
int
shutdown_tdevice(tenovisdev_t *dev)
{
int ret;
pthread_mutex_lock(&dev->mutex);
if (dev->buf.p) {
if (dev->tlid) {
ret = mISDN_write_frame(dev->fid, dev->buf.p,
dev->tlid, MGR_DELLAYER | REQUEST,
0, 0, NULL, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "MGR_DELLAYER ret(%d)\n", ret);
#endif
ret = mISDN_read(dev->fid, dev->buf.p, 1024,
TIMEOUT_10SEC);
#ifdef PRINTDEBUG
fprintf(stdout, "mISDN_read ret(%d) pr(%x) di(%x) l(%d)\n",
ret, dev->buf.f->prim, dev->buf.f->dinfo,
dev->buf.f->len);
#endif
}
}
pthread_mutex_unlock(&dev->mutex);
return(0);
}
int
intern_read(tenovisdev_t *dev)
{
int ret;
#ifdef PRINTDEBUG
fprintf(stdout, __FUNCTION__" addr(%x) prim(%x)\n",
dev->buf.f->addr, dev->buf.f->prim);
#endif
if (dev->buf.f->addr == (dev->tlid | IF_UP)) {
if (dev->buf.f->prim == (DL_ESTABLISH | REQUEST)) {
dev->Flags |= TN_FLG_L2_ACTIV;
ret = mISDN_write_frame(dev->fid, dev->buf.p,
dev->tlid | IF_UP, DL_ESTABLISH | CONFIRM,
0, 0, NULL, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, __FUNCTION__": estab cnf ret(%d)\n",
ret);
#endif
} else if (dev->buf.f->prim == (DL_RELEASE | REQUEST)) {
dev->Flags &= ~TN_FLG_L2_ACTIV;
ret = mISDN_write_frame(dev->fid, dev->buf.p,
dev->tlid | IF_UP, DL_RELEASE | CONFIRM,
0, 0, NULL, TIMEOUT_1SEC);
#ifdef PRINTDEBUG
fprintf(stdout, __FUNCTION__": rel cnf ret(%d)\n",
ret);
#endif
}
}
return(-2);
}