Exemplo n.º 1
0
static void
l3_1tr6_t305(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 = 0x90;
	u_char clen = 1;

	L3DelTimer(&pc->timer);
	if (pc->para.cause != NO_CAUSE)
		cause = pc->para.cause;
	/* Map DSS1 causes */
	switch (cause & 0x7f) {
		case 0x10:
			clen = 0;
			break;
		case 0x15:
			cause = CAUSE_CallRejected;
			break;
	}
	MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1);
	*p++ = WE0_cause;
	*p++ = clen;		/* Laenge */
	if (clen)
		*p++ = cause;
	newl3state(pc, 19);
	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, T308, CC_T308_1);
}
Exemplo n.º 2
0
static void
l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb;
	u_char tmp[24];
	u_char *p = tmp;
	int l;

	MsgHead(p, pc->callref, MT_N1_CONN, PROTO_DIS_N1);
	if (pc->para.spv) {	/* SPV ? */
		/* NSF SPV */
		*p++ = WE0_netSpecFac;
		*p++ = 4;	/* Laenge */
		*p++ = 0;
		*p++ = FAC_SPV;	/* SPV */
		*p++ = pc->para.setup.si1;
		*p++ = pc->para.setup.si2;
		*p++ = WE0_netSpecFac;
		*p++ = 4;	/* Laenge */
		*p++ = 0;
		*p++ = FAC_Activate;	/* aktiviere SPV */
		*p++ = pc->para.setup.si1;
		*p++ = pc->para.setup.si2;
	}
	newl3state(pc, 8);
	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);
	L3DelTimer(&pc->timer);
	L3AddTimer(&pc->timer, T313, CC_T313);
}
Exemplo n.º 3
0
static void
l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd)
{
	struct sk_buff *skb;
	u_char *p;

	if (!(skb = l3_alloc_skb(4)))
		return;
	p = skb_put(skb, 4);
	MsgHead(p, pc->callref, mt, pd);
	l3_msg(pc->st, DL_DATA | REQUEST, skb);
}
Exemplo n.º 4
0
static void
down1tr6(struct PStack *st, int pr, void *arg)
{
	int i, cr;
	struct l3_process *proc;
	struct Channel *chan;
	char tmp[80];

	if ((DL_ESTABLISH | REQUEST)== pr) {
		l3_msg(st, pr, NULL);
		return;
	} else if ((CC_SETUP | REQUEST) == pr) {
		chan = arg;
		cr = newcallref();
		cr |= 0x80;
		if (!(proc = new_l3_process(st, cr))) {
			return;
		} else {
			proc->chan = chan;
			chan->proc = proc;
			memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
			proc->callref = cr;
		}
	} else {
		proc = arg;
	}

	for (i = 0; i < DOWNSTL_LEN; i++)
		if ((pr == downstl[i].primitive) &&
		    ((1 << proc->state) & downstl[i].state))
			break;
	if (i == DOWNSTL_LEN) {
		if (st->l3.debug & L3_DEB_STATE) {
			sprintf(tmp, "down1tr6 state %d prim %d unhandled",
				proc->state, pr);
			l3_debug(st, tmp);
		}
	} else {
		if (st->l3.debug & L3_DEB_STATE) {
			sprintf(tmp, "down1tr6 state %d prim %d",
				proc->state, pr);
			l3_debug(st, tmp);
		}
		downstl[i].rout(proc, pr, arg);
	}
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
static void
up1tr6(struct PStack *st, int pr, void *arg)
{
	int i, mt, cr;
	struct l3_process *proc;
	struct sk_buff *skb = arg;
	char tmp[80];

	switch (pr) {
		case (DL_DATA | INDICATION):
		case (DL_UNIT_DATA | INDICATION):
			break;
		case (DL_ESTABLISH | CONFIRM):
		case (DL_ESTABLISH | INDICATION):
		case (DL_RELEASE | INDICATION):
		case (DL_RELEASE | CONFIRM):
			l3_msg(st, pr, arg);
			return;
			break;
	}
	if (skb->len < 4) {
		if (st->l3.debug & L3_DEB_PROTERR) {
			sprintf(tmp, "up1tr6 len only %d", skb->len);
			l3_debug(st, tmp);
		}
		dev_kfree_skb(skb);
		return;
	}
	if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) {
		if (st->l3.debug & L3_DEB_PROTERR) {
			sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d",
				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
				skb->data[0], skb->len);
			l3_debug(st, tmp);
		}
		dev_kfree_skb(skb);
		return;
	}
	if (skb->data[1] != 1) {
		if (st->l3.debug & L3_DEB_PROTERR) {
			sprintf(tmp, "up1tr6 CR len not 1");
			l3_debug(st, tmp);
		}
		dev_kfree_skb(skb);
		return;
	}
	cr = skb->data[2];
	mt = skb->data[3];
	if (skb->data[0] == PROTO_DIS_N0) {
		dev_kfree_skb(skb);
		if (st->l3.debug & L3_DEB_STATE) {
			sprintf(tmp, "up1tr6%s N0 mt %x unhandled",
			     (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
			l3_debug(st, tmp);
		}
	} else if (skb->data[0] == PROTO_DIS_N1) {
		if (!(proc = getl3proc(st, cr))) {
			if (mt == MT_N1_SETUP) { 
				if (cr < 128) {
					if (!(proc = new_l3_process(st, cr))) {
						if (st->l3.debug & L3_DEB_PROTERR) {
							sprintf(tmp, "up1tr6 no roc mem");
							l3_debug(st, tmp);
						}
						dev_kfree_skb(skb);
						return;
					}
				} else {
					dev_kfree_skb(skb);
					return;
				}
			} else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
				(mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
				(mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
				(mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
				(mt == MT_N1_INFO)) {
				dev_kfree_skb(skb);
				return;
			} else {
				if (!(proc = new_l3_process(st, cr))) {
					if (st->l3.debug & L3_DEB_PROTERR) {
						sprintf(tmp, "up1tr6 no roc mem");
						l3_debug(st, tmp);
					}
					dev_kfree_skb(skb);
					return;
				}
				mt = MT_N1_INVALID;
			}
		}
		for (i = 0; i < DATASTLN1_LEN; i++)
			if ((mt == datastln1[i].primitive) &&
			    ((1 << proc->state) & datastln1[i].state))
				break;
		if (i == DATASTLN1_LEN) {
			dev_kfree_skb(skb);
			if (st->l3.debug & L3_DEB_STATE) {
				sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
				  (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
					proc->state, mt);
				l3_debug(st, tmp);
			}
			return;
		} else {
			if (st->l3.debug & L3_DEB_STATE) {
				sprintf(tmp, "up1tr6%sstate %d mt %x",
				  (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
					proc->state, mt);
				l3_debug(st, tmp);
			}
			datastln1[i].rout(proc, pr, skb);
		}
	}
}
Exemplo n.º 7
0
static void
l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb;
	u_char tmp[128];
	u_char *p = tmp;
	u_char *teln;
	u_char *eaz;
	u_char channel = 0;
	int l;

	MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1);
	teln = pc->para.setup.phone;
	pc->para.spv = 0;
	if (!isdigit(*teln)) {
		switch (0x5f & *teln) {
			case 'S':
				pc->para.spv = 1;
				break;
			case 'C':
				channel = 0x08;
			case 'P':
				channel |= 0x80;
				teln++;
				if (*teln == '1')
					channel |= 0x01;
				else
					channel |= 0x02;
				break;
			default:
				if (pc->st->l3.debug & L3_DEB_WARN)
					l3_debug(pc->st, "Wrong MSN Code");
				break;
		}
		teln++;
	}
	if (channel) {
		*p++ = 0x18;	/* channel indicator */
		*p++ = 1;
		*p++ = channel;
	}
	if (pc->para.spv) {	/* SPV ? */
		/* NSF SPV */
		*p++ = WE0_netSpecFac;
		*p++ = 4;	/* Laenge */
		*p++ = 0;
		*p++ = FAC_SPV;	/* SPV */
		*p++ = pc->para.setup.si1;	/* 0 for all Services */
		*p++ = pc->para.setup.si2;	/* 0 for all Services */
		*p++ = WE0_netSpecFac;
		*p++ = 4;	/* Laenge */
		*p++ = 0;
		*p++ = FAC_Activate;	/* aktiviere SPV (default) */
		*p++ = pc->para.setup.si1;	/* 0 for all Services */
		*p++ = pc->para.setup.si2;	/* 0 for all Services */
	}
	eaz = pc->para.setup.eazmsn;
	if (*eaz) {
		*p++ = WE0_origAddr;
		*p++ = strlen(eaz) + 1;
		/* Classify as AnyPref. */
		*p++ = 0x81;	/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
		while (*eaz)
			*p++ = *eaz++ & 0x7f;
	}
	*p++ = WE0_destAddr;
	*p++ = strlen(teln) + 1;
	/* Classify as AnyPref. */
	*p++ = 0x81;		/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
	while (*teln)
		*p++ = *teln++ & 0x7f;

	*p++ = WE_Shift_F6;
	/* Codesatz 6 fuer Service */
	*p++ = WE6_serviceInd;
	*p++ = 2;		/* len=2 info,info2 */
	*p++ = pc->para.setup.si1;
	*p++ = pc->para.setup.si2;

	l = p - tmp;
	if (!(skb = l3_alloc_skb(l)))
		return;
	memcpy(skb_put(skb, l), tmp, l);
	L3DelTimer(&pc->timer);
	L3AddTimer(&pc->timer, T303, CC_T303);
	newl3state(pc, 1);
	l3_msg(pc->st, DL_DATA | REQUEST, skb);
}
Exemplo n.º 8
0
static void
l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
{
	struct sk_buff *skb;
	u_char tmp[128];
	u_char *p = tmp;
	u_char *teln;
	u_char *eaz;
	u_char channel = 0;
	int l;

	MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1);
	teln = pc->para.setup.phone;
	pc->para.spv = 0;
	if (!isdigit(*teln)) {
		switch (0x5f & *teln) {
		case 'S':
			pc->para.spv = 1;
			break;
		case 'C':
			channel = 0x08;
		case 'P':
			channel |= 0x80;
			teln++;
			if (*teln == '1')
				channel |= 0x01;
			else
				channel |= 0x02;
			break;
		default:
			if (pc->st->l3.debug & L3_DEB_WARN)
				l3_debug(pc->st, "Wrong MSN Code");
			break;
		}
		teln++;
	}
	if (channel) {
		*p++ = 0x18;	
		*p++ = 1;
		*p++ = channel;
	}
	if (pc->para.spv) {	
		
		*p++ = WE0_netSpecFac;
		*p++ = 4;	
		*p++ = 0;
		*p++ = FAC_SPV;	
		*p++ = pc->para.setup.si1;	
		*p++ = pc->para.setup.si2;	
		*p++ = WE0_netSpecFac;
		*p++ = 4;	
		*p++ = 0;
		*p++ = FAC_Activate;	
		*p++ = pc->para.setup.si1;	
		*p++ = pc->para.setup.si2;	
	}
	eaz = pc->para.setup.eazmsn;
	if (*eaz) {
		*p++ = WE0_origAddr;
		*p++ = strlen(eaz) + 1;
		
		*p++ = 0x81;	
		while (*eaz)
			*p++ = *eaz++ & 0x7f;
	}
	*p++ = WE0_destAddr;
	*p++ = strlen(teln) + 1;
	
	*p++ = 0x81;		
	while (*teln)
		*p++ = *teln++ & 0x7f;

	*p++ = WE_Shift_F6;
	
	*p++ = WE6_serviceInd;
	*p++ = 2;		
	*p++ = pc->para.setup.si1;
	*p++ = pc->para.setup.si2;

	l = p - tmp;
	if (!(skb = l3_alloc_skb(l)))
		return;
	memcpy(skb_put(skb, l), tmp, l);
	L3DelTimer(&pc->timer);
	L3AddTimer(&pc->timer, T303, CC_T303);
	newl3state(pc, 1);
	l3_msg(pc->st, DL_DATA | REQUEST, skb);
}