Esempio n. 1
0
struct sk_buff *
gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
{
	struct sk_buff *nskb;
	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC);
	if (nskb) {
		__u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
		unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
		capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
		capimsg_setu16(s, 2, mp->applid);
		capimsg_setu8 (s, 4, CAPI_DATA_B3);
		capimsg_setu8 (s, 5, CAPI_RESP);
		capimsg_setu16(s, 6, mp->msgid++);
		capimsg_setu32(s, 8, mp->ncci);
		capimsg_setu16(s, 12, datahandle);
	}
	return nskb;
}
Esempio n. 2
0
void
hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf, unsigned short len)
{
	struct sk_buff *skb;
	hycapictrl_info *cinfo = card->hyctrlinfo;
	struct capi_ctr *ctrl;
	__u16 ApplId;
	__u16 MsgLen, info;
	__u16 len2, CapiCmd;
	__u32 CP64[2] = {0, 0};
#ifdef HYCAPI_PRINTFNAMES
	printk(KERN_NOTICE "hycapi_rx_capipkt\n");
#endif
	if (!cinfo) {
		return;
	}
	ctrl = &cinfo->capi_ctrl;
	if (len < CAPI_MSG_BASELEN) {
		printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, length %d!\n",
		       card->myid, len);
		return;
	}
	MsgLen = CAPIMSG_LEN(buf);
	ApplId = CAPIMSG_APPID(buf);
	CapiCmd = CAPIMSG_CMD(buf);

	if ((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {
		len2 = len + (30 - MsgLen);
		if (!(skb = alloc_skb(len2, GFP_ATOMIC))) {
			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
			       card->myid);
			return;
		}
		memcpy(skb_put(skb, MsgLen), buf, MsgLen);
		memcpy(skb_put(skb, 2 * sizeof(__u32)), CP64, 2 * sizeof(__u32));
		memcpy(skb_put(skb, len - MsgLen), buf + MsgLen,
		       len - MsgLen);
		CAPIMSG_SETLEN(skb->data, 30);
	} else {
		if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
			       card->myid);
			return;
		}
		memcpy(skb_put(skb, len), buf, len);
	}
	switch (CAPIMSG_CMD(skb->data))
	{
	case CAPI_CONNECT_B3_CONF:
/* Check info-field for error-indication: */
		info = CAPIMSG_U16(skb->data, 12);
		switch (info)
		{
		case 0:
			capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data),
					 hycapi_applications[ApplId - 1].rp.datablkcnt);

			break;
		case 0x0001:
			printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "
			       "protocol. NCPI ignored.\n", card->myid);
			break;
		case 0x2001:
			printk(KERN_ERR "HYSDN Card%d: Message not supported in"
			       " current state\n", card->myid);
			break;
		case 0x2002:
			printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid);
			break;
		case 0x2004:
			printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);
			break;
		case 0x3008:
			printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n",
			       card->myid);
			break;
		default:
			printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n",
			       card->myid, info);
			break;
		}
		break;
	case CAPI_CONNECT_B3_IND:
		capilib_new_ncci(&cinfo->ncci_head, ApplId,
				 CAPIMSG_NCCI(skb->data),
				 hycapi_applications[ApplId - 1].rp.datablkcnt);
		break;
	case CAPI_DATA_B3_CONF:
		capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
				     CAPIMSG_NCCI(skb->data),
				     CAPIMSG_MSGID(skb->data));
		break;
	default:
		break;
	}
	capi_ctr_handle_message(ctrl, ApplId, skb);
}
Esempio n. 3
0
static void capi_signal(__u16 applid, void *param)
{
	struct capidev *cdev = (struct capidev *)param;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
	struct capiminor *mp;
	__u16 datahandle;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
	struct capincci *np;
	struct sk_buff *skb = 0;
	__u32 ncci;

	(void) (*capifuncs->capi_get_message) (applid, &skb);
	if (!skb) {
		printk(KERN_ERR "BUG: capi_signal: no skb\n");
		return;
	}

	if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
		skb_queue_tail(&cdev->recvqueue, skb);
		wake_up_interruptible(&cdev->recvwait);
		return;
	}
	ncci = CAPIMSG_CONTROL(skb->data);
	for (np = cdev->nccis; np && np->ncci != ncci; np = np->next)
		;
	if (!np) {
		printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
		skb_queue_tail(&cdev->recvqueue, skb);
		wake_up_interruptible(&cdev->recvwait);
		return;
	}
#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
	skb_queue_tail(&cdev->recvqueue, skb);
	wake_up_interruptible(&cdev->recvwait);
#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
	mp = np->minorp;
	if (!mp) {
		skb_queue_tail(&cdev->recvqueue, skb);
		wake_up_interruptible(&cdev->recvwait);
		return;
	}


	if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
#ifdef _DEBUG_DATAFLOW
		printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
				datahandle, skb->len-CAPIMSG_LEN(skb->data));
#endif
		skb_queue_tail(&mp->inqueue, skb);
		mp->inbytes += skb->len;
		handle_minor_recv(mp);

	} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {

		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
#ifdef _DEBUG_DATAFLOW
		printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n",
				datahandle,
				CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
#endif
		kfree_skb(skb);
		(void)capiminor_del_ack(mp, datahandle);
		if (mp->tty) {
			if (mp->tty->ldisc.write_wakeup)
				mp->tty->ldisc.write_wakeup(mp->tty);
		} else {
			wake_up_interruptible(&mp->sendwait);
		}
		(void)handle_minor_send(mp);

	} else {
		/* ups, let capi application handle it :-) */
		skb_queue_tail(&cdev->recvqueue, skb);
		wake_up_interruptible(&cdev->recvwait);
	}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
}
Esempio n. 4
0
int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
{
	struct sk_buff *nskb;
	unsigned int datalen;
	__u16 errcode, datahandle;

	datalen = skb->len - CAPIMSG_LEN(skb->data);
	if (mp->tty) {
		if (mp->tty->ldisc.receive_buf == 0) {
			printk(KERN_ERR "capi: ldisc has no receive_buf function\n");
			return -1;
		}
		if (mp->ttyinstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
			printk(KERN_DEBUG "capi: recv tty throttled\n");
#endif
			return -1;
		}
		if (mp->tty->ldisc.receive_room &&
		    mp->tty->ldisc.receive_room(mp->tty) < datalen) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
			printk(KERN_DEBUG "capi: no room in tty\n");
#endif
			return -1;
		}
		if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
			printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
			return -1;
		}
		datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
		errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
		if (errcode != CAPI_NOERROR) {
			printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
					errcode);
			kfree_skb(nskb);
			return -1;
		}
		(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW
		printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
					datahandle, skb->len);
#endif
		mp->tty->ldisc.receive_buf(mp->tty, skb->data, 0, skb->len);
		kfree_skb(skb);
		return 0;

	} else if (mp->file) {
		if (skb_queue_len(&mp->recvqueue) > CAPINC_MAX_RECVQUEUE) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
			printk(KERN_DEBUG "capi: no room in raw queue\n");
#endif
			return -1;
		}
		if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
			printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
			return -1;
		}
		datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
		errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
		if (errcode != CAPI_NOERROR) {
			printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
					errcode);
			kfree_skb(nskb);
			return -1;
		}
		(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW
		printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => raw\n",
					datahandle, skb->len);
#endif
		skb_queue_tail(&mp->recvqueue, skb);
		wake_up_interruptible(&mp->recvwait);
		return 0;
	}
#ifdef _DEBUG_DATAFLOW
	printk(KERN_DEBUG "capi: currently no receiver\n");
#endif
	return -1;
}