您的位置:首页 > 编程语言 > Delphi

Delphi之三汇模拟语音卡(SHT-8B/PCI/FAX)可复用源码

2008-04-09 11:02 465 查看
Delphi之三汇模拟语音卡(SHT-8B/PCI/FAX)可复用源码作者:成晓旭设计简介:1、   设计思路请参考本站Blog的另一篇文章:“Delphi之东进模拟语音卡(D160A)可复用源码”;链接http://blog.csdn.net/CXXSoft/archive/2006/08/23/1108211.aspx。2、   其实,仔细对比,你会发现这两种卡的代码类方法签名几乎99%是一样的,也就是说,这两都之间,还需要更进一步的抽象,以解决“重复代码”或者“相似代码”的问题。3、   更高层次的抽象,请参考我的设计文档。4、   类图(以后补上):5、   卡类源码: 

//------------------------------------------------------------------------------


//


//      产品名称:   成晓旭的个人软件Delphi源码库


//      产品版本:   CXXSoft delphi code source lib 2.0


//      模块名称:   Delphi之三汇模拟语音卡类


//      模块描述:   


//      单元文件:   unSHCard8B.pas   


//      开发作者:   成晓旭


//      备注:       任何人使用此文件时,请保留此段自述文件,谢谢!


//      开发时间:   2003-12-03


//      修改历史:   


//      修改描述:


//------------------------------------------------------------------------------


unit unSHCard8B;




interface


uses


  Windows,


  //unDJTC08a32,unDJNewSig,


  unBaseDefine,


  //unDJ160ADefine,unDJChanne160A,


  unShpa3api,unSHChanne18B,unSH8BDefine;


type


  TCXXCommCard8B = class(TObject)


  private




    ChannelNumber:Word;


    channelObject:array of TCXXSHChannel8B;


    OnCardChannelState:TTrunkStatusEvent;




    procedure ReleaseCommDevice();


    function  GetChannelObjectOrder(const aChannelID:Word):Word;


    function InitChannel():boolean;


  public




    constructor Create(const trunkEvent:TTrunkStatusEvent);


    destructor Destroy(); override;




    function  LoadCommDevice(const loadAll:boolean=false):boolean;


    function  Startup():boolean;


    function  GetAFreeChannel():Word;


    function  GetChannelNumber():Word;


    function  DialPhone(const aChannelID:Word;const DialPhoneNumber:PChar):boolean;


    function  HangUp(const aChannelID:Word):boolean;




  end;






implementation




const


  SH_ConfigFile = 'C:ShCtiShConfig.ini';


  SH_IndexFile = 'C:ShCtiShIndex.ini';


  




...{ TCXXCommCard8B }


constructor TCXXCommCard8B.Create(const trunkEvent:TTrunkStatusEvent);


begin


  ChannelNumber := 0;


  Self.OnCardChannelState := trunkEvent;


end;




destructor TCXXCommCard8B.Destroy;


var


  Loop:Word;


begin


  if (Length(channelObject) > 0) and (channelNumber > 0) then


  begin


    for Loop := 0 to ChannelNumber - 1 do


    begin


      if Assigned(channelObject[Loop]) then


      begin


        channelObject[Loop].Free();


        channelObject[Loop] := nil;


      end;


    end;


  end;


  ReleaseCommDevice();


end;




function TCXXCommCard8B.DialPhone(const aChannelID: Word;


  const DialPhoneNumber: PChar): boolean;


var


  K:Word;


begin


  Result := false;


  K := GetChannelObjectOrder(aChannelID);


  if (K <> ErrorTrunkNumber) and (Assigned(channelObject[K])) then


  begin


    Result := channelObject[K].DialPhone(DialPhoneNumber);


  end;


end;




procedure TCXXCommCard8B.ReleaseCommDevice();


begin


  SsmCloseCti() ;


end;




function TCXXCommCard8B.GetAFreeChannel(): Word;


var


  Loop:Word;


begin


  Result := ErrorTrunkNumber;


  for Loop := Low(channelObject) to High(channelObject) do


  begin


    if NOT channelObject[Loop].CheckDialOutEnabled() then continue;


    if (channelObject[Loop].GetChannelStatus() = atsFree) then


    begin


      Result := channelObject[Loop].GetChannelID();


      break;


    end;


  end;


end;




function TCXXCommCard8B.GetChannelNumber(): Word;


begin


  Result := channelNumber;


end;




function TCXXCommCard8B.GetChannelObjectOrder(


  const aChannelID: Word): Word;


var


  Loop:Word;


