many capi fixes

This commit is contained in:
Karsten Keil 2001-02-22 05:54:40 +00:00
parent 6b1b8a908f
commit d8e1f9e7f2
10 changed files with 233 additions and 75 deletions

View File

@ -6,10 +6,8 @@
#include "helper.h"
#include "debug.h"
#if 0
#define applDebug(appl, lev, fmt, args...) \
debug(lev, appl->contr->cs, "", fmt, ## args)
#endif
capidebug(lev, fmt, ## args)
void applConstr(Appl_t *appl, Contr_t *contr, __u16 ApplId, capi_register_params *rp)
{
@ -261,7 +259,8 @@ void applManufacturerReqI4L(Appl_t *appl, struct sk_buff *skb)
bchannel = manuReq->f.leased.BChannel;
if (bchannel < 1 || bchannel > 2)
goto out;
L4L3(appl->contr, CC_SETUP | INDICATION, &bchannel);
// FIXME
// contrL4L3(appl->contr, CC_SETUP | INDICATION, &bchannel);
break;
case FUNCTION_I4L_DEC_USE_COUNT:
break;

View File

@ -25,6 +25,20 @@ MODULE_PARM(debug, "1i");
#define Capi20Init init_module
#endif
static char deb_buf[256];
void capidebug(int level, char *fmt, ...)
{
va_list args;
if (debug & level) {
va_start(args, fmt);
vsprintf(deb_buf, fmt, args);
printk(KERN_DEBUG "%s\n", deb_buf);
va_end(args);
}
}
// ---------------------------------------------------------------------------
// registration to kernelcapi
@ -136,6 +150,52 @@ int CapiNew(void)
return 0;
}
static int
add_if_contr(Contr_t *ctrl, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &ctrl->inst;
printk(KERN_DEBUG "capi add_if lay %d/%x prot %x\n", hif->layer,
hif->stat, hif->protocol);
if (IF_TYPE(hif) == IF_UP) {
printk(KERN_WARNING "capi add_if here is no UP interface\n");
} else if (IF_TYPE(hif) == IF_DOWN) {
hif->fdata = ctrl;
hif->func = contrL3L4;
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
err = capi_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
}
} else
return(-EINVAL);
return(0);
}
static int
del_if(hisaxinstance_t *inst, hisaxif_t *hif) {
int err;
printk(KERN_DEBUG "capi del_if lay %d/%x %p/%p\n", hif->layer,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
inst->up.protocol = ISDN_PID_NONE;
err = capi_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
} else if ((hif->func == inst->down.func) && (hif->fdata == inst->down.fdata)) {
inst->down.stat = IF_NOACTIV;
inst->down.protocol = ISDN_PID_NONE;
err = capi_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
} else {
printk(KERN_DEBUG "capi del_if no if found\n");
return(-EINVAL);
}
return(0);
}
static int
capi20_manager(void *data, u_int prim, void *arg) {
@ -158,19 +218,19 @@ capi20_manager(void *data, u_int prim, void *arg) {
printk(KERN_WARNING "capi20_manager create_ctrl failed\n");
return(-EINVAL);
}
return(add_if(ctrl, arg));
return(add_if_contr(ctrl, arg));
break;
case MGR_DELIF | REQUEST:
if (!ctrl) {
printk(KERN_WARNING "capi20_manager delif no instance\n");
return(-EINVAL);
}
return(del_if(ctrl, arg));
return(del_if(&ctrl->inst, arg));
break;
case MGR_RELEASE | INDICATION:
if (ctrl) {
printk(KERN_DEBUG "release_capi20 id %x\n", ctrl->inst.st->id);
release_udss1(ctrl);
delContr(ctrl);
} else
printk(KERN_WARNING "capi20_manager release no instance\n");
break;
@ -217,7 +277,7 @@ void cleanup_module(void)
if (contrlist) {
printk(KERN_WARNING "hisaxl3 contrlist not empty\n");
while(contrlist)
release_contr(contrlist);
delContr(contrlist);
capi_obj.ilist = NULL;
}
detach_capi_driver(&hisax_driver);

View File

@ -33,6 +33,7 @@ void init_ncci(void);
void free_listen(void);
void free_cplci(void);
void free_ncci(void);
void capidebug(int, char *, ...);
#define SuppServiceCF 0x00000010
#define SuppServiceTP 0x00000002
@ -58,6 +59,7 @@ typedef struct _DummyProcess {
__u16 invokeId;
__u16 Function;
__u32 Handle;
__u32 adrDummy;
__u16 ApplId;
struct _Contr *contr;
struct timer_list tl;
@ -141,6 +143,7 @@ typedef struct _Contr {
struct _Contr *prev;
struct _Contr *next;
hisaxinstance_t inst;
hisaxinstance_t *ch_list;
struct capi_ctr *ctrl;
__u32 adrController;
int b3_mode;
@ -168,10 +171,11 @@ struct _Plci *contrNewPlci(Contr_t *contr);
struct _Appl *contrId2appl(Contr_t *contr, __u16 ApplId);
struct _Plci *contrAdr2plci(Contr_t *contr, __u32 adr);
void contrDelPlci(Contr_t *contr, struct _Plci *plci);
void contrDummyInd(Contr_t *contr, struct sk_buff *skb);
void contrDummyInd(Contr_t *, __u32, void *);
DummyProcess_t *contrNewDummyPc(Contr_t *contr);
DummyProcess_t *contrId2DummyPc(Contr_t *contr, __u16 invokeId);
int contrL4L3(Contr_t *, __u32, l3msg_t *);
int contrL3L4(hisaxif_t *, u_int, u_int, int, void *);
// ---------------------------------------------------------------------------
// struct Listen
@ -265,20 +269,22 @@ void plciAttachCplci(Plci_t *plci, struct _Cplci *cplci);
void plciDetachCplci(Plci_t *plci, struct _Cplci *cplci);
void plciNewCrInd(Plci_t *plci, void *);
void plciNewCrReq(Plci_t *plci);
int plciL4L3(Plci_t *plci, __u32 prim, void *arg);
// ---------------------------------------------------------------------------
// struct Cplci
typedef struct _Cplci {
__u32 adrPLCI;
Plci_t *plci;
Appl_t *appl;
struct _Ncci *ncci;
Contr_t *contr;
struct FsmInst plci_m;
u_char cause[3]; // we may get a cause from l3 DISCONNECT message
// which we'll need send in DISCONNECT_IND caused by
// l3 RELEASE message
__u32 adrPLCI;
Plci_t *plci;
Appl_t *appl;
struct _Ncci *ncci;
Contr_t *contr;
struct FsmInst plci_m;
u_char cause[4]; // we may get a cause from l3 DISCONNECT message
// which we'll need send in DISCONNECT_IND caused by
// l3 RELEASE message
int bchannel;
struct Bprotocol Bprotocol;
} Cplci_t;
@ -303,9 +309,7 @@ int cplciFacResumeReq(Cplci_t *cplci, struct FacReqParm *facReqParm,
// Ncci_t
typedef struct _Ncci {
struct _Ncci *prev;
struct _Ncci *next;
hisaxinstance_t inst;
hisaxinstance_t *inst;
__u32 adrNCCI;
Contr_t *contr;
Cplci_t *cplci;

View File

@ -6,30 +6,40 @@
#include "helper.h"
#include "debug.h"
#if 0
#define contrDebug(contr, lev, fmt, args...) \
debug(lev, contr->cs, "Contr ", fmt, ## args)
#endif
capidebug(lev, fmt, ## args)
static int contr_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg);
//static void d2_listener(struct IsdnCardState *cs, u_char *buf, int len);
int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t *ocapi)
{
char tmp[10];
int lay, err;
hisaxstack_t *cst = st->child;
hisaxinstance_t *inst;
memset(contr, 0, sizeof(Contr_t));
contr->adrController = st->id;
contr->inst.obj = ocapi;
APPEND_TO_LIST(contr, ocapi->ilist);
while(cst) {
if (!(inst = kmalloc(sizeof(hisaxinstance_t), GFP_KERNEL))) {
printk(KERN_ERR "no mem for inst\n");
int_error();
return -ENOMEM;
}
inst->st = cst;
inst->obj = ocapi;
APPEND_TO_LIST(inst, contr->ch_list);
cst = cst->next;
}
sprintf(tmp, "HiSax%d", contr->adrController);
contr->ctrl = cdrv_if->attach_ctr(&hisax_driver, tmp, contr);
if (!contr->ctrl)
return -ENODEV;
contr->inst.protocol = hif->protocol;
contr->inst.obj = ocapi;
contr->inst.layer = hif->layer;
contr->inst.data = contr;
APPEND_TO_LIST(contr, ocapi->ilist);
ocapi->ctrl(st, MGR_ADDLAYER | INDICATION, &contr->inst);
contr->inst.up.protocol = ISDN_PID_NONE;
contr->inst.up.layer = 0;
@ -44,7 +54,6 @@ int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t
contr->inst.down.stat = IF_UP;
err = ocapi->ctrl(st, MGR_ADDIF | REQUEST, &contr->inst.down);
if (err) {
release_(contr);
printk(KERN_ERR "contrConstr down interface request failed %d\n", err);
return(-EIO);
}
@ -54,6 +63,7 @@ int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t
void contrDestr(Contr_t *contr)
{
int i;
Contr_t *base = contr->inst.obj->ilist;
for (i = 0; i < CAPI_MAXAPPL; i++) {
if (contr->appls[i]) {
@ -73,7 +83,16 @@ void contrDestr(Contr_t *contr)
kfree(contr->dummy_pcs[i]);
}
}
cdrv_if->detach_ctr(contr->ctrl);
if (contr->ctrl)
cdrv_if->detach_ctr(contr->ctrl);
while (contr->ch_list) {
hisaxinstance_t *inst = contr->ch_list;
REMOVE_FROM_LISTBASE(inst, contr->ch_list);
kfree(inst);
}
REMOVE_FROM_LISTBASE(contr, base);
contr->inst.obj->ilist = base;
}
void contrRun(Contr_t *contr)
@ -289,8 +308,8 @@ static Plci_t
return(NULL);
}
static int
contr_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
int
contrL3L4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
{
Contr_t *contr;
Plci_t *plci;
@ -306,12 +325,11 @@ contr_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
if (!plci)
return(-EBUSY);
l3msg->id = plci->adrPLCI;
} else if (prim == (CC_DUMMY | INDICATION)) {
contrDummyInd(contr, arg);
} else if ((l3msg->id & ~CONTROLER_MASK) == DUMMY_CR_FLAG) {
contrDummyInd(contr, prim, l3msg->arg);
} else {
if (!(plci = contrGetPLCI4addr(contr, l3msg->id))) {
contrDebug(contr, LL_DEB_WARN, __FUNCTION__
": unknown plci prim(%x) id(%x)", prim, l3msg->id);
contrDebug(contr, LL_DEB_WARN, __FUNCTION__ ": unknown plci prim(%x) id(%x)", prim, l3msg->id);
return(-ENODEV);
}
plci_l3l4(plci, prim, l3msg->arg);
@ -319,6 +337,16 @@ contr_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
return(0);
}
int contrL4L3(Contr_t *contr, __u32 prim, l3msg_t *l3msg) {
int err = -EINVAL;
if (contr->inst.up.func) {
err = contr->inst.up.func(&contr->inst.up, prim, 0,
DTYPE_L3MSGP, l3msg);
}
return(err);
}
void contrPutStatus(Contr_t *contr, char *msg)
{
printk(KERN_DEBUG "HiSax: %s", msg);
@ -340,6 +368,7 @@ Contr_t *newContr(hisaxobject_t *ocapi, hisaxstack_t *st, hisaxif_t *hif)
return(NULL);
if (contrConstr(contr, st, hif, ocapi) != 0) {
contrDestr(contr);
kfree(contr);
return(NULL);
}

View File

@ -7,10 +7,8 @@
#include "debug.h"
#include "dss1.h"
#if 0
#define cplciDebug(cplci, lev, fmt, args...) \
debug(lev, cplci->contr->cs, "", fmt, ## args)
#endif
capidebug(lev, fmt, ## args)
static u_char BEARER_SPEECH_64K_ALAW[4] = {3, 0x80, 0x90, 0xA3};
static u_char BEARER_SPEECH_64K_ULAW[4] = {3, 0x80, 0x90, 0xA2};
@ -296,7 +294,7 @@ static void plci_connect_req(struct FsmInst *fi, int event, void *arg)
}
plciNewCrReq(plci);
p_L4L3(plci, CC_SETUP | REQUEST, &setup_req);
plciL4L3(plci, CC_SETUP | REQUEST, &setup_req);
answer:
capi_cmsg_answer(cmsg);
cmsg->Info = Info;
@ -329,7 +327,7 @@ static void plci_suspend_req(struct FsmInst *fi, int event, void *arg)
Cplci_t *cplci = fi->userdata;
Plci_t *plci = cplci->plci;
p_L4L3(plci, CC_SUSPEND | REQUEST, arg);
plciL4L3(plci, CC_SUSPEND | REQUEST, arg);
}
static void plci_resume_req(struct FsmInst *fi, int event, void *arg)
@ -342,7 +340,7 @@ static void plci_resume_req(struct FsmInst *fi, int event, void *arg)
FsmChangeState(fi, ST_PLCI_P_RES);
plciNewCrReq(plci);
p_L4L3(plci, CC_RESUME | REQUEST, arg);
plciL4L3(plci, CC_RESUME | REQUEST, arg);
}
static void plci_alert_req(struct FsmInst *fi, int event, void *arg)
@ -358,7 +356,7 @@ static void plci_alert_req(struct FsmInst *fi, int event, void *arg)
} else {
Info = cmsg2alerting_req(cmsg, &alerting_req);
if (Info == 0) {
p_L4L3(plci, CC_ALERTING | REQUEST, &alerting_req);
plciL4L3(plci, CC_ALERTING | REQUEST, &alerting_req);
}
}
@ -381,7 +379,7 @@ static void plci_connect_resp(struct FsmInst *fi, int event, void *arg)
int_error();
}
cplciClearOtherApps(cplci);
p_L4L3(plci, CC_SETUP | RESPONSE, 0);
plciL4L3(plci, CC_CONNECT | REQUEST, 0);
FsmChangeState(fi, ST_PLCI_P_4);
break;
default : // ignore, reject
@ -411,9 +409,9 @@ static void plci_connect_resp(struct FsmInst *fi, int event, void *arg)
// if we already answered, we can't just ignore but must clear actively
memset(&disconnect_req, 0, sizeof(DISCONNECT_t));
disconnect_req.CAUSE = cause;
p_L4L3(plci, CC_DISCONNECT | REQUEST, &disconnect_req);
plciL4L3(plci, CC_DISCONNECT | REQUEST, &disconnect_req);
} else {
p_L4L3(plci, CC_RESET | REQUEST, 0);
plciL4L3(plci, CC_RESET | REQUEST, 0);
}
}
@ -459,12 +457,12 @@ static void plci_disconnect_req(struct FsmInst *fi, int event, void *arg)
cplciLinkDown(cplci);
if (cplci->cause[0]) { // FIXME
p_L4L3(plci, CC_RELEASE | REQUEST, 0);
plciL4L3(plci, CC_RELEASE | REQUEST, 0);
} else {
memset(&disconnect_req, 0, sizeof(DISCONNECT_t));
memcpy(cause, "\x02\x80\x90", 3); // normal call clearing
disconnect_req.CAUSE = cause;
p_L4L3(plci, CC_DISCONNECT | REQUEST, &disconnect_req);
plciL4L3(plci, CC_DISCONNECT | REQUEST, &disconnect_req);
}
}
@ -567,7 +565,7 @@ static void plci_cc_disconnect_ind(struct FsmInst *fi, int event, void *arg)
memcpy(cplci->cause, disc->CAUSE, 3);
if (!(cplci->appl->listen.InfoMask & CAPI_INFOMASK_EARLYB3)) {
cplciLinkDown(cplci);
p_L4L3(cplci->plci, CC_RELEASE | REQUEST, 0);
plciL4L3(cplci->plci, CC_RELEASE | REQUEST, 0);
}
}
@ -701,9 +699,15 @@ static void plci_cc_resume_err(struct FsmInst *fi, int event, void *arg)
static void plci_cc_resume_conf(struct FsmInst *fi, int event, void *arg)
{
Cplci_t *cplci = fi->userdata;
RESUME_ACKNOWLEDGE_t *ack = arg;
_cmsg cmsg;
__u8 tmp[10], *p;
if (!ack || !ack->CHANNEL_ID) {
int_error();
return;
}
cplci->bchannel = ack->CHANNEL_ID[1];
cplciCmsgHeader(cplci, &cmsg, CAPI_FACILITY, CAPI_IND);
p = &tmp[1];
p += capiEncodeWord(p, 0x0005); // Suspend
@ -747,7 +751,7 @@ static void plci_info_req_overlap(struct FsmInst *fi, int event, void *arg)
Info = cmsg2info_req(cmsg, &info_req);
if (Info == CapiSuccess) {
p_L4L3(plci, CC_INFO | REQUEST, &info_req);
plciL4L3(plci, CC_INFO | REQUEST, &info_req);
}
capi_cmsg_answer(cmsg);
@ -854,6 +858,7 @@ void cplciConstr(Cplci_t *cplci, Appl_t *appl, Plci_t *plci)
cplci->plci_m.debug = 0;
cplci->plci_m.userdata = cplci;
cplci->plci_m.printdebug = cplci_debug;
cplci->bchannel = -1;
}
void cplciDestr(Cplci_t *cplci)
@ -894,7 +899,9 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
cplciInfoIndIE(cplci, IE_FACILITY, CAPI_INFOMASK_FACILITY,
p.setup->FACILITY);
cplciInfoIndIE(cplci, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID,
p.setup->FACILITY);
p.setup->CHANNEL_ID);
if (p.setup->CHANNEL_ID)
cplci->bchannel = p.setup->CHANNEL_ID[1];
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_IND, arg);
break;
case CC_TIMEOUT | INDICATION:
@ -914,6 +921,8 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
CAPI_INFOMASK_FACILITY, p.conn->FACILITY);
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
CAPI_INFOMASK_CHANNELID, p.conn->CHANNEL_ID);
if (p.conn->CHANNEL_ID)
cplci->bchannel = p.conn->CHANNEL_ID[1];
}
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_CONF, arg);
break;
@ -923,6 +932,8 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
CAPI_INFOMASK_DISPLAY, p.c_ack->DISPLAY);
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
CAPI_INFOMASK_CHANNELID, p.c_ack->CHANNEL_ID);
if (p.c_ack->CHANNEL_ID)
cplci->bchannel = p.c_ack->CHANNEL_ID[1];
}
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_COMPL_IND, arg);
break;
@ -982,6 +993,8 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
p.s_ack->PROGRESS);
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
CAPI_INFOMASK_CHANNELID, p.s_ack->CHANNEL_ID);
if (p.s_ack->CHANNEL_ID)
cplci->bchannel = p.s_ack->CHANNEL_ID[1];
}
break;
case CC_PROCEEDING | INDICATION:
@ -995,6 +1008,8 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
p.proc->PROGRESS);
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
CAPI_INFOMASK_CHANNELID, p.proc->CHANNEL_ID);
if (p.proc->CHANNEL_ID)
cplci->bchannel = p.proc->CHANNEL_ID[1];
}
break;
case CC_ALERTING | INDICATION:
@ -1012,6 +1027,8 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
CAPI_INFOMASK_FACILITY, p.alert->FACILITY);
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
CAPI_INFOMASK_CHANNELID, p.alert->CHANNEL_ID);
if (p.alert->CHANNEL_ID)
cplci->bchannel = p.alert->CHANNEL_ID[1];
}
break;
case CC_PROGRESS | INDICATION:
@ -1099,6 +1116,16 @@ void cplciLinkUp(Cplci_t *cplci)
{
if (cplci->ncci)
return;
if (cplci->bchannel == -1) {/* no valid channel set */
int_error();
return;
}
if (!(cplci->bchannel & 3) || ((cplci->bchannel & 3) == 3)) {
// at the moment only B-channel 1 or B-channel 2 allowed
int_error();
return;
}
cplci->ncci = kmalloc(sizeof(Ncci_t), GFP_ATOMIC);
if (!cplci->ncci) {

View File

@ -6,10 +6,8 @@
#include "helper.h"
#include "debug.h"
#if 0
#define listenDebug(listen, lev, fmt, args...) \
debug(lev, listen->contr->cs, "", fmt, ## args)
#endif
capidebug(lev, fmt, ## args)
// --------------------------------------------------------------------
// LISTEN state machine
@ -189,3 +187,7 @@ void init_listen(void)
FsmNew(&listen_fsm, fn_listen_list, FN_LISTEN_COUNT);
}
void free_listen(void)
{
FsmFree(&listen_fsm);
}

View File

@ -7,6 +7,8 @@
#include "debug.h"
#include "dss1.h"
static int ncciL4L3(Ncci_t *ncci, u_int prim, int dtyp, void *arg);
// --------------------------------------------------------------------
// NCCI state machine
@ -123,7 +125,7 @@ static void ncci_connect_b3_req(struct FsmInst *fi, int event, void *arg)
ncciRecvCmsg(ncci, cmsg);
if (cmsg->Info < 0x1000)
L4L3(ncci, DL_ESTABLISH | REQUEST, 0);
ncciL4L3(ncci, DL_ESTABLISH | REQUEST, 0, 0);
}
static void ncci_connect_b3_ind(struct FsmInst *fi, int event, void *arg)
@ -177,7 +179,7 @@ static void ncci_disconnect_b3_req(struct FsmInst *fi, int event, void *arg)
ncciRecvCmsg(ncci, cmsg);
} else {
ncciRecvCmsg(ncci, cmsg);
L4L3(ncci, DL_RELEASE | REQUEST, 0);
ncciL4L3(ncci, DL_RELEASE | REQUEST, 0, 0);
}
}
@ -336,7 +338,7 @@ void ncciInitSt(Ncci_t *ncci)
{
#if 0
struct StackParams sp;
int bchannel, retval;
int retval;
Cplci_t *cplci = ncci->cplci;
ncci->l4.st = kmalloc(sizeof(struct PStack), GFP_ATOMIC);
@ -345,19 +347,18 @@ void ncciInitSt(Ncci_t *ncci)
return;
}
memset(ncci->l4.st, 0, sizeof(struct PStack));
bchannel = cplci->plci->l4_pc.l3pc->para.bchannel - 1;
sp.b1_mode = cplci->Bprotocol.B1protocol;
sp.b2_mode = cplci->Bprotocol.B2protocol;
sp.b3_mode = cplci->Bprotocol.B3protocol;
sp.headroom = 22; // reserve space for DATA_B3 IND message in skb's
retval = init_st(&ncci->l4, cplci->contr->cs, &sp, bchannel);
retval = init_st(&ncci->l4, cplci->contr->cs, &sp, cplci->bchannel);
if (retval) {
int_error();
return;
}
if (sp.b2_mode != B2_MODE_TRANS || !test_bit(PLCI_FLAG_OUTGOING, &cplci->plci->flags)) {
// listen for e.g. SABME
L4L3(&ncci->l4, PH_ACTIVATE | REQUEST, 0);
ncciL4L3(ncci, PH_ACTIVATE | REQUEST, 0, 0);
}
#endif
}
@ -481,7 +482,7 @@ void ncciDataReq(Ncci_t *ncci, struct sk_buff *skb)
ncci->xmit_skb_handles[i].MsgId = CAPIMSG_MSGID(skb->data);
skb_pull(skb, CAPIMSG_LEN(skb->data));
L4L3(ncci, DL_DATA | REQUEST, skb);
ncciL4L3(ncci, DL_DATA | REQUEST, DTYPE_SKB, skb);
return;
fail:
@ -634,6 +635,16 @@ static int ncci_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
return(0);
}
static int ncciL4L3(Ncci_t *ncci, u_int prim, int dtyp, void *arg)
{
if (!ncci->inst->down.func) {
int_error();
return -EINVAL;
}
return(ncci->inst->down.func(&ncci->inst->down, prim, 0, dtyp, arg));
}
void init_ncci(void)
{
ncci_fsm.state_count = ST_NCCI_COUNT;
@ -644,3 +655,7 @@ void init_ncci(void)
FsmNew(&ncci_fsm, fn_ncci_list, FN_NCCI_COUNT);
}
void free_ncci(void)
{
FsmFree(&ncci_fsm);
}

