- implement broadcast STATUS messages (Peter Sprenger)

This commit is contained in:
Karsten Keil 2005-11-07 14:56:53 +00:00
parent b645e6ca3d
commit 9f59a14b76
8 changed files with 155 additions and 79 deletions

View File

@ -44,6 +44,7 @@ typedef struct _dchannel_t {
u_long DFlags;
u_int type;
u_int ph_state;
u_char l1_up;
u_char (*read_reg) (void *, u_char);
void (*write_reg) (void *, u_char, u_char);
void (*read_fifo) (void *, u_char *, int);

View File

@ -2097,6 +2097,14 @@ static int hfcmulti_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
printk(KERN_DEBUG "%s: PH_DEACTIVATE no NT-mode port %d (0..%d)\n", __FUNCTION__, hc->chan[dch->channel].port, hc->type-1);
ret = -EINVAL;
}
} else
if (hh->prim == MGR_SHORTSTATUS) {
if(hh->dinfo==SSTATUS_ALL || hh->dinfo==SSTATUS_L1) {
int new_addr;
if(hh->dinfo&SSTATUS_BROADCAST_BIT) new_addr= dch->inst.id | MSG_BROADCAST;
else new_addr=hh->addr | FLG_MSG_TARGET;
return(mISDN_queueup_newhead(inst, new_addr, MGR_SHORTSTATUS,(dch->l1_up) ? SSTATUS_L1_ACTIVATED : SSTATUS_L1_DEACTIVATED, skb));
}
} else {
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: unknown prim %x\n", __FUNCTION__, hh->prim);
@ -2375,6 +2383,7 @@ static void ph_state_change(dchannel_t *dch)
case (1):
prim = PH_ACTIVATE | INDICATION;
para = 0;
dch->l1_up=1;
break;
default:
@ -2382,6 +2391,7 @@ static void ph_state_change(dchannel_t *dch)
return;
prim = PH_DEACTIVATE | INDICATION;
para = 0;
dch->l1_up=0;
}
hc->chan[ch].e1_state = dch->ph_state;
} else {
@ -2397,6 +2407,7 @@ static void ph_state_change(dchannel_t *dch)
case (3):
prim = PH_CONTROL | INDICATION;
para = HW_DEACTIVATE;
dch->l1_up=0;
break;
case (5):
@ -2410,6 +2421,7 @@ static void ph_state_change(dchannel_t *dch)
case (7):
para = INFO4_P8;
dch->l1_up=1;
break;
default:
@ -2439,6 +2451,7 @@ static void ph_state_change(dchannel_t *dch)
prim = PH_DEACTIVATE | INDICATION;
para = 0;
hc->chan[ch].nt_timer = -1;
dch->l1_up=0;
break;
case (4):
@ -2449,6 +2462,7 @@ static void ph_state_change(dchannel_t *dch)
prim = PH_ACTIVATE | INDICATION;
para = 0;
hc->chan[ch].nt_timer = -1;
dch->l1_up=1;
break;
default:
@ -2458,6 +2472,8 @@ static void ph_state_change(dchannel_t *dch)
}
mISDN_queue_data(&dch->inst, FLG_MSG_UP, prim, para, 0, NULL, 0);
mISDN_queue_data(&dch->inst, dch->inst.id | MSG_BROADCAST, MGR_SHORTSTATUS,
(dch->l1_up) ? SSTATUS_L1_ACTIVATED : SSTATUS_L1_DEACTIVATED, 0, NULL, 0);
}
/*************************************/
@ -2889,7 +2905,7 @@ setup_pci(hfc_multi_t *hc, struct pci_dev *pdev,int id_idx)
#endif
pci_set_drvdata(hc->pci_dev, hc);
/* At this point the needed PCI config is done */
/* fifos are still not enabled */
return (0);

View File

