⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l3dss1.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidl3dss1_t313(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.cause = 0xE6;	l3dss1_disconnect_req(pc, pr, NULL);	pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);}static voidl3dss1_t308_1(struct l3_process *pc, u_char pr, void *arg){	newl3state(pc, 19);	L3DelTimer(&pc->timer);	l3dss1_message(pc, MT_RELEASE);	L3AddTimer(&pc->timer, T308, CC_T308_2);}static voidl3dss1_t308_2(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);	release_l3_process(pc);}static voidl3dss1_t318(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.cause = 0x66;	/* Timer expiry */	pc->para.loc = 0;	/* local */	pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);	newl3state(pc, 19);	l3dss1_message(pc, MT_RELEASE);	L3AddTimer(&pc->timer, T308, CC_T308_1);}static voidl3dss1_t319(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.cause = 0x66;	/* Timer expiry */	pc->para.loc = 0;	/* local */	pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);	newl3state(pc, 10);}static voidl3dss1_restart(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->st->l3.l3l4(pc->st, CC_DLRL | INDICATION, pc);	release_l3_process(pc);}static voidl3dss1_status(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	char tmp[64], *t;	int l;	struct sk_buff *skb = arg;	int cause, callState;	cause = callState = -1;	p = skb->data;	t = tmp;	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {		p++;		l = *p++;		t += sprintf(t, "Status CR %x Cause:", pc->callref);		while (l--) {			cause = *p;			t += sprintf(t, " %2x", *p++);		}	} else		sprintf(t, "Status CR %x no Cause", pc->callref);	l3_debug(pc->st, tmp);	p = skb->data;	t = tmp;	t += sprintf(t, "Status state %x ", pc->state);	if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {		p++;		if (1 == *p++) {			callState = *p;			t += sprintf(t, "peer state %x", *p);		} else			t += sprintf(t, "peer state len error");	} else		sprintf(t, "no peer state");	l3_debug(pc->st, tmp);	if (((cause & 0x7f) == 0x6f) && (callState == 0)) {		/* ETS 300-104 7.6.1, 8.6.1, 10.6.1...		 * if received MT_STATUS with cause == 0x6f and call		 * state == 0, then we must set down layer 3		 */		l3dss1_release_ind(pc, pr, arg);	} else		dev_kfree_skb(skb, FREE_READ);}static voidl3dss1_facility(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	p = skb->data;	if ((p = findie(p, skb->len, IE_FACILITY, 0))) {#if HISAX_DE_AOC		l3dss1_parse_facility(pc, p);#else		p = NULL;#endif	}}static voidl3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[32];	u_char *p = tmp;	u_char i, l;	u_char *msg = pc->chan->setup.phone;	MsgHead(p, pc->callref, MT_SUSPEND);	*p++ = IE_CALLID;	l = *msg++;	if (l && (l <= 10)) {	/* Max length 10 octets */		*p++ = l;		for (i = 0; i < l; i++)			*p++ = *msg++;	} else {		l3_debug(pc->st, "SUS wrong CALLID len %d", l);		return;	}	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);	newl3state(pc, 15);	L3AddTimer(&pc->timer, T319, CC_T319);}static voidl3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	L3DelTimer(&pc->timer);	newl3state(pc, 0);	dev_kfree_skb(skb, FREE_READ);	pc->para.cause = -1;	pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc);	release_l3_process(pc);}static voidl3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	int cause = -1;	L3DelTimer(&pc->timer);	p = skb->data;	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {		p++;		if (*p++ == 2)			pc->para.loc = *p++;		cause = *p & 0x7f;	}	dev_kfree_skb(skb, FREE_READ);	pc->para.cause = cause;	pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);	newl3state(pc, 10);}static voidl3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[32];	u_char *p = tmp;	u_char i, l;	u_char *msg = pc->para.setup.phone;	MsgHead(p, pc->callref, MT_RESUME);	*p++ = IE_CALLID;	l = *msg++;	if (l && (l <= 10)) {	/* Max length 10 octets */		*p++ = l;		for (i = 0; i < l; i++)			*p++ = *msg++;	} else {		l3_debug(pc->st, "RES wrong CALLID len %d", l);		return;	}	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);	newl3state(pc, 17);	L3AddTimer(&pc->timer, T319, CC_T319);}static voidl3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	L3DelTimer(&pc->timer);	p = skb->data;	if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {		pc->para.bchannel = p[2] & 0x3;		if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN))			l3_debug(pc->st, "resume ack without bchannel");	} else if (pc->debug & L3_DEB_WARN)		l3_debug(pc->st, "resume ack without bchannel");	dev_kfree_skb(skb, FREE_READ);	pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc);	newl3state(pc, 10);}static voidl3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	int cause = -1;	L3DelTimer(&pc->timer);	p = skb->data;	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {		p++;		if (*p++ == 2)			pc->para.loc = *p++;		cause = *p & 0x7f;	}	dev_kfree_skb(skb, FREE_READ);	pc->para.cause = cause;	newl3state(pc, 0);	pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);	release_l3_process(pc);}static voidl3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg){	u_char tmp[32];	u_char *p;	u_char ri, ch = 0, chan = 0;	int l;	struct sk_buff *skb = arg;	struct l3_process *up;	newl3state(pc, 2);	L3DelTimer(&pc->timer);	p = skb->data;	if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) {		ri = p[2];		l3_debug(pc->st, "Restart %x", ri);	} else {		l3_debug(pc->st, "Restart without restart IE");		ri = 0x86;	}	p = skb->data;	if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {		chan = p[2] & 3;		ch = p[2];		if (pc->st->l3.debug)			l3_debug(pc->st, "Restart for channel %d", chan);	}	dev_kfree_skb(skb, FREE_READ);	newl3state(pc, 2);	up = pc->st->l3.proc;	while (up) {		if ((ri & 7) == 7)			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);		else if (up->para.bchannel == chan)			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);		up = up->next;	}	p = tmp;	MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE);	if (chan) {		*p++ = IE_CHANNEL_ID;		*p++ = 1;		*p++ = ch | 0x80;	}	*p++ = 0x79;		/* RESTART Ind */	*p++ = 1;	*p++ = ri;	l = p - tmp;	if (!(skb = l3_alloc_skb(l)))		return;	memcpy(skb_put(skb, l), tmp, l);	newl3state(pc, 0);	l3_msg(pc->st, DL_DATA | REQUEST, skb);}/* *INDENT-OFF* */static struct stateentry downstatelist[] ={	{SBIT(0),	 CC_SETUP | REQUEST, l3dss1_setup_req},	{SBIT(0),	 CC_RESUME | REQUEST, l3dss1_resume_req},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(10),	 CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},	{SBIT(12),	 CC_RELEASE | REQUEST, l3dss1_release_req},	{ALL_STATES,	 CC_DLRL | REQUEST, l3dss1_reset},	{ALL_STATES,	 CC_RESTART | REQUEST, l3dss1_restart},	{SBIT(6),	 CC_IGNORE | REQUEST, l3dss1_reset},	{SBIT(6),	 CC_REJECT | REQUEST, l3dss1_reject_req},	{SBIT(6),	 CC_ALERTING | REQUEST, l3dss1_alert_req},	{SBIT(6) | SBIT(7),	 CC_SETUP | RESPONSE, l3dss1_setup_rsp},	{SBIT(10),	 CC_SUSPEND | REQUEST, l3dss1_suspend_req},	{SBIT(1),	 CC_T303, l3dss1_t303},	{SBIT(2),	 CC_T304, l3dss1_t304},	{SBIT(3),	 CC_T310, l3dss1_t310},	{SBIT(8),	 CC_T313, l3dss1_t313},	{SBIT(11),	 CC_T305, l3dss1_t305},	{SBIT(15),	 CC_T319, l3dss1_t319},	{SBIT(17),	 CC_T318, l3dss1_t318},	{SBIT(19),	 CC_T308_1, l3dss1_t308_1},	{SBIT(19),	 CC_T308_2, l3dss1_t308_2},};#define DOWNSLLEN \	(sizeof(downstatelist) / sizeof(struct stateentry))static struct stateentry datastatelist[] ={	{ALL_STATES,	 MT_STATUS_ENQUIRY, l3dss1_status_enq},	{ALL_STATES,	 MT_FACILITY, l3dss1_facility},	{SBIT(19),	 MT_STATUS, l3dss1_release_ind},	{ALL_STATES,	 MT_STATUS, l3dss1_status},	{SBIT(0) | SBIT(6),	 MT_SETUP, l3dss1_setup},	{SBIT(1) | SBIT(2),	 MT_CALL_PROCEEDING, l3dss1_call_proc},	{SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),	 MT_CALL_PROCEEDING, l3dss1_status_req},	{SBIT(1),	 MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack},	{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),	 MT_SETUP_ACKNOWLEDGE, l3dss1_status_req},	{SBIT(1) | SBIT(2) | SBIT(3),	 MT_ALERTING, l3dss1_alerting},	{SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),	 MT_ALERTING, l3dss1_status_req},	{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),	 MT_RELEASE_COMPLETE, l3dss1_release_cmpl},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |	 SBIT(11) | SBIT(12) | SBIT(15) /* | SBIT(17) | SBIT(19)*/,	 MT_RELEASE, l3dss1_release},	{SBIT(19),  MT_RELEASE, l3dss1_release_ind},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | SBIT(15),	 MT_DISCONNECT, l3dss1_disconnect},	{SBIT(11),	 MT_DISCONNECT, l3dss1_release_req},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),	 MT_CONNECT, l3dss1_connect},	{SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),	 MT_CONNECT, l3dss1_status_req},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(11) | SBIT(19),	 MT_CONNECT_ACKNOWLEDGE, l3dss1_status_req},	{SBIT(8),	 MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack},	{SBIT(15),	 MT_SUSPEND_ACKNOWLEDGE, l3dss1_suspend_ack},	{SBIT(15),	 MT_SUSPEND_REJECT, l3dss1_suspend_rej},	{SBIT(17),	 MT_RESUME_ACKNOWLEDGE, l3dss1_resume_ack},	{SBIT(17),	 MT_RESUME_REJECT, l3dss1_resume_rej},	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(19),	 MT_INVALID, l3dss1_status_req},};#define DATASLLEN \	(sizeof(datastatelist) / sizeof(struct stateentry))static struct stateentry globalmes_list[] ={	{ALL_STATES,	 MT_STATUS, l3dss1_status},	{SBIT(0),	 MT_RESTART, l3dss1_global_restart},/*	{SBIT(1),	 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},*/};#define GLOBALM_LEN \	(sizeof(globalmes_list) / sizeof(struct stateentry))/* *INDENT-ON* */static voidglobal_handler(struct PStack *st, int mt, struct sk_buff *skb){	int i;	struct l3_process *proc = st->l3.global;	for (i = 0; i < GLOBALM_LEN; i++)		if ((mt == globalmes_list[i].primitive) &&		    ((1 << proc->state) & globalmes_list[i].state))			break;	if (i == GLOBALM_LEN) {		dev_kfree_skb(skb, FREE_READ);		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1 global state %d mt %x unhandled",				proc->state, mt);		}		return;	} else {		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1 global %d mt %x",				proc->state, mt);		}		globalmes_list[i].rout(proc, mt, skb);	}}static voiddss1up(struct PStack *st, int pr, void *arg){	int i, mt, cr, cause, callState;	char *ptr;	struct sk_buff *skb = arg;	struct l3_process *proc;	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->data[0] != PROTO_DIS_EURO) {		if (st->l3.debug & L3_DEB_PROTERR) {			l3_debug(st, "dss1up%sunexpected discriminator %x message len %d",				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",				 skb->data[0], skb->len);		}		dev_kfree_skb(skb, FREE_READ);		return;	}	cr = getcallref(skb->data);	mt = skb->data[skb->data[1] + 2];	if (!cr) {		/* Global CallRef */		global_handler(st, mt, skb);		return;	} else if (cr == -1) {	/* Dummy Callref */		dev_kfree_skb(skb, FREE_READ);		return;	} else if (!(proc = getl3proc(st, cr))) {		/* No transaction process exist, that means no call with		 * this callreference is active		 */		if (mt == MT_SETUP) {			/* Setup creates a new transaction process */			if (!(proc = new_l3_process(st, cr))) {				/* May be to answer with RELEASE_COMPLETE and				 * CAUSE 0x2f "Resource unavailable", but this				 * need a new_l3_process too ... arghh				 */				dev_kfree_skb(skb, FREE_READ);				return;			}		} else if (mt == MT_STATUS) {			cause = 0;			if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {				ptr++;				if (*ptr++ == 2)					ptr++;				cause = *ptr & 0x7f;			}			callState = 0;			if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {				ptr++;				if (*ptr++ == 2)					ptr++;				callState = *ptr;			}			if (callState == 0) {				/* ETS 300-104 part 2.4.1				 * if setup has not been made and a message type				 * MT_STATUS is received with call state == 0,				 * we must send nothing				 */				dev_kfree_skb(skb, FREE_READ);				return;			} else {				/* ETS 300-104 part 2.4.2				 * if setup has not been made and a message type				 * MT_STATUS is received with call state != 0,				 * we must send MT_RELEASE_COMPLETE cause 101				 */				dev_kfree_skb(skb, FREE_READ);				if ((proc = new_l3_process(st, cr))) {					proc->para.cause = 0x65;	/* 101 */					l3dss1_msg_without_setup(proc, 0, NULL);				}				return;			}		} else if (mt == MT_RELEASE_COMPLETE) {			dev_kfree_skb(skb, FREE_READ);			return;		} else {			/* ETS 300-104 part 2			 * if setup has not been made and a message type			 * (except MT_SETUP and RELEASE_COMPLETE) is received,			 * we must send MT_RELEASE_COMPLETE cause 81 */			dev_kfree_skb(skb, FREE_READ);			if ((proc = new_l3_process(st, cr))) {				proc->para.cause = 0x51;	/* 81 */				l3dss1_msg_without_setup(proc, 0, NULL);			}			return;		}	} else if (!l3dss1_check_messagetype_validity(mt)) {		/* ETS 300-104 7.4.2, 8.4.2, 10.3.2, 11.4.2, 12.4.2, 13.4.2,		 * 14.4.2...		 * if setup has been made and invalid message type is received,		 * we must send MT_STATUS cause 0x62		 */		mt = MT_INVALID;	/* sorry, not clean, but do the right thing ;-) */	}	for (i = 0; i < DATASLLEN; i++)		if ((mt == datastatelist[i].primitive) &&		    ((1 << proc->state) & datastatelist[i].state))			break;	if (i == DATASLLEN) {		dev_kfree_skb(skb, FREE_READ);		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1up%sstate %d mt %x unhandled",				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",				proc->state, mt);		}		return;	} else {		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1up%sstate %d mt %x",				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",				proc->state, mt);		}		datastatelist[i].rout(proc, pr, skb);	}}static voiddss1down(struct PStack *st, int pr, void *arg){	int i, cr;	struct l3_process *proc;	struct Channel *chan;	if (((DL_ESTABLISH | REQUEST) == pr) || ((DL_RELEASE | REQUEST) == pr)) {		l3_msg(st, pr, NULL);		return;	} else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {		chan = arg;		cr = newcallref();		cr |= 0x80;		if ((proc = new_l3_process(st, cr))) {			proc->chan = chan;			chan->proc = proc;			proc->para.setup = chan->setup;			proc->callref = cr;		}	} else {		proc = arg;	}	if (!proc) {		printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr);		return;	}	for (i = 0; i < DOWNSLLEN; i++)		if ((pr == downstatelist[i].primitive) &&		    ((1 << proc->state) & downstatelist[i].state))			break;	if (i == DOWNSLLEN) {		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1down state %d prim %d unhandled",				proc->state, pr);		}	} else {		if (st->l3.debug & L3_DEB_STATE) {			l3_debug(st, "dss1down state %d prim %d",				proc->state, pr);		}		downstatelist[i].rout(proc, pr, arg);	}}voidsetstack_dss1(struct PStack *st){	char tmp[64];	st->lli.l4l3 = dss1down;	st->l2.l2l3 = dss1up;	st->l3.N303 = 1;	if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {		printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");	} else {		st->l3.global->state = 0;		st->l3.global->callref = 0;		st->l3.global->next = NULL;		st->l3.global->debug = L3_DEB_WARN;		st->l3.global->st = st;		st->l3.global->N303 = 1;		L3InitTimer(st->l3.global, &st->l3.global->timer);	}	strcpy(tmp, dss1_revision);	printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -