Finally found a big bug!!!
A little mistake in find_proc() caused not to find the broadcast process in some cases. (After many days, an outgoing call (to telephone) did not work anymore.)
This commit is contained in:
parent
7977dd7635
commit
9fe2e02763
470
i4lnet/net_l3.c
470
i4lnet/net_l3.c
|
@ -11,6 +11,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
#include "mISDNlib.h"
|
#include "mISDNlib.h"
|
||||||
|
#include "net_l2.h"
|
||||||
#include "net_l3.h"
|
#include "net_l3.h"
|
||||||
#include "l3dss1.h"
|
#include "l3dss1.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
@ -112,12 +113,19 @@ getcallref(u_char *p)
|
||||||
int l, cr = 0;
|
int l, cr = 0;
|
||||||
|
|
||||||
p++; /* prot discr */
|
p++; /* prot discr */
|
||||||
if (*p & 0xfe) /* wrong callref BRI only 1 octet*/
|
|
||||||
return(-2);
|
|
||||||
l = 0xf & *p++; /* callref length */
|
l = 0xf & *p++; /* callref length */
|
||||||
|
if (l > 2) /* wrong callref only 1 or 2 octet*/
|
||||||
|
return(-2);
|
||||||
if (!l) /* dummy CallRef */
|
if (!l) /* dummy CallRef */
|
||||||
return(-1);
|
return(-1);
|
||||||
cr = *p++;
|
if (l == 1) { /* BRI */
|
||||||
|
cr = *p & 0x7f;
|
||||||
|
cr += (*p & 0x80) << 8;
|
||||||
|
} else { /* PRI */
|
||||||
|
cr = *p++ << 8;
|
||||||
|
cr += *p;
|
||||||
|
}
|
||||||
|
|
||||||
return (cr);
|
return (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +134,7 @@ newl3state(layer3_proc_t *pc, int state)
|
||||||
{
|
{
|
||||||
if (pc->l3->debug & L3_DEB_STATE)
|
if (pc->l3->debug & L3_DEB_STATE)
|
||||||
l3_debug(pc->l3, "newstate cr %d %d%s --> %d%s",
|
l3_debug(pc->l3, "newstate cr %d %d%s --> %d%s",
|
||||||
pc->callref & 0x7F,
|
pc->callref & 0x7FFF,
|
||||||
pc->state, pc->master ? "i" : "",
|
pc->state, pc->master ? "i" : "",
|
||||||
state, pc->master ? "i" : "");
|
state, pc->master ? "i" : "");
|
||||||
pc->state = state;
|
pc->state = state;
|
||||||
|
@ -136,7 +144,7 @@ static void
|
||||||
L3ExpireTimer(L3Timer_t *t)
|
L3ExpireTimer(L3Timer_t *t)
|
||||||
{
|
{
|
||||||
if (t->pc->l3->debug & L3_DEB_STATE)
|
if (t->pc->l3->debug & L3_DEB_STATE)
|
||||||
l3_debug(t->pc->l3, "timer nr %x expired", t->nr);
|
l3_debug(t->pc->l3, "timer %p nr %x expired", t, t->nr);
|
||||||
send_proc(t->pc, IMSG_TIMER_EXPIRED, &t->nr);
|
send_proc(t->pc, IMSG_TIMER_EXPIRED, &t->nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +182,11 @@ StopAllL3Timer(layer3_proc_t *pc)
|
||||||
{
|
{
|
||||||
L3DelTimer(&pc->timer1);
|
L3DelTimer(&pc->timer1);
|
||||||
L3DelTimer(&pc->timer2);
|
L3DelTimer(&pc->timer2);
|
||||||
|
dprint(DBGM_L3, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
|
||||||
|
#warning also remove flags:
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -185,8 +198,13 @@ RemoveAllL3Timer(layer3_proc_t *pc)
|
||||||
if (ret)
|
if (ret)
|
||||||
dprint(DBGM_L3, "RemoveL3Timer1: ret %d\n", ret);
|
dprint(DBGM_L3, "RemoveL3Timer1: ret %d\n", ret);
|
||||||
ret = remove_timer(&pc->timer2.tl);
|
ret = remove_timer(&pc->timer2.tl);
|
||||||
|
dprint(DBGM_L3, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
|
||||||
if (ret)
|
if (ret)
|
||||||
dprint(DBGM_L3, "RemoveL3Timer2: ret %d\n", ret);
|
dprint(DBGM_L3, "RemoveL3Timer2: ret %d\n", ret);
|
||||||
|
#warning also remove flags:
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER308_1, &pc->Flags);
|
||||||
|
test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static layer3_proc_t *
|
static layer3_proc_t *
|
||||||
|
@ -228,7 +246,7 @@ find_proc(layer3_proc_t *master, int ces, int cr)
|
||||||
if (cp)
|
if (cp)
|
||||||
return(cp);
|
return(cp);
|
||||||
}
|
}
|
||||||
if (((p->ces & 0xfffffff0) == 0xfff0) && (p->callref == cr))
|
if (((p->ces & 0xffffff00) == 0xff00) && (p->callref == cr))
|
||||||
break;
|
break;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
@ -304,8 +322,17 @@ static void MsgStart(layer3_proc_t *pc, u_char mt) {
|
||||||
if (pc->callref == -1) { /* dummy cr */
|
if (pc->callref == -1) { /* dummy cr */
|
||||||
*pc->op++ = 0;
|
*pc->op++ = 0;
|
||||||
} else {
|
} else {
|
||||||
*pc->op++ = 1;
|
if (pc->l3->nst->feature & FEATURE_NET_CRLEN2) {
|
||||||
*pc->op++ = pc->callref ^ 0x80;
|
*pc->op++ = 2;
|
||||||
|
*pc->op++ = (pc->callref >> 8) ^ 0x80;
|
||||||
|
*pc->op++ = pc->callref & 0xff;
|
||||||
|
} else {
|
||||||
|
*pc->op++ = 1;
|
||||||
|
*pc->op = pc->callref & 0x7f;
|
||||||
|
if (!(pc->callref & 0x8000))
|
||||||
|
*pc->op |= 0x80;
|
||||||
|
pc->op++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*pc->op++ = mt;
|
*pc->op++ = mt;
|
||||||
}
|
}
|
||||||
|
@ -347,8 +374,17 @@ l3dss1_message(layer3_proc_t *pc, u_char mt)
|
||||||
return(-ENOMEM);
|
return(-ENOMEM);
|
||||||
p = msg_put(msg, 4);
|
p = msg_put(msg, 4);
|
||||||
*p++ = 8;
|
*p++ = 8;
|
||||||
*p++ = 1;
|
if (pc->l3->nst->feature & FEATURE_NET_CRLEN2) {
|
||||||
*p++ = pc->callref ^ 0x80;
|
*p++ = 2;
|
||||||
|
*p++ = (pc->callref >> 8) ^ 0x80;
|
||||||
|
*p++ = pc->callref & 0xff;
|
||||||
|
} else {
|
||||||
|
*p++ = 1;
|
||||||
|
*p = pc->callref & 0x7f;
|
||||||
|
if (!(pc->callref & 0x8000))
|
||||||
|
*p |= 0x80;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
*p++ = mt;
|
*p++ = mt;
|
||||||
dhexprint(DBGM_L3DATA, "l3 oframe:", msg->data, 4);
|
dhexprint(DBGM_L3DATA, "l3 oframe:", msg->data, 4);
|
||||||
if ((ret=l3_msg(pc->l3, DL_DATA | REQUEST, pc->ces, msg)))
|
if ((ret=l3_msg(pc->l3, DL_DATA | REQUEST, pc->ces, msg)))
|
||||||
|
@ -477,23 +513,48 @@ l3dss1_std_ie_err(layer3_proc_t *pc, int ret) {
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
l3dss1_get_channel_id(layer3_proc_t *pc, msg_t *omsg, msg_t *nmsg) {
|
l3dss1_get_channel_id(layer3_proc_t *pc, msg_t *omsg, msg_t *nmsg) {
|
||||||
u_char *sp, *p;
|
u_char *sp, *p;
|
||||||
|
int l;
|
||||||
|
|
||||||
if ((sp = p = findie(omsg->data, omsg->len, IE_CHANNEL_ID, 0))) {
|
if ((sp = p = findie(omsg->data, omsg->len, IE_CHANNEL_ID, 0))) {
|
||||||
if (*p != 1) { /* len for BRI = 1 */
|
l = *p++;
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if (pc->l3->nst->feature & FEATURE_NET_EXTCID) { /* PRI */
|
||||||
l3_debug(pc->l3, "wrong chid len %d", *p);
|
if (l < 3) {
|
||||||
pc->err = -2;
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
return (NULL);
|
l3_debug(pc->l3, "wrong chid len %d", *p);
|
||||||
|
pc->err = -2;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if ((*p & 0x60) != 0x20) {
|
||||||
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
l3_debug(pc->l3, "wrong chid %x (for PRI interface)", *p);
|
||||||
|
pc->err = -3;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
if (*p & 0x10) {
|
||||||
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
l3_debug(pc->l3, "wrong chid %x (channel map not supported)", *p);
|
||||||
|
pc->err = -4;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
pc->bc = *p & 0x7f;
|
||||||
|
} else { /* BRI */
|
||||||
|
if (l < 1) {
|
||||||
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
l3_debug(pc->l3, "wrong chid len %d", *p);
|
||||||
|
pc->err = -2;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (*p & 0x60) {
|
||||||
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
l3_debug(pc->l3, "wrong chid %x", *p);
|
||||||
|
pc->err = -3;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
pc->bc = *p & 3;
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
if (*p & 0x60) { /* only base rate interface */
|
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
|
||||||
l3_debug(pc->l3, "wrong chid %x", *p);
|
|
||||||
pc->err = -3;
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
pc->bc = *p & 3;
|
|
||||||
p = sp;
|
p = sp;
|
||||||
sp = msg_put(nmsg, 1 + *p);
|
sp = msg_put(nmsg, 1 + *p);
|
||||||
memcpy(sp, p, 1 + *p);
|
memcpy(sp, p, 1 + *p);
|
||||||
|
@ -559,7 +620,7 @@ l3dss1_facility(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(FACILITY_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(FACILITY_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
fac = (FACILITY_t *)(umsg->data + mISDN_HEADER_LEN);
|
fac = (FACILITY_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
fac->FACILITY =
|
fac->FACILITY =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
|
||||||
if (mISDN_l3up(pc, umsg))
|
if (mISDN_l3up(pc, umsg))
|
||||||
|
@ -576,7 +637,7 @@ l3dss1_userinfo(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(USER_INFORMATION_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(USER_INFORMATION_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
ui = (USER_INFORMATION_t *)(umsg->data + mISDN_HEADER_LEN);
|
ui = (USER_INFORMATION_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
ui->USER_USER =
|
ui->USER_USER =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg);
|
||||||
if (mISDN_l3up(pc, umsg))
|
if (mISDN_l3up(pc, umsg))
|
||||||
|
@ -596,7 +657,7 @@ l3dss1_setup(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(SETUP_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(SETUP_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
setup = (SETUP_t *)(umsg->data + mISDN_HEADER_LEN);
|
setup = (SETUP_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
/*
|
/*
|
||||||
* Bearer Capabilities
|
* Bearer Capabilities
|
||||||
*/
|
*/
|
||||||
|
@ -698,6 +759,7 @@ l3dss1_setup(layer3_proc_t *pc, int pr, void *arg)
|
||||||
setup->ces = pc->ces;
|
setup->ces = pc->ces;
|
||||||
newl3state(pc, 1);
|
newl3state(pc, 1);
|
||||||
L3DelTimer(&pc->timer2);
|
L3DelTimer(&pc->timer2);
|
||||||
|
dprint(DBGM_L3, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
|
||||||
L3AddTimer(&pc->timer2, T_CTRL, 0x31f);
|
L3AddTimer(&pc->timer2, T_CTRL, 0x31f);
|
||||||
if (err) /* STATUS for none mandatory IE errors after actions are taken */
|
if (err) /* STATUS for none mandatory IE errors after actions are taken */
|
||||||
l3dss1_std_ie_err(pc, err);
|
l3dss1_std_ie_err(pc, err);
|
||||||
|
@ -716,7 +778,7 @@ l3dss1_disconnect(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
disc = (DISCONNECT_t *)(umsg->data + mISDN_HEADER_LEN);
|
disc = (DISCONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
StopAllL3Timer(pc);
|
StopAllL3Timer(pc);
|
||||||
newl3state(pc, 11);
|
newl3state(pc, 11);
|
||||||
if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
||||||
|
@ -744,7 +806,7 @@ l3dss1_disconnect_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(DISCONNECT_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
disc = (DISCONNECT_t *)(umsg->data + mISDN_HEADER_LEN);
|
disc = (DISCONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
StopAllL3Timer(pc);
|
StopAllL3Timer(pc);
|
||||||
if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
if (!(disc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
@ -780,7 +842,7 @@ l3dss1_information(layer3_proc_t *pc, int pr, void *arg) {
|
||||||
(pc->callref << 16), sizeof(INFORMATION_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(INFORMATION_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
info = (INFORMATION_t *)(umsg->data + mISDN_HEADER_LEN);
|
info = (INFORMATION_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
info->COMPLETE =
|
info->COMPLETE =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
|
||||||
info->KEYPAD =
|
info->KEYPAD =
|
||||||
|
@ -808,7 +870,7 @@ l3dss1_release(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(RELEASE_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(RELEASE_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
rel = (RELEASE_t *)(umsg->data + mISDN_HEADER_LEN);
|
rel = (RELEASE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
StopAllL3Timer(pc);
|
StopAllL3Timer(pc);
|
||||||
if (!(rel->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
if (!(rel->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
||||||
if (pc->state != 12)
|
if (pc->state != 12)
|
||||||
|
@ -853,7 +915,7 @@ l3dss1_release_cmpl(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(RELEASE_COMPLETE_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(RELEASE_COMPLETE_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
relc = (RELEASE_COMPLETE_t *)(umsg->data + mISDN_HEADER_LEN);
|
relc = (RELEASE_COMPLETE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
StopAllL3Timer(pc);
|
StopAllL3Timer(pc);
|
||||||
newl3state(pc, 0);
|
newl3state(pc, 0);
|
||||||
if (!(relc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
if (!(relc->CAUSE = l3dss1_get_cause(pc, msg, umsg))) {
|
||||||
|
@ -879,6 +941,36 @@ l3dss1_release_cmpl_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
send_proc(pc, IMSG_END_PROC_M, NULL);
|
send_proc(pc, IMSG_END_PROC_M, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
l3dss1_setup_acknowledge_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
|
{
|
||||||
|
msg_t *umsg, *msg = arg;
|
||||||
|
SETUP_ACKNOWLEDGE_t *sa;
|
||||||
|
|
||||||
|
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
||||||
|
if (!pc->master) {
|
||||||
|
L3DelTimer(&pc->timer1);
|
||||||
|
newl3state(pc, 25);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
umsg = prep_l3data_msg(CC_SETUP_ACKNOWLEDGE | INDICATION, pc->master->ces |
|
||||||
|
(pc->master->callref << 16), sizeof(SETUP_ACKNOWLEDGE_t), msg->len, NULL);
|
||||||
|
if (!umsg)
|
||||||
|
return;
|
||||||
|
sa = (SETUP_ACKNOWLEDGE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
|
L3DelTimer(&pc->timer1); /* T304 */
|
||||||
|
newl3state(pc, 25);
|
||||||
|
sa->CHANNEL_ID =
|
||||||
|
find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
|
||||||
|
sa->FACILITY =
|
||||||
|
find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
|
||||||
|
sa->PROGRESS =
|
||||||
|
find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
|
||||||
|
if (!mISDN_l3up(pc->master, umsg))
|
||||||
|
return;
|
||||||
|
free_msg(umsg);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
l3dss1_proceeding_i(layer3_proc_t *pc, int pr, void *arg)
|
l3dss1_proceeding_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -895,9 +987,11 @@ l3dss1_proceeding_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->master->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
|
(pc->master->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
proc = (CALL_PROCEEDING_t *)(umsg->data + mISDN_HEADER_LEN);
|
proc = (CALL_PROCEEDING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
L3DelTimer(&pc->timer1); /* T304 */
|
L3DelTimer(&pc->timer1); /* T304 */
|
||||||
newl3state(pc, 9);
|
newl3state(pc, 9);
|
||||||
|
proc->CHANNEL_ID =
|
||||||
|
find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
|
||||||
proc->BEARER =
|
proc->BEARER =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
|
||||||
proc->FACILITY =
|
proc->FACILITY =
|
||||||
|
@ -927,9 +1021,11 @@ l3dss1_alerting_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->master->callref << 16), sizeof(ALERTING_t), msg->len, NULL);
|
(pc->master->callref << 16), sizeof(ALERTING_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
al = (ALERTING_t *)(umsg->data + mISDN_HEADER_LEN);
|
al = (ALERTING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
L3DelTimer(&pc->timer1); /* T304 */
|
L3DelTimer(&pc->timer1); /* T304 */
|
||||||
newl3state(pc, 7);
|
newl3state(pc, 7);
|
||||||
|
al->CHANNEL_ID =
|
||||||
|
find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
|
||||||
al->BEARER =
|
al->BEARER =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
|
||||||
al->FACILITY =
|
al->FACILITY =
|
||||||
|
@ -960,14 +1056,16 @@ l3dss1_call_proc(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
cp = (CALL_PROCEEDING_t *)(umsg->data + mISDN_HEADER_LEN);
|
cp = (CALL_PROCEEDING_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
if ((cp->CHANNEL_ID = l3dss1_get_channel_id(pc, msg, umsg))) {
|
if ((cp->CHANNEL_ID = l3dss1_get_channel_id(pc, msg, umsg))) {
|
||||||
if ((0 == pc->bc) || (3 == pc->bc)) {
|
if (!(pc->l3->nst->feature & FEATURE_NET_EXTCID)) { /* BRI */
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if ((0 == pc->bc) || (3 == pc->bc)) {
|
||||||
l3_debug(pc->l3, "setup answer with wrong chid %x", pc->bc);
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
l3dss1_status_send(pc, CAUSE_INVALID_CONTENTS);
|
l3_debug(pc->l3, "setup answer with wrong chid %x", pc->bc);
|
||||||
free_msg(umsg);
|
l3dss1_status_send(pc, CAUSE_INVALID_CONTENTS);
|
||||||
return;
|
free_msg(umsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (1 == pc->state) {
|
} else if (1 == pc->state) {
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
|
@ -1016,7 +1114,7 @@ l3dss1_connect_i(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->master->callref << 16), sizeof(CONNECT_t), msg->len, NULL);
|
(pc->master->callref << 16), sizeof(CONNECT_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
conn = (CONNECT_t *)(umsg->data + mISDN_HEADER_LEN);
|
conn = (CONNECT_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
L3DelTimer(&pc->timer1); /* T310 */
|
L3DelTimer(&pc->timer1); /* T310 */
|
||||||
newl3state(pc, 8);
|
newl3state(pc, 8);
|
||||||
conn->BEARER =
|
conn->BEARER =
|
||||||
|
@ -1052,6 +1150,10 @@ l3dss1_hold(layer3_proc_t *pc, int pr, void *arg)
|
||||||
msg_t *umsg, *msg = arg;
|
msg_t *umsg, *msg = arg;
|
||||||
HOLD_t *hold;
|
HOLD_t *hold;
|
||||||
|
|
||||||
|
if (!(pc->l3->nst->feature & FEATURE_NET_HOLD)) {
|
||||||
|
l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_MT_NOTIMPLEMENTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
||||||
#warning TODO: global mask for supported none mandatory services, like HOLD
|
#warning TODO: global mask for supported none mandatory services, like HOLD
|
||||||
if (pc->hold_state == HOLDAUX_HOLD_IND)
|
if (pc->hold_state == HOLDAUX_HOLD_IND)
|
||||||
|
@ -1066,7 +1168,7 @@ l3dss1_hold(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(HOLD_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(HOLD_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
hold = (HOLD_t *)(umsg->data + mISDN_HEADER_LEN);
|
hold = (HOLD_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
if (mISDN_l3up(pc, umsg))
|
if (mISDN_l3up(pc, umsg))
|
||||||
free_msg(umsg);
|
free_msg(umsg);
|
||||||
}
|
}
|
||||||
|
@ -1077,6 +1179,10 @@ l3dss1_retrieve(layer3_proc_t *pc, int pr, void *arg)
|
||||||
msg_t *umsg, *msg = arg;
|
msg_t *umsg, *msg = arg;
|
||||||
RETRIEVE_t *retr;
|
RETRIEVE_t *retr;
|
||||||
|
|
||||||
|
if (!(pc->l3->nst->feature & FEATURE_NET_HOLD)) {
|
||||||
|
l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_MT_NOTIMPLEMENTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
||||||
if (pc->hold_state == HOLDAUX_RETR_IND)
|
if (pc->hold_state == HOLDAUX_RETR_IND)
|
||||||
return;
|
return;
|
||||||
|
@ -1090,7 +1196,7 @@ l3dss1_retrieve(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(RETRIEVE_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(RETRIEVE_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
retr = (RETRIEVE_t *)(umsg->data + mISDN_HEADER_LEN);
|
retr = (RETRIEVE_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
retr->CHANNEL_ID =
|
retr->CHANNEL_ID =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
|
||||||
if (mISDN_l3up(pc, umsg))
|
if (mISDN_l3up(pc, umsg))
|
||||||
|
@ -1108,7 +1214,7 @@ l3dss1_suspend(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(SUSPEND_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(SUSPEND_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
susp = (SUSPEND_t *)(umsg->data + mISDN_HEADER_LEN);
|
susp = (SUSPEND_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
susp->CALL_ID =
|
susp->CALL_ID =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
|
||||||
susp->FACILITY =
|
susp->FACILITY =
|
||||||
|
@ -1129,7 +1235,7 @@ l3dss1_resume(layer3_proc_t *pc, int pr, void *arg)
|
||||||
(pc->callref << 16), sizeof(RESUME_t), msg->len, NULL);
|
(pc->callref << 16), sizeof(RESUME_t), msg->len, NULL);
|
||||||
if (!umsg)
|
if (!umsg)
|
||||||
return;
|
return;
|
||||||
res = (RESUME_t *)(umsg->data + mISDN_HEADER_LEN);
|
res = (RESUME_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
|
||||||
res->CALL_ID =
|
res->CALL_ID =
|
||||||
find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
|
find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg);
|
||||||
res->FACILITY =
|
res->FACILITY =
|
||||||
|
@ -1150,6 +1256,9 @@ static struct stateentry datastatelist[] =
|
||||||
MT_STATUS, l3dss1_release_cmpl},
|
MT_STATUS, l3dss1_release_cmpl},
|
||||||
{SBIT(0),
|
{SBIT(0),
|
||||||
MT_SETUP, l3dss1_setup},
|
MT_SETUP, l3dss1_setup},
|
||||||
|
#warning setup ack
|
||||||
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
|
MT_SETUP_ACKNOWLEDGE, l3dss1_setup_acknowledge_i},
|
||||||
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
MT_CALL_PROCEEDING, l3dss1_proceeding_i},
|
MT_CALL_PROCEEDING, l3dss1_proceeding_i},
|
||||||
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
|
@ -1188,18 +1297,18 @@ static struct stateentry datastatelist[] =
|
||||||
#define DATASLLEN \
|
#define DATASLLEN \
|
||||||
(sizeof(datastatelist) / sizeof(struct stateentry))
|
(sizeof(datastatelist) / sizeof(struct stateentry))
|
||||||
|
|
||||||
static int
|
static layer3_proc_t
|
||||||
create_child_proc(layer3_proc_t *pc, int mt, msg_t *msg, int state) {
|
*create_child_proc(layer3_proc_t *pc, int mt, msg_t *msg, int state) {
|
||||||
mISDN_head_t *hh;
|
mISDNuser_head_t *hh;
|
||||||
struct _l3_msg l3m;
|
struct _l3_msg l3m;
|
||||||
layer3_proc_t *p3i;
|
layer3_proc_t *p3i;
|
||||||
|
|
||||||
hh = (mISDN_head_t *)msg->data;
|
hh = (mISDNuser_head_t *)msg->data;
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
p3i = create_proc(pc->l3, hh->dinfo, pc->callref, pc);
|
p3i = create_proc(pc->l3, hh->dinfo, pc->callref, pc);
|
||||||
if (!p3i) {
|
if (!p3i) {
|
||||||
l3_debug(pc->l3, "cannot create child\n");
|
l3_debug(pc->l3, "cannot create child\n");
|
||||||
return(-ENOMEM);
|
return(NULL);
|
||||||
}
|
}
|
||||||
p3i->state = pc->state;
|
p3i->state = pc->state;
|
||||||
if (pc->state != -1)
|
if (pc->state != -1)
|
||||||
|
@ -1207,9 +1316,17 @@ create_child_proc(layer3_proc_t *pc, int mt, msg_t *msg, int state) {
|
||||||
l3m.mt = mt;
|
l3m.mt = mt;
|
||||||
l3m.msg = msg;
|
l3m.msg = msg;
|
||||||
send_proc(p3i, IMSG_L2_DATA, &l3m);
|
send_proc(p3i, IMSG_L2_DATA, &l3m);
|
||||||
return(0);
|
return(p3i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
l3dss1_setup_acknowledge_m(layer3_proc_t *pc, int pr, void *arg)
|
||||||
|
{
|
||||||
|
dprint(DBGM_L3,"%s\n", __FUNCTION__);
|
||||||
|
L3DelTimer(&pc->timer1);
|
||||||
|
create_child_proc(pc, pr, arg, 25);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
l3dss1_proceeding_m(layer3_proc_t *pc, int pr, void *arg)
|
l3dss1_proceeding_m(layer3_proc_t *pc, int pr, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -1245,7 +1362,7 @@ l3dss1_release_mx(layer3_proc_t *pc, int pr, void *arg)
|
||||||
{
|
{
|
||||||
msg_t *msg = arg;
|
msg_t *msg = arg;
|
||||||
|
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
l3dss1_release(pc, pr, msg);
|
l3dss1_release(pc, pr, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,7 +1373,7 @@ l3dss1_release_cmpl_m(layer3_proc_t *pc, int pr, void *arg)
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
|
||||||
if (pc->state == 6) {
|
if (pc->state == 6) {
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
if ((p = l3dss1_get_cause(pc, msg, NULL))) {
|
if ((p = l3dss1_get_cause(pc, msg, NULL))) {
|
||||||
dprint(DBGM_L3,"%s cause (%d/%d)\n", __FUNCTION__,
|
dprint(DBGM_L3,"%s cause (%d/%d)\n", __FUNCTION__,
|
||||||
pc->cause, pc->err);
|
pc->cause, pc->err);
|
||||||
|
@ -1280,7 +1397,7 @@ l3dss1_release_cmpl_mx(layer3_proc_t *pc, int pr, void *arg)
|
||||||
{
|
{
|
||||||
msg_t *msg = arg;
|
msg_t *msg = arg;
|
||||||
|
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
l3dss1_release_cmpl(pc, pr, msg);
|
l3dss1_release_cmpl(pc, pr, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,12 +1406,15 @@ l3dss1_information_mx(layer3_proc_t *pc, int pr, void *arg)
|
||||||
{
|
{
|
||||||
msg_t *msg = arg;
|
msg_t *msg = arg;
|
||||||
|
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
l3dss1_information(pc, pr, msg);
|
l3dss1_information(pc, pr, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct stateentry mdatastatelist[] =
|
static struct stateentry mdatastatelist[] =
|
||||||
{
|
{
|
||||||
|
#warning setup acknowledge
|
||||||
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
|
MT_SETUP_ACKNOWLEDGE, l3dss1_setup_acknowledge_m},
|
||||||
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
MT_CALL_PROCEEDING, l3dss1_proceeding_m},
|
MT_CALL_PROCEEDING, l3dss1_proceeding_m},
|
||||||
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
|
||||||
|
@ -1457,8 +1577,16 @@ l3dss1_setup_req(layer3_proc_t *pc, int pr, void *arg)
|
||||||
memcpy(msg_put(msg, l), &pc->obuf[0], l);
|
memcpy(msg_put(msg, l), &pc->obuf[0], l);
|
||||||
newl3state(pc, 6);
|
newl3state(pc, 6);
|
||||||
dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
|
dhexprint(DBGM_L3DATA, "l3 oframe:", &pc->obuf[0], l);
|
||||||
if (l3_msg(pc->l3, DL_UNITDATA | REQUEST, 127, msg))
|
#warning testing
|
||||||
free_msg(msg);
|
if (pc->l3->l2_state0 && (pc->l3->nst->feature & FEATURE_NET_PTP)) {
|
||||||
|
dprint(DBGM_L3, "%s: proc(%p) sending SETUP to CES 0\n", __FUNCTION__, pc);
|
||||||
|
if (l3_msg(pc->l3, DL_DATA | REQUEST, 0, msg))
|
||||||
|
free_msg(msg);
|
||||||
|
} else {
|
||||||
|
dprint(DBGM_L3, "%s: proc(%p) sending SETUP to broadcast CES\n", __FUNCTION__, pc);
|
||||||
|
if (l3_msg(pc->l3, DL_UNITDATA | REQUEST, 127, msg))
|
||||||
|
free_msg(msg);
|
||||||
|
}
|
||||||
L3DelTimer(&pc->timer1);
|
L3DelTimer(&pc->timer1);
|
||||||
test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
|
test_and_clear_bit(FLG_L3P_TIMER303_1, &pc->Flags);
|
||||||
L3AddTimer(&pc->timer1, T303, 0x303);
|
L3AddTimer(&pc->timer1, T303, 0x303);
|
||||||
|
@ -1480,12 +1608,15 @@ l3dss1_connect_req(layer3_proc_t *pc, int pr, void *arg)
|
||||||
if (conn->CHANNEL_ID[0] == 1)
|
if (conn->CHANNEL_ID[0] == 1)
|
||||||
pc->bc = conn->CHANNEL_ID[1] & 3;
|
pc->bc = conn->CHANNEL_ID[1] & 3;
|
||||||
}
|
}
|
||||||
|
#warning pc->bc is nice, but a task of the application. if you change anything, please let me know.
|
||||||
|
#if 0
|
||||||
if (!pc->bc) {
|
if (!pc->bc) {
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
l3_debug(pc->l3, "D-chan connect for waiting call");
|
l3_debug(pc->l3, "D-chan connect for waiting call");
|
||||||
l3dss1_disconnect_req(pc, pr, NULL);
|
l3dss1_disconnect_req(pc, pr, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (conn) {
|
if (conn) {
|
||||||
MsgStart(pc, MT_CONNECT);
|
MsgStart(pc, MT_CONNECT);
|
||||||
if (conn->BEARER)
|
if (conn->BEARER)
|
||||||
|
@ -1529,12 +1660,14 @@ l3dss1_connect_res(layer3_proc_t *pc, int pr, void *arg)
|
||||||
if (connack->CHANNEL_ID[0] == 1)
|
if (connack->CHANNEL_ID[0] == 1)
|
||||||
pc->bc = connack->CHANNEL_ID[1] & 3;
|
pc->bc = connack->CHANNEL_ID[1] & 3;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (!pc->bc) {
|
if (!pc->bc) {
|
||||||
if (pc->l3->debug & L3_DEB_WARN)
|
if (pc->l3->debug & L3_DEB_WARN)
|
||||||
l3_debug(pc->l3, "D-chan connect for waiting call");
|
l3_debug(pc->l3, "D-chan connect for waiting call");
|
||||||
l3dss1_disconnect_req(pc, pr, NULL);
|
l3dss1_disconnect_req(pc, pr, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (connack) {
|
if (connack) {
|
||||||
MsgStart(pc, MT_CONNECT_ACKNOWLEDGE);
|
MsgStart(pc, MT_CONNECT_ACKNOWLEDGE);
|
||||||
if (connack->CHANNEL_ID)
|
if (connack->CHANNEL_ID)
|
||||||
|
@ -1658,9 +1791,9 @@ l3dss1_progress_req(layer3_proc_t *pc, int pr, void *arg)
|
||||||
AddvarIE(pc, IE_DISPLAY, prog->DISPLAY);
|
AddvarIE(pc, IE_DISPLAY, prog->DISPLAY);
|
||||||
if (prog->HLC)
|
if (prog->HLC)
|
||||||
AddvarIE(pc, IE_HLC, prog->HLC);
|
AddvarIE(pc, IE_HLC, prog->HLC);
|
||||||
#warning ETSI 300286-1 only define USER_USER for USER_INFORMATION SETUP ALERTING PROGRESS CONNECT DISCONNECT RELEASE*
|
//#warning ETSI 300286-1 only define USER_USER for USER_INFORMATION SETUP ALERTING PROGRESS CONNECT DISCONNECT RELEASE*
|
||||||
if (prog->USER_USER)
|
// if (prog->USER_USER)
|
||||||
AddvarIE(pc, IE_USER_USER, prog->USER_USER);
|
// AddvarIE(pc, IE_USER_USER, prog->USER_USER);
|
||||||
SendMsg(pc, -1);
|
SendMsg(pc, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1794,7 +1927,7 @@ l3dss1_t303(layer3_proc_t *pc, int pr, void *arg)
|
||||||
sizeof(RELEASE_COMPLETE_t), 3, NULL);
|
sizeof(RELEASE_COMPLETE_t), 3, NULL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
relc = (RELEASE_COMPLETE_t *)(msg->data + mISDN_HEADER_LEN);
|
relc = (RELEASE_COMPLETE_t *)(msg->data + mISDNUSER_HEAD_SIZE);
|
||||||
newl3state(pc, 0);
|
newl3state(pc, 0);
|
||||||
relc->CAUSE = msg_put(msg, 3);
|
relc->CAUSE = msg_put(msg, 3);
|
||||||
relc->CAUSE[0] = 2;
|
relc->CAUSE[0] = 2;
|
||||||
|
@ -1818,6 +1951,7 @@ l3dss1_t303(layer3_proc_t *pc, int pr, void *arg)
|
||||||
free_msg(msg);
|
free_msg(msg);
|
||||||
}
|
}
|
||||||
L3DelTimer(&pc->timer2);
|
L3DelTimer(&pc->timer2);
|
||||||
|
dprint(DBGM_L3, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
|
||||||
L3AddTimer(&pc->timer2, T312, 0x312);
|
L3AddTimer(&pc->timer2, T312, 0x312);
|
||||||
test_and_set_bit(FLG_L3P_TIMER312,
|
test_and_set_bit(FLG_L3P_TIMER312,
|
||||||
&pc->Flags);
|
&pc->Flags);
|
||||||
|
@ -1830,7 +1964,7 @@ l3dss1_t303(layer3_proc_t *pc, int pr, void *arg)
|
||||||
sizeof(RELEASE_COMPLETE_t), 3, NULL);
|
sizeof(RELEASE_COMPLETE_t), 3, NULL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
relc = (RELEASE_COMPLETE_t *)(msg->data + mISDN_HEADER_LEN);
|
relc = (RELEASE_COMPLETE_t *)(msg->data + mISDNUSER_HEAD_SIZE);
|
||||||
relc->CAUSE = msg_put(msg, 3);
|
relc->CAUSE = msg_put(msg, 3);
|
||||||
relc->CAUSE[0] = 2;
|
relc->CAUSE[0] = 2;
|
||||||
relc->CAUSE[1] = 0x85;
|
relc->CAUSE[1] = 0x85;
|
||||||
|
@ -1867,6 +2001,7 @@ l3dss1_t312(layer3_proc_t *pc, int pr, void *arg)
|
||||||
|
|
||||||
test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
|
test_and_clear_bit(FLG_L3P_TIMER312, &pc->Flags);
|
||||||
L3DelTimer(&pc->timer2);
|
L3DelTimer(&pc->timer2);
|
||||||
|
dprint(DBGM_L3, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
|
||||||
l3_debug(pc->l3, "%s: state %d", __FUNCTION__, pc->state);
|
l3_debug(pc->l3, "%s: state %d", __FUNCTION__, pc->state);
|
||||||
if (pc->state == 22) {
|
if (pc->state == 22) {
|
||||||
StopAllL3Timer(pc);
|
StopAllL3Timer(pc);
|
||||||
|
@ -2124,7 +2259,7 @@ machen
|
||||||
CC_FACILITY | REQUEST, l3dss1_facility_req},
|
CC_FACILITY | REQUEST, l3dss1_facility_req},
|
||||||
{SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
|
{SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
|
||||||
CC_USER_INFORMATION | REQUEST, l3dss1_userinfo_req},
|
CC_USER_INFORMATION | REQUEST, l3dss1_userinfo_req},
|
||||||
{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) | SBIT(12),
|
{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(25),
|
||||||
CC_INFORMATION | REQUEST, l3dss1_information_req},
|
CC_INFORMATION | REQUEST, l3dss1_information_req},
|
||||||
{SBIT(2) | SBIT(3) | SBIT(4),
|
{SBIT(2) | SBIT(3) | SBIT(4),
|
||||||
CC_PROGRESS | REQUEST, l3dss1_progress_req},
|
CC_PROGRESS | REQUEST, l3dss1_progress_req},
|
||||||
|
@ -2184,6 +2319,7 @@ imsg_intrelease(layer3_proc_t *master, layer3_proc_t *child)
|
||||||
case 25:
|
case 25:
|
||||||
if (master->child ||
|
if (master->child ||
|
||||||
test_bit(FLG_L3P_TIMER312, &master->Flags)) {
|
test_bit(FLG_L3P_TIMER312, &master->Flags)) {
|
||||||
|
dprint(DBGM_L3, "%s: JOLLY child=%p, flg=%d\n", __FUNCTION__, master->child, test_bit(FLG_L3P_TIMER312, &master->Flags));
|
||||||
#warning TODO: save cause
|
#warning TODO: save cause
|
||||||
#warning bedenke auch, dass vielleicht overlap sending mit information-messages praktisch wäre (später PTP)
|
#warning bedenke auch, dass vielleicht overlap sending mit information-messages praktisch wäre (später PTP)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2371,7 +2507,7 @@ send_proc(layer3_proc_t *proc, int op, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dl_data_mux(layer3_t *l3, mISDN_head_t *hh, msg_t *msg)
|
dl_data_mux(layer3_t *l3, mISDNuser_head_t *hh, msg_t *msg)
|
||||||
{
|
{
|
||||||
layer3_proc_t *proc;
|
layer3_proc_t *proc;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
@ -2454,14 +2590,15 @@ dl_data_mux(layer3_t *l3, mISDN_head_t *hh, msg_t *msg)
|
||||||
} else {
|
} else {
|
||||||
dprint(DBGM_L3, "%s: mt(%x) do not create proc\n", __FUNCTION__,
|
dprint(DBGM_L3, "%s: mt(%x) do not create proc\n", __FUNCTION__,
|
||||||
l3m.mt);
|
l3m.mt);
|
||||||
|
#warning TODO: it happens that a response to an outgoing setup is received after connect of another terminal. in this case we must release.
|
||||||
free_msg(msg);
|
free_msg(msg);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((proc->ces & 0xfffffff0) == 0xfff0) {
|
if ((proc->ces & 0xfffffff0) == 0xff00) {
|
||||||
dprint(DBGM_L3, "%s: master state %d found\n", __FUNCTION__,
|
dprint(DBGM_L3, "%s: master state %d found\n", __FUNCTION__,
|
||||||
proc->state);
|
proc->state);
|
||||||
msg_push(msg, mISDN_HEADER_LEN);
|
msg_push(msg, mISDNUSER_HEAD_SIZE);
|
||||||
send_proc(proc, IMSG_MASTER_L2_DATA, &l3m);
|
send_proc(proc, IMSG_MASTER_L2_DATA, &l3m);
|
||||||
} else
|
} else
|
||||||
send_proc(proc, IMSG_L2_DATA, &l3m);
|
send_proc(proc, IMSG_L2_DATA, &l3m);
|
||||||
|
@ -2472,14 +2609,14 @@ dl_data_mux(layer3_t *l3, mISDN_head_t *hh, msg_t *msg)
|
||||||
int
|
int
|
||||||
l3_muxer(net_stack_t *nst, msg_t *msg)
|
l3_muxer(net_stack_t *nst, msg_t *msg)
|
||||||
{
|
{
|
||||||
mISDN_head_t *hh;
|
mISDNuser_head_t *hh;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
hh = (mISDN_head_t *)msg->data;
|
hh = (mISDNuser_head_t *)msg->data;
|
||||||
dprint(DBGM_L3, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
|
dprint(DBGM_L3, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
|
||||||
dprint(DBGM_L3, "%s: pr(%x) di(%x)\n", __FUNCTION__,
|
dprint(DBGM_L3, "%s: pr(%x) di(%x)\n", __FUNCTION__,
|
||||||
hh->prim, hh->dinfo);
|
hh->prim, hh->dinfo);
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
if (hh->prim == (DL_DATA | INDICATION)) {
|
if (hh->prim == (DL_DATA | INDICATION)) {
|
||||||
ret = dl_data_mux(nst->layer3, hh, msg);
|
ret = dl_data_mux(nst->layer3, hh, msg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2494,26 +2631,60 @@ l3_muxer(net_stack_t *nst, msg_t *msg)
|
||||||
static int
|
static int
|
||||||
manager_l3(net_stack_t *nst, msg_t *msg)
|
manager_l3(net_stack_t *nst, msg_t *msg)
|
||||||
{
|
{
|
||||||
mISDN_head_t *hh;
|
mISDNuser_head_t *hh;
|
||||||
layer3_proc_t *proc;
|
layer3_proc_t *proc;
|
||||||
struct _l3_msg l3m;
|
struct _l3_msg l3m;
|
||||||
|
|
||||||
hh = (mISDN_head_t *)msg->data;
|
hh = (mISDNuser_head_t *)msg->data;
|
||||||
dprint(DBGM_L3, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
|
dprint(DBGM_L3, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
|
||||||
dprint(DBGM_L3, "%s: pr(%x) di(%x)\n", __FUNCTION__,
|
dprint(DBGM_L3, "%s: pr(%x) di(%x)\n", __FUNCTION__,
|
||||||
hh->prim, hh->dinfo);
|
hh->prim, hh->dinfo);
|
||||||
msg_pull(msg, mISDN_HEADER_LEN);
|
msg_pull(msg, mISDNUSER_HEAD_SIZE);
|
||||||
proc = find_proc(nst->layer3->proc, hh->dinfo & 0xffff,
|
proc = find_proc(nst->layer3->proc, hh->dinfo & 0xffff,
|
||||||
(hh->dinfo>>16)& 0xffff);
|
(hh->dinfo>>16)& 0xffff);
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
if (hh->prim == (CC_SETUP | REQUEST)) {
|
if (hh->prim == (CC_SETUP | REQUEST)) {
|
||||||
int l4id;
|
int l4id;
|
||||||
nst->layer3->next_cr++;
|
nst->layer3->next_cr++;
|
||||||
if (nst->layer3->next_cr>126)
|
if (nst->feature & FEATURE_NET_CRLEN2) {
|
||||||
nst->layer3->next_cr = 1;
|
if (nst->layer3->next_cr>32766)
|
||||||
|
nst->layer3->next_cr = 1;
|
||||||
|
} else {
|
||||||
|
if (nst->layer3->next_cr>126)
|
||||||
|
nst->layer3->next_cr = 1;
|
||||||
|
}
|
||||||
proc = create_proc(nst->layer3, hh->dinfo & 0xffff,
|
proc = create_proc(nst->layer3, hh->dinfo & 0xffff,
|
||||||
nst->layer3->next_cr | 0x80, NULL);
|
nst->layer3->next_cr | 0x8000, NULL);
|
||||||
|
if (!proc) {
|
||||||
|
dprint(DBGM_L3, "%s: pr(%x) failed to create proc.\n",
|
||||||
|
__FUNCTION__, hh->prim);
|
||||||
|
free_msg(msg);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
dprint(DBGM_L3, "%s: proc(%p)\n", __FUNCTION__, proc);
|
dprint(DBGM_L3, "%s: proc(%p)\n", __FUNCTION__, proc);
|
||||||
|
#warning testing
|
||||||
|
#if 0
|
||||||
|
printf("check for tei 0 active\n");
|
||||||
|
l2 = nst->layer2;
|
||||||
|
while(l2) {
|
||||||
|
if (l2->tei == 0 && l2->sapi == 0)
|
||||||
|
break;
|
||||||
|
l2 = l2->next;
|
||||||
|
}
|
||||||
|
if (l2) if (l2->state == ST_L2_4) {
|
||||||
|
p3i = create_proc(proc->l3, 0, proc->callref, proc);
|
||||||
|
if (!p3i) {
|
||||||
|
l3_debug(proc->l3, "cannot create child\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
proc = p3i;
|
||||||
|
|
||||||
|
dprint(DBGM_L3, "%s: TEI 0 is active, so we created proc(%p)\n", __FUNCTION__, proc);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
APPEND_TO_LIST(proc, nst->layer3->proc);
|
APPEND_TO_LIST(proc, nst->layer3->proc);
|
||||||
l4id = proc->ces | (proc->callref << 16);
|
l4id = proc->ces | (proc->callref << 16);
|
||||||
if_link(nst->manager, (ifunc_t)nst->l3_manager, CC_SETUP |
|
if_link(nst->manager, (ifunc_t)nst->l3_manager, CC_SETUP |
|
||||||
|
@ -2547,7 +2718,7 @@ release_l3(layer3_t *l3) {
|
||||||
l3->proc->ces);
|
l3->proc->ces);
|
||||||
send_proc(l3->proc, IMSG_END_PROC, NULL);
|
send_proc(l3->proc, IMSG_END_PROC, NULL);
|
||||||
}
|
}
|
||||||
msg_queue_purge(&l3->squeue);
|
msg_queue_purge(&l3->squeue0);
|
||||||
REMOVE_FROM_LISTBASE(l3, l3->nst->layer3);
|
REMOVE_FROM_LISTBASE(l3, l3->nst->layer3);
|
||||||
free(l3);
|
free(l3);
|
||||||
}
|
}
|
||||||
|
@ -2578,74 +2749,157 @@ l3down(layer3_t *l3, u_int prim, int dinfo, msg_t *msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_squeue(layer3_t *l3)
|
send_squeue(layer3_t *l3, msg_queue_t *squeue)
|
||||||
{
|
{
|
||||||
msg_t *msg;
|
msg_t *msg;
|
||||||
|
|
||||||
while((msg = msg_dequeue(&l3->squeue))) {
|
while((msg = msg_dequeue(&l3->squeue0))) {
|
||||||
if (l3->nst->l3_l2(l3->nst, msg))
|
if (l3->nst->l3_l2(l3->nst, msg))
|
||||||
free_msg(msg);
|
free_msg(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning testing
|
||||||
|
static int
|
||||||
|
remove_proc(layer3_proc_t **procp, int ces)
|
||||||
|
{
|
||||||
|
int found = 1;
|
||||||
|
int any = 0;
|
||||||
|
layer3_proc_t *proc;
|
||||||
|
|
||||||
|
if (ces > 126)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
while(found) {
|
||||||
|
found = 0;
|
||||||
|
proc = *procp;
|
||||||
|
while(proc) {
|
||||||
|
dprint(DBGM_L3, "%s: comparing %s proc(%x) ces(%x)\n", __FUNCTION__,
|
||||||
|
(proc->master)?"child":"master", proc, proc->ces);
|
||||||
|
if (proc->ces == ces) {
|
||||||
|
dprint(DBGM_L3, "%s: found proc(%x)\n", __FUNCTION__,
|
||||||
|
proc);
|
||||||
|
if (proc->master)
|
||||||
|
send_proc(proc, IMSG_END_PROC_M, NULL);
|
||||||
|
else
|
||||||
|
send_proc(proc, IMSG_END_PROC, NULL);
|
||||||
|
any = 1;
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (proc->child) {
|
||||||
|
if (remove_proc(&proc->child, ces)) {
|
||||||
|
any = 1;
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proc = proc->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(any);
|
||||||
|
}
|
||||||
|
|
||||||
|
#warning l2_state makes no sense in multipoint environment. shouldnt we use something like l2_state[ces] ?
|
||||||
static int
|
static int
|
||||||
l3_msg(layer3_t *l3, u_int pr, int dinfo, void *arg)
|
l3_msg(layer3_t *l3, u_int pr, int dinfo, void *arg)
|
||||||
{
|
{
|
||||||
msg_t *msg = arg;
|
msg_t *msg = arg, *lmsg = NULL;
|
||||||
|
#warning testing
|
||||||
|
int ces = dinfo & 0xffff;
|
||||||
dprint(DBGM_L3, "%s: pr(%x) di(%x) arg(%p)\n", __FUNCTION__,
|
dprint(DBGM_L3, "%s: pr(%x) di(%x) arg(%p)\n", __FUNCTION__,
|
||||||
pr, dinfo, arg);
|
pr, dinfo, arg);
|
||||||
switch (pr) {
|
switch (pr) {
|
||||||
case (DL_UNITDATA | REQUEST):
|
case (DL_UNITDATA | REQUEST):
|
||||||
return(l3down(l3, pr, dinfo, arg));
|
return(l3down(l3, pr, dinfo, arg));
|
||||||
case (DL_DATA | REQUEST):
|
case (DL_DATA | REQUEST):
|
||||||
if (l3->l2_state == ST_L3_LC_ESTAB) {
|
if (l3->l2_state0 == ST_L3_LC_ESTAB || ces > 0) {
|
||||||
return(l3down(l3, pr, dinfo, arg));
|
return(l3down(l3, pr, dinfo, arg));
|
||||||
} else {
|
} else {
|
||||||
mISDN_addhead(pr, dinfo, msg);
|
if (ces == 0) {
|
||||||
msg_queue_tail(&l3->squeue, msg);
|
mISDN_addhead(pr, dinfo, msg);
|
||||||
l3->l2_state = ST_L3_LC_ESTAB_WAIT;
|
msg_queue_tail(&l3->squeue0, msg);
|
||||||
l3down(l3, DL_ESTABLISH | REQUEST, dinfo, NULL);
|
l3->l2_state0 = ST_L3_LC_ESTAB_WAIT;
|
||||||
return(0);
|
l3down(l3, DL_ESTABLISH | REQUEST, dinfo, NULL);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (DL_DATA | CONFIRM):
|
case (DL_DATA | CONFIRM):
|
||||||
break;
|
break;
|
||||||
case (DL_ESTABLISH | REQUEST):
|
case (DL_ESTABLISH | REQUEST):
|
||||||
if (l3->l2_state != ST_L3_LC_ESTAB) {
|
if (ces == 0) {
|
||||||
l3down(l3, pr, dinfo, NULL);
|
if (l3->l2_state0 != ST_L3_LC_ESTAB) {
|
||||||
l3->l2_state = ST_L3_LC_ESTAB_WAIT;
|
l3down(l3, pr, dinfo, NULL);
|
||||||
|
l3->l2_state0 = ST_L3_LC_ESTAB_WAIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (DL_ESTABLISH | CONFIRM):
|
case (DL_ESTABLISH | CONFIRM):
|
||||||
if (l3->l2_state != ST_L3_LC_REL_WAIT) {
|
if (ces == 0) {
|
||||||
l3->l2_state = ST_L3_LC_ESTAB;
|
if (l3->l2_state0 != ST_L3_LC_REL_WAIT) {
|
||||||
send_squeue(l3);
|
l3->l2_state0 = ST_L3_LC_ESTAB;
|
||||||
|
send_squeue(l3, &l3->squeue0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!l3->nst->l3_manager)
|
||||||
|
break;
|
||||||
|
if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
|
||||||
|
break;
|
||||||
|
if (l3->nst->l3_manager(l3->nst->manager, lmsg))
|
||||||
|
free_msg(lmsg);
|
||||||
break;
|
break;
|
||||||
case (DL_ESTABLISH | INDICATION):
|
case (DL_ESTABLISH | INDICATION):
|
||||||
if (l3->l2_state == ST_L3_LC_REL) {
|
if (ces == 0) {
|
||||||
l3->l2_state = ST_L3_LC_ESTAB;
|
if (l3->l2_state0 == ST_L3_LC_REL) {
|
||||||
send_squeue(l3);
|
l3->l2_state0 = ST_L3_LC_ESTAB;
|
||||||
|
send_squeue(l3, &l3->squeue0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!l3->nst->l3_manager)
|
||||||
|
break;
|
||||||
|
if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
|
||||||
|
break;
|
||||||
|
if (l3->nst->l3_manager(l3->nst->manager, lmsg))
|
||||||
|
free_msg(lmsg);
|
||||||
break;
|
break;
|
||||||
case (DL_RELEASE | INDICATION):
|
case (DL_RELEASE | INDICATION):
|
||||||
#warning du musst alle processe releasen CC_RELEASE!!! dies geschieht z.b. wenn man das telefon vom s0-bus abnimmt und der layer-2 dadurch zusammen bricht.
|
#warning du musst alle processe releasen CC_RELEASE!!! dies geschieht z.b. wenn man das telefon vom s0-bus abnimmt und der layer-2 dadurch zusammen bricht.
|
||||||
#warning geschieht dies auch im TE-mode?
|
#warning geschieht dies auch im TE-mode?
|
||||||
#warning TODO DL_RELEASE | INDICATION handling; inclusiv special state 10 (T309)
|
#warning TODO DL_RELEASE | INDICATION handling; inclusiv special state 10 (T309)
|
||||||
if (l3->l2_state == ST_L3_LC_ESTAB) {
|
if (ces == 0) {
|
||||||
l3->l2_state = ST_L3_LC_REL;
|
if (l3->l2_state0 == ST_L3_LC_ESTAB) {
|
||||||
|
l3->l2_state0 = ST_L3_LC_REL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!l3->nst->l3_manager)
|
||||||
|
break;
|
||||||
|
if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
|
||||||
|
break;
|
||||||
|
if (l3->nst->l3_manager(l3->nst->manager, lmsg))
|
||||||
|
free_msg(lmsg);
|
||||||
|
remove_proc(&l3->proc, dinfo);
|
||||||
break;
|
break;
|
||||||
case (DL_RELEASE | CONFIRM):
|
case (DL_RELEASE | CONFIRM):
|
||||||
if (l3->l2_state == ST_L3_LC_REL_WAIT) {
|
if (ces == 0) {
|
||||||
l3->l2_state = ST_L3_LC_REL;
|
if (l3->l2_state0 == ST_L3_LC_REL_WAIT) {
|
||||||
|
l3->l2_state0 = ST_L3_LC_REL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!l3->nst->l3_manager)
|
||||||
|
break;
|
||||||
|
if (!(lmsg = create_link_msg(pr, dinfo, 0, NULL, 0)))
|
||||||
|
break;
|
||||||
|
if (l3->nst->l3_manager(l3->nst->manager, lmsg))
|
||||||
|
free_msg(lmsg);
|
||||||
|
remove_proc(&l3->proc, dinfo);
|
||||||
break;
|
break;
|
||||||
case (DL_RELEASE | REQUEST):
|
case (DL_RELEASE | REQUEST):
|
||||||
if (l3->l2_state == ST_L3_LC_ESTAB) {
|
if (ces == 0) {
|
||||||
l3down(l3, pr, dinfo, NULL);
|
if (l3->l2_state0 == ST_L3_LC_ESTAB) {
|
||||||
l3->l2_state = ST_L3_LC_REL_WAIT;
|
l3down(l3, pr, dinfo, NULL);
|
||||||
|
l3->l2_state0 = ST_L3_LC_REL_WAIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2666,8 +2920,9 @@ int Isdnl3Init(net_stack_t *nst)
|
||||||
nst->l2_l3 = l3_muxer;
|
nst->l2_l3 = l3_muxer;
|
||||||
nst->manager_l3 = manager_l3;
|
nst->manager_l3 = manager_l3;
|
||||||
l3->debug = 0xff;
|
l3->debug = 0xff;
|
||||||
msg_queue_init(&l3->squeue);
|
#warning testing
|
||||||
l3->l2_state = ST_L3_LC_REL;
|
msg_queue_init(&l3->squeue0);
|
||||||
|
l3->l2_state0 = ST_L3_LC_REL;
|
||||||
APPEND_TO_LIST(l3, nst->layer3);
|
APPEND_TO_LIST(l3, nst->layer3);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -2679,7 +2934,4 @@ void cleanup_Isdnl3(net_stack_t *nst)
|
||||||
while(nst->layer3)
|
while(nst->layer3)
|
||||||
release_l3(nst->layer3);
|
release_l3(nst->layer3);
|
||||||
}
|
}
|
||||||
//puts("jolldebug 1");
|
|
||||||
// free(malloc(1000));
|
|
||||||
//puts("jolldebug 2");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue