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

📄 l3ni1.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		case 88:	// 1200/75 bit/s			si2 += 1;			break;		case 87:	// 75/1200 bit/s			si2 += 2;			break;		case 67:	// 2400 bit/s			si2 += 3;			break;		case 69:	// 4800 bit/s			si2 += 4;			break;		case 72:	// 9600 bit/s			si2 += 5;			break;		case 73:	// 14400 bit/s			si2 += 6;			break;		case 75:	// 19200 bit/s			si2 += 7;			break;	}	info = p[7] & 0x7f;	if ((info & 16) && (!(info & 8)))	// 7 data bits		si2 += 32;	// else 8 data bits	if ((info & 96) == 96)	// 2 stop bits		si2 += 16;	// else 1 stop bit	if ((info & 2) && (!(info & 1)))	// even parity		si2 += 8;	// else no parity	return si2;}static u_charDecodeSyncParams(u_char si2, u_char info){	info &= 0x7f;	switch (info) {		case 40:	// bit/s negotiation failed  ai := 165 not 175!			return si2 + 15;		case 15:	// 56000 bit/s failed, ai := 0 not 169 !			return si2 + 9;		case 14:	// 48000 bit/s			return si2 + 8;		case 11:	// 19200 bit/s			return si2 + 7;		case 9:	// 14400 bit/s			return si2 + 6;		case 8:	// 9600  bit/s			return si2 + 5;		case 5:	// 4800  bit/s			return si2 + 4;		case 3:	// 2400  bit/s			return si2 + 3;		case 23:	// 75/1200 bit/s			return si2 + 2;		case 24:	// 1200/75 bit/s			return si2 + 1;		default:	// 1200 bit/s			return si2;	}}static u_charDecodeSI2(struct sk_buff *skb){	u_char *p;		//, *pend=skb->data + skb->len;	if ((p = findie(skb->data, skb->len, 0x7c, 0))) {		switch (p[4] & 0x0f) {			case 0x01:				if (p[1] == 0x04)	// sync. Bitratenadaption					return DecodeSyncParams(160, p[5]);	// V.110/X.30				else if (p[1] == 0x06)	// async. Bitratenadaption					return DecodeASyncParams(192, p);	// V.110/X.30				break;			case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption				if (p[1] > 3) 					return DecodeSyncParams(176, p[5]);	// V.120				break;		}	}	return 0;}#endifstatic voidl3ni1_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 *sub;	u_char *sp;	int l;	MsgHead(p, pc->callref, MT_SETUP);	teln = pc->para.setup.phone;	*p++ = 0xa1;		/* complete indicator */	/*	 * Set Bearer Capability, Map info from 1TR6-convention to NI1	 */	switch (pc->para.setup.si1) {	case 1:	                  /* Telephony                                */		*p++ = IE_BEARER;		*p++ = 0x3;	  /* Length                                   */		*p++ = 0x90;	  /* 3.1khz Audio      			      */		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */		*p++ = 0xa2;	  /* u-Law Audio                              */		break;	case 5:	                  /* Datatransmission 64k, BTX                */	case 7:	                  /* Datatransmission 64k                     */	default:		*p++ = IE_BEARER;		*p++ = 0x2;	  /* Length                                   */		*p++ = 0x88;	  /* Coding Std. CCITT, unrestr. dig. Inform. */		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */		break;	}	sub = NULL;	sp = teln;	while (*sp) {		if ('.' == *sp) {			sub = sp;			*sp = 0;		} else			sp++;	}		*p++ = IE_KEYPAD;	*p++ = strlen(teln);	while (*teln)		*p++ = (*teln++) & 0x7F;	if (sub)		*sub++ = '.';	#if EXT_BEARER_CAPS	if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {	// sync. Bitratenadaption, V.110/X.30		*p++ = IE_LLC;		*p++ = 0x04;		*p++ = 0x88;		*p++ = 0x90;		*p++ = 0x21;		*p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);	} else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {	// sync. Bitratenadaption, V.120		*p++ = IE_LLC;		*p++ = 0x05;		*p++ = 0x88;		*p++ = 0x90;		*p++ = 0x28;		*p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);		*p++ = 0x82;	} else if (pc->para.setup.si2 >= 192) {		// async. Bitratenadaption, V.110/X.30		*p++ = IE_LLC;		*p++ = 0x06;		*p++ = 0x88;		*p++ = 0x90;		*p++ = 0x21;		p = EncodeASyncParams(p, pc->para.setup.si2 - 192);	} else {	  switch (pc->para.setup.si1) {		case 1:	                /* Telephony                                */			*p++ = IE_LLC;			*p++ = 0x3;	/* Length                                   */			*p++ = 0x90;	/* Coding Std. CCITT, 3.1 kHz audio         */			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */			*p++ = 0xa2;	/* u-Law Audio                              */			break;		case 5:	                /* Datatransmission 64k, BTX                */		case 7:	                /* Datatransmission 64k                     */		default:			*p++ = IE_LLC;			*p++ = 0x2;	/* Length                                   */			*p++ = 0x88;	/* Coding Std. CCITT, unrestr. dig. Inform. */			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */			break;	  }	}#endif	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);}static voidl3ni1_call_proc(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int id, ret;	if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {		if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {			if (pc->debug & L3_DEB_WARN)				l3_debug(pc->st, "setup answer with wrong chid %x", id);			pc->para.cause = 100;			l3ni1_status_send(pc, pr, NULL);			return;		}		pc->para.bchannel = id;	} else if (1 == pc->state) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);		if (id == -1)			pc->para.cause = 96;		else			pc->para.cause = 100;		l3ni1_status_send(pc, pr, NULL);		return;	}	/* Now we are on none mandatory IEs */	ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING);	if (ERR_IE_COMPREHENSION == ret) {		l3ni1_std_ie_err(pc, ret);		return;	}	L3DelTimer(&pc->timer);	newl3state(pc, 3);	L3AddTimer(&pc->timer, T310, CC_T310);	if (ret) /* STATUS for none mandatory IE errors after actions are taken */		l3ni1_std_ie_err(pc, ret);	pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);}static voidl3ni1_setup_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int id, ret;	if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {		if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {			if (pc->debug & L3_DEB_WARN)				l3_debug(pc->st, "setup answer with wrong chid %x", id);			pc->para.cause = 100;			l3ni1_status_send(pc, pr, NULL);			return;		}		pc->para.bchannel = id;	} else {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);		if (id == -1)			pc->para.cause = 96;		else			pc->para.cause = 100;		l3ni1_status_send(pc, pr, NULL);		return;	}	/* Now we are on none mandatory IEs */	ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE);	if (ERR_IE_COMPREHENSION == ret) {		l3ni1_std_ie_err(pc, ret);		return;	}	L3DelTimer(&pc->timer);	newl3state(pc, 2);	L3AddTimer(&pc->timer, T304, CC_T304);	if (ret) /* STATUS for none mandatory IE errors after actions are taken */		l3ni1_std_ie_err(pc, ret);	pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);}static voidl3ni1_disconnect(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	u_char *p;	int ret;	u_char cause = 0;	StopAllL3Timer(pc);	if ((ret = l3ni1_get_cause(pc, skb))) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "DISC get_cause ret(%d)", ret);		if (ret < 0)			cause = 96;		else if (ret > 0)			cause = 100;	} 	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))		l3ni1_parse_facility(pc->st, pc, pc->callref, p);	ret = check_infoelements(pc, skb, ie_DISCONNECT);	if (ERR_IE_COMPREHENSION == ret)		cause = 96;	else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret))		cause = 99;	ret = pc->state;	newl3state(pc, 12);	if (cause)		newl3state(pc, 19);       	if (11 != ret)		pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);       	else if (!cause)		   l3ni1_release_req(pc, pr, NULL);	if (cause) {		l3ni1_message_cause(pc, MT_RELEASE, cause);		L3AddTimer(&pc->timer, T308, CC_T308_1);	}}static voidl3ni1_connect(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	ret = check_infoelements(pc, skb, ie_CONNECT);	if (ERR_IE_COMPREHENSION == ret) {		l3ni1_std_ie_err(pc, ret);		return;	}	L3DelTimer(&pc->timer);	/* T310 */	newl3state(pc, 10);	pc->para.chargeinfo = 0;	/* here should inserted COLP handling KKe */	if (ret)		l3ni1_std_ie_err(pc, ret);	pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);}static voidl3ni1_alerting(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	ret = check_infoelements(pc, skb, ie_ALERTING);	if (ERR_IE_COMPREHENSION == ret) {		l3ni1_std_ie_err(pc, ret);		return;	}	L3DelTimer(&pc->timer);	/* T304 */	newl3state(pc, 4);	if (ret)		l3ni1_std_ie_err(pc, ret);	pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);}static voidl3ni1_setup(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	int bcfound = 0;	char tmp[80];	struct sk_buff *skb = arg;	int id;	int err = 0;	/*	 * Bearer Capabilities	 */	p = skb->data;	/* only the first occurence 'll be detected ! */	if ((p = findie(p, skb->len, 0x04, 0))) {		if ((p[1] < 2) || (p[1] > 11))			err = 1;		else {			pc->para.setup.si2 = 0;			switch (p[2] & 0x7f) {				case 0x00: /* Speech */				case 0x10: /* 3.1 Khz audio */					pc->para.setup.si1 = 1;					break;				case 0x08: /* Unrestricted digital information */					pc->para.setup.si1 = 7;/* JIM, 05.11.97 I wanna set service indicator 2 */#if EXT_BEARER_CAPS					pc->para.setup.si2 = DecodeSI2(skb);#endif					break;				case 0x09: /* Restricted digital information */					pc->para.setup.si1 = 2;					break;				case 0x11:					/* Unrestr. digital information  with 					 * tones/announcements ( or 7 kHz audio					 */					pc->para.setup.si1 = 3;					break;				case 0x18: /* Video */					pc->para.setup.si1 = 4;					break;				default:					err = 2;					break;			}			switch (p[3] & 0x7f) {				case 0x40: /* packed mode */					pc->para.setup.si1 = 8;					break;				case 0x10: /* 64 kbit */				case 0x11: /* 2*64 kbit */				case 0x13: /* 384 kbit */				case 0x15: /* 1536 kbit */				case 0x17: /* 1920 kbit */					pc->para.moderate = p[3] & 0x7f;					break;				default:					err = 3;					break;			}		}		if (pc->debug & L3_DEB_SI)			l3_debug(pc->st, "SI=%d, AI=%d",				pc->para.setup.si1, pc->para.setup.si2);		if (err) {			if (pc->debug & L3_DEB_WARN)				l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)",					p[1], p[2], p[3]);			pc->para.cause = 100;			l3ni1_msg_without_setup(pc, pr, NULL);			return;		}	} else {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "setup without bearer capabilities");		/* ETS 300-104 1.3.3 */		pc->para.cause = 96;		l3ni1_msg_without_setup(pc, pr, NULL);		return;	}	/*	 * Channel Identification	 */	if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) {		if ((pc->para.bchannel = id)) {			if ((3 == id) && (0x10 == pc->para.moderate)) {				if (pc->debug & L3_DEB_WARN)					l3_debug(pc->st, "setup with wrong chid %x",						id);				pc->para.cause = 100;				l3ni1_msg_without_setup(pc, pr, NULL);				return;			}			bcfound++;		} else                    { if (pc->debug & L3_DEB_WARN)			 l3_debug(pc->st, "setup without bchannel, call waiting");                     bcfound++;                   } 	} else {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "setup with wrong chid ret %d", id);		if (id == -1)			pc->para.cause = 96;		else			pc->para.cause = 100;		l3ni1_msg_without_setup(pc, pr, NULL);		return;	}	/* Now we are on none mandatory IEs */	err = check_infoelements(pc, skb, ie_SETUP);	if (ERR_IE_COMPREHENSION == err) {		pc->para.cause = 96;		l3ni1_msg_without_setup(pc, pr, NULL);		return;	}	p = skb->data;	if ((p = findie(p, skb->len, 0x70, 0)))		iecpy(pc->para.setup.eazmsn, p, 1);	else		pc->para.setup.eazmsn[0] = 0;	p = skb->data;	if ((p = findie(p, skb->len, 0x71, 0))) {		/* Called party subaddress */		if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {			tmp[0] = '.';			iecpy(&tmp[1], p, 2);			strcat(pc->para.setup.eazmsn, tmp);		} else if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "wrong called subaddress");	}	p = skb->data;	if ((p = findie(p, skb->len, 0x6c, 0))) {		pc->para.setup.plan = p[2];		if (p[2] & 0x80) {

⌨️ 快捷键说明

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