Enscript Output

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

void sig_ind(PLCI   * plci)
{
  dword x_Id;
  dword Id;
  dword rId;
  word Number = 0;
  word i;
  word cip;
  dword cip_mask;
  byte   *ie;
  DIVA_CAPI_ADAPTER   * a;
    API_PARSE saved_parms[MAX_MSG_PARMS+1];
#define MAXPARMSIDS 31
    byte   * parms[MAXPARMSIDS];
    byte   * add_i[4];
    byte   * multi_fac_parms[MAX_MULTI_IE];
    byte   * multi_pi_parms [MAX_MULTI_IE];
    byte   * multi_ssext_parms [MAX_MULTI_IE];
    byte   * multi_CiPN_parms [MAX_MULTI_IE];

    byte   * multi_vswitch_parms [MAX_MULTI_IE];

  byte ai_len;
    byte   *esc_chi = "";
    byte   *esc_law = "";
    byte   *pty_cai = "";
    byte   *esc_cr  = "";
    byte   *esc_profile = "";

    byte facility[256];
  PLCI   * tplci = NULL;
  byte chi[] = "\x02\x18\x01";
  byte voice_cai[]  = "\x06\x14\x00\x00\x00\x00\x08";
    byte resume_cau[] = "\x05\x05\x00\x02\x00\x00";
  /* ESC_MSGTYPE must be the last but one message, a new IE has to be */
  /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
  /* SMSG is situated at the end because its 0 (for compatibility reasons */
  /* (see Info_Mask Bit 4, first IE. then the message type)           */
    word parms_id[] =
         {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
          UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
          RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
          CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG};
          /* 14 FTY repl by ESC_CHI */
          /* 18 PI  repl by ESC_LAW */
         /* removed OAD changed to 0xff for future use, OAD is multiIE now */
     word multi_fac_id[] = {1, FTY};
     word multi_pi_id[]  = {1, PI};
     word multi_CiPN_id[]  = {1, OAD};
     word multi_ssext_id[]  = {1, ESC_SSEXT};

     word multi_vswitch_id[]  = {1, ESC_VSWITCH};

  byte   * cau;
  word ncci;
    byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
    byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
    byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
    byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
  byte force_mt_info = FALSE;
  byte dir;
  dword d;
  word w;

  a = plci->adapter;
  Id = ((word)plci->Id<<8)|a->Id;
  WRITE_WORD(&SS_Ind[4],0x0000);

  if (plci->sig_remove_id)
  {
    plci->Sig.RNR = 2; /* discard */
    dbug(1,dprintf("SIG discard while remove pending"));
    return;
  }
  if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER;
  dbug(1,dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
    Id,plci->Id,plci->tel,plci->State,plci->channels,plci->hangup_flow_ctrl_timer));
  if(plci->Sig.Ind==CALL_HOLD_ACK && plci->channels)
  {
    plci->Sig.RNR = 1;
    return;
  }
  if(plci->Sig.Ind==HANGUP && plci->channels)
  {
    plci->Sig.RNR = 1;
    plci->hangup_flow_ctrl_timer++;
    /* recover the network layer after timeout */
    if(plci->hangup_flow_ctrl_timer==100)
    {
      dbug(1,dprintf("Exceptional disc"));
      plci->Sig.RNR = 0;
      plci->hangup_flow_ctrl_timer = 0;
      for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
      {
        if (a->ncci_plci[ncci] == plci->Id)
        {
          cleanup_ncci_data (plci, ncci);
          if(plci->channels)plci->channels--;
          if (plci->appl)
            sendf(plci->appl,_DISCONNECT_B3_I, (((dword) ncci) << 16) | Id,0,"ws",0,"");
        }
      }
      if (plci->appl)
        sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
      plci_remove(plci);
      plci->State=IDLE;
    }
    return;
  }

  /* do first parse the info with no OAD in, because OAD will be converted */
  /* first the multiple facility IE, then mult. progress ind.              */
  /* then the parameters for the info_ind + conn_ind                       */
  IndParse(plci,multi_fac_id,multi_fac_parms,MAX_MULTI_IE);
  IndParse(plci,multi_pi_id,multi_pi_parms,MAX_MULTI_IE);
  IndParse(plci,multi_ssext_id,multi_ssext_parms,MAX_MULTI_IE);

  IndParse(plci,multi_vswitch_id,multi_vswitch_parms,MAX_MULTI_IE);

  IndParse(plci,parms_id,parms,0);
  IndParse(plci,multi_CiPN_id,multi_CiPN_parms,MAX_MULTI_IE);
  esc_chi  = parms[14];
  esc_law  = parms[18];
  pty_cai  = parms[24];
  esc_cr   = parms[25];
  esc_profile = parms[27];
  if(esc_cr[0] && plci)
  {
    if(plci->cr_enquiry && plci->appl)
    {
      plci->cr_enquiry = FALSE;
      /* d = MANU_ID            */
      /* w = m_command          */
      /* b = total length       */
      /* b = indication type    */
      /* b = length of all IEs  */
      /* b = IE1                */
      /* S = IE1 length + cont. */
      /* b = IE2                */
      /* S = IE2 lenght + cont. */
      sendf(plci->appl,
        _MANUFACTURER_I,
        Id,
        0,
        "dwbbbbSbS",_DI_MANU_ID,plci->m_command,
        2+1+1+esc_cr[0]+1+1+esc_law[0],plci->Sig.Ind,1+1+esc_cr[0]+1+1+esc_law[0],ESC,esc_cr,ESC,esc_law);
    }
  }
  /* create the additional info structure                                  */
  add_i[1] = parms[15]; /* KEY of additional info */
  add_i[2] = parms[11]; /* UUI of additional info */
  ai_len = AddInfo(add_i,multi_fac_parms, esc_chi, facility);

  /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card  */
  /* indication returns by the card if requested by the function           */
  /* AutomaticLaw() after driver init                                      */
  if (a->automatic_law<4)
  {
    if(esc_law[0]){
      if(esc_law[2]){
        dbug(0,dprintf("u-Law selected"));
        a->u_law = 1;
      }
      else {
        dbug(0,dprintf("a-Law selected"));
        a->u_law = 0;
      }
      a->automatic_law = 4;
      if(plci==a->automatic_lawPLCI) {
        plci->internal_command = 0;
        sig_req(plci,REMOVE,0);
        send_req(plci);
        a->automatic_lawPLCI = NULL;
      }
    }
    if (esc_profile[0])
    {
      dbug (1, dprintf ("[%06x] CardProfile: %lx %lx %lx %lx %lx",
        UnMapController (a->Id), READ_DWORD (&esc_profile[6]),
        READ_DWORD (&esc_profile[10]), READ_DWORD (&esc_profile[14]),
        READ_DWORD (&esc_profile[18]), READ_DWORD (&esc_profile[46])));

      a->profile.Global_Options &= 0x000000ffL;
      a->profile.B1_Protocols &= 0x000003ffL;
      a->profile.B2_Protocols &= 0x00001fdfL;
      a->profile.B3_Protocols &= 0x000000b7L;

      a->profile.Global_Options &= READ_DWORD (&esc_profile[6]) |
        GL_BCHANNEL_OPERATION_SUPPORTED;
      a->profile.B1_Protocols &= READ_DWORD (&esc_profile[10]);
      a->profile.B2_Protocols &= READ_DWORD (&esc_profile[14]);
      a->profile.B3_Protocols &= READ_DWORD (&esc_profile[18]);
      a->manufacturer_features = READ_DWORD (&esc_profile[46]);
      a->man_profile.private_options = 0;

      if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
      {
        a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
        a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
      }


      if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP)
        a->man_profile.private_options |= 1L << PRIVATE_RTP;
      a->man_profile.rtp_primary_payloads = READ_DWORD (&esc_profile[50]);
      a->man_profile.rtp_additional_payloads = READ_DWORD (&esc_profile[54]);


      if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
        a->man_profile.private_options |= 1L << PRIVATE_T38;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
        a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
        a->man_profile.private_options |= 1L << PRIVATE_V18;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
        a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
        a->man_profile.private_options |= 1L << PRIVATE_PIAFS;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
        a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
        a->man_profile.private_options |= 1L << PRIVATE_VOWN;


      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
        a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;

    }
    else
    {
      a->profile.Global_Options &= 0x0000007fL;
      a->profile.B1_Protocols &= 0x000003dfL;
      a->profile.B2_Protocols &= 0x00001adfL;
      a->profile.B3_Protocols &= 0x000000b7L;
      a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF;
    }
    if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
      MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
    {
      a->profile.Global_Options |= GL_DTMF_SUPPORTED;
    }
    a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL;
    dbug (1, dprintf ("[%06x] Profile: %lx %lx %lx %lx %lx",
      UnMapController (a->Id), a->profile.Global_Options,
      a->profile.B1_Protocols, a->profile.B2_Protocols,
      a->profile.B3_Protocols, a->manufacturer_features));
  }
  /* codec plci for the handset/hook state support is just an internal id  */
  if(plci!=a->AdvCodecPLCI)
  {
    force_mt_info =  SendMultiIE(plci,Id,multi_fac_parms, FTY, 0x20, 0);
    force_mt_info |= SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, 0);
    SendSSExtInd(NULL,plci,Id,multi_ssext_parms);
    SendInfo(plci,Id, parms, force_mt_info);

    VSwitchReqInd(plci,Id,multi_vswitch_parms);

  }

  /* switch the codec to the b-channel                                     */
  if(esc_chi[0] && plci && !plci->SuppState){
    plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
    mixer_set_bchannel_id_esc (plci, plci->b_channel);
    dbug(1,dprintf("storeChannel=0x%x",plci->b_channel));
    if(plci->tel==ADV_VOICE && plci->appl) {
      SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
    }
  }

  if(plci->appl) Number = plci->appl->Number++;

  switch(plci->Sig.Ind) {
  /* Response to Get_Supported_Services request */
  case S_SUPPORTED:
    dbug(1,dprintf("S_Supported"));
    if(!plci->appl) break;
    if(pty_cai[0]==4)
    {
      WRITE_DWORD(&CF_Ind[6],READ_DWORD(&pty_cai[1]) );
    }
    else
    {
      WRITE_DWORD(&CF_Ind[6],MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
    }
    WRITE_WORD (&CF_Ind[1], 0);
    WRITE_WORD (&CF_Ind[4], 0);
    sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,plci->number, "wws",0,3,CF_Ind);
    plci_remove(plci);
    break;
                    
  /* Supplementary Service rejected */
  case S_SERVICE_REJ:
    dbug(1,dprintf("S_Reject=0x%x",pty_cai[5]));
    if(!pty_cai[0]) break;
    switch (pty_cai[5])
    {
    case ECT_EXECUTE:
    case THREE_PTY_END:
    case THREE_PTY_BEGIN:
      if(!plci->relatedPTYPLCI) break;
      tplci = plci->relatedPTYPLCI;
      rId = ( (word)tplci->Id<<8)|tplci->adapter->Id;
      if(tplci->tel) rId|=EXT_CONTROLLER;
      if(pty_cai[5]==ECT_EXECUTE)
      {
        WRITE_WORD(&SS_Ind[1],S_ECT);

        plci->vswitchstate=0;
        plci->relatedPTYPLCI->vswitchstate=0;

      }
      else
      {
        WRITE_WORD(&SS_Ind[1],pty_cai[5]+3);
      }
      if(pty_cai[2]!=0xff)
      {
        WRITE_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
      }
      else
      {
        WRITE_WORD(&SS_Ind[4],0x300E);
      }
      plci->relatedPTYPLCI = NULL;
      plci->ptyState = 0;
      sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
      break;

    case CALL_DEFLECTION:
      if(pty_cai[2]!=0xff)
      {
        WRITE_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
      }
      else
      {
        WRITE_WORD(&SS_Ind[4],0x300E);
      }
      WRITE_WORD(&SS_Ind[1],pty_cai[5]);
      for(i=0; i<max_appl; i++)
      {
        if(application[i].CDEnable)
        {
          if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
          application[i].CDEnable = FALSE;
        }
      }
      break;

    case DEACTIVATION_DIVERSION:
    case ACTIVATION_DIVERSION:
    case DIVERSION_INTERROGATE_CFU:
    case DIVERSION_INTERROGATE_CFB:
    case DIVERSION_INTERROGATE_CFNR:
    case DIVERSION_INTERROGATE_NUM:
    case CCBS_REQUEST:
    case CCBS_DEACTIVATE:
    case CCBS_INTERROGATE:
      if(!plci->appl) break;
      if(pty_cai[2]!=0xff)
      {
        WRITE_WORD(&Interr_Err_Ind[4],0x3600|(word)pty_cai[2]);
      }
      else
      {
        WRITE_WORD(&Interr_Err_Ind[4],0x300E);
      }
      switch (pty_cai[5])
      {
        case DEACTIVATION_DIVERSION:
          dbug(1,dprintf("Deact_Div"));
          Interr_Err_Ind[0]=0x9;
          Interr_Err_Ind[3]=0x6;
          WRITE_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_STOP);
          break;
        case ACTIVATION_DIVERSION:
          dbug(1,dprintf("Act_Div"));
          Interr_Err_Ind[0]=0x9;
          Interr_Err_Ind[3]=0x6;
          WRITE_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_START);
          break;
        case DIVERSION_INTERROGATE_CFU:
        case DIVERSION_INTERROGATE_CFB:
        case DIVERSION_INTERROGATE_CFNR:
          dbug(1,dprintf("Interr_Div"));
          Interr_Err_Ind[0]=0xa;
          Interr_Err_Ind[3]=0x7;
          WRITE_WORD(&Interr_Err_Ind[1],S_INTERROGATE_DIVERSION);
          break;
        case DIVERSION_INTERROGATE_NUM:
          dbug(1,dprintf("Interr_Num"));
          Interr_Err_Ind[0]=0xa;
          Interr_Err_Ind[3]=0x7;
          WRITE_WORD(&Interr_Err_Ind[1],S_INTERROGATE_NUMBERS);
          break;
        case CCBS_REQUEST:
          dbug(1,dprintf("CCBS Request"));
          Interr_Err_Ind[0]=0xd;
          Interr_Err_Ind[3]=0xa;
          WRITE_WORD(&Interr_Err_Ind[1],S_CCBS_REQUEST);
          break;
        case CCBS_DEACTIVATE:
          dbug(1,dprintf("CCBS Deactivate"));
          Interr_Err_Ind[0]=0x9;
          Interr_Err_Ind[3]=0x6;
          WRITE_WORD(&Interr_Err_Ind[1],S_CCBS_DEACTIVATE);
          break;
        case CCBS_INTERROGATE:
          dbug(1,dprintf("CCBS Interrogate"));
          Interr_Err_Ind[0]=0xb;
          Interr_Err_Ind[3]=0x8;
          WRITE_WORD(&Interr_Err_Ind[1],S_CCBS_INTERROGATE);
          break;
      }
      WRITE_DWORD(&Interr_Err_Ind[6],plci->appl->S_Handle);
      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, Interr_Err_Ind);
      plci_remove(plci);
      break;
    case ACTIVATION_MWI:      
    case DEACTIVATION_MWI:
      if(pty_cai[5]==ACTIVATION_MWI)
      {
        WRITE_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
      }
      else WRITE_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
      
      if(pty_cai[2]!=0xff)
      {
        WRITE_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
      }
      else
      {
        WRITE_WORD(&SS_Ind[4],0x300E);
      }

      if(plci->cr_enquiry)
      {
        sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
        plci_remove(plci);
      }
      else
      {
        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
      }
      break;
    case CONF_ADD: /* ERROR */
    case CONF_BEGIN:
    case CONF_DROP:
    case CONF_ISOLATE:
    case CONF_REATTACH:
      CONF_Ind[0]=9;
      CONF_Ind[3]=6;   
      switch(pty_cai[5])
      {
      case CONF_BEGIN:
          WRITE_WORD(&CONF_Ind[1],S_CONF_BEGIN);
          plci->ptyState = 0;
          break;
      case CONF_DROP:
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          WRITE_WORD(&CONF_Ind[1],S_CONF_DROP);
          plci->ptyState = CONNECTED;
          break;
      case CONF_ISOLATE:
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          WRITE_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
          plci->ptyState = CONNECTED;
          break;
      case CONF_REATTACH:
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          WRITE_WORD(&CONF_Ind[1],S_CONF_REATTACH);
          plci->ptyState = CONNECTED;
          break;
      case CONF_ADD:
          WRITE_WORD(&CONF_Ind[1],S_CONF_ADD);
          plci->relatedPTYPLCI = NULL;
          tplci=plci->relatedPTYPLCI;
          if(tplci) tplci->ptyState = CONNECTED;
          plci->ptyState = CONNECTED;
          break;
      }
          
      if(pty_cai[2]!=0xff)
      {
        WRITE_WORD(&CONF_Ind[4],0x3600|(word)pty_cai[2]);
      }
      else
      {
        WRITE_WORD(&CONF_Ind[4],0x3303); /* Time-out: network did not respond
                                            within the required time */
      }

      WRITE_DWORD(&CONF_Ind[6],0x0);
      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
      break;
    }
    break;

  /* Supplementary Service indicates success */
  case S_SERVICE:
    dbug(1,dprintf("Service_Ind"));
    WRITE_WORD (&CF_Ind[4], 0);
    switch (pty_cai[5])
    {
    case THREE_PTY_END:
    case THREE_PTY_BEGIN:
    case ECT_EXECUTE:
      if(!plci->relatedPTYPLCI) break;
      tplci = plci->relatedPTYPLCI;
      rId = ( (word)tplci->Id<<8)|tplci->adapter->Id;
      if(tplci->tel) rId|=EXT_CONTROLLER;
      if(pty_cai[5]==ECT_EXECUTE)
      {
        WRITE_WORD(&SS_Ind[1],S_ECT);

        if(plci->vswitchstate!=3)
        {

        plci->ptyState = IDLE;
        plci->relatedPTYPLCI = NULL;
        plci->ptyState = 0;

        }

        dbug(1,dprintf("ECT OK"));
        sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);



      }
      else
      {
        switch (plci->ptyState)
        {
        case S_3PTY_BEGIN:
          plci->ptyState = CONNECTED;
          dbug(1,dprintf("3PTY ON"));
          break;

        case S_3PTY_END:
          plci->ptyState = IDLE;
          plci->relatedPTYPLCI = NULL;
          plci->ptyState = 0;
          dbug(1,dprintf("3PTY OFF"));
          break;
        }
        WRITE_WORD(&SS_Ind[1],pty_cai[5]+3);
        sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
      }
      break;

    case CALL_DEFLECTION:
      WRITE_WORD(&SS_Ind[1],pty_cai[5]);
      for(i=0; i<max_appl; i++)
      {
        if(application[i].CDEnable)
        {
          if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
          application[i].CDEnable = FALSE;
        }
      }
      break;

    case DEACTIVATION_DIVERSION:
    case ACTIVATION_DIVERSION:
      if(!plci->appl) break;
      WRITE_WORD(&CF_Ind[1],pty_cai[5]+2);
      WRITE_DWORD(&CF_Ind[6],plci->appl->S_Handle);
      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, CF_Ind);
      plci_remove(plci);
      break;

    case DIVERSION_INTERROGATE_CFU:
    case DIVERSION_INTERROGATE_CFB:
    case DIVERSION_INTERROGATE_CFNR:
    case DIVERSION_INTERROGATE_NUM:
    case CCBS_REQUEST:
    case CCBS_DEACTIVATE:
    case CCBS_INTERROGATE:
      if(!plci->appl) break;
      switch (pty_cai[5])
      {
        case DIVERSION_INTERROGATE_CFU:
        case DIVERSION_INTERROGATE_CFB:
        case DIVERSION_INTERROGATE_CFNR:
          dbug(1,dprintf("Interr_Div"));
          WRITE_WORD(&pty_cai[1],S_INTERROGATE_DIVERSION);
          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
          break;
        case DIVERSION_INTERROGATE_NUM:
          dbug(1,dprintf("Interr_Num"));
          WRITE_WORD(&pty_cai[1],S_INTERROGATE_NUMBERS);
          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
          break;
        case CCBS_REQUEST:
          dbug(1,dprintf("CCBS Request"));
          WRITE_WORD(&pty_cai[1],S_CCBS_REQUEST);
          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
          break;
        case CCBS_DEACTIVATE:
          dbug(1,dprintf("CCBS Deactivate"));
          WRITE_WORD(&pty_cai[1],S_CCBS_DEACTIVATE);
          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
          break;
        case CCBS_INTERROGATE:
          dbug(1,dprintf("CCBS Interrogate"));
          WRITE_WORD(&pty_cai[1],S_CCBS_INTERROGATE);
          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
          break;
      }
      WRITE_WORD(&pty_cai[4],0); /* Supplementary Service Reason */
      WRITE_DWORD(&pty_cai[6],plci->appl->S_Handle);
      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"wS",3, pty_cai);
      plci_remove(plci);
      break;

    case ACTIVATION_MWI:
    case DEACTIVATION_MWI:
      if(pty_cai[5]==ACTIVATION_MWI)
      {
        WRITE_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
      }
      else WRITE_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
      if(plci->cr_enquiry)
      {
        sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
        plci_remove(plci);
      }
      else
      {
        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
      }
      break;
    case MWI_INDICATION:
      if(pty_cai[0]>=0x12)
      {
        WRITE_WORD(&pty_cai[3],S_MWI_INDICATE);
        pty_cai[2]=pty_cai[0]-2; /* len Parameter */
        pty_cai[5]=pty_cai[0]-5; /* Supplementary Service-specific parameter len */
        if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_MWI))
        {
          if(plci->internal_command==GET_MWI_STATE) /* result on Message Waiting Listen */
          {
            sendf(plci->appl,_FACILITY_I,Id&0xf,0,"wS",3, &pty_cai[2]);
            plci_remove(plci);
            return;
          }
          else  sendf(plci->appl,_FACILITY_I,Id,0,"wS",3, &pty_cai[2]);
          pty_cai[0]=0;
        }
        else
        {
          for(i=0; i<max_appl; i++)
          {                     
            if(a->Notification_Mask[i]&SMASK_MWI)
            {
              sendf(&application[i],_FACILITY_I,Id&0x7,0,"wS",3, &pty_cai[2]);
              pty_cai[0]=0;
            }
          }
        }

        if(!pty_cai[0])
        { /* acknowledge */
          facility[2]= 0; /* returncode */
        }
        else facility[2]= 0xff;
      }
      else
      {
        /* reject */
        facility[2]= 0xff; /* returncode */
      }
      facility[0]= 2;
      facility[1]= MWI_RESPONSE; /* Function */
      add_p(plci,CAI,facility);
      add_p(plci,ESC,multi_ssext_parms[0]); /* remembered parameter -> only one possible */
      sig_req(plci,S_SERVICE,0);
      send_req(plci);
      plci->command = 0;
      next_internal_command (Id, plci);
      break;
    case CONF_ADD: /* OK */
    case CONF_BEGIN:
    case CONF_DROP:
    case CONF_ISOLATE:
    case CONF_REATTACH:
    case CONF_PARTYDISC:
      CONF_Ind[0]=9;
      CONF_Ind[3]=6;
      switch(pty_cai[5])
      {
      case CONF_BEGIN:
          WRITE_WORD(&CONF_Ind[1],S_CONF_BEGIN);
          if(pty_cai[0]==6)
          {
              d=pty_cai[6];
              WRITE_DWORD(&CONF_Ind[6],d); /* PartyID */
          }
          else
          {
              WRITE_DWORD(&CONF_Ind[6],0x0);
          }
          break;
      case CONF_ISOLATE:
          WRITE_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          break;
      case CONF_REATTACH:
          WRITE_WORD(&CONF_Ind[1],S_CONF_REATTACH);
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          break;
      case CONF_DROP:
          WRITE_WORD(&CONF_Ind[1],S_CONF_DROP);
          CONF_Ind[0]=5;
          CONF_Ind[3]=2;
          break;
      case CONF_ADD:
          WRITE_WORD(&CONF_Ind[1],S_CONF_ADD);
          d=pty_cai[6];
          WRITE_DWORD(&CONF_Ind[6],d); /* PartyID */
          tplci=plci->relatedPTYPLCI;
          if(tplci) tplci->ptyState = CONNECTED;
          break;
      case CONF_PARTYDISC:
          CONF_Ind[0]=7;
          CONF_Ind[3]=4;          
          WRITE_WORD(&CONF_Ind[1],S_CONF_PARTYDISC);
          d=pty_cai[6];
          WRITE_DWORD(&CONF_Ind[4],d); /* PartyID */
          break;
      }
      plci->ptyState = CONNECTED;
      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
      break;
    case CCBS_INFO_RETAIN:
    case CCBS_ERASECALLLINKAGEID:
    case CCBS_STOP_ALERTING:
      CONF_Ind[0]=5;
      CONF_Ind[3]=2;
      switch(pty_cai[5])
      {
      case CCBS_INFO_RETAIN:
        WRITE_WORD(&CONF_Ind[1],S_CCBS_INFO_RETAIN);
        break;
      case CCBS_STOP_ALERTING:
        WRITE_WORD(&CONF_Ind[1],S_CCBS_STOP_ALERTING);
    break;
      case CCBS_ERASECALLLINKAGEID:
        WRITE_WORD(&CONF_Ind[1],S_CCBS_ERASECALLLINKAGEID);
        CONF_Ind[0]=7;
        CONF_Ind[3]=4;
        CONF_Ind[6]=0;
        CONF_Ind[7]=0;
        break;
      }      
      w=pty_cai[6];
      WRITE_WORD(&CONF_Ind[4],w); /* PartyID */

      if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_CCBS))
      {
        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
      }
      else
      {
        for(i=0; i<max_appl; i++)
            if(a->Notification_Mask[i]&SMASK_CCBS)
                sendf(&application[i],_FACILITY_I,Id&0x7,0,"ws",3, CONF_Ind);
      }
      break;
    }
    break;
  case CALL_HOLD_REJ:
    cau = parms[7];
    if(cau)
    {
      i = _L3_CAUSE | cau[2];
      if(cau[2]==0) i = 0x3603;
    }
    else
    {
      i = 0x3603;
    }
    WRITE_WORD(&SS_Ind[1],S_HOLD);
    WRITE_WORD(&SS_Ind[4],i);
    if(plci->SuppState == HOLD_REQUEST)
    {
      plci->SuppState = IDLE;
      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
    }
    break;

  case CALL_HOLD_ACK:
    if(plci->SuppState == HOLD_REQUEST)
    {
      plci->SuppState = CALL_HELD;
      CodecIdCheck(a, plci);
      start_internal_command (Id, plci, hold_save_command);
    }
    break;

  case CALL_RETRIEVE_REJ:
    cau = parms[7];
    if(cau)
    {
      i = _L3_CAUSE | cau[2];
      if(cau[2]==0) i = 0x3603;
    }
    else
    {
      i = 0x3603;
    }
    WRITE_WORD(&SS_Ind[1],S_RETRIEVE);
    WRITE_WORD(&SS_Ind[4],i);
    if(plci->SuppState == RETRIEVE_REQUEST)
    {
      plci->SuppState = CALL_HELD;
      CodecIdCheck(a, plci);
      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
    }
    break;

  case CALL_RETRIEVE_ACK:
    WRITE_WORD(&SS_Ind[1],S_RETRIEVE);
    if(plci->SuppState == RETRIEVE_REQUEST)
    {
      plci->SuppState = IDLE;
      plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
      plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
      if(plci->tel)
      {
        mixer_set_bchannel_id_esc (plci, plci->b_channel);
        dbug(1,dprintf("RetrChannel=0x%x",plci->b_channel));
        SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
        if(plci->B2_prot==B2_TRANSPARENT && plci->B3_prot==B3_TRANSPARENT)
        {
          dbug(1,dprintf("Get B-ch"));
          start_internal_command (Id, plci, retrieve_restore_command);
        }
        else
          sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
      }
      else
        start_internal_command (Id, plci, retrieve_restore_command);
    }
    break;

  case INDICATE_IND:
    if(plci->State != LISTENING) {
      sig_req(plci,HANGUP,0);
      send_req(plci);
      break;
    }
    cip = find_cip(a,parms[4],parms[6]);
    cip_mask = 1L<<cip;
    dbug(1,dprintf("cip=%d,cip_mask=%lx",cip,cip_mask));
    clear_c_ind_mask (plci);
    if (!remove_started && !a->adapter_disabled)
    {
      set_c_ind_mask_bit (plci, MAX_APPL);
      group_optimization(a, plci);
      for(i=0; i<max_appl; i++) {
        if(application[i].Id
        && (a->CIP_Mask[i]&1 || a->CIP_Mask[i]&cip_mask)
        && CPN_filter_ok(parms[0],a,i)
        && test_group_ind_mask_bit (plci, i) ) {
          dbug(1,dprintf("storedcip_mask[%d]=0x%lx",i,a->CIP_Mask[i] ));
          set_c_ind_mask_bit (plci, i);
          dump_c_ind_mask (plci);
          plci->State = INC_CON_PENDING;
          plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
            CALL_DIR_IN | CALL_DIR_ANSWER;
          if(esc_chi[0]) {
            plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
            mixer_set_bchannel_id_esc (plci, plci->b_channel);
          }
          /* if a listen on the ext controller is done, check if hook states */
          /* are supported or if just a on board codec must be activated     */
          if(a->codec_listen[i] && !a->AdvSignalPLCI) {
            if(a->profile.Global_Options & HANDSET)
              plci->tel = ADV_VOICE;
            else if(a->profile.Global_Options & ON_BOARD_CODEC)
              plci->tel = CODEC;
            if(plci->tel) Id|=EXT_CONTROLLER;
            a->codec_listen[i] = plci;
          }

          sendf(&application[i],_CONNECT_I,Id,0,
                "wSSSSSSSbSSSSS", cip,    /* CIP                 */
                             parms[0],    /* CalledPartyNumber   */
                             multi_CiPN_parms[0],    /* CallingPartyNumber  */
                             parms[2],    /* CalledPartySubad    */
                             parms[3],    /* CallingPartySubad   */
                             parms[4],    /* BearerCapability    */
                             parms[5],    /* LowLC               */
                             parms[6],    /* HighLC              */
                             ai_len,      /* nested struct add_i */
                             add_i[0],    /* B channel info    */
                             add_i[1],    /* keypad facility   */
                             add_i[2],    /* user user data    */
                             add_i[3],    /* nested facility   */
                             multi_CiPN_parms[1]    /* second CiPN(SCR)   */
                             );
          SendSSExtInd(&application[i],
                        plci,
                        Id,
                        multi_ssext_parms);
          SendSetupInfo(&application[i],
                        plci,
                        Id,
                        parms,
                        SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, TRUE));
        }
      }
      clear_c_ind_mask_bit (plci, MAX_APPL);
      dump_c_ind_mask (plci);
    }
    if(c_ind_mask_empty (plci)) {
      sig_req(plci,HANGUP,0);
      send_req(plci);
      plci->State = IDLE;
    }
    plci->notifiedcall = 0;
    a->listen_active--;
    listen_check(a);
    break;

  case CALL_PEND_NOTIFY:
    plci->notifiedcall = 1;
    listen_check(a);
    break;

  case CALL_IND:
  case CALL_CON:
    if(plci->State==ADVANCED_VOICE_SIG || plci->State==ADVANCED_VOICE_NOSIG)
    {
      if(plci->internal_command==PERM_COD_CONN_PEND)
      {
        if(plci->State==ADVANCED_VOICE_NOSIG)
        {
          dbug(1,dprintf("***Codec OK"));
          if(a->AdvSignalPLCI)
          {
            tplci = a->AdvSignalPLCI;
            if(tplci->spoofed_msg)
            {
              dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci->spoofed_msg));
              tplci->command = 0;
              tplci->internal_command = 0;
              x_Id = ((word)tplci->Id<<8)|tplci->adapter->Id | 0x80;
              switch (tplci->spoofed_msg)
              {
              case CALL_RES:
                tplci->command = _CONNECT_I|RESPONSE;
                api_load_msg (&tplci->saved_msg, saved_parms);
                add_b1(tplci,&saved_parms[1],0,tplci->B1_facilities);
                if (tplci->adapter->Info_Mask[tplci->appl->Id-1] & 0x200)
                {
                  /* early B3 connect (CIP mask bit 9) no release after a disc */
                  add_p(tplci,LLI,"\x01\x01");
                }
                add_s(tplci, CONN_NR, &saved_parms[2]);
                add_s(tplci, LLC, &saved_parms[4]);
                add_ai(tplci, &saved_parms[5]);
                tplci->State = INC_CON_ACCEPT;
                sig_req(tplci, CALL_RES,0);
                send_req(tplci);
                break;

              case AWAITING_SELECT_B:
                dbug(1,dprintf("Select_B continue"));
                start_internal_command (x_Id, tplci, select_b_command);
                break;

              case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
                if(!tplci->Sig.Id)
                {
                  dbug(1,dprintf("No SigID!"));
                  sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI);
                  plci_remove(tplci);
                  break;
                }
                tplci->command = _MANUFACTURER_R;
                api_load_msg (&tplci->saved_msg, saved_parms);
                dir = saved_parms[2].info[0];
                if(dir==1) {
                  sig_req(tplci,CALL_REQ,0);
                }
                else if(!dir){
                  sig_req(tplci,LISTEN_REQ,0);
                }
                send_req(tplci);
                sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,0);
                break;

              case (CALL_REQ|AWAITING_MANUF_CON):
                sig_req(tplci,CALL_REQ,0);
                send_req(tplci);
                break;

              case CALL_REQ:
                if(!tplci->Sig.Id)
                {
                  dbug(1,dprintf("No SigID!"));
                  sendf(tplci->appl,_CONNECT_R|CONFIRM,tplci->adapter->Id,0,"w",_OUT_OF_PLCI);
                  plci_remove(tplci);
                  break;
                }
                tplci->command = _CONNECT_R;
                api_load_msg (&tplci->saved_msg, saved_parms);
                add_s(tplci,CPN,&saved_parms[1]);
                add_s(tplci,DSA,&saved_parms[3]);
                add_ai(tplci,&saved_parms[9]);
                sig_req(tplci,CALL_REQ,0);
                send_req(tplci);
                break;

              case CALL_RETRIEVE:
                tplci->command = C_RETRIEVE_REQ;
                sig_req(tplci,CALL_RETRIEVE,0);
                send_req(tplci);
                break;
              }
              tplci->spoofed_msg = 0;
              if (tplci->internal_command == 0)
                next_internal_command (x_Id, tplci);
            }
          }
          next_internal_command (Id, plci);
          break;
        }
        dbug(1,dprintf("***Codec Hook Init Req"));
        plci->internal_command = PERM_COD_HOOK;
        add_p(plci,FTY,"\x01\x09");             /* Get Hook State*/
        sig_req(plci,TEL_CTRL,0);
        send_req(plci);
      }
    }
    else if(plci->command != _MANUFACTURER_R  /* old style permanent connect */
    && plci->State!=INC_ACT_PENDING)
    {
      mixer_set_bchannel_id_esc (plci, plci->b_channel);
      if(plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */
      {
        chi[2] = plci->b_channel;
        SetVoiceChannel(a->AdvCodecPLCI, chi, a);
      }
      sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"Sss",parms[21],"","");
      plci->State = INC_ACT_PENDING;
    }
    break;

  case TEL_CTRL:
    Number = 0;
    ie = multi_fac_parms[0]; /* inspect the facility hook indications */
    if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
      switch (ie[1]&0x91) {
        case 0x80:   /* hook off */
        case 0x81:
          if(plci->internal_command==PERM_COD_HOOK)
          {
            dbug(1,dprintf("init:hook_off"));
            plci->hook_state = ie[1];
            next_internal_command (Id, plci);
            break;
          }
          else /* ignore doubled hook indications */
          {
            if( ((plci->hook_state)&0xf0)==0x80)
            {
              dbug(1,dprintf("ignore hook"));
              break;
            }
            plci->hook_state = ie[1]&0x91;
          }
          /* check for incoming call pending */
          /* and signal '+'.Appl must decide */
          /* with connect_res if call must   */
          /* accepted or not                 */
          for(i=0, tplci=NULL;i<max_appl;i++){
            if(a->codec_listen[i]
            && (a->codec_listen[i]->State==INC_CON_PENDING
              ||a->codec_listen[i]->State==INC_CON_ALERT) ){
              tplci = a->codec_listen[i];
              tplci->appl = &application[i];
            }
          }
          /* no incoming call, do outgoing call */
          /* and signal '+' if outg. setup   */
          if(!a->AdvSignalPLCI && !tplci){
            if((i=get_plci(a))) {
              a->AdvSignalPLCI = &a->plci[i-1];
              tplci = a->AdvSignalPLCI;
              tplci->tel  = ADV_VOICE;
              WRITE_WORD(&voice_cai[5],a->AdvSignalAppl->MaxDataLength);
              if (a->Info_Mask[a->AdvSignalAppl->Id-1] & 0x200){
                /* early B3 connect (CIP mask bit 9) no release after a disc */
                add_p(tplci,LLI,"\x01\x01");
              }
              add_p(tplci, CAI, voice_cai);
              add_p(tplci, OAD, a->TelOAD);
              add_p(tplci, OSA, a->TelOSA);
              add_p(tplci,SHIFT|6,NULL);
              add_p(tplci,SIN,"\x02\x01\x00");
              add_p(tplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
              sig_req(tplci,ASSIGN,DSIG_ID);
              a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ;
              a->AdvSignalPLCI->command = 0;
              tplci->appl = a->AdvSignalAppl;
              tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
              send_req(tplci);
            }

          }

          if(!tplci) break;
          Id = ((word)tplci->Id<<8)|a->Id;
          Id|=EXT_CONTROLLER;
          sendf(tplci->appl,
                _FACILITY_I,
                Id,
                0,
                "ws", (word)0, "\x01+");
          break;

        case 0x90:   /* hook on  */
        case 0x91:
          if(plci->internal_command==PERM_COD_HOOK)
          {
            dbug(1,dprintf("init:hook_on"));
            plci->hook_state = ie[1]&0x91;
            next_internal_command (Id, plci);
            break;
          }
          else /* ignore doubled hook indications */
          {
            if( ((plci->hook_state)&0xf0)==0x90) break;
            plci->hook_state = ie[1]&0x91;
          }
          /* hangup the adv. voice call and signal '-' to the appl */
          if(a->AdvSignalPLCI) {
            Id = ((word)a->AdvSignalPLCI->Id<<8)|a->Id;
            if(plci->tel) Id|=EXT_CONTROLLER;
            sendf(a->AdvSignalAppl,
                  _FACILITY_I,
                  Id,
                  0,
                  "ws", (word)0, "\x01-");
            a->AdvSignalPLCI->internal_command = HOOK_ON_REQ;
            a->AdvSignalPLCI->command = 0;
            sig_req(a->AdvSignalPLCI,HANGUP,0);
            send_req(a->AdvSignalPLCI);
          }
          break;
      }
    }
    break;

  case RESUME:
    clear_c_ind_mask_bit (plci, (word)(plci->appl->Id-1));
    WRITE_WORD(&resume_cau[4],GOOD);
    sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau);
    break;

  case SUSPEND:
    clear_c_ind_mask (plci);

    if (plci->NL.Id && !plci->nl_remove_id) {
      mixer_remove (plci);
      nl_req_ncci(plci,REMOVE,0);
    }
    if (!plci->sig_remove_id) {
      plci->internal_command = 0;
      sig_req(plci,REMOVE,0);
    }
    send_req(plci);
    if(!plci->channels) {
      sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, "\x05\x04\x00\x02\x00\x00");
      sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
    }
    break;

  case SUSPEND_REJ:
    break;

  case HANGUP:
    plci->hangup_flow_ctrl_timer=0;
    if(plci->manufacturer && plci->State==LOCAL_CONNECT) break;
    cau = parms[7];
    if(cau) {
      i = _L3_CAUSE | cau[2];
      if(cau[2]==0) i = 0;
      else if(cau[2]==8) i = _L1_ERROR;
      else if(cau[2]==9 || cau[2]==10) i = _L2_ERROR;
      else if(cau[2]==5) i = _CAPI_GUARD_ERROR;
    }
    else {
      i = _L3_ERROR;
    }

    if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT)
    {
      for(i=0; i<max_appl; i++)
      {
        if(test_c_ind_mask_bit (plci, i))
          sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
      }
    }
    else
    {
      clear_c_ind_mask (plci);
    }
    if(!plci->appl)
    {
      if (plci->State == LISTENING)
      {
        plci->notifiedcall=0;
        a->listen_active--;
      }
      plci->State = INC_DIS_PENDING;
      if(c_ind_mask_empty (plci))
      {
        plci->State = IDLE;
        if (plci->NL.Id && !plci->nl_remove_id)
        {
          mixer_remove (plci);
          nl_req_ncci(plci,REMOVE,0);
        }
        if (!plci->sig_remove_id)
        {
          plci->internal_command = 0;
          sig_req(plci,REMOVE,0);
        }
        send_req(plci);
      }
    }
    else
    {
        /* collision of DISCONNECT or CONNECT_RES with HANGUP can   */
        /* result in a second HANGUP! Don't generate another        */
        /* DISCONNECT                                               */
      if(plci->State!=IDLE && plci->State!=INC_DIS_PENDING)
      {
        if(plci->State==RESUMING)
        {
          WRITE_WORD(&resume_cau[4],i);
          sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau);
        }
        plci->State = INC_DIS_PENDING;
        sendf(plci->appl,_DISCONNECT_I,Id,0,"w",i);
      }
    }
    break;

  case SSEXT_IND:
    SendSSExtInd(NULL,plci,Id,multi_ssext_parms);
    break;

  case VSWITCH_REQ:
    VSwitchReqInd(plci,Id,multi_vswitch_parms);
    break;
  case VSWITCH_IND:
 if(plci->relatedPTYPLCI &&
  plci->vswitchstate==3 &&
  plci->relatedPTYPLCI->vswitchstate==3 &&
  parms[MAXPARMSIDS-1][0])
 {
  add_p(plci->relatedPTYPLCI,SMSG,parms[MAXPARMSIDS-1]);
  sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
  send_req(plci->relatedPTYPLCI);
 }
    else VSwitchReqInd(plci,Id,multi_vswitch_parms);
    break;

  }
}

Generated by GNU enscript 1.6.4.