View File

@ -6,18 +6,9 @@
#include "helper.h"
#include "debug.h"
#if 0
#define plciDebug(plci, lev, fmt, args...) \
debug(lev, plci->contr->cs, "", fmt, ## args)
capidebug(lev, fmt, ## args)
static void l4pc_l3l4(struct l4_process *l4_pc, int pr, void *arg)
{
Plci_t *plci = l4_pc->priv;
plci_l3l4(plci, pr, arg);
}
#endif
void plciConstr(Plci_t *plci, Contr_t *contr, __u32 adrPLCI)
{
@ -63,7 +54,7 @@ void plciHandleSetupInd(Plci_t *plci, int pr, SETUP_t *setup)
memset(&relcmpl, 0, sizeof(RELEASE_COMPLETE_t));
relcmpl.CAUSE = cause;
p_L4L3(plci, CC_RELEASE_COMPLETE | REQUEST, &relcmpl);
plciL4L3(plci, CC_RELEASE_COMPLETE | REQUEST, &relcmpl);
}
}
@ -128,5 +119,15 @@ void plciNewCrInd(Plci_t *plci, struct l3_process *l3_pc)
void plciNewCrReq(Plci_t *plci)
{
L4L3(plci->contr, CC_NEW_CR | REQUEST, &plci->adrPLCI);
plciL4L3(plci, CC_NEW_CR | REQUEST, NULL);
}
int plciL4L3(Plci_t *plci, __u32 prim, void *arg)
{
l3msg_t l3msg;
l3msg.id = plci->adrPLCI;
l3msg.arg = arg;
return(contrL4L3(plci->contr, prim, &l3msg));
}

View File

@ -272,6 +272,16 @@ void encodeInvokeComponentLength(__u8 *msg, __u8 *p)
msg[0] = p - &msg[1];
}
static int dummy_L4L3(DummyProcess_t *dpc, __u32 prim, void *arg) {
Contr_t *contr = dpc->contr;
l3msg_t l3msg;
l3msg.id = contr->adrController | DUMMY_CR_FLAG;
l3msg.arg = arg;
return(contrL4L3(contr, prim, &l3msg));
}
DummyProcess_t *applNewDummyPc(Appl_t *appl, __u16 Function, __u32 Handle)
{
DummyProcess_t *dummy_pc;
@ -452,7 +462,6 @@ DummyProcess_t *contrNewDummyPc(Contr_t* contr)
}
contr->dummy_pcs[i] = dummy_pc;
dummyPcConstr(dummy_pc, contr, ++contr->lastInvokeId);
return dummy_pc;
}
@ -701,3 +710,13 @@ void contrDummyFacility(Contr_t *contr, FACILITY_t *fac)
}
void contrDummyInd(Contr_t *contr, __u32 prim, void *arg)
{
switch (prim) {
case CC_FACILITY | INDICATION:
contrDummyFacility(contr, arg);
break;
default:
int_error();
}
}

View File

@ -133,7 +133,6 @@
#define CC_TIMEOUT 0x031200
#define CC_NEW_CR 0x03f000
#define CC_RELEASE_CR 0x03f100
#define CC_DUMMY 0x03f200
#define LAYER_MASK 0x0F0000
@ -215,6 +214,9 @@
#define DTYPE_SKB -1
#define DTYPE_L3MSGP -2
#define DUMMY_CR_FLAG 0x7FFFFF00
#define CONTROLER_MASK 0x000000FF
/* special packet type */
#define PACKET_NOACK 250