2 * Copyright (c) 1997, 2002 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
26 /*---------------------------------------------------------------------------
28 * i4b_l2if.c - Layer 3 interface to Layer 2
29 * -------------------------------------------
30 * last edit-date: [Sun Aug 11 12:48:41 2002]
32 *---------------------------------------------------------------------------*/
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
37 #include <sys/param.h>
38 #include <sys/systm.h>
41 #include <i4b/include/i4b_debug.h>
42 #include <i4b/include/i4b_ioctl.h>
43 #include <i4b/include/i4b_cause.h>
45 #include <i4b/include/i4b_isdnq931.h>
46 #include <i4b/include/i4b_l2l3.h>
47 #include <i4b/include/i4b_l3l4.h>
48 #include <i4b/include/i4b_mbuf.h>
50 #include <i4b/layer3/i4b_l3.h>
51 #include <i4b/layer3/i4b_l3fsm.h>
52 #include <i4b/layer3/i4b_q931.h>
55 static unsigned char make_q931_cause(cause_t cause);
57 /*---------------------------------------------------------------------------*
58 * this converts our internal state (number) to the number specified
59 * in Q.931 and is used for reporting our state in STATUS messages.
60 *---------------------------------------------------------------------------*/
61 int i4b_status_tab[] = {
80 /*---------------------------------------------------------------------------*
81 * return a valid q.931/q.850 cause from any of the internal causes
82 *---------------------------------------------------------------------------*/
84 make_q931_cause(cause_t cause)
86 register unsigned char ret;
88 switch(GET_CAUSE_TYPE(cause))
91 ret = GET_CAUSE_VAL(cause);
94 ret = cause_tab_q931[GET_CAUSE_VAL(cause)];
97 panic("make_q931_cause: unknown cause type!");
104 /*---------------------------------------------------------------------------*
105 * return status of data link
106 *---------------------------------------------------------------------------*/
108 i4b_get_dl_stat(call_desc_t *cd)
110 return(ctrl_desc[cd->controller].dl_est);
113 /*---------------------------------------------------------------------------*
114 * DL ESTABLISH INDICATION from Layer 2
115 *---------------------------------------------------------------------------*/
117 i4b_dl_establish_ind(int unit)
122 NDBGL2(L2_PRIM, "DL-ESTABLISH-IND unit %d",unit);
124 /* first set DL up in controller descriptor */
126 for(i=0; i < nctrl; i++)
128 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
129 (ctrl_desc[i].unit == unit))
131 NDBGL3(L3_MSG, "unit=%d DL established!",unit);
132 ctrl_desc[i].dl_est = DL_UP;
139 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
145 /* second, inform all (!) active call of the event */
147 for(i=0; i < N_CALL_DESC; i++)
149 if( (call_desc[i].cdid != 0) &&
150 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
151 (ctrl_desc[call_desc[i].controller].unit == unit))
153 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
154 unit, i, call_desc[i].cdid, call_desc[i].cr);
155 next_l3state(&call_desc[i], EV_DLESTIN);
162 NDBGL3(L3_ERR, "ERROR, no cdid for unit %d found!", unit);
171 /*---------------------------------------------------------------------------*
172 * DL ESTABLISH CONFIRM from Layer 2
173 *---------------------------------------------------------------------------*/
175 i4b_dl_establish_cnf(int unit)
180 NDBGL2(L2_PRIM, "DL-ESTABLISH-CONF unit %d",unit);
182 for(i=0; i < N_CALL_DESC; i++)
184 if( (call_desc[i].cdid != 0) &&
185 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
186 (ctrl_desc[call_desc[i].controller].unit == unit))
188 ctrl_desc[call_desc[i].controller].dl_est = DL_UP;
190 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
191 unit, i, call_desc[i].cdid, call_desc[i].cr);
193 next_l3state(&call_desc[i], EV_DLESTCF);
200 NDBGL3(L3_ERR, "ERROR, no cdid for unit %d found!", unit);
209 /*---------------------------------------------------------------------------*
210 * DL RELEASE INDICATION from Layer 2
211 *---------------------------------------------------------------------------*/
213 i4b_dl_release_ind(int unit)
218 NDBGL2(L2_PRIM, "DL-RELEASE-IND unit %d",unit);
220 /* first set controller to down */
222 for(i=0; i < nctrl; i++)
224 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
225 (ctrl_desc[i].unit == unit))
227 NDBGL3(L3_MSG, "unit=%d DL released!",unit);
228 ctrl_desc[i].dl_est = DL_DOWN;
235 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
241 /* second, inform all (!) active calls of the event */
243 for(i=0; i < N_CALL_DESC; i++)
245 if( (call_desc[i].cdid != 0) &&
246 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
247 (ctrl_desc[call_desc[i].controller].unit == unit))
249 NDBGL3(L3_MSG, "unit=%d, index=%d cdid=%u cr=%d",
250 unit, i, call_desc[i].cdid, call_desc[i].cr);
251 next_l3state(&call_desc[i], EV_DLRELIN);
258 /* this is not an error since it might be a normal call end */
259 NDBGL3(L3_MSG, "no cdid for unit %d found", unit);
264 /*---------------------------------------------------------------------------*
265 * DL RELEASE CONFIRM from Layer 2
266 *---------------------------------------------------------------------------*/
268 i4b_dl_release_cnf(int unit)
272 NDBGL2(L2_PRIM, "DL-RELEASE-CONF unit %d",unit);
274 for(i=0; i < nctrl; i++)
276 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
277 (ctrl_desc[i].unit == unit))
279 NDBGL3(L3_MSG, "unit=%d DL released!",unit);
280 ctrl_desc[i].dl_est = DL_DOWN;
284 NDBGL3(L3_ERR, "ERROR, controller not found for unit=%d!",unit);
288 /*---------------------------------------------------------------------------*
289 * i4b_dl_data_ind - process a rx'd I-frame got from layer 2
290 *---------------------------------------------------------------------------*/
292 i4b_dl_data_ind(int unit, struct mbuf *m)
295 NDBGL2(L2_PRIM, "DL-DATA-IND unit %d",unit);
297 i4b_decode_q931(unit, m->m_len, m->m_data);
302 /*---------------------------------------------------------------------------*
303 * dl_unit_data_ind - process a rx'd U-frame got from layer 2
304 *---------------------------------------------------------------------------*/
306 i4b_dl_unit_data_ind(int unit, struct mbuf *m)
309 NDBGL2(L2_PRIM, "DL-UNIT-DATA-IND unit %d",unit);
311 i4b_decode_q931(unit, m->m_len, m->m_data);
316 /*---------------------------------------------------------------------------*
317 * send CONNECT message
318 *---------------------------------------------------------------------------*/
320 i4b_l3_tx_connect(call_desc_t *cd)
325 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
327 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_CONNECT_LEN)) == NULL)
328 panic("i4b_l3_tx_connect: can't allocate mbuf\n");
330 ptr = m->m_data + I_FRAME_HDRLEN;
332 *ptr++ = PD_Q931; /* protocol discriminator */
333 *ptr++ = 0x01; /* call reference length */
334 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
335 *ptr++ = CONNECT; /* message type = connect */
337 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
340 /*---------------------------------------------------------------------------*
341 * send RELEASE COMPLETE message
342 *---------------------------------------------------------------------------*/
344 i4b_l3_tx_release_complete(call_desc_t *cd, int send_cause_flag)
348 int len = I_FRAME_HDRLEN + MSG_RELEASE_COMPLETE_LEN;
350 if(send_cause_flag == 0)
353 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x",
354 ctrl_desc[cd->controller].unit, cd->cr);
358 NDBGL3(L3_PRIM, "unit=%d, cr=0x%02x, cause=0x%x",
359 ctrl_desc[cd->controller].unit, cd->cr, cd->cause_out);
362 if((m = i4b_Dgetmbuf(len)) == NULL)
363 panic("i4b_l3_tx_release_complete: can't allocate mbuf\n");
365 ptr = m->m_data + I_FRAME_HDRLEN;
367 *ptr++ = PD_Q931; /* protocol discriminator */
368 *ptr++ = 0x01; /* call reference length */
369 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
370 *ptr++ = RELEASE_COMPLETE; /* message type = release complete */
374 *ptr++ = IEI_CAUSE; /* cause ie */
376 *ptr++ = CAUSE_STD_LOC_OUT;
377 *ptr++ = make_q931_cause(cd->cause_out);
380 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
383 /*---------------------------------------------------------------------------*
384 * send DISCONNECT message
385 *---------------------------------------------------------------------------*/
387 i4b_l3_tx_disconnect(call_desc_t *cd)
392 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
394 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_DISCONNECT_LEN)) == NULL)
395 panic("i4b_l3_tx_disconnect: can't allocate mbuf\n");
397 ptr = m->m_data + I_FRAME_HDRLEN;
399 *ptr++ = PD_Q931; /* protocol discriminator */
400 *ptr++ = 0x01; /* call ref length */
401 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
402 *ptr++ = DISCONNECT; /* message type = disconnect */
404 *ptr++ = IEI_CAUSE; /* cause ie */
406 *ptr++ = CAUSE_STD_LOC_OUT;
407 *ptr++ = make_q931_cause(cd->cause_out);
409 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
412 /*---------------------------------------------------------------------------*
414 *---------------------------------------------------------------------------*/
416 i4b_l3_tx_setup(call_desc_t *cd)
421 int slen = strlen(cd->src_telno);
422 int sslen = strlen(cd->src_subaddr);
423 int dlen = strlen(cd->dst_telno);
424 int dslen = strlen(cd->dst_subaddr);
425 int klen = strlen(cd->keypad);
428 * there is one additional octet if cd->bprot == BPROT_NONE
429 * NOTE: the selection of a bearer capability by a B L1
430 * protocol is highly questionable and a better
431 * mechanism should be used in future. (-hm)
434 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
436 len = I_FRAME_HDRLEN +
438 (slen ? (3+slen) : 0) +
439 (sslen ? (3+sslen) : 0) +
440 (dlen ? (3+dlen) : 0) +
441 (dslen ? (3+dslen) : 0) +
442 (klen ? (2+klen) : 0) +
443 (cd->bprot == BPROT_NONE ? 1 : 0);
445 if((m = i4b_Dgetmbuf(len)) == NULL)
447 panic("i4b_l3_tx_setup: can't allocate mbuf\n");
450 cd->crflag = CRF_ORIG; /* we are the originating side */
452 ptr = m->m_data + I_FRAME_HDRLEN;
454 *ptr++ = PD_Q931; /* protocol discriminator */
455 *ptr++ = 0x01; /* call ref length */
456 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
457 *ptr++ = SETUP; /* message type = setup */
459 *ptr++ = IEI_SENDCOMPL; /* sending complete */
461 *ptr++ = IEI_BEARERCAP; /* bearer capability */
464 * currently i have no idea if this should be switched by
465 * the choosen B channel protocol or if there should be a
466 * separate configuration item for the bearer capability.
467 * For now, it is switched by the choosen b protocol (-hm)
472 case BPROT_NONE: /* telephony */
473 *ptr++ = IEI_BEARERCAP_LEN+1;
474 *ptr++ = IT_CAP_SPEECH;
475 *ptr++ = IT_RATE_64K;
476 *ptr++ = IT_UL1_G711A;
479 case BPROT_RHDLC: /* raw HDLC */
480 if (cd->bcap == BCAP_DOV) /* Data over Voice */
482 *ptr++ = IEI_BEARERCAP_LEN+1;
483 *ptr++ = IT_CAP_SPEECH;
484 *ptr++ = IT_RATE_64K;
485 *ptr++ = IT_UL1_G711A;
489 *ptr++ = IEI_BEARERCAP_LEN;
490 *ptr++ = IT_CAP_UNR_DIG_INFO;
491 *ptr++ = IT_RATE_64K;
496 *ptr++ = IEI_BEARERCAP_LEN;
497 *ptr++ = IT_CAP_UNR_DIG_INFO;
498 *ptr++ = IT_RATE_64K;
502 *ptr++ = IEI_CHANNELID; /* channel id */
503 *ptr++ = IEI_CHANNELID_LEN; /* channel id length */
505 switch(cd->channelid)
508 *ptr++ = CHANNELID_B1;
511 *ptr++ = CHANNELID_B2;
514 *ptr++ = CHANNELID_ANY;
520 *ptr++ = IEI_KEYPAD; /* keypad facility */
521 *ptr++ = klen; /* keypad facility length */
522 strncpy(ptr, cd->keypad, klen);
528 *ptr++ = IEI_CALLINGPN; /* calling party no */
529 *ptr++ = IEI_CALLINGPN_LEN+slen;/* calling party no length */
530 *ptr++ = NUMBER_TYPEPLAN; /* type of number, number plan id */
531 strncpy(ptr, cd->src_telno, slen);
537 *ptr++ = IEI_CALLINGPS; /* calling subaddr */
538 *ptr++ = IEI_CALLINGPS_LEN+sslen; /* calling subaddr len */
539 *ptr++ = SUBADDR_TYPE_NSAP; /* type = NSAP */
540 strncpy(ptr, cd->src_subaddr, sslen);
546 *ptr++ = IEI_CALLEDPN; /* called party no */
547 *ptr++ = IEI_CALLEDPN_LEN+dlen; /* called party no length */
548 *ptr++ = NUMBER_TYPEPLAN; /* type of number, number plan id */
549 strncpy(ptr, cd->dst_telno, dlen);
555 *ptr++ = IEI_CALLEDPS; /* calling party subaddr */
556 *ptr++ = IEI_CALLEDPS_LEN+dslen;/* calling party subaddr len */
557 *ptr++ = SUBADDR_TYPE_NSAP; /* type = NSAP */
558 strncpy(ptr, cd->dst_subaddr, dslen);
562 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
565 /*---------------------------------------------------------------------------*
566 * send CONNECT ACKNOWLEDGE message
567 *---------------------------------------------------------------------------*/
569 i4b_l3_tx_connect_ack(call_desc_t *cd)
574 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
576 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_CONNECT_ACK_LEN)) == NULL)
577 panic("i4b_l3_tx_connect_ack: can't allocate mbuf\n");
579 ptr = m->m_data + I_FRAME_HDRLEN;
581 *ptr++ = PD_Q931; /* protocol discriminator */
582 *ptr++ = 0x01; /* call reference length */
583 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
584 *ptr++ = CONNECT_ACKNOWLEDGE; /* message type = connect ack */
586 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
589 /*---------------------------------------------------------------------------*
590 * send STATUS message
591 *---------------------------------------------------------------------------*/
593 i4b_l3_tx_status(call_desc_t *cd, u_char q850cause)
598 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
600 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_STATUS_LEN)) == NULL)
601 panic("i4b_l3_tx_status: can't allocate mbuf\n");
603 ptr = m->m_data + I_FRAME_HDRLEN;
605 *ptr++ = PD_Q931; /* protocol discriminator */
606 *ptr++ = 0x01; /* call reference length */
607 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
608 *ptr++ = STATUS; /* message type = connect ack */
610 *ptr++ = IEI_CAUSE; /* cause ie */
612 *ptr++ = CAUSE_STD_LOC_OUT;
613 *ptr++ = q850cause | EXT_LAST;
615 *ptr++ = IEI_CALLSTATE; /* call state ie */
616 *ptr++ = CALLSTATE_LEN;
617 *ptr++ = i4b_status_tab[cd->Q931state];
619 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
622 /*---------------------------------------------------------------------------*
623 * send RELEASE message
624 *---------------------------------------------------------------------------*/
626 i4b_l3_tx_release(call_desc_t *cd, int send_cause_flag)
630 int len = I_FRAME_HDRLEN + MSG_RELEASE_LEN;
632 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
634 if(send_cause_flag == 0)
637 if((m = i4b_Dgetmbuf(len)) == NULL)
638 panic("i4b_l3_tx_release: can't allocate mbuf\n");
640 ptr = m->m_data + I_FRAME_HDRLEN;
642 *ptr++ = PD_Q931; /* protocol discriminator */
643 *ptr++ = 0x01; /* call reference length */
644 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
645 *ptr++ = RELEASE; /* message type = release complete */
649 *ptr++ = IEI_CAUSE; /* cause ie */
651 *ptr++ = CAUSE_STD_LOC_OUT;
652 *ptr++ = make_q931_cause(cd->cause_out);
655 DL_Data_Req(ctrl_desc[cd->controller].unit, m);
658 /*---------------------------------------------------------------------------*
659 * send ALERTING message
660 *---------------------------------------------------------------------------*/
662 i4b_l3_tx_alert(call_desc_t *cd)
667 if((m = i4b_Dgetmbuf(I_FRAME_HDRLEN + MSG_ALERT_LEN)) == NULL)
668 panic("i4b_l3_tx_alert: can't allocate mbuf\n");
670 NDBGL3(L3_PRIM, "unit %d, cr = 0x%02x", ctrl_desc[cd->controller].unit, cd->cr);
672 ptr = m->m_data + I_FRAME_HDRLEN;
674 *ptr++ = PD_Q931; /* protocol discriminator */
675 *ptr++ = 0x01; /* call reference length */
676 *ptr++ = setup_cr(cd, cd->cr); /* call reference value */
677 *ptr++ = ALERT; /* message type = alert */
679 DL_Data_Req(ctrl_desc[cd->controller].unit, m);