The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netisdn/i4b_l2.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: i4b_l2.c,v 1.24 2008/07/20 01:05:27 martin Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  *---------------------------------------------------------------------------
   28  *
   29  *      i4b_l2.c - ISDN layer 2 (Q.921)
   30  *      -------------------------------
   31  *
   32  *      $Id: i4b_l2.c,v 1.24 2008/07/20 01:05:27 martin Exp $
   33  *
   34  * $FreeBSD$
   35  *
   36  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   37  *
   38  *---------------------------------------------------------------------------*/
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: i4b_l2.c,v 1.24 2008/07/20 01:05:27 martin Exp $");
   42 
   43 #ifdef __FreeBSD__
   44 #include "i4bq921.h"
   45 #else
   46 #define NI4BQ921        1
   47 #endif
   48 #if NI4BQ921 > 0
   49 
   50 #include <sys/param.h>
   51 #include <sys/kernel.h>
   52 #include <sys/systm.h>
   53 #include <sys/mbuf.h>
   54 #include <sys/socket.h>
   55 #include <net/if.h>
   56 
   57 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   58 #include <sys/callout.h>
   59 #endif
   60 
   61 #ifdef __FreeBSD__
   62 #include <machine/i4b_debug.h>
   63 #include <machine/i4b_ioctl.h>
   64 #else
   65 #include <netisdn/i4b_debug.h>
   66 #include <netisdn/i4b_ioctl.h>
   67 #endif
   68 
   69 #include <netisdn/i4b_l3l4.h>
   70 #include <netisdn/i4b_l2.h>
   71 #include <netisdn/i4b_l1l2.h>
   72 #include <netisdn/i4b_isdnq931.h>
   73 #include <netisdn/i4b_mbuf.h>
   74 #include <netisdn/i4b_global.h>
   75 
   76 #include <netisdn/i4b_l2fsm.h>
   77 
   78 /* this layers debug level */
   79 
   80 unsigned int i4b_l2_debug = L2_DEBUG_DEFAULT;
   81 
   82 /*---------------------------------------------------------------------------*
   83  *      DL_ESTABLISH_REQ from layer 3
   84  *---------------------------------------------------------------------------*/
   85 int i4b_dl_establish_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv)
   86 {
   87         NDBGL2(L2_PRIM, "isdnif %d", l2sc->drv->isdnif);
   88         i4b_l1_activate(l2sc);
   89         i4b_next_l2state(l2sc, drv, EV_DLESTRQ);
   90         return(0);
   91 }
   92 
   93 /*---------------------------------------------------------------------------*
   94  *      DL_RELEASE_REQ from layer 3
   95  *---------------------------------------------------------------------------*/
   96 int i4b_dl_release_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv)
   97 {
   98         NDBGL2(L2_PRIM, "isdnif %d", l2sc->drv->isdnif);
   99         i4b_next_l2state(l2sc, drv, EV_DLRELRQ);
  100         return(0);
  101 }
  102 
  103 /*---------------------------------------------------------------------------*
  104  *      DL UNIT DATA REQUEST from Layer 3
  105  *---------------------------------------------------------------------------*/
  106 int i4b_dl_unit_data_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  107 {
  108 #ifdef NOTDEF
  109         NDBGL2(L2_PRIM, "isdnif %d", l2sc->isdnif);
  110 #endif
  111         return(0);
  112 }
  113 
  114 /*---------------------------------------------------------------------------*
  115  *      DL DATA REQUEST from Layer 3
  116  *---------------------------------------------------------------------------*/
  117 int i4b_dl_data_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  118 {
  119         switch(l2sc->Q921_state)
  120         {
  121                 case ST_AW_EST:
  122                 case ST_MULTIFR:
  123                 case ST_TIMREC:
  124 
  125                         if(IF_QFULL(&l2sc->i_queue))
  126                         {
  127                                 NDBGL2(L2_ERROR, "i_queue full!!");
  128                                 i4b_Dfreembuf(m);
  129                         }
  130                         else
  131                         {
  132                                 int s;
  133 
  134                                 s = splnet();
  135                                 IF_ENQUEUE(&l2sc->i_queue, m);
  136                                 splx(s);
  137 
  138                                 i4b_i_frame_queued_up(l2sc);
  139                         }
  140                         break;
  141 
  142                 default:
  143                         NDBGL2(L2_ERROR, "isdnif %d ERROR in state [%s], freeing mbuf", l2sc->drv->isdnif, i4b_print_l2state(l2sc));
  144                         i4b_Dfreembuf(m);
  145                         break;
  146         }
  147         return(0);
  148 }
  149 
  150 /*---------------------------------------------------------------------------*
  151  *      isdn_layer2_activate_ind - link activation/deactivation indication from layer 1
  152  *---------------------------------------------------------------------------*/
  153 int
  154 isdn_layer2_activate_ind(struct l2_softc *l2sc, struct isdn_l3_driver *drv, int event_activate)
  155 {
  156         if (event_activate) {
  157                 l2sc->ph_active = PH_ACTIVE;
  158         } else {
  159                 l2sc->ph_active = PH_INACTIVE;
  160         }
  161         return(0);
  162 }
  163 
  164 /*---------------------------------------------------------------------------*
  165  *      i4b_l2_unit_init - place layer 2 unit into known state
  166  *---------------------------------------------------------------------------*/
  167 static void
  168 i4b_l2_unit_init(l2_softc_t *l2sc)
  169 {
  170         int s;
  171 
  172         s = splnet();
  173         l2sc->Q921_state = ST_TEI_UNAS;
  174         l2sc->tei_valid = TEI_INVALID;
  175         l2sc->vr = 0;
  176         l2sc->vs = 0;
  177         l2sc->va = 0;
  178         l2sc->ack_pend = 0;
  179         l2sc->rej_excpt = 0;
  180         l2sc->peer_busy = 0;
  181         l2sc->own_busy = 0;
  182         l2sc->l3initiated = 0;
  183 
  184         l2sc->rxd_CR = 0;
  185         l2sc->rxd_PF = 0;
  186         l2sc->rxd_NR = 0;
  187         l2sc->RC = 0;
  188         l2sc->iframe_sent = 0;
  189 
  190         l2sc->postfsmfunc = NULL;
  191 
  192         if(l2sc->ua_num != UA_EMPTY)
  193         {
  194                 i4b_Dfreembuf(l2sc->ua_frame);
  195                 l2sc->ua_num = UA_EMPTY;
  196                 l2sc->ua_frame = NULL;
  197         }
  198 
  199         i4b_T200_stop(l2sc);
  200         i4b_T202_stop(l2sc);
  201         i4b_T203_stop(l2sc);
  202 
  203         splx(s);
  204 }
  205 
  206 /*---------------------------------------------------------------------------*
  207  *      isdn_layer2_status_ind - status indication upward
  208  *---------------------------------------------------------------------------*/
  209 int
  210 isdn_layer2_status_ind(l2_softc_t *l2sc, struct isdn_l3_driver *drv, int status, int parm)
  211 {
  212         int s;
  213         int sendup = 1;
  214 
  215         s = splnet();
  216 
  217         NDBGL2(L2_PRIM, "isdnif %d, status=%d, parm=%d", l2sc->drv->isdnif, status, parm);
  218 
  219         switch(status)
  220         {
  221                 case STI_ATTACH:
  222                         if (parm == 0) {
  223                                 /* detach */
  224                                 callout_stop(&l2sc->T200_callout);
  225                                 callout_stop(&l2sc->T202_callout);
  226                                 callout_stop(&l2sc->T203_callout);
  227                                 callout_stop(&l2sc->IFQU_callout);
  228                                 break;
  229                         }
  230 
  231                         l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN;
  232                         l2sc->ua_frame = NULL;
  233                         memset(&l2sc->stat, 0, sizeof(lapdstat_t));
  234 
  235                         /* initialize the callout handles for timeout routines */
  236                         callout_init(&l2sc->T200_callout, 0);
  237                         callout_init(&l2sc->T202_callout, 0);
  238                         callout_init(&l2sc->T203_callout, 0);
  239                         callout_init(&l2sc->IFQU_callout, 0);
  240 
  241                         i4b_l2_unit_init(l2sc);
  242                         break;
  243 
  244                 case STI_L1STAT:        /* state of layer 1 */
  245                         break;
  246 
  247                 case STI_PDEACT:        /* Timer 4 expired */
  248 /*XXX*/                 if((l2sc->Q921_state >= ST_AW_EST) &&
  249                            (l2sc->Q921_state <= ST_TIMREC))
  250                         {
  251                                 NDBGL2(L2_ERROR, "isdnif %d, persistent deactivation!", l2sc->drv->isdnif);
  252                                 i4b_l2_unit_init(l2sc);
  253                                 parm = -1;      /* this is passed as the new
  254                                                  * TEI to upper layers */
  255                         }
  256                         else
  257                         {
  258                                 sendup = 0;
  259                         }
  260                         break;
  261 
  262                 case STI_NOL1ACC:
  263                         i4b_l2_unit_init(l2sc);
  264                         NDBGL2(L2_ERROR, "isdnif %d, cannot access S0 bus!", l2sc->drv->isdnif);
  265                         break;
  266 
  267                 default:
  268                         NDBGL2(L2_ERROR, "ERROR, isdnif %d, unknown status message!", l2sc->drv->isdnif);
  269                         break;
  270         }
  271 
  272         if(sendup)
  273                 i4b_mdl_status_ind(l2sc->drv, status, parm);  /* send up to layer 3 */
  274 
  275         splx(s);
  276 
  277         return(0);
  278 }
  279 
  280 /*---------------------------------------------------------------------------*
  281  *      MDL_COMMAND_REQ from layer 3
  282  *---------------------------------------------------------------------------*/
  283 int i4b_mdl_command_req(struct isdn_l3_driver *drv, int command, void *parm)
  284 {
  285         struct l2_softc *sc = (l2_softc_t*)drv->l1_token;
  286 
  287         NDBGL2(L2_PRIM, "isdnif %d, command=%d, parm=%p", drv->isdnif, command, parm);
  288 
  289         switch(command)
  290         {
  291                 case CMR_DOPEN:
  292                         i4b_l2_unit_init(sc);
  293                         /* XXX - enable interrupts */
  294                         break;
  295                 case CMR_DCLOSE:
  296                         /* XXX - disable interrupts */
  297                         break;
  298         }
  299 
  300         /* pass down to layer 1 driver */
  301         if (sc->driver)
  302                 sc->driver->mph_command_req(sc->l1_token, command, parm);
  303 
  304         return(0);
  305 }
  306 
  307 /*---------------------------------------------------------------------------*
  308  * isdn_layer2_data_ind - process a rx'd frame got from layer 1
  309  *---------------------------------------------------------------------------*/
  310 int
  311 isdn_layer2_data_ind(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  312 {
  313         u_char *ptr = m->m_data;
  314 
  315         if ( (*(ptr + OFF_CNTL) & 0x01) == 0 )
  316         {
  317                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
  318                 {
  319                         l2sc->stat.err_rx_len++;
  320                         NDBGL2(L2_ERROR, "ERROR, I-frame < 6 octetts!");
  321                         i4b_Dfreembuf(m);
  322                         return(0);
  323                 }
  324                 i4b_rxd_i_frame(l2sc, drv, m);
  325         }
  326         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x01 )
  327         {
  328                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
  329                 {
  330                         l2sc->stat.err_rx_len++;
  331                         NDBGL2(L2_ERROR, "ERROR, S-frame < 6 octetts!");
  332                         i4b_Dfreembuf(m);
  333                         return(0);
  334                 }
  335                 i4b_rxd_s_frame(l2sc, drv, m);
  336         }
  337         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x03 )
  338         {
  339                 if(m->m_len < 3)        /* 5 oct - 2 chksum oct */
  340                 {
  341                         l2sc->stat.err_rx_len++;
  342                         NDBGL2(L2_ERROR, "ERROR, U-frame < 5 octetts!");
  343                         i4b_Dfreembuf(m);
  344                         return(0);
  345                 }
  346                 i4b_rxd_u_frame(l2sc, drv, m);
  347         }
  348         else
  349         {
  350                 l2sc->stat.err_rx_badf++;
  351                 NDBGL2(L2_ERROR, "ERROR, bad frame rx'd - ");
  352                 i4b_print_frame(m->m_len, m->m_data);
  353                 i4b_Dfreembuf(m);
  354         }
  355         return(0);
  356 }
  357 
  358 int i4b_l2_channel_get_state(struct isdn_l3_driver *drv, int b_chanid)
  359 {
  360         l2_softc_t *sc = drv->l1_token;
  361         return sc->bchan_state[b_chanid];
  362 }
  363 
  364 void i4b_l2_channel_set_state(struct isdn_l3_driver *drv, int b_chanid, int state)
  365 {
  366         l2_softc_t *sc = drv->l1_token;
  367         sc->bchan_state[b_chanid] = state;
  368 }
  369 
  370 /*---------------------------------------------------------------------------*
  371  *      telephony silence detection
  372  *---------------------------------------------------------------------------*/
  373 
  374 #define TEL_IDLE_MIN (BCH_MAX_DATALEN/2)
  375 
  376 int
  377 isdn_bchan_silence(unsigned char *data, int len)
  378 {
  379         register int i = 0;
  380         register int j = 0;
  381 
  382         /* count idle bytes */
  383 
  384         for(;i < len; i++)
  385         {
  386                 if((*data >= 0xaa) && (*data <= 0xac))
  387                         j++;
  388                 data++;
  389         }
  390 
  391 #ifdef NOTDEF
  392         printf("isic_hscx_silence: got %d silence bytes in frame\n", j);
  393 #endif
  394 
  395         if(j < (TEL_IDLE_MIN))
  396                 return(0);
  397         else
  398                 return(1);
  399 
  400 }
  401 
  402 
  403 #endif /* NI4BQ921 > 0 */

Cache object: 82ade61aba766d0c09e611cea734c756


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.