Delphi之東進數字語音卡(SS1)可複用原始碼

gudesheng發表於2008-01-03

Delphi之東進數字語音卡(SS1)可複用原始碼

作者:成曉旭

Bloghttp://blog.csdn.net/cxxsoft

(宣告:歡迎轉載,請保證文章的完整性)

        由於工作原因,本人將不在從事商業應有軟體的開發工作,現在開始逐級“解密”自己以前寫的部分自有產權程式碼,但願對後來的朋友有點參考、借鑑的價值。

        本程式碼是本人開發的計劃開源的CIT通用平臺的東進1號信令數字語言卡封裝,設計思路與模擬語音卡的封裝非常類似,在此不再贅述。有興趣的朋友,請參考本人的另外一篇文章《Delphi之東進模擬語音卡(D160A)可複用原始碼》:http://blog.csdn.net/cxxsoft/archive/2006/08/23/1108211.aspx

        核心思想是一致的:卡、通道分別設計和實現;通道內,核心的還是狀態機模式輪巡通道狀態來管理硬體卡裝置;板卡封裝內實現不實現任何業務介面,但允許動態注入實現業務介面的物件,來近一步分發、處理板卡層採集的基礎資料。

卡類原始碼:

//------------------------------------------------------------------------------
//
//      產品名稱:   成曉旭的個人軟體Delphi原始碼庫
//      產品版本:   CXXSoft delphi code source lib 2.0
//      模組名稱:   Delphi之東進數字語音卡類
//      模組描述:   
//      單元檔案:   unDJCardSS1.pas   
//      開發作者:   成曉旭
//      作者blog:   http://blog.csdn.net/CXXSoft
//      備註:       任何人使用此檔案時,請保留此段自述檔案,謝謝!
//      開發時間:   2005-01-09
//      修改歷史:   
//      修改描述:
//------------------------------------------------------------------------------
unit unDJCardSS1;

interface
uses
  Windows,SysUtils,Classes,
  unBaseDefine,
  Tce1_32,
  Tce1_FSK;

type
  TDJCommCardSS1 
= class(TThread)
  
private
    onTrunkEvent:TTrunkSatausEvent;
    onRecEvent:TTrunkReceiveEvent;
    isLoadFSK:boolean;
    CommIsFSK:boolean;
    Trunks:array of TObject;
    function  InitCardForFSK():boolean;
    procedure FreeCardForFSK();
    procedure ThreadKernelProcess();
  
protected
    procedure Execute(); 
override;
  
