⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.pas

📁 由内线接电话终端
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  AppPath := ExtractFilePath(Paramstr(0));
  RouterINI := TIniFile.Create(AppPath + 'Router.ini');
  RouterINI.WriteInteger('Config', 'Count', SGRouter.RowCount - 1);
  for i:= 1 to SGRouter.RowCount - 1 do
  begin
    RouterINI.WriteString('Router' + inttostr(i), 'Number', Trim(SGRouter.Cells[1, i]));
    RouterINI.WriteString('Router' + inttostr(i), 'SubLen', Trim(SGRouter.Cells[2, i]));
    RouterINI.WriteString('Router' + inttostr(i), 'SubNumber', Trim(SGRouter.Cells[3, i]));
    RouterINI.WriteString('Router' + inttostr(i), 'LineType', Trim(SGRouter.Cells[4, i]));
    RouterINI.WriteString('Router' + inttostr(i), 'Line', Trim(SGRouter.Cells[5, i]));
    RouterINI.WriteString('Router' + inttostr(i), 'Comment', Trim(SGRouter.Cells[6, i]));

  end;
  RouterINI.Destroy;
  ShowMessage('保存完成');
end;

//编辑路由表
procedure TfrmExchange.btnEditClick(Sender: TObject);
begin
  if mRow <> 0 then
  if (EdNumber.Text <> '') and (EdSubLen.Text <> '') and (EdSubNumber.Text <> '') and (EdLineType.Text <> '') and (EdLine.Text <> '') and (EdComment.Text <> '') then
  begin
    SGRouter.Cells[1, mRow] := EdNumber.Text;
    SGRouter.Cells[2, mRow] := EdSubLen.Text;
    SGRouter.Cells[3, mRow] := EdSubNumber.Text;
    SGRouter.Cells[4, mRow] := EdLineType.Text;
    SGRouter.Cells[5, mRow] := EdLine.Text;
    SGRouter.Cells[6, mRow] := EdComment.Text;

    EdNumber.Text := '';
    EdSubLen.Text := '';
    EdSubNumber.Text := '';
    EdLineType.Text := '';
    EdLine.Text := '';
    EdComment.Text := '';

    mRow := 0;
  end
  else
    ShowMessage('请确认各项是否正确!');
end;

//通道非正常释放的原因
function TfrmExchange.ReleaseErrReason(Param : Integer) : String;
begin
  case Param of
  P_R_NODIALTONE:
    result := '没有检测到拨号音';
  P_R_NOANSWER:
    result := '没有响应';
  P_R_RINGTIMEOUT:
    result := '振铃超时';
  P_R_LINEUSED:
    result := '线路正被对方占用或没有复位完成';
  P_R_CONGESTION:
    result := '设备拥塞';
  P_R_INCOMPLETE:
    result := '地址不全';
  P_R_FAILURE:
    result := '呼入故障';
  P_R_CALLBARRING:
    result := '接入拒绝';
  P_R_BUSYLOCAL:
    result := '市话忙';
  P_R_BUSYDDD:
    result := '长话忙';
  P_R_NULLDN:
    result := '空号';
  P_R_NODIGITALPATH:
    result := '没有数字通路';
  end;
end;

//呼出错误原因
function TfrmExchange.CalloutErrReason(Param : Integer) : String;
begin
  case Param of
    P_CC_CHBUSY:
      result := '通道使用中';
    P_CC_CHCALLMASK:
      result := '在配置中通道呼出被禁止';
    P_CC_CHNOTEXIST:
      result := '通道号不存在';
    P_CC_PCMNOSYN:
      result := '数字线端口没有同步';
    P_CC_CANNOTASSIGNCH:
      result := '不支持用户设置的呼出通道指定的方式';
    P_CC_REMOTENOANSWER:
      result := '对方没有响应';
//    P_CC_DPCUNAVAILABLE:
//      result := 'DPC不可到达';
  end;
end;

function strmatch(s1:string;s2:string):boolean; //s1包含s2或s2包含s1则返回true,否则返回false
var
  Len,Len2:integer;
