2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 *---------------------------------------------------------------------------
27 * i4b_l4mgmt.c - layer 4 calldescriptor management utilites
28 * -----------------------------------------------------------
30 * $Id: i4b_l4mgmt.c,v 1.34 2000/09/01 14:11:51 hm Exp $
32 * $FreeBSD: src/sys/i4b/layer4/i4b_l4mgmt.c,v 1.6.2.2 2001/08/10 14:08:43 obrien Exp $
33 * $DragonFly: src/sys/net/i4b/layer4/i4b_l4mgmt.c,v 1.7 2005/06/03 16:50:13 dillon Exp $
35 * last edit-date: [Fri Oct 13 15:58:34 2000]
37 *---------------------------------------------------------------------------*/
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/thread2.h>
48 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
49 #include <sys/callout.h>
52 #if defined(__DragonFly__) || defined(__FreeBSD__)
53 #include <net/i4b/include/machine/i4b_debug.h>
54 #include <net/i4b/include/machine/i4b_ioctl.h>
56 #include <i4b/i4b_debug.h>
57 #include <i4b/i4b_ioctl.h>
60 #include "../include/i4b_l3l4.h"
61 #include "../include/i4b_global.h"
65 call_desc_t call_desc[N_CALL_DESC]; /* call descriptor array */
67 static unsigned int get_cdid(void);
69 int nctrl; /* number of attached controllers */
71 #if defined(__DragonFly__) || (defined(__NetBSD__) && __NetBSD_Version__ >= 104230000) || defined(__FreeBSD__)
72 void i4b_init_callout(call_desc_t *);
75 /*---------------------------------------------------------------------------*
76 * return a new unique call descriptor id
77 * --------------------------------------
78 * returns a new calldescriptor id which is used to uniquely identyfy
79 * a single call in the communication between kernel and userland.
80 * this cdid is then used to associate a calldescriptor with an id.
81 *---------------------------------------------------------------------------*/
85 static unsigned int cdid_count = 0;
95 if(cdid_count == CDID_UNUSED) /* zero is invalid */
97 else if(cdid_count > CDID_MAX) /* wraparound ? */
100 /* check if id already in use */
102 for(i=0; i < N_CALL_DESC; i++)
104 if(call_desc[i].cdid == cdid_count)
116 /*---------------------------------------------------------------------------*
117 * reserve a calldescriptor for later usage
118 * ----------------------------------------
119 * searches the calldescriptor array until an unused
120 * descriptor is found, gets a new calldescriptor id
121 * and reserves it by putting the id into the cdid field.
122 * returns pointer to the calldescriptor.
123 *---------------------------------------------------------------------------*/
134 for(i=0; i < N_CALL_DESC; i++)
136 if(call_desc[i].cdid == CDID_UNUSED)
138 bzero(&call_desc[i], sizeof(call_desc_t)); /* clear it */
139 call_desc[i].cdid = get_cdid(); /* fill in new cdid */
140 cd = &(call_desc[i]); /* get pointer to descriptor */
141 NDBGL4(L4_MSG, "found free cd - index=%d cdid=%u",
142 i, call_desc[i].cdid);
150 panic("reserve_cd: no free call descriptor available!");
152 #if defined(__DragonFly__) || (defined(__NetBSD__) && __NetBSD_Version__ >= 104230000) || defined(__FreeBSD__)
153 i4b_init_callout(cd);
159 /*---------------------------------------------------------------------------*
160 * free a calldescriptor
161 * ---------------------
162 * free a unused calldescriptor by giving address of calldescriptor
163 * and writing a 0 into the cdid field marking it as unused.
164 *---------------------------------------------------------------------------*/
166 freecd_by_cd(call_desc_t *cd)
172 for(i=0; i < N_CALL_DESC; i++)
174 if( (call_desc[i].cdid != CDID_UNUSED) &&
175 (&(call_desc[i]) == cd) )
177 NDBGL4(L4_MSG, "releasing cd - index=%d cdid=%u cr=%d",
178 i, call_desc[i].cdid, cd->cr);
179 call_desc[i].cdid = CDID_UNUSED;
185 panic("freecd_by_cd: ERROR, cd not found, cr = %d\n", cd->cr);
190 /*---------------------------------------------------------------------------*
191 * return pointer to calldescriptor by giving the calldescriptor id
192 * ----------------------------------------------------------------
193 * lookup a calldescriptor in the calldescriptor array by looking
194 * at the cdid field. return pointer to calldescriptor if found,
195 * else return NULL if not found.
196 *---------------------------------------------------------------------------*/
198 cd_by_cdid(unsigned int cdid)
202 for(i=0; i < N_CALL_DESC; i++)
204 if(call_desc[i].cdid == cdid)
206 NDBGL4(L4_MSG, "found cdid - index=%d cdid=%u cr=%d",
207 i, call_desc[i].cdid, call_desc[i].cr);
208 #if defined(__DragonFly__) || (defined(__NetBSD__) && __NetBSD_Version__ >= 104230000) || defined(__FreeBSD__)
209 i4b_init_callout(&call_desc[i]);
211 return(&(call_desc[i]));
217 /*---------------------------------------------------------------------------*
218 * search calldescriptor
219 * ---------------------
220 * This routine searches for the calldescriptor for a passive controller
221 * given by unit number, callreference and callreference flag.
222 * It returns a pointer to the calldescriptor if found, else a NULL.
223 *---------------------------------------------------------------------------*/
225 cd_by_unitcr(int unit, int cr, int crf)
229 for(i=0; i < N_CALL_DESC; i++)
231 if((call_desc[i].cdid != CDID_UNUSED) &&
232 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
233 (ctrl_desc[call_desc[i].controller].unit == unit) &&
234 (call_desc[i].cr == cr) &&
235 (call_desc[i].crflag == crf) )
237 NDBGL4(L4_MSG, "found cd, index=%d cdid=%u cr=%d",
238 i, call_desc[i].cdid, call_desc[i].cr);
239 #if defined(__DragonFly__) || (defined(__NetBSD__) && __NetBSD_Version__ >= 104230000) || defined(__FreeBSD__)
240 i4b_init_callout(&call_desc[i]);
242 return(&(call_desc[i]));
248 /*---------------------------------------------------------------------------*
249 * generate 7 bit "random" number used for outgoing Call Reference
250 *---------------------------------------------------------------------------*/
252 get_rand_cr(int unit)
255 static u_char val, retval;
256 static int called = 42;
260 for(i=0; i < 50 ; i++, val++)
264 #if defined(__DragonFly__) || defined(__FreeBSD__)
267 read_random((char *)&val, sizeof(val));
269 val = (u_char)random();
270 #endif /* RANDOMDEV */
275 val ^= (time.tv_sec >> 8) ^ time.tv_usec;
277 val ^= time.tv_sec ^ (time.tv_usec >> 8);
282 if(retval == 0 || retval == 0x7f)
285 for(j=0; j < N_CALL_DESC; j++)
287 if( (call_desc[j].cdid != CDID_UNUSED) &&
288 (call_desc[j].cr == retval) )
301 /*---------------------------------------------------------------------------*
302 * initialize the callout handles for FreeBSD
303 *---------------------------------------------------------------------------*/
304 #if defined(__DragonFly__) || (defined(__NetBSD__) && __NetBSD_Version__ >= 104230000) || defined(__FreeBSD__)
306 i4b_init_callout(call_desc_t *cd)
308 if(cd->callouts_inited == 0)
310 callout_init(&cd->idle_timeout);
311 callout_init(&cd->T303_timeout);
312 callout_init(&cd->T305_timeout);
313 callout_init(&cd->T308_timeout);
314 callout_init(&cd->T309_timeout);
315 callout_init(&cd->T310_timeout);
316 callout_init(&cd->T313_timeout);
317 callout_init(&cd->T400_timeout);
318 cd->callouts_inited = 1;
323 /*---------------------------------------------------------------------------*
325 *---------------------------------------------------------------------------*/
327 i4b_l4_daemon_attached(void)
333 for(i=0; i < nctrl; i++)
335 /*XXX*/ if(ctrl_desc[i].ctrl_type == CTRL_PASSIVE)
337 NDBGL4(L4_MSG, "CMR_DOPEN sent to unit %d", ctrl_desc[i].unit);
338 (*ctrl_desc[i].N_MGMT_COMMAND)(ctrl_desc[i].unit, CMR_DOPEN, 0);
344 /*---------------------------------------------------------------------------*
346 *---------------------------------------------------------------------------*/
348 i4b_l4_daemon_detached(void)
354 for(i=0; i < nctrl; i++)
356 /*XXX*/ if(ctrl_desc[i].ctrl_type == CTRL_PASSIVE)
358 NDBGL4(L4_MSG, "CMR_DCLOSE sent to unit %d", ctrl_desc[i].unit);
359 (*ctrl_desc[i].N_MGMT_COMMAND)(ctrl_desc[i].unit, CMR_DCLOSE, 0);
365 #ifdef I4B_CD_DEBUG_PRINT
367 extern char *print_l3state(call_desc_t *cd);
369 void i4b_print_cdp(call_desc_t *cdp);
370 void i4b_print_cdx(int index);
371 void i4b_print_cda(void);
372 void i4b_print_cdaa(void);
374 /*---------------------------------------------------------------------------*
375 * print a call descriptor by cd-pointer
376 *---------------------------------------------------------------------------*/
378 i4b_print_cdp(call_desc_t *cdp)
380 if((cdp > &(call_desc[N_CALL_DESC])) || (cdp < &(call_desc[0])))
382 printf("i4b_print_cd: cdp out of range!\n");
386 printf("i4b_print_cd: printing call descriptor %d at 0x%lx:\n", cdp - (&(call_desc[0])), (unsigned long)cdp);
388 printf(" cdid = %d\n", cdp->cdid);
389 printf(" controller = %d (u=%d, dl=%d, b1=%d, b2=%d)\n",
391 ctrl_desc[cdp->controller].unit,
392 ctrl_desc[cdp->controller].dl_est,
393 ctrl_desc[cdp->controller].bch_state[CHAN_B1],
394 ctrl_desc[cdp->controller].bch_state[CHAN_B2]);
395 printf(" cr = 0x%02x\n", cdp->cr);
396 printf(" crflag = %d\n", cdp->crflag);
397 printf(" channelid = %d\n", cdp->channelid);
398 printf(" bprot = %d\n", cdp->bprot);
399 printf(" driver = %d\n", cdp->driver);
400 printf(" driver_unit = %d\n", cdp->driver_unit);
401 printf(" call_state = %d\n", cdp->call_state);
402 printf(" Q931state = %s\n", print_l3state(cdp));
403 printf(" event = %d\n", cdp->event);
404 printf(" response = %d\n", cdp->response);
405 printf(" T303 = %d\n", cdp->T303);
406 printf("T303_first_to = %d\n", cdp->T303_first_to);
407 printf(" T305 = %d\n", cdp->T305);
408 printf(" T308 = %d\n", cdp->T308);
409 printf("T308_first_to = %d\n", cdp->T308_first_to);
410 printf(" T309 = %d\n", cdp->T309);
411 printf(" T310 = %d\n", cdp->T310);
412 printf(" T313 = %d\n", cdp->T313);
413 printf(" T400 = %d\n", cdp->T400);
414 printf(" dir = %s\n", cdp->dir == DIR_OUTGOING ? "out" : "in");
417 /*---------------------------------------------------------------------------*
418 * print a call descriptor by index
419 *---------------------------------------------------------------------------*/
421 i4b_print_cdx(int index)
423 if(index >= N_CALL_DESC)
425 printf("i4b_print_cdx: index %d >= N_CALL_DESC %d\n", index, N_CALL_DESC);
428 i4b_print_cdp(&(call_desc[index]));
431 /*---------------------------------------------------------------------------*
432 * print all call descriptors
433 *---------------------------------------------------------------------------*/
439 for(i=0; i < N_CALL_DESC; i++)
441 i4b_print_cdp(&(call_desc[i]));
445 /*---------------------------------------------------------------------------*
446 * print all active call descriptors
447 *---------------------------------------------------------------------------*/
453 for(i=0; i < N_CALL_DESC; i++)
455 if(call_desc[i].cdid != CDID_UNUSED)
457 i4b_print_cdp(&(call_desc[i]));
462 #endif /* I4B_CD_DEBUG_PRINT */
464 #endif /* NI4BQ931 > 0 */