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_l4if.c - Layer 3 interface to Layer 4
28 * -------------------------------------------
30 * $Id: i4b_l4if.c,v 1.19 2005/12/11 12:25:06 christos Exp $
34 * last edit-date: [Fri Jan 5 11:33:47 2001]
36 *---------------------------------------------------------------------------*/
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: i4b_l4if.c,v 1.14.2.4 2005/03/04 16:53:45 skrll Exp $");
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
52 #include <sys/socket.h>
55 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
56 #include <sys/callout.h>
60 #include <machine/i4b_debug.h>
61 #include <machine/i4b_ioctl.h>
62 #include <machine/i4b_cause.h>
64 #include <netisdn/i4b_debug.h>
65 #include <netisdn/i4b_ioctl.h>
66 #include <netisdn/i4b_cause.h>
69 #include <netisdn/i4b_isdnq931.h>
70 #include <netisdn/i4b_l2.h>
71 #include <netisdn/i4b_l1l2.h>
72 #include <netisdn/i4b_l3l4.h>
73 #include <netisdn/i4b_mbuf.h>
74 #include <netisdn/i4b_global.h>
76 #include <netisdn/i4b_l3.h>
77 #include <netisdn/i4b_l3fsm.h>
78 #include <netisdn/i4b_q931.h>
80 #include <netisdn/i4b_l4.h>
82 void n_connect_request(struct call_desc
*cd
);
83 void n_connect_response(struct call_desc
*cd
, int response
, int cause
);
84 void n_disconnect_request(struct call_desc
*cd
, int cause
);
85 void n_alert_request(struct call_desc
*cd
);
86 void n_mgmt_command(struct isdn_l3_driver
*drv
, int cmd
, void *parm
);
88 /*---------------------------------------------------------------------------*
89 * i4b_mdl_status_ind - status indication from lower layers
90 *---------------------------------------------------------------------------*/
92 i4b_mdl_status_ind(struct isdn_l3_driver
*d
, int status
, int parm
)
94 int sendup
, update_leds
= 0;
97 NDBGL3(L3_MSG
, "isdnif = %d, status = %d, parm = %d",
98 d
->isdnif
, status
, parm
);
104 NDBGL3(L3_MSG
, "STI_ATTACH: attaching isdnif %d", d
->isdnif
);
106 NDBGL3(L3_MSG
, "STI_ATTACH: dettaching isdnif %d", d
->isdnif
);
111 i4b_l4_l12stat(d
, 1, parm
);
113 NDBGL3(L3_MSG
, "STI_L1STAT: isdnif %d layer 1 = %s", d
->isdnif
, status
? "up" : "down");
117 i4b_l4_l12stat(d
, 2, parm
);
119 NDBGL3(L3_MSG
, "STI_L2STAT: isdnif %d layer 2 = %s", d
->isdnif
, status
? "up" : "down");
124 i4b_l4_teiasg(d
, parm
);
126 NDBGL3(L3_MSG
, "STI_TEIASG: isdnif %d TEI = %d = 0x%02x", d
->isdnif
, parm
, parm
);
129 case STI_PDEACT
: /* L1 T4 timeout */
130 NDBGL3(L3_ERR
, "STI_PDEACT: isdnif %d TEI = %d = 0x%02x", d
->isdnif
, parm
, parm
);
135 for(i
=0; i
< num_call_desc
; i
++)
137 if(call_desc
[i
].isdnif
== d
->isdnif
)
139 i4b_l3_stop_all_timers(&(call_desc
[i
]));
140 if(call_desc
[i
].cdid
!= CDID_UNUSED
) {
142 call_desc
[i
].cdid
= CDID_UNUSED
;
149 for (i
= 0; i
< d
->nbch
; i
++)
150 d
->bch_state
[i
] = BCH_ST_FREE
;
155 i4b_l4_pdeact(d
, sendup
);
159 case STI_NOL1ACC
: /* no outgoing access to S0 */
160 NDBGL3(L3_ERR
, "STI_NOL1ACC: isdnif %d no outgoing access to S0", d
->isdnif
);
163 for(i
=0; i
< num_call_desc
; i
++)
165 if(call_desc
[i
].isdnif
== d
->isdnif
)
167 if(call_desc
[i
].cdid
!= CDID_UNUSED
)
169 SET_CAUSE_TYPE(call_desc
[i
].cause_in
, CAUSET_I4B
);
170 SET_CAUSE_VAL(call_desc
[i
].cause_in
, CAUSE_I4B_L1ERROR
);
171 i4b_l4_disconnect_ind(&(call_desc
[i
]));
177 for (i
= 0; i
< d
->nbch
; i
++)
178 d
->bch_state
[i
] = BCH_ST_FREE
;
184 NDBGL3(L3_ERR
, "ERROR, isdnif %d, unknown status value %d!", d
->isdnif
, status
);
188 if (update_leds
&& d
!= NULL
)
189 update_controller_leds(d
);
195 update_controller_leds(struct isdn_l3_driver
*d
)
201 if (d
->bch_state
[CHAN_B1
] != BCH_ST_FREE
)
203 if (d
->bch_state
[CHAN_B2
] != BCH_ST_FREE
)
206 d
->l3driver
->N_MGMT_COMMAND(d
, CMR_SETLEDS
, (void*)leds
);
209 /*---------------------------------------------------------------------------*
210 * send command to the lower layers
211 *---------------------------------------------------------------------------*/
213 n_mgmt_command(struct isdn_l3_driver
*d
, int cmd
, void *parm
)
220 NDBGL3(L3_MSG
, "CMR_DOPEN for isdnif %d", d
->isdnif
);
222 for(i
=0; i
< num_call_desc
; i
++)
224 if(call_desc
[i
].isdnif
== d
->isdnif
)
226 call_desc
[i
].cdid
= CDID_UNUSED
;
230 for (i
= 0; i
< d
->nbch
; i
++)
231 d
->bch_state
[i
] = BCH_ST_FREE
;
237 NDBGL3(L3_MSG
, "CMR_DCLOSE for isdnif %d", d
->isdnif
);
241 NDBGL3(L3_MSG
, "unknown cmd %d for isdnif %d",
246 i4b_mdl_command_req(d
, cmd
, parm
);
249 /*---------------------------------------------------------------------------*
250 * handle connect request message from userland
251 *---------------------------------------------------------------------------*/
253 n_connect_request(struct call_desc
*cd
)
255 next_l3state(cd
, EV_SETUPRQ
);
258 /*---------------------------------------------------------------------------*
259 * handle setup response message from userland
260 *---------------------------------------------------------------------------*/
262 n_connect_response(struct call_desc
*cd
, int response
, int cause
)
264 struct isdn_l3_driver
*d
= cd
->l3drv
;
269 cd
->response
= response
;
270 cd
->cause_out
= cause
;
274 case SETUP_RESP_ACCEPT
:
275 next_l3state(cd
, EV_SETACRS
);
276 chstate
= BCH_ST_USED
;
279 case SETUP_RESP_REJECT
:
280 next_l3state(cd
, EV_SETRJRS
);
281 chstate
= BCH_ST_FREE
;
284 case SETUP_RESP_DNTCRE
:
285 next_l3state(cd
, EV_SETDCRS
);
286 chstate
= BCH_ST_FREE
;
289 default: /* failsafe */
290 next_l3state(cd
, EV_SETDCRS
);
291 chstate
= BCH_ST_FREE
;
292 NDBGL3(L3_ERR
, "unknown response, doing SETUP_RESP_DNTCRE");
296 if((cd
->channelid
>= 0) && (cd
->channelid
< d
->nbch
))
298 d
->bch_state
[cd
->channelid
] = chstate
;
300 * XXX: don't call l2 function for active cards
302 if (d
->l3driver
->N_DOWNLOAD
== NULL
)
303 i4b_l2_channel_set_state(cd
->l3drv
,
304 cd
->channelid
, chstate
);
305 update_controller_leds(d
);
309 NDBGL3(L3_MSG
, "Warning, invalid channelid %d, response = %d\n", cd
->channelid
, response
);
313 /*---------------------------------------------------------------------------*
314 * handle disconnect request message from userland
315 *---------------------------------------------------------------------------*/
317 n_disconnect_request(struct call_desc
*cd
, int cause
)
319 cd
->cause_out
= cause
;
321 next_l3state(cd
, EV_DISCRQ
);
324 /*---------------------------------------------------------------------------*
325 * handle alert request message from userland
326 *---------------------------------------------------------------------------*/
328 n_alert_request(struct call_desc
*cd
)
330 next_l3state(cd
, EV_ALERTRQ
);
333 #endif /* NI4BQ931 > 0 */