begin


  Result := ErrorTrunkNumber;


  for Loop := Low(channelObject) to High(channelObject) do


  begin


    if (channelObject[Loop].GetChannelID = aChannelID) then


    begin


      Result := Loop;


      break;


    end;


  end;


end;




function TCXXCommCard8B.HangUp(const aChannelID: Word): boolean;


var


  K:Word;


begin


  Result := false;


  K := GetChannelObjectOrder(aChannelID);


  if (K <> ErrorTrunkNumber) and (Assigned(channelObject[K])) then


  begin


    channelObject[K].ChannelHangUp();


    Result := true;


  end;


end;




function TCXXCommCard8B.LoadCommDevice(const loadAll:boolean): boolean;


const


  loadEmpty = true;


begin


  Result := false;


  if SsmStartCti(SH_ConfigFile,SH_IndexFile) <> 0 then


  begin


    TCXXSHChannel8B.InformInvodeError();


    Exit;


  end;


  if(SsmGetMaxUsableBoard() <> SsmGetMaxCfgBoard()) then


  begin                                                      //部分板卡初始化失败,取出失败原因


    TCXXSHChannel8B.InformInvodeError();


    Exit;


  end;


  Result := InitChannel();


end;




function TCXXCommCard8B.Startup(): boolean;


var


  Loop:integer;


begin


  for Loop := 0 to channelNumber - 1 do


  begin


    channelObject[Loop].Startup();


  end;


  Result := true;


end;




function TCXXCommCard8B.InitChannel():boolean;


var


  number,Loop:integer;


begin


  Result := false;


  number := SsmGetMaxCh();


  if (number < 0) then Exit;


  ChannelNumber := number;


  SetLength(channelObject,channelNumber);


  for Loop := 0 to channelNumber - 1 do


  begin


    channelObject[Loop] := TCXXSHChannel8B.Create(OnCardChannelState);


    channelObject[Loop].CreateCommChannel(Loop);


  end;


  Result := true;


end;




end.


 6、   通道类源码: 

//------------------------------------------------------------------------------


//


//      产品名称:   成晓旭的个人软件Delphi源码库


//      产品版本:   CXXSoft delphi code source lib 2.0


//      模块名称:   Delphi之三汇模拟语音卡通道类


//      模块描述:   


//      单元文件:   unSHChanne18B.pas


//      开发作者:   成晓旭


//      备注:       任何人使用此文件时,请保留此段自述文件,谢谢!


//      开发时间:   2003-12-01


//      修改历史:   


//      修改描述:


//------------------------------------------------------------------------------


unit unSHChanne18B;






...{$DEFINE ThreadChannel}




interface




uses


  Windows,Classes,SysUtils,




  unBaseDefine,unShpa3api,unSH8BDefine,


  //unDJ160ADefine,


  unDJTC08a32,unDJNewSig;




Type








  ...{$IFDEF ThreadChannel}


  TCXXSHChannel8B = class(TThread)




  ...{$ELSE}


  TCXXSHChannel8B = class(TObject)




  ...{$ENDIF}


  private


    channelType:TChannelType;


    oldChannelState,channelState:TTrunkState;


    channelID:Word;


    phoneNumber:string;


    dtmfString:string;


    aCallerId:PAnsiChar;


    


    isConntectd:boolean;




    isDialOut:boolean;


    aTrunkState:TTrunkStatus;


    


    procedure ChannelProcessor();


    procedure InformTrunkStatus(const aMsgFlag: TLVOperateFlag);




    procedure ClearTrunkStatus();


    procedure ClearChannelBuffer();


    function  CheckSigHangup():boolean;


    function  CheckCallIn():boolean;


    function  SwitchOnCallIn():boolean;




    procedure ProcessCallInSuccess();


    procedure ProcessDialSuccess();




    procedure ProcessCheckDialSend();


    procedure ProcessDialOut();




    procedure Stop();




    //三汇卡专用方法


    function GetTrunkStateBySsm(const ssmState: integer): TTrunkState;


  protected




  ...{$IFDEF ThreadChannel}


    procedure Execute(); override;




  ...{$ENDIF}


  public


    strMessage:string;


    OnChannelState:TTrunkStatusEvent;




    constructor Create(const trunkEvent:TTrunkStatusEvent);


    destructor Destroy();override;




    procedure CreateCommChannel(const aChennelID: Word);


    procedure Startup();




    function  GetChannelID():Word;


    function  GetChannelStatus():TTrunkState;


    function  GetChannelType():TChannelType;


    function  DialPhone(const DialPhoneNumber:PChar):boolean;overload;


    function  DialPhone(const DialPhoneNumber:PChar;const PreDialNumber:PChar):boolean;overload;


    procedure ChannelHangUp();




    function  GetDialOut():boolean;




    //三汇卡特性方法


    function CheckDialOutEnabled():boolean;


    class procedure InformInvodeError();


  end;


