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

📄 eicon_idi.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					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", "V.32", "K56Flex",         "X2", "V.18", "V.18LH", "V.18HL", "V.21LH", "V.21HL",         "Bell 103LH", "Bell 103HL", "V.23", "V.23", "EDT 110",         "Baudot45", "Baudot47", "Baudot50", "DTMF" };	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;                                if (p->norm > 34) {                                  sprintf(cmd.parm.num, "%d/(%d)", p->speed, p->norm);                                } else {                                  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					}				}				break;			case INDICATE_IND:				eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", ch

⌨️ 快捷键说明

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