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

📄 capidrv.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
		       card->contrnr, nccip->chan, nccip->ncci);		break;	case CAPI_CONNECT_B3_ACTIVE_CONF:	/* ncci */		goto ignored;	case CAPI_CONNECT_B3_IND:	/* ncci */		plcip = find_plci_by_ncci(card, cmsg->adr.adrNCCI);		if (plcip) {			nccip = new_ncci(card, plcip, cmsg->adr.adrNCCI);			if (nccip) {				ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_IND);				capi_fill_CONNECT_B3_RESP(cmsg,							  global.appid,							  card->msgid++,							  nccip->ncci,	/* adr */							  0,	/* Reject */							  0	/* NCPI */				);				send_message(card, cmsg);				ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);				break;			}			printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n",							card->contrnr);		} else {			printk(KERN_ERR "capidrv-%d: %s: plci for ncci 0x%x not found\n",			   card->contrnr,			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),			       cmsg->adr.adrNCCI);		}		capi_fill_CONNECT_B3_RESP(cmsg,					  global.appid,					  card->msgid++,					  cmsg->adr.adrNCCI,					  2,	/* Reject */					  0	/* NCPI */		);		send_message(card, cmsg);		break;	case CAPI_CONNECT_B3_CONF:	/* ncci */		if (!(nccip = find_ncci_by_msgid(card,						 cmsg->adr.adrNCCI,						 cmsg->Messagenumber)))			goto notfound;		nccip->ncci = cmsg->adr.adrNCCI;		if (cmsg->Info) {			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",			   card->contrnr,			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),			       cmsg->Info, capi_info2str(cmsg->Info), 			       cmsg->adr.adrNCCI);		}		if (cmsg->Info)			ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_ERROR);		else			ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_OK);		break;	case CAPI_CONNECT_B3_T90_ACTIVE_IND:	/* ncci */		capi_cmsg_answer(cmsg);		send_message(card, cmsg);		break;	case CAPI_DATA_B3_IND:	/* ncci */		/* handled in handle_data() */		goto ignored;	case CAPI_DATA_B3_CONF:	/* ncci */		if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))			goto notfound;		len = capidrv_del_ack(nccip, cmsg->DataHandle);		if (len < 0)			break;	        cmd.command = ISDN_STAT_BSENT;	        cmd.driver = card->myid;	        cmd.arg = nccip->chan;		cmd.parm.length = len;	        card->interface.statcallb(&cmd);		break;	case CAPI_DISCONNECT_B3_IND:	/* ncci */		if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))			goto notfound;		card->bchans[nccip->chan].disconnecting = 1;		ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);		capi_cmsg_answer(cmsg);		send_message(card, cmsg);		ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);		break;	case CAPI_DISCONNECT_B3_CONF:	/* ncci */		if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))			goto notfound;		if (cmsg->Info) {			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",			   card->contrnr,			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),			       cmsg->Info, capi_info2str(cmsg->Info), 			       cmsg->adr.adrNCCI);			ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_CONF_ERROR);		}		break;	case CAPI_RESET_B3_IND:	/* ncci */		if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))			goto notfound;		ncci_change_state(card, nccip, EV_NCCI_RESET_B3_IND);		capi_cmsg_answer(cmsg);		send_message(card, cmsg);		break;	case CAPI_RESET_B3_CONF:	/* ncci */		goto ignored;	/* $$$$ */	case CAPI_FACILITY_IND:	/* Controller/plci/ncci */		goto ignored;	case CAPI_FACILITY_CONF:	/* Controller/plci/ncci */		goto ignored;	default:		printk(KERN_ERR "capidrv-%d: got %s for ncci 0x%x ???",		       card->contrnr,		       capi_cmd2str(cmsg->Command, cmsg->Subcommand),		       cmsg->adr.adrNCCI);	}	return;      ignored:	printk(KERN_INFO "capidrv-%d: %s for ncci 0x%x ignored\n",	       card->contrnr,	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),	       cmsg->adr.adrNCCI);	return;      notfound:	printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n",	       card->contrnr,	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),	       cmsg->adr.adrNCCI);}static void handle_data(_cmsg * cmsg, struct sk_buff *skb){	capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);	capidrv_ncci *nccip;	if (!card) {		printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",		       capi_cmd2str(cmsg->Command, cmsg->Subcommand),		       cmsg->adr.adrController & 0x7f);		kfree_skb(skb);		return;	}	if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) {		printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n",		       card->contrnr,		       capi_cmd2str(cmsg->Command, cmsg->Subcommand),		       cmsg->adr.adrNCCI);		kfree_skb(skb);		return;	}	(void) skb_pull(skb, CAPIMSG_LEN(skb->data));	card->interface.rcvcallb_skb(card->myid, nccip->chan, skb);	capi_cmsg_answer(cmsg);	send_message(card, cmsg);}static _cmsg s_cmsg;static void capidrv_signal(__u16 applid, void *dummy){	struct sk_buff *skb = 0;	while ((*capifuncs->capi_get_message) (global.appid, &skb) == CAPI_NOERROR) {		capi_message2cmsg(&s_cmsg, skb->data);		if (debugmode > 2)			printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",					applid, capi_cmsg2str(&s_cmsg));		if (s_cmsg.Command == CAPI_DATA_B3		    && s_cmsg.Subcommand == CAPI_IND) {			handle_data(&s_cmsg, skb);			global.nrecvdatapkt++;			continue;		}		if ((s_cmsg.adr.adrController & 0xffffff00) == 0)			handle_controller(&s_cmsg);		else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0)			handle_plci(&s_cmsg);		else			handle_ncci(&s_cmsg);		/*		 * data of skb used in s_cmsg,		 * free data when s_cmsg is not used again		 * thanks to Lars Heete <hel@admin.de>		 */		kfree_skb(skb);		global.nrecvctlpkt++;	}}/* ------------------------------------------------------------------- */#define PUTBYTE_TO_STATUS(card, byte) \	do { \		*(card)->q931_write++ = (byte); \        	if ((card)->q931_write > (card)->q931_end) \	  		(card)->q931_write = (card)->q931_buf; \	} while (0)static void handle_dtrace_data(capidrv_contr *card,			     int send, int level2, __u8 *data, __u16 len){    	__u8 *p, *end;    	isdn_ctrl cmd;    	if (!len) {		printk(KERN_DEBUG "capidrv-%d: avmb1_q931_data: len == %d\n",				card->contrnr, len);		return;	}	if (level2) {		PUTBYTE_TO_STATUS(card, 'D');		PUTBYTE_TO_STATUS(card, '2');        	PUTBYTE_TO_STATUS(card, send ? '>' : '<');        	PUTBYTE_TO_STATUS(card, ':');	} else {        	PUTBYTE_TO_STATUS(card, 'D');        	PUTBYTE_TO_STATUS(card, '3');        	PUTBYTE_TO_STATUS(card, send ? '>' : '<');        	PUTBYTE_TO_STATUS(card, ':');    	}	for (p = data, end = data+len; p < end; p++) {		__u8 w;		PUTBYTE_TO_STATUS(card, ' ');		w = (*p >> 4) & 0xf;		PUTBYTE_TO_STATUS(card, (w < 10) ? '0'+w : 'A'-10+w);		w = *p & 0xf;		PUTBYTE_TO_STATUS(card, (w < 10) ? '0'+w : 'A'-10+w);	}	PUTBYTE_TO_STATUS(card, '\n');	cmd.command = ISDN_STAT_STAVAIL;	cmd.driver = card->myid;	cmd.arg = len*3+5;	card->interface.statcallb(&cmd);}/* ------------------------------------------------------------------- */static _cmsg cmdcmsg;static int capidrv_ioctl(isdn_ctrl * c, capidrv_contr * card){	switch (c->arg) {	case 1:		debugmode = (int)(*((unsigned int *)c->parm.num));		printk(KERN_DEBUG "capidrv-%d: debugmode=%d\n",				card->contrnr, debugmode);		return 0;	default:		printk(KERN_DEBUG "capidrv-%d: capidrv_ioctl(%ld) called ??\n",				card->contrnr, c->arg);		return -EINVAL;	}	return -EINVAL;}/* * Handle leased lines (CAPI-Bundling) */struct internal_bchannelinfo {   unsigned short channelalloc;   unsigned short operation;   unsigned char  cmask[31];};static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep){	unsigned long bmask = 0;	int active = !0;	char *s;	int i;	if (strncmp(teln, "FV:", 3) != 0)		return 1;	s = teln + 3;	while (*s && *s == ' ') s++;	if (!*s) return -2;	if (*s == 'p' || *s == 'P') {		active = 0;		s++;	}	if (*s == 'a' || *s == 'A') {		active = !0;		s++;	}	while (*s) {		int digit1 = 0;		int digit2 = 0;		if (!isdigit(*s)) return -3;		while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; }		if (digit1 <= 0 && digit1 > 30) return -4;		if (*s == 0 || *s == ',' || *s == ' ') {			bmask |= (1 << digit1);			digit1 = 0;			if (*s) s++;			continue;		}		if (*s != '-') return -5;		s++;		if (!isdigit(*s)) return -3;		while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; }		if (digit2 <= 0 && digit2 > 30) return -4;		if (*s == 0 || *s == ',' || *s == ' ') {			if (digit1 > digit2)				for (i = digit2; i <= digit1 ; i++)					bmask |= (1 << i);			else 				for (i = digit1; i <= digit2 ; i++)					bmask |= (1 << i);			digit1 = digit2 = 0;			if (*s) s++;			continue;		}		return -6;	}	if (activep) *activep = active;	if (bmaskp) *bmaskp = bmask;	return 0;}static int FVteln2capi20(char *teln, __u8 AdditionalInfo[1+2+2+31]){	unsigned long bmask;	int active;	int rc, i;   	rc = decodeFVteln(teln, &bmask, &active);	if (rc) return rc;	/* Length */	AdditionalInfo[0] = 2+2+31;        /* Channel: 3 => use channel allocation */        AdditionalInfo[1] = 3; AdditionalInfo[2] = 0;	/* Operation: 0 => DTE mode, 1 => DCE mode */        if (active) {   		AdditionalInfo[3] = 0; AdditionalInfo[4] = 0;   	} else {   		AdditionalInfo[3] = 1; AdditionalInfo[4] = 0;	}	/* Channel mask array */	AdditionalInfo[5] = 0; /* no D-Channel */	for (i=1; i <= 30; i++)		AdditionalInfo[5+i] = (bmask & (1 << i)) ? 0xff : 0;	return 0;}static int capidrv_command(isdn_ctrl * c, capidrv_contr * card){	isdn_ctrl cmd;	struct capidrv_bchan *bchan;	struct capidrv_plci *plcip;	__u8 AdditionalInfo[1+2+2+31];        int rc, isleasedline = 0;	if (c->command == ISDN_CMD_IOCTL)		return capidrv_ioctl(c, card);	switch (c->command) {	case ISDN_CMD_DIAL:{			__u8 calling[ISDN_MSNLEN + 3];			__u8 called[ISDN_MSNLEN + 2];			if (debugmode)				printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_DIAL(ch=%ld,\"%s,%d,%d,%s\")\n",					card->contrnr,					c->arg,				        c->parm.setup.phone,				        c->parm.setup.si1,				        c->parm.setup.si2,				        c->parm.setup.eazmsn);			bchan = &card->bchans[c->arg % card->nbchan];			if (bchan->plcip) {				printk(KERN_ERR "capidrv-%d: dail ch=%ld,\"%s,%d,%d,%s\" in use (plci=0x%x)\n",					card->contrnr,			        	c->arg, 				        c->parm.setup.phone,				        c->parm.setup.si1,				        c->parm.setup.si2,				        c->parm.setup.eazmsn,				        bchan->plcip->plci);				return 0;			}			bchan->si1 = c->parm.setup.si1;			bchan->si2 = c->parm.setup.si2;			strncpy(bchan->num, c->parm.setup.phone, sizeof(bchan->num));			strncpy(bchan->mynum, c->parm.setup.eazmsn, sizeof(bchan->mynum));                        rc = FVteln2capi20(bchan->num, AdditionalInfo);			isleasedline = (rc == 0);			if (rc < 0)				printk(KERN_ERR "capidrv-%d: WARNING: illegal leased linedefinition \"%s\"\n", card->contrnr, bchan->num);			if (isleasedline) {				calling[0] = 0;				called[0] = 0;			        if (debugmode)					printk(KERN_DEBUG "capidrv-%d: connecting leased line\n", card->contrnr);			} else {		        	calling[0] = strlen(bchan->mynum) + 2;		        	calling[1] = 0;		     		calling[2] = 0x80;			   	strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN);				called[0] = strlen(bchan->num) + 1;				called[1] = 0x80;				strncpy(called + 2, bchan->num, ISDN_MSNLEN);			}			capi_fill_CONNECT_REQ(&cmdcmsg,					      global.appid,					      card->msgid++,					      card->contrnr,	/* adr */					  si2cip(bchan->si1, bchan->si2),	/* cipvalue */					      called,	/* CalledPartyNumber */					      calling,	/* CallingPartyNumber */					      0,	/* CalledPartySubaddress */					      0,	/* CallingPartySubaddress */					    b1prot(bchan->l2, bchan->l3),	/* B1protocol */					    b2prot(bchan->l2, bchan->l3),	/* B2protocol */					    b3prot(bchan->l2, bchan->l3),	/* B3protocol */					    b1config(bchan->l2, bchan->l3),	/* B1configuration */					      0,	/* B2configuration */					      0,	/* B3configuration */					      0,	/* BC */					      0,	/* LLC */					      0,	/* HLC */					      /* BChannelinformation */					      isleasedline ? AdditionalInfo : 0,					      0,	/* Keypadfacility */					      0,	/* Useruserdata */					      0		/* Facilitydataarray */			    );			if ((plcip = new_plci(card, (c->arg % card->nbchan))) == 0) {				cmd.command = ISDN_STAT_DHUP;				cmd.driver = card->myid;				cmd.arg = (c->arg % card->nbchan);				card->interface.statcallb(&cmd);				return -1;			}			plcip->msgid = cmdcmsg.Messagenumber;

⌨️ 快捷键说明

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