131 lines
2.4 KiB
C
131 lines
2.4 KiB
C
/* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "hisax_capi.h"
|
|
#include "helper.h"
|
|
#include "debug.h"
|
|
|
|
#define plciDebug(plci, lev, fmt, args...) \
|
|
capidebug(lev, fmt, ## args)
|
|
|
|
|
|
void plciConstr(Plci_t *plci, Contr_t *contr, __u32 adrPLCI)
|
|
{
|
|
memset(plci, 0, sizeof(Plci_t));
|
|
plci->adrPLCI = adrPLCI;
|
|
plci->contr = contr;
|
|
}
|
|
|
|
void plciDestr(Plci_t *plci)
|
|
{
|
|
#if 0
|
|
if (plci->l4_pc.l3pc) {
|
|
// FIXME: we need to kill l3_process, actually
|
|
plci->l4_pc.l3pc->l4pc = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void plciHandleSetupInd(Plci_t *plci, int pr, SETUP_t *setup)
|
|
{
|
|
int ApplId;
|
|
__u16 CIPValue;
|
|
Appl_t *appl;
|
|
Cplci_t *cplci;
|
|
|
|
for (ApplId = 1; ApplId <= CAPI_MAXAPPL; ApplId++) {
|
|
appl = contrId2appl(plci->contr, ApplId);
|
|
if (appl) {
|
|
CIPValue = q931CIPValue(setup);
|
|
if (listenHandle(&appl->listen, CIPValue)) {
|
|
cplci = applNewCplci(appl, plci);
|
|
if (!cplci) {
|
|
int_error();
|
|
break;
|
|
}
|
|
cplci_l3l4(cplci, pr, setup);
|
|
}
|
|
}
|
|
}
|
|
if (plci->nAppl == 0) {
|
|
RELEASE_COMPLETE_t relcmpl;
|
|
u_char cause[3] = {2,0x80,0xd8}; /* incompatible destination */
|
|
|
|
memset(&relcmpl, 0, sizeof(RELEASE_COMPLETE_t));
|
|
relcmpl.CAUSE = cause;
|
|
plciL4L3(plci, CC_RELEASE_COMPLETE | REQUEST,
|
|
sizeof(RELEASE_COMPLETE_t), &relcmpl);
|
|
}
|
|
}
|
|
|
|
void plci_l3l4(Plci_t *plci, int pr, void *arg)
|
|
{
|
|
__u16 applId;
|
|
Cplci_t *cplci;
|
|
|
|
switch (pr) {
|
|
case CC_SETUP | INDICATION:
|
|
plciHandleSetupInd(plci, pr, arg);
|
|
break;
|
|
case CC_RELEASE_CR | INDICATION:
|
|
if (plci->nAppl == 0) {
|
|
contrDelPlci(plci->contr, plci);
|
|
}
|
|
break;
|
|
default:
|
|
for (applId = 1; applId <= CAPI_MAXAPPL; applId++) {
|
|
cplci = plci->cplcis[applId - 1];
|
|
if (cplci)
|
|
cplci_l3l4(cplci, pr, arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void plciAttachCplci(Plci_t *plci, Cplci_t *cplci)
|
|
{
|
|
__u16 applId = cplci->appl->ApplId;
|
|
|
|
if (plci->cplcis[applId - 1]) {
|
|
int_error();
|
|
return;
|
|
}
|
|
plci->cplcis[applId - 1] = cplci;
|
|
plci->nAppl++;
|
|
}
|
|
|
|
void plciDetachCplci(Plci_t *plci, Cplci_t *cplci)
|
|
{
|
|
__u16 applId = cplci->appl->ApplId;
|
|
|
|
if (plci->cplcis[applId - 1] != cplci) {
|
|
int_error();
|
|
return;
|
|
}
|
|
cplci->plci = 0;
|
|
plci->cplcis[applId - 1] = 0;
|
|
plci->nAppl--;
|
|
if (plci->nAppl == 0) {
|
|
contrDelPlci(plci->contr, plci);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
void plciNewCrInd(Plci_t *plci, struct l3_process *l3_pc)
|
|
{
|
|
l3_pc->l4pc = &plci->l4_pc;
|
|
l3_pc->l4pc->l3pc = l3_pc;
|
|
}
|
|
#endif
|
|
|
|
void plciNewCrReq(Plci_t *plci)
|
|
{
|
|
plciL4L3(plci, CC_NEW_CR | REQUEST, 0, NULL);
|
|
}
|
|
|
|
int plciL4L3(Plci_t *plci, __u32 prim, int len, void *arg)
|
|
{
|
|
return(contrL4L3(plci->contr, prim, plci->adrPLCI, len, arg));
|
|
}
|
|
|