Delphi之东进数字语音卡(SS1)可复用源码
作者:成晓旭
Blog:http://blog.csdn.net/cxxsoft
(声明:欢迎转载,请保证文章的完整性)
        由于工作原因,本人将不在从事商业应有软件的开发工作,现在开始逐级“解密”自己以前写的部分自有产权代码,但愿对后来的朋友有点参考、借鉴的价值。
        本代码是本人开发的计划开源的CIT通用平台的东进1号信令数字语言卡封装,设计思路与模拟语音卡的封装非常类似,在此不再赘述。有兴趣的朋友,请参考本人的另外一篇文章《Delphi之东进模拟语音卡(D
        核心思想是一致的:卡、通道分别设计和实现;通道内,核心的还是“状态机模式”轮巡通道状态来管理硬件卡设备;板卡封装内实现不实现任何业务接口,但允许动态注入实现业务接口的对象,来近一步分发、处理板卡层采集的基础数据。
卡类源代码:
 //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //
// //      产品名称:   成晓旭的个人软件Delphi源码库
//      产品名称:   成晓旭的个人软件Delphi源码库 //      产品版本:   CXXSoft delphi code source lib 2.0
//      产品版本:   CXXSoft delphi code source lib 2.0 //      模块名称:   Delphi之东进数字语音卡类
//      模块名称:   Delphi之东进数字语音卡类 //      模块描述:
//      模块描述:    //      单元文件:   unDJCardSS1.pas
//      单元文件:   unDJCardSS1.pas    //      开发作者:   成晓旭
//      开发作者:   成晓旭 //      作者blog:   http://blog.csdn.net/CXXSoft
//      作者blog:   http://blog.csdn.net/CXXSoft //      备注:       任何人使用此文件时,请保留此段自述文件,谢谢!
//      备注:       任何人使用此文件时,请保留此段自述文件,谢谢! //      开发时间:   2005-01-09
//      开发时间:   2005-01-09 //      修改历史:
//      修改历史:    //      修改描述:
//      修改描述: //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ unit unDJCardSS1;
unit unDJCardSS1;
 interface
interface uses
uses Windows,SysUtils,Classes,
  Windows,SysUtils,Classes, unBaseDefine,
  unBaseDefine, Tce1_32,
  Tce1_32, Tce1_FSK;
  Tce1_FSK;
 type
type TDJCommCardSS1 = class(TThread)
  TDJCommCardSS1 = class(TThread) private
  private onTrunkEvent:TTrunkSatausEvent;
    onTrunkEvent:TTrunkSatausEvent; onRecEvent:TTrunkReceiveEvent;
    onRecEvent:TTrunkReceiveEvent; isLoadFSK:boolean;
    isLoadFSK:boolean; CommIsFSK:boolean;
    CommIsFSK:boolean; Trunks:array of TObject;
    Trunks:array of TObject; function  InitCardForFSK():boolean;
    function  InitCardForFSK():boolean; procedure FreeCardForFSK();
    procedure FreeCardForFSK(); procedure ThreadKernelProcess();
    procedure ThreadKernelProcess(); protected
  protected procedure Execute(); override;
    procedure Execute(); override; public
  public TotalTrunkNum,InTrunkNum,OutTrunkNum:Word;
    TotalTrunkNum,InTrunkNum,OutTrunkNum:Word; TrunkConnected:array of boolean;
    TrunkConnected:array of boolean;
 constructor Create(const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
    constructor Create(const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent); destructor Destroy(); override;
    destructor Destroy(); override; //初始化中继卡
    //初始化中继卡 function  InitCard(const isFSKComm: boolean): Boolean;
    function  InitCard(const isFSKComm: boolean): Boolean; //释放中继卡
    //释放中继卡   function  FreeCommCard():boolean;
    function  FreeCommCard():boolean; //开始运行中继卡管理模块
    //开始运行中继卡管理模块 procedure StartRunCommModule();
    procedure StartRunCommModule(); //获取一个空闲通道(指定通道类型)
    //获取一个空闲通道(指定通道类型) function  GetAFreeTrunkByType(const aTrunkType:TTrunkType):integer;
    function  GetAFreeTrunkByType(const aTrunkType:TTrunkType):integer; //获取一个空闲呼出通道
    //获取一个空闲呼出通道 function  GetAFreeTrunkByOut():integer;
    function  GetAFreeTrunkByOut():integer; //挂断指定通道
    //挂断指定通道 procedure HangOfByTrunkID(const aChannelID:integer);
    procedure HangOfByTrunkID(const aChannelID:integer); //通过指定通道拨号
    //通过指定通道拨号 procedure DialPhoneByTrunkID(const aChannelID:integer;const phoneNumber,callerNumber:PChar;const aDevID:integer=-1);
    procedure DialPhoneByTrunkID(const aChannelID:integer;const phoneNumber,callerNumber:PChar;const aDevID:integer=-1); //通过指定通道发送数据
    //通过指定通道发送数据 function  SendStringByTrunkID(const aChannelID:integer;const sendBuffer:PChar):boolean;
    function  SendStringByTrunkID(const aChannelID:integer;const sendBuffer:PChar):boolean; end;
  end;
 implementation
implementation
 { TDJCommCardSS1 }
{ TDJCommCardSS1 } uses
uses unDJChannelSS1;
  unDJChannelSS1;
 constructor TDJCommCardSS1.Create(const aStateEvent: TTrunkSatausEvent;
constructor TDJCommCardSS1.Create(const aStateEvent: TTrunkSatausEvent; const aRecEvent:TTrunkReceiveEvent);
  const aRecEvent:TTrunkReceiveEvent); begin
begin inherited Create(true);
  inherited Create(true); Self.FreeOnTerminate := true;
  Self.FreeOnTerminate := true; onTrunkEvent := aStateEvent;
  onTrunkEvent := aStateEvent; onRecEvent := aRecEvent;
  onRecEvent := aRecEvent; end;
end;
 destructor TDJCommCardSS1.Destroy();
destructor TDJCommCardSS1.Destroy(); begin
begin Self.Suspend();
  Self.Suspend(); Self.Terminate();
  Self.Terminate(); FreeCommCard();
  FreeCommCard(); end;
end;
 procedure TDJCommCardSS1.DialPhoneByTrunkID(const aChannelID: integer;
procedure TDJCommCardSS1.DialPhoneByTrunkID(const aChannelID: integer; const phoneNumber, callerNumber: PChar;const aDevID:integer);
  const phoneNumber, callerNumber: PChar;const aDevID:integer); begin
begin if (aChannelID > ErrTrunkId) and (DJTrk_CheckTrunkFree(aChannelID)) then
  if (aChannelID > ErrTrunkId) and (DJTrk_CheckTrunkFree(aChannelID)) then TDJCommChannelsSS1(Trunks[aChannelID]).StartDialPhone(phoneNumber,callerNumber,aDevID,);
    TDJCommChannelsSS1(Trunks[aChannelID]).StartDialPhone(phoneNumber,callerNumber,aDevID,); end;
end;
 procedure TDJCommCardSS1.Execute;
procedure TDJCommCardSS1.Execute; begin
begin while NOT Terminated do
  while NOT Terminated do begin
  begin Synchronize(ThreadKernelProcess);
    Synchronize(ThreadKernelProcess); Sleep(1);
    Sleep(1); end;
  end; end;
end;
 procedure TDJCommCardSS1.FreeCardForFSK();
procedure TDJCommCardSS1.FreeCardForFSK(); begin
begin if CommIsFSK and isLoadFSK then
  if CommIsFSK and isLoadFSK then begin
  begin DJFsk_Release();
    DJFsk_Release(); end;
  end; end;
end;
 function TDJCommCardSS1.FreeCommCard(): boolean;
function TDJCommCardSS1.FreeCommCard(): boolean; var
var Loop:Word;
  Loop:Word; begin
begin Sleep(1000);
  Sleep(1000); if TotalTrunkNum > 0 then
  if TotalTrunkNum > 0 then begin
  begin for Loop:= 0 to TotalTrunkNum - 1 do
    for Loop:= 0 to TotalTrunkNum - 1 do begin
    begin if Assigned(TDJCommChannelsSS1(Trunks[Loop])) then
      if Assigned(TDJCommChannelsSS1(Trunks[Loop])) then begin
      begin TDJCommChannelsSS1(Trunks[Loop]).Free();
        TDJCommChannelsSS1(Trunks[Loop]).Free(); TDJCommChannelsSS1(Trunks[Loop]) := nil;
        TDJCommChannelsSS1(Trunks[Loop]) := nil; end;
      end; end;
    end; end;
  end; DJSys_DisableCard();
  DJSys_DisableCard(); FreeCardForFSK();
  FreeCardForFSK(); Result := true;
  Result := true; end;
end;
 function TDJCommCardSS1.GetAFreeTrunkByOut(): integer;
function TDJCommCardSS1.GetAFreeTrunkByOut(): integer; begin
begin Result := GetAFreeTrunkByType(Type_Export);
  Result := GetAFreeTrunkByType(Type_Export); end;
end;
 function TDJCommCardSS1.GetAFreeTrunkByType(
function TDJCommCardSS1.GetAFreeTrunkByType( const aTrunkType: TTrunkType): integer;
  const aTrunkType: TTrunkType): integer; var
var Loop:Word;
  Loop:Word; begin
begin Result := ErrTrunkID;
  Result := ErrTrunkID; for Loop := 0 to TotalTrunkNum - 1 do
  for Loop := 0 to TotalTrunkNum - 1 do begin
  begin if ((TDJCommChannelsSS1(Trunks[Loop]).GetTrunkType() = aTrunkType)
    if ((TDJCommChannelsSS1(Trunks[Loop]).GetTrunkType() = aTrunkType) and (DJTrk_CheckTrunkFree(Loop))) then
          and (DJTrk_CheckTrunkFree(Loop))) then begin
    begin Result := Loop;
      Result := Loop; break;
      break; end;
    end; end;
  end; end;
end;
 procedure TDJCommCardSS1.HangOfByTrunkID(const aChannelID: integer);
procedure TDJCommCardSS1.HangOfByTrunkID(const aChannelID: integer); begin
begin TDJCommChannelsSS1(Trunks[aChannelID]).InOutHangOff();
  TDJCommChannelsSS1(Trunks[aChannelID]).InOutHangOff(); end;
end;
 function TDJCommCardSS1.InitCard(const isFSKComm: boolean): Boolean;
function TDJCommCardSS1.InitCard(const isFSKComm: boolean): Boolean; const
const PromptFile = 'Prompt.ini';
  PromptFile = 'Prompt.ini'; var
var Loop: Integer;
  Loop: Integer; isOK: boolean;
  isOK: boolean; TimeOfNow: SystemTime;
  TimeOfNow: SystemTime; begin
begin Result := False;
  Result := False; CommIsFSK := isFSKComm;
  CommIsFSK := isFSKComm; isOK :=(DJSys_EnableCard('',PromptFile)=_ERR_OK);
  isOK :=(DJSys_EnableCard('',PromptFile)=_ERR_OK); if Not isOK then exit;
  if Not isOK then exit; isOK := InitCardForFSK();
  isOK := InitCardForFSK(); if NOT isOK then Exit;
  if NOT isOK then Exit; isLoadFSK := isOK;
  isLoadFSK := isOK; GetLocalTime(TimeOfNow);
  GetLocalTime(TimeOfNow); DJSys_SetSysTime(TimeOfNow.wHour,TimeOfNow.wMinute,TimeOfNow.wSecond);
  DJSys_SetSysTime(TimeOfNow.wHour,TimeOfNow.wMinute,TimeOfNow.wSecond); TotalTrunkNum:=DJTrk_GetTotalTrunkNum();
  TotalTrunkNum:=DJTrk_GetTotalTrunkNum(); InTrunkNum:=TotalTrunkNum shr 1;
  InTrunkNum:=TotalTrunkNum shr 1; OutTrunkNum:=TotalTrunkNum - InTrunkNum;
  OutTrunkNum:=TotalTrunkNum - InTrunkNum;
 SetLength(Trunks,TotalTrunkNum);
  SetLength(Trunks,TotalTrunkNum); SetLength(TrunkConnected,TotalTrunkNum);
  SetLength(TrunkConnected,TotalTrunkNum);
 for Loop:=0 to OutTrunkNum-1 do
  for Loop:=0 to OutTrunkNum-1 do Trunks[Loop]:=TDJCommChannelsSS1.Create(Self,Loop,Type_Export,CommIsFSK,onTrunkEvent,onRecEvent);
    Trunks[Loop]:=TDJCommChannelsSS1.Create(Self,Loop,Type_Export,CommIsFSK,onTrunkEvent,onRecEvent); for Loop:=OutTrunkNum to TotalTrunkNum-1 do
  for Loop:=OutTrunkNum to TotalTrunkNum-1 do Trunks[Loop]:=TDJCommChannelsSS1.Create(Self,Loop,Type_Import,CommIsFSK,onTrunkEvent,onRecEvent);
    Trunks[Loop]:=TDJCommChannelsSS1.Create(Self,Loop,Type_Import,CommIsFSK,onTrunkEvent,onRecEvent); for Loop:= 0 to TotalTrunkNum - 1 do
  for Loop:= 0 to TotalTrunkNum - 1 do begin
  begin TDJCommChannelsSS1(Trunks[Loop]).ClearTrunkBuffer(csReceiving);
    TDJCommChannelsSS1(Trunks[Loop]).ClearTrunkBuffer(csReceiving); end;
  end;
 DJSys_AutoApplyDtmf(ENABLEDTMF);    //自动分配DTMF资源
  DJSys_AutoApplyDtmf(ENABLEDTMF);    //自动分配DTMF资源 DJSys_EnableAutoKB();                 //自动回送KB信号
  DJSys_EnableAutoKB();                 //自动回送KB信号 isOK:=isOK and DJSys_EnableDtmfSend();
  isOK:=isOK and DJSys_EnableDtmfSend(); Result := isOK;
  Result := isOK; end;
end;
 function TDJCommCardSS1.InitCardForFSK(): boolean;
function TDJCommCardSS1.InitCardForFSK(): boolean; var
var k:integer;
  k:integer; begin
begin Result := true;
  Result := true; if CommIsFSK then
  if CommIsFSK then begin
  begin k := DJFsk_InitForFsk(SZK_Mode);
    k := DJFsk_InitForFsk(SZK_Mode); Result := (k = 1);
    Result := (k = 1); end;
  end; end;
end;
 function TDJCommCardSS1.SendStringByTrunkID(const aChannelID: integer;
function TDJCommCardSS1.SendStringByTrunkID(const aChannelID: integer; const sendBuffer: PChar):boolean;
  const sendBuffer: PChar):boolean; begin
begin Result := TDJCommChannelsSS1(Trunks[aChannelID]).SendString(sendBuffer);
  Result := TDJCommChannelsSS1(Trunks[aChannelID]).SendString(sendBuffer); end;
end;
 procedure TDJCommCardSS1.StartRunCommModule();
procedure TDJCommCardSS1.StartRunCommModule(); begin
begin Resume();
  Resume(); end;
end;
 procedure TDJCommCardSS1.ThreadKernelProcess();
procedure TDJCommCardSS1.ThreadKernelProcess(); var
var Loop:Word;
  Loop:Word; begin
begin DJSys_PushPlay();
  DJSys_PushPlay(); for Loop := 0 to TotalTrunkNum - 1 do
  for Loop := 0 to TotalTrunkNum - 1 do begin
  begin try
    try TDJCommChannelsSS1(Trunks[Loop]).DJChannelProcessor();
      TDJCommChannelsSS1(Trunks[Loop]).DJChannelProcessor(); except
    except end;
    end; end;
  end; end;
end;
 end.
end. //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //
// //      产品名称:   成晓旭的个人软件Delphi源码库
//      产品名称:   成晓旭的个人软件Delphi源码库 //      产品版本:   CXXSoft delphi code source lib 2.0
//      产品版本:   CXXSoft delphi code source lib 2.0 //      模块名称:   Delphi之东进数字语音卡通道类
//      模块名称:   Delphi之东进数字语音卡通道类 //      模块描述:
//      模块描述:    //      单元文件:   unDJChannelSS1.pas
//      单元文件:   unDJChannelSS1.pas    //      开发作者:   成晓旭
//      开发作者:   成晓旭 //      作者blog:   http://blog.csdn.net/CXXSoft
//      作者blog:   http://blog.csdn.net/CXXSoft //      备注:       任何人使用此文件时,请保留此段自述文件,谢谢!
//      备注:       任何人使用此文件时,请保留此段自述文件,谢谢! //      开发时间:   2005-01-09
//      开发时间:   2005-01-09 //      修改历史:
//      修改历史:    //      修改描述:
//      修改描述: //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ unit unDJChannelSS1;
unit unDJChannelSS1;
 interface
interface uses
uses Windows, SysUtils,
  Windows, SysUtils, unBaseDefine,
  unBaseDefine, Tce1_32,
  Tce1_32, Tce1_FSK,
  Tce1_FSK, unDJCardSS1;
  unDJCardSS1; type
type
 TCXXStatus = (csSending,csReceiving,csPlaying);
  TCXXStatus = (csSending,csReceiving,csPlaying); 
   TDJCommChannelsSS1 = class(TObject)
  TDJCommChannelsSS1 = class(TObject) private
  private CommIsFSK:boolean;
    CommIsFSK:boolean; controller:TDJCommCardSS1;
    controller:TDJCommCardSS1; TrunkID:integer;
    TrunkID:integer; TrunkStep:TTrunkStep;
    TrunkStep:TTrunkStep;
 MaxBuffer: array [0..DTMF_BUFFER_SIZE-1] of Char;
    MaxBuffer: array [0..DTMF_BUFFER_SIZE-1] of Char; msgChannel:TTrunkStatusInfo;
    msgChannel:TTrunkStatusInfo; msgFrame:TRecCommFrame;
    msgFrame:TRecCommFrame;
 commFrameNumber,recPos:Word;
    commFrameNumber,recPos:Word; subStatus:TCXXStatus;
    subStatus:TCXXStatus; commPhone:string;
    commPhone:string; commFrameStr:string;
    commFrameStr:string;
 //应该进一步优化为注入的接口,非简单的回调句柄
    //应该进一步优化为注入的接口,非简单的回调句柄 onTrunkState:TTrunkSatausEvent;
    onTrunkState:TTrunkSatausEvent; onRecEvent:TTrunkReceiveEvent;
    onRecEvent:TTrunkReceiveEvent; InOutType:TTrunkType;
    InOutType:TTrunkType;
 function  SendDataFromTrunk():boolean;
    function  SendDataFromTrunk():boolean; function  CheckSendDataEnd():boolean;
    function  CheckSendDataEnd():boolean; procedure SaveMaxBufferToFrameStr();
    procedure SaveMaxBufferToFrameStr(); procedure ProcessConnected();
    procedure ProcessConnected(); //注意:此方法与具体业务的通信协议存在严重依赖关系(IoC实现依赖反转)
    //注意:此方法与具体业务的通信协议存在严重依赖关系(IoC实现依赖反转) function  CheckReceiveOverFSK(const dataBuffer:array of char;const dataNumber:Word):boolean;
    function  CheckReceiveOverFSK(const dataBuffer:array of char;const dataNumber:Word):boolean; //注意:此方法与具体业务的通信协议存在严重依赖关系(IoC实现依赖反转)
    //注意:此方法与具体业务的通信协议存在严重依赖关系(IoC实现依赖反转) function  CheckReceiveOverDTMF(const dataBuffer:array of char;const dataNumber:Word):boolean;
    function  CheckReceiveOverDTMF(const dataBuffer:array of char;const dataNumber:Word):boolean; function  GetCommData(const dataBuffer:array of char;const dataNumber:Word):string;
    function  GetCommData(const dataBuffer:array of char;const dataNumber:Word):string; function  ReceiveDataFromTrunk():boolean;
    function  ReceiveDataFromTrunk():boolean;
 procedure InformChannelStatus(const aStep:TTrunkStep;const lvof:TLVOperateFlag);
    procedure InformChannelStatus(const aStep:TTrunkStep;const lvof:TLVOperateFlag); procedure InformBusinessStatus(const aCommData:string;const cif:TCommInformFlag);
    procedure InformBusinessStatus(const aCommData:string;const cif:TCommInformFlag); procedure InformDialStatus(const aStep:TTrunkStep);
    procedure InformDialStatus(const aStep:TTrunkStep); procedure InWaitingIntoToConnect();
    procedure InWaitingIntoToConnect(); function  GetCommFrameFromSendString(const commFrame:string):string;
    function  GetCommFrameFromSendString(const commFrame:string):string;
 procedure RegisterTrunkEvent(const trunkStateEvent:TTrunkSatausEvent);
    procedure RegisterTrunkEvent(const trunkStateEvent:TTrunkSatausEvent); procedure RegisterReceiveEvent(const trunkRecEvent:TTrunkReceiveEvent);
    procedure RegisterReceiveEvent(const trunkRecEvent:TTrunkReceiveEvent); public
  public 
     constructor Create(const trunkController: TDJCommCardSS1; const TrkID: Integer;
    constructor Create(const trunkController: TDJCommCardSS1; const TrkID: Integer; const TrunkType: TTrunkType;const isFSKComm: boolean;
      const TrunkType: TTrunkType;const isFSKComm: boolean; const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
      const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent); destructor Destroy; override;
    destructor Destroy; override;
 //获取通道状态
    //获取通道状态 function GetTrunkType():TTrunkType;
    function GetTrunkType():TTrunkType; procedure DJChannelProcessor();
    procedure DJChannelProcessor(); //通道挂机
    //通道挂机 procedure InOutHangOff();
    procedure InOutHangOff(); //开始拨号
    //开始拨号 procedure StartDialPhone(const phoneNumber,callerNumber:PChar;const aDevID:integer=-1);
    procedure StartDialPhone(const phoneNumber,callerNumber:PChar;const aDevID:integer=-1); //发送通信数据
    //发送通信数据 function  SendString(const pchSend:PChar):boolean;
    function  SendString(const pchSend:PChar):boolean; //清空通道数据缓冲
    //清空通道数据缓冲 procedure ClearTrunkBuffer(const aSB:TCXXStatus);
    procedure ClearTrunkBuffer(const aSB:TCXXStatus); //获取通道号
    //获取通道号 function  GetTrunkID():integer;
    function  GetTrunkID():integer; end;
  end;
 implementation
implementation
 { TDJCommChannelsSS1 }
{ TDJCommChannelsSS1 } const
const Frame_FillChar = #0;
  Frame_FillChar = #0; Leader_Flag = $55;
  Leader_Flag = $55; HeadNumber = 30;
  HeadNumber = 30; hasLeader = true;
  hasLeader = true; 
   function TDJCommChannelsSS1.CheckSendDataEnd(): boolean;
function TDJCommChannelsSS1.CheckSendDataEnd(): boolean; begin
begin Result := false;
  Result := false; if CommIsFSK then
  if CommIsFSK then begin
  begin if (DJFsk_CheckSendFSKEnd(TrunkID,SZK_Mode) = 1) then
    if (DJFsk_CheckSendFSKEnd(TrunkID,SZK_Mode) = 1) then begin
    begin DJFsk_StopSend(TrunkID,SZK_Mode);
      DJFsk_StopSend(TrunkID,SZK_Mode); Result := true;
      Result := true; end;
    end; end
  end else
  else begin
  begin if DJTrk_CheckDtmfSendEnd(TrunkID) then
    if DJTrk_CheckDtmfSendEnd(TrunkID) then begin
    begin DJVoc_StopPlayFile(TrunkID);
      DJVoc_StopPlayFile(TrunkID); Result := true;
      Result := true; end;
    end; end;
  end; if Result then
  if Result then ClearTrunkBuffer(csReceiving);
    ClearTrunkBuffer(csReceiving); end;
end;
 procedure TDJCommChannelsSS1.ClearTrunkBuffer(const aSB:TCXXStatus);
procedure TDJCommChannelsSS1.ClearTrunkBuffer(const aSB:TCXXStatus); begin
begin subStatus := aSB;
  subStatus := aSB; if CommIsFSK then
  if CommIsFSK then DJFsk_ResetFskBuffer(TrunkID,SZK_Mode)
    DJFsk_ResetFskBuffer(TrunkID,SZK_Mode) else
  else DJTrk_InitDtmfBufNew(TrunkID);
    DJTrk_InitDtmfBufNew(TrunkID); commFrameNumber := 0;
  commFrameNumber := 0; recPos := 0;
  recPos := 0; end;
end;
 constructor TDJCommChannelsSS1.Create(const trunkController: TDJCommCardSS1; const TrkID: Integer;
constructor TDJCommChannelsSS1.Create(const trunkController: TDJCommCardSS1; const TrkID: Integer; const TrunkType: TTrunkType; const isFSKComm: boolean;
  const TrunkType: TTrunkType; const isFSKComm: boolean; const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
  const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent); var
var t:TTrunkType;
  t:TTrunkType; begin
begin inherited Create;
  inherited Create; RegisterTrunkEvent(aStateEvent);
  RegisterTrunkEvent(aStateEvent); RegisterReceiveEvent(aRecEvent);
  RegisterReceiveEvent(aRecEvent); controller :=trunkController;
  controller :=trunkController; TrunkID:=TrkID;
  TrunkID:=TrkID; commPhone := '';
  commPhone := ''; TrunkStep:=TTrunkStep(-1);
  TrunkStep:=TTrunkStep(-1); t := TrunkType;
  t := TrunkType; if DJTrk_SetTrunkType(TrkID,t) then
  if DJTrk_SetTrunkType(TrkID,t) then InOutType:=TrunkType;
    InOutType:=TrunkType; CommIsFSK := isFSKComm;
  CommIsFSK := isFSKComm; controller.TrunkConnected[TrunkID] := false;
  controller.TrunkConnected[TrunkID] := false; ClearTrunkBuffer(csReceiving);
  ClearTrunkBuffer(csReceiving); InformChannelStatus(Step_Free,lvofAdd);
  InformChannelStatus(Step_Free,lvofAdd); end;
end;
 destructor TDJCommChannelsSS1.Destroy();
destructor TDJCommChannelsSS1.Destroy(); begin
begin inherited;
  inherited; DJTrk_BackwardHangUp(TrunkID);
  DJTrk_BackwardHangUp(TrunkID); end;
end;
 procedure TDJCommChannelsSS1.DJChannelProcessor();
procedure TDJCommChannelsSS1.DJChannelProcessor(); var
var aStep: TTrunkStep;
  aStep: TTrunkStep; begin
begin //DJSys_PushPlay();
  //DJSys_PushPlay(); aStep:= DJTrk_GetTrunkStatus(TrunkID);
  aStep:= DJTrk_GetTrunkStatus(TrunkID); //状态变化
  //状态变化 if TrunkStep <> aStep then
  if TrunkStep <> aStep then begin
  begin TrunkStep:= aStep;
    TrunkStep:= aStep; InformChannelStatus(TrunkStep,lvofUpdate);
    InformChannelStatus(TrunkStep,lvofUpdate); end;
  end; //前向挂机
  //前向挂机 if (TrunkStep<>Step_Free) and DJTrk_CheckForwardHangUp(TrunkID) then
  if (TrunkStep<>Step_Free) and DJTrk_CheckForwardHangUp(TrunkID) then begin
  begin InOutHangOff();
    InOutHangOff(); end;
  end; //入中继拨入,等待接续(建立连接)
  //入中继拨入,等待接续(建立连接) if (TrunkStep = Step_Wait) and (DJTrk_CheckTrunkIn(TrunkID)) then
  if (TrunkStep = Step_Wait) and (DJTrk_CheckTrunkIn(TrunkID)) then begin
  begin InWaitingIntoToConnect();
    InWaitingIntoToConnect(); end;
  end; //通道连接已经建立
  //通道连接已经建立 if (TrunkStep = Step_Connect) then
  if (TrunkStep = Step_Connect) then begin
  begin ProcessConnected();
    ProcessConnected(); end;
  end; //出通道拨号失败
  //出通道拨号失败 if TrunkStep=Step_DialFail then
  if TrunkStep=Step_DialFail then begin
  begin InformDialStatus(TrunkStep);
    InformDialStatus(TrunkStep); end;
  end; if TrunkStep=Step_Delay then
  if TrunkStep=Step_Delay then Exit;
    Exit; //出入通道空闲
  //出入通道空闲 if TrunkStep = Step_Free then
  if TrunkStep = Step_Free then begin
  begin //等待接收呼入
    //等待接收呼入 end;
  end; end;
end;
 function TDJCommChannelsSS1.GetTrunkID(): integer;
function TDJCommChannelsSS1.GetTrunkID(): integer; begin
begin Result := Self.TrunkID;
  Result := Self.TrunkID; end;
end;
 procedure TDJCommChannelsSS1.InformChannelStatus(const aStep: TTrunkStep;const lvof:TLVOperateFlag);
procedure TDJCommChannelsSS1.InformChannelStatus(const aStep: TTrunkStep;const lvof:TLVOperateFlag); begin
begin msgChannel.lvFlag := lvof;
  msgChannel.lvFlag := lvof; msgChannel.TrunkID := IntToStr(Self.TrunkID);
  msgChannel.TrunkID := IntToStr(Self.TrunkID); msgChannel.DeviceID := '';
  msgChannel.DeviceID := ''; msgChannel.TrunkTypeStr:=TrunkTypeInStr[InOutType];
  msgChannel.TrunkTypeStr:=TrunkTypeInStr[InOutType]; msgChannel.TrunkStep := Ord(aStep);
  msgChannel.TrunkStep := Ord(aStep); msgChannel.TrunkStepStr:=TrunkStepInStr[aStep];
  msgChannel.TrunkStepStr:=TrunkStepInStr[aStep]; if aStep = Step_Free then
  if aStep = Step_Free then begin
  begin msgChannel.Phone:='';
    msgChannel.Phone:=''; msgChannel.Data:='';
    msgChannel.Data:=''; end
  end else
  else begin
  begin msgChannel.Phone:=commPhone;
    msgChannel.Phone:=commPhone; msgChannel.Data:=commFrameStr;
    msgChannel.Data:=commFrameStr; end;
  end; if Assigned(onTrunkState) then
  if Assigned(onTrunkState) then onTrunkState(msgChannel);
    onTrunkState(msgChannel); end;
end;
 procedure TDJCommChannelsSS1.InformDialStatus(const aStep: TTrunkStep);
procedure TDJCommChannelsSS1.InformDialStatus(const aStep: TTrunkStep); var
var dStatus:TDialStatus;
  dStatus:TDialStatus; begin
begin dStatus := DJTrk_GetDialStatus(TrunkID);
  dStatus := DJTrk_GetDialStatus(TrunkID); case dStatus of
  case dStatus of DS_Busy,DS_OverTime,DS_NoUser,DS_LineError:
  DS_Busy,DS_OverTime,DS_NoUser,DS_LineError: begin
  begin InOutHangOff();
    InOutHangOff(); end;
  end; end;
  end; end;
end;
 procedure TDJCommChannelsSS1.InformBusinessStatus(const aCommData: string;const cif:TCommInformFlag);
procedure TDJCommChannelsSS1.InformBusinessStatus(const aCommData: string;const cif:TCommInformFlag); begin
begin //依赖注入的业务处理接口调用,实现业务处理的
  //依赖注入的业务处理接口调用,实现业务处理的 end;
end;
 procedure TDJCommChannelsSS1.InOutHangOff();
procedure TDJCommChannelsSS1.InOutHangOff(); begin
begin DJTrk_BackwardHangUp(TrunkID);
  DJTrk_BackwardHangUp(TrunkID); controller.TrunkConnected[TrunkID] := false;
  controller.TrunkConnected[TrunkID] := false; InformBusinessStatus('',cifDisconnected);
  InformBusinessStatus('',cifDisconnected); end;
end;
 procedure TDJCommChannelsSS1.InWaitingIntoToConnect;
procedure TDJCommChannelsSS1.InWaitingIntoToConnect; begin
begin DJVoc_PlayFile(TrunkID,'.Voicedtmf13');
  DJVoc_PlayFile(TrunkID,'.Voicedtmf13'); DJVoc_StopPlayFile(TrunkID);
  DJVoc_StopPlayFile(TrunkID); end;
end;

 procedure TDJCommChannelsSS1.ProcessConnected();
procedure TDJCommChannelsSS1.ProcessConnected(); var
var ss:TCXXStatus;
  ss:TCXXStatus;   begin
begin if NOT controller.TrunkConnected[TrunkID] then
  if NOT controller.TrunkConnected[TrunkID] then begin
  begin controller.TrunkConnected[TrunkID] := true;
    controller.TrunkConnected[TrunkID] := true; ss := csReceiving;
    ss := csReceiving; InformBusinessStatus('',cifConnected);
    InformBusinessStatus('',cifConnected); ClearTrunkBuffer(ss);
    ClearTrunkBuffer(ss); end;
  end; case subStatus of
  case subStatus of csSending:
  csSending: begin
  begin if CheckSendDataEnd() then
    if CheckSendDataEnd() then begin
    begin InformChannelStatus(Step_Connect,lvofUpdate);
        InformChannelStatus(Step_Connect,lvofUpdate); InformBusinessStatus(commFrameStr,cifSend);
        InformBusinessStatus(commFrameStr,cifSend); end;
    end; end;
  end; csReceiving:
  csReceiving: begin
  begin if ReceiveDataFromTrunk() then
    if ReceiveDataFromTrunk() then begin
    begin msgFrame.CommFrame := commFrameStr;
      msgFrame.CommFrame := commFrameStr; msgFrame.CommType := Comm_FSK;
      msgFrame.CommType := Comm_FSK; InformChannelStatus(Step_Connect,lvofUpdate);
      InformChannelStatus(Step_Connect,lvofUpdate); InformBusinessStatus(commFrameStr,cifReceive);
      InformBusinessStatus(commFrameStr,cifReceive); end;
    end; end;
  end; csPlaying:
  csPlaying: begin
  begin 
     end;
  end; end;
  end; end;
end;
 function TDJCommChannelsSS1.ReceiveDataFromTrunk(): boolean;
function TDJCommChannelsSS1.ReceiveDataFromTrunk(): boolean; var
var num,Loop:integer;
  num,Loop:integer; tempBuffer:array[0..DTMF_BUFFER_SIZE-1] of Char;
  tempBuffer:array[0..DTMF_BUFFER_SIZE-1] of Char; begin
begin Result := false;
  Result := false; try
  try if Self.CommIsFSK then
    if Self.CommIsFSK then begin
    begin //FSK方式版本
      //FSK方式版本 FillChar(tempBuffer,DTMF_BUFFER_SIZE,Frame_FillChar);
      FillChar(tempBuffer,DTMF_BUFFER_SIZE,Frame_FillChar); num := DJFsk_GetFSK(TrunkID,tempBuffer,SZK_MODE);
      num := DJFsk_GetFSK(TrunkID,tempBuffer,SZK_MODE); if (num > 0) then
      if (num > 0) then begin
      begin if CheckReceiveOverFSK(tempBuffer,num) then
        if CheckReceiveOverFSK(tempBuffer,num) then begin
        begin Self.commFrameStr := GetCommData(tempBuffer,num);
          Self.commFrameStr := GetCommData(tempBuffer,num); Self.ClearTrunkBuffer(csReceiving);
          Self.ClearTrunkBuffer(csReceiving); Result := true;
          Result := true; end;
        end; end;
      end; end
    end else
    else begin
    begin //DTMF方式版本
      //DTMF方式版本 num := DJTrk_GetReceiveDtmfNumNew(TrunkID);
      num := DJTrk_GetReceiveDtmfNumNew(TrunkID); if num > 0 then
      if num > 0 then begin
      begin for Loop := 0 to num - 1 do
        for Loop := 0 to num - 1 do begin
        begin MaxBuffer[recPos+Loop] := DJTrk_GetDtmfCodeNew(TrunkID);
          MaxBuffer[recPos+Loop] := DJTrk_GetDtmfCodeNew(TrunkID); recPos := (recPos + 1) mod DTMF_BUFFER_SIZE;
          recPos := (recPos + 1) mod DTMF_BUFFER_SIZE; end;
        end; Inc(commFrameNumber,num);
        Inc(commFrameNumber,num); if CheckReceiveOverDTMF(tempBuffer,num) then
        if CheckReceiveOverDTMF(tempBuffer,num) then begin
        begin ClearTrunkBuffer(csReceiving);
          ClearTrunkBuffer(csReceiving); Result := true;
          Result := true; end;
        end; end;
      end; end;
    end; except
  except Result := false;
    Result := false; end;
  end; end;
end;
 procedure TDJCommChannelsSS1.RegisterReceiveEvent(
procedure TDJCommChannelsSS1.RegisterReceiveEvent( const trunkRecEvent: TTrunkReceiveEvent);
  const trunkRecEvent: TTrunkReceiveEvent); begin
begin onRecEvent := trunkRecEvent;
  onRecEvent := trunkRecEvent; end;
end;
 procedure TDJCommChannelsSS1.RegisterTrunkEvent(
procedure TDJCommChannelsSS1.RegisterTrunkEvent( const trunkStateEvent: TTrunkSatausEvent);
  const trunkStateEvent: TTrunkSatausEvent); begin
begin onTrunkState := trunkStateEvent;
  onTrunkState := trunkStateEvent; end;
end;
 procedure TDJCommChannelsSS1.SaveMaxBufferToFrameStr();
procedure TDJCommChannelsSS1.SaveMaxBufferToFrameStr(); var
var Loop:Word;
  Loop:Word; begin
begin commFrameStr := '';
  commFrameStr := ''; for Loop := 0 to commFrameNumber - 1 do
  for Loop := 0 to commFrameNumber - 1 do begin
  begin commFrameStr := commFrameStr + MaxBuffer[Loop];
    commFrameStr := commFrameStr + MaxBuffer[Loop]; end;
  end; end;
end;
 function TDJCommChannelsSS1.SendDataFromTrunk():boolean;
function TDJCommChannelsSS1.SendDataFromTrunk():boolean; begin
begin Result := false;
  Result := false; if controller.TrunkConnected[TrunkID] then
  if controller.TrunkConnected[TrunkID] then begin
  begin if CommIsFSK then
    if CommIsFSK then begin
    begin Result := DJFsk_SendFSK(TrunkID,@MaxBuffer[0],commFrameNumber,SZK_Mode) = 1;
      Result := DJFsk_SendFSK(TrunkID,@MaxBuffer[0],commFrameNumber,SZK_Mode) = 1; end
    end else
    else begin
    begin Result := DJTrk_SendDtmfStr(TrunkID,@MaxBuffer[0]) = 1;
      Result := DJTrk_SendDtmfStr(TrunkID,@MaxBuffer[0]) = 1; end;
    end; end;
  end; if Result then
  if Result then subStatus := csSending;
    subStatus := csSending; end;
end;
 function TDJCommChannelsSS1.SendString(const pchSend: PChar):boolean;
function TDJCommChannelsSS1.SendString(const pchSend: PChar):boolean; var
var Loop:integer;
  Loop:integer; strTemp:string;
  strTemp:string; begin
begin Result := false;
  Result := false; if Self.CommIsFSK and hasLeader then
  if Self.CommIsFSK and hasLeader then begin
  begin //加FSK前导字符的版本
    //加FSK前导字符的版本 strTemp := GetCommFrameFromSendString(pchSend);
    strTemp := GetCommFrameFromSendString(pchSend); commFrameNumber := Length(strTemp);
    commFrameNumber := Length(strTemp); if commFrameNumber > 0 then
    if commFrameNumber > 0 then begin
    begin for Loop := 0 to commFrameNumber-1 do
      for Loop := 0 to commFrameNumber-1 do MaxBuffer[Loop] := strTemp[Loop+1];
        MaxBuffer[Loop] := strTemp[Loop+1]; MaxBuffer[commFrameNumber] := #0;
      MaxBuffer[commFrameNumber] := #0; SaveMaxBufferToFrameStr();
      SaveMaxBufferToFrameStr(); Result := SendDataFromTrunk();
      Result := SendDataFromTrunk(); end;
    end; end
  end else
  else begin
  begin //不加前导字符的版本
    //不加前导字符的版本 commFrameNumber := Length(pchSend);
    commFrameNumber := Length(pchSend); if commFrameNumber > 0 then
    if commFrameNumber > 0 then begin
    begin for Loop := 0 to commFrameNumber-1 do
      for Loop := 0 to commFrameNumber-1 do MaxBuffer[Loop] := pchSend[Loop];
        MaxBuffer[Loop] := pchSend[Loop]; MaxBuffer[commFrameNumber] := #0;
      MaxBuffer[commFrameNumber] := #0; SaveMaxBufferToFrameStr();
      SaveMaxBufferToFrameStr(); Result := SendDataFromTrunk();
      Result := SendDataFromTrunk(); end;
    end; end;
  end; end;
end;
 procedure TDJCommChannelsSS1.StartDialPhone(const phoneNumber,
procedure TDJCommChannelsSS1.StartDialPhone(const phoneNumber, callerNumber: PChar;const aDevID:integer);
  callerNumber: PChar;const aDevID:integer); begin
begin if DJTrk_CheckTrunkFree(TrunkID) and(Trim(phoneNumber) <> '') then
  if DJTrk_CheckTrunkFree(TrunkID) and(Trim(phoneNumber) <> '') then begin
  begin commPhone := Trim(phoneNumber);
    commPhone := Trim(phoneNumber); DJTrk_StartDial(TrunkID,PChar(commPhone),'');
    DJTrk_StartDial(TrunkID,PChar(commPhone),''); end;
  end; end;
end;
 function TDJCommChannelsSS1.CheckReceiveOverFSK(const dataBuffer: array of char;
function TDJCommChannelsSS1.CheckReceiveOverFSK(const dataBuffer: array of char; const dataNumber: Word): boolean;
  const dataNumber: Word): boolean; begin
begin //业务实现方法:判定通信帧串发送结束
  //业务实现方法:判定通信帧串发送结束 Result := true;
  Result := true; end;
end;
 function TDJCommChannelsSS1.GetCommData(const dataBuffer: array of char;
function TDJCommChannelsSS1.GetCommData(const dataBuffer: array of char; const dataNumber: Word): string;
  const dataNumber: Word): string; var
var Loop:Word;
  Loop:Word; begin
begin Result := '';
  Result := ''; if dataNumber <= 0 then Exit;
  if dataNumber <= 0 then Exit; for Loop := 0 to dataNumber - 1 do
  for Loop := 0 to dataNumber - 1 do begin
  begin if (dataBuffer[Loop] <> Frame_FillChar) then
    if (dataBuffer[Loop] <> Frame_FillChar) then Result := Result + dataBuffer[Loop];
      Result := Result + dataBuffer[Loop]; end;
  end; end;
end;
 function TDJCommChannelsSS1.GetCommFrameFromSendString(
function TDJCommChannelsSS1.GetCommFrameFromSendString( const commFrame: string): string;
  const commFrame: string): string; var
var Loop:integer;
  Loop:integer; begin
begin Result := commFrame;
  Result := commFrame; for Loop := 0 to HeadNumber - 1 do
  for Loop := 0 to HeadNumber - 1 do Result := CHR(Leader_Flag) + Result;
    Result := CHR(Leader_Flag) + Result; end;
end;
 function TDJCommChannelsSS1.CheckReceiveOverDTMF(
function TDJCommChannelsSS1.CheckReceiveOverDTMF( const dataBuffer: array of char; const dataNumber: Word): boolean;
  const dataBuffer: array of char; const dataNumber: Word): boolean; begin
begin //业务实现方法:判定通信帧串发送结束
  //业务实现方法:判定通信帧串发送结束 Result := true;
  Result := true; end;
end;
 function TDJCommChannelsSS1.GetTrunkType(): TTrunkType;
function TDJCommChannelsSS1.GetTrunkType(): TTrunkType; begin
begin Result := Self.InOutType;
  Result := Self.InOutType; end;
end;
 end.
end.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1770257
 
                    
                     
                    
                 
                    
                 
        
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号