begin
  result:=true;
  Len:=length(s1);
  Len2:=length(s2);
  if(len>len2)then
    len:=len2;
  if(len=0)then
     exit; //空串认为匹配
  if(copy(s1,1,len)=copy(s2,1,len)) then //最大匹配
    exit; //成功
  result:=false; //失败     
end;

//收到呼入消息
procedure TfrmExchange.PCICARD1L1Call(ASender: TObject; ChType, ChIndex,
  Func, Param, SubParam1, SubParam2: Smallint; const Called,
  Caller: WideString);
var
  i, j, k, PcmIndex : Integer;
  strCol, strData : String;
  Len : Integer;
  tmpCH : TAgentState;
  digitCH, dgCH : TDigitState;
  CalledType, CalledIndex : Integer;
begin
{  Memo.Lines.Add('Call : ChType->' + inttostr(ChType) +
                  '  ChIndex->' + inttostr(ChIndex) +
                  '  Func->' + inttostr(Func) +
                  '  Param->' + inttostr(Param) +
                  '  SubParam1->' + inttostr(SubParam1) +
                  '  SubParam2->' + inttostr(SubParam2) +
                  '  Called->' + Called +
                  '  Caller->' + Caller
                 );
}
  if bStart = False then     //交换功能不可用
  begin
    Exit;
  end;

  case ChType of
  CHTYPE_AGENT:   //内线呼入
  begin
    memo.Lines.Add('座席线路呼入通道号='+inttostr(chindex)+',被叫='+called +',主叫='+caller);

    PCH := AgentLamp.DataList.GetChPointer(ChIndex);    //取第ChIndex通道的状态保存结构
    if PCH.State = 3 then     //通道通话中,退出
      Exit;

    if Func = 0 then    //普通呼叫
    begin
      AgentLamp.SetLampRed(ChIndex, ChIndex, '电话呼入  ');
      PCH.State := 1;   //将通道状态置为忙

      //保存主叫号码,可在"配置器"->"逻辑通道"->"模拟内线"->"本端号码"处设置某内线通道号码
      //如果没有在配置器中设置内线通道号码,则需要从路由表中读取主叫
      if Caller <> '' then
      begin
        PCH.Caller := Caller;
      end
      else
      begin
        i := GetChRow(ChType, ChIndex);
        PCH.Caller := Trim(SGRouter.Cells[NumberCol, i]) + Trim(SGRouter.Cells[SubNumberCol, i]);
      end;
    end;

    if Called <> '' then                      //如果收到被叫号码
    begin
      PCH.Data := PCH.Data + Called;          //保存被叫号码
      AgentLamp.SetLampComment(ChIndex, '收号:' + Trim(PCH.Data) + '  ');

      if PCH.AcmOk = False then               //号码没有收全
      begin
        for i := 1 to PCH.SimilarCount do     //判断是否收局号足够,即判断收集的被叫号码和路由表中号码的匹配情况
        begin
          strCol := Trim(SGRouter.Cells[NumberCol, PCH.SimilarRow[i - 1]]);     //能匹配行的路由表号码
          strData := Trim(PCH.Data);     //收到的被叫

          SetLength(strCol, Length(strData));
          if strCol = strData then    //如果在路由表号码中能匹配到已收的被叫号码
          begin
            j := j + 1;    //将匹配行计数加一
            PCH.SimilarRow[j - 1] := PCH.SimilarRow[i - 1];    //保存匹配行所在的行到匹配数组中
          end;
        end;

        PCH.SimilarCount := j;    //保存能匹配的行数

        if PCH.SimilarCount < 1 then   //没有找到能匹配的行
        begin
          PCH.State := 0;     //设置此内线通道状态为0(空闲)
          PCH.Data  := '';    //暂存数据为空
          PCH.SimilarCount := SGRouter.RowCount - 1;  //设置默认匹配数为路由表路由数
          PCICARD1.L1Media(CHTYPE_AGENT, ChIndex, F_MEDIA_Tx_TTStr, RESPAR_PFIRSTMSG, RESTYPE_VOCPCM, 0, ',你拨的是空号,请虫新拨号', 0, 0);
          PCICARD1.L1Media(ChType, ChIndex, F_MEDIA_Tx_CPSign, RESPAR_PLOOPMSG, RESTYPE_VOCPCM, 0, '', 3, 0);
          Exit;
        end
        else if PCH.SimilarCount = 1 then   //在路由表中只有一个匹配的路由
        begin  
          if Length(PCH.Data) = Length(SGRouter.Cells[NumberCol, PCH.SimilarRow[0]]) then  //后续号码收全
          begin
            PCH.AcmOk := True;    //置号码(局号)收全标志
            PCH.CalledRow := PCH.SimilarRow[0];   //将被叫所在的行保存到通道状态结构中
          end;
        end
        else   //在路由表中不只一个匹配的路由
        begin
          PCH.SimilarCount := j;
          if Length(PCH.Data) = Length(SGRouter.Cells[NumberCol, PCH.SimilarRow[0]]) then
          begin
            PCH.AcmOk := True;    //置号码(局号)收全标志
          end;
        end;
      end;      // end of if call <> ''

      if PCH.AcmOk = True then    //号码(局号)收全
      begin
        Len := Length(SGRouter.Cells[NumberCol, PCH.SimilarRow[0]]) + strtoint(SGRouter.Cells[SubLenCol, PCH.SimilarRow[0]]);
        if Length(PCH.Data) = Len then          //收号码长度相同,准备呼出
        begin
          for i := 1 to PCH.SimilarCount do
          begin
            if Trim(PCH.Data) = Trim(SGRouter.Cells[NumberCol, PCH.SimilarRow[i - 1]] + SGRouter.Cells[SubNumberCol, PCH.SimilarRow[i - 1]]) then     // 如果收号成功
            begin
              CopyMemory(@PCH.Called[0], @PCH.Data[Length(SGRouter.Cells[NumberCol, PCH.SimilarRow[i - 1]])], strtoint(SGRouter.Cells[SubLenCol, PCH.SimilarRow[i - 1]]) + 1);               //保存被叫号
              AgentLamp.SetLampComment(ChIndex, '号码收全,呼出   ');            //找到呼出号码
              PCH.CalledRow := PCH.SimilarRow[i - 1];                           //保存呼出号码的行
              PCH.Called := SGRouter.Cells[NumberCol, PCH.CalledRow] + SGRouter.Cells[SubNumberCol, PCH.CalledRow];            //被叫号码
              k := GetChRow(ChType, ChIndex);
              PCH.Caller := SGRouter.Cells[NumberCol, k] + SGRouter.Cells[SubNumberCol, k];

              tmpCH := AgentLamp.DataList.GetChPointer(strtoint(SGRouter.cells[LineCol, PCH.CalledRow]));
              tmpCH.State := 2;
              tmpCH.CallerRow := ChIndex;

              CalledType := StrToChType(LineTypeCol, PCH.CalledRow);
              CalledIndex := strtoint(SGRouter.cells[LineCol, PCH.CalledRow]);

              if (CalledType = ChType) and (CalledIndex = ChIndex) then
              begin
                PCICARD1.L1Media(ChType, ChIndex, F_MEDIA_Tx_CPSign, RESPAR_PFIRSTMSG or RESPAR_PLOOPMSG, RESTYPE_VOCPCM, 0, '', 3, 0);
              end
              else
              begin
                PCICARD1.L1Call(CalledType, CalledIndex, 0, 0, ChType, ChIndex, PCH.Called, PCH.Caller);
              end;
              break;
            end
            else if  Trim(SGRouter.Cells[SubNumberCol, PCH.SimilarRow[i - 1]]) = Trim('XXXXXXXX') then  //为数字线,用PCM呼出
            begin
              CopyMemory(@PCH.Called[0], @PCH.Data[Length(SGRouter.Cells[NumberCol, PCH.SimilarRow[i - 1]])], strtoint(SGRouter.Cells[SubLenCol, PCH.SimilarRow[i - 1]]) + 1);
              k := GetChRow(ChType, ChIndex);
              PcmIndex :=  strtoint(SGRouter.Cells[LineCol, PCH.SimilarRow[i - 1]]) * 32;

              dgCH := DigitLamp.DataList.GetChPointer(PcmIndex div 32);
              if dgCH.UsedCount < 31 then             //如果数字线有空闲通道,则对此通道呼出
              begin
                CalledType := StrToChType(LineTypeCol, PCH.SimilarRow[i - 1]);
                CalledIndex := PcmIndex;
                if (CalledIndex div 32) > DigitNum then
                begin
                  ShowMessage('配置的PCM号超出实际PCM!');
                  Exit;
                end;
