Beispiel #1
0
int
l2_tei(teimgr_t *tm, struct sk_buff *skb)
{
	mISDN_head_t	*hh;
	int		ret = -EINVAL;

	if (!tm || !skb)
		return(ret);
	hh = mISDN_HEAD_P(skb);
	if (tm->debug)
		printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim);
	switch(hh->prim) {
	    case (MDL_UNITDATA | INDICATION):
	    	return(tei_ph_data_ind(tm, hh->dinfo, skb));
	    case (MDL_ASSIGN | INDICATION):
		if (test_bit(FLG_FIXED_TEI, &tm->l2->flag)) {
			if (tm->debug)
				tm->tei_m.printdebug(&tm->tei_m,
					"fixed assign tei %d", tm->l2->tei);
			skb_trim(skb, 0);
			mISDN_sethead(MDL_ASSIGN | REQUEST, tm->l2->tei, skb);
			if (!tei_l2(tm->l2, skb))
				return(0);
//			cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
		} else
			mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL);
		break;
	    case (MDL_ERROR | INDICATION):
	    	if (!test_bit(FLG_FIXED_TEI, &tm->l2->flag))
			mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL);
		break;
	}
	dev_kfree_skb(skb);
	return(0);
}
Beispiel #2
0
int
l1_event(struct layer1 *l1, u_int event)
{
	int		err = 0;

	if (!l1)
		return -EINVAL;
	switch (event) {
	case HW_RESET_IND:
		mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
		break;
	case HW_DEACT_IND:
		mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
		break;
	case HW_POWERUP_IND:
		mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
		break;
	case HW_DEACT_CNF:
		mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
		break;
	case ANYSIGNAL:
		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
		break;
	case LOSTFRAMING:
		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
		break;
	case INFO2:
		mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
		break;
	case INFO4_P8:
		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
		break;
	case INFO4_P10:
		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
		break;
	case PH_ACTIVATE_REQ:
		if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
			l1->dcb(l1->dch, PH_ACTIVATE_IND);
		else {
			test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
			mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
		}
		break;
	case CLOSE_CHANNEL:
		release_l1(l1);
		break;
	default:
		if (*debug & DEBUG_L1)
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_DEBUG "%s %x unhandled\n",
			    __func__, event);
#else
			;
#endif
		err = -EINVAL;
	}
	return err;
}
Beispiel #3
0
static int
tei_ph_data_ind(teimgr_t *tm, int dtyp, struct sk_buff *skb)
{
	u_char *dp;
	int mt;
	int ret = -EINVAL;

	if (!skb)
		return(ret);
	if (test_bit(FLG_FIXED_TEI, &tm->l2->flag) &&
		!test_bit(FLG_LAPD_NET, &tm->l2->flag))
		return(ret);
	if (skb->len < 8) {
		tm->tei_m.printdebug(&tm->tei_m,
			"short mgr frame %ld/8", skb->len);
		return(ret);
	}
	dp = skb->data + 2;
	if ((*dp & 0xef) != UI) {
		tm->tei_m.printdebug(&tm->tei_m,
			"mgr frame is not ui %x", *dp);
		return(ret);
	}
	dp++;
	if (*dp++ != TEI_ENTITY_ID) {
		/* wrong management entity identifier, ignore */
		dp--;
		tm->tei_m.printdebug(&tm->tei_m,
			"tei handler wrong entity id %x", *dp);
		return(ret);
	} else {
		mt = *(dp+2);
		if (tm->debug)
			tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt);
		if (mt == ID_ASSIGNED)
			mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp);
		else if (mt == ID_DENIED)
			mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp);
		else if (mt == ID_CHK_REQ)
			mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp);
		else if (mt == ID_REMOVE)
			mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp);
		else if (mt == ID_REQUEST && 
			test_bit(FLG_LAPD_NET, &tm->l2->flag))
			mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN_REQ, dp);
		else {
			tm->tei_m.printdebug(&tm->tei_m,
				"tei handler wrong mt %x", mt);
			return(ret);
		}
	}
	dev_kfree_skb(skb);
	return(0);
}
Beispiel #4
0
static void
l2_restart_multi(struct FsmInst *fi, int event, void *arg)
{
	struct layer2	*l2 = fi->userdata;
	struct sk_buff	*skb = arg;
	int		est = 0;

	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);

	l2mgr(l2, MDL_ERROR_IND, (void *) 'F');

	if (l2->vs != l2->va) {
		skb_queue_purge(&l2->i_queue);
		est = 1;
	}

	clear_exception(l2);
	l2->vs = 0;
	l2->va = 0;
	l2->vr = 0;
	l2->sow = 0;
	mISDN_FsmChangeState(fi, ST_L2_7);
	stop_t200(l2, 3);
	mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);

	if (est)
		l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