@ -211,7 +211,7 @@ compose_msg(struct sk_buff *skb, Q931_info_t *qi)
ie_info_t *ie;
buf += L3_EXTRA_SIZE;
if (qi->more_data.off) {
p = skb_put(skb, 1);
*p = buf[qi->more_data.off];
@ -398,7 +398,7 @@ static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
IE_USER_USER, -1};
static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};
@ -411,7 +411,7 @@ static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |
IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,
IE_SIGNAL, IE_USER_USER, -1};
/* a RELEASE_COMPLETE with errors don't require special actions
/* a RELEASE_COMPLETE with errors don't require special actions
static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY,
IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
*/
@ -436,7 +436,7 @@ static int ie_HOLD_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
static int ie_RETRIEVE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_DISPLAY, -1};
static int ie_RETRIEVE_ACKNOWLEDGE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_DISPLAY, -1};
static int ie_RETRIEVE_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
/* not used
/* not used
* static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY,
* IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
* static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1};
@ -526,7 +526,7 @@ check_infoelements(l3_process_t *pc, struct sk_buff *skb, int *checklist)
ie_info_t *iep;
int i, l, newpos, oldpos;
int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;
p = skb->data;
p += L3_EXTRA_SIZE;
iep = &qi->bearer_capability;
@ -564,7 +564,7 @@ check_infoelements(l3_process_t *pc, struct sk_buff *skb, int *checklist)
return(ERR_IE_LENGTH);
if (err_seq)
return(ERR_IE_SEQUENCE);
}
}
return(0);
}
@ -622,7 +622,7 @@ l3dss1_std_ie_err(l3_process_t *pc, int ret) {
if (pc->l3->debug & L3_DEB_CHECK)
l3_debug(pc->l3, "check_infoelements ret %d", ret);
switch(ret) {
case 0:
case 0:
break;
case ERR_IE_COMPREHENSION:
l3dss1_status_send(pc, CAUSE_MANDATORY_IE_MISS);
@ -1043,7 +1043,7 @@ l3dss1_disconnect(l3_process_t *pc, u_char pr, void *arg)
cause = CAUSE_MANDATORY_IE_MISS;
else
cause = CAUSE_INVALID_CONTENTS;
}
}
ret = check_infoelements(pc, skb, ie_DISCONNECT);
if (ERR_IE_COMPREHENSION == ret)
cause = CAUSE_MANDATORY_IE_MISS;
@ -1141,7 +1141,7 @@ l3dss1_setup(l3_process_t *pc, u_char pr, void *arg)
case 0x08: /* Unrestricted digital information */
case 0x09: /* Restricted digital information */
case 0x11:
/* Unrestr. digital information with
/* Unrestr. digital information with
* tones/announcements ( or 7 kHz audio
*/
case 0x18: /* Video */
@ -1170,7 +1170,7 @@ l3dss1_setup(l3_process_t *pc, u_char pr, void *arg)
l3dss1_msg_without_setup(pc, CAUSE_INVALID_CONTENTS);
dev_kfree_skb(skb);
return;
}
}
} else {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "setup without bearer capabilities");
@ -1198,7 +1198,7 @@ l3dss1_setup(l3_process_t *pc, u_char pr, void *arg)
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "setup without bchannel, call waiting");
bcfound++;
}
}
} else {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "setup with wrong chid ret %d", err);
@ -1307,7 +1307,7 @@ l3dss1_progress(l3_process_t *pc, u_char pr, void *arg) {
cause = CAUSE_MANDATORY_IE_MISS;
err = 4;
}
if (err) {
if (err) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "progress error %d", err);
l3dss1_status_send(pc, cause);
@ -1331,7 +1331,7 @@ l3dss1_notify(l3_process_t *pc, u_char pr, void *arg) {
Q931_info_t *qi = (Q931_info_t *)skb->data;
int err = 0;
u_char *p, cause = CAUSE_INVALID_CONTENTS;
if (qi->notify.off) {
p = skb->data;
p += L3_EXTRA_SIZE + qi->notify.off;
@ -1355,7 +1355,7 @@ l3dss1_notify(l3_process_t *pc, u_char pr, void *arg) {
cause = CAUSE_MANDATORY_IE_MISS;
err = 3;
}
if (err) {
if (err) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "notify error %d", err);
l3dss1_status_send(pc, cause);
@ -1445,9 +1445,9 @@ static void
l3dss1_status(l3_process_t *pc, u_char pr, void *arg) {
struct sk_buff *skb = arg;
Q931_info_t *qi = (Q931_info_t *)skb->data;
int ret = 0;
int ret = 0;
u_char *p, cause = 0, callState = 0xff;
if ((ret = l3dss1_get_cause(pc, skb))) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "STATUS get_cause ret(%d)", ret);
@ -1506,7 +1506,7 @@ l3dss1_facility(l3_process_t *pc, u_char pr, void *arg)
struct sk_buff *skb = arg;
Q931_info_t *qi = (Q931_info_t *)skb->data;
int ret;
ret = check_infoelements(pc, skb, ie_FACILITY);
l3dss1_std_ie_err(pc, ret);
if (!qi->facility.off) {
@ -1514,7 +1514,7 @@ l3dss1_facility(l3_process_t *pc, u_char pr, void *arg)
l3_debug(pc->l3, "FACILITY without IE_FACILITY");
dev_kfree_skb(skb);
return;
}
}
if (mISDN_l3up(pc, CC_FACILITY | INDICATION, skb))
dev_kfree_skb(skb);
}
@ -1545,7 +1545,7 @@ l3dss1_suspend_rej(l3_process_t *pc, u_char pr, void *arg)
if ((ret = l3dss1_get_cause(pc, skb))) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "SUSP_REJ get_cause err(%d)", ret);
if (ret == -1)
if (ret == -1)
cause = CAUSE_MANDATORY_IE_MISS;
else
cause = CAUSE_INVALID_CONTENTS;
@ -1614,7 +1614,7 @@ l3dss1_resume_rej(l3_process_t *pc, u_char pr, void *arg)
if ((ret = l3dss1_get_cause(pc, skb))) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "RES_REJ get_cause err(%d)", ret);
if (ret == -1)
if (ret == -1)
cause = CAUSE_MANDATORY_IE_MISS;
else
cause = CAUSE_INVALID_CONTENTS;
@ -1804,7 +1804,7 @@ l3dss1_hold_rej(l3_process_t *pc, u_char pr, void *arg)
if ((ret = l3dss1_get_cause(pc, skb))) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "HOLD_REJ get_cause err(%d)", ret);
if (ret == -1)
if (ret == -1)
cause = CAUSE_MANDATORY_IE_MISS;
else
cause = CAUSE_INVALID_CONTENTS;
@ -2029,7 +2029,7 @@ l3dss1_retrieve_rej(l3_process_t *pc, u_char pr, void *arg)
if ((ret = l3dss1_get_cause(pc, skb))) {
if (pc->l3->debug & L3_DEB_WARN)
l3_debug(pc->l3, "RETRIEVE_REJ get_cause err(%d)", ret);
if (ret == -1)
if (ret == -1)
cause = CAUSE_MANDATORY_IE_MISS;
else
cause = CAUSE_INVALID_CONTENTS;
@ -2245,7 +2245,7 @@ l3dss1_dl_reestablish(l3_process_t *pc, u_char pr, void *arg)
L3AddTimer(&pc->timer, T309, CC_T309);
l3_msg(pc->l3, DL_ESTABLISH | REQUEST, 0, 0, NULL);
}
static void
l3dss1_dl_reest_status(l3_process_t *pc, u_char pr, void *arg)
{
@ -2583,7 +2583,7 @@ dss1_fromdown(layer3_t *l3, struct sk_buff *skb, mISDN_head_t *hh)
if (ptr[qi->cause.off +1] >= 2)
cause = ptr[qi->cause.off + 3] & 0x7f;
else
cause = ptr[qi->cause.off + 2] & 0x7f;
cause = ptr[qi->cause.off + 2] & 0x7f;
}
callState = 0;
if (qi->call_state.off) {
@ -2680,7 +2680,7 @@ dss1_fromup(layer3_t *l3, struct sk_buff *skb, mISDN_head_t *hh)
}
}
return(ret);
}
}
if ((l3->debug & L3_DEB_MSG) && skb->len)
mISDN_LogL3Msg(skb);
if (!proc && hh->dinfo == MISDN_ID_DUMMY) {
@ -2724,7 +2724,7 @@ static int
dss1man(l3_process_t *proc, u_int pr, void *arg)
{
u_int i;
if (!proc) {
printk(KERN_ERR "mISDN dss1man without proc pr=%04x\n", pr);
return(-EINVAL);
@ -2761,11 +2761,12 @@ dss1_function(mISDNinstance_t *inst, struct sk_buff *skb)
printk(KERN_DEBUG "%s: addr(%08x) prim(%x)\n", __FUNCTION__, hh->addr, hh->prim);
if (!l3)
return(ret);
switch(hh->addr & MSG_DIR_MASK) {
case FLG_MSG_DOWN:
ret = dss1_fromup(l3, skb, hh);
break;
case MSG_BROADCAST: // we define broadcast comes from down below
case FLG_MSG_UP:
ret = dss1_fromdown(l3, skb, hh);
break;
@ -2773,7 +2774,7 @@ dss1_function(mISDNinstance_t *inst, struct sk_buff *skb)
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
default: /* broadcast */
default:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;

View File

@ -124,7 +124,7 @@ enum {
EV_DEACT_CNF,
EV_DEACT_IND,
EV_POWER_UP,
EV_ANYSIG_IND,
EV_ANYSIG_IND,
EV_INFO2_IND,
EV_INFO4_IND,
EV_TIMER_DEACT,
@ -142,7 +142,7 @@ static char *strL1Event[] =
"EV_DEACT_CNF",
"EV_DEACT_IND",
"EV_POWER_UP",
"EV_ANYSIG_IND",
"EV_ANYSIG_IND",
"EV_INFO2_IND",
"EV_INFO4_IND",
"EV_TIMER_DEACT",
@ -267,7 +267,7 @@ l1_timer3(struct FsmInst *fi, int event, void *arg)
layer1_t *l1 = fi->userdata;
u_int db = HW_D_NOBLOCKED;
test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
l1up(l1, PH_CONTROL | INDICATION, 0, 4, &db);
@ -545,7 +545,7 @@ l1from_down(layer1_t *l1, struct sk_buff *skb, mISDN_head_t *hh)
mISDN_debug(l1->inst.st->id, NULL,
"l1from_down ctrl ind %x unhandled", hh->dinfo);
} else if (hh->prim == (PH_CONTROL | CONFIRM)) {
if (hh->dinfo == HW_DEACTIVATE)
if (hh->dinfo == HW_DEACTIVATE)
mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
else if (l1->debug)
mISDN_debug(l1->inst.st->id, NULL,
@ -588,19 +588,20 @@ l1_function(mISDNinstance_t *inst, struct sk_buff *skb)
printk(KERN_DEBUG "%s: addr(%08x) prim(%x)\n", __FUNCTION__, hh->addr, hh->prim);
if (!l1)
return(ret);
switch(hh->addr & MSG_DIR_MASK) {
case FLG_MSG_DOWN:
ret = l1from_up(l1, skb, hh);
break;
case FLG_MSG_UP:
case MSG_BROADCAST: // we define broaadcast comes from down below
ret = l1from_down(l1, skb, hh);
break;
case MSG_TO_OWNER:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
default: /* broadcast */
default:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
@ -736,7 +737,7 @@ l1_manager(void *data, u_int prim, void *arg) {
printk(KERN_WARNING "l1_manager connect no instance\n");
return(err);
}
switch(prim) {
case MGR_NEWLAYER | REQUEST:
err = new_l1(data, arg);

View File

@ -197,7 +197,7 @@ l2_chain_down(mISDNinstance_t *inst, struct sk_buff *skb) {
static int
ph_data_confirm(mISDNinstance_t *inst, mISDN_head_t *hh, struct sk_buff *skb) {
layer2_t *l2 = inst->privat;
struct sk_buff *nskb = skb;
struct sk_buff *nskb = skb;
// mISDNif_t *next = up->clone;
int ret = -EAGAIN;
@ -408,7 +408,7 @@ inline int
IsSFrame(u_char * data, layer2_t *l2)
{
register u_char d = *data;
if (!test_bit(FLG_MOD128, &l2->flag))
d &= 0xf;
return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
@ -660,7 +660,7 @@ l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
l2mgr(l2, MDL_ERROR | INDICATION, (void *) 'C');
else
l2mgr(l2, MDL_ERROR | INDICATION, (void *) 'D');
}
static void
@ -697,7 +697,7 @@ static void
l2_go_st3(struct FsmInst *fi, int event, void *arg)
{
dev_kfree_skb((struct sk_buff *)arg);
mISDN_FsmChangeState(fi, ST_L2_3);
mISDN_FsmChangeState(fi, ST_L2_3);
}
static void
@ -803,7 +803,7 @@ l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
test_and_set_bit(FLG_L3_INIT, &l2->flag);
test_and_clear_bit(FLG_PEND_REL, &l2->flag);
dev_kfree_skb(skb);
}
}
static void
l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
@ -981,6 +981,8 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
if (skb_queue_len(&l2->i_queue) && cansend(l2))
mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST, MGR_SHORTSTATUS, SSTATUS_L2_ESTABLISH, 0, NULL, 0);
}
static void
@ -997,6 +999,8 @@ l2_released(struct FsmInst *fi, int event, void *arg)
stop_t200(l2, 6);
lapb_dl_release_l2l3(l2, CONFIRM);
mISDN_FsmChangeState(fi, ST_L2_4);
mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST, MGR_SHORTSTATUS, SSTATUS_L2_RELEASED, 0, NULL, 0);
}
static void
@ -1619,7 +1623,7 @@ l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
{
layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg;
discard_queue(&l2->i_queue);
discard_queue(&l2->ui_queue);
if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
@ -1820,7 +1824,7 @@ ph_data_indication(layer2_t *l2, mISDN_head_t *hh, struct sk_buff *skb) {
u_int l;
int c = 0;
l = l2addrsize(l2);
if (skb->len <= l) {
mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
@ -1954,6 +1958,15 @@ l2from_down(layer2_t *l2, struct sk_buff *askb, mISDN_head_t *hh)
dev_kfree_skb(cskb);
ret = 0;
break;
case MGR_SHORTSTATUS:
if(hh->dinfo==SSTATUS_ALL || hh->dinfo==SSTATUS_L2) {
int new_addr;
if(hh->dinfo&SSTATUS_BROADCAST_BIT) new_addr= l2->inst.id | MSG_BROADCAST;
else new_addr=hh->addr | FLG_MSG_TARGET;
return(mISDN_queueup_newhead(&l2->inst, new_addr, MGR_SHORTSTATUS,
(l2->l2m.state==ST_L2_7) ? SSTATUS_L2_ESTABLISH : SSTATUS_L2_RELEASED, cskb));
}
break;
default:
if (l2->debug)
l2m_debug(&l2->l2m, "l2 unknown pr %x", hh->prim);
@ -2040,19 +2053,20 @@ l2_function(mISDNinstance_t *inst, struct sk_buff *skb)
printk(KERN_DEBUG "%s: addr(%08x) prim(%x)\n", __FUNCTION__, hh->addr, hh->prim);
if (!l2)
return(ret);
switch(hh->addr & MSG_DIR_MASK) {
case FLG_MSG_DOWN:
ret = l2from_up(l2, skb, hh);
break;
case FLG_MSG_UP:
case MSG_BROADCAST: // we define broaadcast comes from down below
ret = l2from_down(l2, skb, hh);
break;
case MSG_TO_OWNER:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
default: /* broadcast */
default:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
@ -2373,7 +2387,7 @@ l2_status(layer2_t *l2, status_info_l2_t *si)
}
static char MName[] = "ISDNL2";
#ifdef MODULE
MODULE_AUTHOR("Karsten Keil");
#ifdef MODULE_LICENSE

View File

@ -160,7 +160,7 @@ get_stack4id(u_int id)
if (!id) /* 0 isn't a valid id */
return(NULL);
read_lock(&stacklist_lock);
list_for_each_entry(st, &mISDN_stacklist, list) {
list_for_each_entry(st, &mISDN_stacklist, list) {
if (id == st->id) {
read_unlock(&stacklist_lock);
return(st);
@ -230,7 +230,7 @@ get_nextlayer(mISDNstack_t *st, u_int addr)
int_errtxt("st(%08x) addr(%08x) wrong address", st->id, addr);
return(NULL);
}
}
}
if ((layer < 0) || (layer > MAX_LAYER_NR)) {
int_errtxt("st(%08x) addr(%08x) layer %d out of range", st->id, addr, layer);
return(NULL);
@ -318,10 +318,10 @@ int
insertlayer(mISDNstack_t *st, mISDNlayer_t *layer, int layermask)
{
mISDNlayer_t *item;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s(%p, %p, %x)\n",
__FUNCTION__, st, layer, layermask);
__FUNCTION__, st, layer, layermask);
if (!st || !layer) {
int_error();
return(-EINVAL);
@ -331,7 +331,7 @@ insertlayer(mISDNstack_t *st, mISDNlayer_t *layer, int layermask)
} else {
list_for_each_entry(item, &st->layerlist, list) {
if (layermask < get_layermask(item)) {
list_add_tail(&layer->list, &item->list);
list_add_tail(&layer->list, &item->list);
return(0);
}
}
@ -386,7 +386,7 @@ mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
if (test_bit(mISDN_STACK_KILLED, &st->status))
return(-EBUSY);
if ((st->id & STACK_ID_MASK) != (id & STACK_ID_MASK)) {
int_errtxt("stack id not match st(%08x) id(%08x) inst(%08x) aflag(%08x) prim(%x)",
int_errtxt("stack id not match st(%08x) id(%08x) inst(%08x) aflag(%08x) prim(%x)",
st->id, id, inst->id, aflag, hh->prim);
}
hh->addr = id;
@ -398,9 +398,38 @@ static void
do_broadcast(mISDNstack_t *st, struct sk_buff *skb)
{
mISDN_head_t *hh = mISDN_HEAD_P(skb);
mISDNinstance_t *inst=NULL;
struct sk_buff *c_skb;
int i,err;
for(i=0;i<=MAX_LAYER_NR;i++) {
if(i==(hh->addr & LAYER_ID_MASK)) continue; // skip own layer
inst = st->i_array[i];
if(!inst) break; // we reached the last layer
c_skb = skb_copy(skb, GFP_KERNEL); // we need a private copy
if(!c_skb) break; // stop here when copy not possible
if (core_debug & DEBUG_MSG_THREAD_INFO)
printk(KERN_DEBUG "%s: inst(%08x) msg call addr(%08x) prim(%x)\n",
__FUNCTION__, inst->id, hh->addr, hh->prim);
if (inst->function) {
err = inst->function(inst, c_skb);
if (err) {
if(core_debug & DEBUG_MSG_THREAD_ERR)
printk(KERN_DEBUG "%s: instance(%08x)->function return(%d)\n", __FUNCTION__, inst->id, err);
dev_kfree_skb(c_skb); // free private copy
}
} else {
if (core_debug & DEBUG_MSG_THREAD_ERR)
printk(KERN_DEBUG "%s: instance(%08x) no function\n", __FUNCTION__, inst->id);
dev_kfree_skb(c_skb); // free private copy
}
}
/* not implemented yet */
int_errtxt("%s: st(%08x) addr(%08x) prim(%x) dinfo(%x)", __FUNCTION__, st->id, hh->addr, hh->prim, hh->dinfo);
dev_kfree_skb(skb);
}
@ -476,7 +505,7 @@ mISDNStackd(void *data)
if (test_and_set_bit(mISDN_STACK_CLEARING, &st->status)) {
int_errtxt("double clearing");
}
}
if (hhe->data[0]) {
if (st->notify) {
int_errtxt("notify already set");
@ -587,7 +616,7 @@ mISDNStackd(void *data)
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) proceed %d msg %d clone %d sleep %d stopped\n",
st->id, st->msg_cnt, st->clone_cnt, st->sleep_cnt, st->stopped_cnt);
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) utime(%ld) stime(%ld)\n", st->id, st->thread->utime, st->thread->stime);
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) nvcsw(%ld) nivcsw(%ld)\n", st->id, st->thread->nvcsw, st->thread->nivcsw);
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) nvcsw(%ld) nivcsw(%ld)\n", st->id, st->thread->nvcsw, st->thread->nivcsw);
#endif
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) killed now\n", st->id);
test_and_set_bit(mISDN_STACK_KILLED, &st->status);
@ -670,7 +699,7 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
}
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "Stack id %x added\n", newst->id);
kernel_thread(mISDNStackd, (void *)newst, 0);
kernel_thread(mISDNStackd, (void *)newst, 0);
return(newst);
}
@ -881,7 +910,7 @@ release_stacks(mISDNobject_t *obj)
printk(KERN_DEBUG "%s: inst%d(%p)\n", __FUNCTION__, i, st->i_array[i]);
if (st->i_array[i]->obj == obj)
rel++;
}
}
if (rel) {
read_unlock(&stacklist_lock);
release_stack(st);
@ -939,7 +968,7 @@ register_layer(mISDNstack_t *st, mISDNinstance_t *inst)
//}
}
/*
* To simplify registration we assume that our stacks are
* To simplify registration we assume that our stacks are
* always build with monoton increasing layernumbers from
* bottom (HW,L0) to highest number
*/
@ -964,7 +993,7 @@ register_layer(mISDNstack_t *st, mISDNinstance_t *inst)
return(-EBUSY);
}
// }
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: inst(%p/%p) id(%x)\n", __FUNCTION__,
inst, inst->obj, inst->id);
@ -1214,7 +1243,7 @@ test_stack_protocol(mISDNstack_t *st, u_int l1prot, u_int l2prot, u_int l3prot)
int cnt = MAX_LAYER_NR + 1, ret = 1;
mISDN_pid_t pid;
mISDNinstance_t *inst;
clear_stack(st,1);
memset(&pid, 0, sizeof(mISDN_pid_t));
pid.layermask = ISDN_LAYER(1);
@ -1222,7 +1251,7 @@ test_stack_protocol(mISDNstack_t *st, u_int l1prot, u_int l2prot, u_int l3prot)
pid.layermask |= ISDN_LAYER(2);
if (!(l3prot == 1))
pid.layermask |= ISDN_LAYER(3);
pid.protocol[1] = l1prot | ISDN_PID_LAYER(1) | ISDN_PID_BCHANNEL_BIT;
if (pid.layermask & ISDN_LAYER(2))
pid.protocol[2] = l2prot | ISDN_PID_LAYER(2) | ISDN_PID_BCHANNEL_BIT;