implementation






...{ TCXXSHChannel8B }




procedure TCXXSHChannel8B.ChannelHangUp();


begin


  isDialOut := false;


  SsmHangUp(channelID);


  ClearChannelBuffer();


  ClearTrunkStatus();


  InformTrunkStatus(lvofUpdate);


end;




procedure TCXXSHChannel8B.ChannelProcessor();


var


  ssmState:integer;


begin


//  ssmState := SsmGetChState(channelID);


//  channelState := GetTrunkStateBySsm(ssmState);


  CheckCallIn();


    case channelState of


    atsFree:


    begin


      //


    end;


    atsCallIning:


    begin


      SwitchOnCallIn();


    end;


    atsCallInSuccess:


    begin


      if CheckSigHangup() then Exit;


      ProcessCallInSuccess();


    end;


    atsCheckSendDial:


    begin


      ProcessCheckDialSend();


    end;


    atsDialing:


    begin


      ProcessDialOut();


    end;


    atsDialSuccess:


    begin


      if CheckSigHangup() then Exit;


      ProcessDialSuccess();


      strMessage := '拨号成功';


    end;


    atsHangOff:


    begin


      ChannelHangUp();


    end;


    end;


    if (oldChannelState <> channelState) then


    begin


      oldChannelState := channelState;


      InformTrunkStatus(lvofUpdate);


    end;


end;




function TCXXSHChannel8B.CheckCallIn(): boolean;


begin


  Result := false;


  if(SsmGetChState(channelID)=2) then //检测到振铃信号


  begin


    SsmGetCallerId(channelID, aCallerId); //取出CALLERID信息


    channelState := atsCallIning;


    Result := true;


  end;




...{


  Result := RingDetect(channelID);


  if Result then


  begin


    OffHook(channelID);


    if isDialOut then


      channelState := atsDialSuccess


    else


      channelState := atsCallIning;


  end;


}


end;




function TCXXSHChannel8B.CheckSigHangup(): boolean;


begin


  Result := false;


  if (SsmGetChState(channelID) = S_CALL_PENDING) then


  begin


    strMessage := '对方已挂机';


    InformTrunkStatus(lvofUpdate);


    SsmStopPlay(channelID);


    channelState := atsHangOff;


    Result := true;


  end;


end;




procedure TCXXSHChannel8B.ClearTrunkStatus();


begin


  channelState := atsFree;


  oldChannelState := channelState;


  phoneNumber := '';


  dtmfString := '';


  strMessage := '';


  isConntectd := false;


end;




constructor TCXXSHChannel8B.Create(const trunkEvent:TTrunkStatusEvent);


begin


  GetMem(aCallerId,50);


  Self.OnChannelState := trunkEvent;




...{$IFDEF ThreadChannel}


  Self.FreeOnTerminate := true;


  inherited Create(true);




...{$ENDIF}


end;






destructor TCXXSHChannel8B.Destroy;


begin


  ChannelHangUp();


  Stop();




...{$IFNDEF ThreadChannel}


  inherited Destroy();




...{$ENDIF}


  InformTrunkStatus(lvofDelete);


  FreeMem(aCallerId);  


end;




function TCXXSHChannel8B.DialPhone(const DialPhoneNumber:PChar;


  const PreDialNumber:PChar): boolean;


begin


  Result := false;


  if (channelState <> atsFree) then Exit;


  phoneNumber := DialPhoneNumber;


  Result := (SsmPickup(channelID) = 0);


  if NOT Result then Exit;


  Result := (SsmAutoDial(channelID,DialPhoneNumber)=0);


  if Result then


  begin


    isDialOut := true;


    channelState := atsCheckSendDial;


  end;


end;




function TCXXSHChannel8B.DialPhone(


  const DialPhoneNumber: PChar): boolean;


begin


  Result := DialPhone(DialPhoneNumber,'');


end;






...{$IFDEF ThreadChannel}


procedure TCXXSHChannel8B.Execute;


begin


  while NOT Terminated do


  begin


    Synchronize(ChannelProcessor);


    Sleep(10);


  end;


end;




...{$ENDIF}




function TCXXSHChannel8B.GetChannelID(): Word;


begin


  Result := channelID;


end;




function TCXXSHChannel8B.GetChannelStatus(): TTrunkState;


begin


  Result := channelState;


end;