public
    TotalTrunkNum,InTrunkNum,OutTrunkNum:Word;
    TrunkConnected:array of boolean;

    constructor Create(
const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
    destructor Destroy(); 
override;
    
//初始化中繼卡
    function  InitCard(const isFSKComm: boolean): Boolean;
    
//釋放中繼卡  
    function  FreeCommCard():boolean;
    
//開始執行中繼卡管理模組
    procedure StartRunCommModule();
    
//獲取一個空閒通道(指定通道型別)
    function  GetAFreeTrunkByType(const aTrunkType:TTrunkType):integer;
    
//獲取一個空閒撥出通道
    function  GetAFreeTrunkByOut():integer;
    
//結束通話指定通道
    procedure HangOfByTrunkID(const aChannelID:integer);
    
//通過指定通道撥號
    procedure DialPhoneByTrunkID(const aChannelID:integer;const phoneNumber,callerNumber:PChar;const aDevID:integer=-1);
    
//通過指定通道傳送資料
    function  SendStringByTrunkID(const aChannelID:integer;const sendBuffer:PChar):boolean;
  end;

implementation

{ TDJCommCardSS1 }
uses
  unDJChannelSS1;

constructor TDJCommCardSS1.Create(
const aStateEvent: TTrunkSatausEvent;
  
const aRecEvent:TTrunkReceiveEvent);
begin
  inherited Create(
true);
  Self.FreeOnTerminate :
= true;
  onTrunkEvent :
= aStateEvent;
  onRecEvent :
= aRecEvent;
end;

destructor TDJCommCardSS1.Destroy();
begin
  Self.Suspend();
  Self.Terminate();
  FreeCommCard();
end;

procedure TDJCommCardSS1.DialPhoneByTrunkID(
const aChannelID: integer;
  
const phoneNumber, callerNumber: PChar;const aDevID:integer);
begin
  
if (aChannelID > ErrTrunkId) and (DJTrk_CheckTrunkFree(aChannelID)) then
    TDJCommChannelsSS1(Trunks[aChannelID]).StartDialPhone(phoneNumber,callerNumber,aDevID,);
end;

procedure TDJCommCardSS1.Execute;
begin
  
while NOT Terminated do
  begin
    Synchronize(ThreadKernelProcess);
    Sleep(
1);
  end;
end;

procedure TDJCommCardSS1.FreeCardForFSK();
begin
  
if CommIsFSK and isLoadFSK then
  begin
    DJFsk_Release();
  end;
end;

function TDJCommCardSS1.FreeCommCard(): boolean;
var
  Loop:Word;
begin
  Sleep(
1000);
  
if TotalTrunkNum > 0 then
  begin
    
for Loop:= 0 to TotalTrunkNum - 1 do
    begin
      
if Assigned(TDJCommChannelsSS1(Trunks[Loop])) then
      begin
        TDJCommChannelsSS1(Trunks[Loop]).Free();
        TDJCommChannelsSS1(Trunks[Loop]) :
= nil;
      end;
    end;
  end;
  DJSys_DisableCard();
  FreeCardForFSK();
  Result :
= true;
end;

function TDJCommCardSS1.GetAFreeTrunkByOut(): integer;
begin
  Result :
= GetAFreeTrunkByType(Type_Export);
end;

function TDJCommCardSS1.GetAFreeTrunkByType(
  
const aTrunkType: TTrunkType): integer;
var
  Loop:Word;
begin
  Result :
= ErrTrunkID;
  
for Loop := 0 to TotalTrunkNum - 1 do
  begin
    
if ((TDJCommChannelsSS1(Trunks[Loop]).GetTrunkType() = aTrunkType)
          and (DJTrk_CheckTrunkFree(Loop))) then
    begin
      Result :
= Loop;
      
break;
    end;
  end;
end;

procedure TDJCommCardSS1.HangOfByTrunkID(
const aChannelID: integer);
begin
  TDJCommChannelsSS1(Trunks[aChannelID]).InOutHangOff();
end;

function TDJCommCardSS1.InitCard(
const isFSKComm: boolean): Boolean;
const
  PromptFile 
= 'Prompt.ini';
var
  Loop: Integer;
  isOK: boolean;
  TimeOfNow: SystemTime;
begin
  Result :
= False;
  CommIsFSK :
= isFSKComm;
  isOK :
=(DJSys_EnableCard('',PromptFile)=_ERR_OK);
  
if Not isOK then exit;
  isOK :
= InitCardForFSK();
  
if NOT isOK then Exit;
  isLoadFSK :
= isOK;
  GetLocalTime(TimeOfNow);
  DJSys_SetSysTime(TimeOfNow.wHour,TimeOfNow.wMinute,TimeOfNow.wSecond);
  TotalTrunkNum:
=DJTrk_GetTotalTrunkNum();
  InTrunkNum:
=TotalTrunkNum shr 1;
  OutTrunkNum:
=TotalTrunkNum - InTrunkNum;

  SetLength(Trunks,TotalTrunkNum);
  SetLength(TrunkConnected,TotalTrunkNum);

  
for Loop:=0 to OutTrunkNum-1 do
    Trunks[Loop]:
=TDJCommChannelsSS1.Create(Self,Loop,Type_Export,CommIsFSK,onTrunkEvent,onRecEvent);
  
for Loop:=OutTrunkNum to TotalTrunkNum-1 do
    Trunks[Loop]:
=TDJCommChannelsSS1.Create(Self,Loop,Type_Import,CommIsFSK,onTrunkEvent,onRecEvent);
  
for Loop:= 0 to TotalTrunkNum - 1 do
  begin
    TDJCommChannelsSS1(Trunks[Loop]).ClearTrunkBuffer(csReceiving);
  end;

  DJSys_AutoApplyDtmf(ENABLEDTMF);    
//自動分配DTMF資源
  DJSys_EnableAutoKB();                 //自動回送KB訊號
  isOK:=isOK and DJSys_EnableDtmfSend();
  Result :
= isOK;
end;

function TDJCommCardSS1.InitCardForFSK(): boolean;
var
  k:integer;
begin
  Result :
= true;
  
if CommIsFSK then
  begin
    k :
= DJFsk_InitForFsk(SZK_Mode);
    Result :
= (k = 1);
  end;
end;

function TDJCommCardSS1.SendStringByTrunkID(
const aChannelID: integer;
  
const sendBuffer: PChar):boolean;
begin
  Result :
= TDJCommChannelsSS1(Trunks[aChannelID]).SendString(sendBuffer);
end;

procedure TDJCommCardSS1.StartRunCommModule();
begin
  Resume();
end;

procedure TDJCommCardSS1.ThreadKernelProcess();
var
  Loop:Word;
begin
  DJSys_PushPlay();
  
for Loop := 0 to TotalTrunkNum - 1 do
  begin
    
try
      TDJCommChannelsSS1(Trunks[Loop]).DJChannelProcessor();
    except
    end;
  end;
end;

end.

 

通道類原始碼:

//------------------------------------------------------------------------------
//
//      產品名稱:   成曉旭的個人軟體Delphi原始碼庫
//      產品版本:   CXXSoft delphi code source lib 2.0
//      模組名稱:   Delphi之東進數字語音卡通道類
//      模組描述:   
//      單元檔案:   unDJChannelSS1.pas   
//      開發作者:   成曉旭
//      作者blog:   http://blog.csdn.net/CXXSoft
//      備註:       任何人使用此檔案時,請保留此段自述檔案,謝謝!
//      開發時間:   2005-01-09
//      修改歷史:   
//      修改描述:
//------------------------------------------------------------------------------
unit unDJChannelSS1;

interface
uses
  Windows, SysUtils,
  unBaseDefine,
  Tce1_32,
  Tce1_FSK,
  unDJCardSS1;
type

  TCXXStatus 
= (csSending,csReceiving,csPlaying);
  
  TDJCommChannelsSS1 
= class(TObject)
  
private
    CommIsFSK:boolean;
    controller:TDJCommCardSS1;
    TrunkID:integer;
    TrunkStep:TTrunkStep;

    MaxBuffer: array [
0..DTMF_BUFFER_SIZE-1] of Char;
    msgChannel:TTrunkStatusInfo;
    msgFrame:TRecCommFrame;

    commFrameNumber,recPos:Word;
    subStatus:TCXXStatus;
    commPhone:
string;
    commFrameStr:
string;

    
//應該進一步優化為注入的介面,非簡單的回撥控制程式碼
    onTrunkState:TTrunkSatausEvent;
    onRecEvent:TTrunkReceiveEvent;
    InOutType:TTrunkType;

    function  SendDataFromTrunk():boolean;
    function  CheckSendDataEnd():boolean;
    procedure SaveMaxBufferToFrameStr();
    procedure ProcessConnected();
    
//注意:此方法與具體業務的通訊協議存在嚴重依賴關係(IoC實現依賴反轉)
    function  CheckReceiveOverFSK(const dataBuffer:array of char;const dataNumber:Word):boolean;
    
//注意:此方法與具體業務的通訊協議存在嚴重依賴關係(IoC實現依賴反轉)
    function  CheckReceiveOverDTMF(const dataBuffer:array of char;const dataNumber:Word):boolean;
    function  GetCommData(
const dataBuffer:array of char;const dataNumber:Word):string;
    function  ReceiveDataFromTrunk():boolean;

    procedure InformChannelStatus(
const aStep:TTrunkStep;const lvof:TLVOperateFlag);
    procedure InformBusinessStatus(
const aCommData:string;const cif:TCommInformFlag);
    procedure InformDialStatus(
const aStep:TTrunkStep);
    procedure InWaitingIntoToConnect();
    function  GetCommFrameFromSendString(
const commFrame:string):string;

    procedure RegisterTrunkEvent(
const trunkStateEvent:TTrunkSatausEvent);
    procedure RegisterReceiveEvent(
const trunkRecEvent:TTrunkReceiveEvent);
  
public
    
    constructor Create(
const trunkController: TDJCommCardSS1; const TrkID: Integer;
      
const TrunkType: TTrunkType;const isFSKComm: boolean;
      
const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
    destructor Destroy; 
override;

    
//獲取通道狀態
    function GetTrunkType():TTrunkType;
    procedure DJChannelProcessor();
    
//通道掛機
    procedure InOutHangOff();
    
//開始撥號
    procedure StartDialPhone(const phoneNumber,callerNumber:PChar;const aDevID:integer=-1);
    
//傳送通訊資料
    function  SendString(const pchSend:PChar):boolean;
    
//清空通道資料緩衝
    procedure ClearTrunkBuffer(const aSB:TCXXStatus);
    
//獲取通道號
    function  GetTrunkID():integer;
  end;

implementation

{ TDJCommChannelsSS1 }
const
  Frame_FillChar 
= #0;
  Leader_Flag 
= $55;
  HeadNumber 
= 30;
  hasLeader 
= true;
  
function TDJCommChannelsSS1.CheckSendDataEnd(): boolean;
begin
  Result :
= false;
  
if CommIsFSK then
  begin
    
if (DJFsk_CheckSendFSKEnd(TrunkID,SZK_Mode) = 1) then
    begin
      DJFsk_StopSend(TrunkID,SZK_Mode);
      Result :
= true;
    end;
  end
  
else
  begin
    
if DJTrk_CheckDtmfSendEnd(TrunkID) then
    begin
      DJVoc_StopPlayFile(TrunkID);
      Result :
= true;
    end;
  end;
  
if Result then
    ClearTrunkBuffer(csReceiving);
end;

procedure TDJCommChannelsSS1.ClearTrunkBuffer(
const aSB:TCXXStatus);
begin
  subStatus :
= aSB;
  
if CommIsFSK then
    DJFsk_ResetFskBuffer(TrunkID,SZK_Mode)
  
else
    DJTrk_InitDtmfBufNew(TrunkID);
  commFrameNumber :
= 0;
  recPos :
= 0;
end;

constructor TDJCommChannelsSS1.Create(
const trunkController: TDJCommCardSS1; const TrkID: Integer;
  
const TrunkType: TTrunkType; const isFSKComm: boolean;
  
const aStateEvent: TTrunkSatausEvent;const aRecEvent:TTrunkReceiveEvent);
var
  t:TTrunkType;
begin
  inherited Create;
  RegisterTrunkEvent(aStateEvent);
  RegisterReceiveEvent(aRecEvent);
  controller :
=trunkController;
  TrunkID:
=TrkID;
  commPhone :
= '';
  TrunkStep:
=TTrunkStep(-1);
  t :
= TrunkType;
  
if DJTrk_SetTrunkType(TrkID,t) then
    InOutType:
=TrunkType;
  CommIsFSK :
= isFSKComm;
  controller.TrunkConnected[TrunkID] :
= false;
  ClearTrunkBuffer(csReceiving);
  InformChannelStatus(Step_Free,lvofAdd);
end;

destructor TDJCommChannelsSS1.Destroy();
begin
  inherited;
  DJTrk_BackwardHangUp(TrunkID);
end;

procedure TDJCommChannelsSS1.DJChannelProcessor();
var
  aStep: TTrunkStep;
begin
  
//DJSys_PushPlay();
  aStep:= DJTrk_GetTrunkStatus(TrunkID);
  
//狀態變化
  if TrunkStep <> aStep then
  begin
    TrunkStep:
= aStep;
    InformChannelStatus(TrunkStep,lvofUpdate);
  end;
  
//前向掛機
  if (TrunkStep<>Step_Free) and DJTrk_CheckForwardHangUp(TrunkID) then
  begin
    InOutHangOff();
  end;
  
//入中繼撥入,等待接續(建立連線)
  if (TrunkStep = Step_Wait) and (DJTrk_CheckTrunkIn(TrunkID)) then
  begin
    InWaitingIntoToConnect();
  end;
  
//通道連線已經建立
  if (TrunkStep = Step_Connect) then
  begin
    ProcessConnected();
  end;
  
//出通道撥號失敗
  if TrunkStep=Step_DialFail then
  begin
    InformDialStatus(TrunkStep);
  end;
  
if TrunkStep=Step_Delay then
    Exit;
  
//出入通道空閒
  if TrunkStep = Step_Free then
  begin
    
//等待接收呼入
  end;
end;

function TDJCommChannelsSS1.GetTrunkID(): integer;
begin
  Result :
= Self.TrunkID;
end;

procedure TDJCommChannelsSS1.InformChannelStatus(
const aStep: TTrunkStep;const lvof:TLVOperateFlag);
begin
  msgChannel.lvFlag :
= lvof;
  msgChannel.TrunkID :
= IntToStr(Self.TrunkID);
  msgChannel.DeviceID :
= '';
  msgChannel.TrunkTypeStr:
=TrunkTypeInStr[InOutType];
  msgChannel.TrunkStep :
= Ord(aStep);
  msgChannel.TrunkStepStr:
=TrunkStepInStr[aStep];
  
if aStep = Step_Free then
  begin
    msgChannel.Phone:
='';
    msgChannel.Data:
='';
  end
  
else
  begin
    msgChannel.Phone:
=commPhone;
    msgChannel.Data:
=commFrameStr;
  end;
  
if Assigned(onTrunkState) then
    onTrunkState(msgChannel);
end;

procedure TDJCommChannelsSS1.InformDialStatus(
const aStep: TTrunkStep);
var
  dStatus:TDialStatus;
begin
  dStatus :
= DJTrk_GetDialStatus(TrunkID);
  
case dStatus of
  DS_Busy,DS_OverTime,DS_NoUser,DS_LineError:
  begin
    InOutHangOff();
  end;
  end;
end;

procedure TDJCommChannelsSS1.InformBusinessStatus(
const aCommData: string;const cif:TCommInformFlag);
begin
  
//依賴注入的業務處理介面呼叫,實現業務處理的
end;

procedure TDJCommChannelsSS1.InOutHangOff();
begin
  DJTrk_BackwardHangUp(TrunkID);
  controller.TrunkConnected[TrunkID] :
= false;
  InformBusinessStatus(
'',cifDisconnected);
end;

procedure TDJCommChannelsSS1.InWaitingIntoToConnect;
begin
  DJVoc_PlayFile(TrunkID,
'.Voicedtmf13');
  DJVoc_StopPlayFile(TrunkID);
end;


procedure TDJCommChannelsSS1.ProcessConnected();
var
  ss:TCXXStatus;  
begin
  
if NOT controller.TrunkConnected[TrunkID] then
  begin
    controller.TrunkConnected[TrunkID] :
= true;
    ss :
= csReceiving;
    InformBusinessStatus(
'',cifConnected);
    ClearTrunkBuffer(ss);
  end;
  
case subStatus of
  csSending:
  begin
    
if CheckSendDataEnd() then
    begin
        InformChannelStatus(Step_Connect,lvofUpdate);
        InformBusinessStatus(commFrameStr,cifSend);
    end;
  end;
  csReceiving:
  begin
    
if ReceiveDataFromTrunk() then
    begin
      msgFrame.CommFrame :
= commFrameStr;
      msgFrame.CommType :
= Comm_FSK;
      InformChannelStatus(Step_Connect,lvofUpdate);
      InformBusinessStatus(commFrameStr,cifReceive);
    end;
  end;
  csPlaying:
  begin
    
  end;
  end;
end;

function TDJCommChannelsSS1.ReceiveDataFromTrunk(): boolean;
var
  num,Loop:integer;
  tempBuffer:array[
0..DTMF_BUFFER_SIZE-1] of Char;
begin
  Result :
= false;
  
try
    
if Self.CommIsFSK then
    begin
      
//FSK方式版本
      FillChar(tempBuffer,DTMF_BUFFER_SIZE,Frame_FillChar);
      num :
= DJFsk_GetFSK(TrunkID,tempBuffer,SZK_MODE);
      
if (num > 0) then
      begin
        
if CheckReceiveOverFSK(tempBuffer,num) then
        begin
          Self.commFrameStr :
= GetCommData(tempBuffer,num);
          Self.ClearTrunkBuffer(csReceiving);
          Result :
= true;
        end;
      end;
    end
    
else
    begin
      
//DTMF方式版本
      num := DJTrk_GetReceiveDtmfNumNew(TrunkID);
      
if num > 0 then
      begin
        
for Loop := 0 to num - 1 do
        begin
          MaxBuffer[recPos
+Loop] := DJTrk_GetDtmfCodeNew(TrunkID);
          recPos :
= (recPos + 1) mod DTMF_BUFFER_SIZE;
        end;
        Inc(commFrameNumber,num);
        
if CheckReceiveOverDTMF(tempBuffer,num) then
        begin
          ClearTrunkBuffer(csReceiving);
          Result :
= true;
        end;
      end;
    end;
  except
    Result :
= false;
  end;
end;

procedure TDJCommChannelsSS1.RegisterReceiveEvent(
  
const trunkRecEvent: TTrunkReceiveEvent);
begin
  onRecEvent :
= trunkRecEvent;
end;

procedure TDJCommChannelsSS1.RegisterTrunkEvent(
  
const trunkStateEvent: TTrunkSatausEvent);
begin
  onTrunkState :
= trunkStateEvent;
end;

procedure TDJCommChannelsSS1.SaveMaxBufferToFrameStr();
var
  Loop:Word;
begin
  commFrameStr :
= '';
  
for Loop := 0 to commFrameNumber - 1 do
  begin
    commFrameStr :
= commFrameStr + MaxBuffer[Loop];
  end;
end;

function TDJCommChannelsSS1.SendDataFromTrunk():boolean;
begin
  Result :
= false;
  
if controller.TrunkConnected[TrunkID] then
  begin
    
if CommIsFSK then
    begin
      Result :
= DJFsk_SendFSK(TrunkID,@MaxBuffer[0],commFrameNumber,SZK_Mode) = 1;
    end
    
else
    begin
      Result :
= DJTrk_SendDtmfStr(TrunkID,@MaxBuffer[0]) = 1;
    end;
  end;
  
if Result then
    subStatus :
= csSending;
end;

function TDJCommChannelsSS1.SendString(
const pchSend: PChar):boolean;
var
  Loop:integer;
  strTemp:
string;
begin
  Result :
= false;
  
if Self.CommIsFSK and hasLeader then
  begin
    
//加FSK前導字元的版本
    strTemp := GetCommFrameFromSendString(pchSend);
    commFrameNumber :
= Length(strTemp);
    
if commFrameNumber > 0 then
    begin
      
for Loop := 0 to commFrameNumber-1 do
        MaxBuffer[Loop] :
= strTemp[Loop+1];
      MaxBuffer[commFrameNumber] :
= #0;
      SaveMaxBufferToFrameStr();
      Result :
= SendDataFromTrunk();
    end;
  end
  
else
  begin
    
//不加前導字元的版本
    commFrameNumber := Length(pchSend);
    
if commFrameNumber > 0 then
    begin
      
for Loop := 0 to commFrameNumber-1 do
        MaxBuffer[Loop] :
= pchSend[Loop];
      MaxBuffer[commFrameNumber] :
= #0;
      SaveMaxBufferToFrameStr();
      Result :
= SendDataFromTrunk();
    end;
  end;
end;

procedure TDJCommChannelsSS1.StartDialPhone(
const phoneNumber,
  callerNumber: PChar;
const aDevID:integer);
begin
  
if DJTrk_CheckTrunkFree(TrunkID) and(Trim(phoneNumber) <> '') then
  begin
    commPhone :
= Trim(phoneNumber);
    DJTrk_StartDial(TrunkID,PChar(commPhone),
'');
  end;
end;

function TDJCommChannelsSS1.CheckReceiveOverFSK(
const dataBuffer: array of char;
  
const dataNumber: Word): boolean;
begin
  
//業務實現方法:判定通訊幀串傳送結束
  Result := true;
end;

function TDJCommChannelsSS1.GetCommData(
const dataBuffer: array of char;
  
const dataNumber: Word): string;
var
  Loop:Word;
begin
  Result :
= '';
  
if dataNumber <= 0 then Exit;
  
for Loop := 0 to dataNumber - 1 do
  begin
    
if (dataBuffer[Loop] <> Frame_FillChar) then
      Result :
= Result + dataBuffer[Loop];
  end;
end;

function TDJCommChannelsSS1.GetCommFrameFromSendString(
  
const commFrame: string): string;
var
  Loop:integer;
begin
  Result :
= commFrame;
  
for Loop := 0 to HeadNumber - 1 do
    Result :
= CHR(Leader_Flag) + Result;
end;

function TDJCommChannelsSS1.CheckReceiveOverDTMF(
  
const dataBuffer: array of charconst dataNumber: Word): boolean;
begin
  
//業務實現方法:判定通訊幀串傳送結束
  Result := true;
end;

function TDJCommChannelsSS1.GetTrunkType(): TTrunkType;
begin
  Result :
= Self.InOutType;
end;

end.

 

 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1770257


相關文章