View File

@ -1,7 +1,7 @@
/* $Id$
*
* Linux modular ISDN subsystem, mISDN
* X.25/X.31 Layer3 for DTE mode
* X.25/X.31 Layer3 for DTE mode
*
* Author Karsten Keil (kkeil@suse.de)
*
@ -370,7 +370,7 @@ static struct FsmNode PFnList[] =
{ST_P0, EV_L3_OUTGOING_CALL, p_p0_outgoing},
{ST_P0, EV_L3_CLEARING, p_clearing_req},
{ST_P1, EV_L3_READY, p_ready},
{ST_P1, EV_L3_OUTGOING_CALL, p_outgoing},
{ST_P1, EV_L3_OUTGOING_CALL, p_outgoing},
{ST_P1, EV_L2_INCOMING_CALL, p_incoming},
{ST_P1, EV_L2_CLEAR, p_clear_ind},
{ST_P1, EV_L2_CALL_CNF, p_invalid_pkt},
@ -493,7 +493,7 @@ d_reset_timeout(struct FsmInst *fi, int event, void *arg)
l3c->cause[1] = 51;
mISDN_FsmChangeState(fi, ST_D0);
if (test_bit(X25_STATE_PERMANENT, &l3c->state))
X25_clear_connection(l3c, NULL, 0x3303);
X25_clear_connection(l3c, NULL, 0x3303);
else
mISDN_FsmEvent(&l3c->x25p, EV_L3_CLEARING, NULL);
}
@ -660,7 +660,7 @@ dte_data_ind_d(x25_channel_t *chan, struct sk_buff *skb, u_char gfi, u_char ptyp
mISDN_FsmEvent(&chan->x25d, EV_L3_RESETING, NULL);
} else {
int flag = (pr_m & 1) ? CAPI_FLAG_MOREDATA : 0;
if (gfi & X25_GFI_QBIT)
flag |= CAPI_FLAG_QUALIFIER;
if (gfi & X25_GFI_DBIT)
@ -755,7 +755,7 @@ dte_data_ind_r(x25_l3_t *l3, struct sk_buff *skb, u_char gfi, __u16 channel, u_c
{
int ret = X25_ERRCODE_DISCARD;
if (ptype == X25_PTYPE_NOTYPE) {
if (channel) {
if (l3->x25r.state == ST_R1)
@ -908,7 +908,7 @@ dte_create_channel(x25_l3_t *l3, int typ, u_char flag, __u16 ch, int len, u_char
x25_channel_t *l3c;
__u16 nch = ch;
int ret;
if (typ == X25_CHANNEL_OUTGOING) {
if (ch == 0) {
/* first search for allready created channels in P1 state */
@ -1069,7 +1069,7 @@ dte_from_up(x25_l3_t *l3, struct sk_buff *skb, mISDN_head_t *hh)
ncpi = (x25_ncpi_t *)skb->data;
l3c = dte_create_channel(l3, X25_CHANNEL_OUTGOING, ncpi->Flags,
(ncpi->Group<<8) | ncpi->Channel,
ncpi->len - 3, &ncpi->Contens[0]);
ncpi->len - 3, &ncpi->Contens[0]);
}
if (l3c)
l3c->ncci = addr | (l3c->lchan << 16);
@ -1132,7 +1132,7 @@ dte_from_up(x25_l3_t *l3, struct sk_buff *skb, mISDN_head_t *hh)
info = 0;
} else
info = 0x2002;
skb_trim(skb, 0);
memcpy(skb_put(skb, 2), &info, 2);
err = X25sendL4skb(l3c, l3, addr, CAPI_DISCONNECT_B3_CONF, hh->dinfo, skb);
@ -1217,19 +1217,20 @@ dte_function(mISDNinstance_t *inst, struct sk_buff *skb)
printk(KERN_DEBUG "%s: addr(%08x) prim(%x)\n", __FUNCTION__, hh->addr, hh->prim);
if (!l3)
return(ret);
switch(hh->addr & MSG_DIR_MASK) {
case FLG_MSG_DOWN:
ret = dte_from_up(l3, skb, hh);
break;
case FLG_MSG_UP:
case MSG_BROADCAST: // we define broaadcast comes from down below
ret = dte_from_down(l3, skb, hh);
break;
case MSG_TO_OWNER:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;
default: /* broadcast */
default:
/* FIXME: must be handled depending on type */
int_errtxt("not implemented yet");
break;

View File

@ -38,7 +38,7 @@
* <8 bit subcommand>
*
*/
/* SUBCOMMANDS */
#define REQUEST 0x80
#define CONFIRM 0x81
@ -95,6 +95,7 @@
#define MGR_HASPROTOCOL 0x0fe300
#define MGR_EVALSTACK 0x0fe400
#define MGR_GLOBALOPT 0x0fe500
#define MGR_SHORTSTATUS 0x0fe600
#define MGR_LOADFIRM 0x0ff000
#define MGR_LOGDATA 0x0ff100
#define MGR_DEBUGDATA 0x0ff200
@ -121,8 +122,8 @@
#define ANYSIGNAL 0x1f01
/* PH_CONTROL parameter */
#define HW_RESET 0x0001
#define HW_POWERDOWN 0x0100
#define HW_RESET 0x0001
#define HW_POWERDOWN 0x0100
#define HW_POWERUP 0x0101
#define HW_DEACTIVATE 0x0200
#define HW_ACTIVATE 0x0201
@ -158,8 +159,8 @@
#define HW_FIRM_START 0xFF10
#define HW_FIRM_DATA 0xFF11
#define HW_FIRM_END 0xFF12
#define HW_D_BLOCKED 0xFF20
#define HW_D_NOBLOCKED 0xFF21
#define HW_D_BLOCKED 0xFF20
#define HW_D_NOBLOCKED 0xFF21
#define HW_TESTRX_RAW 0xFF40
#define HW_TESTRX_HDLC 0xFF41
#define HW_TESTRX_OFF 0xFF4f
@ -234,7 +235,7 @@
#define MPH_DEACTIVATE 0x011000
#define MPH_ACTIVATE 0x011100
#define MPH_INFORMATION 0x012000
/* layer 2 */
#define DL_ESTABLISH 0x020100
#define DL_RELEASE 0x020000
@ -397,6 +398,18 @@
#define ISDN_PID_L3_DF_EXTCID 0x00200000
#define ISDN_PID_L3_DF_CRLEN2 0x00400000
// short message status
#define SSTATUS_ALL 0x0fffffff
#define SSTATUS_BROADCAST_BIT 0x10000000
#define SSTATUS_L1 0x01ffffff
#define SSTATUS_L2 0x02ffffff
#define SSTATUS_L1_DEACTIVATED 0x01000000
#define SSTATUS_L1_ACTIVATED 0x01000001
#define SSTATUS_L2_RELEASED 0x02000000
#define SSTATUS_L2_ESTABLISH 0x02000001
#define mISDN_CORE_DEVICE 0
#define mISDN_RAW_DEVICE 128
@ -576,7 +589,7 @@ typedef struct _status_info {
typedef struct _logdata {
char *head;
char *fmt;
va_list args;
va_list args;
} logdata_t;
typedef struct _moditem {