//                PCICARD1.L1Call(CalledType, CalledIndex, 0, 0, ChType, ChIndex, SGRouter.Cells[NumberCol, k] + SGRouter.Cells[SubNumberCol, k], Trim(PCH.Caller));
                 PCICARD1.L1Call(CalledType, CalledIndex, 0, 0, ChType, ChIndex, Trim(PCH.Called), Trim(PCH.Caller));
                AgentLamp.SetLampComment(ChIndex, '号码收全,呼出   ');            //找到呼出号码
                break;
              end;
            end
            else
            begin
            if i = PCH.SimilarCount then      //没有此号码
            begin
              PCH.State := 0;
              PCH.Data  := '';
              PCH.SimilarCount := SGRouter.RowCount - 1;
              PCICARD1.L1Media(CHTYPE_AGENT, ChIndex, F_MEDIA_Tx_TTStr, RESPAR_PFIRSTMSG, RESTYPE_VOCPCM, 0, ',你拨的是空号,请虫新拨号', 0, 0);
              PCICARD1.L1Media(ChType, ChIndex, F_MEDIA_Tx_CPSign,  RESPAR_PLOOPMSG, RESTYPE_VOCPCM, 0, '', 3, 0);
              Exit;
            end;  // end of else
          end;  // end of for i := 1 to PCH.SimilarCount do
        end;   // end of if Length(PCH.Data) = Len then

        end;  // end of if length(pch.data) = len then
      end;  // end of pch.acmok = true then

    end; // end of call <> ''
  end; // end of CHTYPE_AGENT


  CHTYPE_DTNO1, CHTYPE_DTNO7, CHTYPE_DTDSS1, CHTYPE_DTNO7ISUP:    //如果是数字线收到呼入
  begin
    memo.Lines.Add('数字线路呼入通道号='+inttostr(chindex)+',被叫='+called +',主叫='+caller);
    digitCH := DigitLamp.DataList.GetChPointer( ChIndex div 32 );
    if Called <> '' then
    begin
      for i := 1 to SGRouter.RowCount - 1 do
      begin
        if strmatch((SGRouter.Cells[NumberCol, i] + SGRouter.Cells[SubNumberCol, i]),Called) then     //被叫匹配局号
         begin
          DigitLamp.SetLampRed( ChIndex div 32, ChIndex div 32, '    呼入');
          j := StrToChType(LineTypeCol, i);
          PCICARD1.L1Call(j, strtoint(SGRouter.Cells[LineCol, i]), 0, 0, ChType, ChIndex, Caller, Called);//自动分配呼出
          break;
        end;

        if i = SGRouter.RowCount then    //查完整个路由表都没有匹配的局号
        begin
          PCICARD1.L1Release(ChType, ChIndex, 0, 0);
        end;
      end;
    end;
  end;

  end; // end of Case

end;

function TfrmExchange.StrToChType(Col : Integer; Row : Integer) : Integer;
var
  i : Integer;
  tmpStr : String;
begin
  tmpStr := SGRouter.Cells[Col, Row];
  if Trim(tmpStr) = '内线' then
  begin
    result := CHTYPE_AGENT;
  end
  else if Trim(tmpStr) = '一号信令' then
  begin
    result := CHTYPE_DTNO1;
  end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -