模拟语音卡
                            
                            
                            Delphi之東進(jìn)模擬語音卡(D160A)可復(fù)用源碼
 
網(wǎng)友急需,先開源吧,文檔過幾天慢慢補。
 
 作者:成曉旭 
 
 設(shè)計簡介: 1、?? 將卡、通道分別單獨進(jìn)行設(shè)計與封裝。 2、?? 所有的外部操作接口都封裝在卡類這一類。 3、?? 在我的項目中,在卡類這一級還增加了適配器或者代理,分別實現(xiàn)了Adapter或Proxy模式;以盡可能地解耦卡設(shè)備的實現(xiàn)細(xì)節(jié)與具體應(yīng)用業(yè)務(wù)之間的關(guān)系。因為,我們的系統(tǒng)中使用了幾家不同的卡設(shè)備,另一方面,這些卡設(shè)備,在不同的軟件系統(tǒng)中,又有不同的業(yè)務(wù)應(yīng)用需求。 4、?? 當(dāng)然,卡這一級,也可以實現(xiàn)一個統(tǒng)一的接口,這樣對外部可以表現(xiàn)出相對統(tǒng)一的行為,以方便業(yè)務(wù)層代碼的調(diào)用,比如說:在數(shù)據(jù)采集的應(yīng)用中,統(tǒng)一的接口可以讓采集控制層不必依賴于具體的采集設(shè)備和通信方式,可以一致地實現(xiàn)數(shù)據(jù)收發(fā),不管通信方式是RS232、RS485、TCP/IP、PSTN,還是別的方式或者通信設(shè)備。 5、?? 在通道設(shè)計中,核心的就是一個“狀態(tài)機模式”,通過輪巡通道狀態(tài)來管理硬件卡設(shè)備,并且,還自己設(shè)計了一個業(yè)務(wù)級的“業(yè)務(wù)狀態(tài)機”,來抽象業(yè)務(wù)方面需要關(guān)心的“業(yè)務(wù)狀態(tài)”,通過增加“業(yè)務(wù)狀態(tài)機”這樣一個中間層,以解耦業(yè)務(wù)狀態(tài)與設(shè)備狀態(tài)之間的依賴。(這一點,在我看到的所有卡廠商提供的各類Demo程序里面都沒有這樣做,這也無形中誤導(dǎo)了很多的開發(fā)人員,我看到的所有應(yīng)用軟件開發(fā)的源碼都是:設(shè)備細(xì)節(jié)、尤其是通道狀態(tài),與業(yè)務(wù)邏輯代碼緊緊地耦合在一起,難解難分)。 6、?? 此設(shè)計的另一個亮點是:IoC模式的應(yīng)用(2004年自己在設(shè)計此類時還不知道這個概念,全憑自己的經(jīng)驗總結(jié)出這樣的設(shè)計)。對通道進(jìn)入“呼入成功”、“呼出成功”等業(yè)務(wù)狀態(tài)的調(diào)用代碼從通道類是解耦出來:設(shè)計一個接口,在各個業(yè)務(wù)狀態(tài)的處理方法中,再調(diào)用接口方法,將具體的業(yè)務(wù)處理邏輯委托給實現(xiàn)此接口的對象。并且這個接口的實現(xiàn)是通過“依賴注入”實現(xiàn)IoC的。這樣設(shè)計,就達(dá)到了很好的可復(fù)用性和靈活性。 7、?? 當(dāng)然,更好的實現(xiàn)可以采用AOP(面向方法編程)的思想或者實現(xiàn)技術(shù),這樣可復(fù)用性更好,如此設(shè)計,在業(yè)務(wù)與卡方法的調(diào)用之間,耦合度將是最低的。 8、?? 目前的版本,沒有在代碼中體現(xiàn)接口的實現(xiàn)…… 9、?? 類圖(以后補上): ??? 10、卡類源碼: 
 
  //------------------------------------------------------------------------------