procedure TCXXSHChannel8B.InformTrunkStatus(const aMsgFlag: TLVOperateFlag);


begin


  if NOT Assigned(OnChannelState) then Exit;


  aTrunkState.lvFlag := aMsgFlag;


  aTrunkState.TrunkID := IntToStr(channelID);


  aTrunkState.TrunkType := Ord(channelType);


  aTrunkState.TrunkTypeStr := ChannelTypeString[channelType];


  aTrunkState.TrunkStep := Ord(channelState);


  aTrunkState.TrunkStepStr := TrunkStateString[channelState];


  aTrunkState.TrunkPhone := phoneNumber;


  aTrunkState.TrunkData := dtmfString;


  OnChannelState(aTrunkState);


end;




procedure TCXXSHChannel8B.ProcessCallInSuccess();


begin




end;




function TCXXSHChannel8B.SwitchOnCallIn(): boolean;


begin


  SsmPickup(channelID);                 //摘机


  ClearChannelBuffer();


  channelState := atsCallInSuccess;


  Result := true;


end;




procedure TCXXSHChannel8B.ProcessDialSuccess();


begin




end;




procedure TCXXSHChannel8B.CreateCommChannel(const aChennelID: Word);


var


  ct:integer;


begin


  channelID := aChennelID;


  ct := SsmGetChType(channelID);


  if (ct < 0) then Exit;


  channelType := TChannelType(ct);


  ClearTrunkStatus();


  InformTrunkStatus(lvofAdd);


end;




function TCXXSHChannel8B.GetChannelType(): TChannelType;


begin


  Result := channelType;


end;




function TCXXSHChannel8B.GetDialOut(): boolean;


begin


  Result := isDialOut;


end;




procedure TCXXSHChannel8B.ProcessCheckDialSend();


begin


  //三汇卡直接转换状态


  channelState := atsDialing;


end;




procedure TCXXSHChannel8B.Startup();


begin




  ...{$IFDEF ThreadChannel}


  Resume();




  ...{$ENDIF}


end;




procedure TCXXSHChannel8B.Stop();


begin




  ...{$IFDEF ThreadChannel}


  Suspend();


  Terminate();




  ...{$ENDIF}


end;




function TCXXSHChannel8B.CheckDialOutEnabled(): boolean;


begin


  //内线通道、坐席通道、磁石通道和录音通道不支持本SsmPicuup操作


  Result := NOT((channelType = ct1) or


                (channelType = ct2) or


                (channelType = ct3) or


                (channelType = ct10));


end;




class procedure TCXXSHChannel8B.InformInvodeError;


var


  msgBuffer:PAnsiChar;


begin


  GetMem(msgBuffer,255);


  try


    SsmGetLastErrMsg(msgBuffer);


    //记录异常日志,或者通知用户


    //Showmessage(msgBuffer);


  finally


    FreeMem(msgBuffer);


  end;


end;




function TCXXSHChannel8B.GetTrunkStateBySsm(


  const ssmState: integer): TTrunkState;


begin


  Result := atsFree;


  case ssmState of


    0:        Result := atsFree;


    4,5,6,9:  Result := atsCallIning;


    7:        Result := atsHangOff;


    //8:“断线”状态。只有录音通道才会进入本状态。暂时不处理


    //8:        Result := atsHangOff;


    //3:        Result := atsCallInSuccess;


  end;


end;




procedure TCXXSHChannel8B.ProcessDialOut();


var


  dState:integer;


begin


  dState := SsmChkAutoDial(channelID);


  case dState of


    DIAL_VOICE,


    DIAL_VOICEF1,


    DIAL_VOICEF2:


    begin


      channelState := atsDialSuccess;


      isConntectd := true;


    end;


    DIAL_STANDBY,


    DIAL_NO_DIALTONE,


    DIAL_ECHO_NOVOICE,


    DIAL_NOVOICE,


    DIAL_NOANSWER,


    DIAL_FAILURE,


    DIAL_INVALID_PHONUM:


    begin


      channelState := atsHangOff;


    end;


  end;


  strMessage := '拨号中...';


end;




procedure TCXXSHChannel8B.ClearChannelBuffer();


begin


  SsmClearRxDTMFBuf(channelID);         //清空驱动程序内部的DTMF按键号码接收缓冲区


  SsmClearRxBuf(channelID);             //清除指定通道ch上MODEM模块的接收缓冲区中的所有数据


  //“抢拨” 开关是指当在放音过程中收到对方的DTMF按键字符时,由驱动程序程序立即停止正在进行的放音操作。


  //SsmSetDtmfStopPlay(channelID,true);         //打开抢拨开关


end;




end.


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: