Beispiel #1
0
static void
l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;
	u_char *p;

	p = skb->data;
	if ((p = findie(p, skb->len, WE0_cause, 0))) {
		if (p[1] > 0) {
			pc->para.cause = p[2];
			if (p[1] > 1)
				pc->para.loc = p[3];
			else
				pc->para.loc = 0;
		} else {
			pc->para.cause = 0;
			pc->para.loc = 0;
		}
	} else {
		pc->para.cause = NO_CAUSE;
		l3_1tr6_error(pc, "missing REL cause", skb);
		return;
	}
	dev_kfree_skb(skb);
	StopAllL3Timer(pc);
	newl3state(pc, 0);
	l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1);
	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
	release_l3_process(pc);
}
Beispiel #2
0
void
release_l3_process(l3_process_t *p)
{
	layer3_t *l3;

	if (!p)
		return;
	l3 = p->l3;
	mISDN_l3up(p, CC_RELEASE_CR | INDICATION, NULL);
	list_del(&p->list);
	StopAllL3Timer(p);
	kfree(p);
	if (list_empty(&l3->plist) && !test_bit(FLG_PTP, &l3->Flag)) {
		if (l3->debug)
			l3_debug(l3, "release_l3_process: last process");
		if (!skb_queue_len(&l3->squeue)) {
			if (l3->debug)
				l3_debug(l3, "release_l3_process: release link");
			mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL);
		} else {
			if (l3->debug)
				l3_debug(l3, "release_l3_process: not release link");
		}
	}
};
Beispiel #3
0
static void
l3_1tr6_disconnect_req(struct PStack *st, u_char pr, void *arg)
{
	struct sk_buff *skb;
	u_char tmp[16];
	u_char *p = tmp;
	int l;
	u_char cause = 0x10;
	u_char clen = 1;

	if (st->pa->cause > 0)
		cause = st->pa->cause;
	/* Map DSS1 causes */
	switch (cause & 0x7f) {
		case 0x10:
			clen = 0;
			break;
		case 0x15:
			cause = CAUSE_CallRejected;
			break;
	}
	StopAllL3Timer(st);
	MsgHead(p, st->l3.callref, MT_N1_DISC, PROTO_DIS_N1);
	*p++ = WE0_cause;
	*p++ = clen;		/* Laenge */
	if (clen)
		*p++ = cause | 0x80;
	newl3state(st, 11);
	l = p - tmp;
	if (!(skb = l3_alloc_skb(l)))
		return;
	memcpy(skb_put(skb, l), tmp, l);
	st->l3.l3l2(st, DL_DATA, skb);
	L3AddTimer(&st->l3.timer, st->l3.t305, CC_T305);
}
Beispiel #4
0
static void
l3_1tr6_rel(struct PStack *st, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;
	u_char *p;

	p = skb->data;
	if ((p = findie(p, skb->len, WE0_cause, 0))) {
		if (p[1] > 0) {
			st->pa->cause = p[2];
			if (p[1] > 1)
				st->pa->loc = p[3];
			else
				st->pa->loc = 0;
		} else {
			st->pa->cause = 0;
			st->pa->loc = 0;
		}
	} else
		st->pa->cause = -1;
	SET_SKB_FREE(skb);
	dev_kfree_skb(skb, FREE_READ);
	StopAllL3Timer(st);
	newl3state(st, 0);
	l3_1TR6_message(st, MT_N1_REL_ACK, PROTO_DIS_N1);
	st->l3.l3l4(st, CC_RELEASE_IND, NULL);
}
Beispiel #5
0
static void
l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg)
{
	StopAllL3Timer(pc);
	newl3state(pc, 19);
	l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
	L3AddTimer(&pc->timer, T308, CC_T308_1);
}
Beispiel #6
0
static void
l3_1tr6_release_req(struct PStack *st, u_char pr, void *arg)
{
	StopAllL3Timer(st);
	newl3state(st, 19);
	l3_1TR6_message(st, MT_N1_REL, PROTO_DIS_N1);
	L3AddTimer(&st->l3.timer, st->l3.t308, CC_T308_1);
}
Beispiel #7
0
static void
l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;
	u_char *p;
	int i, tmpcharge = 0;
	char a_charge[8], tmp[32];

	StopAllL3Timer(pc);
	p = skb->data;
	if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
		iecpy(a_charge, p, 1);
		for (i = 0; i < strlen(a_charge); i++) {
			tmpcharge *= 10;
			tmpcharge += a_charge[i] & 0xf;
		}
		if (tmpcharge > pc->para.chargeinfo) {
			pc->para.chargeinfo = tmpcharge;
			pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
		}
		if (pc->st->l3.debug & L3_DEB_CHARGE) {
			sprintf(tmp, "charging info %d", pc->para.chargeinfo);
			l3_debug(pc->st, tmp);
		}
	} else if (pc->st->l3.debug & L3_DEB_CHARGE)
		l3_debug(pc->st, "charging info not found");


	p = skb->data;
	if ((p = findie(p, skb->len, WE0_cause, 0))) {
		if (p[1] > 0) {
			pc->para.cause = p[2];
			if (p[1] > 1)
				pc->para.loc = p[3];
			else
				pc->para.loc = 0;
		} else {
			pc->para.cause = 0;
			pc->para.loc = 0;
		}
	} else {
		if (pc->st->l3.debug & L3_DEB_WARN)
			l3_debug(pc->st, "cause not found");
		pc->para.cause = NO_CAUSE;
	}
	if (!findie(skb->data, skb->len, WE6_date, 6)) {
		l3_1tr6_error(pc, "missing connack date", skb);
		return;
	}
	dev_kfree_skb(skb);
	newl3state(pc, 12);
	pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
}
Beispiel #8
0
static void
l3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;

	dev_kfree_skb(skb);
	StopAllL3Timer(pc);
	newl3state(pc, 0);
	pc->para.cause = NO_CAUSE;
	pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
	release_l3_process(pc);
}
Beispiel #9
0
void
releasestack_isdnl3(struct PStack *st)
{
	while (st->l3.proc)
		release_l3_process(st->l3.proc);
	if (st->l3.global) {
		StopAllL3Timer(st->l3.global);
		kfree(st->l3.global);
		st->l3.global = NULL;
	}
	discard_queue(&st->l3.squeue);
}
Beispiel #10
0
static void
l3_1tr6_rel_ack(struct PStack *st, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;

	SET_SKB_FREE(skb);
	dev_kfree_skb(skb, FREE_READ);
	StopAllL3Timer(st);
	newl3state(st, 0);
	st->pa->cause = -1;
	st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
}
void
releasestack_isdnl3(struct PStack *st)
{
	while (st->l3.proc)
		release_l3_process(st->l3.proc);
	if (st->l3.global) {
		StopAllL3Timer(st->l3.global);
		kfree(st->l3.global);
		st->l3.global = NULL;
	}
	FsmDelTimer(&st->l3.l3m_timer, 54);
	skb_queue_purge(&st->l3.squeue);
}
Beispiel #12
0
void
release_l3(layer3_t *l3)
{
	l3_process_t *p, *np;

	if (l3->l3m.debug)
		printk(KERN_DEBUG "release_l3(%p) plist(%s) global(%p) dummy(%p)\n",
			l3, list_empty(&l3->plist) ? "no" : "yes", l3->global, l3->dummy);
	list_for_each_entry_safe(p, np, &l3->plist, list)
		release_l3_process(p);
	if (l3->global) {
		StopAllL3Timer(l3->global);
		kfree(l3->global);
		l3->global = NULL;
	}
	if (l3->dummy) {
		StopAllL3Timer(l3->dummy);
		kfree(l3->dummy);
		l3->dummy = NULL;
	}
	mISDN_FsmDelTimer(&l3->l3m_timer, 54);
	discard_queue(&l3->squeue);
}
Beispiel #13
0
static void
l3_1tr6_disc(struct PStack *st, u_char pr, void *arg)
{
	struct sk_buff *skb = arg;
	u_char *p;
	int i, tmpcharge = 0;
	char a_charge[8], tmp[32];

	StopAllL3Timer(st);
	p = skb->data;
	if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
		iecpy(a_charge, p, 1);
		for (i = 0; i < strlen(a_charge); i++) {
			tmpcharge *= 10;
			tmpcharge += a_charge[i] & 0xf;
		}
		if (tmpcharge > st->pa->chargeinfo) {
			st->pa->chargeinfo = tmpcharge;
			st->l3.l3l4(st, CC_INFO_CHARGE, NULL);
		}
		if (st->l3.debug & L3_DEB_CHARGE) {
			sprintf(tmp, "charging info %d", st->pa->chargeinfo);
			l3_debug(st, tmp);
		}
	} else if (st->l3.debug & L3_DEB_CHARGE)
		l3_debug(st, "charging info not found");


	p = skb->data;
	if ((p = findie(p, skb->len, WE0_cause, 0))) {
		if (p[1] > 0) {
			st->pa->cause = p[2];
			if (p[1] > 1)
				st->pa->loc = p[3];
			else
				st->pa->loc = 0;
		} else {
			st->pa->cause = 0;
			st->pa->loc = 0;
		}
	} else {
		if (st->l3.debug & L3_DEB_WARN)
			l3_debug(st, "cause not found");
		st->pa->cause = -1;
	}
	SET_SKB_FREE(skb);
	dev_kfree_skb(skb, FREE_READ);
	newl3state(st, 12);
	st->l3.l3l4(st, CC_DISCONNECT_IND, NULL);
}
Beispiel #14
0
static void
l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb;
	u_char tmp[16];
	u_char *p = tmp;
	int l;
	u_char cause = 0x10;
	u_char clen = 1;

	if (pc->para.cause > 0)
		cause = pc->para.cause;
	/* Map DSS1 causes */
	switch (cause & 0x7f) {
		case 0x10:
			clen = 0;
			break;
                case 0x11:
                        cause = CAUSE_UserBusy;
                        break;
		case 0x15:
			cause = CAUSE_CallRejected;
			break;
	}
	StopAllL3Timer(pc);
	MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1);
	*p++ = WE0_cause;
	*p++ = clen;		/* Laenge */
	if (clen)
		*p++ = cause | 0x80;
	newl3state(pc, 11);
	l = p - tmp;
	if (!(skb = l3_alloc_skb(l)))
		return;
	memcpy(skb_put(skb, l), tmp, l);
	l3_msg(pc->st, DL_DATA | REQUEST, skb);
	L3AddTimer(&pc->timer, T305, CC_T305);
}
void
release_l3_process(struct l3_process *p)
{
	struct l3_process *np, *pp = NULL;

	if (!p)
		return;
	np = p->st->l3.proc;
	while (np) {
		if (np == p) {
			StopAllL3Timer(p);
			if (pp)
				pp->next = np->next;
			else if (!(p->st->l3.proc = np->next) &&
				!test_bit(FLG_PTP, &p->st->l2.flag)) {
				if (p->debug)
					l3_debug(p->st, "release_l3_process: last process");
				if (!skb_queue_len(&p->st->l3.squeue)) {
					if (p->debug)
						l3_debug(p->st, "release_l3_process: release link");
					if (p->st->protocol != ISDN_PTYPE_NI1)
						FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL);
					else
						FsmEvent(&p->st->l3.l3m, EV_RELEASE_IND, NULL);
				} else {
					if (p->debug)
						l3_debug(p->st, "release_l3_process: not release link");
				}
			} 
			kfree(p);
			return;
		}
		pp = np;
		np = np->next;
	}
	printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref);
	l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref);
};
Beispiel #16
0
void
release_l3_process(struct l3_process *p)
{
	struct l3_process *np, *pp = NULL;

	if (!p)
		return;
	np = p->st->l3.proc;
	while (np) {
		if (np == p) {
			StopAllL3Timer(p);
			if (pp)
				pp->next = np->next;
			else
				p->st->l3.proc = np->next;
			kfree(p);
			return;
		}
		pp = np;
		np = np->next;
	}
	printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref);
	l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref);
};