//
//??????產(chǎn)品名稱:???成曉旭的個人軟件Delphi源碼庫
//??????產(chǎn)品版本:???CXXSoft?delphi?code?source?lib?2.0
//??????模塊名稱:???Delphi之東進(jìn)模擬語音卡類
//??????模塊描述:???
//??????單元文件:???unDJCard160A.pas???
//??????開發(fā)作者:???成曉旭
//??????備注:???????任何人使用此文件時,請保留此段自述文件,謝謝!
//??????開發(fā)時間:???2004-08-03
//??????修改歷史:???
//??????修改描述:
//------------------------------------------------------------------------------
unit?unDJCard160A;
interface
uses
??Windows,
??unDJTC08a32,unDJNewSig,
??unBaseDefine,unDJ160ADefine,
??unDJChanne160A;
type
??TCXXCommCard160A?=?class(TObject)
??private
????ChannelNumber:Word;
????channelObject:array?of?TCXXDJChannel160A;
????OnCardChannelState:TTrunkStatusEvent;
????procedure?Stop();
????procedure?ReleaseCommDevice();
????function??GetChannelObjectOrder(const?aChannelID:Word):Word;
??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
...{?TCXXCommCard160A?}
constructor?TCXXCommCard160A.Create(const?trunkEvent:TTrunkStatusEvent);
begin
??ChannelNumber?:=?0;
??Self.OnCardChannelState?:=?trunkEvent;
end;
destructor?TCXXCommCard160A.Destroy;
var
??Loop:Word;
begin
??Stop();
??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?TCXXCommCard160A.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?TCXXCommCard160A.ReleaseCommDevice();
begin
??DisableCard();
??FreeDrv();
end;
function?TCXXCommCard160A.GetAFreeChannel():?Word;
var
??Loop:Word;
begin
??Result?:=?ErrorTrunkNumber;
??for?Loop?:=?Low(channelObject)?to?High(channelObject)?do
??begin
????if?(channelObject[Loop].GetChannelType()?=?ctEmpty)?then?continue;
????if?(channelObject[Loop].GetChannelStatus()?=?atsFree)?then
????begin
??????Result?:=?channelObject[Loop].GetChannelID();
??????break;
????end;
??end;
end;
function?TCXXCommCard160A.GetChannelNumber():?Word;
begin
??Result?:=?channelNumber;
end;
function?TCXXCommCard160A.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?TCXXCommCard160A.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?TCXXCommCard160A.LoadCommDevice(const?loadAll:boolean):?boolean;
const
??loadEmpty?=?true;
var
??Loop,tempNumber:Word;
??isFlag:LongInt;
??function?CheckLoadTrunk():boolean;
??begin
????Result?:=?loadAll?or?((NOT?loadAll)?and(TChannelType(CheckChType(Loop))?<>?ctEmpty));
??end;
begin
??isFlag?:=?LoadDRV();
??Result?:=?(isFlag=0);
??if?NOT?Result?then?Exit;
??tempNumber?:=?CheckValidCh();
??Result?:=?EnableCard(tempNumber,1024*8)=0;
??if?NOT?Result?then
??begin
????FreeDrv();
????Exit;
??end;
??Result?:=?Sig_Init()=1;
??if?NOT?Result?then?Exit;
??SetBusyPara(700);
??SetPackRate(PACK_64KBPS?);
??channelNumber?:=?tempNumber;
??SetLength(channelObject,channelNumber);
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????if?CheckLoadTrunk()?then
????begin
??????channelObject[Loop]?:=?TCXXDJChannel160A.Create(OnCardChannelState);
??????channelObject[Loop].CreateCommChannel(Loop);
????end;
??end;
end;
function?TCXXCommCard160A.Startup():?boolean;
var
??Loop:integer;
begin
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????channelObject[Loop].Resume();
??end;
??Result?:=?true;
end;
procedure?TCXXCommCard160A.Stop();
var
??Loop:integer;
begin
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????channelObject[Loop].Suspend();
????channelObject[Loop].Terminate();
????channelObject[Loop]?:=?nil;
??end;
end;
end.
11、????????????? 通道類源碼: //------------------------------------------------------------------------------
//
//??????產(chǎn)品名稱:???成曉旭的個人軟件Delphi源碼庫
//??????產(chǎn)品版本:???CXXSoft?delphi?code?source?lib?2.0
//??????模塊名稱:???Delphi之東進(jìn)模擬語音卡通道類
//??????模塊描述:???
//??????單元文件:???unDJChanne160A.pas???
//??????開發(fā)作者:???成曉旭
//??????備注:???????任何人使用此文件時,請保留此段自述文件,謝謝!
//??????開發(fā)時間:???2004-08-03
//??????修改歷史:???
//??????修改描述:
//------------------------------------------------------------------------------
unit?unDJChanne160A;
interface
uses
??Windows,Classes,SysUtils,
??unBaseDefine,unDJ160ADefine,
??unDJTC08a32,unDJNewSig;
Type
??TCXXDJChannel160A?=?class(TThread)
??//TCXXDJChannel160A?=?class(TObject)
??private
????channelType:TChannelType;
????oldChannelState,channelState:TTrunkState;
????channelID:Word;
????phoneNumber:string;
????dtmfString:string;
????isConntectd:boolean;
????isDialOut:boolean;
????aTrunkState:TTrunkStatus;
????
????procedure?InformTrunkStatus(const?aMsgFlag:?TLVOperateFlag);
????procedure?ClearTrunkStatus();
????function??CheckSigHangup():boolean;
????function??CheckCallIn():boolean;
????function??SwitchOnCallIn():boolean;
????procedure?ProcessCallInSuccess();
????procedure?ProcessDialSuccess();
????procedure?ProcessCheckDialSend();
??protected
????procedure?Execute();?override;
??public
????strMessage:string;
????OnChannelState:TTrunkStatusEvent;
????constructor?Create(const?trunkEvent:TTrunkStatusEvent);
????destructor?Destroy();override;
????procedure?CreateCommChannel(const?aChennelID:?Word);
????procedure?ChannelProcessor();
????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;
??end;
implementation
...{?TCXXDJChannel160A?}
procedure?TCXXDJChannel160A.ChannelHangUp();
begin
??isDialOut?:=?false;
??StopSigCheck(channelID);
??HangUp(channelID);
??Sig_ResetCheck(channelID);
??StartSigCheck(channelID);
??InitDTMFBuf(channelID);
??ClearTrunkStatus();
??InformTrunkStatus(lvofUpdate);
end;
procedure?TCXXDJChannel160A.ChannelProcessor();
var
??dState:Word;
begin
??PUSH_PLAY();
??FeedSigFunc();
??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
??????dState?:=?Sig_CheckDial(channelID);
??????case?dState?of
??//??????S_NORESULT:
????????S_CONNECT:
????????begin
??????????channelState?:=?atsDialSuccess;
??????????isConntectd?:=?true;
????????end;
????????S_BUSY,
????????S_NOBODY,
????????S_NODIALSIG,
????????S_NOSIGNAL:
????????begin
??????????channelState?:=?atsHangOff;
????????end;
??????end;
??????strMessage?:=?'撥號中...';
????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?TCXXDJChannel160A.CheckCallIn():?boolean;
begin
??Result?:=?RingDetect(channelID);
??if?Result?then
??begin
????OffHook(channelID);
????if?isDialOut?then
??????channelState?:=?atsDialSuccess
????else
??????channelState?:=?atsCallIning;
??end;
end;
function?TCXXDJChannel160A.CheckSigHangup():?boolean;
begin
??Result?:=?false;
??if?(Sig_CheckBusy(channelID)=1)?then
??begin
????strMessage?:=?'對方已掛機';
????InformTrunkStatus(lvofUpdate);
????StopPlayFile(channelID);
????channelState?:=?atsHangOff;
????Result?:=?true;
??end;
end;
procedure?TCXXDJChannel160A.ClearTrunkStatus();
begin
??channelState?:=?atsFree;
??oldChannelState?:=?channelState;
??phoneNumber?:=?'';
??dtmfString?:=?'';
??strMessage?:=?'';
??isConntectd?:=?false;
end;
constructor?TCXXDJChannel160A.Create(const?trunkEvent:TTrunkStatusEvent);
begin
??Self.OnChannelState?:=?trunkEvent;
??Self.FreeOnTerminate?:=?true;
??inherited?Create(true);
end;
destructor?TCXXDJChannel160A.Destroy;
begin
??Suspend();
??ChannelHangUp();
??//inherited?Destroy();
end;
function?TCXXDJChannel160A.DialPhone(const?DialPhoneNumber:PChar;
??const?PreDialNumber:PChar):?boolean;
begin
??isDialOut?:=?true;
??phoneNumber?:=?DialPhoneNumber;
??OffHook(channelID);
??InitDTMFBuf(channelID);
??Result?:=?Sig_StartDial(channelID,DialPhoneNumber,PreDialNumber,0)=1;
??channelState?:=?atsCheckSendDial;
end;
function?TCXXDJChannel160A.DialPhone(
??const?DialPhoneNumber:?PChar):?boolean;
begin
??Result?:=?DialPhone(DialPhoneNumber,'');
end;
procedure?TCXXDJChannel160A.Execute;
begin
??while?NOT?Terminated?do
??begin
????Synchronize(ChannelProcessor);
????Sleep(10);
??end;
end;
function?TCXXDJChannel160A.GetChannelID():?Word;
begin
??Result?:=?channelID;
end;
function?TCXXDJChannel160A.GetChannelStatus():?TTrunkState;
begin
??Result?:=?channelState;
end;
procedure?TCXXDJChannel160A.InformTrunkStatus(const?aMsgFlag:?TLVOperateFlag);
begin
??aTrunkState.lvFlag?:=?aMsgFlag;
??aTrunkState.TrunkID?:=?IntToStr(channelID);
??aTrunkState.TrunkType?:=?channelType;
??aTrunkState.TrunkTypeStr?:=?ChannelTypeString[channelType];
??aTrunkState.TrunkStep?:=?channelState;
??aTrunkState.TrunkStepStr?:=?TrunkStateString[channelState];
??aTrunkState.TrunkPhone?:=?phoneNumber;
??aTrunkState.TrunkData?:=?dtmfString;
??OnChannelState(aTrunkState);
end;
procedure?TCXXDJChannel160A.ProcessCallInSuccess();
begin
end;
function?TCXXDJChannel160A.SwitchOnCallIn():?boolean;
begin
??OffHook(channelID);
??InitDTMFBuf(channelID);
??StartSigCheck(channelID);
??channelState?:=?atsCallInSuccess;
??Result?:=?true;
end;
procedure?TCXXDJChannel160A.ProcessDialSuccess();
begin
end;
procedure?TCXXDJChannel160A.CreateCommChannel(const?aChennelID:?Word);
begin
??channelID?:=?aChennelID;
??channelType?:=?TChannelType(CheckChType(channelID));
??ClearTrunkStatus();
??InformTrunkStatus(lvofAdd);
end;
function?TCXXDJChannel160A.GetChannelType():?TChannelType;
begin
??Result?:=?channelType;
end;
function?TCXXDJChannel160A.GetDialOut():?boolean;
begin
??Result?:=?isDialOut;
end;
procedure?TCXXDJChannel160A.ProcessCheckDialSend();
begin
??if(CheckSendEnd(channelID)?=?1)?then
??begin
????StartSigCheck(channelID);
????channelState?:=?atsDialing;
??end;
end;
end.
                            
                        
                        
                        //
