1/*
2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 *---------------------------------------------------------------------------
26 *
27 *	i4b_l2timer.c - layer 2 timer handling
28 *	--------------------------------------
29 *
30 *	$Id: i4b_l2timer.c,v 1.11 2006/11/16 01:33:49 christos Exp $
31 *
32 * $FreeBSD$
33 *
34 *      last edit-date: [Fri Jan  5 11:33:47 2001]
35 *
36 *---------------------------------------------------------------------------*/
37
38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: i4b_l2timer.c,v 1.10 2006/10/16 12:23:00 pooka Exp $");
40
41#ifdef __FreeBSD__
42#include "i4bq921.h"
43#else
44#define NI4BQ921	1
45#endif
46#if NI4BQ921 > 0
47
48#include <sys/param.h>
49#include <sys/kernel.h>
50#include <sys/systm.h>
51#include <sys/mbuf.h>
52#include <sys/socket.h>
53#include <net/if.h>
54
55#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
56#include <sys/callout.h>
57#endif
58
59#ifdef __FreeBSD__
60#include <machine/i4b_debug.h>
61#include <machine/i4b_ioctl.h>
62#else
63#include <netisdn/i4b_debug.h>
64#include <netisdn/i4b_ioctl.h>
65#endif
66
67#include <netisdn/i4b_global.h>
68#include <netisdn/i4b_l2.h>
69#include <netisdn/i4b_l1l2.h>
70#include <netisdn/i4b_isdnq931.h>
71#include <netisdn/i4b_mbuf.h>
72#include <netisdn/i4b_l2fsm.h>
73#include <netisdn/i4b_l3l4.h>
74
75/*---------------------------------------------------------------------------*
76 *	Q.921 timer T200 timeout function
77 *---------------------------------------------------------------------------*/
78static void
79i4b_T200_timeout(l2_softc_t *l2sc)
80{
81	NDBGL2(L2_T_ERR, "isdnif %d, RC = %d", l2sc->drv->isdnif, l2sc->RC);
82	i4b_next_l2state(l2sc, l2sc->drv, EV_T200EXP);
83}
84
85/*---------------------------------------------------------------------------*
86 *	Q.921 timer T200 start
87 *---------------------------------------------------------------------------*/
88void
89i4b_T200_start(l2_softc_t *l2sc)
90{
91	if(l2sc->T200 == TIMER_ACTIVE)
92		return;
93
94	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->drv->isdnif);
95	l2sc->T200 = TIMER_ACTIVE;
96
97	START_TIMER(l2sc->T200_callout, i4b_T200_timeout, l2sc, T200DEF);
98}
99
100/*---------------------------------------------------------------------------*
101 *	Q.921 timer T200 stop
102 *---------------------------------------------------------------------------*/
103void
104i4b_T200_stop(l2_softc_t *l2sc)
105{
106	int s;
107	s = splnet();
108	if(l2sc->T200 != TIMER_IDLE)
109	{
110		STOP_TIMER(l2sc->T200_callout, i4b_T200_timeout, l2sc);
111		l2sc->T200 = TIMER_IDLE;
112	}
113	splx(s);
114	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->drv->isdnif);
115}
116
117/*---------------------------------------------------------------------------*
118 *	Q.921 timer T200 restart
119 *---------------------------------------------------------------------------*/
120void
121i4b_T200_restart(l2_softc_t *l2sc)
122{
123	int s;
124	s = splnet();
125	if(l2sc->T200 != TIMER_IDLE)
126	{
127		STOP_TIMER(l2sc->T200_callout, i4b_T200_timeout, l2sc);
128	}
129	else
130	{
131		l2sc->T200 = TIMER_ACTIVE;
132	}
133
134	START_TIMER(l2sc->T200_callout, i4b_T200_timeout, l2sc, T200DEF);
135	splx(s);
136	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->drv->isdnif);
137}
138
139/*---------------------------------------------------------------------------*
140 *	Q.921 timer T202 timeout function
141 *---------------------------------------------------------------------------*/
142static void
143i4b_T202_timeout(l2_softc_t *l2sc)
144{
145	NDBGL2(L2_T_ERR, "isdnif %d, N202 = %d", l2sc->drv->isdnif, l2sc->N202);
146
147	if(--(l2sc->N202))
148	{
149		(*l2sc->T202func)(l2sc);
150	}
151}
152
153/*---------------------------------------------------------------------------*
154 *	Q.921 timer T202 start
155 *---------------------------------------------------------------------------*/
156void
157i4b_T202_start(l2_softc_t *l2sc)
158{
159	if (l2sc->N202 == TIMER_ACTIVE)
160		return;
161
162	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->drv->isdnif);
163	l2sc->N202 = N202DEF;
164	l2sc->T202 = TIMER_ACTIVE;
165
166	START_TIMER(l2sc->T202_callout, i4b_T202_timeout, l2sc, T202DEF);
167}
168
169/*---------------------------------------------------------------------------*
170 *	Q.921 timer T202 stop
171 *---------------------------------------------------------------------------*/
172void
173i4b_T202_stop(l2_softc_t *l2sc)
174{
175	int s;
176	s = splnet();
177	if(l2sc->T202 != TIMER_IDLE)
178	{
179		STOP_TIMER(l2sc->T202_callout, i4b_T202_timeout, l2sc);
180		l2sc->T202 = TIMER_IDLE;
181	}
182	splx(s);
183	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->drv->isdnif);
184}
185
186/*---------------------------------------------------------------------------*
187 *	Q.921 timer T203 timeout function
188 *---------------------------------------------------------------------------*/
189#if I4B_T203_ACTIVE
190static void
191i4b_T203_timeout(l2_softc_t *l2sc)
192{
193	NDBGL2(L2_T_ERR, "isdnif %d", l2sc->isdnif);
194	i4b_next_l2state(l2sc, EV_T203EXP);
195}
196#endif
197
198/*---------------------------------------------------------------------------*
199 *	Q.921 timer T203 start
200 *---------------------------------------------------------------------------*/
201void
202i4b_T203_start(l2_softc_t *l2sc)
203{
204#if I4B_T203_ACTIVE
205	if (l2sc->T203 == TIMER_ACTIVE)
206		return;
207
208	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->isdnif);
209	l2sc->T203 = TIMER_ACTIVE;
210
211	START_TIMER(l2sc->T203_callout, i4b_T203_timeout, l2sc, T203DEF);
212#endif
213}
214
215/*---------------------------------------------------------------------------*
216 *	Q.921 timer T203 stop
217 *---------------------------------------------------------------------------*/
218void
219i4b_T203_stop(l2_softc_t *l2sc)
220{
221#if I4B_T203_ACTIVE
222	int s;
223	s = splnet();
224	if(l2sc->T203 != TIMER_IDLE)
225	{
226		STOP_TIMER(l2sc->T203_callout, i4b_T203_timeout, l2sc);
227		l2sc->T203 = TIMER_IDLE;
228	}
229	splx(s);
230	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->isdnif);
231#endif
232}
233
234/*---------------------------------------------------------------------------*
235 *	Q.921 timer T203 restart
236 *---------------------------------------------------------------------------*/
237void
238i4b_T203_restart(l2_softc_t *l2sc)
239{
240#if I4B_T203_ACTIVE
241	int s;
242	s = splnet();
243
244	if(l2sc->T203 != TIMER_IDLE)
245	{
246		STOP_TIMER(l2sc->T203_callout, i4b_T203_timerout, l2sc);
247	}
248	else
249	{
250		l2sc->T203 = TIMER_ACTIVE;
251	}
252
253	START_TIMER(l2sc->T203_callout, i4b_T203_timerout, l2sc, T203DEF);
254	splx(s);
255	NDBGL2(L2_T_MSG, "isdnif %d", l2sc->isdnif);
256#endif
257}
258
259#endif /* NI4BQ921 > 0 */
260