Enscript Output

extractedLnx/linux-2.6.9/drivers/isdn/hardware/eicon/message.c_control_rc.c

void control_rc(PLCI   * plci, byte req, byte rc, byte ch, byte global_req, byte nl_rc)
{
  dword Id;
  dword rId;
  word Number;
  word Info=0;
  word i;
  word ncci;
  DIVA_CAPI_ADAPTER   * a;
  APPL   * appl;
  PLCI   * rplci;
    byte SSparms[]  = "\x05\x00\x00\x02\x00\x00";
    byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";

  if (!plci) {
    dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
    return;
  }
  dbug(1,dprintf("req0_in/out=%d/%d",plci->req_in,plci->req_out));
  if(plci->req_in!=plci->req_out)
  {
    if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
    {
      dbug(1,dprintf("req_1return"));
      return;
    }
    /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
  }
  plci->req_in = plci->req_in_start = plci->req_out = 0;
  dbug(1,dprintf("control_rc"));

  appl = plci->appl;
  a = plci->adapter;
  ncci = a->ch_ncci[ch];
  if(appl)
  {
    Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id;
    if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER;
    Number = plci->number;
    dbug(1,dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x",Id,plci->Id,plci->tel,plci->Sig.Id,plci->command,plci->internal_command));
    dbug(1,dprintf("channels=0x%x",plci->channels));
    if (plci_remove_check(plci))
      return;
    if(req==REMOVE && rc==ASSIGN_OK)
    {
      sig_req(plci,HANGUP,0);
      sig_req(plci,REMOVE,0);
      send_req(plci);
    }
    if(plci->command)
    {
      switch(plci->command)
      {
      case C_HOLD_REQ:
        dbug(1,dprintf("HoldRC=0x%x",rc));
        SSparms[1] = (byte)S_HOLD;
        if(rc!=OK)
        {
          plci->SuppState = IDLE;
          Info = 0x2001;
        }
        sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
        break;

      case C_RETRIEVE_REQ:
        dbug(1,dprintf("RetrieveRC=0x%x",rc));
        SSparms[1] = (byte)S_RETRIEVE;
        if(rc!=OK)
        {
          plci->SuppState = CALL_HELD;
          Info = 0x2001;
        }
        sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
        break;

      case _INFO_R:
        dbug(1,dprintf("InfoRC=0x%x",rc));
        if(rc!=OK) Info=_WRONG_STATE;
        sendf(appl,_INFO_R|CONFIRM,Id,Number,"w",Info);
        break;

      case _CONNECT_R:
        dbug(1,dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x",req,rc,global_req,nl_rc));
        if (plci->State == INC_DIS_PENDING)
          break;
        if(plci->Sig.Id!=0xff)
        {
          if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
           || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
          {
            dbug(1,dprintf("No more IDs/Call_Req failed"));
            sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
            plci_remove(plci);
            plci->State = IDLE;
            break;
          }
          if(plci->State!=LOCAL_CONNECT)plci->State = OUTG_CON_PENDING;
          sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
        }
        else /* D-ch activation */
        {
          if (rc != ASSIGN_OK)
          {
            dbug(1,dprintf("No more IDs/X.25 Call_Req failed"));
            sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
            plci_remove(plci);
            plci->State = IDLE;
            break;
          }
          sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
          sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"sss","","","");
          plci->State = INC_ACT_PENDING;
        }
        break;

      case _CONNECT_I|RESPONSE:
        if (plci->State != INC_DIS_PENDING)
          plci->State = INC_CON_ACCEPT;
        break;

      case _DISCONNECT_R:
        if (plci->State == INC_DIS_PENDING)
          break;
        if(plci->Sig.Id!=0xff)
        {
          plci->State = OUTG_DIS_PENDING;
          sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0);
        }
        break;

      case SUSPEND_REQ:
        break;

      case RESUME_REQ:
        break;

      case _CONNECT_B3_R:
        if(rc!=OK)
        {
          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",_WRONG_IDENTIFIER);
          break;
        }
        ncci = get_ncci (plci, ch, 0);
        Id = (Id & 0xffff) | (((dword) ncci) << 16);
        plci->channels++;
        if(req==N_RESET)
        {
          a->ncci_state[ncci] = INC_ACT_PENDING;
          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0);
          sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
        }
        else
        {
          a->ncci_state[ncci] = OUTG_CON_PENDING;
          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0);
        }
        break;

      case _CONNECT_B3_I|RESPONSE:
        break;

      case _RESET_B3_R:
/*        sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/
        break;

      case _DISCONNECT_B3_R:
        sendf(appl,_DISCONNECT_B3_R|CONFIRM,Id,Number,"w",0);
        break;

      case _MANUFACTURER_R:
        break;

      case PERM_LIST_REQ:
        if(rc!=OK)
        {
          Info = _WRONG_IDENTIFIER;
          sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
          plci_remove(plci);
        }
        else
          sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
        break;

      default:
        break;
      }
      plci->command = 0;
    }
    else if (plci->internal_command)
    {
      switch(plci->internal_command)
      {
      case BLOCK_PLCI:
        return;

      case GET_MWI_STATE:
        if(rc==OK) /* command supported, wait for indication */
        {
          return;
        }
        plci_remove(plci);
        break;

        /* Get Supported Services */
      case GETSERV_REQ_PEND:
        if(rc==OK) /* command supported, wait for indication */
        {
          break;
        }
        WRITE_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
        sendf(appl, _FACILITY_R|CONFIRM, Id, Number, "wws",0,3,SSstruct);
        plci_remove(plci);
        break;

      case INTERR_DIVERSION_REQ_PEND:      /* Interrogate Parameters        */
      case INTERR_NUMBERS_REQ_PEND:
      case CF_START_PEND:                  /* Call Forwarding Start pending */
      case CF_STOP_PEND:                   /* Call Forwarding Stop pending  */
      case CCBS_REQUEST_REQ_PEND:
      case CCBS_DEACTIVATE_REQ_PEND:
      case CCBS_INTERROGATE_REQ_PEND:
        switch(plci->internal_command)
        {
          case INTERR_DIVERSION_REQ_PEND:
            SSparms[1] = S_INTERROGATE_DIVERSION;
            break;
          case INTERR_NUMBERS_REQ_PEND:
            SSparms[1] = S_INTERROGATE_NUMBERS;
            break;
          case CF_START_PEND:
            SSparms[1] = S_CALL_FORWARDING_START;
            break;
          case CF_STOP_PEND:
            SSparms[1] = S_CALL_FORWARDING_STOP;
            break;
          case CCBS_REQUEST_REQ_PEND:
            SSparms[1] = S_CCBS_REQUEST;
            break;
          case CCBS_DEACTIVATE_REQ_PEND:
            SSparms[1] = S_CCBS_DEACTIVATE;
            break;
          case CCBS_INTERROGATE_REQ_PEND:
            SSparms[1] = S_CCBS_INTERROGATE;
            break;
        }
        if(global_req==ASSIGN)
        {
          dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req,rc));
          return;
        }
        if(!plci->appl) break;
        if(rc==ISDN_GUARD_REJ)
        {
          Info = _CAPI_GUARD_ERROR;
        }
        else if(rc!=OK)
        {
          Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
        }
        sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,
              plci->number,"wws",Info,(word)3,SSparms);
        if(Info) plci_remove(plci);
        break;

        /* 3pty conference pending */
      case PTY_REQ_PEND:
        if(!plci->relatedPTYPLCI) break;
        rplci = plci->relatedPTYPLCI;
        SSparms[1] = plci->ptyState;
        rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
        if(rplci->tel) rId|=EXT_CONTROLLER;
        if(rc!=OK)
        {
          Info = 0x300E; /* not supported */
          plci->relatedPTYPLCI = NULL;
          plci->ptyState = 0;
        }
        sendf(rplci->appl,
              _FACILITY_R|CONFIRM,
              rId,
              plci->number,
              "wws",Info,(word)3,SSparms);
        break;

        /* Explicit Call Transfer pending */
      case ECT_REQ_PEND:
        dbug(1,dprintf("ECT_RC=0x%x/0x%x",req,rc));
        if(!plci->relatedPTYPLCI) break;
        rplci = plci->relatedPTYPLCI;
        SSparms[1] = S_ECT;
        rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
        if(rplci->tel) rId|=EXT_CONTROLLER;
        if(rc!=OK)
        {
          Info = 0x300E; /* not supported */
          plci->relatedPTYPLCI = NULL;
          plci->ptyState = 0;
        }
        sendf(rplci->appl,
              _FACILITY_R|CONFIRM,
              rId,
              plci->number,
              "wws",Info,(word)3,SSparms);
        break;

      case _MANUFACTURER_R:
        dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req,rc));
        if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
        {
          dbug(1,dprintf("No more IDs"));
          sendf(appl,_MANUFACTURER_R|CONFIRM,Id,Number,"dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI);
          plci_remove(plci);  /* after codec init, internal codec commands pending */
        }
        break;

      case _CONNECT_R:
        dbug(1,dprintf("_Connect_R=0x%x/0x%x",req,rc));
        if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
        {
          dbug(1,dprintf("No more IDs"));
          sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
          plci_remove(plci);  /* after codec init, internal codec commands pending */
        }
        break;

      case PERM_COD_HOOK:                     /* finished with Hook_Ind */
        return;

      case PERM_COD_CALL:
        dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc));
        plci->internal_command = PERM_COD_CONN_PEND;
        return;

      case PERM_COD_ASSIGN:
        dbug(1,dprintf("***Codec Assign A, Rc = 0x%x",rc));
        if(rc!=ASSIGN_OK) break;
        sig_req(plci,CALL_REQ,0);
        send_req(plci);
        plci->internal_command = PERM_COD_CALL;
        return;

        /* Null Call Reference Request pending */
      case C_NCR_FAC_REQ:
        dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req,rc));
        if(global_req==ASSIGN)
        {
          if(rc==ASSIGN_OK)
          {
            return;
          }
          else
          {
            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
            appl->NullCREnable = FALSE;
            plci_remove(plci);
          }
        }
        else if(req==NCR_FACILITY)
        {
          if(rc==OK)
          {
            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",0);
          }
          else
          {
            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
            appl->NullCREnable = FALSE;
          }
          plci_remove(plci);
        }
        break;

      case HOOK_ON_REQ:
        if(plci->channels)
        {
          if(a->ncci_state[ncci]==CONNECTED)
          {
            a->ncci_state[ncci] = OUTG_DIS_PENDING;
            cleanup_ncci_data (plci, ncci);
            nl_req_ncci(plci,N_DISC,(byte)ncci);
          }
          break;
        }
        break;

      case HOOK_OFF_REQ:
        if (plci->State == INC_DIS_PENDING)
          break;
        sig_req(plci,CALL_REQ,0);
        send_req(plci);
        plci->State=OUTG_CON_PENDING;
        break;


      case MWI_ACTIVATE_REQ_PEND:
      case MWI_DEACTIVATE_REQ_PEND:
        if(global_req == ASSIGN && rc==ASSIGN_OK)
        {
          dbug(1,dprintf("MWI_REQ assigned"));
          return;
        }
        else if(rc!=OK)
        {                 
          if(rc==WRONG_IE)
          {
            Info = 0x2007; /* Illegal message parameter coding */
            dbug(1,dprintf("MWI_REQ invalid parameter"));
          }
          else
          {
            Info = 0x300B; /* not supported */                      
            dbug(1,dprintf("MWI_REQ not supported"));
          }
          /* 0x3010: Request not allowed in this state */
          WRITE_WORD(&SSparms[4],0x300E); /* SS not supported */
                    
        }
        if(plci->internal_command==MWI_ACTIVATE_REQ_PEND)
        {
          WRITE_WORD(&SSparms[1],S_MWI_ACTIVATE);
        }
        else WRITE_WORD(&SSparms[1],S_MWI_DEACTIVATE);

        if(plci->cr_enquiry)
        {
          sendf(plci->appl,
                _FACILITY_R|CONFIRM,
                Id&0xf,
                plci->number,
                "wws",Info,(word)3,SSparms);
          if(rc!=OK) plci_remove(plci);
        }
        else
        {
          sendf(plci->appl,
                _FACILITY_R|CONFIRM,
                Id,
                plci->number,
                "wws",Info,(word)3,SSparms);
        }
        break;

      case CONF_BEGIN_REQ_PEND:
      case CONF_ADD_REQ_PEND:
      case CONF_SPLIT_REQ_PEND:
      case CONF_DROP_REQ_PEND:
      case CONF_ISOLATE_REQ_PEND:
      case CONF_REATTACH_REQ_PEND:
        dbug(1,dprintf("CONF_RC=0x%x/0x%x",req,rc));
        if((plci->internal_command==CONF_ADD_REQ_PEND)&&(!plci->relatedPTYPLCI)) break;
        rplci = plci;
        rId = Id;
        switch(plci->internal_command)
        {
          case CONF_BEGIN_REQ_PEND:
            SSparms[1] = S_CONF_BEGIN;
            break;
          case CONF_ADD_REQ_PEND:
            SSparms[1] = S_CONF_ADD;
            rplci = plci->relatedPTYPLCI;
            rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
            break;
          case CONF_SPLIT_REQ_PEND:
            SSparms[1] = S_CONF_SPLIT;
            break;
          case CONF_DROP_REQ_PEND:
            SSparms[1] = S_CONF_DROP;
            break;
          case CONF_ISOLATE_REQ_PEND:
            SSparms[1] = S_CONF_ISOLATE;
            break;
          case CONF_REATTACH_REQ_PEND:
            SSparms[1] = S_CONF_REATTACH;
            break;
        }
        
        if(rc!=OK)
        {
          Info = 0x300E; /* not supported */
          plci->relatedPTYPLCI = NULL;
          plci->ptyState = 0;
        }
        sendf(rplci->appl,
              _FACILITY_R|CONFIRM,
              rId,
              plci->number,
              "wws",Info,(word)3,SSparms);
        break;

      case VSWITCH_REQ_PEND:
        if(rc!=OK)
        {
          if(plci->relatedPTYPLCI)
          {
            plci->relatedPTYPLCI->vswitchstate=0;
            plci->relatedPTYPLCI->vsprot=0;
            plci->relatedPTYPLCI->vsprotdialect=0;    
          }
          plci->vswitchstate=0;
          plci->vsprot=0;
          plci->vsprotdialect=0;
        }
        else
        {
          if(plci->relatedPTYPLCI &&
             plci->vswitchstate==1 &&
             plci->relatedPTYPLCI->vswitchstate==3) /* join complete */
            plci->vswitchstate=3;
        }
        break;

  /* Call Deflection Request pending (SSCT) */
      case CD_REQ_PEND:
        SSparms[1] = S_CALL_DEFLECTION;
        if(rc!=OK)
        {
          Info = 0x300E; /* not supported */
          plci->appl->CDEnable = 0;
        }  
        sendf(plci->appl,_FACILITY_R|CONFIRM,Id,
          plci->number,"wws",Info,(word)3,SSparms);
        break;

      case RTP_CONNECT_B3_REQ_COMMAND_2:
        if (rc == OK)
        {
          ncci = get_ncci (plci, ch, 0);
          Id = (Id & 0xffff) | (((dword) ncci) << 16);
          plci->channels++;
          a->ncci_state[ncci] = OUTG_CON_PENDING;
        }

      default:
        if (plci->internal_command_queue[0])
        {
          (*(plci->internal_command_queue[0]))(Id, plci, rc);
          if (plci->internal_command)
            return;
        }
        break;
      }
      next_internal_command (Id, plci);
    }
  }
  else /* appl==0 */
  {
    Id = ((word)plci->Id<<8)|plci->adapter->Id;
    if(plci->tel) Id|=EXT_CONTROLLER;

    switch(plci->internal_command)
    {
    case BLOCK_PLCI:
      return;

    case START_L1_SIG_ASSIGN_PEND:
    case REM_L1_SIG_ASSIGN_PEND:
      if(global_req == ASSIGN)
      {
        break;
      }
      else
      {
        dbug(1,dprintf("***L1 Req rem PLCI"));
        plci->internal_command = 0;
        sig_req(plci,REMOVE,0);
        send_req(plci);
      }
      break;

      /* Call Deflection Request pending, just no appl ptr assigned */
    case CD_REQ_PEND:
      SSparms[1] = S_CALL_DEFLECTION;
      if(rc!=OK)
      {
        Info = 0x300E; /* not supported */
      }
      for(i=0; i<max_appl; i++)
      {
        if(application[i].CDEnable)
        {
          if(!application[i].Id) application[i].CDEnable = 0;
          else
          {
            sendf(&application[i],_FACILITY_R|CONFIRM,Id,
                  plci->number,"wws",Info,(word)3,SSparms);
            if(Info) application[i].CDEnable = 0;
          }
        }
      }
      plci->internal_command = 0;
      break;

    case PERM_COD_HOOK:                   /* finished with Hook_Ind */
      return;

    case PERM_COD_CALL:
      plci->internal_command = PERM_COD_CONN_PEND;
      dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc));
      return;

    case PERM_COD_ASSIGN:
      dbug(1,dprintf("***Codec Assign, Rc = 0x%x",rc));
      plci->internal_command = 0;
      if(rc!=ASSIGN_OK) break;
      plci->internal_command = PERM_COD_CALL;
      sig_req(plci,CALL_REQ,0);
      send_req(plci);
      return;

    case LISTEN_SIG_ASSIGN_PEND:
      if(rc == ASSIGN_OK)
      {
        plci->internal_command = 0;
        dbug(1,dprintf("ListenCheck, new SIG_ID = 0x%x",plci->Sig.Id));
        add_p(plci,ESC,"\x02\x18\x00");             /* support call waiting */
        sig_req(plci,INDICATE_REQ,0);
        send_req(plci);
      }
      else
      {
        dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc));
        a->listen_active--;
        plci_remove(plci);
        plci->State = IDLE;
      }
      break;

    case USELAW_REQ:
      if(global_req == ASSIGN)
      {
        if (rc==ASSIGN_OK)
      {
        sig_req(plci,LAW_REQ,0);
        send_req(plci);
        dbug(1,dprintf("Auto-Law assigned"));
        }
        else
        {
          dbug(1,dprintf("Auto-Law assign failed"));
          a->automatic_law = 3;
          plci->internal_command = 0;
          a->automatic_lawPLCI = NULL;
        }
        break;
      }
      else if(req == LAW_REQ && rc==OK)
      {
        dbug(1,dprintf("Auto-Law initiated"));
        a->automatic_law = 2;
        plci->internal_command = 0;
      }
      else
      {
        dbug(1,dprintf("Auto-Law not supported"));
        a->automatic_law = 3;
        plci->internal_command = 0;
        sig_req(plci,REMOVE,0);
        send_req(plci);
        a->automatic_lawPLCI = NULL;
      }
      break;
    }
    plci_remove_check(plci);
  }
}

Generated by GNU enscript 1.6.4.