/*		mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
 *		    MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
 *		    0, NULL, 0);
 */
	if (skb_queue_len(&l2->i_queue) && cansend(l2))
		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
}
Beispiel #5
0
static void
invoke_retransmission(struct layer2 *l2, unsigned int nr)
{
	u_int	p1;

	if (l2->vs != nr) {
		while (l2->vs != nr) {
			(l2->vs)--;
			if (test_bit(FLG_MOD128, &l2->flag)) {
				l2->vs %= 128;
				p1 = (l2->vs - l2->va) % 128;
			} else {
				l2->vs %= 8;
				p1 = (l2->vs - l2->va) % 8;
			}
			p1 = (p1 + l2->sow) % l2->window;
			if (l2->windowar[p1])
				skb_queue_head(&l2->i_queue, l2->windowar[p1]);
			else
				printk(KERN_WARNING
				    "%s: windowar[%d] is NULL\n",
				    __func__, p1);
			l2->windowar[p1] = NULL;
		}
		mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
	}
}
Beispiel #6
0
void
release_l3_process(l3_process_t *p)
{
	layer3_t *l3;

	if (!p)
		return;
	l3 = p->l3;
	mISDN_l3up(p, CC_RELEASE_CR | INDICATION, NULL);
	list_del(&p->list);
	StopAllL3Timer(p);
	kfree(p);
	if (list_empty(&l3->plist) && !test_bit(FLG_PTP, &l3->Flag)) {
		if (l3->debug)
			l3_debug(l3, "release_l3_process: last process");
		if (!skb_queue_len(&l3->squeue)) {
			if (l3->debug)
				l3_debug(l3, "release_l3_process: release link");
			mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL);
		} else {
			if (l3->debug)
				l3_debug(l3, "release_l3_process: not release link");
		}
	}
};
Beispiel #7
0
static void
FsmExpireTimer(struct FsmTimer *ft)
{
#if FSM_TIMER_DEBUG
	if (ft->fi->debug)
		ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
#endif
	mISDN_FsmEvent(ft->fi, ft->event, ft->arg);
}
Beispiel #8
0
static void
lc_connect(struct FsmInst *fi, int event, void *arg)
{
	layer3_t *l3 = fi->userdata;
	struct sk_buff *skb;
	int dequeued = 0;

	mISDN_FsmChangeState(fi, ST_L3_LC_ESTAB);
	while ((skb = skb_dequeue(&l3->squeue))) {
		if (l3down(l3, DL_DATA | REQUEST, l3_newid(l3), skb))
			dev_kfree_skb(skb);
		dequeued++;
	}
	if (list_empty(&l3->plist) &&  dequeued) {
		if (l3->debug)
			l3m_debug(fi, "lc_connect: release link");
		mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL);
	} else
		l3ml3p(l3, DL_ESTABLISH | INDICATION);
}
Beispiel #9
0
static void
listen_req_l_x(struct FsmInst *fi, int event, void *arg, int state)
{
	Application_t	*app = fi->userdata;
	_cmsg		*cmsg = arg;

	mISDN_FsmChangeState(fi, state);

	app->InfoMask = cmsg->InfoMask;
	app->CIPmask = cmsg->CIPmask;
	app->CIPmask2 = cmsg->CIPmask2;
	listenDebug(app, CAPI_DBG_LISTEN_INFO, "set InfoMask to 0x%x", app->InfoMask);
	listenDebug(app, CAPI_DBG_LISTEN_INFO, "set CIP to 0x%x,0x%x", app->CIPmask,
		app->CIPmask2);

	capi_cmsg_answer(cmsg);
	cmsg->Info = CAPI_NOERROR;

	if (mISDN_FsmEvent(&app->listen_m, EV_LISTEN_CONF, cmsg))
		cmsg_free(cmsg);
}
Beispiel #10
0
static int
ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
	struct sk_buff *nskb = skb;
	int ret = -EAGAIN;

	if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
		if (hh->id == l2->down_id) {
			nskb = skb_dequeue(&l2->down_queue);
			if (nskb) {
				l2->down_id = mISDN_HEAD_ID(nskb);
				if (l2down_skb(l2, nskb)) {
					dev_kfree_skb(nskb);
					l2->down_id = MISDN_ID_NONE;
				}
			} else
				l2->down_id = MISDN_ID_NONE;
			if (ret) {
				dev_kfree_skb(skb);
				ret = 0;
			}
			if (l2->down_id == MISDN_ID_NONE) {
				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
				mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
			}
		}
	}
	if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
		nskb = skb_dequeue(&l2->down_queue);
		if (nskb) {
			l2->down_id = mISDN_HEAD_ID(nskb);
			if (l2down_skb(l2, nskb)) {
				dev_kfree_skb(nskb);
				l2->down_id = MISDN_ID_NONE;
				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
			}
		} else
			test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
	}
	return ret;
}
Beispiel #11
0
static void
tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
{
	teimgr_t *otm, *tm = fi->userdata;
	u_char *dp = arg;
	int tei, ri;

	ri = ((unsigned int) *dp++ << 8);
	ri += *dp++;
	dp++;
	tei = *dp >> 1;
	if (tm->debug)
		tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
			ri, tei);
	if ((otm = findtei(tm, tei))) {	/* same tei is in use */
		if (ri != otm->ri) {	/* and it wasn't our request */
			tm->tei_m.printdebug(fi,
				"possible duplicate assignment tei %d", tei);
			mISDN_FsmEvent(&otm->tei_m, EV_VERIFY, NULL);
		}
	} 
}
Beispiel #12
0
__u16
listenSendMessage(Application_t *app, struct sk_buff *skb)
{
	_cmsg	*cmsg;

	cmsg = cmsg_alloc();
	if (!cmsg) {
		int_error();
		return (CAPI_MSGOSRESOURCEERR);
	}
	capi_message2cmsg(cmsg, skb->data);
	switch (CMSGCMD(cmsg)) {
		case CAPI_LISTEN_REQ:
			if (mISDN_FsmEvent(&app->listen_m, EV_LISTEN_REQ, cmsg))
				cmsg_free(cmsg);
			break;
		default:
			int_error();
			cmsg_free(cmsg);
	}
	dev_kfree_skb(skb);
	return(CAPI_NOERROR);
}
Beispiel #13
0
static void
l2_connected(struct FsmInst *fi, int event, void *arg)
{
	struct layer2	*l2 = fi->userdata;
	struct sk_buff	*skb = arg;
	int pr = -1;

	if (!get_PollFlag(l2, skb)) {
		l2_mdl_error_ua(fi, event, arg);
		return;
	}
	dev_kfree_skb(skb);
	if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
		l2_disconnect(fi, event, NULL);
	if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
		pr = DL_ESTABLISH_CNF;
	} else if (l2->vs != l2->va) {
		skb_queue_purge(&l2->i_queue);
		pr = DL_ESTABLISH_IND;
	}
	stop_t200(l2, 5);
	l2->vr = 0;
	l2->vs = 0;
	l2->va = 0;
	l2->sow = 0;
	mISDN_FsmChangeState(fi, ST_L2_7);
	mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
	if (pr != -1)
		l2up_create(l2, pr, 0, NULL);

	if (skb_queue_len(&l2->i_queue) && cansend(l2))
		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);

	if (l2->tm)
		l2_tei(l2, MDL_STATUS_UP_IND, 0);
}
Beispiel #14
0
int
l3_msg(layer3_t *l3, u_int pr, int dinfo, int len, void *arg)
{
	switch (pr) {
		case (DL_DATA | REQUEST):
			if (l3->l3m.state == ST_L3_LC_ESTAB) {
				return(l3down(l3, pr, l3_newid(l3), arg));
			} else {
				struct sk_buff *skb = arg;

//				printk(KERN_DEBUG "%s: queue skb %p len(%d)\n",
//					__FUNCTION__, skb, skb->len);
				skb_queue_tail(&l3->squeue, skb);
				mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_REQ, NULL); 
			}
			break;
		case (DL_ESTABLISH | REQUEST):
			mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_REQ, NULL);
			break;
		case (DL_ESTABLISH | CONFIRM):
			mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_CNF, NULL);
			break;
		case (DL_ESTABLISH | INDICATION):
			mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_IND, NULL);
			break;
		case (DL_RELEASE | INDICATION):
			mISDN_FsmEvent(&l3->l3m, EV_RELEASE_IND, NULL);
			break;
		case (DL_RELEASE | CONFIRM):
			mISDN_FsmEvent(&l3->l3m, EV_RELEASE_CNF, NULL);
			break;
		case (DL_RELEASE | REQUEST):
			mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL);
			break;
	}
	return(0);
}
Beispiel #15
0
int
l1_event(struct layer1 *l1, u_int event)
{
	int		err = 0;

	if (!l1)
		return -EINVAL;
	switch (event) {
	case HW_RESET_IND:
		mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
		break;
	case HW_DEACT_IND:
		mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
		break;
	case HW_POWERUP_IND:
		mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
		break;
	case HW_DEACT_CNF:
		mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
		break;
	case ANYSIGNAL:
		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
		break;
	case LOSTFRAMING:
		mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
		break;
	case INFO2:
		mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
		break;
	case INFO4_P8:
		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
		break;
	case INFO4_P10:
		mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
		break;
	case PH_ACTIVATE_REQ:
		if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
			l1->dcb(l1->dch, PH_ACTIVATE_IND);
		else {
			test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
			mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
		}
		break;
	case CLOSE_CHANNEL:
		release_l1(l1);
		break;
	default:
		if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) {
			int val = event & HW_TIMER3_VMASK;

			if (val < 5)
				val = 5;
			if (val > 30)
				val = 30;
			l1->t3_value = val;
			break;
		}
		if (*debug & DEBUG_L1)
			printk(KERN_DEBUG "%s %x unhandled\n",
			       __func__, event);
		err = -EINVAL;
	}
	return err;
}