📄 main.pas
字号:
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 + -