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.17 2005/02/26 22:39:49 perry 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.17 2005/02/26 22:39:49 perry 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.17 2005/02/26 22:39:49 perry 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_l2.h>
   77 #include <netisdn/i4b_l2fsm.h>
   78 
   79 /* this layers debug level */
   80 
   81 unsigned int i4b_l2_debug = L2_DEBUG_DEFAULT;
   82 
   83 /*---------------------------------------------------------------------------*
   84  *      DL_ESTABLISH_REQ from layer 3
   85  *---------------------------------------------------------------------------*/
   86 int i4b_dl_establish_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv)
   87 {
   88         NDBGL2(L2_PRIM, "isdnif %d", l2sc->drv->isdnif);
   89         i4b_l1_activate(l2sc);
   90         i4b_next_l2state(l2sc, drv, EV_DLESTRQ);
   91         return(0);
   92 }
   93 
   94 /*---------------------------------------------------------------------------*
   95  *      DL_RELEASE_REQ from layer 3
   96  *---------------------------------------------------------------------------*/
   97 int i4b_dl_release_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv)
   98 {
   99         NDBGL2(L2_PRIM, "isdnif %d", l2sc->drv->isdnif);
  100         i4b_next_l2state(l2sc, drv, EV_DLRELRQ);
  101         return(0);
  102 }
  103 
  104 /*---------------------------------------------------------------------------*
  105  *      DL UNIT DATA REQUEST from Layer 3
  106  *---------------------------------------------------------------------------*/
  107 int i4b_dl_unit_data_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  108 {
  109 #ifdef NOTDEF
  110         NDBGL2(L2_PRIM, "isdnif %d", l2sc->isdnif);
  111 #endif
  112         return(0);
  113 }
  114 
  115 /*---------------------------------------------------------------------------*
  116  *      DL DATA REQUEST from Layer 3
  117  *---------------------------------------------------------------------------*/
  118 int i4b_dl_data_req(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  119 {
  120         switch(l2sc->Q921_state)
  121         {
  122                 case ST_AW_EST:
  123                 case ST_MULTIFR:
  124                 case ST_TIMREC:
  125 
  126                         if(IF_QFULL(&l2sc->i_queue))
  127                         {
  128                                 NDBGL2(L2_ERROR, "i_queue full!!");
  129                                 i4b_Dfreembuf(m);
  130                         }
  131                         else
  132                         {
  133                                 int s;
  134 
  135                                 s = splnet();
  136                                 IF_ENQUEUE(&l2sc->i_queue, m);
  137                                 splx(s);
  138 
  139                                 i4b_i_frame_queued_up(l2sc);
  140                         }
  141                         break;
  142 
  143                 default:
  144                         NDBGL2(L2_ERROR, "isdnif %d ERROR in state [%s], freeing mbuf", l2sc->drv->isdnif, i4b_print_l2state(l2sc));
  145                         i4b_Dfreembuf(m);
  146                         break;
  147         }
  148         return(0);
  149 }
  150 
  151 /*---------------------------------------------------------------------------*
  152  *      isdn_layer2_activate_ind - link activation/deactivation indication from layer 1
  153  *---------------------------------------------------------------------------*/
  154 int
  155 isdn_layer2_activate_ind(struct l2_softc *l2sc, struct isdn_l3_driver *drv, int event_activate)
  156 {
  157         if (event_activate) {
  158                 l2sc->ph_active = PH_ACTIVE;
  159         } else {
  160                 l2sc->ph_active = PH_INACTIVE;
  161         }
  162         return(0);
  163 }
  164 
  165 /*---------------------------------------------------------------------------*
  166  *      i4b_l2_unit_init - place layer 2 unit into known state
  167  *---------------------------------------------------------------------------*/
  168 static void
  169 i4b_l2_unit_init(l2_softc_t *l2sc)
  170 {
  171         int s;
  172 
  173         s = splnet();
  174         l2sc->Q921_state = ST_TEI_UNAS;
  175         l2sc->tei_valid = TEI_INVALID;
  176         l2sc->vr = 0;
  177         l2sc->vs = 0;
  178         l2sc->va = 0;
  179         l2sc->ack_pend = 0;
  180         l2sc->rej_excpt = 0;
  181         l2sc->peer_busy = 0;
  182         l2sc->own_busy = 0;
  183         l2sc->l3initiated = 0;
  184 
  185         l2sc->rxd_CR = 0;
  186         l2sc->rxd_PF = 0;
  187         l2sc->rxd_NR = 0;
  188         l2sc->RC = 0;
  189         l2sc->iframe_sent = 0;
  190 
  191         l2sc->postfsmfunc = NULL;
  192 
  193         if(l2sc->ua_num != UA_EMPTY)
  194         {
  195                 i4b_Dfreembuf(l2sc->ua_frame);
  196                 l2sc->ua_num = UA_EMPTY;
  197                 l2sc->ua_frame = NULL;
  198         }
  199 
  200         i4b_T200_stop(l2sc);
  201         i4b_T202_stop(l2sc);
  202         i4b_T203_stop(l2sc);
  203 
  204         splx(s);
  205 }
  206 
  207 /*---------------------------------------------------------------------------*
  208  *      isdn_layer2_status_ind - status indication upward
  209  *---------------------------------------------------------------------------*/
  210 int
  211 isdn_layer2_status_ind(l2_softc_t *l2sc, struct isdn_l3_driver *drv, int status, int parm)
  212 {
  213         int s;
  214         int sendup = 1;
  215 
  216         s = splnet();
  217 
  218         NDBGL2(L2_PRIM, "isdnif %d, status=%d, parm=%d", l2sc->drv->isdnif, status, parm);
  219 
  220         switch(status)
  221         {
  222                 case STI_ATTACH:
  223                         if (parm == 0) {
  224                                 /* detach */
  225                                 callout_stop(&l2sc->T200_callout);
  226                                 callout_stop(&l2sc->T202_callout);
  227                                 callout_stop(&l2sc->T203_callout);
  228                                 callout_stop(&l2sc->IFQU_callout);
  229                                 break;
  230                         }
  231 
  232                         l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN;
  233                         l2sc->ua_frame = NULL;
  234                         memset(&l2sc->stat, 0, sizeof(lapdstat_t));
  235                         i4b_l2_unit_init(l2sc);
  236 
  237                         /* initialize the callout handles for timeout routines */
  238                         callout_init(&l2sc->T200_callout);
  239                         callout_init(&l2sc->T202_callout);
  240                         callout_init(&l2sc->T203_callout);
  241                         callout_init(&l2sc->IFQU_callout);
  242 
  243                         break;
  244 
  245                 case STI_L1STAT:        /* state of layer 1 */
  246                         break;
  247 
  248                 case STI_PDEACT:        /* Timer 4 expired */
  249 /*XXX*/                 if((l2sc->Q921_state >= ST_AW_EST) &&
  250                            (l2sc->Q921_state <= ST_TIMREC))
  251                         {
  252                                 NDBGL2(L2_ERROR, "isdnif %d, persistent deactivation!", l2sc->drv->isdnif);
  253                                 i4b_l2_unit_init(l2sc);
  254                                 parm = -1;      /* this is passed as the new
  255                                                  * TEI to upper layers */
  256                         }
  257                         else
  258                         {
  259                                 sendup = 0;
  260                         }
  261                         break;
  262 
  263                 case STI_NOL1ACC:
  264                         i4b_l2_unit_init(l2sc);
  265                         NDBGL2(L2_ERROR, "isdnif %d, cannot access S0 bus!", l2sc->drv->isdnif);
  266                         break;
  267 
  268                 default:
  269                         NDBGL2(L2_ERROR, "ERROR, isdnif %d, unknown status message!", l2sc->drv->isdnif);
  270                         break;
  271         }
  272 
  273         if(sendup)
  274                 i4b_mdl_status_ind(l2sc->drv, status, parm);  /* send up to layer 3 */
  275 
  276         splx(s);
  277 
  278         return(0);
  279 }
  280 
  281 /*---------------------------------------------------------------------------*
  282  *      MDL_COMMAND_REQ from layer 3
  283  *---------------------------------------------------------------------------*/
  284 int i4b_mdl_command_req(struct isdn_l3_driver *drv, int command, void * parm)
  285 {
  286         struct l2_softc *sc = (l2_softc_t*)drv->l1_token;
  287 
  288         NDBGL2(L2_PRIM, "isdnif %d, command=%d, parm=%p", drv->isdnif, command, parm);
  289 
  290         switch(command)
  291         {
  292                 case CMR_DOPEN:
  293                         i4b_l2_unit_init(sc);
  294                         /* XXX - enable interrupts */
  295                         break;
  296                 case CMR_DCLOSE:
  297                         /* XXX - disable interrupts */
  298                         break;
  299         }
  300 
  301         /* pass down to layer 1 driver */
  302         if (sc->driver)
  303                 sc->driver->mph_command_req(sc->l1_token, command, parm);
  304 
  305         return(0);
  306 }
  307 
  308 /*---------------------------------------------------------------------------*
  309  * isdn_layer2_data_ind - process a rx'd frame got from layer 1
  310  *---------------------------------------------------------------------------*/
  311 int
  312 isdn_layer2_data_ind(l2_softc_t *l2sc, struct isdn_l3_driver *drv, struct mbuf *m)
  313 {
  314         u_char *ptr = m->m_data;
  315 
  316         if ( (*(ptr + OFF_CNTL) & 0x01) == 0 )
  317         {
  318                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
  319                 {
  320                         l2sc->stat.err_rx_len++;
  321                         NDBGL2(L2_ERROR, "ERROR, I-frame < 6 octetts!");
  322                         i4b_Dfreembuf(m);
  323                         return(0);
  324                 }
  325                 i4b_rxd_i_frame(l2sc, drv, m);
  326         }
  327         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x01 )
  328         {
  329                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
  330                 {
  331                         l2sc->stat.err_rx_len++;
  332                         NDBGL2(L2_ERROR, "ERROR, S-frame < 6 octetts!");
  333                         i4b_Dfreembuf(m);
  334                         return(0);
  335                 }
  336                 i4b_rxd_s_frame(l2sc, drv, m);
  337         }
  338         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x03 )
  339         {
  340                 if(m->m_len < 3)        /* 5 oct - 2 chksum oct */
  341                 {
  342                         l2sc->stat.err_rx_len++;
  343                         NDBGL2(L2_ERROR, "ERROR, U-frame < 5 octetts!");
  344                         i4b_Dfreembuf(m);
  345                         return(0);
  346                 }
  347                 i4b_rxd_u_frame(l2sc, drv, m);
  348         }
  349         else
  350         {
  351                 l2sc->stat.err_rx_badf++;
  352                 NDBGL2(L2_ERROR, "ERROR, bad frame rx'd - ");
  353                 i4b_print_frame(m->m_len, m->m_data);
  354                 i4b_Dfreembuf(m);
  355         }
  356         return(0);
  357 }
  358 
  359 int i4b_l2_channel_get_state(struct isdn_l3_driver *drv, int b_chanid)
  360 {
  361         l2_softc_t *sc = drv->l1_token;
  362         return sc->bchan_state[b_chanid];
  363 }
  364 
  365 void i4b_l2_channel_set_state(struct isdn_l3_driver *drv, int b_chanid, int state)
  366 {
  367         l2_softc_t *sc = drv->l1_token;
  368         sc->bchan_state[b_chanid] = state;
  369 }
  370 
  371 /*---------------------------------------------------------------------------*
  372  *      telephony silence detection
  373  *---------------------------------------------------------------------------*/
  374 
  375 #define TEL_IDLE_MIN (BCH_MAX_DATALEN/2)
  376 
  377 int
  378 isdn_bchan_silence(unsigned char *data, int len)
  379 {
  380         register int i = 0;
  381         register int j = 0;
  382 
  383         /* count idle bytes */
  384 
  385         for(;i < len; i++)
  386         {
  387                 if((*data >= 0xaa) && (*data <= 0xac))
  388                         j++;
  389                 data++;
  390         }
  391 
  392 #ifdef NOTDEF
  393         printf("isic_hscx_silence: got %d silence bytes in frame\n", j);
  394 #endif
  395 
  396         if(j < (TEL_IDLE_MIN))
  397                 return(0);
  398         else
  399                 return(1);
  400 
  401 }
  402 
  403 
  404 #endif /* NI4BQ921 > 0 */

Cache object: e09fd0d051103fa17fd596665848d61e


[ 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.