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

📄 eicon_idi.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (chan->fax->r_compression != 0) {			/* telling fake compression in second DIS message */				chan->fax->r_compression = 0;				cmd.driver = ccard->myid;				cmd.command = ISDN_STAT_FAXIND;				cmd.arg = chan->No;				chan->fax->r_code = ISDN_TTY_FAX_DIS;				ccard->interface.statcallb(&cmd);			}			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_FAXIND;			cmd.arg = chan->No;			chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */			ccard->interface.statcallb(&cmd);		} else		if (chan->fax->phase == ISDN_FAX_PHASE_D) {			if ((chan->fax->code == EDATA_T30_MCF) &&			    (chan->fax->fet != 2)) {				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);			}			switch(chan->fax->fet) {				case 0:	/* new page */					/* stay in phase D , wait on cmd +FDT */					break;				case 1:	/* new document */					/* link-level switch to phase B */					break;				case 2:	/* session end */				default:					/* send_edata produces error on some */					/* fax-machines here, so we don't */					/* idi_send_edata(ccard, chan); */					break;			}		}	}	if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {		idi_parse_edata(ccard, chan, buffer, len);		if ((chan->fax->code == EDATA_T30_DCS) &&		    (chan->fax->phase == ISDN_FAX_PHASE_A)) {			idi_reset_fax_stat(chan);			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_BCONN;			cmd.arg = chan->No;			strcpy(cmd.parm.num, "");			ccard->interface.statcallb(&cmd);			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_FAXIND;			cmd.arg = chan->No;			chan->fax->r_code = ISDN_TTY_FAX_FCON_I;			ccard->interface.statcallb(&cmd);		} else		if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&		    (chan->fax->phase == ISDN_FAX_PHASE_A)) {			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_FAXIND;			cmd.arg = chan->No;			chan->fax->r_code = ISDN_TTY_FAX_RID;			ccard->interface.statcallb(&cmd);			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_FAXIND;			cmd.arg = chan->No;			chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;			ccard->interface.statcallb(&cmd);		} else		if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&		    (chan->fax->phase == ISDN_FAX_PHASE_B)) {			cmd.driver = ccard->myid;			cmd.command = ISDN_STAT_FAXIND;			cmd.arg = chan->No;			chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;			ccard->interface.statcallb(&cmd);		} else		if (chan->fax->phase == ISDN_FAX_PHASE_C) {			switch(chan->fax->code) {				case EDATA_T30_TRAIN_OK:					idi_send_edata(ccard, chan);					break;				case EDATA_T30_MPS:					chan->fax->fet = 0;					idi_edata_rcveop(ccard, chan);					break;				case EDATA_T30_EOM:					chan->fax->fet = 1;					idi_edata_rcveop(ccard, chan);					break;				case EDATA_T30_EOP:					chan->fax->fet = 2;					idi_edata_rcveop(ccard, chan);					break;			}		}	}}voidfax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len){	struct sk_buff *skb;	        skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);	if (!skb) {		eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);		return;	}	skb_reserve(skb, MAX_HEADER_LEN);	memcpy(skb_put(skb, len), Data, len);	ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);}voididi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb){	eicon_OBJBUFFER InBuf;	eicon_OBJBUFFER LineBuf;	unsigned int Length = 0;	unsigned int aLength = 0;	unsigned int ObjectSize = 0;	unsigned int ObjHeadLen = 0;	unsigned int ObjDataLen = 0;	__u8 Recordtype;	__u8 PageHeaderLen;		__u8 Event;	eicon_sff_pagehead *ob_page;	__u16 Cl2Eol = 0x8000;#	define EVENT_NONE	0#	define EVENT_NEEDDATA	1	if (!chan->fax) {		eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");		return;	}		if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {		InBuf.Data = skb->data;		InBuf.Size = skb->len;		InBuf.Len  = 0;		InBuf.Next = InBuf.Data;		LineBuf.Data = chan->fax2.abLine;		LineBuf.Size = sizeof(chan->fax2.abLine);		LineBuf.Len  = chan->fax2.LineLen;		LineBuf.Next = LineBuf.Data + LineBuf.Len;		Event = EVENT_NONE;		while (Event == EVENT_NONE) {			switch(chan->fax2.NextObject) {				case FAX_OBJECT_DOCU:						Length = LineBuf.Len + (InBuf.Size - InBuf.Len);						if (Length < sizeof(eicon_sff_dochead)) {							Event = EVENT_NEEDDATA;							break;						}						ObjectSize = sizeof(eicon_sff_dochead);						Length = ObjectSize;						if (LineBuf.Len < Length) {							Length -= LineBuf.Len;							LineBuf.Len = 0;							LineBuf.Next = LineBuf.Data;							InBuf.Len += Length;							InBuf.Next += Length;						} else {							LineBuf.Len -= Length;							LineBuf.Next = LineBuf.Data + LineBuf.Len;							memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);						}						chan->fax2.PrevObject = FAX_OBJECT_DOCU;						chan->fax2.NextObject = FAX_OBJECT_PAGE;					break;				case FAX_OBJECT_PAGE:						Length = LineBuf.Len + (InBuf.Size - InBuf.Len);						if (Length < 2) {							Event = EVENT_NEEDDATA;							break;						}						if (LineBuf.Len == 0) {							*LineBuf.Next++ = *InBuf.Next++;							LineBuf.Len++;							InBuf.Len++;						}						if (LineBuf.Len == 1) {							*LineBuf.Next++ = *InBuf.Next++;							LineBuf.Len++;							InBuf.Len++;						}						PageHeaderLen = *(LineBuf.Data + 1);						ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);						if (Length < ObjectSize) {							Event = EVENT_NEEDDATA;							break;						}						Length = ObjectSize;						/* extract page dimensions */						if (LineBuf.Len < Length) {							aLength = Length - LineBuf.Len;							memcpy(LineBuf.Next, InBuf.Next, aLength);							LineBuf.Next += aLength;							InBuf.Next += aLength;							LineBuf.Len += aLength;							InBuf.Len += aLength;						}						if (Length > 2) {							ob_page = (eicon_sff_pagehead *)LineBuf.Data;							switch(ob_page->linelength) {								case 2048:									chan->fax->r_width = 1;									break;								case 2432:									chan->fax->r_width = 2;									break;								case 1216:									chan->fax->r_width = 3;									break;								case 864:									chan->fax->r_width = 4;									break;								case 1728:								default:									chan->fax->r_width = 0;							}							switch(ob_page->pagelength) {								case 1143:								case 2287:									chan->fax->r_length = 0;									break;								case 1401:								case 2802:									chan->fax->r_length = 1;									break;								default:									chan->fax->r_length = 2;							}							eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength);							eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength);						}						LineBuf.Len -= Length;						LineBuf.Next = LineBuf.Data + LineBuf.Len;						memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);						chan->fax2.PrevObject = FAX_OBJECT_PAGE;						chan->fax2.NextObject = FAX_OBJECT_LINE;					break;				case FAX_OBJECT_LINE:						Length = LineBuf.Len + (InBuf.Size - InBuf.Len);						if (Length < 1) {							Event = EVENT_NEEDDATA;							break;						}						if (LineBuf.Len == 0) {							*LineBuf.Next++ = *InBuf.Next++;							LineBuf.Len++;							InBuf.Len++;						}						Recordtype = *LineBuf.Data;						if (Recordtype == 0) {							/* recordtype pixel row (2 byte length) */							ObjHeadLen = 3;							if (Length < ObjHeadLen) {								Event = EVENT_NEEDDATA;								break;							}							while (LineBuf.Len < ObjHeadLen) {								*LineBuf.Next++ = *InBuf.Next++;								LineBuf.Len++;								InBuf.Len++;							}							ObjDataLen = *((__u16*) (LineBuf.Data + 1));							ObjectSize = ObjHeadLen + ObjDataLen;							if (Length < ObjectSize) {								Event = EVENT_NEEDDATA;								break;							}						} else						if ((Recordtype >= 1) && (Recordtype <= 216)) {							/* recordtype pixel row (1 byte length) */							ObjHeadLen = 1;							ObjDataLen = Recordtype;							ObjectSize = ObjHeadLen + ObjDataLen;							if (Length < ObjectSize) {								Event = EVENT_NEEDDATA;								break;							}						} else						if ((Recordtype >= 217) && (Recordtype <= 253)) {							/* recordtype empty lines */							ObjHeadLen = 1;							ObjDataLen = 0;							ObjectSize = ObjHeadLen + ObjDataLen;							LineBuf.Len--;							LineBuf.Next = LineBuf.Data + LineBuf.Len;							memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);							break;						} else						if (Recordtype == 254) {							/* recordtype page header */							chan->fax2.PrevObject = FAX_OBJECT_LINE;							chan->fax2.NextObject = FAX_OBJECT_PAGE;							break;						} else {							/* recordtype user information */							ObjHeadLen = 2;							if (Length < ObjHeadLen) {								Event = EVENT_NEEDDATA;								break;							}							while (LineBuf.Len < ObjHeadLen) {								*LineBuf.Next++ = *InBuf.Next++;								LineBuf.Len++;								InBuf.Len++;							}							ObjDataLen = *(LineBuf.Data + 1);							ObjectSize = ObjHeadLen + ObjDataLen;							if (ObjDataLen == 0) {								/* illegal line coding */								LineBuf.Len -= ObjHeadLen;								LineBuf.Next = LineBuf.Data + LineBuf.Len;								memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len);								break;							} else {								/* user information */								if (Length < ObjectSize) {									Event = EVENT_NEEDDATA;									break;								}								Length = ObjectSize;								if (LineBuf.Len < Length) {									Length -= LineBuf.Len;									LineBuf.Len = 0;									LineBuf.Next = LineBuf.Data;									InBuf.Len += Length;									InBuf.Next += Length;								} else {									LineBuf.Len -= Length;									LineBuf.Next = LineBuf.Data + LineBuf.Len;									memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);								}							}							break;							}						Length = ObjectSize;						if (LineBuf.Len > ObjHeadLen) {							fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,									(LineBuf.Len - ObjHeadLen));						}						Length -= LineBuf.Len;						LineBuf.Len = 0;						LineBuf.Next = LineBuf.Data;						if (Length > 0) {							fax_put_rcv(ccard, chan, InBuf.Next, Length);							InBuf.Len += Length;							InBuf.Next += Length;						}						fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));					break;			} /* end of switch (chan->fax2.NextObject) */		} /* end of while (Event==EVENT_NONE) */		if (InBuf.Len < InBuf.Size) {			Length = InBuf.Size - InBuf.Len;			if ((LineBuf.Len + Length) > LineBuf.Size) {				eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No,					Length);				} else {					memcpy(LineBuf.Next, InBuf.Next, Length);					LineBuf.Len += Length;				}		}		chan->fax2.LineLen = LineBuf.Len;	} else { /* CONN_OUT */		/* On CONN_OUT we do not need incoming data, drop it */		/* maybe later for polling */	}#	undef EVENT_NONE#	undef EVENT_NEEDDATA	return;}intidi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf){	struct sk_buff *skb;	skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);	if (!skb) {		eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);		return(-1);	}	memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);	OutBuf->Len = 0;	OutBuf->Next = OutBuf->Data;	return(idi_send_data(ccard, chan, 0, skb, 1, 0));}intidi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb){	isdn_ctrl cmd;	eicon_OBJBUFFER InBuf;	__u8 InData;	__u8 InMask;	eicon_OBJBUFFER OutBuf;	eicon_OBJBUFFER LineBuf;	__u32 LineData;	unsigned int LineDataLen;	__u8 Byte;	__u8 Event;	int ret = 1;#	define EVENT_NONE	0#	define EVENT_EOD	1#	define EVENT_EOL 	2#	define EVENT_EOP 	3	if ((!ccard) || (!chan))		return -1;	if (!chan->fax) {		eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");		return -1;	}	if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {		/* Simply ignore any data written in data mode when receiving a fax.    */		/* This is not completely correct because only XON's should come here.  */        	dev_kfree_skb(skb);		return 1;	}	if (chan->fax->phase != ISDN_FAX_PHASE_C) {        	dev_kfree_skb(skb);		return 1;	}        if (chan->queued + skb->len > 1200)                return 0;	if (chan->pqueued > 1)		return 0;	InBuf.Data = skb->data;	InBuf.Size = skb->len;	InBuf.Len  = 0;	InBuf.Next = InBuf.Data;	InData = 0;	InMask = 0;	LineBuf.Data = chan->fax2.abLine;	LineBuf.Size = sizeof(chan->fax2.abLine);	LineBuf.Len  = chan->fax2.LineLen;	LineBuf.Next = LineBuf.Data + LineBuf.Len;	LineData = chan->fax2.LineData;	LineDataLen = chan->fax2.LineDataLen;	OutBuf.Data = chan->fax2.abFrame;	OutBuf.Size = sizeof(chan->fax2.abFrame);	OutBuf.Len = 0;	OutBuf.Next = OutBuf.Data;	Event = EVENT_NONE;	chan->fax2.Eop = 0;	for (;;) {	  for (;;) {

⌨️ 快捷键说明

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