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

📄 l3dss1.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int l;	MsgHead(p, pc->callref, mt);	*p++ = IE_CAUSE;	*p++ = 0x2;	*p++ = 0x80;	*p++ = cause | 0x80;	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);}static voidl3dss1_status_send(struct l3_process *pc, u_char pr, void *arg){	u_char tmp[16];	u_char *p = tmp;	int l;	struct sk_buff *skb;	MsgHead(p, pc->callref, MT_STATUS);	*p++ = IE_CAUSE;	*p++ = 0x2;	*p++ = 0x80;	*p++ = pc->para.cause | 0x80;	*p++ = IE_CALL_STATE;	*p++ = 0x1;	*p++ = pc->state & 0x3f;	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);}static voidl3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg){	/* This routine is called if here was no SETUP made (checks in dss1up and in	 * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code	 * MT_STATUS_ENQUIRE in the NULL state is handled too	 */	u_char tmp[16];	u_char *p = tmp;	int l;	struct sk_buff *skb;	switch (pc->para.cause) {		case 81:	/* invalid callreference */		case 88:	/* incomp destination */		case 96:	/* mandory IE missing */		case 100:       /* invalid IE contents */		case 101:	/* incompatible Callstate */			MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);			*p++ = IE_CAUSE;			*p++ = 0x2;			*p++ = 0x80;			*p++ = pc->para.cause | 0x80;			break;		default:			printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n",				pc->para.cause);			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);	dss1_release_l3_process(pc);}static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,		IE_USER_USER, -1};static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, 		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,		IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY,		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL,		IE_CALLED_PN, -1};static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1};static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |		IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,		IE_SIGNAL, IE_USER_USER, -1};/* a RELEASE_COMPLETE with errors don't require special actions static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};*/static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY,		IE_DISPLAY, -1};static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER  | IE_MANDATORY,		IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY, IE_PROGRESS,		IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,		IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,		IE_LLC, IE_HLC, IE_USER_USER, -1};static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE |		IE_MANDATORY, IE_DISPLAY, -1};static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1};static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1};static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};/* not used  * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY, *		IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1}; * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND | *		IE_MANDATORY, -1}; */static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1};static int comp_required[] = {1,2,3,5,6,7,9,10,11,14,15,-1};static int l3_valid_states[] = {0,1,2,3,4,6,7,8,9,10,11,12,15,17,19,25,-1};struct ie_len {	int ie;	int len;};staticstruct ie_len max_ie_len[] = {	{IE_SEGMENT, 4},	{IE_BEARER, 12},	{IE_CAUSE, 32},	{IE_CALL_ID, 10},	{IE_CALL_STATE, 3},	{IE_CHANNEL_ID,	34},	{IE_FACILITY, 255},	{IE_PROGRESS, 4},	{IE_NET_FAC, 255},	{IE_NOTIFY, 3},	{IE_DISPLAY, 82},	{IE_DATE, 8},	{IE_KEYPAD, 34},	{IE_SIGNAL, 3},	{IE_INFORATE, 6},	{IE_E2E_TDELAY, 11},	{IE_TDELAY_SEL, 5},	{IE_PACK_BINPARA, 3},	{IE_PACK_WINSIZE, 4},	{IE_PACK_SIZE, 4},	{IE_CUG, 7},	{IE_REV_CHARGE, 3},	{IE_CALLING_PN, 24},	{IE_CALLING_SUB, 23},	{IE_CALLED_PN, 24},	{IE_CALLED_SUB, 23},	{IE_REDIR_NR, 255},	{IE_TRANS_SEL, 255},	{IE_RESTART_IND, 3},	{IE_LLC, 18},	{IE_HLC, 5},	{IE_USER_USER, 131},	{-1,0},};static intgetmax_ie_len(u_char ie) {	int i = 0;	while (max_ie_len[i].ie != -1) {		if (max_ie_len[i].ie == ie)			return(max_ie_len[i].len);		i++;	}	return(255);}static intie_in_set(struct l3_process *pc, u_char ie, int *checklist) {	int ret = 1;	while (*checklist != -1) {		if ((*checklist & 0xff) == ie) {			if (ie & 0x80)				return(-ret);			else				return(ret);		}		ret++;		checklist++;	}	return(0);}static intcheck_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist){	int *cl = checklist;	u_char mt;	u_char *p, ie;	int l, newpos, oldpos;	int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;	u_char codeset = 0;	u_char old_codeset = 0;	u_char codelock = 1;		p = skb->data;	/* skip cr */	p++;	l = (*p++) & 0xf;	p += l;	mt = *p++;	oldpos = 0;	while ((p - skb->data) < skb->len) {		if ((*p & 0xf0) == 0x90) { /* shift codeset */			old_codeset = codeset;			codeset = *p & 7;			if (*p & 0x08)				codelock = 0;			else				codelock = 1;			if (pc->debug & L3_DEB_CHECK)				l3_debug(pc->st, "check IE shift%scodeset %d->%d",					codelock ? " locking ": " ", old_codeset, codeset);			p++;			continue;		}		if (!codeset) { /* only codeset 0 */			if ((newpos = ie_in_set(pc, *p, cl))) {				if (newpos > 0) {					if (newpos < oldpos)						err_seq++;					else						oldpos = newpos;				}			} else {				if (ie_in_set(pc, *p, comp_required))					err_compr++;				else					err_ureg++;			}		}		ie = *p++;		if (ie & 0x80) {			l = 1;		} else {			l = *p++;			p += l;			l += 2;		}		if (!codeset && (l > getmax_ie_len(ie)))			err_len++;		if (!codelock) {			if (pc->debug & L3_DEB_CHECK)				l3_debug(pc->st, "check IE shift back codeset %d->%d",					codeset, old_codeset);			codeset = old_codeset;			codelock = 1;		}	}	if (err_compr | err_ureg | err_len | err_seq) {		if (pc->debug & L3_DEB_CHECK)			l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",				mt, err_compr, err_ureg, err_len, err_seq);		if (err_compr)			return(ERR_IE_COMPREHENSION);		if (err_ureg)			return(ERR_IE_UNRECOGNIZED);		if (err_len)			return(ERR_IE_LENGTH);		if (err_seq)			return(ERR_IE_SEQUENCE);	} 	return(0);}/* verify if a message type exists and contain no IE error */static intl3dss1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg){	switch (mt) {		case MT_ALERTING:		case MT_CALL_PROCEEDING:		case MT_CONNECT:		case MT_CONNECT_ACKNOWLEDGE:		case MT_DISCONNECT:		case MT_INFORMATION:		case MT_FACILITY:		case MT_NOTIFY:		case MT_PROGRESS:		case MT_RELEASE:		case MT_RELEASE_COMPLETE:		case MT_SETUP:		case MT_SETUP_ACKNOWLEDGE:		case MT_RESUME_ACKNOWLEDGE:		case MT_RESUME_REJECT:		case MT_SUSPEND_ACKNOWLEDGE:		case MT_SUSPEND_REJECT:		case MT_USER_INFORMATION:		case MT_RESTART:		case MT_RESTART_ACKNOWLEDGE:		case MT_CONGESTION_CONTROL:		case MT_STATUS:		case MT_STATUS_ENQUIRY:			if (pc->debug & L3_DEB_CHECK)				l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt);			break;		case MT_RESUME: /* RESUME only in user->net */		case MT_SUSPEND: /* SUSPEND only in user->net */		default:			if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))				l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt);			pc->para.cause = 97;			l3dss1_status_send(pc, 0, NULL);			return(1);	}	return(0);}static voidl3dss1_std_ie_err(struct l3_process *pc, int ret) {	if (pc->debug & L3_DEB_CHECK)		l3_debug(pc->st, "check_infoelements ret %d", ret);	switch(ret) {		case 0: 			break;		case ERR_IE_COMPREHENSION:			pc->para.cause = 96;			l3dss1_status_send(pc, 0, NULL);			break;		case ERR_IE_UNRECOGNIZED:			pc->para.cause = 99;			l3dss1_status_send(pc, 0, NULL);			break;		case ERR_IE_LENGTH:			pc->para.cause = 100;			l3dss1_status_send(pc, 0, NULL);			break;		case ERR_IE_SEQUENCE:		default:			break;	}}static intl3dss1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) {	u_char *p;	p = skb->data;	if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {		p++;		if (*p != 1) { /* len for BRI = 1 */			if (pc->debug & L3_DEB_WARN)				l3_debug(pc->st, "wrong chid len %d", *p);			return (-2);		}		p++;		if (*p & 0x60) { /* only base rate interface */			if (pc->debug & L3_DEB_WARN)				l3_debug(pc->st, "wrong chid %x", *p);			return (-3);		}		return(*p & 0x3);	} else		return(-1);}static intl3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) {	u_char l, i=0;	u_char *p;	p = skb->data;	pc->para.cause = 31;	pc->para.loc = 0;	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {		p++;		l = *p++;		if (l>30)			return(1);		if (l) {			pc->para.loc = *p++;			l--;		} else {			return(2);		}		if (l && !(pc->para.loc & 0x80)) {			l--;			p++; /* skip recommendation */		}		if (l) {			pc->para.cause = *p++;			l--;			if (!(pc->para.cause & 0x80))				return(3);		} else			return(4);		while (l && (i<6)) {			pc->para.diag[i++] = *p++;			l--;		}	} else		return(-1);	return(0);}static voidl3dss1_msg_with_uus(struct l3_process *pc, u_char cmd){	struct sk_buff *skb;	u_char tmp[16+40];	u_char *p = tmp;	int l;	MsgHead(p, pc->callref, cmd);        if (pc->prot.dss1.uus1_data[0])	 { *p++ = IE_USER_USER; /* UUS info element */           *p++ = strlen(pc->prot.dss1.uus1_data) + 1;           *p++ = 0x04; /* IA5 chars */           strcpy(p,pc->prot.dss1.uus1_data);           p += strlen(pc->prot.dss1.uus1_data);           pc->prot.dss1.uus1_data[0] = '\0';            } 	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);} /* l3dss1_msg_with_uus */static voidl3dss1_release_req(struct l3_process *pc, u_char pr, void *arg){	StopAllL3Timer(pc);	newl3state(pc, 19);	if (!pc->prot.dss1.uus1_data[0]) 		l3dss1_message(pc, MT_RELEASE);	else		l3dss1_msg_with_uus(pc, MT_RELEASE);	L3AddTimer(&pc->timer, T308, CC_T308_1);}static voidl3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	if ((ret = l3dss1_get_cause(pc, skb))>0) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "RELCMPL get_cause ret(%d)",ret);	} else if (ret < 0)		pc->para.cause = NO_CAUSE;	StopAllL3Timer(pc);	newl3state(pc, 0);	L3L4(pc->st, CC_RELEASE | CONFIRM, pc);	dss1_release_l3_process(pc);}#if EXT_BEARER_CAPSstatic u_char *EncodeASyncParams(u_char * p, u_char si2){				// 7c 06 88  90 21 42 00 bb	p[0] = 0;	p[1] = 0x40;		// Intermediate rate: 16 kbit/s jj 2000.02.19	p[2] = 0x80;	if (si2 & 32)		// 7 data bits		p[2] += 16;	else			// 8 data bits		p[2] += 24;	if (si2 & 16)		// 2 stop bits		p[2] += 96;	else			// 1 stop bit		p[2] += 32;	if (si2 & 8)		// even parity		p[2] += 2;	else			// no parity		p[2] += 3;	switch (si2 & 0x07) {		case 0:			p[0] = 66;	// 1200 bit/s			break;		case 1:			p[0] = 88;	// 1200/75 bit/s			break;		case 2:			p[0] = 87;	// 75/1200 bit/s			break;		case 3:			p[0] = 67;	// 2400 bit/s			break;		case 4:			p[0] = 69;	// 4800 bit/s			break;		case 5:			p[0] = 72;	// 9600 bit/s			break;		case 6:			p[0] = 73;	// 14400 bit/s			break;		case 7:			p[0] = 75;	// 19200 bit/s			break;

⌨️ 快捷键说明

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