main.cpp
上传用户:gnaf34
上传日期:2022-04-22
资源大小:1657k
文件大小:102k
- /*
- * main.cxx
- *
- * This is where the action starts!
- *
- * Copyright (c) ITEC-Ohio, 2002.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Open H323 Library available at http://www.openh323.org
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- */
- #include "afx.h"
- #include <iostream.h>
- #include <fstream.h>
- #include <vector>
- #include <ptlib.h>
- #include <string.h>
- #include <io.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <windows.h>
- #include "ximage.h"
- #include "main.h"
- #include "gsmcodec.h"
- #include "lpc10codec.h"
- #include "mscodecs.h"
- #include "h261codec.h"
- #include "videoio.h"
- #include "h323pdu.h"
- #include "g7231codec.h"
- #ifdef HAS_CU30
- #include "cu30codec.h"
- #endif
- #define FICTITOUS_VIDEO "fake"
- //GNUPlot related Information
- extern CString currentTestFolder;
- extern char exeFolderPath[MAX_PATH];
- extern CString consoleStr;
- /* Customize this path if needed */
- //#define PROGNAME "c:\gnuplot\wgnuplot.exe"
- #define PROGNAME "wgnuplot.exe"
- /* CRS: The value given above will work correctly as long as pgnuplot.exe
- * is in the same directory as wgnuplot.exe or the directory containing
- * wgnuplot.exe is included in the path. I would recommend placing the
- * pgnuplot.exe executable in the same directory as wgnuplot.exe and
- * leaving this definition alone.
- */
- #define WINDOWNAME "gnuplot"
- #define PARENTCLASS "wgnuplot_parent"
- #define TEXTCLASS "wgnuplot_text"
- #define GRAPHWINDOW "gnuplot graph"
- #define GRAPHCLASS "wgnuplot_graph"
- #define BUFFER_SIZE 80
- #ifndef _O_BINARY
- # define _O_BINARY O_BINARY
- #endif
- #if (__BORLANDC__ >= 0x450) /* about BCBuilder 1.0 */
- # define _setmode setmode
- #endif
- /* GLOBAL Variables */
- HWND hwndParent = NULL;
- HWND hwndText = NULL;
- char psBuffer[BUFFER_SIZE];
- char psGnuplotCommandLine[MAX_PATH];
- LPTSTR psCmdLine;
- BOOL bSuccess;
- PROCESS_INFORMATION piProcInfo;
- STARTUPINFO siStartInfo;
- //End of GNUPlot related information
- #if defined(P_FREEBSD) || defined(P_OPENBSD)
- #define DEFAULT_VIDEO "/dev/bktr0"
- #endif
- #ifndef DEFAULT_VIDEO
- #define DEFAULT_VIDEO "/dev/video0"
- #endif
- #ifdef HAS_X11
- #include "xlibvid.h"
- #endif
- #ifdef HAS_SDL
- #include "sdlvid.h"
- #endif
- #ifdef HAS_OSS
- #define DEFAULT_MIXER "/dev/mixer"
- #include <linux/soundcard.h>
- #endif
- // uncomment below if to include xJack G729 code
- #ifdef _WIN32
- #define G729
- #endif
- #ifdef HAS_LIDDEVICE
- static const char * AECLevelNames[] = { "Off", "Low", "Medium", "High", "Auto AEC", "Auto AEC/AGC" };
- #endif
- #include "version.h"
- ///////This ifdef _win32 is required to enable sdl on windows to work.
- /*#ifdef _WIN32
- int main(int argc, char ** argv) {
- PProcess::PreInitialise(argc, argv, _environ);
- static BeaconClient instance;
- return instance._main();
- }
- #else
- PCREATE_PROCESS(BeaconClient);
- #endif*/
- #define DEFAULT_TIMEOUT 60000
- #define LAST_CALL_COUNT 16
- #define POTS_LINE 0
- class RingThread : public PThread
- {
- PCLASSINFO(RingThread, PThread);
- public:
- RingThread(MyH323EndPoint & ep)
- : PThread(1000, NoAutoDeleteThread),
- endpoint(ep)
- { Resume(); }
- void Main()
- { endpoint.HandleRinging(); }
- protected:
- MyH323EndPoint & endpoint;
- };
- #define new PNEW
- //variables to pass as call parameters
- CString FastStart;
- CString Tunnel;
- CString SetUp;
- CString TcpBasePort;
- CString TcpMaxPort;
- CString UdpBasePort;
- CString UdpMaxPort;
- CString RtpBasePort;
- CString RtpMaxPort;
- CString SaveResult;
- CString SilenceDetection;
- CString AudioCodec;
- CString JitterBuffer;
- CString VideoDevice;
- CString Format;
- CString temp;
- const char CodecsConfigSection[] = "Codecs";
- const char RecentCallsConfigSection[] = "Recent Calls";
- const char SpeedDialConfigSection[] = "Speed Dial";
- const char MainWindowTopConfigKey[] = "MainWindowTop";
- const char MainWindowLeftConfigKey[] = "MainWindowLeft";
- const char MainWindowWidthConfigKey[] = "MainWindowWidth";
- const char MainWindowHeightConfigKey[] = "MainWindowHeight";
- const char LocalVideoWindowTopConfigKey[] = "LocalVideoWindowTop";
- const char LocalVideoWindowLeftConfigKey[] = "LocalVideoWindowLeft";
- const char RemoteVideoWindowTopConfigKey[] = "RemoteVideoWindowTop";
- const char RemoteVideoWindowLeftConfigKey[] = "RemoteVideoWindowLeft";
- const char AutoAnswerConfigKey[] = "AutoAnswer";
- const char DtmfAsStringConfigKey[] = "DtmfAsString";
- const char UserInputModeConfigKey[] = "UserInputMode";
- const char SilenceDetectConfigKey[] = "SilenceDetect";
- const char SilenceDeadbandConfigKey[] = "SilenceDeadband";
- const char SignalDeadbandConfigKey[] = "SignalDeadband";
- const char NoFastStartConfigKey[] = "NoFastStart";
- const char NoTunnelingConfigKey[] = "NoTunneling";
- const char NoH245inSetupConfigKey[] = "NoH245inSetup";
- const char MaxRecentCallsConfigKey[] = "MaxRecentCalls";
- const char TCPPortBaseConfigKey[] = "TCPPortBase";
- const char TCPPortMaxConfigKey[] = "TCPPortMax";
- const char UDPPortBaseConfigKey[] = "UDPPortBase";
- const char UDPPortMaxConfigKey[] = "UDPPortMax";
- const char RTPPortBaseConfigKey[] = "RTPPortBase";
- const char RTPPortMaxConfigKey[] = "RTPPortMax";
- const char IpTosConfigKey[] = "IpTOS";
- const char UsernameConfigKey[] = "Username";
- const char AliasConfigKey[] = "Alias %u";
- const char AlwaysForwardPartyConfigKey[] = "AlwaysForwardParty";
- const char BusyForwardPartyConfigKey[] = "BusyForwardParty";
- const char NoAnswerForwardPartyConfigKey[] = "NoAnswerForwardParty";
- const char CallIntrusionTypeKey[] = "CallIntrusionTypeKey";
- const char CallIntrusionProtectionLevelKey[] = "CallIntrusionProtectionLevel";
- const char CallIntrusionCapabilityLevelKey[] = "CallIntrusionCapabilityLevel";
- const char TransferProtocolConfigKey[] = "TransferProtocol";
- const char NoAnswerTimeConfigKey[] = "NoAnswerTime";
- const char RingSoundFileConfigKey[] = "RingSoundFile";
- const char SoundBuffersConfigKey[] = "SoundBuffers";
- const char AECConfigKey[] = "AEC";
- const char CountryConfigKey[] = "Country";
- const char JitterConfigKey[] = "Jitter";
- const char BandwidthTypeConfigKey[] = "BandwidthType";
- const char BandwidthConfigKey[] = "Bandwidth";
- const char UseGatekeeperConfigKey[] = "UseGatekeeper";
- const char RequireGatekeeperConfigKey[] = "RequireGatekeeper";
- const char TimeToLiveConfigKey[] = "TimeToLive";
- const char AccessTokenOIDConfigKey[] = "AccessTokenOID";
- const char GatekeeperHostConfigKey[] = "GatekeeperHost";
- const char GatekeeperIdConfigKey[] = "GatekeeperId";
- const char GatekeeperPasswordConfigKey[] = "GatekeeperPassword";
- const char SoundPlayConfigKey[] = "SoundPlayDevice";
- const char SoundRecordConfigKey[] = "SoundRecordDevice";
- const char SpeakerVolumeConfigKey[] = "SpeakerVolume";
- const char MicrophoneVolumeConfigKey[] = "MicrophoneVolume";
- const char UseQuicknetConfigKey[] = "UseQuicknet";
- const char QuicknetDeviceConfigKey[] = "QuicknetDevice";
- const char DeviceTypeConfigKey[] = "LineInterfaceDeviceType";
- const char DeviceNameConfigKey[] = "LineInterfaceDeviceName";
- const char H261QCIFConfigKey[] = "H261_QCIF";
- const char H261CIFConfigKey[] = "H261_CIF";
- const char AutoReceiveVideoConfigKey[] = "AutoReceiveVideo";
- const char VideoDeviceConfigKey[] = "VideoDevice";
- const char VideoSizeConfigKey[] = "VideoSize";
- const char VideoSourceConfigKey[] = "VideoSource";
- const char VideoFormatConfigKey[] = "VideoFormat";
- const char VideoQualityConfigKey[] = "VideoQuality";
- const char VideoLocalConfigKey[] = "VideoLocal";
- const char VideoFlipLocalConfigKey[] = "VideoFlipLocal";
- const char VideoFlipRemoteConfigKey[] = "VideoFlipRemote";
- ///////////////////////////////////////////////////////////////
- BeaconClient::BeaconClient()
- : PProcess("ITEC-Ohio", "H.323 Beacon Client",
- MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
- {
- endpoint = NULL;
- }
- BeaconClient::~BeaconClient()
- {
- }
- const char* globalEndReason = "";
- extern BeaconClient* globalInstance;
- //For Statistics Part
- PTime now;
- PTime StartTimeGlobal;
- int StartTimeGlobalYear;
- int StartTimeGlobalMonth;
- int StartTimeGlobalDay;
- int StartTimeGlobalHour;
- int StartTimeGlobalMinute;
- int StartTimeGlobalSecond;
- extern CString sessionStartTime;
- extern CString sessionEndTime;
- extern CString localmachine;
- extern CString ipglobal;
- extern CString sessionDate;
- DWORD RoundTripTimeDelayGlobal;
- PStringStream DurationTimeGlobal;
- DWORD AudioFrameRateGlobal;
- DWORD PacketSentGlobal;
- DWORD OctetSendGlobal;
- DWORD MaximumSendTimeGlobal;
- DWORD AverageSendTimeGlobal;
- DWORD MinimumSendTimeGlobal;
- DWORD PacketsReceivedGlobal;
- DWORD OctetsReceivedGlobal;
- DWORD MaximumReceiveTimeGlobal;
- DWORD AverageReceiveTimeGlobal;
- DWORD MinimumReceiveTimeGlobal;
- DWORD PacketsLostGlobal;
- DWORD PacketsOutOfOrderGlobal;
- DWORD PacketsOutTooLateGlobal;
- DWORD JitterTimeGlobal;
- PString PayloadTypeGlobal;
- PString TokenCurrentCall;
- PString ReceivedDTMFMessages;
- char *ReceivedDTMF;
- // This variable being used for the need of generating statistic
- BOOLEAN GenerateStatistic;
- //FlagEndPoint to check if EndPoint is already deleted
- int FlagEndPoint = 1;
- //IndexBandwidth added to make a call with particular bandwidth
- int indexbandwidth;
- unsigned int call_bandwidth;
- unsigned bandwidthAvailable;
- H323VideoCodec * videoCodecDlgAudioVideo;
-
- void BeaconClient::Main()
- {
- globalEndReason = "";
- int verbose = 255;
- bool hasMenu = 1;
-
- endpoint = new MyH323EndPoint;
- switch(indexbandwidth){
- case 0:
- {
- call_bandwidth = 56000;
- }
- break;
- case 1:
- {
- call_bandwidth = 128000;
- }
- break;
- case 2:
- {
- call_bandwidth = 256000;
- }
- break;
- case 3:
- {
- call_bandwidth = 384000;
- }
- break;
- case 4:
- {
- call_bandwidth = 512000;
- }
- break;
- case 5:
- {
- call_bandwidth = 768000;
- }
- break;
- default:
- {
- call_bandwidth = 56000;
- }
- break;
- } // End of switch statement;
- //Read stuff from settings file 'S.conf' and put in variables.
- char file[MAX_PATH];
- char exeFilePath[MAX_PATH]; //a string for GetModuleFileName() to store exe Path
- GetModuleFileName( NULL,&exeFilePath[0],sizeof (exeFilePath));
- //Extract path by copying without exe string..
- for(int i=0; i < abs(strlen(exeFilePath)-16); i++){
- file[i] = exeFilePath[i];
- }
- file[i] = ' ';
-
- //strcpy(file,exeFolderPath);
- strcat(file,"S.conf");
- FILE *fp;
- int t=10;
-
- fp = fopen(file,"r");
- //consoleStr+=file;
- //mp= CString("");
- //Call Options
- fscanf(fp,"%s",temp); //for CCall_Options
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp); //
- FastStart = CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- Tunnel = CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- SetUp = CString(temp);
- //consoleStr+="rn";
- //consoleStr+;
- //Output File Path
- fscanf(fp,"%s",temp);//for Output_File_Path
- fscanf(fp,"%s",temp);
- fseek(fp,sizeof(char),SEEK_CUR);
- //fscanf(fp,"%s ",temp);
- char filepath[MAX_PATH];
- fgets(filepath,MAX_PATH,fp);
-
- //Port Options
- fscanf(fp,"%s",temp); //for Ports_Options
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- TcpBasePort= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- TcpMaxPort= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- UdpBasePort= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- UdpMaxPort= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- RtpBasePort= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- RtpMaxPort= CString(temp);
-
- //Test Save Results
- fscanf(fp,"%s",temp); //for Test_Save_Results
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- SaveResult = CString(temp);
- //consoleStr+="rnSave Result: ";
- //consoleStr+=SaveResult;
-
- //Audio Options
- fscanf(fp,"%s",temp); //for Audio_options
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- SilenceDetection= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- AudioCodec= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- JitterBuffer= CString(temp);
-
- //Video Options
- fscanf(fp,"%s",temp); //for Video_options
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- VideoDevice= CString(temp);
- fscanf(fp,"%s",temp);
- fscanf(fp,"%s",temp);
- Format= CString(temp);
- //consoleStr+="rn";
- //consoleStr+=Format;
- fclose(fp);
- //reading done, pass as parameter to the call.
- //create a call options object and set the parameters from the above variables.
- CallOptions optionsFromFile;
- if(FastStart=="0") optionsFromFile.noFastStart=true;
- else optionsFromFile.noFastStart=false;
-
- if(Tunnel=="0") optionsFromFile.noH245Tunnelling=true;
- else optionsFromFile.noH245Tunnelling=false;
-
- if(SilenceDetection=="0") optionsFromFile.noSilenceSuppression=true;
- else optionsFromFile.noSilenceSuppression=false;
-
- optionsFromFile.jitter=atoi(JitterBuffer);
- //optionsFromFile.jitter=endpoint->GetMaxAudioDelayJitter();
- optionsFromFile.connectPort=H323ListenerTCP::DefaultSignalPort;
- optionsFromFile.connectRing=0;
-
- /* PArgList strArgs( "f-fast-disable."
- "T-h245tunneldisable."
- "e-silence."
- "j-jitter:"
- "-connectport:"
- "-connectring:"
- );
- */
- // optionsFromFile.Initialise(strArgs);
-
- endpoint->SetInitialBandwidth((unsigned)(call_bandwidth));
- endpoint->SetTCPPorts(atoi(TcpBasePort),atoi(TcpMaxPort));
- endpoint->SetUDPPorts(atoi(UdpBasePort),atoi(UdpMaxPort));
- endpoint->SetRtpIpPorts(atoi(RtpBasePort),atoi(RtpMaxPort));
- //int gsmFrames = 4;
-
- //endpoint->SetCapability(PINDEX descriptorNum, PINDEX simultaneous, H323Capability * cap );
-
-
- if(endpoint->Initialise(PString(AudioCodec))){
- //if(endpoint->Initialise(strArgs, 0, FALSE)){
- //MessageBox("Calling Makecall");
- //consoleStr+="rnCalling Makecall from Main";
- //consoleStr+=ipAddress;
- //endpoint->MakeOutgoingCall(ipAddress, ipAddress);
- endpoint->MakeOutgoingCall(ipAddress, ipAddress,optionsFromFile);
- H323Connection * connection = endpoint->FindConnectionWithLock(endpoint->currentCallToken);
- TokenCurrentCall = endpoint->currentCallToken;
- //connection->SendUserInput(str);
- if (connection == NULL)
- return;
- connection->Unlock();
- }
- }
- // This module will report statistic such as
- // Packet Loss, Round Trip Delay, Packet Out Of Order
- // The strange thing right now, is Statistic seems depend on
- // other peer (either client or server)
- // Before statistic can be collected, Call has to be
- // establish first (FlagEndPoint == 0 means call already establish)
- // globalinstance != NULL and chan != NULL and session != NULL
- // are additional parameter. Reasons we have multiple check is
- // sometimes GetStatistic Thread being call before actual call
- // being establish. We want to prevent that from happening
- int BeaconClient::GetStatistics()
- {
-
- if (FlagEndPoint == 0)
- {
- if (globalInstance != NULL)
- {
- H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(endpoint->currentCallToken);
- //connection->SendUserInput(str);
- if (connection == NULL)
-
- {
- //MessageBox(0,globalEndReason,"Beacon Client",MB_OK);
- //FlagEndPoint = 1;
- //Quit();
- return -1;
- }
-
- H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
- if (chan != NULL)
- {
- H323Codec * rawCodec = chan->GetCodec();
-
- H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
- AudioFrameRateGlobal = codec->GetFrameRate(); //Audio Codec
-
- RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
- if (session != NULL)
- {
-
-
- //FlagEndPoint = 0;
- StartTimeGlobal= connection->GetConnectionStartTime();
- StartTimeGlobalYear = StartTimeGlobal.GetYear();
- StartTimeGlobalMonth = StartTimeGlobal.GetMonth();
- StartTimeGlobalDay = StartTimeGlobal.GetDay();
- StartTimeGlobalHour = StartTimeGlobal.GetHour();
- StartTimeGlobalMinute = StartTimeGlobal.GetMinute();
- StartTimeGlobalSecond = StartTimeGlobal.GetSecond();
- RoundTripTimeDelayGlobal = connection->GetRoundTripDelay().GetMilliSeconds();
- //DurationTimeGlobal = now - StartTimeGlobal;
- PacketSentGlobal = session->GetPacketsSent();
- OctetSendGlobal = session->GetOctetsSent();
- MaximumSendTimeGlobal = session->GetMaximumSendTime();
- AverageSendTimeGlobal = session->GetAverageSendTime();
- MinimumSendTimeGlobal = session->GetMinimumSendTime();
- PacketsReceivedGlobal = session->GetPacketsReceived();
- OctetsReceivedGlobal = session->GetOctetsReceived();
- MaximumReceiveTimeGlobal = session->GetMaximumReceiveTime();
- AverageReceiveTimeGlobal = session->GetAverageReceiveTime();
- MinimumReceiveTimeGlobal = session->GetMinimumReceiveTime();
- PacketsLostGlobal = session->GetPacketsLost();
- PacketsOutOfOrderGlobal = session->GetPacketsOutOfOrder();
- PacketsOutTooLateGlobal = session->GetPacketsTooLate();
- // Please replace with JitterTimeGlobal = session->GetJitterTimeTmp();
- // JitterTimeGlobal = session->GetJitterTime();
- JitterTimeGlobal = session->GetJitterTimeTmp();
-
- PayloadTypeGlobal = session->GetPayLoadTypeFunc();
- GenerateStatistic = TRUE;
- // To Check Bandwidth being usage
- bandwidthAvailable = endpoint->GetInitialBandwidth();
- //return 0;
- } // Session != NULL
- else
- {
- //return -1;
- }
- } // Channel != NULL
-
- connection->Unlock();
-
- } // globalInstance != NULL
- } // FlagEndPoint != NULL
- return 0;
- }
- BOOL CALLBACK cbGetTextWindow(HWND hwnd, LPARAM lParam )
- {
- /* save the value of the parent window */
- hwndParent = hwnd;
- /* check to see if it has a child text window */
- hwndText = FindWindowEx(hwnd, NULL, TEXTCLASS, NULL );
- /* if the text window was found, stop looking */
- return ( hwndText != NULL );
- }
- /* sends a string to the specified window */
- /* CRS: made this into a function call */
- void BeaconClient::PostString(HWND hwnd, CString pc1)
- {
- char *pc;
- pc = pc1.GetBuffer(pc1.GetLength());
- while( *pc ){
- PostMessage( hwnd, WM_CHAR, *pc, 1L );
- /* CRS: should add a check of return code on PostMessage. If 0, the
- message que was full and the message wasn't posted. */
- pc++;
- }
- }
- /* FindUnquotedSpace(): Search a string for the first space not enclosed in quotes.
- * Returns a pointer to the space, or the empty string if no space is found.
- * -CRS 30061999
- */
- char* BeaconClient::FindUnquotedSpace( char *pc )
- {
- while ( (*pc) && (*pc != ' ') && (*pc != 't') ){
- if ( *pc == '"' ){
- do {
- pc++;
- } while ( (pc[1]) && (*pc != '"') );
- }
- pc++;
- }
- return pc;
- }
- int BeaconClient::PrepareGnuPlot()
- {
- strcpy(psGnuplotCommandLine,exeFolderPath);
- strcat(psGnuplotCommandLine,PROGNAME);
-
- /* HBB 19990325, to allow pgnuplot < script > output.gif */
- _setmode(fileno(stdout), _O_BINARY);
- /* CRS: create the new command line, passing all of the command
- * line options to wgnuplot so that it can process them:
- * first, get the command line,
- * then move past the name of the program (e.g., 'pgnuplot'),
- * finally, add what's left of the line onto the gnuplot command line. */
- psCmdLine = GetCommandLine();
- psCmdLine = "C:\gnuplot\wngnuplot.exe";
- #ifdef SHOWCMDLINE
- fprintf(stderr,"CmdLine: %sn", psCmdLine);
- fprintf(stderr,"argv[0]: %sn",argv[0]);
- #endif
- /* CRS 30061999: Search for the first unquoted space. This should
- separate the program name from the arguments. */
- psCmdLine = FindUnquotedSpace( psCmdLine );
- strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine));
-
- #ifdef SHOWCMDLINE
- fprintf(stderr,"Arguments: %sn", psCmdLine);
- fprintf(stderr,"GnuplotCommandLine: %sn",psGnuplotCommandLine);
- #endif
- /* CRS: if stdin isn't redirected then just launch wgnuplot normally
- * and exit. */
- /*
- if ( isatty(fileno(stdin)) ) {
- if ( WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31 ){
- exit(EXIT_SUCCESS);
- }
- fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n",
- GetLastError(), psGnuplotCommandLine);
- exit(EXIT_FAILURE);
- }
- */
- /* CRS: initialize the STARTUPINFO and call CreateProcess(). */
- siStartInfo.cb = sizeof(STARTUPINFO);
- siStartInfo.lpReserved = NULL;
- siStartInfo.lpReserved2 = NULL;
- siStartInfo.cbReserved2 = 0;
- siStartInfo.lpDesktop = NULL;
- siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
- siStartInfo.wShowWindow = SW_HIDE;
- bSuccess = CreateProcess(
- NULL, /* pointer to name of executable module */
- psGnuplotCommandLine, /* pointer to command line string */
- NULL, /* pointer to process security attributes */
- NULL, /* pointer to thread security attributes */
- FALSE, /* handle inheritance flag */
- 0, /* creation flags */
- NULL, /* pointer to new environment block */
- NULL, /* pointer to current directory name */
- &siStartInfo, /* pointer to STARTUPINFO */
- &piProcInfo /* pointer to PROCESS_INFORMATION */
- );
- /* if CreateProcess() failed, print a warning and exit. */
- if ( ! bSuccess ) {
- fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n",
- GetLastError(), psGnuplotCommandLine);
- exit(EXIT_FAILURE);
- }
- /* CRS: give gnuplot enough time to start (1 sec.) */
- if ( WaitForInputIdle(piProcInfo.hProcess, 1000) ) {
- fprintf(stderr, "Timeout: gnuplot is not readyn");
- exit(EXIT_FAILURE);
- }
- /* CRS: get the HWND of the parent window and text windows */
- EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);
- /* CRS: free the process and thread handles */
- CloseHandle(piProcInfo.hProcess);
- CloseHandle(piProcInfo.hThread);
- if ( ! hwndParent || ! hwndText ) {
- /* Still no gnuplot window? Problem! */
- fprintf(stderr, "Can't find the gnuplot window");
- exit(EXIT_FAILURE);
- }
- /* wait for commands on stdin, and pass them on to the wgnuplot text
- * window */
- /*
- while ( fgets(psBuffer, BUFFER_SIZE, stdin) != NULL ) {
- PostString(hwndText, psBuffer);
- }
- */
- /* Example */
- CString CurrentImageFile;
- CString strtmp1;
- CString strtmp2;
- CString strtmp3;
-
- //Packet Loss
- PostString(hwndText,"nresetn");
- PostString(hwndText,"nset title "Packet Loss for H.323 Beacon Test Session"n");
- PostString(hwndText,"nset data style linesn");
- PostString(hwndText,"nset xlabel "Test Session Time"n");
- PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
- PostString(hwndText,"nset yrange [0.0:]n");
- PostString(hwndText,"nset xdata timen");
- PostString(hwndText,"nset xrange [:]n");
- PostString(hwndText,"nset ylabel "Packet Loss %"n");
- PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
- PostString(hwndText,"nset gridn");
- PostString(hwndText,"nset key left n");
- PostString(hwndText,"nset key boxn");
- PostString(hwndText,"nset terminal png smalln");
- strtmp1 = "n set output "";
- strtmp2 = "\PacketLoss.png"n";
- if(atoi(SaveResult)==1){
- CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- }else {
- CurrentImageFile = strtmp1 + strtmp2;
- }
- //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- //PostString(hwndText,"nset output "PacketLoss.png"n");
- PostString(hwndText,CurrentImageFile);
- PostString(hwndText,"nplot 'pktloss_gplot.txt' using 1:2 title "Packet Loss" with linespoints lt 27 lw 3, 'pktloss_gplot.txt' using 1:3 title "Good" with linespoints lt 16 , 'pktloss_gplot.txt' using 1:4 title "Acceptable" with linespoints lt 4, 'pktloss_gplot.txt' using 1:5 title "UnAcceptable" with linespoints lt 1n");
- // Save it in tmp folder
- //PostString(hwndText,"nreplotn");
- // Audio Jitter
- PostString(hwndText,"nresetn");
- PostString(hwndText,"nset title "Audio Jitter for H.323 Beacon Test Session"n");
- PostString(hwndText,"nset data style linesn");
- PostString(hwndText,"nset xlabel "Test Session Time"n");
- PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
- PostString(hwndText,"nset yrange [0.0:]n");
- PostString(hwndText,"nset xdata timen");
- PostString(hwndText,"nset xrange [:]n");
- PostString(hwndText,"nset ylabel "Audio Jitter ms"n");
- PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
- PostString(hwndText,"nset gridn");
- PostString(hwndText,"nset key left n");
- PostString(hwndText,"nset key boxn");
- PostString(hwndText,"nset terminal png smalln");
- strtmp1 = "n set output "";
- strtmp2 = "\AudioJitter.png"n";
-
- if(atoi(SaveResult)==1){
- CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- }else {
- CurrentImageFile = strtmp1 + strtmp2;
- }
-
- //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- PostString(hwndText,CurrentImageFile);
- PostString(hwndText,"nplot 'audjitter_gplot.txt' using 1:2 title "Audio Jitter" with linespoints lt 27 lw 3, 'audjitter_gplot.txt' using 1:3 title "Good" with linespoints lt 16 , 'audjitter_gplot.txt' using 1:4 title "Acceptable" with linespoints lt 4, 'audjitter_gplot.txt' using 1:5 title "UnAcceptable" with linespoints lt 1n");
- // Save it in tmp folder
- //PostString(hwndText,"nreplotn");
- PostString(hwndText,"nexitn");
- return 0;
- }
- int BeaconClient::PrepareGnuPlotLatency()
- {
- /* HBB 19990325, to allow pgnuplot < script > output.gif */
- _setmode(fileno(stdout), _O_BINARY);
- /* CRS: create the new command line, passing all of the command
- * line options to wgnuplot so that it can process them:
- * first, get the command line,
- * then move past the name of the program (e.g., 'pgnuplot'),
- * finally, add what's left of the line onto the gnuplot command line. */
- psCmdLine = GetCommandLine();
- psCmdLine = "C:\gnuplot\wngnuplot.exe";
- #ifdef SHOWCMDLINE
- fprintf(stderr,"CmdLine: %sn", psCmdLine);
- fprintf(stderr,"argv[0]: %sn",argv[0]);
- #endif
- /* CRS 30061999: Search for the first unquoted space. This should
- separate the program name from the arguments. */
- psCmdLine = FindUnquotedSpace( psCmdLine );
- strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine));
-
- #ifdef SHOWCMDLINE
- fprintf(stderr,"Arguments: %sn", psCmdLine);
- fprintf(stderr,"GnuplotCommandLine: %sn",psGnuplotCommandLine);
- #endif
- /* CRS: if stdin isn't redirected then just launch wgnuplot normally
- * and exit. */
- /*
- if ( isatty(fileno(stdin)) ) {
- if ( WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31 ){
- exit(EXIT_SUCCESS);
- }
- fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n",
- GetLastError(), psGnuplotCommandLine);
- exit(EXIT_FAILURE);
- }
- */
- /* CRS: initialize the STARTUPINFO and call CreateProcess(). */
- siStartInfo.cb = sizeof(STARTUPINFO);
- siStartInfo.lpReserved = NULL;
- siStartInfo.lpReserved2 = NULL;
- siStartInfo.cbReserved2 = 0;
- siStartInfo.lpDesktop = NULL;
- siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
- siStartInfo.wShowWindow = SW_SHOWMINIMIZED;
- bSuccess = CreateProcess(
- NULL, /* pointer to name of executable module */
- psGnuplotCommandLine, /* pointer to command line string */
- NULL, /* pointer to process security attributes */
- NULL, /* pointer to thread security attributes */
- FALSE, /* handle inheritance flag */
- 0, /* creation flags */
- NULL, /* pointer to new environment block */
- NULL, /* pointer to current directory name */
- &siStartInfo, /* pointer to STARTUPINFO */
- &piProcInfo /* pointer to PROCESS_INFORMATION */
- );
- /* if CreateProcess() failed, print a warning and exit. */
- if ( ! bSuccess ) {
- fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n",
- GetLastError(), psGnuplotCommandLine);
- exit(EXIT_FAILURE);
- }
- /* CRS: give gnuplot enough time to start (1 sec.) */
- if ( WaitForInputIdle(piProcInfo.hProcess, 1000) ) {
- fprintf(stderr, "Timeout: gnuplot is not readyn");
- exit(EXIT_FAILURE);
- }
- /* CRS: get the HWND of the parent window and text windows */
- EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);
- /* CRS: free the process and thread handles */
- CloseHandle(piProcInfo.hProcess);
- CloseHandle(piProcInfo.hThread);
- if ( ! hwndParent || ! hwndText ) {
- /* Still no gnuplot window? Problem! */
- fprintf(stderr, "Can't find the gnuplot window");
- exit(EXIT_FAILURE);
- }
- /* wait for commands on stdin, and pass them on to the wgnuplot text
- * window */
- /*
- while ( fgets(psBuffer, BUFFER_SIZE, stdin) != NULL ) {
- PostString(hwndText, psBuffer);
- }
- */
- /* Example */
- CString CurrentImageFile;
- CString strtmp1;
- CString strtmp2;
- CString strtmp3;
- // Latency
- PostString(hwndText,"nresetn");
- PostString(hwndText,"nset terminal png smalln");
- PostString(hwndText,"nset title "Latency for H.323 Beacon Test Session"n");
- //PostString(hwndText,"nset output "Latency.png"n");
- PostString(hwndText,"nset data style linesn");
- PostString(hwndText,"nset xlabel "Test Session Time"n");
- PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
- PostString(hwndText,"nset yrange [0.0:]n");
- PostString(hwndText,"nset xdata timen");
- PostString(hwndText,"nset xrange [:]n");
- PostString(hwndText,"nset ylabel "Latency ms"n");
- PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
- PostString(hwndText,"nset gridn");
- PostString(hwndText,"nset key left n");
- PostString(hwndText,"nset key boxn");
- //PostString(hwndText,"nplot 'C:\gnuplot\beacon.dat' using 1:2 title "Packet Loss" with linespoints lt 2 , 'C:\gnuplot\beacon.dat' using 1:3 title "Good" with lines lt 3 , 'C:\gnuplot\beacon.dat' using 1:4 title "Acceptable" with lines lt 4, 'C:\gnuplot\beacon.dat' using 1:5 title "UnAcceptable" with lines lt 5n");
-
-
- strtmp1 = "n set output "";
- strtmp2 = "\Latency.png"n";
-
- if(atoi(SaveResult)==1){
- CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- }else {
- CurrentImageFile = strtmp1 + strtmp2;
- }
- //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
- PostString(hwndText,CurrentImageFile);
- PostString(hwndText,"nplot 'rtd_gplot.txt' using 1:2 title "Latency" with linespoints lt 27 lw 3, 'rtd_gplot.txt' using 1:3 title "Good" with linespoints lt 16 , 'rtd_gplot.txt' using 1:4 title "Acceptable" with linespoints lt 4, 'rtd_gplot.txt' using 1:5 title "UnAcceptable" with linespoints lt 1n");
-
- //PostString(hwndText,"nreplotn");
- PostString(hwndText,"nexitn");
- return 0;
- }
-
- void BeaconClient::ConvertPngToBmp(CString filepath)
- {
- CxImage image;
- char *filename1;
- CString tmpFileName;
- CString tmpFileName1;
-
- if(atoi(SaveResult)==1){
- tmpFileName = filepath + "\PacketLoss.png";
- tmpFileName1 = filepath + "\PacketLoss.bmp";
- }else {
- tmpFileName = "PacketLoss.png";
- tmpFileName1 = "PacketLoss.bmp";
- }
-
- // Convert PacketLoss.png to PacketLoss.bmp
- filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
- image.Load(filename1,CXIMAGE_FORMAT_PNG);
- if (image.IsValid())
- {
- filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
- image.Save(filename1,CXIMAGE_FORMAT_BMP);
- }
- else
- {
- consoleStr+= "rn PacketLoss.png Not Valid!";
- }
- if(atoi(SaveResult)==1){
- tmpFileName = filepath + "\AudioJitter.png";
- tmpFileName1 = filepath + "\AudioJitter.bmp";
- }else {
- tmpFileName = "AudioJitter.png";
- tmpFileName1 = "AudioJitter.bmp";
- }
- //tmpFileName = filepath + "\AudioJitter.png";
- //tmpFileName1 = filepath + "\AudioJitter.bmp";
- // Convert PacketLoss.png to PacketLoss.bmp
- filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
- image.Load(filename1,CXIMAGE_FORMAT_PNG);
- if (image.IsValid())
- {
- filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
- image.Save(filename1,CXIMAGE_FORMAT_BMP);
- }
- else
- {
- consoleStr+="rn AudioJitter.png Not Valid!";
- }
-
- if(atoi(SaveResult)==1){
- tmpFileName = filepath + "\Latency.png";
- tmpFileName1 = filepath + "\Latency.bmp";
- }else {
- tmpFileName = "Latency.png";
- tmpFileName1 = "Latency.bmp";
- }
-
- //tmpFileName = filepath + "\Latency.png";
- //tmpFileName1 = filepath + "\Latency.bmp";
- // Convert PacketLoss.png to PacketLoss.bmp
- filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
- image.Load(filename1,CXIMAGE_FORMAT_PNG);
- if (image.IsValid())
- {
- filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
- image.Save(filename1,CXIMAGE_FORMAT_BMP);
- }
- else
- {
- consoleStr+="rnFile Latency.png Not Valid!";
- }
- }
-
-
- int BeaconClient::CheckConnections()
- {
- if (FlagEndPoint == 0)
- {
- if (globalInstance != NULL)
- {
- H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(endpoint->currentCallToken);
- //connection->SendUserInput(str);
- if (connection != NULL)
- {
-
-
-
-
-
- H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
- if (chan != NULL)
- {
- H323Codec * rawCodec = chan->GetCodec();
- H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
- AudioFrameRateGlobal = codec->GetFrameRate(); //Audio Codec
-
-
-
- RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
-
- if (session != NULL)
- {
- } // Session != NULL
- } // Channel != NULL
- else
- {
- return -1; // If Channel == NULL
- }
-
- connection->Unlock();
- } // connection != NULL
- } // globalInstance != NULL
- } // FlagEndPoint != NULL
- return 0;
-
- }
- void BeaconClient::Quit()
- {
- globalInstance->endpoint->ClearAllCalls();
- delete endpoint;
- //FlagEndPoint == 1, Call has been Cleared
- FlagEndPoint = 1;
- }
- ///////////////////////////////////////////////////////////////
- BOOL MyH323EndPoint::Initialise(PString AudioCodec)
- {
- uiState = uiDialtone;
- localVideoChannel = NULL;
- WORD port = H323ListenerTCP::DefaultSignalPort;
- WORD listenPort = port;
- defaultCallOptions.jitter = GetMaxAudioDelayJitter();
- defaultCallOptions.connectPort = port;
- defaultCallOptions.connectRing = 0;
- currentCallOptions = defaultCallOptions;
- terminateOnHangup = 1;
- autoAnswer = 0;
- videoPIP = FALSE;
- videoSize = 0; //Default is small.
- isXJack = FALSE;
- lidDevice = NULL;
- #ifdef HAS_VBLASTER
- #endif
- #ifdef HAS_IXJ
- #endif
- ringDelay = 5;
- int g711Frames = 30;
- int gsmFrames = 4;
- //originals
- /* H323_GSM0610Capability * gsmCap;
- SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
- gsmCap->SetTxFramesInPacket(gsmFrames);
- MicrosoftGSMAudioCapability * msGsmCap;
- SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
- msGsmCap->SetTxFramesInPacket(gsmFrames);
- H323_G711Capability * g711uCap;
- SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
- g711uCap->SetTxFramesInPacket(g711Frames);
- H323_G711Capability * g711aCap;
- SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
- g711aCap->SetTxFramesInPacket(g711Frames);
-
- //Added by Mukund
-
- //G723
- //H323_G7231Capability * g7231cap;
- //SetCapability(0, 0, g7231cap = new H323_G7231Capability());
-
- //G726
- H323_G726_Capability * g726cap;
- //SetCapability(0, 0, g726cap = new H323_G726_Capability(g726cap));
- SetCapability(0, 0, g726cap = new H323_G726_Capability(*this, H323_G726_Capability::e_24k));
- // SetCapability(0, 0, new H323_G726_Capability(H323_G726_Capability::e_32k));
- // SetCapability(0, 0, new H323_G726_Capability(H323_G726_Capability::e_40k));
- //G728
- // SetCapability(0, 0, new H323_G728ACapability);
- //G729
- H323_G729ACapability * g729aCap;
- SetCapability(0, 0,g729aCap = new H323_G729ACapability);
- //G722
- // SetCapability(0, 0, new H323_G722Capability);
- //MPEG
- // SetCapability(0, 0, new H323_MPEGCapability);
-
- SetCapability(0, 0, new H323_LPC10Capability(*this));
- */
- static const char * const oldArgName[] = {
- "g7231", "g729", "g728", "gsm", "g711-ulaw", "g711-alaw"
- };
-
- // static const char * const capName[] = {
- // "G.723.1", "G.729", "G.728", "GSM", "G.711-uLaw", "G.711-ALaw"
- //};
-
- static const char * const capName[] = {
- "GSM-06.10{sw}", "MS-GSM{sw}","G.711-uLaw-64k", "G.711-ALaw-64k{sw}",
- "G.726-24k{sw}", "G.729A{n/a}", "LPC-10{sw}"
- };
- consoleStr+= "rnSetting preferred codec:: ";
- consoleStr+=AudioCodec;
- //PStringArray toReorder(7,capName);
- //PString temp;
- fstream fs("Cap.dat",ios::out,filebuf::sh_none);
- if(AudioCodec=="GSM-06.10{sw}"){
- fs<<"Codec Option: 1 n";
- H323_GSM0610Capability * gsmCap;
- SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
- gsmCap->SetTxFramesInPacket(gsmFrames);
- }else if(AudioCodec=="MS-GSM{sw}"){
- fs<<"Codec Option: 2 n";
- MicrosoftGSMAudioCapability * msGsmCap;
- SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
- msGsmCap->SetTxFramesInPacket(gsmFrames);
- }else if(AudioCodec=="G.711-uLaw-64k{sw}"){
- fs<<"Codec Option: 3 n";;
- H323_G711Capability * g711uCap;
- SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
- g711uCap->SetTxFramesInPacket(g711Frames);
-
- // temp = toReorder[1];
- // toReorder[1] = toReorder[3];
- // toReorder[3] = toReorder[1];
- }else if(AudioCodec=="G.711-ALaw-64k{sw}"){
- fs<<"Codec Option: 4 n";
- H323_G711Capability * g711aCap;
- SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
- g711aCap->SetTxFramesInPacket(g711Frames);
- // temp = toReorder[1];
- // toReorder[1] = toReorder[4];
- // toReorder[4] = toReorder[1];
- }else if(AudioCodec=="G.726-24k{sw}"){
- fs<<"Codec Option: 5 n";
- H323_G726_Capability * g726cap;
- //SetCapability(0, 0, g726cap = new H323_G726_Capability(g726cap));
- SetCapability(0, 0, g726cap = new H323_G726_Capability(*this, H323_G726_Capability::e_24k));
- // temp = toReorder[1];
- // toReorder[1] = toReorder[5];
- // toReorder[5] = toReorder[1];
- }else if(AudioCodec=="G.729A{n/a}"){
- fs<<"Codec Option: 6 n";
- H323_G729ACapability * g729aCap;
- SetCapability(0, 0,g729aCap = new H323_G729ACapability);
-
- // temp = toReorder[1];
- // toReorder[1] = toReorder[6];
- // toReorder[6] = toReorder[1];
- }else if(AudioCodec=="LPC-10{sw}"){
- fs<<"Codec Option: 7 n";
-
- SetCapability(0, 0, new H323_LPC10Capability(*this));// temp = toReorder[1];
- // toReorder[1] = toReorder[7];
- // toReorder[7] = toReorder[1];
- }
- //toReorder[toReorder.GetSize()] = AudioCodec;
- //FILE * fp ;
- //fp = fopen("Cap.dat","w");
- //fstream fs("Cap.dat",ios::out,filebuf::sh_none);
- capabilities.PrintOn(fs);
- // capabilities.Reorder(toReorder);
- fs<<"Adding cap to tablen";
-
- //close(fs);
- H323_UserInputCapability::AddAllCapabilities(capabilities, 0, P_MAX_INDEX);
- //SetCapability(0, P_MAX_INDEX, new H323_T120Capability);
- capabilities.PrintOn(fs);
-
- PStringArray interfaceList;
- PString interfacePrintable;
- PIPSocket::Address interfaceAddress(INADDR_ANY);
- interfacePrintable = psprintf("ALL:%i", listenPort);
- ringThread = NULL;
- autoDisconnect = 0;
- return TRUE;
- }
- BOOL MyH323EndPoint::Initialise(PConfigArgs & args, int _verbose, BOOL _hasMenu)
- {
- PINDEX i;
- verbose = _verbose;
- hasMenu = _hasMenu;
- uiState = uiDialtone;
- localVideoChannel = NULL;
- // get ports
- WORD port = H323ListenerTCP::DefaultSignalPort;
- WORD listenPort = port;
- defaultCallOptions.jitter = GetMaxAudioDelayJitter();
- defaultCallOptions.connectPort = port;
- defaultCallOptions.connectRing = 0;
- currentCallOptions = defaultCallOptions;
- //////////
- terminateOnHangup = 1;
- autoAnswer = 0;
-
- alwaysForwardParty = args.GetOptionString('F');
- busyForwardParty = args.GetOptionString('B');
- noAnswerForwardParty = args.GetOptionString('N');
- noAnswerTime = args.GetOptionString("answer-timeout", "30").AsUnsigned();
- dialAfterHangup = args.HasOption("dial-after-hangup");
- setupParameter = args.GetOptionString("setup-param");
-
- if (verbose >= 3) {
- cout << "Local username: " << GetLocalUserName() << "n"
- << "TerminateOnHangup is " << terminateOnHangup << "n"
- << "Auto answer is " << autoAnswer << "n"
- << "DialAfterHangup is " << dialAfterHangup << "n"
- << defaultCallOptions
- << endl;
- }
- videoPIP = FALSE;
- videoSize = 0; //Default is small.
- if (verbose >= 3) {
- if (videoReceiveDevice.IsEmpty())
- cout << "Video receive disabled" << endl << endl;
- else {
- cout << "Video receive using device : " << videoReceiveDevice << endl;
- cout << "Video receive quality hint : " << videoQuality << endl << endl;
- }
- if (!autoStartTransmitVideo)
- cout << "Video transmit disabled" << endl << endl;
-
- }
- isXJack = FALSE;
- lidDevice = NULL;
- #ifdef HAS_VBLASTER
- #endif
- #ifdef HAS_IXJ
- #endif
- ringDelay = 5;
- #if defined(HAS_LIDDEVICE)
- if ((lidDevice == NULL) || !lidDevice->IsOpen() ) {
- #endif
-
- if (verbose >= 3)
- cout << "Sound output device: "" << GetSoundChannelPlayDevice() << ""n"
- "Sound input device: "" << GetSoundChannelRecordDevice() << ""n";
- #if defined(HAS_LIDDEVICE)
- } // endif
- #endif
-
- #if defined(HAS_LIDDEVICE)
-
- #endif
- int g711Frames = 30;
-
- int gsmFrames = 4;
-
- if (verbose >= 3) {
- cout <<"G.711 frame size: " << g711Frames << endl;
- cout <<"GSM frame size: " << gsmFrames << endl;
- }
- //originals
- H323_GSM0610Capability * gsmCap;
- SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
- gsmCap->SetTxFramesInPacket(gsmFrames);
- MicrosoftGSMAudioCapability * msGsmCap;
- SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
- msGsmCap->SetTxFramesInPacket(gsmFrames);
- H323_G711Capability * g711uCap;
- SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
- g711uCap->SetTxFramesInPacket(g711Frames);
- H323_G711Capability * g711aCap;
- SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
- g711aCap->SetTxFramesInPacket(g711Frames);
-
- SetCapability(0, 0, new H323_LPC10Capability(*this));
- PStringArray toRemove = args.GetOptionString('D').Lines();
- PStringArray toReorder = args.GetOptionString('P').Lines();
- static const char * const oldArgName[] = {
- "g7231", "g729", "g728", "gsm", "g711-ulaw", "g711-alaw"
- };
- static const char * const capName[] = {
- "G.723.1", "G.729", "G.728", "GSM", "G.711-uLaw", "G.711-ALaw"
- };
-
- for (i = 0; i < PARRAYSIZE(oldArgName); i++) {
- if (args.HasOption(PString("no-")+oldArgName[i]))
- toRemove[toRemove.GetSize()] = capName[i];
- if (args.HasOption(oldArgName[i]))
- toReorder[toReorder.GetSize()] = capName[i];
- }
- capabilities.Remove(toRemove);
- capabilities.Reorder(toReorder);
-
- //AddCapability puts the codec into the list of codecs we can send
- //SetCapability puts the codec into the list of codecs we can send and receive
- H323_UserInputCapability::AddAllCapabilities(capabilities, 0, P_MAX_INDEX);
- //SetCapability(0, P_MAX_INDEX, new H323_T120Capability);
- if (verbose >= 4)
- cout << "Codecs (in preference order):n" << setprecision(2) << capabilities << endl << endl;
- PStringArray interfaceList;
- PString interfacePrintable;
- PIPSocket::Address interfaceAddress(INADDR_ANY);
- interfacePrintable = psprintf("ALL:%i", listenPort);
- if (verbose >= 3)
- cout << "Listening interfaces : " << interfacePrintable << endl;
- ringThread = NULL;
- autoDisconnect = 0;
- return TRUE;
- }
- /* New One */
- H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
- {
-
- unsigned options = 0;
- if (currentCallOptions.noFastStart)
- options |= H323Connection::FastStartOptionDisable;
- if (currentCallOptions.noH245Tunnelling)
- options |= H323Connection::H245TunnelingOptionDisable;
- /*
- if (currentCallOptions.noH245InSetup)
- options |= H323Connection::H245inSetupOptionDisable;
- */
- return new MyH323Connection(*this, callReference,
- options,
- (WORD)currentCallOptions.jitter,
- verbose);
- }
- /* Old */
- /*
- H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
- {
- return new MyH323Connection(*this, callReference,
- currentCallOptions.noFastStart,
- currentCallOptions.noH245Tunnelling,
- (WORD)currentCallOptions.jitter,
- verbose);
- }
- */
- void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection,
- const PString & /*token*/)
- {
- cout << "Call with "" << connection.GetRemotePartyName() << "" established." << endl;
- uiState = uiCallInProgress;
- }
- void MyH323EndPoint::OnAutoDisconnect(PTimer &, INT)
- {
- if (currentCallToken.IsEmpty())
- cout << "Autodisconnect occurred without current call token" << endl;
- else {
- ClearCall(currentCallToken);
- cout << "Autodisconnect triggered" << endl;
- }
- }
- void MyH323EndPoint::TriggerDisconnect()
- {
- // we have an autodisconnect timer specified, start the timer
- if (autoDisconnect <= 0)
- PTRACE(2, "MaintAuto disconnect not triggered");
- else {
- PTRACE(2, "MaintAuto disconnect triggered");
- autoDisconnectTimer.SetNotifier(PCREATE_NOTIFIER(OnAutoDisconnect));
- autoDisconnectTimer = PTimeInterval(autoDisconnect * 100);
- }
- }
- void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
- {
- // stop any ringing that is occurring
- StopRinging();
- // ignore connections that are not the current connection
- if (clearedCallToken != currentCallToken)
- return;
- // update values for current call token and call forward call token:
- if (!callTransferCallToken) {
- // after clearing the first call during a call proceeding,
- // the call transfer call token becomes the new call token
- currentCallToken = callTransferCallToken;
- callTransferCallToken = PString();
- }
- else
- currentCallToken = PString(); // indicate that our connection is now cleared
- // indicate call has hungup
- uiState = uiCallHungup;
- if (verbose != 0) {
- BOOL printDuration = TRUE;
- PString remoteName = '"' + connection.GetRemotePartyName() + '"';
- switch (connection.GetCallEndReason()) {
- case H323Connection::EndedByCallForwarded :
- printDuration = FALSE; // Don't print message here, was printed when forwarded
- break;
- case H323Connection::EndedByRemoteUser :
- globalEndReason = "Remote User has cleared call";
- cout << remoteName << " has cleared the call";
- break;
- case H323Connection::EndedByCallerAbort :
- globalEndReason = "Has stopped calling";
- cout << remoteName << " has stopped calling";
- break;
- case H323Connection::EndedByRefusal :
- globalEndReason = "Remote H.323 Beacon Server did not accept your test session!";
- cout << remoteName << " did not accept your call";
- break;
- case H323Connection::EndedByRemoteBusy :
- globalEndReason = "Remote H.323 Beacon Server was busy!";
- cout << remoteName << " was busy";
- break;
- case H323Connection::EndedByRemoteCongestion :
- globalEndReason = "congested link to remote H.323 Beacon Server!";
- cout << "Congested link to " << remoteName;
- break;
- case H323Connection::EndedByNoAnswer :
- globalEndReason = "No H.323 peer is running at remote site!";
- cout << remoteName << " did not answer your call";
- break;
- case H323Connection::EndedByTransportFail :
- globalEndReason = "Remote H.323 Beacon Server has ended the Test Session!";
- cout << "Call with " << remoteName << " ended abnormally";
- break;
- case H323Connection::EndedByCapabilityExchange :
- globalEndReason = "Could not find common codec with remote H.323 Beacon Server!";
- cout << "Could not find common codec with " << remoteName;
- break;
- case H323Connection::EndedByNoAccept :
- globalEndReason = "Did not accept incoming call from remote H.323 Beacon Server!";
- cout << "Did not accept incoming call from " << remoteName;
- break;
- case H323Connection::EndedByAnswerDenied :
- globalEndReason = "Refused incoming call from remote H.323 Beacon Server!";
- cout << "Refused incoming call from " << remoteName;
- break;
- case H323Connection::EndedByNoUser :
- globalEndReason = "Gatekeeper could not find user with remoteName";
- cout << "Gatekeeper could find user " << remoteName;
- break;
- case H323Connection::EndedByNoBandwidth :
- globalEndReason = "aborted, insufficient bandwidth";
- cout << "Call to " << remoteName << " aborted, insufficient bandwidth.";
- break;
- case H323Connection::EndedByUnreachable :
- globalEndReason = "Remote H.323 Beacon Server Could not be reached!";
- cout << remoteName << " could not be reached.";
- break;
- case H323Connection::EndedByHostOffline :
- globalEndReason = " Failed to initiate a call... Possible causes are:n 1. There is no Internet Connectivity on the H.323 Beacon Client PC n 2. Remote H.323 Beacon Server is not Online...either the IP Address for the n H.323 Beacon Server is invalid or the H.323 Beacon Server program is n not running on the remote server... n 3. A Firewall in the Network is blocking the necessary ports";
- cout << remoteName << " is not online.";
- break;
- case H323Connection::EndedByNoEndPoint :
- globalEndReason = "The Remote H.323 Beacon Server is not Online!";
- cout << "No phone running for " << remoteName;
- break;
- case H323Connection::EndedByConnectFail :
- globalEndReason = "Please enter a valid IP Address!";
- cout << "Transport error calling (Possible Cause: No IP Address Entered)" << remoteName;
- break;
- default :
- globalEndReason = "Call with remote H.323 Beacon Server completed!";
- globalEndReason = "";
- cout << "Call with " << remoteName << " completed";
- }
- PTime connectTime = connection.GetConnectionStartTime();
- if (printDuration && connectTime.GetTimeInSeconds() != 0)
- cout << ", duration "
- << setprecision(0) << setw(5)
- << (PTime() - connectTime)
- << endl;
- }
- if (!hasMenu && terminateOnHangup) {
- exitFlag.Signal();
- }
- }
- BOOL MyH323EndPoint::OpenAudioChannel(H323Connection & connection,
- BOOL isEncoding,
- unsigned bufferSize,
- H323AudioCodec & codec)
- {
- #if defined(HAS_LIDDEVICE)
- if ((lidDevice != NULL) && lidDevice->IsOpen()) {
- PTRACE(2, "xJacktAttaching channel to codec");
- if (!codec.AttachChannel(new OpalLineChannel(*lidDevice, POTS_LINE, codec)))
- return FALSE;
- }
- else
- #endif
- if (!H323EndPoint::OpenAudioChannel(connection, isEncoding, bufferSize, codec)) {
- cerr << "Could not open sound device ";
- if (isEncoding)
- cerr << GetSoundChannelRecordDevice();
- else
- cerr << GetSoundChannelPlayDevice();
- cerr << " - Check permissions or full duplex capability." << endl;
- return FALSE;
- }
- codec.SetSilenceDetectionMode(currentCallOptions.noSilenceSuppression ?
- H323AudioCodec::NoSilenceDetection :
- H323AudioCodec::AdaptiveSilenceDetection);
- return TRUE;
- }
- BOOL MyH323EndPoint::OpenVideoChannel(H323Connection & connection,
- BOOL isEncoding,
- H323VideoCodec & codec)
- {
-
- PVideoChannel * channel = new PVideoChannel;
- PVideoOutputDevice * device = NULL;
- PVideoInputDevice * grabber = NULL;
-
- PString nameStr = isEncoding ? PString("Local") :
- connection.GetRemotePartyName();
- if (isEncoding) {
- PAssert(autoStartTransmitVideo, "video encoder created without enable");
- codec.SetTxQualityLevel(videoTxQuality);
- codec.SetBackgroundFill(videoFill);
- codec.SetAverageBitRate(videoBitRate);
- unsigned newFrameWidth,newFrameHeight;
- newFrameWidth = 352>>(1-videoSize);
- newFrameHeight = 288>>(1-videoSize);
- if (videoFake)
- grabber = new PFakeVideoInputDevice();
- else
- grabber = new PVideoInputDevice();
-
- PTRACE(3,"Attempt to open videoDevice "<<videoDevice<<" for reading.");
- if ( !grabber->Open(videoDevice, FALSE)) {
- PTRACE(3,"Failed to open the camera device");
- goto errVideo;
- }
- if ( !grabber->SetVideoFormat(
- videoIsPal ? PVideoDevice::PAL : PVideoDevice::NTSC)) {
- PTRACE(3,"Failed to set format to " << (videoIsPal ? "PAL" : "NTSC"));
- goto errVideo;
- }
- if ( !grabber->SetChannel(videoInput) ) {
- PTRACE(3,"Failed to set channel to "<<videoInput);
- goto errVideo;
- }
- if (!(pfdColourFormat.IsEmpty()))
- grabber->SetPreferredColourFormat(pfdColourFormat);
- if ( !grabber->SetColourFormatConverter("YUV420P") ) {
- PTRACE(3,"Failed to set format to yuv420p");
- goto errVideo;
- }
- if ( !grabber->SetFrameRate(videoFramesPS)) {
- PTRACE(3,"Failed to set framerate to " << videoFramesPS );
- goto errVideo;
- }
- if ( !grabber->SetFrameSizeConverter(newFrameWidth,newFrameHeight,FALSE) ) {
- PTRACE(3, "Failed to set framesize to "<<newFrameWidth<<"x"<<newFrameHeight);
- goto errVideo;
- }
- PTRACE(3,"OpenVideoChannelt done. Successfully opened a video camera");
- goto exitVideo;
-
- errVideo:
- delete grabber;
- grabber = (PVideoInputDevice *) new PFakeVideoInputDevice(); //This one never fails.
- grabber->SetColourFormat("YUV420P");
- grabber->SetVideoFormat(PVideoDevice::PAL); // not actually used for fake video.
- grabber->SetChannel(100); //NTSC test image.
- grabber->SetFrameRate(0); //Select default frame rate.
- grabber->SetFrameSize(newFrameWidth,newFrameHeight);
- PTRACE(3,"Made a fictitious video camera showing NTSC test frame");
-
- exitVideo:
- grabber->Start();
- channel->AttachVideoReader(grabber);
- }
- if ((!isEncoding) || videoLocal) {
- PAssert(!videoReceiveDevice.IsEmpty(), "video display created without device type");
- #ifdef HAS_SDL
- // Dump received video to SDL
- if (videoReceiveDevice *= "sdl")
- device = new SDLVideoDevice(nameStr,isEncoding,videoPIP);
- #endif
- #ifdef HAS_X11
- // Dump received video to X11 window
- if (videoReceiveDevice.Left(3) *= "x11") {
- PString str = videoReceiveDevice;
- BOOL shared = str.Right(1) *= "s";
- str = str.Mid(3);
- if (!shared)
- device = new XlibVideoDevice(nameStr,isEncoding,videoPIP);
- else {
- str = str.Left(str.GetLength()-1);
- device = new ShmXlibVideoDevice(nameStr,isEncoding,videoPIP);
- }
- int depth = str.AsInteger();
- if (depth > 0)
- ((GenericXlibVideoDevice *)device)->ForceDepth(depth);
- }
- #endif
- #ifdef WIN32
- // code to specify windows 32 display device,
- // which uses MS windows conversion routines.
- #endif
- // Dump video to PPM files
- //can have two ppm video devices. 99==local 00==received.
- if (videoReceiveDevice *= "ppm")
- device = new PPMVideoOutputDevice(isEncoding? 99:0);
- }
- #ifdef HAS_VGALIB //vgalib can only do receive video device.
- if (!isEncoding) {
- // Dump received video to VGA
- if (videoReceiveDevice *= "svga")
- device = new LinuxSVGAFullOutputDevice();
- else if (videoReceiveDevice *= "svga256")
- device = new LinuxSVGA256OutputDevice();
- }
- #endif
- // Dump video to nowhere
- if ((videoReceiveDevice *= "null") || (isEncoding&&(!videoLocal)))
- device = new NullVideoOutputDevice();
- if (device == NULL)
- PError << "unknown video output device "" << videoReceiveDevice << """ << endl;
- PAssert(device != NULL, "NULL video device");
-
- PTRACE(3,"device->SetFrameSize("
- << codec.GetWidth() << "," << codec.GetHeight() << ") from codec");
- //NB cannot resize receive video window if the following line is used
- //device->SetFrameSize(352>>(1-videoSize), 288>>(1-videoSize));
- device->SetFrameSize(codec.GetWidth(), codec.GetHeight()); // needed to enable resize
- channel->AttachVideoPlayer(device);
-
- //Select true, delete video chanel on closing codec.
-
- return codec.AttachChannel(channel,TRUE);
-
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /*
- BOOL MyH323EndPoint::OpenVideoChannel(H323Connection & connection,
- BOOL isEncoding,
- H323VideoCodec & codec)
- {
- PVideoChannel * channel = new PVideoChannel;
- // a H323VideoDevice * displayDevice;
- if (isEncoding)
- {
- PConfig config;
-
-
- //codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,1));
- codec.SetTxQualityLevel(1); /**Quality of the transmitted video. 1 is good, 31 is poor.
- codec.SetBackgroundFill(2);
- //Create grabber.
- PVideoInputDevice * grabber = new PVideoInputDevice();
- PStringList devices = grabber->GetDeviceNames();
- PString deviceName;
- // Modified, so it just use whatever the "FIRST" available video hardware
- if (devices.IsEmpty())
- deviceName = "Frame test N.0 - Moving line";
- else
- deviceName = grabber->GetDeviceNames()[0];
- //deviceName = config.GetString(VideoDeviceConfigKey, deviceName);
-
-
- // Modified, so it does not use any config files
- //if (!grabber->Open(deviceName, FALSE) ||
- // !grabber->SetVideoFormat((PVideoDevice::VideoFormat)config.GetInteger(VideoFormatConfigKey, PVideoDevice::Auto)) ||
- // !grabber->SetChannel(config.GetInteger(VideoSourceConfigKey,1)) ||
- // !grabber->SetColourFormatConverter("YUV420P") ||
- // !grabber->SetFrameSize(videoWidth, videoHeight) ||
- // !grabber->SetVFlipState(localFlip))
- if (!grabber->Open(deviceName, FALSE) ||
- !grabber->SetVideoFormat(PVideoDevice::Auto) || // Set Video Format to be Auto
- !grabber->SetChannel(1) || // Set Channel to be 1
- !grabber->SetColourFormatConverter("YUV420P") ||
- !grabber->SetFrameSize(180, 180) || // videoWidth = 180, videoHeight = 180 // To be fit in Dialog Audio Video
- !grabber->SetVFlipState(TRUE))
- {
- PTRACE(1, "Failed to open or configure the video device "" << deviceName << '"');
- delete grabber;
- grabber = new PFakeVideoInputDevice();
- grabber->SetColourFormat("YUV420P");
- grabber->SetVideoFormat(PVideoDevice::PAL);
- grabber->SetFrameSize(180, 180);
- grabber->SetVFlipState(FALSE);
- grabber->SetChannel(atoi(&deviceName[13]));
- }
- grabber->Start();
- channel->AttachVideoReader(grabber);
- // Always play it in Dialog Audio Video Window
- //a if (localVideo)
- //a {
- // Replace this, so it can play on Beacon Client Video
- //adisplayDevice = new VideoDevice(mainWindow, TRUE, connection.GetLocalPartyName(), FALSE);
- //a }
- //a else
- //a {
- //a displayDevice = new NullVideoOutputDevice;
- //a }
- }
- else
- // Replace this, so it can play on Beacon Client Video
- //displayDevice = new VideoDevice(mainWindow, FALSE, connection.GetRemotePartyName(), remoteFlip);
- // a displayDevice->SetFrameSize(180, 180); // videowidth = 180, videoheight = 180
-
- //Give the video window (which plays video) to the channel.
- // a channel->AttachVideoPlayer(displayDevice);
- //return codec.AttachChannel(channel,TRUE);
- return TRUE;
- }
- */
- //
- // if gateway is empty, then dest is assumed to be a IP address and optional port
- // if gateway is non-empty, then gateway is assumed to be an IP address and optional port, and
- // dest is passed to the gateway as the e164 address
- //
- void MyH323EndPoint::MakeOutgoingCall(const PString & dest,
- const PString & gateway)
- {
- // consoleStr+="rnInside Makeoutgoing call with default parameters";
- MakeOutgoingCall(dest, gateway, defaultCallOptions);
- }
- void MyH323EndPoint::MakeOutgoingCall(const PString & dest,
- const PString & gateway,
- CallOptions callOptions)
- {
- // consoleStr+="rn Inside Makeoutgoingcall with call options";
- //consoleStr+=
- currentCallOptions = callOptions;
- PString fullAddress;
- if (!gateway)
- fullAddress = gateway;
- else
- fullAddress = dest;
- if ((fullAddress.Find(':') == P_MAX_INDEX) && (callOptions.connectPort != H323ListenerTCP::DefaultSignalPort))
- fullAddress += psprintf(":%i", currentCallOptions.connectPort);
- if (!gateway)
- fullAddress = dest.Trim() + '@' + fullAddress;
- if (!MakeCall(fullAddress, currentCallToken)) {
- cout << "Error making call to "" << fullAddress << '"' << endl;
- return;
- }
- PConfig config("Calls");
- int index = config.GetInteger("index");
- PString lastCalledParty = config.GetString(PString(PString::Unsigned, index));
- index = (index + 1) % LAST_CALL_COUNT;
- PTime now;
- PString indexStr = PString(PString::Unsigned, index);
- config.SetString(indexStr, fullAddress);
- config.SetString(indexStr + "_Time", now.AsString());
- config.SetString("index", indexStr);
- cout << GetLocalUserName() << " is calling host " << fullAddress << endl;
- uiState = uiConnectingCall;
- }
- //
- // StartCall accepts any of the following types of arguments
- // speedial '#' lookup the string in the registry, and continue processing
- // ipaddress dial this IP address or hostname
- // num ' ' gateway dial the number using the specified gateway
- //
- void MyH323EndPoint::StartCall(const PString & ostr)
- {
- PString str = ostr.Trim();
- if (str.IsEmpty())
- cout << "Must supply hostname to connect to!n";
- CallOptions callOptions = defaultCallOptions;
- // check for speed dials, and match wild cards as we go
- PString key, prefix;
- if ((str.GetLength() > 1) && (str[str.GetLength()-1] == '#')) {
- key = str.Left(str.GetLength()-1).Trim();
- str = PString();
- PConfig config("Speeddial");
- PINDEX p;
- for (p = key.GetLength(); p > 0; p--) {
- PString newKey = key.Left(p);
- prefix = newKey;
- PINDEX q;
- // look for wild cards
- str = config.GetString(newKey + '*').Trim();
- if (!str.IsEmpty())
- break;
- // look for digit matches
- for (q = p; q < key.GetLength(); q++)
- newKey += '?';
- str = config.GetString(newKey).Trim();
- if (!str.IsEmpty())
- break;
- }
- if (str.IsEmpty()) {
- cout << "Speed dial "" << key << "" not defined";
- if (gatekeeper != NULL) {
- cout << ", trying gatekeeper ..." << endl;
- MakeOutgoingCall(key, PString(), callOptions);
- return;
- }
- else
- cout << endl;
- }
- else if ((p = str.Find('(')) != P_MAX_INDEX) {
- PString argStr = str.Mid(p);
- if (argStr.GetLength() > 0 && argStr[argStr.GetLength()-1] == ')')
- argStr = argStr.Mid(1, argStr.GetLength()-2);
- //Passing arguments to the call
- PArgList strArgs(argStr,
- "f-fast-disable."
- "T-h245tunneldisable."
- "e-silence."
- "j-jitter:"
- "-connectport:"
- "-connectring:");
- callOptions.Initialise(strArgs);
- str = str.Left(p);
- cout << "Per connection call options set: " << argStr << endl
- << callOptions
- << endl;
- }
- }
- if (!str.IsEmpty()) {
- PINDEX idx = str.Find(' ');
- if (idx == P_MAX_INDEX) {
- if (!key && (str[0] == '@'))
- MakeOutgoingCall(key, str.Mid(1), callOptions);
- else if (!key && !prefix && (str[0] == '%')) {
- if (key.Left(prefix.GetLength()) == prefix)
- key = key.Mid(prefix.GetLength());
- MakeOutgoingCall(key, str.Mid(1), callOptions);
- } else
- MakeOutgoingCall(str, PString(), callOptions);
- } else {
- PString host = str.Left(idx).Trim();
- PString gw = str.Mid(idx).Trim();
- MakeOutgoingCall(host, gw, callOptions);
- }
- return;
- }
- uiState = MyH323EndPoint::uiCallHungup;
- }
- void MyH323EndPoint::AwaitTermination()
- {
- PThread * userInterfaceThread = NULL;
- if (hasMenu)
- userInterfaceThread = new UserInterfaceThread(*this);
- #if ! defined(HAS_LIDDEVICE)
- exitFlag.Wait();
- #else
- if ((lidDevice == NULL) || !lidDevice->IsOpen())
- exitFlag.Wait();
- else {
- speakerphoneSwitch = FALSE;
- BOOL oldOnHook = TRUE;
- BOOL oldRealOnHook = TRUE;
- int olduiState = uiStateIllegal;
- PTime offHookTime;
- PString digits;
- // poll the handset every 100ms looking for state changes
- while (!exitFlag.Wait(100)) {
- // lock the user interface state whilst we change it
- uiStateMutex.Wait();
- // get real hook state
- BOOL realOnHook = !lidDevice->IsLineOffHook(POTS_LINE);
- BOOL onHook = realOnHook;
- // if in speakerphone mode,
- if (speakerphoneSwitch) {
- // if the phone is onhook then don't look at the real hook state
- if (realOnHook)
- onHook = FALSE;
- // if the handset just went offhook, then get out of speakerphone mode
- else if (realOnHook != oldRealOnHook) {
- speakerphoneSwitch = FALSE;
- lidDevice->EnableAudio(0, TRUE);
- if (verbose > 1)
- cout << "Speakerphone off" << endl;
- }
- }
- // handle onhook/offhook transitions
- if (onHook != oldOnHook) {
- if (onHook) {
- digits = PString();
- HandleHandsetOnHook();
- } else {
- HandleHandsetOffHook();
- offHookTime = PTime();
- }
- HandleStateChange(onHook);
- olduiState = uiState;
- }
- // handle timeouts and DTMF digits
- if (!onHook) {
- HandleHandsetTimeouts(offHookTime);
- HandleHandsetDTMF(digits);
- }
- // handle any state changes
- if (uiState != olduiState) {
- offHookTime = PTime();
- HandleStateChange(onHook);
- }
- // save hook state so we can detect changes
- oldOnHook = onHook;
- oldRealOnHook = realOnHook;
- // save the old UI state so we can detect changes
- olduiState = uiState;
- uiStateMutex.Signal();
- }
- }
- #endif
- if (userInterfaceThread != NULL) {
- userInterfaceThread->Terminate();
- userInterfaceThread->WaitForTermination();
- delete userInterfaceThread;
- }
- }
- #if defined(HAS_LIDDEVICE)
- #if 0
- static char * stateNames[] = {
- "Dialtone",
- "AnsweringCall",
- "ConnectingCall",
- "WaitingForAnswer",
- "CallInProgress",
- "CallHungup",
- "StateIllegal"
- };
- #endif
- void MyH323EndPoint::HandleStateChange(BOOL onHook)
- {
- switch (uiState) {
- // dialtone whilst no call active
- case uiDialtone:
- if (onHook)
- lidDevice->RingLine(0, 0);
- else if (autoHook) {
- lidDevice->StopTone(0);
- } else {
- cout << "Playing dialtone" << endl;
- lidDevice->PlayTone(0, OpalLineInterfaceDevice::DialTone);
- }
- break;
- // no tone whilst waiting for remote party to connect
- case uiConnectingCall:
- if (onHook)
- lidDevice->RingLine(0, 0);
- else
- lidDevice->StopTone(0);
- break;
- // when connected, play ring tone
- case uiWaitingForAnswer:
- if (onHook)
- lidDevice->RingLine(0, 0);
- else {
- cout << "Playing ringtone" << endl;
- lidDevice->PlayTone(0, OpalLineInterfaceDevice::RingTone);
- }
- break;
- // when a call is in progress, stop all tones and remove DTMF tones from the stream
- case uiCallInProgress:
- if (onHook)
- lidDevice->RingLine(0, 0);
- else {
- lidDevice->StopTone(0);
- lidDevice->SetRemoveDTMF(0, TRUE);
- }
- break;
- // remote end has hungup
- case uiCallHungup:
- if (terminateOnHangup)
- exitFlag.Signal();
- if (autoHook || onHook) {
- uiState = uiDialtone;
- lidDevice->RingLine(0, 0);
- } else {
- if (dialAfterHangup)
- uiState = uiDialtone;
- else
- lidDevice->PlayTone(POTS_LINE, OpalLineInterfaceDevice::BusyTone);
- }
- break;
- case uiAnsweringCall:
- if (autoHook || !onHook)
- lidDevice->StopTone(0);
- else {
- lidDevice->SetCallerID(POTS_LINE, "");
- if (callerIdEnable) {
- MyH323Connection * connection = (MyH323Connection *)FindConnectionWithLock(currentCallToken);
- if (connection != NULL) {
- lidDevice->SetCallerID(POTS_LINE, connection->GetCallerIdString());
- connection->Unlock();
- }
- }
- lidDevice->RingLine(0, 0x33);
- }
- break;
- default:
- if (!onHook || autoHook)
- lidDevice->StopTone(0);
- else
- lidDevice->RingLine(0, 0);
- break;
- }
- }
- void MyH323EndPoint::HandleHandsetOffHook()
- {
- if (verbose > 1)
- cout << "Offhook - ";
- // if (speakerphoneSwitch) {
- // if (verbose > 1)
- // cout << "speakerphone off - ";
- // speakerphoneSwitch = FALSE;
- // lidDevice->EnableAudio(0, TRUE);
- // }
-
- switch (uiState) {
- case uiDialtone:
- if (!autoDial) {
- if (verbose > 1)
- cout << "auto-dialing " << autoDial << endl;
- StartCall(autoDial);
- } else {
- if (verbose > 1)
- cout << "dialtone" << endl;
- }
- break;
-
- case uiConnectingCall:
- if (verbose > 1)
- cout << "call connecting" << endl;
- break;
-
- case uiAnsweringCall:
- if (verbose > 1)
- cout << "answering call" << endl;
- AnswerCall(H323Connection::AnswerCallNow);
- break;
-
- case uiWaitingForAnswer:
- if (verbose > 1)
- cout << "waiting for remote answer" << endl;
- break;
- case uiCallInProgress: // should never occur!
- if (verbose > 1)
- cout << "call in progress" << endl;
- break;
-
- default:
- if (verbose > 1)
- cout << "not sure!" << endl;
- break;
- }
- }
- void MyH323EndPoint::HandleHandsetOnHook()
- {
- if (uiState == uiCallHungup)
- uiState = uiDialtone;
- if (verbose > 1)
- cout << "Onhook - ";
- //#ifndef OLD_IXJ_DRIVER
- // if (speakerphoneSwitch) {
- // lidDevice->EnableAudio(0, FALSE);
- // if (verbose > 1)
- // cout << "speakerphone on." << endl;
- // } else
- //#endif
- // {
- if (verbose > 1)
- cout << "ending call." << endl;
- ClearCall(currentCallToken);
- // }
- speakerphoneSwitch = FALSE;
- }
- void MyH323EndPoint::HandleHandsetDTMF(PString & digits)
- {
- char newDigit = lidDevice->ReadDTMF(0);
- if (newDigit != ' ') {
- digits += newDigit;
- if (!digits) {
- switch (uiState) {
- case uiCallInProgress:
- {
- if (verbose > 1)
- cout << "Sending user indication message " << digits << endl;
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection != NULL) {
- connection->SendUserInput(digits);
- connection->Unlock();
- }
- digits = PString();
- }
- break;
-
- case uiDialtone:
- lidDevice->StopTone(0);
- if (digits.GetLength() > 0) {
- PINDEX i;
- for (i = 0; i < digits.GetLength(); i++)
- if (!isdigit(digits[i]))
- break;
- BOOL allDigits = i == digits.GetLength();
- // handle strings ending in '#'
- if (digits[digits.GetLength()-1] == '#') {
- // if pressed '#', then redial last number
- if (digits.GetLength() == 1) {
- PConfig config("Calls");
- int index = config.GetInteger("index");
- PString lastCalledParty = config.GetString(PString(PString::Unsigned, index));
- if (lastCalledParty.IsEmpty())
- cout << "No last called party to dial" << endl;
- else {
- if (!MakeCall(lastCalledParty, currentCallToken))
- cout << "Error making call to "" << lastCalledParty << '"' << endl;
- else {
- if (verbose > 1)
- cout << "Redialling last number at " << lastCalledParty << endl;
- uiState = uiConnectingCall;
- }
- }
- }
- // if pressed '*#', then redial last caller
- else if ((digits.GetLength() == 2) && (digits[0] == '*')) {
- PConfig config("Callers");
- int index = config.GetInteger("index");
- PString lastCallingParty = config.GetString(PString(PString::Unsigned, index));
- if (lastCallingParty.IsEmpty())
- cout << "No last calling party to dial" << endl;
- else {
- if (!MakeCall(lastCallingParty, currentCallToken))
- cout << "Error making call to "" << lastCallingParty << '"' << endl;
- else {
- if (verbose > 1)
- cout << "Calling back last party at " << lastCallingParty << endl;
- uiState = uiConnectingCall;
- }
- }
- }
- // if string starts with '*', then convert to IP address
- else if ((digits.GetLength() >= 9) && (digits[0] == '*')) {
- digits = digits.Mid(1, digits.GetLength()-2);
- digits.Replace('*', '.', TRUE);
- StartCall(digits);
- // if there are some digits, then use them as a speed dial
- } else if (digits.GetLength() > 1)
- StartCall(digits);
- // clear out the dialled digits
- digits = PString();
- } else if (allDigits && (digits.GetLength() == 10)) {
- while (digits[0] == '0')
- digits = digits.Mid(1);
- if (digits.GetLength() > 0) {
- StartCall(digits);
- digits = PString();
- }
- }
- }
- break;
-
- default:
- break;
- }
- }
- }
- }
- void MyH323EndPoint::HandleHandsetTimeouts(const PTime & offHookTime)
- {
- int timeout = 0;
-
- switch (uiState) {
- case uiDialtone:
- timeout = DEFAULT_TIMEOUT;
- break;
- case uiConnectingCall:
- timeout = DEFAULT_TIMEOUT;
- break;
- case uiWaitingForAnswer:
- timeout = DEFAULT_TIMEOUT;
- break;
- default:
- break;
- }
- if (timeout > 0) {
- PTime now;
- if ((now - offHookTime) > timeout) {
- if (verbose > 1)
- cout << "Operation timed out" << endl;
- ClearCall(currentCallToken);
- uiState = uiCallHungup;
- }
- }
- }
- #endif
- void MyH323EndPoint::HandleUserInterface()
- {
- PConsoleChannel console(PConsoleChannel::StandardInput);
- PTRACE(2, "BeaconClienttUser interface thread started.");
- PStringStream help;
- help << "Select:n"
- " 0-9 : send user indication messagen"
- " C : connect to remote hostn"
- " T : Transfer to another hostn"
- " O : Hold calln"
- " S : Display statisticsn"
- " H : Hang up phonen"
- " L : List speed dialsn"
- " I : Show call historyn"
- " D : Create new speed dialn"
- " {} : Increase/reduce record volumen"
- " [] : Increase/reduce playback volumen"
- " V : Display current volumesn"
- #ifdef HAS_LIDDEVICE
- " A : turn AEC up/downn"
- #endif
- " E : Turn silence supression on/offn"
- " F : Forward call calls to addressn"
- " J : Flip video input top to bottomn";
- ;
- #ifdef HAS_LIDDEVICE
- if (isXJack) {
- #ifndef OLD_IXJ_DRIVER
- if ((lidDevice != NULL) && lidDevice->IsOpen())
- help << " P : Enter speakerphone moden";
- #endif
- }
- #endif
- help << " X : Exit programn";
- for (;;) {
- // display the prompt
- cout << "Command ? " << flush;
- // terminate the menu loop if console finished
- //char ch = 'q';
- char ch = (char)console.peek();
- if (console.eof()) {
- if (verbose)
- cerr << "nConsole gone - menu disabled" << endl;
- return;
- }
-
- if (isdigit(ch)) {
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection == NULL) {
- cout << "No call in progressn";
- console.ignore(INT_MAX, 'n');
- } else {
- PString str;
- console >> str;
- cout << "Sending user indication: " << str << endl;
- connection->SendUserInput(str);
- connection->Unlock();
- }
- }
- else {
- console >> ch;
- switch (tolower(ch)) {
- case '?' :
- cout << help << endl;
- break;
- case 'x' :
- case 'q' :
- cout << "Exiting." << endl;
- ClearAllCalls();
- uiState = uiDialtone;
- exitFlag.Signal();
- console.ignore(INT_MAX, 'n');
- return;
- case 'h' :
- if (!currentCallToken) {
- cout << "Hanging up call." << endl;
- if (!ClearCall(currentCallToken))
- cout << "Could not hang up current call!n";
- speakerphoneSwitch = FALSE;
- }
- console.ignore(INT_MAX, 'n');
- break;
-
- case 't' :
- if (!currentCallToken) {
- PString str;
- console >> str;
- cout << "Transferring call to " << str << endl;
- TransferCall(currentCallToken, str.Trim());
- }
- else
- console.ignore(INT_MAX, 'n');
- break;
- case 'o' :
- if (!currentCallToken) {
- cout << "Holding call." << endl;
- HoldCall(currentCallToken, TRUE);
- }
- console.ignore(INT_MAX, 'n');
- break;
- case 'y' :
- AnswerCall(H323Connection::AnswerCallNow);
- console.ignore(INT_MAX, 'n');
- break;
- case 'n' :
- AnswerCall(H323Connection::AnswerCallDenied);
- console.ignore(INT_MAX, 'n');
- break;
- case 'c' :
- if (!currentCallToken.IsEmpty())
- cout << "Cannot make call whilst call in progressn";
- else {
- PString str;
- console >> str;
- StartCall(str.Trim());
- }
- break;
- /* CHANGED - star */
- //case 'l' :
- // ListSpeedDials();
- // break;
-
- /*case 'd' :
- {
- PString str;
- console >> str;
- NewSpeedDial(str.Trim());
- }
- break;*/
- /* CHANGED - end */
- case 'e' :
- if (currentCallToken.IsEmpty())
- cout << "No call in progress" << endl;
- else {
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection == NULL)
- cout << "No connection active.n";
- else {
- connection->Unlock();
- H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
- if (chan == NULL)
- cout << "Cannot find audio channel" << endl;
- else {
- H323Codec * rawCodec = chan->GetCodec();
- if (!rawCodec->IsDescendant(H323AudioCodec::Class()))
- cout << "Audio channel is not audio!" << endl;
- else {
- H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
- H323AudioCodec::SilenceDetectionMode mode = codec->GetSilenceDetectionMode();
- if (mode == H323AudioCodec::AdaptiveSilenceDetection) {
- mode = H323AudioCodec::NoSilenceDetection;
- cout << "Silence detection off" << endl;
- } else {
- mode = H323AudioCodec::AdaptiveSilenceDetection;
- cout << "Silence detection on" << endl;
- }
- codec->SetSilenceDetectionMode(mode);
- }
- }
- // connection->Unlock();
- }
- }
- break;
- case 's' :
- if (currentCallToken.IsEmpty())
- cout << "No call in progress" << endl;
- else {
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection == NULL)
- cout << "No connection statistics available.n";
- else {
- PTime now;
- PTime callStart = connection->GetConnectionStartTime();
- cout << "Connection statistics:n "
- << "Remote party : " << connection->GetRemotePartyName() << "n "
- << "Start : " << callStart << "n "
- << "Duration : " << setw(5) << setprecision(0) << (now - callStart) << " minsn "
- << "Round trip delay : " << connection->GetRoundTripDelay().GetMilliSeconds() << " msec"
- << endl;
- RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
- if (session == NULL)
- cout << "No RTP session statistics available.n";
- else
- cout << "RTP session statistics:n "
- << session->GetPacketsSent() << '/'
- << session->GetOctetsSent()
- << " packets/bytes sentn "
-
- << session->GetMaximumSendTime() << '/'
- << session->GetAverageSendTime() << '/'
- << session->GetMinimumSendTime() << " max/avg/min send timen "
-
- << session->GetPacketsReceived() << '/'
- << session->GetOctetsReceived()
- << " packets/bytes receivedn "
-
- << session->GetMaximumReceiveTime() << '/'
- << session->GetAverageReceiveTime() << '/'
- << session->GetMinimumReceiveTime() << " max/avg/min receive timen "
-
- << session->GetPacketsLost() << '/'
- << session->GetPacketsOutOfOrder() << '/'
- << session->GetPacketsTooLate()
- << " packets dropped/out of order/laten "
-
- << endl;
-
- connection->Unlock();
- }
- }
- break;
- #ifdef HAS_LIDDEVICE
- #ifndef OLD_IXJ_DRIVER
- case 'p' :
- if (isXJack) {
- if ((lidDevice != NULL) && lidDevice->IsOpen()) {
- speakerphoneSwitch = !speakerphoneSwitch;
- lidDevice->EnableAudio(0, !speakerphoneSwitch);
- if (verbose > 1)
- cout << "Speakerphone "
- << (speakerphoneSwitch ? "on" : "off")
- << endl;
- }
- console.ignore(INT_MAX, 'n');
- }
- break;
- #endif
-
- case 'a' :
- if ((lidDevice != NULL) && lidDevice->IsOpen()) {
- int aec = lidDevice->GetAEC(0);
- if (ch == 'a')
- aec--;
- else
- aec++;
- if (aec < 0)
- aec = OpalLineInterfaceDevice::AECAGC;
- else if (aec > OpalLineInterfaceDevice::AECAGC)
- aec = OpalLineInterfaceDevice::AECOff;
-
- lidDevice->SetAEC(0, (OpalLineInterfaceDevice::AECLevels)aec);
-
- if (aec == OpalLineInterfaceDevice::AECAGC ||
- (ch == 'a' && aec == OpalLineInterfaceDevice::AECHigh) ||
- (ch == 'A' && aec == OpalLineInterfaceDevice::AECOff)) {
- unsigned recvol;
- lidDevice->GetRecordVolume(0, recvol);
- if (verbose > 2)
- cout << "New volume level is " << recvol << endl;
- }
- if (verbose > 2)
- cout << "New AEC level is " << AECLevelNames[aec] << endl;
- } else
- cout <<"AEC change ignored as device closed"<<endl;
- break;
- #endif
- case 'v' :
- #if defined(HAS_LIDDEVICE)
- if ((lidDevice != NULL) && lidDevice->IsOpen()) {
- unsigned vol;
- lidDevice->GetPlayVolume(0, vol);
- cout << "Play volume is " << vol << endl;
- lidDevice->GetRecordVolume(0, vol);
- cout << "Record volume is " << vol << endl;
- }
- #endif
- #if defined(HAS_LIDDEVICE) && defined(HAS_OSS)
- else
- #endif
- #ifdef HAS_OSS
- {
- cout << "Play volume is " << ossPlayVol << endl;
- cout << "Record volume is " << ossRecVol << endl;
- }
- #endif
- break;
- case '[' :
- case ']' :
- case '{' :
- case '}' :
- #ifdef HAS_LIDDEVICE
- if ((lidDevice != NULL) && lidDevice->IsOpen()) {
- unsigned vol;
- if (ch == '{' || ch == '}')
- lidDevice->GetRecordVolume(0, vol);
- else
- lidDevice->GetPlayVolume(0, vol);
- // adjust volume up or down
- vol += ((ch == '[') || (ch == '{')) ? -5 : 5;
- if (vol < 0)
- vol = 0;
- else if (vol > 100)
- vol = 100;
- // write to hardware
- if (ch == '{' || ch == '}') {
- lidDevice->SetRecordVolume(0, vol);
- if (verbose > 2)
- cout << "Record volume is " << vol << endl;
- } else {
- lidDevice->SetPlayVolume(0, vol);
- if (verbose > 2)
- cout << "Play volume is " << vol << endl;
- }
- }
- #endif
- #if defined(HAS_LIDDEVICE) && defined(HAS_OSS)
- else
- #endif
- #ifdef HAS_OSS
- {
- int vol;
- if (ch == '{' || ch == '}')
- vol = ossRecVol;
- else
- vol = ossPlayVol;
-
- vol += ((ch == '[') || (ch == '{')) ? -5 : 5;
- if (vol < 0)
- vol = 0;
- else if (vol > 100)
- vol = 100;
-
- if (mixerDev >= 0) {
- int volVal = vol | (vol << 8);
- if (ch == '{' || ch == '}') {
- ossRecVol = vol;
- ::ioctl(mixerDev, MIXER_WRITE(mixerRecChan), &volVal);
- cout << "Record volume is " << ossRecVol << endl;
- } else {
- ossPlayVol = vol;
- ::ioctl(mixerDev, SOUND_MIXER_WRITE_PCM, &volVal);
- cout << "Play volume is " << ossPlayVol << endl;
- }
- } else
- cout << "Audio setting change ignored as mixer device disabled"<<endl;
- }
- #endif
- break;
- case 'f' :
- console >> alwaysForwardParty;
- alwaysForwardParty = alwaysForwardParty.Trim();
- if (!alwaysForwardParty)
- cout << "Forwarding all calls to "" << alwaysForwardParty << '"' << endl;
- else
- cout << "Call forwarding of all calls disabled." << endl;
- break;
-
- case 'i' :
- case 'I' :
- {
- PString title;
- if (ch == 'i')
- title = "Callers";
- else
- title = "Calls";
- cout << title << endl;
- PConfig config(title);
- int index = config.GetInteger("index");
- PINDEX i;
- for (i = 0; i < LAST_CALL_COUNT; i++) {
- PString indexStr = PString(PString::Unsigned, index);
- PString number = config.GetString(indexStr);
- if (number.IsEmpty())
- continue;
- cout << indexStr
- << ": "
- << number
- << " at "
- << config.GetString(indexStr + "_Time")
- << endl;
- if (index == 0)
- index = LAST_CALL_COUNT-1;
- else
- index--;
- }
- }
- break;
- case 'j' :
- if (currentCallToken.IsEmpty())
- cout << "No call in progress" << endl;
- else {
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection == NULL)
- cout << "No connection active.n";
- else {
- connection->Unlock();
- H323Channel * chan = connection->FindChannel(RTP_Session::DefaultVideoSessionID, FALSE);
- if (chan == NULL)
- cout << "Cannot find sending video channel" << endl;
- else {
- H323Codec * rawCodec = chan->GetCodec();
- if (!rawCodec->IsDescendant(H323VideoCodec::Class()))
- cout << "Sending video codec is not video!" << endl;
- else {
- H323VideoCodec * codec = (H323VideoCodec *)rawCodec;
- videoCodecDlgAudioVideo = (H323VideoCodec *)rawCodec;
- PChannel * rawChan = codec->GetRawDataChannel();
- if (NULL == rawChan)
- cout << "Cannot find sending video channel" << endl;
- else {
- if (!rawChan->IsDescendant(PVideoChannel::Class()))
- cerr << "Sending video channel is not Class PVideoChannel!" << endl;
- else {
- PVideoChannel * videoChan = (PVideoChannel *)rawChan;
- if (!videoChan->ToggleVFlipInput())
- cerr << "nCould not toggle Vflip state of video input device" << endl;
- }
- }
- }
- }
- }
- }
- break;
-
- default:
- cout << "Unknown command " << ch << endl;
- console.ignore(INT_MAX, 'n');
- break;
- }
- }
- }
- }
- void MyH323EndPoint::AnswerCall(H323Connection::AnswerCallResponse response)
- {
- if (uiState != uiAnsweringCall)
- return;
- StopRinging();
- H323Connection * connection = FindConnectionWithLock(currentCallToken);
- if (connection == NULL)
- return;
- connection->AnsweringCall(response);
- connection->Unlock();
- if (response == H323Connection::AnswerCallNow) {
- cout << "Accepting call." << endl;
- uiState = uiCallInProgress;
- } else {
- cout << "Rejecting call." << endl;
- uiState = uiCallHungup;
- }
- }
- void MyH323EndPoint::HandleRinging()
- {
- PSoundChannel dev(GetSoundChannelPlayDevice(), PSoundChannel::Player);
- if (!dev.IsOpen()) {
- PTRACE(2, "Cannot open sound device for ring");
- return;
- }
- if (ringDelay < 0) {
- PTRACE(2, "Playing " << ringFile);
- dev.PlayFile(ringFile, TRUE);
- } else {
- PTimeInterval delay(0, ringDelay);
- PTRACE(2, "Playing " << ringFile << " with repeat of " << delay << " ms");
- do {
- dev.PlayFile(ringFile, TRUE);
- } while (!ringFlag.Wait(delay));
- }
- }
- void MyH323EndPoint::StartRinging()
- {
- PAssert(ringThread == NULL, "Ringing thread already present");
- if (!noAnswerForwardParty)
- noAnswerTimer = PTimeInterval(0, noAnswerTime);
- if (!ringFile)
- ringThread = new RingThread(*this);
- }
- void MyH323EndPoint::StopRinging()
- {
- noAnswerTimer.Stop();
- if (ringThread == NULL)
- return;
- ringFlag.Signal();
- ringThread->WaitForTermination();
- delete ringThread;
- ringThread = NULL;
- }
- void MyH323EndPoint::SendDTMF(const char * tone)
- {
- #ifdef HAS_LIDDEVICE
- lidDevice->PlayDTMF(0, tone, 200, 100);
- #endif
- }
- ///////////////////////////////////////////////////////////////
- BOOL CallOptions::Initialise(PArgList & args)
- {
- // set default connection options
- noFastStart = args.HasOption('f');
- noH245Tunnelling = args.HasOption('T');
- noSilenceSuppression = args.HasOption('e');
- if (args.HasOption("connectring"))
- connectRing = args.HasOption("connectring");
- if (!args.GetOptionString("connectport").IsEmpty())
- connectPort = (WORD)args.GetOptionString("connectport").AsInteger();
- if (args.HasOption('j')) {
- int newjitter = args.GetOptionString('j').AsUnsigned();
- if (newjitter >= 20 && newjitter <= 10000)
- jitter = newjitter;
- else {
- cerr << "Jitter should be between 20 milliseconds and 10 seconds." << endl;
- return FALSE;
- }
- }
- return TRUE;
- }
- void CallOptions::PrintOn(ostream & strm) const
- {
- strm << "FastStart is " << !noFastStart << "n"
- << "H245Tunnelling is " << !noH245Tunnelling << "n"
- << "SilenceSupression is " << !noSilenceSuppression << "n"
- << "Jitter buffer: " << jitter << " msn"
- << "Connect port: " << connectPort << "n";
- }
- void MyH323EndPoint::TestHandleUserInterface()
- {
- PConsoleChannel console(PConsoleChannel::StandardInput);
- PTRACE(2, "BeaconClienttTESTING interface thread started.");
- PStringStream help;
- help << "Select:n"
- " J : Flip video input top to bottomn"
- " Q : Exit programn"
- " X : Exit programn";
- for (;;) {
- // display the prompt
- cout << "(testing) Command ? " << flush;
- // terminate the menu loop if console finished
- char ch = (char)console.peek();
- if (console.eof()) {
- if (verbose)
- cerr << "nConsole gone - menu disabled" << endl;
- return;
- }
- console >> ch;
- switch (tolower(ch)) {
- case 'j' :
- if (NULL == localVideoChannel) {
- cerr << "nNo video Channel" << endl;
- break;
- }
- if (!localVideoChannel->ToggleVFlipInput())
- cerr << "nCould not toggle Vflip state of video input device" << endl;
- break;
-
- case 'x' :
- case 'q' :
- cout << "Exiting." << endl;
- exitFlag.Signal();
- console.ignore(INT_MAX, 'n');
- return;
- break;
- case '?' :
- default:
- cout << help << endl;
- break;
-
- } // end switch
- } // end for
- }
- ///////////////////////////////////////////////////////////////
- /* Modified One */
- /*
- MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
- unsigned callReference,
- unsigned options,
- WORD jitter,
- int _verbose)
- : H323Connection(ep, callReference, disableFastStart, disableTunneling),
- myEndpoint(ep),
- verbose(_verbose)
- {
- SetMaxAudioDelayJitter(jitter);
- channelsOpen = 0;
- }
- */
- // New One
- MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
- unsigned callReference,
- unsigned options,
- WORD jitter,
- int _verbose)
- : H323Connection(ep, callReference, options),
- myEndpoint(ep),
- verbose(_verbose)
- {
- SetMaxAudioDelayJitter(jitter);
- channelsOpen = 0;
- }
- /*
- // Old One
- MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
- unsigned callReference,
- BOOL disableFastStart,
- BOOL disableTunneling,
- WORD jitter,
- int _verbose)
- : H323Connection(ep, callReference, disableFastStart, disableTunneling),
- myEndpoint(ep),
- verbose(_verbose)
- {
- SetMaxAudioDelayJitter(jitter);
- channelsOpen = 0;
- }
- */
- BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
- {
- if (!myEndpoint.setupParameter) {
- setupPDU.m_h323_uu_pdu.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardData);
- setupPDU.m_h323_uu_pdu.m_nonStandardData.m_nonStandardIdentifier.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
- endpoint.SetH221NonStandardInfo(setupPDU.m_h323_uu_pdu.m_nonStandardData.m_nonStandardIdentifier);
- setupPDU.m_h323_uu_pdu.m_nonStandardData.m_data = myEndpoint.setupParameter;
- }
- return TRUE;
- }
- H323Connection::AnswerCallResponse
- MyH323Connection::OnAnswerCall(const PString & caller,
- const H323SignalPDU & /*setupPDU*/,
- H323SignalPDU & /*connectPDU*/)
- {
- PTRACE(1, "H225tOnWaitForAnswer");
- PTime now;
- if (myEndpoint.autoAnswer) {
- cout << "Automatically accepting call at " << now << endl;
- return AnswerCallNow;
- }
- myEndpoint.currentCallToken = GetCallToken();
- myEndpoint.uiState = MyH323EndPoint::uiAnsweringCall;
- cout << "Incoming call from ""
- << caller
- << "" at "
- << now
- << ", answer call (Y/n)? "
- << flush;
- myEndpoint.StartRinging();
-
- return AnswerCallPending;
- }
- BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
- {
- if (!H323Connection::OnStartLogicalChannel(channel))
- return FALSE;
- if (verbose >= 2) {
- cout << "Started logical channel: ";
- switch (channel.GetDirection()) {
- case H323Channel::IsTransmitter :
- cout << "sending ";
- break;
- case H323Channel::IsReceiver :
- cout << "receiving ";
- break;
- default :
- break;
- }
- cout << channel.GetCapability() << endl;
- }
- if (channel.GetDirection() == H323Channel::IsReceiver) {
- int videoQuality = myEndpoint.videoQuality;
- if (channel.GetCodec()->IsDescendant(H323VideoCodec::Class()) && (videoQuality >= 0)) {
- //const H323_H261Capability & h261Capability = (const H323_H261Capability &)channel.GetCapability();
- //if (!h261Capability.GetTemporalSpatialTradeOffCapability())
- // cout << "Remote endpoint does not allow video quality configuration" << endl;
- //else {
- cout << "Requesting remote endpoint to send video quality " << videoQuality << "/31" << endl;
-
- // kludge to wait for channel to ACK to be sent
- PThread::Current()->Sleep(2000);
-
- H323ControlPDU pdu;
- H245_CommandMessage & command = pdu.Build(H245_CommandMessage::e_miscellaneousCommand);
-
- H245_MiscellaneousCommand & miscCommand = command;
- miscCommand.m_logicalChannelNumber = (unsigned)channel.GetNumber();
- miscCommand.m_type.SetTag(H245_MiscellaneousCommand_type::e_videoTemporalSpatialTradeOff);
- PASN_Integer & value = miscCommand.m_type;
- value = videoQuality;
- WriteControlPDU(pdu);
- //}
- }
- }
- // adjust the count of channels we have open
- channelsOpen++;
- PTRACE(2, "MaintchannelsOpen = " << channelsOpen);
- // if we get to two channels (one open, one receive), then (perhaps) trigger a timeout for shutdown
- if (channelsOpen == 2)
- myEndpoint.TriggerDisconnect();
- return TRUE;
- }
- void MyH323Connection::OnClosedLogicalChannel(H323Channel & channel)
- {
- channelsOpen--;
- H323Connection::OnClosedLogicalChannel(channel);
- }
- BOOL MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/,
- const PString & username)
- {
- PAssert((myEndpoint.uiState == MyH323EndPoint::uiConnectingCall) ||
- (myEndpoint.uiState == MyH323EndPoint::uiWaitingForAnswer) ||
- !myEndpoint.callTransferCallToken,
- psprintf("Alerting received in state %i whilst not waiting for incoming call!", myEndpoint.uiState));
- if (verbose > 0)
- cout << "Ringing phone for "" << username << "" ..." << endl;
- myEndpoint.uiState = MyH323EndPoint::uiWaitingForAnswer;
- return TRUE;
- }
- void MyH323Connection::OnUserInputString(const PString & value)
- {
- cout << "User input received: "" << value << '"' << endl;
-
- //strcpy(ReceivedDTMF,value);
- ReceivedDTMFMessages = value;
- #ifdef HAS_LIDDEVICE
- //myEndpoint.SendDTMF(value);
- #endif
- }
- PString MyH323Connection::GetCallerIdString() const
- {
- H323TransportAddress addr = GetControlChannel().GetRemoteAddress();
- PIPSocket::Address ip;
- WORD port;
- addr.GetIpAndPort(ip, port);
- DWORD decimalIp = (ip[0] << 24) +
- (ip[1] << 16) +
- (ip[2] << 8) +
- ip[3];
- PString remotePartyName = GetRemotePartyName();
- PINDEX bracket = remotePartyName.Find('[');
- if (bracket != P_MAX_INDEX)
- remotePartyName = remotePartyName.Left(bracket);
- bracket = remotePartyName.Find('(');
- if (bracket != P_MAX_INDEX)
- remotePartyName = remotePartyName.Left(bracket);
- return psprintf("%010litt", decimalIp) + remotePartyName;
- }
- // End of File ///////////////////////////////////////////////////////////////