//??????產(chǎn)品名稱:???成曉旭的個人軟件Delphi源碼庫
//??????產(chǎn)品版本:???CXXSoft?delphi?code?source?lib?2.0
//??????模塊名稱:???Delphi之東進(jìn)模擬語音卡類
//??????模塊描述:???
//??????單元文件:???unDJCard160A.pas???
//??????開發(fā)作者:???成曉旭
//??????備注:???????任何人使用此文件時,請保留此段自述文件,謝謝!
//??????開發(fā)時間:???2004-08-03
//??????修改歷史:???
//??????修改描述:
//------------------------------------------------------------------------------
unit?unDJCard160A;
interface
uses
??Windows,
??unDJTC08a32,unDJNewSig,
??unBaseDefine,unDJ160ADefine,
??unDJChanne160A;
type
??TCXXCommCard160A?=?class(TObject)
??private
????ChannelNumber:Word;
????channelObject:array?of?TCXXDJChannel160A;
????OnCardChannelState:TTrunkStatusEvent;
????procedure?Stop();
????procedure?ReleaseCommDevice();
????function??GetChannelObjectOrder(const?aChannelID:Word):Word;
??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
...{?TCXXCommCard160A?}
constructor?TCXXCommCard160A.Create(const?trunkEvent:TTrunkStatusEvent);
begin
??ChannelNumber?:=?0;
??Self.OnCardChannelState?:=?trunkEvent;
end;
destructor?TCXXCommCard160A.Destroy;
var
??Loop:Word;
begin
??Stop();
??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?TCXXCommCard160A.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?TCXXCommCard160A.ReleaseCommDevice();
begin
??DisableCard();
??FreeDrv();
end;
function?TCXXCommCard160A.GetAFreeChannel():?Word;
var
??Loop:Word;
begin
??Result?:=?ErrorTrunkNumber;
??for?Loop?:=?Low(channelObject)?to?High(channelObject)?do
??begin
????if?(channelObject[Loop].GetChannelType()?=?ctEmpty)?then?continue;
????if?(channelObject[Loop].GetChannelStatus()?=?atsFree)?then
????begin
??????Result?:=?channelObject[Loop].GetChannelID();
??????break;
????end;
??end;
end;
function?TCXXCommCard160A.GetChannelNumber():?Word;
begin
??Result?:=?channelNumber;
end;
function?TCXXCommCard160A.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?TCXXCommCard160A.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?TCXXCommCard160A.LoadCommDevice(const?loadAll:boolean):?boolean;
const
??loadEmpty?=?true;
var
??Loop,tempNumber:Word;
??isFlag:LongInt;
??function?CheckLoadTrunk():boolean;
??begin
????Result?:=?loadAll?or?((NOT?loadAll)?and(TChannelType(CheckChType(Loop))?<>?ctEmpty));
??end;
begin
??isFlag?:=?LoadDRV();
??Result?:=?(isFlag=0);
??if?NOT?Result?then?Exit;
??tempNumber?:=?CheckValidCh();
??Result?:=?EnableCard(tempNumber,1024*8)=0;
??if?NOT?Result?then
??begin
????FreeDrv();
????Exit;
??end;
??Result?:=?Sig_Init()=1;
??if?NOT?Result?then?Exit;
??SetBusyPara(700);
??SetPackRate(PACK_64KBPS?);
??channelNumber?:=?tempNumber;
??SetLength(channelObject,channelNumber);
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????if?CheckLoadTrunk()?then
????begin
??????channelObject[Loop]?:=?TCXXDJChannel160A.Create(OnCardChannelState);
??????channelObject[Loop].CreateCommChannel(Loop);
????end;
??end;
end;
function?TCXXCommCard160A.Startup():?boolean;
var
??Loop:integer;
begin
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????channelObject[Loop].Resume();
??end;
??Result?:=?true;
end;
procedure?TCXXCommCard160A.Stop();
var
??Loop:integer;
begin
??for?Loop?:=?0?to?channelNumber?-?1?do
??begin
????channelObject[Loop].Suspend();
????channelObject[Loop].Terminate();
????channelObject[Loop]?:=?nil;
??end;
end;
end.
11、????????????? 通道類源碼: //------------------------------------------------------------------------------
//
//??????產(chǎn)品名稱:???成曉旭的個人軟件Delphi源碼庫
//??????產(chǎn)品版本:???CXXSoft?delphi?code?source?lib?2.0
//??????模塊名稱:???Delphi之東進(jìn)模擬語音卡通道類
//??????模塊描述:???
//??????單元文件:???unDJChanne160A.pas???
//??????開發(fā)作者:???成曉旭
//??????備注:???????任何人使用此文件時,請保留此段自述文件,謝謝!
//??????開發(fā)時間:???2004-08-03
//??????修改歷史:???
//??????修改描述:
//------------------------------------------------------------------------------
unit?unDJChanne160A;
interface
uses
??Windows,Classes,SysUtils,
??unBaseDefine,unDJ160ADefine,
??unDJTC08a32,unDJNewSig;
Type
??TCXXDJChannel160A?=?class(TThread)
??//TCXXDJChannel160A?=?class(TObject)
??private
????channelType:TChannelType;
????oldChannelState,channelState:TTrunkState;
????channelID:Word;
????phoneNumber:string;
????dtmfString:string;
????isConntectd:boolean;
????isDialOut:boolean;
????aTrunkState:TTrunkStatus;
????
????procedure?InformTrunkStatus(const?aMsgFlag:?TLVOperateFlag);
????procedure?ClearTrunkStatus();
????function??CheckSigHangup():boolean;
????function??CheckCallIn():boolean;
????function??SwitchOnCallIn():boolean;
????procedure?ProcessCallInSuccess();
????procedure?ProcessDialSuccess();
????procedure?ProcessCheckDialSend();
??protected
????procedure?Execute();?override;
??public
????strMessage:string;
????OnChannelState:TTrunkStatusEvent;
????constructor?Create(const?trunkEvent:TTrunkStatusEvent);
????destructor?Destroy();override;
????procedure?CreateCommChannel(const?aChennelID:?Word);
????procedure?ChannelProcessor();
????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;
??end;
implementation
...{?TCXXDJChannel160A?}
procedure?TCXXDJChannel160A.ChannelHangUp();
begin
??isDialOut?:=?false;
??StopSigCheck(channelID);
??HangUp(channelID);
??Sig_ResetCheck(channelID);
??StartSigCheck(channelID);
??InitDTMFBuf(channelID);
??ClearTrunkStatus();
??InformTrunkStatus(lvofUpdate);
end;
procedure?TCXXDJChannel160A.ChannelProcessor();
var
??dState:Word;
begin
??PUSH_PLAY();
??FeedSigFunc();
??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
??????dState?:=?Sig_CheckDial(channelID);
??????case?dState?of
??//??????S_NORESULT:
????????S_CONNECT:
????????begin
??????????channelState?:=?atsDialSuccess;
??????????isConntectd?:=?true;
????????end;
????????S_BUSY,
????????S_NOBODY,
????????S_NODIALSIG,
????????S_NOSIGNAL:
????????begin
??????????channelState?:=?atsHangOff;
????????end;
??????end;
??????strMessage?:=?'撥號中...';
????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?TCXXDJChannel160A.CheckCallIn():?boolean;
begin
??Result?:=?RingDetect(channelID);
??if?Result?then
??begin
????OffHook(channelID);
????if?isDialOut?then
??????channelState?:=?atsDialSuccess
????else
??????channelState?:=?atsCallIning;
??end;
end;
function?TCXXDJChannel160A.CheckSigHangup():?boolean;
begin
??Result?:=?false;
??if?(Sig_CheckBusy(channelID)=1)?then
??begin
????strMessage?:=?'對方已掛機';
????InformTrunkStatus(lvofUpdate);
????StopPlayFile(channelID);
????channelState?:=?atsHangOff;
????Result?:=?true;
??end;
end;
procedure?TCXXDJChannel160A.ClearTrunkStatus();
begin
??channelState?:=?atsFree;
??oldChannelState?:=?channelState;
??phoneNumber?:=?'';
??dtmfString?:=?'';
??strMessage?:=?'';
??isConntectd?:=?false;
end;
constructor?TCXXDJChannel160A.Create(const?trunkEvent:TTrunkStatusEvent);
begin
??Self.OnChannelState?:=?trunkEvent;
??Self.FreeOnTerminate?:=?true;
??inherited?Create(true);
end;
destructor?TCXXDJChannel160A.Destroy;
begin
??Suspend();
??ChannelHangUp();
??//inherited?Destroy();
end;
function?TCXXDJChannel160A.DialPhone(const?DialPhoneNumber:PChar;
??const?PreDialNumber:PChar):?boolean;
begin
??isDialOut?:=?true;
??phoneNumber?:=?DialPhoneNumber;
??OffHook(channelID);
??InitDTMFBuf(channelID);
??Result?:=?Sig_StartDial(channelID,DialPhoneNumber,PreDialNumber,0)=1;
??channelState?:=?atsCheckSendDial;
end;
function?TCXXDJChannel160A.DialPhone(
??const?DialPhoneNumber:?PChar):?boolean;
begin
??Result?:=?DialPhone(DialPhoneNumber,'');
end;
procedure?TCXXDJChannel160A.Execute;
begin
??while?NOT?Terminated?do
??begin
????Synchronize(ChannelProcessor);
????Sleep(10);
??end;
end;
function?TCXXDJChannel160A.GetChannelID():?Word;
begin
??Result?:=?channelID;
end;
function?TCXXDJChannel160A.GetChannelStatus():?TTrunkState;
begin
??Result?:=?channelState;
end;
procedure?TCXXDJChannel160A.InformTrunkStatus(const?aMsgFlag:?TLVOperateFlag);
begin
??aTrunkState.lvFlag?:=?aMsgFlag;
??aTrunkState.TrunkID?:=?IntToStr(channelID);
??aTrunkState.TrunkType?:=?channelType;
??aTrunkState.TrunkTypeStr?:=?ChannelTypeString[channelType];
??aTrunkState.TrunkStep?:=?channelState;
??aTrunkState.TrunkStepStr?:=?TrunkStateString[channelState];
??aTrunkState.TrunkPhone?:=?phoneNumber;
??aTrunkState.TrunkData?:=?dtmfString;
??OnChannelState(aTrunkState);
end;
procedure?TCXXDJChannel160A.ProcessCallInSuccess();
begin
end;
function?TCXXDJChannel160A.SwitchOnCallIn():?boolean;
begin
??OffHook(channelID);
??InitDTMFBuf(channelID);
??StartSigCheck(channelID);
??channelState?:=?atsCallInSuccess;
??Result?:=?true;
end;
procedure?TCXXDJChannel160A.ProcessDialSuccess();
begin
end;
procedure?TCXXDJChannel160A.CreateCommChannel(const?aChennelID:?Word);
begin
??channelID?:=?aChennelID;
??channelType?:=?TChannelType(CheckChType(channelID));
??ClearTrunkStatus();
??InformTrunkStatus(lvofAdd);
end;
function?TCXXDJChannel160A.GetChannelType():?TChannelType;
begin
??Result?:=?channelType;
end;
function?TCXXDJChannel160A.GetDialOut():?boolean;
begin
??Result?:=?isDialOut;
end;
procedure?TCXXDJChannel160A.ProcessCheckDialSend();
begin
??if(CheckSendEnd(channelID)?=?1)?then
??begin
????StartSigCheck(channelID);
????channelState?:=?atsDialing;
??end;
end;
end.
總結(jié)
 
                            
                        - 上一篇: vue 框架的特点
- 下一篇: 微信小程序 超市购物页面
