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

📄 eicon_idi.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (InMask == 0) {			if (InBuf.Len >= InBuf.Size) {				Event = EVENT_EOD;				break;			}			if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {				chan->fax2.Dle = _DLE_;				InBuf.Next++;				InBuf.Len++;				if (InBuf.Len >= InBuf.Size) {					Event = EVENT_EOD;					break;				}			}			if (chan->fax2.Dle == _DLE_) {				chan->fax2.Dle = 0;				if (*InBuf.Next == _ETX_) {					Event = EVENT_EOP;					break;				} else				if (*InBuf.Next == _DLE_) {					/* do nothing */				} else {					eicon_log(ccard, 1,						"idi_err: Ch%d: unknown DLE escape %02x found\n",							chan->No, *InBuf.Next);					InBuf.Next++;					InBuf.Len++;					if (InBuf.Len >= InBuf.Size) {						Event = EVENT_EOD;						break;					}				}			}			InBuf.Len++;			InData = *InBuf.Next++;			InMask = (chan->fax->bor) ? 0x80 : 0x01;		}		while (InMask) {			LineData >>= 1;			LineDataLen++;			if (InData & InMask)				LineData |= 0x80000000;			if (chan->fax->bor)				InMask >>= 1;			else				InMask <<= 1;			if ((LineDataLen >= T4_EOL_BITSIZE) &&			   ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {				Event = EVENT_EOL;				if (LineDataLen > T4_EOL_BITSIZE) {					Byte = (__u8)						((LineData & ~T4_EOL_MASK_DWORD) >>						(32 - LineDataLen));					if (Byte == 0) {						if (! chan->fax2.NullByteExist) {							chan->fax2.NullBytesPos = LineBuf.Len;							chan->fax2.NullByteExist = 1;						}					} else {						chan->fax2.NullByteExist = 0;					}					if (LineBuf.Len < LineBuf.Size) {						*LineBuf.Next++  = Byte;						LineBuf.Len++;					}				}				LineDataLen = 0;				break;			}			if (LineDataLen >= T4_EOL_BITSIZE + 8) {				Byte = (__u8)					((LineData & ~T4_EOL_MASK_DWORD) >>					(32 - T4_EOL_BITSIZE - 8));				LineData &= T4_EOL_MASK_DWORD;				LineDataLen = T4_EOL_BITSIZE;				if (Byte == 0) {					if (! chan->fax2.NullByteExist) {						chan->fax2.NullBytesPos = LineBuf.Len;						chan->fax2.NullByteExist = 1;					}				} else {					chan->fax2.NullByteExist = 0;				}				if (LineBuf.Len < LineBuf.Size) {					*LineBuf.Next++  = Byte; 					LineBuf.Len++;				}			}		}		if (Event != EVENT_NONE)			break;	  }		if ((Event != EVENT_EOL) && (Event != EVENT_EOP))			break;		if ((Event == EVENT_EOP) && (LineDataLen > 0)) {			LineData >>= 32 - LineDataLen;			LineDataLen = 0;			while (LineData != 0) {				Byte = (__u8) LineData;				LineData >>= 8;				if (Byte == 0) {					if (! chan->fax2.NullByteExist) {						chan->fax2.NullBytesPos = LineBuf.Len;						chan->fax2.NullByteExist = 1;					}				} else {					chan->fax2.NullByteExist = 0;				}				if (LineBuf.Len < LineBuf.Size) {					*LineBuf.Next++  = Byte;					LineBuf.Len++;				}							}		}		if (chan->fax2.NullByteExist) {			if (chan->fax2.NullBytesPos == 0) {				LineBuf.Len = 0;			} else {				LineBuf.Len = chan->fax2.NullBytesPos + 1;			}		}		if (LineBuf.Len > 0) {			if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) {				ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);			}			if (LineBuf.Len <= 216) {				*OutBuf.Next++ = (__u8) LineBuf.Len;				OutBuf.Len++;			} else {				*OutBuf.Next++ = 0;				*((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len;				OutBuf.Len += 3;			}			memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);			OutBuf.Next += LineBuf.Len;			OutBuf.Len  += LineBuf.Len;		}		LineBuf.Len = 0;		LineBuf.Next = LineBuf.Data;		chan->fax2.NullByteExist = 0;		if (Event == EVENT_EOP)			break;		Event = EVENT_NONE;	}	if (Event == EVENT_EOP) {		chan->fax2.Eop = 1;		chan->fax2.PageCount++;		cmd.driver = ccard->myid;		cmd.command = ISDN_STAT_FAXIND;		cmd.arg = chan->No;		chan->fax->r_code = ISDN_TTY_FAX_EOP;		ccard->interface.statcallb(&cmd);	}	if (OutBuf.Len > 0) {		ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);	}	chan->fax2.LineLen = LineBuf.Len;	chan->fax2.LineData = LineData;	chan->fax2.LineDataLen = LineDataLen;#	undef EVENT_NONE#	undef EVENT_EOD#	undef EVENT_EOL#	undef EVENT_EOP	if (ret >= 0)	        dev_kfree_skb(skb);	if (ret == 0)		ret = 1;	return(ret);}voididi_fax_hangup(eicon_card *ccard, eicon_chan *chan){	isdn_ctrl cmd;	if (!chan->fax) {		eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");		return;	}	if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) &&	    (chan->fax->code == 0)) {		cmd.driver = ccard->myid;		cmd.command = ISDN_STAT_FAXIND;		cmd.arg = chan->No;		chan->fax->r_code = ISDN_TTY_FAX_PTS;		ccard->interface.statcallb(&cmd);	}	if ((chan->fax->code > 1) && (chan->fax->code < 120))		chan->fax->code += 120;	eicon_log(ccard, 8, "idi_fax: Ch%d: Hangup (code=%d)\n", chan->No, chan->fax->code);	chan->fax->r_code = ISDN_TTY_FAX_HNG;	cmd.driver = ccard->myid;	cmd.command = ISDN_STAT_FAXIND;	cmd.arg = chan->No;	ccard->interface.statcallb(&cmd);}#endif	/******** FAX ********/intidi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len){	struct sk_buff *skb;	struct sk_buff *skb2;	eicon_REQ *reqbuf;	eicon_chan_ptr *chan2;	if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {		eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state);		return -ENODEV;	}	eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No,			UReq, buffer[0], buffer[1], buffer[2], buffer[3]);	skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);	skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);	if ((!skb) || (!skb2)) {		eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);		if (skb) 			dev_kfree_skb(skb);		if (skb2) 			dev_kfree_skb(skb2);		return -ENOMEM;	}	chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));	chan2->ptr = chan;	reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));	reqbuf->Req = N_UDATA;	reqbuf->ReqCh = chan->e.IndCh;	reqbuf->ReqId = 1;	reqbuf->XBuffer.length = len + 1;	reqbuf->XBuffer.P[0] = UReq;	memcpy(&reqbuf->XBuffer.P[1], buffer, len);	reqbuf->Reference = 1; /* Net Entity */	skb_queue_tail(&chan->e.X, skb);	skb_queue_tail(&card->sndq, skb2);	eicon_schedule_tx(card);	return (0);}voididi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value){	u_char buf[6];	struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;	if ((!ccard) || (!chan))		return;	memset(buf, 0, 6);	switch(cmd) {		case ISDN_AUDIO_SETDD:			if (value[0]) {				dtmf_buf->tone = (__u16) (value[1] * 5);				dtmf_buf->gap = (__u16) (value[1] * 5);				idi_send_udata(ccard, chan,					DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER,					buf, 4);			} else {				idi_send_udata(ccard, chan,					DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,					buf, 0);			}			break;	}}voididi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len){	isdn_ctrl cmd;	eicon_dsp_ind *p = (eicon_dsp_ind *) (&buffer[1]);        static char *connmsg[] =        {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34",         "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90",         "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17"};	static u_char dtmf_code[] = {	'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'	};	if ((!ccard) || (!chan))		return;	switch (buffer[0]) {		case DSP_UDATA_INDICATION_SYNC:			eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time);			break;		case DSP_UDATA_INDICATION_DCD_OFF:			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time);			break;		case DSP_UDATA_INDICATION_DCD_ON:			if ((chan->l2prot == ISDN_PROTO_L2_MODEM) &&			    (chan->fsm_state == EICON_STATE_WMCONN)) {				chan->fsm_state = EICON_STATE_ACTIVE;				cmd.driver = ccard->myid;				cmd.command = ISDN_STAT_BCONN;				cmd.arg = chan->No;				sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);				ccard->interface.statcallb(&cmd);			}			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time);			eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,				p->norm, p->options, p->speed, p->delay); 			break;		case DSP_UDATA_INDICATION_CTS_OFF:			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time);			break;		case DSP_UDATA_INDICATION_CTS_ON:			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time);			eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,				p->norm, p->options, p->speed, p->delay); 			break;		case DSP_UDATA_INDICATION_DISCONNECT:			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);			break;		case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED:			eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No,				dtmf_code[buffer[1]]);			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_AUDIO;			cmd.parm.num[0] = ISDN_AUDIO_DTMF;			cmd.parm.num[1] = dtmf_code[buffer[1]];			cmd.arg = chan->No;			ccard->interface.statcallb(&cmd);			break;		default:			eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);	}}voideicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len){	int i,j,n;	int buflen = len * 3 + 30;	char *p;	struct trace_s {		unsigned long time;		unsigned short size;		unsigned short code;		unsigned char data[1];	} *q;	if (!(p = kmalloc(buflen, GFP_ATOMIC))) {		eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");		return;	}	memset(p, 0, buflen);	q = (struct trace_s *)buffer;	if (DebugVar & 512) {		if ((q->code == 3) || (q->code == 4)) {			n = (short) *(q->data);			if (n) {				j = sprintf(p, "DTRC:");				for (i = 0; i < n; i++) {					j += sprintf(p + j, "%02x ", q->data[i+2]);				}				j += sprintf(p + j, "\n");			}		}	} else {		j = sprintf(p, "XLOG: %lx %04x %04x ",			q->time, q->size, q->code);		for (i = 0; i < q->size; i++) {			j += sprintf(p + j, "%02x ", q->data[i]);		}		j += sprintf(p + j, "\n");	}	if (strlen(p))		eicon_putstatus(ccard, p);	kfree(p);}voididi_handle_ind(eicon_card *ccard, struct sk_buff *skb){	int tmp;	char tnum[64];	int dlev;	int free_buff;	ulong flags;	struct sk_buff *skb2;        eicon_IND *ind = (eicon_IND *)skb->data;	eicon_chan *chan;	idi_ind_message message;	isdn_ctrl cmd;	if (!ccard) {		eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");  		dev_kfree_skb(skb);		return;	}	if ((chan = ccard->IdTable[ind->IndId]) == NULL) {		eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");  		dev_kfree_skb(skb);		return;	}		if ((ind->Ind != 8) && (ind->Ind != 0xc))		dlev = 144;	else		dlev = 128;       	eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,	        ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);	free_buff = 1;	/* Signal Layer */	if (chan->e.D3Id == ind->IndId) {		idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);		switch(ind->Ind) {			case HANGUP:				eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No);		                while((skb2 = skb_dequeue(&chan->e.X))) {					dev_kfree_skb(skb2);				}				spin_lock_irqsave(&eicon_lock, flags);				chan->queued = 0;				chan->pqueued = 0;				chan->waitq = 0;				chan->waitpq = 0;				spin_unlock_irqrestore(&eicon_lock, flags);				if (message.e_cau[0] & 0x7f) {					cmd.driver = ccard->myid;					cmd.arg = chan->No;					sprintf(cmd.parm.num,"E%02x%02x", 						chan->cause[0]&0x7f, message.e_cau[0]&0x7f); 					cmd.command = ISDN_STAT_CAUSE;					ccard->interface.statcallb(&cmd);				}				chan->cause[0] = 0; 				if (((chan->fsm_state == EICON_STATE_ACTIVE) ||				    (chan->fsm_state == EICON_STATE_WMCONN)) ||				    ((chan->l2prot == ISDN_PROTO_L2_FAX) &&				    (chan->fsm_state == EICON_STATE_OBWAIT))) {					chan->fsm_state = EICON_STATE_NULL;				} else {					if (chan->e.B2Id)						idi_do_req(ccard, chan, REMOVE, 1);					chan->statectrl &= ~WAITING_FOR_HANGUP;					chan->statectrl &= ~IN_HOLD;					if (chan->statectrl & HAVE_CONN_REQ) {						eicon_log(ccard, 32, "idi_req: Ch%d: queueing delayed conn_req\n", chan->No);						chan->statectrl &= ~HAVE_CONN_REQ;						if ((chan->tskb1) && (chan->tskb2)) {							skb_queue_tail(&chan->e.X, chan->tskb1);							skb_queue_tail(&ccard->sndq, chan->tskb2); 							eicon_schedule_tx(ccard);						}						chan->tskb1 = NULL;						chan->tskb2 = NULL;					} else {						chan->fsm_state = EICON_STATE_NULL;						cmd.driver = ccard->myid;						cmd.arg = chan->No;						cmd.command = ISDN_STAT_DHUP;						ccard->interface.statcallb(&cmd);						eicon_idi_listen_req(ccard, chan);#ifdef CONFIG_ISDN_TTY_FAX						chan->fax = 0;#endif			

⌨️ 快捷键说明

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