2 * Copyright (c) 1997, 2001 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_l2if.c - Layer 3 interface to Layer 2
28 * -------------------------------------------
30 * $Id: i4b_l2if.c,v 1.23 2000/08/24 11:48:58 hm Exp $
32 * $FreeBSD: src/sys/i4b/layer3/i4b_l2if.c,v 1.6.2.2 2001/12/16 15:12:58 hm Exp $
33 * $DragonFly: src/sys/net/i4b/layer3/i4b_l2if.c,v 1.4 2003/08/07 21:17:29 dillon Exp $
35 * last edit-date: [Mon May 29 16:56:22 2000]
37 *---------------------------------------------------------------------------*/
39 #include "use_i4bq931.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
46 #include <net/i4b/include/machine/i4b_debug.h>
47 #include <net/i4b/include/machine/i4b_ioctl.h>
48 #include <net/i4b/include/machine/i4b_cause.h>
50 #include "../include/i4b_isdnq931.h"
51 #include "../include/i4b_l2l3.h"
52 #include "../include/i4b_l3l4.h"
53 #include "../include/i4b_mbuf.h"
56 #include "i4b_l3fsm.h"
60 static unsigned char make_q931_cause(cause_t cause);
62 /*---------------------------------------------------------------------------*
63 * this converts our internal state (number) to the number specified
64 * in Q.931 and is used for reporting our state in STATUS messages.
65 *---------------------------------------------------------------------------*/
66 int i4b_status_tab[] = {
85 /*---------------------------------------------------------------------------*
86 * return a valid q.931/q.850 cause from any of the internal causes
87 *---------------------------------------------------------------------------*/
89 make_q931_cause(cause_t cause)
93 switch(GET_CAUSE_TYPE(cause))
96 ret = GET_CAUSE_VAL(cause);
99 ret = cause_tab_q931[GET_CAUSE_VAL(cause)];
102 panic("make_q931_cause: unknown cause type!");
109 /*---------------------------------------------------------------------------*
110 * return status of data link
111 *---------------------------------------------------------------------------*/
113 i4b_get_dl_stat(call_desc_t *cd)
115 return(ctrl_desc[cd->controller].dl_est);
118 /*---------------------------------------------------------------------------*
119 * DL ESTABLISH INDICATION from Layer 2
120 *---------------------------------------------------------------------------*/
122 i4b_dl_establish_ind(int unit)
127 NDBGL2(L2_PRIM, "DL-ESTABLISH-IND unit %d",unit);
129 /* first set DL up in controller descriptor */
131 for(i=0; i < nctrl; i++)
133 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
134 (ctrl_desc[i].unit == unit))
136 NDBGL3(L3_MSG, "unit=%d DL established!",unit);
137 ctrl_desc[i].dl_est = DL_UP;
144 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
150 /* second, inform all (!) active call of the event */
152 for(i=0; i < N_CALL_DESC; i++)
154 if( (call_desc[i].cdid != 0) &&
155 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
156 (ctrl_desc[call_desc[i].controller].unit == unit))
158 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
159 unit, i, call_desc[i].cdid, call_desc[i].cr);
160 next_l3state(&call_desc[i], EV_DLESTIN);
167 NDBGL3(L3_ERR, "ERROR, no cdid for unit %d found!", unit);
176 /*---------------------------------------------------------------------------*
177 * DL ESTABLISH CONFIRM from Layer 2
178 *---------------------------------------------------------------------------*/
180 i4b_dl_establish_cnf(int unit)
185 NDBGL2(L2_PRIM, "DL-ESTABLISH-CONF unit %d",unit);
187 for(i=0; i < N_CALL_DESC; i++)
189 if( (call_desc[i].cdid != 0) &&
190 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
191 (ctrl_desc[call_desc[i].controller].unit == unit))
193 ctrl_desc[call_desc[i].controller].dl_est = DL_UP;
195 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
196 unit, i, call_desc[i].cdid, call_desc[i].cr);
198 next_l3state(&call_desc[i], EV_DLESTCF);
205 NDBGL3(L3_ERR, "ERROR, no cdid for unit %d found!", unit);
214 /*---------------------------------------------------------------------------*
215 * DL RELEASE INDICATION from Layer 2
216 *---------------------------------------------------------------------------*/
218 i4b_dl_release_ind(int unit)
223 NDBGL2(L2_PRIM, "DL-RELEASE-IND unit %d",unit);
225 /* first set controller to down */
227 for(i=0; i < nctrl; i++)
229 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
230 (ctrl_desc[i].unit == unit))
232 NDBGL3(L3_MSG, "unit=%d DL released!",unit);
233 ctrl_desc[i].dl_est = DL_DOWN;
240 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
246 /* second, inform all (!) active calls of the event */
248 for(i=0; i < N_CALL_DESC; i++)
250 if( (call_desc[i].cdid != 0) &&
251 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
252 (ctrl_desc[call_desc[i].controller].unit == unit))
254 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
255 unit, i, call_desc[i].cdid, call_desc[i].cr);
256 next_l3state(&call_desc[i], EV_DLRELIN);
263 /* this is not an error since it might be a normal call end */
264 NDBGL3(L3_MSG, "no cdid for unit %d found", unit);
269 /*---------------------------------------------------------------------------*
270 * DL RELEASE CONFIRM from Layer 2
271 *---------------------------------------------------------------------------*/
273 i4b_dl_release_cnf(int unit)
277 NDBGL2(L2_PRIM, "DL-RELEASE-CONF unit %d",unit);
279 for(i=0; i < nctrl; i++)
281 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
282 (ctrl_desc[i].unit == unit))
284 NDBGL3(L3_MSG, "unit=%d DL released!",unit);
285 ctrl_desc[i].dl_est = DL_DOWN;
289 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
293 /*---------------------------------------------------------------------------*
294 * i4b_dl_data_ind - process a rx'd I-frame got from layer 2
295 *---------------------------------------------------------------------------*/
297 i4b_dl_data_ind(int unit, struct mbuf *m)
300 NDBGL2(L2_PRIM, "DL-DATA-IND unit %d",unit);
302 i4b_decode_q931(unit, m->m_len, m->m_data);
307 /*---------------------------------------------------------------------------*
308 * dl_unit_data_ind - process a rx'd U-frame got from layer 2
309 *---------------------------------------------------------------------------*/
311 i4b_dl_unit_data_ind(int unit, struct mbuf *m)
314 NDBGL2(L2_PRIM, "DL-UNIT-DATA-IND unit %d",unit);
316 i4b_decode_q931(unit, m->m_len, m->m_data);
321 /*---------------------------------------------------------------------------*
322 * send CONNECT message
323 *---------------------------------------------------------------------------*/
325 i4b_l3_tx_connect(call_desc_t *cd)
330 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
332 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_CONNECT_LEN)) == NULL)
333 panic("i4b_l3_tx_connect: can't allocate mbuf\n");
335 ptr = m->m_data + I_FRAME_HDRLEN;
337 *ptr++ = PD_Q931; /* protocol discriminator */
338 *ptr++ = 0x01; /* call reference length */
339 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
340 *ptr++ = CONNECT; /* message type = connect */
342 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
345 /*---------------------------------------------------------------------------*
346 * send RELEASE COMPLETE message
347 *---------------------------------------------------------------------------*/
349 i4b_l3_tx_release_complete(call_desc_t *cd, int send_cause_flag)
353 int len = I_FRAME_HDRLEN + MSG_RELEASE_COMPLETE_LEN;
355 if(send_cause_flag == 0)
358 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x",
359 ctrl_desc[cd->controller].unit, cd->cr);
363 NDBGL3(L3_PRIM, "unit=%d, cr=0x%02x, cause=0x%x",
364 ctrl_desc[cd->controller].unit, cd->cr, cd->cause_out);
367 if((m = i4b_Dgetmbuf(len)) == NULL)
368 panic("i4b_l3_tx_release_complete: can't allocate mbuf\n");
370 ptr = m->m_data + I_FRAME_HDRLEN;
372 *ptr++ = PD_Q931; /* protocol discriminator */
373 *ptr++ = 0x01; /* call reference length */
374 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
375 *ptr++ = RELEASE_COMPLETE; /* message type = release complete */
379 *ptr++ = IEI_CAUSE; /* cause ie */
381 *ptr++ = CAUSE_STD_LOC_OUT;
382 *ptr++ = make_q931_cause(cd->cause_out);
385 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
388 /*---------------------------------------------------------------------------*
389 * send DISCONNECT message
390 *---------------------------------------------------------------------------*/
392 i4b_l3_tx_disconnect(call_desc_t *cd)
397 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
399 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_DISCONNECT_LEN)) == NULL)
400 panic("i4b_l3_tx_disconnect: can't allocate mbuf\n");
402 ptr = m->m_data + I_FRAME_HDRLEN;
404 *ptr++ = PD_Q931; /* protocol discriminator */
405 *ptr++ = 0x01; /* call ref length */
406 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
407 *ptr++ = DISCONNECT; /* message type = disconnect */
409 *ptr++ = IEI_CAUSE; /* cause ie */
411 *ptr++ = CAUSE_STD_LOC_OUT;
412 *ptr++ = make_q931_cause(cd->cause_out);
414 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
417 /*---------------------------------------------------------------------------*
419 *---------------------------------------------------------------------------*/
421 i4b_l3_tx_setup(call_desc_t *cd)
426 int slen = strlen(cd->src_telno);
427 int dlen = strlen(cd->dst_telno);
428 int klen = strlen(cd->keypad);
431 * there is one additional octet if cd->bprot == BPROT_NONE
432 * NOTE: the selection of a bearer capability by a B L1
433 * protocol is highly questionable and a better
434 * mechanism should be used in future. (-hm)
437 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
439 len = I_FRAME_HDRLEN +
441 (slen ? (3+slen) : 0) +
442 (dlen ? (3+dlen) : 0) +
443 (klen ? (2+klen) : 0) +
444 (cd->bprot == BPROT_NONE ? 1 : 0);
446 if((m = i4b_Dgetmbuf(len)) == NULL)
448 panic("i4b_l3_tx_setup: can't allocate mbuf\n");
451 cd->crflag = CRF_ORIG; /* we are the originating side */
453 ptr = m->m_data + I_FRAME_HDRLEN;
455 *ptr++ = PD_Q931; /* protocol discriminator */
456 *ptr++ = 0x01; /* call ref length */
457 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
458 *ptr++ = SETUP; /* message type = setup */
460 *ptr++ = IEI_SENDCOMPL; /* sending complete */
462 *ptr++ = IEI_BEARERCAP; /* bearer capability */
465 * currently i have no idea if this should be switched by
466 * the choosen B channel protocol or if there should be a
467 * separate configuration item for the bearer capability.
468 * For now, it is switched by the choosen b protocol (-hm)
473 case BPROT_NONE: /* telephony */
474 *ptr++ = IEI_BEARERCAP_LEN+1;
475 *ptr++ = IT_CAP_SPEECH;
476 *ptr++ = IT_RATE_64K;
477 *ptr++ = IT_UL1_G711A;
480 case BPROT_RHDLC: /* raw HDLC */
481 *ptr++ = IEI_BEARERCAP_LEN;
482 *ptr++ = IT_CAP_UNR_DIG_INFO;
483 *ptr++ = IT_RATE_64K;
487 *ptr++ = IEI_BEARERCAP_LEN;
488 *ptr++ = IT_CAP_UNR_DIG_INFO;
489 *ptr++ = IT_RATE_64K;
493 *ptr++ = IEI_CHANNELID; /* channel id */
494 *ptr++ = IEI_CHANNELID_LEN; /* channel id length */
496 switch(cd->channelid)
499 *ptr++ = CHANNELID_B1;
502 *ptr++ = CHANNELID_B2;
505 *ptr++ = CHANNELID_ANY;
511 *ptr++ = IEI_KEYPAD; /* keypad facility */
512 *ptr++ = klen; /* keypad facility length */
513 strncpy(ptr, cd->keypad, klen);
519 *ptr++ = IEI_CALLINGPN; /* calling party no */
520 *ptr++ = IEI_CALLINGPN_LEN+slen;/* calling party no length */
521 *ptr++ = NUMBER_TYPEPLAN; /* type of number, number plan id */
522 strncpy(ptr, cd->src_telno, slen);
528 *ptr++ = IEI_CALLEDPN; /* called party no */
529 *ptr++ = IEI_CALLEDPN_LEN+dlen; /* called party no length */
530 *ptr++ = NUMBER_TYPEPLAN; /* type of number, number plan id */
531 strncpy(ptr, cd->dst_telno, dlen);
535 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
538 /*---------------------------------------------------------------------------*
539 * send CONNECT ACKNOWLEDGE message
540 *---------------------------------------------------------------------------*/
542 i4b_l3_tx_connect_ack(call_desc_t *cd)
547 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
549 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_CONNECT_ACK_LEN)) == NULL)
550 panic("i4b_l3_tx_connect_ack: can't allocate mbuf\n");
552 ptr = m->m_data + I_FRAME_HDRLEN;
554 *ptr++ = PD_Q931; /* protocol discriminator */
555 *ptr++ = 0x01; /* call reference length */
556 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
557 *ptr++ = CONNECT_ACKNOWLEDGE; /* message type = connect ack */
559 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
562 /*---------------------------------------------------------------------------*
563 * send STATUS message
564 *---------------------------------------------------------------------------*/
566 i4b_l3_tx_status(call_desc_t *cd, u_char q850cause)
571 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
573 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_STATUS_LEN)) == NULL)
574 panic("i4b_l3_tx_status: can't allocate mbuf\n");
576 ptr = m->m_data + I_FRAME_HDRLEN;
578 *ptr++ = PD_Q931; /* protocol discriminator */
579 *ptr++ = 0x01; /* call reference length */
580 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
581 *ptr++ = STATUS; /* message type = connect ack */
583 *ptr++ = IEI_CAUSE; /* cause ie */
585 *ptr++ = CAUSE_STD_LOC_OUT;
586 *ptr++ = q850cause | EXT_LAST;
588 *ptr++ = IEI_CALLSTATE; /* call state ie */
589 *ptr++ = CALLSTATE_LEN;
590 *ptr++ = i4b_status_tab[cd->Q931state];
592 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
595 /*---------------------------------------------------------------------------*
596 * send RELEASE message
597 *---------------------------------------------------------------------------*/
599 i4b_l3_tx_release(call_desc_t *cd, int send_cause_flag)
603 int len = I_FRAME_HDRLEN + MSG_RELEASE_LEN;
605 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
607 if(send_cause_flag == 0)
610 if((m = i4b_Dgetmbuf(len)) == NULL)
611 panic("i4b_l3_tx_release: can't allocate mbuf\n");
613 ptr = m->m_data + I_FRAME_HDRLEN;
615 *ptr++ = PD_Q931; /* protocol discriminator */
616 *ptr++ = 0x01; /* call reference length */
617 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
618 *ptr++ = RELEASE; /* message type = release complete */
622 *ptr++ = IEI_CAUSE; /* cause ie */
624 *ptr++ = CAUSE_STD_LOC_OUT;
625 *ptr++ = make_q931_cause(cd->cause_out);
628 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
631 /*---------------------------------------------------------------------------*
632 * send ALERTING message
633 *---------------------------------------------------------------------------*/
635 i4b_l3_tx_alert(call_desc_t *cd)
640 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_ALERT_LEN)) == NULL)
641 panic("i4b_l3_tx_alert: can't allocate mbuf\n");
643 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
645 ptr = m->m_data + I_FRAME_HDRLEN;
647 *ptr++ = PD_Q931; /* protocol discriminator */
648 *ptr++ = 0x01; /* call reference length */
649 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
650 *ptr++ = ALERT; /* message type = alert */
652 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
655 #endif /* NI4BQ931 > 0 */