main.cpp
上传用户:gnaf34
上传日期:2022-04-22
资源大小:1657k
文件大小:102k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * main.cxx
  3.  *
  4.  * This is where the action starts!
  5.  *
  6.  * Copyright (c) ITEC-Ohio, 2002.
  7.  *
  8.  * The contents of this file are subject to the Mozilla Public License
  9.  * Version 1.0 (the "License"); you may not use this file except in
  10.  * compliance with the License. You may obtain a copy of the License at
  11.  * http://www.mozilla.org/MPL/
  12.  *
  13.  * Software distributed under the License is distributed on an "AS IS"
  14.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  15.  * the License for the specific language governing rights and limitations
  16.  * under the License.
  17.  *
  18.  * The Original Code is Open H323 Library available at http://www.openh323.org
  19.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  20.  *
  21.  */
  22. #include "afx.h"
  23. #include <iostream.h>
  24. #include <fstream.h>
  25. #include <vector>
  26. #include <ptlib.h>
  27. #include <string.h>
  28. #include <io.h>
  29. #include <fcntl.h>
  30. #include <stdlib.h>
  31. #include <windows.h>
  32. #include "ximage.h"
  33. #include "main.h"
  34. #include "gsmcodec.h"
  35. #include "lpc10codec.h"
  36. #include "mscodecs.h"
  37. #include "h261codec.h"
  38. #include "videoio.h"
  39. #include "h323pdu.h"
  40. #include "g7231codec.h"
  41. #ifdef HAS_CU30
  42. #include "cu30codec.h"
  43. #endif
  44. #define FICTITOUS_VIDEO "fake"
  45. //GNUPlot related Information
  46. extern CString currentTestFolder;
  47. extern char exeFolderPath[MAX_PATH];
  48. extern CString consoleStr;
  49. /* Customize this path if needed */
  50. //#define PROGNAME "c:\gnuplot\wgnuplot.exe"
  51. #define PROGNAME "wgnuplot.exe"
  52. /* CRS: The value given above will work correctly as long as pgnuplot.exe
  53.  * is in the same directory as wgnuplot.exe or the directory containing
  54.  * wgnuplot.exe is included in the path. I would recommend placing the 
  55.  * pgnuplot.exe executable in the same directory as wgnuplot.exe and 
  56.  * leaving this definition alone.
  57.  */
  58. #define WINDOWNAME "gnuplot"
  59. #define PARENTCLASS "wgnuplot_parent"
  60. #define TEXTCLASS "wgnuplot_text"
  61. #define GRAPHWINDOW "gnuplot graph"
  62. #define GRAPHCLASS "wgnuplot_graph"
  63. #define BUFFER_SIZE 80
  64. #ifndef _O_BINARY
  65. # define _O_BINARY O_BINARY
  66. #endif
  67. #if (__BORLANDC__ >= 0x450) /* about BCBuilder 1.0 */
  68. # define _setmode setmode
  69. #endif
  70. /* GLOBAL Variables */
  71. HWND hwndParent = NULL;
  72. HWND hwndText = NULL;
  73. char    psBuffer[BUFFER_SIZE];
  74. char    psGnuplotCommandLine[MAX_PATH];
  75. LPTSTR  psCmdLine;
  76. BOOL    bSuccess;
  77. PROCESS_INFORMATION piProcInfo; 
  78. STARTUPINFO         siStartInfo; 
  79. //End of GNUPlot related information
  80. #if defined(P_FREEBSD) || defined(P_OPENBSD)
  81. #define DEFAULT_VIDEO "/dev/bktr0"
  82. #endif
  83. #ifndef DEFAULT_VIDEO
  84. #define DEFAULT_VIDEO "/dev/video0"
  85. #endif
  86. #ifdef HAS_X11
  87. #include "xlibvid.h"
  88. #endif
  89. #ifdef HAS_SDL
  90. #include "sdlvid.h"
  91. #endif
  92. #ifdef HAS_OSS
  93. #define DEFAULT_MIXER "/dev/mixer"
  94. #include <linux/soundcard.h>
  95. #endif
  96. // uncomment below if to include xJack G729 code
  97. #ifdef _WIN32
  98. #define G729
  99. #endif
  100. #ifdef HAS_LIDDEVICE
  101. static const char * AECLevelNames[] = { "Off", "Low", "Medium", "High", "Auto AEC", "Auto AEC/AGC" };
  102. #endif
  103. #include "version.h"
  104. ///////This ifdef _win32 is required to enable sdl on windows to work.
  105. /*#ifdef _WIN32
  106. int main(int argc, char ** argv) {                    
  107.         PProcess::PreInitialise(argc, argv, _environ);
  108.         static BeaconClient instance;                      
  109.         return instance._main();                      
  110. }                                                     
  111. #else
  112. PCREATE_PROCESS(BeaconClient);
  113. #endif*/
  114. #define DEFAULT_TIMEOUT 60000
  115. #define LAST_CALL_COUNT 16
  116. #define POTS_LINE       0
  117. class RingThread : public PThread
  118. {
  119.   PCLASSINFO(RingThread, PThread);
  120.   public:
  121.     RingThread(MyH323EndPoint & ep)
  122.       : PThread(1000, NoAutoDeleteThread),
  123.         endpoint(ep)
  124.       { Resume(); }
  125.     void Main()
  126.       { endpoint.HandleRinging(); }
  127.   protected:
  128.     MyH323EndPoint & endpoint;
  129. };
  130. #define new PNEW
  131. //variables to pass as call parameters
  132. CString FastStart;
  133. CString Tunnel;
  134. CString SetUp;
  135. CString TcpBasePort;
  136. CString TcpMaxPort;
  137. CString UdpBasePort;
  138. CString UdpMaxPort;
  139. CString RtpBasePort;
  140. CString RtpMaxPort;
  141. CString SaveResult;
  142. CString SilenceDetection;
  143. CString AudioCodec;
  144. CString JitterBuffer;
  145. CString VideoDevice;
  146. CString Format;
  147. CString temp;
  148. const char CodecsConfigSection[] = "Codecs";
  149. const char RecentCallsConfigSection[] = "Recent Calls";
  150. const char SpeedDialConfigSection[] = "Speed Dial";
  151. const char MainWindowTopConfigKey[] = "MainWindowTop";
  152. const char MainWindowLeftConfigKey[] = "MainWindowLeft";
  153. const char MainWindowWidthConfigKey[] = "MainWindowWidth";
  154. const char MainWindowHeightConfigKey[] = "MainWindowHeight";
  155. const char LocalVideoWindowTopConfigKey[] = "LocalVideoWindowTop";
  156. const char LocalVideoWindowLeftConfigKey[] = "LocalVideoWindowLeft";
  157. const char RemoteVideoWindowTopConfigKey[] = "RemoteVideoWindowTop";
  158. const char RemoteVideoWindowLeftConfigKey[] = "RemoteVideoWindowLeft";
  159. const char AutoAnswerConfigKey[] = "AutoAnswer";
  160. const char DtmfAsStringConfigKey[] = "DtmfAsString";
  161. const char UserInputModeConfigKey[] = "UserInputMode";
  162. const char SilenceDetectConfigKey[] = "SilenceDetect";
  163. const char SilenceDeadbandConfigKey[] = "SilenceDeadband";
  164. const char SignalDeadbandConfigKey[] = "SignalDeadband";
  165. const char NoFastStartConfigKey[] = "NoFastStart";
  166. const char NoTunnelingConfigKey[] = "NoTunneling";
  167. const char NoH245inSetupConfigKey[] = "NoH245inSetup";
  168. const char MaxRecentCallsConfigKey[] = "MaxRecentCalls";
  169. const char TCPPortBaseConfigKey[] = "TCPPortBase";
  170. const char TCPPortMaxConfigKey[] = "TCPPortMax";
  171. const char UDPPortBaseConfigKey[] = "UDPPortBase";
  172. const char UDPPortMaxConfigKey[] = "UDPPortMax";
  173. const char RTPPortBaseConfigKey[] = "RTPPortBase";
  174. const char RTPPortMaxConfigKey[] = "RTPPortMax";
  175. const char IpTosConfigKey[] = "IpTOS";
  176. const char UsernameConfigKey[] = "Username";
  177. const char AliasConfigKey[] = "Alias %u";
  178. const char AlwaysForwardPartyConfigKey[] = "AlwaysForwardParty";
  179. const char BusyForwardPartyConfigKey[] = "BusyForwardParty";
  180. const char NoAnswerForwardPartyConfigKey[] = "NoAnswerForwardParty";
  181. const char CallIntrusionTypeKey[] = "CallIntrusionTypeKey";
  182. const char CallIntrusionProtectionLevelKey[] = "CallIntrusionProtectionLevel";
  183. const char CallIntrusionCapabilityLevelKey[] = "CallIntrusionCapabilityLevel";
  184. const char TransferProtocolConfigKey[] = "TransferProtocol";
  185. const char NoAnswerTimeConfigKey[] = "NoAnswerTime";
  186. const char RingSoundFileConfigKey[] = "RingSoundFile";
  187. const char SoundBuffersConfigKey[] = "SoundBuffers";
  188. const char AECConfigKey[] = "AEC";
  189. const char CountryConfigKey[] = "Country";
  190. const char JitterConfigKey[] = "Jitter";
  191. const char BandwidthTypeConfigKey[] = "BandwidthType";
  192. const char BandwidthConfigKey[] = "Bandwidth";
  193. const char UseGatekeeperConfigKey[] = "UseGatekeeper";
  194. const char RequireGatekeeperConfigKey[] = "RequireGatekeeper";
  195. const char TimeToLiveConfigKey[] = "TimeToLive";
  196. const char AccessTokenOIDConfigKey[] = "AccessTokenOID";
  197. const char GatekeeperHostConfigKey[] = "GatekeeperHost";
  198. const char GatekeeperIdConfigKey[] = "GatekeeperId";
  199. const char GatekeeperPasswordConfigKey[] = "GatekeeperPassword";
  200. const char SoundPlayConfigKey[] = "SoundPlayDevice";
  201. const char SoundRecordConfigKey[] = "SoundRecordDevice";
  202. const char SpeakerVolumeConfigKey[] = "SpeakerVolume";
  203. const char MicrophoneVolumeConfigKey[] = "MicrophoneVolume";
  204. const char UseQuicknetConfigKey[] = "UseQuicknet";
  205. const char QuicknetDeviceConfigKey[] = "QuicknetDevice";
  206. const char DeviceTypeConfigKey[] = "LineInterfaceDeviceType";
  207. const char DeviceNameConfigKey[] = "LineInterfaceDeviceName";
  208. const char H261QCIFConfigKey[] = "H261_QCIF";
  209. const char H261CIFConfigKey[] = "H261_CIF";
  210. const char AutoReceiveVideoConfigKey[] = "AutoReceiveVideo";
  211. const char VideoDeviceConfigKey[] = "VideoDevice";
  212. const char VideoSizeConfigKey[] = "VideoSize";
  213. const char VideoSourceConfigKey[] = "VideoSource";
  214. const char VideoFormatConfigKey[] = "VideoFormat";
  215. const char VideoQualityConfigKey[] = "VideoQuality";
  216. const char VideoLocalConfigKey[] = "VideoLocal";
  217. const char VideoFlipLocalConfigKey[] = "VideoFlipLocal";
  218. const char VideoFlipRemoteConfigKey[] = "VideoFlipRemote";
  219. ///////////////////////////////////////////////////////////////
  220. BeaconClient::BeaconClient()
  221.   : PProcess("ITEC-Ohio", "H.323 Beacon Client",
  222.              MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
  223. {
  224. endpoint = NULL;
  225. }
  226. BeaconClient::~BeaconClient()
  227. {
  228. }
  229. const char* globalEndReason = "";
  230. extern BeaconClient* globalInstance;
  231. //For Statistics Part
  232. PTime now;
  233. PTime StartTimeGlobal;
  234. int StartTimeGlobalYear;
  235. int StartTimeGlobalMonth;
  236. int StartTimeGlobalDay;
  237. int StartTimeGlobalHour;
  238. int StartTimeGlobalMinute;
  239. int StartTimeGlobalSecond;
  240. extern CString sessionStartTime;
  241. extern CString sessionEndTime;
  242. extern CString localmachine;
  243. extern CString ipglobal;
  244. extern CString sessionDate;
  245. DWORD RoundTripTimeDelayGlobal;
  246. PStringStream DurationTimeGlobal;
  247. DWORD AudioFrameRateGlobal;
  248. DWORD PacketSentGlobal;
  249. DWORD OctetSendGlobal;
  250. DWORD MaximumSendTimeGlobal;
  251. DWORD AverageSendTimeGlobal;
  252. DWORD MinimumSendTimeGlobal;
  253. DWORD PacketsReceivedGlobal;
  254. DWORD OctetsReceivedGlobal;
  255. DWORD MaximumReceiveTimeGlobal;
  256. DWORD AverageReceiveTimeGlobal;
  257. DWORD MinimumReceiveTimeGlobal;
  258. DWORD PacketsLostGlobal;
  259. DWORD PacketsOutOfOrderGlobal;
  260. DWORD PacketsOutTooLateGlobal;
  261. DWORD JitterTimeGlobal;
  262. PString PayloadTypeGlobal;
  263. PString TokenCurrentCall;
  264. PString ReceivedDTMFMessages;
  265. char *ReceivedDTMF;
  266. // This variable being used for the need of generating statistic
  267. BOOLEAN GenerateStatistic; 
  268. //FlagEndPoint to check if EndPoint is already deleted
  269. int FlagEndPoint = 1;
  270. //IndexBandwidth added to make a call with particular bandwidth
  271. int indexbandwidth;
  272. unsigned int call_bandwidth;
  273. unsigned bandwidthAvailable;
  274. H323VideoCodec * videoCodecDlgAudioVideo; 
  275.                        
  276. void BeaconClient::Main()
  277. {
  278.   globalEndReason = "";
  279.   int verbose = 255;
  280.   bool hasMenu = 1;
  281.   
  282.   endpoint = new MyH323EndPoint; 
  283.   switch(indexbandwidth){
  284.   case 0:
  285.   {
  286.   call_bandwidth = 56000;
  287.   }
  288.   break;
  289.   case 1:
  290.   {
  291.   call_bandwidth = 128000;
  292.   }
  293.   break;
  294.   case 2:
  295.   {
  296.   call_bandwidth = 256000;
  297.   }
  298.   break;
  299.   case 3:
  300.   {
  301.   call_bandwidth = 384000;
  302.   }
  303.   break;
  304.   case 4:
  305.   {
  306.   call_bandwidth = 512000;
  307.   }
  308.   break;
  309.   case 5:
  310.   {
  311.   call_bandwidth = 768000;
  312.   }
  313.   break;
  314.   default:
  315.   {
  316.   call_bandwidth = 56000;
  317.   }
  318.   break;
  319.   } // End of switch statement;
  320. //Read stuff from settings file 'S.conf' and put in variables.
  321.     char file[MAX_PATH];
  322. char exeFilePath[MAX_PATH]; //a string for GetModuleFileName() to store exe Path
  323. GetModuleFileName( NULL,&exeFilePath[0],sizeof (exeFilePath));
  324. //Extract path by copying without exe string..
  325. for(int i=0; i < abs(strlen(exeFilePath)-16); i++){
  326. file[i] = exeFilePath[i];
  327. }
  328. file[i] = '';
  329. //strcpy(file,exeFolderPath);
  330. strcat(file,"S.conf");
  331.     FILE *fp;
  332. int t=10;
  333. fp = fopen(file,"r");
  334. //consoleStr+=file;
  335. //mp= CString("");
  336. //Call Options
  337. fscanf(fp,"%s",temp); //for CCall_Options
  338. fscanf(fp,"%s",temp);
  339. fscanf(fp,"%s",temp); //
  340. FastStart = CString(temp);
  341. fscanf(fp,"%s",temp);
  342. fscanf(fp,"%s",temp);
  343. Tunnel = CString(temp);
  344.     fscanf(fp,"%s",temp);
  345. fscanf(fp,"%s",temp);
  346.     SetUp = CString(temp);
  347. //consoleStr+="rn";
  348.     //consoleStr+;
  349. //Output File Path
  350. fscanf(fp,"%s",temp);//for Output_File_Path
  351. fscanf(fp,"%s",temp);
  352. fseek(fp,sizeof(char),SEEK_CUR);
  353. //fscanf(fp,"%s ",temp);
  354. char filepath[MAX_PATH];
  355. fgets(filepath,MAX_PATH,fp);
  356. //Port Options
  357. fscanf(fp,"%s",temp); //for Ports_Options
  358. fscanf(fp,"%s",temp);
  359. fscanf(fp,"%s",temp);
  360. TcpBasePort= CString(temp);
  361. fscanf(fp,"%s",temp);
  362. fscanf(fp,"%s",temp);
  363. TcpMaxPort= CString(temp);
  364. fscanf(fp,"%s",temp);
  365. fscanf(fp,"%s",temp);
  366. UdpBasePort= CString(temp);
  367. fscanf(fp,"%s",temp);
  368. fscanf(fp,"%s",temp);
  369. UdpMaxPort= CString(temp);
  370. fscanf(fp,"%s",temp);
  371. fscanf(fp,"%s",temp);
  372. RtpBasePort= CString(temp);
  373. fscanf(fp,"%s",temp);
  374. fscanf(fp,"%s",temp);
  375. RtpMaxPort= CString(temp);
  376. //Test Save Results
  377. fscanf(fp,"%s",temp); //for Test_Save_Results
  378. fscanf(fp,"%s",temp);
  379. fscanf(fp,"%s",temp);
  380.     SaveResult = CString(temp);
  381. //consoleStr+="rnSave Result: ";
  382. //consoleStr+=SaveResult;
  383. //Audio Options
  384. fscanf(fp,"%s",temp); //for Audio_options
  385. fscanf(fp,"%s",temp);
  386. fscanf(fp,"%s",temp);
  387. SilenceDetection= CString(temp);
  388.     fscanf(fp,"%s",temp);
  389. fscanf(fp,"%s",temp);
  390. AudioCodec= CString(temp);
  391. fscanf(fp,"%s",temp);
  392. fscanf(fp,"%s",temp);
  393. JitterBuffer= CString(temp);
  394. //Video Options
  395. fscanf(fp,"%s",temp); //for Video_options
  396. fscanf(fp,"%s",temp);
  397. fscanf(fp,"%s",temp);
  398. VideoDevice= CString(temp);
  399. fscanf(fp,"%s",temp);
  400. fscanf(fp,"%s",temp);
  401. Format= CString(temp);
  402.     //consoleStr+="rn";
  403.     //consoleStr+=Format;
  404.     fclose(fp);
  405. //reading done, pass as parameter to the call.
  406.     //create a call options object and set the parameters from the above variables.
  407. CallOptions optionsFromFile;
  408. if(FastStart=="0") optionsFromFile.noFastStart=true;
  409. else optionsFromFile.noFastStart=false;
  410.     
  411. if(Tunnel=="0") optionsFromFile.noH245Tunnelling=true;
  412. else optionsFromFile.noH245Tunnelling=false;
  413. if(SilenceDetection=="0") optionsFromFile.noSilenceSuppression=true;
  414. else optionsFromFile.noSilenceSuppression=false;
  415.     
  416. optionsFromFile.jitter=atoi(JitterBuffer);
  417. //optionsFromFile.jitter=endpoint->GetMaxAudioDelayJitter();
  418.     optionsFromFile.connectPort=H323ListenerTCP::DefaultSignalPort;
  419.     optionsFromFile.connectRing=0;
  420. /* PArgList strArgs(  "f-fast-disable."
  421.                        "T-h245tunneldisable."
  422.                        "e-silence."
  423.                        "j-jitter:"
  424.                        "-connectport:"
  425.                        "-connectring:" 
  426.    );
  427. */
  428.   //  optionsFromFile.Initialise(strArgs);
  429. endpoint->SetInitialBandwidth((unsigned)(call_bandwidth));
  430. endpoint->SetTCPPorts(atoi(TcpBasePort),atoi(TcpMaxPort));
  431. endpoint->SetUDPPorts(atoi(UdpBasePort),atoi(UdpMaxPort));
  432. endpoint->SetRtpIpPorts(atoi(RtpBasePort),atoi(RtpMaxPort));
  433.     //int gsmFrames = 4;
  434.   
  435. //endpoint->SetCapability(PINDEX descriptorNum, PINDEX simultaneous, H323Capability * cap ); 
  436.  if(endpoint->Initialise(PString(AudioCodec))){
  437.  //if(endpoint->Initialise(strArgs, 0, FALSE)){
  438.   //MessageBox("Calling Makecall");
  439.   //consoleStr+="rnCalling Makecall from Main";
  440.   //consoleStr+=ipAddress;
  441.   //endpoint->MakeOutgoingCall(ipAddress, ipAddress);
  442.   endpoint->MakeOutgoingCall(ipAddress, ipAddress,optionsFromFile);
  443.   H323Connection * connection = endpoint->FindConnectionWithLock(endpoint->currentCallToken);
  444.   TokenCurrentCall = endpoint->currentCallToken;
  445.   //connection->SendUserInput(str);
  446.   if (connection == NULL)
  447. return;
  448.   connection->Unlock();
  449.  } 
  450. }
  451. // This module will report statistic such as
  452. // Packet Loss, Round Trip Delay, Packet Out Of Order
  453. // The strange thing right now, is Statistic seems depend on
  454. // other peer (either client or server)
  455. // Before statistic can be collected, Call has to be 
  456. // establish first (FlagEndPoint == 0 means call already establish)
  457. // globalinstance != NULL and chan != NULL and session != NULL
  458. // are additional parameter. Reasons we have multiple check is
  459. // sometimes GetStatistic Thread being call before actual call
  460. // being establish. We want to prevent that from happening
  461. int BeaconClient::GetStatistics()
  462. {
  463.  
  464.   if (FlagEndPoint == 0)
  465.   {
  466.    if (globalInstance != NULL)
  467. {
  468.   H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(endpoint->currentCallToken);
  469.   //connection->SendUserInput(str);
  470.   if (connection == NULL)
  471.   
  472.   {
  473. //MessageBox(0,globalEndReason,"Beacon Client",MB_OK);
  474. //FlagEndPoint = 1;
  475. //Quit();
  476. return -1;
  477.   }
  478.   
  479.       H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
  480.   if (chan != NULL)
  481.   {
  482.    H323Codec * rawCodec  = chan->GetCodec();
  483.  
  484.    H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
  485.    AudioFrameRateGlobal = codec->GetFrameRate();  //Audio Codec
  486.       
  487.    RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
  488.    if (session != NULL)   
  489.    {
  490.       
  491.    
  492. //FlagEndPoint = 0;
  493.     StartTimeGlobal= connection->GetConnectionStartTime();
  494. StartTimeGlobalYear = StartTimeGlobal.GetYear();
  495. StartTimeGlobalMonth = StartTimeGlobal.GetMonth();
  496. StartTimeGlobalDay = StartTimeGlobal.GetDay();
  497.     StartTimeGlobalHour = StartTimeGlobal.GetHour();
  498.     StartTimeGlobalMinute = StartTimeGlobal.GetMinute();
  499.     StartTimeGlobalSecond = StartTimeGlobal.GetSecond();
  500.     RoundTripTimeDelayGlobal = connection->GetRoundTripDelay().GetMilliSeconds();
  501.   //DurationTimeGlobal = now - StartTimeGlobal;
  502.     PacketSentGlobal = session->GetPacketsSent();
  503.     OctetSendGlobal = session->GetOctetsSent();
  504.     MaximumSendTimeGlobal = session->GetMaximumSendTime();
  505.     AverageSendTimeGlobal = session->GetAverageSendTime();
  506.     MinimumSendTimeGlobal = session->GetMinimumSendTime();
  507.     PacketsReceivedGlobal = session->GetPacketsReceived();
  508.         OctetsReceivedGlobal = session->GetOctetsReceived();
  509.         MaximumReceiveTimeGlobal = session->GetMaximumReceiveTime();
  510.         AverageReceiveTimeGlobal = session->GetAverageReceiveTime();
  511.     MinimumReceiveTimeGlobal = session->GetMinimumReceiveTime();
  512.     PacketsLostGlobal = session->GetPacketsLost();
  513.         PacketsOutOfOrderGlobal = session->GetPacketsOutOfOrder();
  514.         PacketsOutTooLateGlobal = session->GetPacketsTooLate();
  515. // Please replace with  JitterTimeGlobal = session->GetJitterTimeTmp();
  516.    // JitterTimeGlobal = session->GetJitterTime();
  517. JitterTimeGlobal = session->GetJitterTimeTmp();
  518. PayloadTypeGlobal = session->GetPayLoadTypeFunc();
  519. GenerateStatistic = TRUE;
  520. // To Check Bandwidth being usage
  521. bandwidthAvailable = endpoint->GetInitialBandwidth();
  522. //return 0;
  523.    }  // Session != NULL
  524.    else
  525.    {
  526. //return -1;
  527.    }
  528.   } // Channel != NULL
  529.       connection->Unlock();
  530.   
  531.    }  // globalInstance != NULL
  532.   }   // FlagEndPoint != NULL
  533.   return 0;
  534. }
  535. BOOL CALLBACK cbGetTextWindow(HWND  hwnd, LPARAM  lParam )
  536. {
  537. /* save the value of the parent window */
  538. hwndParent = hwnd;
  539. /* check to see if it has a child text window */
  540. hwndText = FindWindowEx(hwnd, NULL, TEXTCLASS, NULL );
  541. /* if the text window was found, stop looking */
  542. return ( hwndText != NULL );
  543. }
  544. /* sends a string to the specified window */
  545. /* CRS: made this into a function call */
  546. void BeaconClient::PostString(HWND hwnd, CString pc1)
  547. {
  548. char *pc;
  549. pc = pc1.GetBuffer(pc1.GetLength());
  550. while( *pc ){
  551. PostMessage( hwnd, WM_CHAR, *pc, 1L );
  552. /* CRS: should add a check of return code on PostMessage. If 0, the 
  553.    message que was full and the message wasn't posted. */
  554. pc++;
  555. }
  556. }
  557. /* FindUnquotedSpace(): Search a string for the first space not enclosed in quotes.
  558.  *   Returns a pointer to the space, or the empty string if no space is found. 
  559.  *   -CRS 30061999  
  560.  */
  561. char* BeaconClient::FindUnquotedSpace( char *pc )
  562. {
  563. while ( (*pc) && (*pc != ' ') && (*pc != 't') ){
  564. if ( *pc == '"' ){
  565. do {
  566. pc++;
  567. } while ( (pc[1]) && (*pc != '"') );
  568. }
  569. pc++;
  570. }
  571. return pc;
  572. }
  573. int BeaconClient::PrepareGnuPlot()
  574. {
  575. strcpy(psGnuplotCommandLine,exeFolderPath);
  576. strcat(psGnuplotCommandLine,PROGNAME);
  577. /* HBB 19990325, to allow pgnuplot < script > output.gif */
  578. _setmode(fileno(stdout), _O_BINARY);
  579. /* CRS: create the new command line, passing all of the command
  580.  * line options to wgnuplot so that it can process them:
  581.  * first, get the command line,
  582.  * then move past the name of the program (e.g., 'pgnuplot'),
  583.  * finally, add what's left of the line onto the gnuplot command line. */
  584. psCmdLine = GetCommandLine();
  585. psCmdLine = "C:\gnuplot\wngnuplot.exe";
  586. #ifdef SHOWCMDLINE
  587. fprintf(stderr,"CmdLine: %sn", psCmdLine);
  588. fprintf(stderr,"argv[0]: %sn",argv[0]);
  589. #endif
  590. /* CRS 30061999: Search for the first unquoted space. This should 
  591.    separate the program name from the arguments. */
  592. psCmdLine = FindUnquotedSpace( psCmdLine );
  593. strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine));
  594.     
  595. #ifdef SHOWCMDLINE
  596. fprintf(stderr,"Arguments: %sn", psCmdLine);
  597. fprintf(stderr,"GnuplotCommandLine: %sn",psGnuplotCommandLine);
  598. #endif
  599. /* CRS: if stdin isn't redirected then just launch wgnuplot normally
  600.  * and exit. */
  601. /*
  602. if ( isatty(fileno(stdin)) ) {
  603. if ( WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31 ){
  604. exit(EXIT_SUCCESS);
  605. }
  606. fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n", 
  607.     GetLastError(), psGnuplotCommandLine);
  608. exit(EXIT_FAILURE);
  609. }
  610. */
  611. /* CRS: initialize the STARTUPINFO and call CreateProcess(). */ 
  612. siStartInfo.cb = sizeof(STARTUPINFO); 
  613. siStartInfo.lpReserved = NULL; 
  614. siStartInfo.lpReserved2 = NULL; 
  615. siStartInfo.cbReserved2 = 0; 
  616. siStartInfo.lpDesktop = NULL; 
  617. siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
  618. siStartInfo.wShowWindow = SW_HIDE;
  619. bSuccess = CreateProcess( 
  620. NULL,                   /* pointer to name of executable module   */
  621. psGnuplotCommandLine,   /* pointer to command line string         */
  622. NULL,                   /* pointer to process security attributes */
  623. NULL,                   /* pointer to thread security attributes  */
  624. FALSE,                  /* handle inheritance flag                */
  625. 0, /* creation flags                         */
  626. NULL,                   /* pointer to new environment block       */
  627. NULL,                   /* pointer to current directory name      */
  628. &siStartInfo,           /* pointer to STARTUPINFO                 */
  629. &piProcInfo             /* pointer to PROCESS_INFORMATION         */
  630. );
  631. /* if CreateProcess() failed, print a warning and exit. */
  632. if ( ! bSuccess ) {
  633. fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n", 
  634. GetLastError(), psGnuplotCommandLine);
  635. exit(EXIT_FAILURE);
  636. }
  637. /* CRS: give gnuplot enough time to start (1 sec.) */
  638. if ( WaitForInputIdle(piProcInfo.hProcess, 1000) ) {
  639. fprintf(stderr, "Timeout: gnuplot is not readyn");
  640. exit(EXIT_FAILURE);
  641. }
  642. /* CRS: get the HWND of the parent window and text windows */
  643. EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);
  644. /* CRS: free the process and thread handles */
  645. CloseHandle(piProcInfo.hProcess);
  646. CloseHandle(piProcInfo.hThread);
  647. if ( ! hwndParent || ! hwndText ) {
  648. /* Still no gnuplot window? Problem! */
  649. fprintf(stderr, "Can't find the gnuplot window");
  650. exit(EXIT_FAILURE);
  651. }
  652. /* wait for commands on stdin, and pass them on to the wgnuplot text
  653.  * window */
  654. /*
  655. while ( fgets(psBuffer, BUFFER_SIZE, stdin) != NULL ) {
  656. PostString(hwndText, psBuffer);
  657. }
  658. */
  659. /* Example */
  660. CString CurrentImageFile;
  661. CString strtmp1;
  662. CString strtmp2;
  663. CString strtmp3;
  664. //Packet Loss
  665. PostString(hwndText,"nresetn");
  666. PostString(hwndText,"nset title "Packet Loss for H.323 Beacon Test Session"n");
  667. PostString(hwndText,"nset data style linesn");
  668. PostString(hwndText,"nset xlabel "Test Session Time"n");
  669. PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
  670. PostString(hwndText,"nset yrange [0.0:]n");
  671. PostString(hwndText,"nset xdata timen");
  672. PostString(hwndText,"nset xrange [:]n");
  673. PostString(hwndText,"nset ylabel "Packet Loss %"n");
  674. PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
  675. PostString(hwndText,"nset gridn");
  676. PostString(hwndText,"nset key left n");
  677. PostString(hwndText,"nset key boxn");
  678. PostString(hwndText,"nset terminal png smalln");
  679. strtmp1 = "n set output "";
  680. strtmp2 = "\PacketLoss.png"n";
  681. if(atoi(SaveResult)==1){
  682. CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  683. }else {
  684. CurrentImageFile = strtmp1 + strtmp2;
  685. }
  686. //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  687. //PostString(hwndText,"nset output "PacketLoss.png"n");
  688. PostString(hwndText,CurrentImageFile);
  689. 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");
  690. // Save it in tmp folder
  691. //PostString(hwndText,"nreplotn");
  692. // Audio Jitter
  693. PostString(hwndText,"nresetn");
  694. PostString(hwndText,"nset title "Audio Jitter for H.323 Beacon Test Session"n");
  695. PostString(hwndText,"nset data style linesn");
  696. PostString(hwndText,"nset xlabel "Test Session Time"n");
  697. PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
  698. PostString(hwndText,"nset yrange [0.0:]n");
  699. PostString(hwndText,"nset xdata timen");
  700. PostString(hwndText,"nset xrange [:]n");
  701. PostString(hwndText,"nset ylabel "Audio Jitter ms"n");
  702. PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
  703. PostString(hwndText,"nset gridn");
  704. PostString(hwndText,"nset key left n");
  705. PostString(hwndText,"nset key boxn");
  706. PostString(hwndText,"nset terminal png smalln");
  707. strtmp1 = "n set output "";
  708. strtmp2 = "\AudioJitter.png"n";
  709. if(atoi(SaveResult)==1){
  710. CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  711. }else {
  712. CurrentImageFile = strtmp1 + strtmp2;
  713. }
  714. //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  715. PostString(hwndText,CurrentImageFile);
  716. 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");
  717. // Save it in tmp folder
  718. //PostString(hwndText,"nreplotn");
  719. PostString(hwndText,"nexitn");
  720. return 0;
  721. }
  722. int BeaconClient::PrepareGnuPlotLatency()
  723. {
  724. /* HBB 19990325, to allow pgnuplot < script > output.gif */
  725. _setmode(fileno(stdout), _O_BINARY);
  726. /* CRS: create the new command line, passing all of the command
  727.  * line options to wgnuplot so that it can process them:
  728.  * first, get the command line,
  729.  * then move past the name of the program (e.g., 'pgnuplot'),
  730.  * finally, add what's left of the line onto the gnuplot command line. */
  731. psCmdLine = GetCommandLine();
  732. psCmdLine = "C:\gnuplot\wngnuplot.exe";
  733. #ifdef SHOWCMDLINE
  734. fprintf(stderr,"CmdLine: %sn", psCmdLine);
  735. fprintf(stderr,"argv[0]: %sn",argv[0]);
  736. #endif
  737. /* CRS 30061999: Search for the first unquoted space. This should 
  738.    separate the program name from the arguments. */
  739. psCmdLine = FindUnquotedSpace( psCmdLine );
  740. strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine));
  741.     
  742. #ifdef SHOWCMDLINE
  743. fprintf(stderr,"Arguments: %sn", psCmdLine);
  744. fprintf(stderr,"GnuplotCommandLine: %sn",psGnuplotCommandLine);
  745. #endif
  746. /* CRS: if stdin isn't redirected then just launch wgnuplot normally
  747.  * and exit. */
  748. /*
  749. if ( isatty(fileno(stdin)) ) {
  750. if ( WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31 ){
  751. exit(EXIT_SUCCESS);
  752. }
  753. fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n", 
  754.     GetLastError(), psGnuplotCommandLine);
  755. exit(EXIT_FAILURE);
  756. }
  757. */
  758. /* CRS: initialize the STARTUPINFO and call CreateProcess(). */ 
  759. siStartInfo.cb = sizeof(STARTUPINFO); 
  760. siStartInfo.lpReserved = NULL; 
  761. siStartInfo.lpReserved2 = NULL; 
  762. siStartInfo.cbReserved2 = 0; 
  763. siStartInfo.lpDesktop = NULL; 
  764. siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
  765. siStartInfo.wShowWindow = SW_SHOWMINIMIZED;
  766. bSuccess = CreateProcess( 
  767. NULL,                   /* pointer to name of executable module   */
  768. psGnuplotCommandLine,   /* pointer to command line string         */
  769. NULL,                   /* pointer to process security attributes */
  770. NULL,                   /* pointer to thread security attributes  */
  771. FALSE,                  /* handle inheritance flag                */
  772. 0,                      /* creation flags                         */
  773. NULL,                   /* pointer to new environment block       */
  774. NULL,                   /* pointer to current directory name      */
  775. &siStartInfo,           /* pointer to STARTUPINFO                 */
  776. &piProcInfo             /* pointer to PROCESS_INFORMATION         */
  777. );
  778. /* if CreateProcess() failed, print a warning and exit. */
  779. if ( ! bSuccess ) {
  780. fprintf(stderr,"ERROR %u: Couldn't execute: "%s"n", 
  781. GetLastError(), psGnuplotCommandLine);
  782. exit(EXIT_FAILURE);
  783. }
  784. /* CRS: give gnuplot enough time to start (1 sec.) */
  785. if ( WaitForInputIdle(piProcInfo.hProcess, 1000) ) {
  786. fprintf(stderr, "Timeout: gnuplot is not readyn");
  787. exit(EXIT_FAILURE);
  788. }
  789. /* CRS: get the HWND of the parent window and text windows */
  790. EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);
  791. /* CRS: free the process and thread handles */
  792. CloseHandle(piProcInfo.hProcess);
  793. CloseHandle(piProcInfo.hThread);
  794. if ( ! hwndParent || ! hwndText ) {
  795. /* Still no gnuplot window? Problem! */
  796. fprintf(stderr, "Can't find the gnuplot window");
  797. exit(EXIT_FAILURE);
  798. }
  799. /* wait for commands on stdin, and pass them on to the wgnuplot text
  800.  * window */
  801. /*
  802. while ( fgets(psBuffer, BUFFER_SIZE, stdin) != NULL ) {
  803. PostString(hwndText, psBuffer);
  804. }
  805. */
  806. /* Example */
  807. CString CurrentImageFile;
  808. CString strtmp1;
  809. CString strtmp2;
  810. CString strtmp3;
  811. // Latency
  812. PostString(hwndText,"nresetn");
  813. PostString(hwndText,"nset terminal png smalln");
  814. PostString(hwndText,"nset title "Latency for H.323 Beacon Test Session"n");
  815. //PostString(hwndText,"nset output "Latency.png"n");
  816. PostString(hwndText,"nset data style linesn");
  817. PostString(hwndText,"nset xlabel "Test Session Time"n");
  818. PostString(hwndText,"nset timefmt "%Y-%m-%d_%H:%M:%S"n");
  819. PostString(hwndText,"nset yrange [0.0:]n");
  820. PostString(hwndText,"nset xdata timen");
  821. PostString(hwndText,"nset xrange [:]n");
  822. PostString(hwndText,"nset ylabel "Latency ms"n");
  823. PostString(hwndText,"nset format x "%d/%m/%Y\n%H:%M:%S"n");
  824. PostString(hwndText,"nset gridn");
  825. PostString(hwndText,"nset key left n");
  826. PostString(hwndText,"nset key boxn");
  827. //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");
  828. strtmp1 = "n set output "";
  829. strtmp2 = "\Latency.png"n";
  830. if(atoi(SaveResult)==1){
  831. CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  832. }else {
  833. CurrentImageFile = strtmp1 + strtmp2;
  834. }
  835. //CurrentImageFile = strtmp1 + currentTestFolder + strtmp2;
  836. PostString(hwndText,CurrentImageFile);
  837. 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");
  838. //PostString(hwndText,"nreplotn");
  839. PostString(hwndText,"nexitn");
  840. return 0;
  841. }
  842.    
  843. void BeaconClient::ConvertPngToBmp(CString filepath)
  844. {
  845. CxImage image;
  846. char *filename1;
  847.     CString tmpFileName;
  848. CString tmpFileName1;
  849. if(atoi(SaveResult)==1){
  850. tmpFileName = filepath + "\PacketLoss.png";
  851. tmpFileName1 = filepath + "\PacketLoss.bmp";
  852. }else {
  853. tmpFileName =  "PacketLoss.png";
  854. tmpFileName1 = "PacketLoss.bmp";
  855. }
  856. // Convert PacketLoss.png to PacketLoss.bmp
  857. filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
  858. image.Load(filename1,CXIMAGE_FORMAT_PNG);
  859. if (image.IsValid()) 
  860. {
  861. filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
  862. image.Save(filename1,CXIMAGE_FORMAT_BMP);
  863. }
  864. else
  865. {
  866. consoleStr+= "rn PacketLoss.png Not Valid!";
  867. }
  868. if(atoi(SaveResult)==1){
  869. tmpFileName = filepath + "\AudioJitter.png";
  870. tmpFileName1 = filepath + "\AudioJitter.bmp";
  871. }else {
  872. tmpFileName =  "AudioJitter.png";
  873. tmpFileName1 = "AudioJitter.bmp";
  874. }
  875. //tmpFileName = filepath + "\AudioJitter.png";
  876. //tmpFileName1 = filepath + "\AudioJitter.bmp";
  877. // Convert PacketLoss.png to PacketLoss.bmp
  878. filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
  879. image.Load(filename1,CXIMAGE_FORMAT_PNG);
  880. if (image.IsValid()) 
  881. {
  882. filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
  883. image.Save(filename1,CXIMAGE_FORMAT_BMP);
  884. }
  885. else
  886. {
  887. consoleStr+="rn AudioJitter.png Not Valid!";
  888. }
  889. if(atoi(SaveResult)==1){
  890. tmpFileName = filepath + "\Latency.png";
  891. tmpFileName1 = filepath + "\Latency.bmp";
  892. }else {
  893. tmpFileName =  "Latency.png";
  894. tmpFileName1 = "Latency.bmp";
  895. }
  896. //tmpFileName = filepath + "\Latency.png";
  897. //tmpFileName1 = filepath + "\Latency.bmp";
  898. // Convert PacketLoss.png to PacketLoss.bmp
  899. filename1 = tmpFileName.GetBuffer(tmpFileName.GetLength());
  900. image.Load(filename1,CXIMAGE_FORMAT_PNG);
  901. if (image.IsValid()) 
  902. {
  903. filename1 = tmpFileName1.GetBuffer(tmpFileName1.GetLength());
  904. image.Save(filename1,CXIMAGE_FORMAT_BMP);
  905. }
  906. else
  907. {
  908. consoleStr+="rnFile Latency.png Not Valid!";
  909. }
  910. }  
  911.    
  912.  
  913. int BeaconClient::CheckConnections()
  914. {
  915. if (FlagEndPoint == 0)
  916.   {
  917.    if (globalInstance != NULL)
  918. {
  919.   H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(endpoint->currentCallToken);
  920.   //connection->SendUserInput(str);
  921.   if (connection != NULL)
  922.   {   
  923.  
  924.   
  925.  
  926.   
  927.       H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
  928.   if (chan != NULL)
  929.   {
  930.    H323Codec * rawCodec  = chan->GetCodec();
  931.    H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
  932.    AudioFrameRateGlobal = codec->GetFrameRate();  //Audio Codec
  933.   
  934.       
  935.    RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
  936.    if (session != NULL)   
  937.    {
  938.    }  // Session != NULL
  939.   } // Channel != NULL
  940. else
  941. {
  942.   return -1;  // If Channel == NULL
  943. }
  944.  
  945.       connection->Unlock();
  946.   } // connection != NULL
  947.    }  // globalInstance != NULL
  948.   }   // FlagEndPoint != NULL
  949.   return 0;
  950. }
  951. void BeaconClient::Quit()
  952. {
  953. globalInstance->endpoint->ClearAllCalls();
  954. delete endpoint;
  955. //FlagEndPoint == 1, Call has been Cleared
  956. FlagEndPoint = 1;
  957. }
  958. ///////////////////////////////////////////////////////////////
  959. BOOL MyH323EndPoint::Initialise(PString AudioCodec)
  960. {
  961. uiState = uiDialtone;
  962. localVideoChannel = NULL;
  963. WORD port       = H323ListenerTCP::DefaultSignalPort;
  964. WORD listenPort = port;
  965. defaultCallOptions.jitter      = GetMaxAudioDelayJitter();
  966. defaultCallOptions.connectPort = port;
  967. defaultCallOptions.connectRing = 0;
  968. currentCallOptions = defaultCallOptions;
  969. terminateOnHangup    = 1;
  970. autoAnswer           = 0;
  971. videoPIP   = FALSE;
  972. videoSize = 0; //Default is small.
  973. isXJack = FALSE;
  974. lidDevice = NULL;
  975. #ifdef HAS_VBLASTER
  976. #endif
  977. #ifdef HAS_IXJ
  978. #endif
  979.     ringDelay = 5;
  980. int g711Frames = 30;
  981.    int gsmFrames = 4;
  982. //originals
  983. /* H323_GSM0610Capability * gsmCap; 
  984.   SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
  985.   gsmCap->SetTxFramesInPacket(gsmFrames);
  986.   MicrosoftGSMAudioCapability * msGsmCap;
  987.   SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
  988.   msGsmCap->SetTxFramesInPacket(gsmFrames);
  989.   H323_G711Capability * g711uCap;
  990.   SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
  991.   g711uCap->SetTxFramesInPacket(g711Frames);
  992.   H323_G711Capability * g711aCap;
  993.   SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
  994.   g711aCap->SetTxFramesInPacket(g711Frames);
  995.   
  996. //Added by Mukund
  997. //G723
  998. //H323_G7231Capability * g7231cap;
  999. //SetCapability(0, 0, g7231cap = new H323_G7231Capability());
  1000.   
  1001.   //G726
  1002. H323_G726_Capability * g726cap;
  1003. //SetCapability(0, 0, g726cap = new H323_G726_Capability(g726cap));
  1004. SetCapability(0, 0, g726cap = new H323_G726_Capability(*this, H323_G726_Capability::e_24k));
  1005. // SetCapability(0, 0, new H323_G726_Capability(H323_G726_Capability::e_32k));
  1006. // SetCapability(0, 0, new H323_G726_Capability(H323_G726_Capability::e_40k));
  1007. //G728
  1008. // SetCapability(0, 0, new H323_G728ACapability);
  1009. //G729 
  1010. H323_G729ACapability * g729aCap;
  1011. SetCapability(0, 0,g729aCap = new H323_G729ACapability);
  1012. //G722
  1013. // SetCapability(0, 0, new H323_G722Capability);
  1014. //MPEG
  1015. // SetCapability(0, 0, new H323_MPEGCapability);
  1016.  SetCapability(0, 0, new H323_LPC10Capability(*this));
  1017. */   
  1018.   static const char * const oldArgName[] = {
  1019. "g7231",   "g729",  "g728",  "gsm", "g711-ulaw", "g711-alaw"
  1020.   };
  1021.   
  1022.  // static const char * const capName[] = {
  1023. // "G.723.1", "G.729", "G.728", "GSM", "G.711-uLaw", "G.711-ALaw"
  1024.   //};
  1025.   
  1026.   static const char * const capName[] = {
  1027. "GSM-06.10{sw}", "MS-GSM{sw}","G.711-uLaw-64k", "G.711-ALaw-64k{sw}",
  1028. "G.726-24k{sw}", "G.729A{n/a}", "LPC-10{sw}"
  1029.   };
  1030.  consoleStr+= "rnSetting preferred codec:: ";
  1031.  consoleStr+=AudioCodec;  
  1032.   //PStringArray toReorder(7,capName);
  1033.   //PString temp;
  1034. fstream fs("Cap.dat",ios::out,filebuf::sh_none);
  1035.   if(AudioCodec=="GSM-06.10{sw}"){
  1036.   fs<<"Codec Option: 1 n";
  1037.   H323_GSM0610Capability * gsmCap; 
  1038.   SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
  1039.   gsmCap->SetTxFramesInPacket(gsmFrames);
  1040.   }else if(AudioCodec=="MS-GSM{sw}"){
  1041.   fs<<"Codec Option: 2 n";
  1042. MicrosoftGSMAudioCapability * msGsmCap;
  1043.   SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
  1044.   msGsmCap->SetTxFramesInPacket(gsmFrames);
  1045.  }else if(AudioCodec=="G.711-uLaw-64k{sw}"){
  1046.  fs<<"Codec Option: 3 n";;
  1047. H323_G711Capability * g711uCap;
  1048.   SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
  1049.   g711uCap->SetTxFramesInPacket(g711Frames);
  1050.   
  1051.   // temp = toReorder[1];
  1052. // toReorder[1] = toReorder[3];
  1053. // toReorder[3] = toReorder[1];
  1054.   }else if(AudioCodec=="G.711-ALaw-64k{sw}"){
  1055.  fs<<"Codec Option: 4 n";
  1056.   H323_G711Capability * g711aCap;
  1057.   SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
  1058.   g711aCap->SetTxFramesInPacket(g711Frames);
  1059.   // temp = toReorder[1];
  1060. // toReorder[1] = toReorder[4];
  1061. // toReorder[4] = toReorder[1];
  1062.   }else if(AudioCodec=="G.726-24k{sw}"){
  1063.  fs<<"Codec Option: 5 n";
  1064.   H323_G726_Capability * g726cap;
  1065. //SetCapability(0, 0, g726cap = new H323_G726_Capability(g726cap));
  1066. SetCapability(0, 0, g726cap = new H323_G726_Capability(*this, H323_G726_Capability::e_24k));
  1067.   // temp = toReorder[1];
  1068. // toReorder[1] = toReorder[5];
  1069. // toReorder[5] = toReorder[1];
  1070.   }else if(AudioCodec=="G.729A{n/a}"){
  1071.    fs<<"Codec Option: 6 n";
  1072. H323_G729ACapability * g729aCap;
  1073. SetCapability(0, 0,g729aCap = new H323_G729ACapability);
  1074.   
  1075.   // temp = toReorder[1];
  1076. // toReorder[1] = toReorder[6];
  1077. // toReorder[6] = toReorder[1];
  1078.   }else if(AudioCodec=="LPC-10{sw}"){
  1079.  fs<<"Codec Option: 7 n";
  1080.   
  1081.   SetCapability(0, 0, new H323_LPC10Capability(*this));// temp = toReorder[1];
  1082. // toReorder[1] = toReorder[7];
  1083. // toReorder[7] = toReorder[1];
  1084.   }
  1085.   //toReorder[toReorder.GetSize()] = AudioCodec;
  1086.   //FILE * fp ;
  1087.   //fp = fopen("Cap.dat","w");
  1088.   //fstream fs("Cap.dat",ios::out,filebuf::sh_none);
  1089.   capabilities.PrintOn(fs);
  1090.  // capabilities.Reorder(toReorder);
  1091.   fs<<"Adding cap to  tablen";
  1092.   
  1093.   //close(fs);
  1094.   H323_UserInputCapability::AddAllCapabilities(capabilities, 0, P_MAX_INDEX);
  1095.   //SetCapability(0, P_MAX_INDEX, new H323_T120Capability);
  1096. capabilities.PrintOn(fs);
  1097.   
  1098.   PStringArray interfaceList;
  1099. PString interfacePrintable;
  1100. PIPSocket::Address interfaceAddress(INADDR_ANY);
  1101. interfacePrintable = psprintf("ALL:%i", listenPort);
  1102.   ringThread = NULL;
  1103.   autoDisconnect = 0;
  1104. return TRUE;
  1105. }
  1106. BOOL MyH323EndPoint::Initialise(PConfigArgs & args, int _verbose, BOOL _hasMenu)
  1107. {
  1108.   PINDEX i;
  1109.   verbose = _verbose;
  1110.   hasMenu = _hasMenu;
  1111.   uiState = uiDialtone;
  1112.   localVideoChannel = NULL;
  1113.   // get ports
  1114.   WORD port       = H323ListenerTCP::DefaultSignalPort;
  1115.   WORD listenPort = port;
  1116.   defaultCallOptions.jitter      = GetMaxAudioDelayJitter();
  1117.   defaultCallOptions.connectPort = port;
  1118.   defaultCallOptions.connectRing = 0;
  1119.   currentCallOptions = defaultCallOptions;
  1120.   //////////
  1121.   terminateOnHangup    = 1;
  1122.   autoAnswer           = 0;
  1123.  
  1124.   alwaysForwardParty   = args.GetOptionString('F');
  1125.   busyForwardParty     = args.GetOptionString('B');
  1126.   noAnswerForwardParty = args.GetOptionString('N');
  1127.   noAnswerTime         = args.GetOptionString("answer-timeout", "30").AsUnsigned();
  1128.   dialAfterHangup      = args.HasOption("dial-after-hangup");
  1129.   setupParameter       = args.GetOptionString("setup-param");
  1130.   
  1131.   if (verbose >= 3) {
  1132.     cout << "Local username: " << GetLocalUserName() << "n"
  1133.          << "TerminateOnHangup is " << terminateOnHangup << "n"
  1134.          << "Auto answer is " << autoAnswer << "n"
  1135.          << "DialAfterHangup is " << dialAfterHangup << "n"
  1136.          << defaultCallOptions
  1137.          << endl;
  1138.   }
  1139.   videoPIP   = FALSE;
  1140.   videoSize = 0; //Default is small.
  1141.   if (verbose >= 3) {
  1142.     if (videoReceiveDevice.IsEmpty())
  1143.       cout << "Video receive disabled" << endl << endl;
  1144.     else {
  1145.       cout << "Video receive using device : " << videoReceiveDevice << endl;
  1146.       cout << "Video receive quality hint : " << videoQuality << endl << endl;
  1147.     }
  1148.     if (!autoStartTransmitVideo)
  1149.       cout << "Video transmit disabled" << endl << endl;
  1150.  
  1151.   }
  1152.   isXJack = FALSE;
  1153.   lidDevice = NULL;
  1154. #ifdef HAS_VBLASTER
  1155. #endif
  1156. #ifdef HAS_IXJ
  1157. #endif
  1158.     ringDelay = 5;
  1159. #if defined(HAS_LIDDEVICE)
  1160.   if ((lidDevice == NULL) || !lidDevice->IsOpen() ) {
  1161. #endif
  1162.  
  1163.     if (verbose >= 3)
  1164.       cout << "Sound output device: "" << GetSoundChannelPlayDevice() << ""n"
  1165.               "Sound  input device: "" << GetSoundChannelRecordDevice() << ""n";
  1166. #if defined(HAS_LIDDEVICE)
  1167.   } // endif
  1168. #endif
  1169.  
  1170. #if defined(HAS_LIDDEVICE)
  1171.  
  1172. #endif
  1173.   int g711Frames = 30;
  1174.   
  1175.   int gsmFrames = 4;
  1176.   
  1177.   if (verbose >= 3) {
  1178.     cout <<"G.711 frame size: " << g711Frames << endl;
  1179.     cout <<"GSM frame size: " << gsmFrames << endl;
  1180.   }
  1181. //originals
  1182.   H323_GSM0610Capability * gsmCap; 
  1183.   SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
  1184.   gsmCap->SetTxFramesInPacket(gsmFrames);
  1185.   MicrosoftGSMAudioCapability * msGsmCap;
  1186.   SetCapability(0, 0, msGsmCap = new MicrosoftGSMAudioCapability);
  1187.   msGsmCap->SetTxFramesInPacket(gsmFrames);
  1188.   H323_G711Capability * g711uCap;
  1189.   SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
  1190.   g711uCap->SetTxFramesInPacket(g711Frames);
  1191.   H323_G711Capability * g711aCap;
  1192.   SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
  1193.   g711aCap->SetTxFramesInPacket(g711Frames);
  1194.   
  1195.   SetCapability(0, 0, new H323_LPC10Capability(*this));
  1196.   PStringArray toRemove = args.GetOptionString('D').Lines();
  1197.   PStringArray toReorder = args.GetOptionString('P').Lines();
  1198.   static const char * const oldArgName[] = {
  1199.     "g7231",   "g729",  "g728",  "gsm", "g711-ulaw", "g711-alaw"
  1200.   };
  1201.   static const char * const capName[] = {
  1202.     "G.723.1", "G.729", "G.728", "GSM", "G.711-uLaw", "G.711-ALaw"
  1203.   };
  1204.  
  1205.   for (i = 0; i < PARRAYSIZE(oldArgName); i++) {
  1206.     if (args.HasOption(PString("no-")+oldArgName[i]))
  1207.       toRemove[toRemove.GetSize()] = capName[i];
  1208.     if (args.HasOption(oldArgName[i]))
  1209.       toReorder[toReorder.GetSize()] = capName[i];
  1210.   }
  1211.   capabilities.Remove(toRemove);
  1212.   capabilities.Reorder(toReorder);
  1213.   
  1214.   //AddCapability puts the codec into the list of codecs we can send
  1215.   //SetCapability puts the codec into the list of codecs we can send and receive
  1216.   H323_UserInputCapability::AddAllCapabilities(capabilities, 0, P_MAX_INDEX);
  1217.   //SetCapability(0, P_MAX_INDEX, new H323_T120Capability);
  1218.   if (verbose >= 4)
  1219.     cout <<  "Codecs (in preference order):n" << setprecision(2) << capabilities << endl << endl;
  1220. PStringArray interfaceList;
  1221. PString interfacePrintable;
  1222.     PIPSocket::Address interfaceAddress(INADDR_ANY);
  1223.     interfacePrintable = psprintf("ALL:%i", listenPort);
  1224.   if (verbose >= 3) 
  1225.     cout << "Listening interfaces : " << interfacePrintable << endl;
  1226.   ringThread = NULL;
  1227.   autoDisconnect = 0;
  1228.   return TRUE;
  1229. }
  1230. /* New One */
  1231. H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
  1232. {
  1233.   unsigned options = 0;
  1234.   if (currentCallOptions.noFastStart)
  1235.     options |= H323Connection::FastStartOptionDisable;
  1236.   if (currentCallOptions.noH245Tunnelling)
  1237.     options |= H323Connection::H245TunnelingOptionDisable;
  1238.   /*
  1239.   if (currentCallOptions.noH245InSetup)
  1240.     options |= H323Connection::H245inSetupOptionDisable;
  1241. */
  1242.   return new MyH323Connection(*this, callReference,
  1243.                               options,
  1244.                               (WORD)currentCallOptions.jitter,
  1245.                               verbose);
  1246. }
  1247. /* Old */
  1248. /*
  1249. H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
  1250. {
  1251.   return new MyH323Connection(*this, callReference,
  1252.                               currentCallOptions.noFastStart,
  1253.                               currentCallOptions.noH245Tunnelling,
  1254.                               (WORD)currentCallOptions.jitter,
  1255.                               verbose);
  1256. }
  1257. */
  1258. void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection,
  1259.                                              const PString & /*token*/)
  1260. {
  1261.   cout << "Call with "" << connection.GetRemotePartyName() << "" established." << endl;
  1262.   uiState = uiCallInProgress;
  1263. }
  1264. void MyH323EndPoint::OnAutoDisconnect(PTimer &, INT)
  1265. {
  1266.   if (currentCallToken.IsEmpty()) 
  1267.     cout << "Autodisconnect occurred without current call token" << endl;
  1268.   else {
  1269.     ClearCall(currentCallToken);
  1270.     cout << "Autodisconnect triggered" << endl;
  1271.   }
  1272. }
  1273. void MyH323EndPoint::TriggerDisconnect()
  1274. {
  1275.   // we have an autodisconnect timer specified, start the timer
  1276.   if (autoDisconnect <= 0)
  1277.     PTRACE(2, "MaintAuto disconnect not triggered");
  1278.   else {
  1279.     PTRACE(2, "MaintAuto disconnect triggered");
  1280.     autoDisconnectTimer.SetNotifier(PCREATE_NOTIFIER(OnAutoDisconnect));
  1281.     autoDisconnectTimer = PTimeInterval(autoDisconnect * 100);
  1282.   }
  1283. }
  1284. void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
  1285. {
  1286.   // stop any ringing that is occurring
  1287.   StopRinging();
  1288.   // ignore connections that are not the current connection
  1289.   if (clearedCallToken != currentCallToken)
  1290.     return;
  1291.   // update values for current call token and call forward call token:
  1292.   if (!callTransferCallToken) {
  1293.     // after clearing the first call during a call proceeding,
  1294.     // the call transfer call token becomes the new call token
  1295.     currentCallToken = callTransferCallToken;
  1296.     callTransferCallToken = PString();
  1297.   }
  1298.   else
  1299.     currentCallToken = PString(); // indicate that our connection is now cleared
  1300.   // indicate call has hungup
  1301.   uiState = uiCallHungup;
  1302.   if (verbose != 0) {
  1303.     BOOL printDuration = TRUE;
  1304.     PString remoteName = '"' + connection.GetRemotePartyName() + '"';
  1305.     switch (connection.GetCallEndReason()) {
  1306.       case H323Connection::EndedByCallForwarded :
  1307.         printDuration = FALSE;   // Don't print message here, was printed when forwarded
  1308.         break;
  1309.       case H323Connection::EndedByRemoteUser :
  1310. globalEndReason = "Remote User has cleared call";
  1311.         cout << remoteName << " has cleared the call";
  1312.         break;
  1313.       case H323Connection::EndedByCallerAbort :
  1314. globalEndReason = "Has stopped calling";
  1315.         cout << remoteName << " has stopped calling";
  1316.         break;
  1317.       case H323Connection::EndedByRefusal :
  1318. globalEndReason = "Remote H.323 Beacon Server did not accept your test session!";
  1319.         cout << remoteName << " did not accept your call";
  1320.         break;
  1321.       case H323Connection::EndedByRemoteBusy :
  1322. globalEndReason = "Remote H.323 Beacon Server was busy!";
  1323.         cout << remoteName << " was busy";
  1324.         break;
  1325.       case H323Connection::EndedByRemoteCongestion :
  1326. globalEndReason = "congested link to remote H.323 Beacon Server!";
  1327.         cout << "Congested link to " << remoteName;
  1328.         break;
  1329.       case H323Connection::EndedByNoAnswer :
  1330. globalEndReason = "No H.323 peer is running at remote site!";
  1331.         cout << remoteName << " did not answer your call";
  1332.         break;
  1333.       case H323Connection::EndedByTransportFail :
  1334. globalEndReason = "Remote H.323 Beacon Server has ended the Test Session!";
  1335.         cout << "Call with " << remoteName << " ended abnormally";
  1336.         break;
  1337.       case H323Connection::EndedByCapabilityExchange :
  1338. globalEndReason = "Could not find common codec with remote H.323 Beacon Server!";
  1339.         cout << "Could not find common codec with " << remoteName;
  1340.         break;
  1341.       case H323Connection::EndedByNoAccept :
  1342. globalEndReason = "Did not accept incoming call from remote H.323 Beacon Server!";
  1343.         cout << "Did not accept incoming call from " << remoteName;
  1344.         break;
  1345.       case H323Connection::EndedByAnswerDenied :
  1346. globalEndReason = "Refused incoming call from remote H.323 Beacon Server!";
  1347.         cout << "Refused incoming call from " << remoteName;
  1348.         break;
  1349.       case H323Connection::EndedByNoUser :
  1350. globalEndReason = "Gatekeeper could not find user with remoteName";
  1351.         cout << "Gatekeeper could find user " << remoteName;
  1352.         break;
  1353.       case H323Connection::EndedByNoBandwidth :
  1354. globalEndReason = "aborted, insufficient bandwidth";
  1355.         cout << "Call to " << remoteName << " aborted, insufficient bandwidth.";
  1356.         break;
  1357.       case H323Connection::EndedByUnreachable :
  1358. globalEndReason = "Remote H.323 Beacon Server Could not be reached!";
  1359.         cout << remoteName << " could not be reached.";
  1360.         break;
  1361.       case H323Connection::EndedByHostOffline :
  1362. 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";
  1363.         cout << remoteName << " is not online.";
  1364.         break;
  1365.       case H323Connection::EndedByNoEndPoint :
  1366.  globalEndReason = "The Remote H.323 Beacon Server is not Online!";
  1367.         cout << "No phone running for " << remoteName;
  1368.         break;
  1369.       case H323Connection::EndedByConnectFail :
  1370. globalEndReason = "Please enter a valid IP Address!";
  1371.         cout << "Transport error calling (Possible Cause: No IP Address Entered)" << remoteName;
  1372.         break;
  1373.       default :
  1374. globalEndReason = "Call with remote H.323 Beacon Server completed!";
  1375. globalEndReason = "";
  1376.         cout << "Call with " << remoteName << " completed";
  1377.     }
  1378.     PTime connectTime = connection.GetConnectionStartTime();
  1379.     if (printDuration && connectTime.GetTimeInSeconds() != 0)
  1380.       cout << ", duration "
  1381.            << setprecision(0) << setw(5)
  1382.            << (PTime() - connectTime)
  1383.            << endl;
  1384.   }
  1385.   if (!hasMenu && terminateOnHangup) {
  1386.     exitFlag.Signal();
  1387.   }
  1388. }
  1389. BOOL MyH323EndPoint::OpenAudioChannel(H323Connection & connection,
  1390.                                          BOOL isEncoding,
  1391.                                          unsigned bufferSize,
  1392.                                          H323AudioCodec & codec)
  1393. {
  1394. #if defined(HAS_LIDDEVICE)
  1395.   if ((lidDevice != NULL) && lidDevice->IsOpen()) {
  1396.     PTRACE(2, "xJacktAttaching channel to codec");
  1397.     if (!codec.AttachChannel(new OpalLineChannel(*lidDevice, POTS_LINE, codec)))
  1398.       return FALSE;
  1399.   }
  1400.   else
  1401. #endif
  1402.   if (!H323EndPoint::OpenAudioChannel(connection, isEncoding, bufferSize, codec)) {
  1403.     cerr << "Could not open sound device ";
  1404.     if (isEncoding)
  1405.       cerr << GetSoundChannelRecordDevice();
  1406.     else
  1407.       cerr << GetSoundChannelPlayDevice();
  1408.     cerr << " - Check permissions or full duplex capability." << endl;
  1409.     return FALSE;
  1410.   }
  1411.   codec.SetSilenceDetectionMode(currentCallOptions.noSilenceSuppression ?
  1412.                                    H323AudioCodec::NoSilenceDetection :
  1413.                                    H323AudioCodec::AdaptiveSilenceDetection);
  1414.   return TRUE;
  1415. }
  1416. BOOL MyH323EndPoint::OpenVideoChannel(H323Connection & connection,
  1417.                                      BOOL isEncoding,
  1418.                                      H323VideoCodec & codec)
  1419. {
  1420.   PVideoChannel      * channel = new PVideoChannel;
  1421.   PVideoOutputDevice * device  = NULL;
  1422.   PVideoInputDevice  * grabber = NULL;
  1423.   
  1424.   PString nameStr = isEncoding ? PString("Local") : 
  1425.                                  connection.GetRemotePartyName();
  1426.   if (isEncoding) {
  1427.     PAssert(autoStartTransmitVideo, "video encoder created without enable");
  1428.     codec.SetTxQualityLevel(videoTxQuality);
  1429.     codec.SetBackgroundFill(videoFill);   
  1430.     codec.SetAverageBitRate(videoBitRate);
  1431.     unsigned newFrameWidth,newFrameHeight;              
  1432.     newFrameWidth =  352>>(1-videoSize);                
  1433.     newFrameHeight = 288>>(1-videoSize);                
  1434.     if (videoFake)
  1435.       grabber = new PFakeVideoInputDevice();
  1436.     else
  1437.       grabber = new PVideoInputDevice();
  1438.     
  1439.     PTRACE(3,"Attempt to open videoDevice "<<videoDevice<<" for reading."); 
  1440.     if ( !grabber->Open(videoDevice, FALSE)) {
  1441.       PTRACE(3,"Failed to open the camera device");
  1442.       goto errVideo;
  1443.     }
  1444.     if ( !grabber->SetVideoFormat(
  1445.          videoIsPal ? PVideoDevice::PAL : PVideoDevice::NTSC)) {
  1446.       PTRACE(3,"Failed to set format to " << (videoIsPal ? "PAL" : "NTSC"));
  1447.       goto errVideo;
  1448.     }
  1449.     if ( !grabber->SetChannel(videoInput) ) {
  1450.       PTRACE(3,"Failed to set channel to "<<videoInput);
  1451.       goto errVideo;
  1452.     }
  1453.     if (!(pfdColourFormat.IsEmpty()))
  1454.       grabber->SetPreferredColourFormat(pfdColourFormat);
  1455.     if ( !grabber->SetColourFormatConverter("YUV420P") ) {
  1456.       PTRACE(3,"Failed to set format to yuv420p");
  1457.       goto errVideo;
  1458.     }
  1459.     if (  !grabber->SetFrameRate(videoFramesPS)) {
  1460.       PTRACE(3,"Failed to set framerate to " << videoFramesPS );
  1461.       goto errVideo;
  1462.     }
  1463.     if  ( !grabber->SetFrameSizeConverter(newFrameWidth,newFrameHeight,FALSE) ) {
  1464.       PTRACE(3, "Failed to set framesize to "<<newFrameWidth<<"x"<<newFrameHeight);
  1465.       goto errVideo;
  1466.     }
  1467.     PTRACE(3,"OpenVideoChannelt done. Successfully opened a video camera");
  1468.     goto exitVideo;
  1469.  
  1470.   errVideo:
  1471.     delete grabber;
  1472.     grabber = (PVideoInputDevice *) new PFakeVideoInputDevice(); //This one never fails.
  1473.     grabber->SetColourFormat("YUV420P");
  1474.     grabber->SetVideoFormat(PVideoDevice::PAL);  // not actually used for fake video.
  1475.     grabber->SetChannel(100);     //NTSC test image.
  1476.     grabber->SetFrameRate(0);     //Select default frame rate.
  1477.     grabber->SetFrameSize(newFrameWidth,newFrameHeight);
  1478.     PTRACE(3,"Made a fictitious video camera showing NTSC test frame");
  1479.  
  1480.   exitVideo:
  1481.     grabber->Start();
  1482.     channel->AttachVideoReader(grabber);
  1483.   }
  1484.   if ((!isEncoding) || videoLocal) {
  1485.     PAssert(!videoReceiveDevice.IsEmpty(), "video display created without device type");
  1486. #ifdef HAS_SDL
  1487.      // Dump received video to SDL 
  1488.      if (videoReceiveDevice *= "sdl")
  1489.        device = new SDLVideoDevice(nameStr,isEncoding,videoPIP);
  1490. #endif
  1491. #ifdef HAS_X11
  1492.     // Dump received video to X11 window
  1493.     if (videoReceiveDevice.Left(3) *= "x11") {
  1494.       PString str = videoReceiveDevice;
  1495.       BOOL shared = str.Right(1) *= "s";
  1496.       str = str.Mid(3);
  1497.       if (!shared)
  1498.          device = new XlibVideoDevice(nameStr,isEncoding,videoPIP);
  1499.       else {
  1500.         str = str.Left(str.GetLength()-1); 
  1501.         device = new ShmXlibVideoDevice(nameStr,isEncoding,videoPIP);
  1502.       }
  1503.       int depth = str.AsInteger();
  1504.       if (depth > 0) 
  1505.         ((GenericXlibVideoDevice *)device)->ForceDepth(depth);
  1506.     }
  1507. #endif
  1508. #ifdef WIN32
  1509.     // code to specify windows 32 display device,
  1510.     // which uses MS windows conversion routines.
  1511. #endif
  1512.     // Dump video to PPM files
  1513.     //can have two ppm video devices. 99==local    00==received.
  1514.     if (videoReceiveDevice *= "ppm")
  1515.       device = new PPMVideoOutputDevice(isEncoding? 99:0);
  1516.   }
  1517. #ifdef HAS_VGALIB    //vgalib can only do receive video device.
  1518.   if (!isEncoding) {
  1519.      // Dump received video to VGA 
  1520.      if (videoReceiveDevice *= "svga")
  1521.        device = new LinuxSVGAFullOutputDevice();
  1522.      else if (videoReceiveDevice *= "svga256")
  1523.        device = new LinuxSVGA256OutputDevice();
  1524.   }
  1525. #endif
  1526.   // Dump video to nowhere
  1527.   if ((videoReceiveDevice *= "null") || (isEncoding&&(!videoLocal))) 
  1528.     device = new NullVideoOutputDevice();
  1529.   if (device == NULL)  
  1530.     PError << "unknown video output device "" << videoReceiveDevice << """ << endl;
  1531.   PAssert(device != NULL, "NULL video device");
  1532.   
  1533.   PTRACE(3,"device->SetFrameSize(" 
  1534.  << codec.GetWidth() << "," << codec.GetHeight() << ") from codec");
  1535.   //NB cannot resize receive video window if the following line is used
  1536.   //device->SetFrameSize(352>>(1-videoSize), 288>>(1-videoSize));
  1537.   device->SetFrameSize(codec.GetWidth(), codec.GetHeight()); // needed to enable resize
  1538.   channel->AttachVideoPlayer(device);
  1539.  
  1540.   //Select true, delete video chanel on closing codec.
  1541.   
  1542.   return codec.AttachChannel(channel,TRUE);
  1543.   
  1544. return TRUE;
  1545. }
  1546. ///////////////////////////////////////////////////////////////////////////////
  1547. /*
  1548. BOOL MyH323EndPoint::OpenVideoChannel(H323Connection & connection,
  1549.                                          BOOL isEncoding,
  1550.                                          H323VideoCodec & codec)
  1551. {
  1552.   PVideoChannel   * channel = new PVideoChannel;
  1553.   // a H323VideoDevice * displayDevice;
  1554.   if (isEncoding) 
  1555.   {
  1556.     PConfig config;
  1557.     
  1558.     //codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,1));
  1559. codec.SetTxQualityLevel(1); /**Quality of the transmitted video. 1 is good, 31 is poor.
  1560.     codec.SetBackgroundFill(2);
  1561.     //Create grabber.
  1562.     PVideoInputDevice * grabber = new PVideoInputDevice();
  1563.     PStringList devices = grabber->GetDeviceNames();
  1564.     PString deviceName;
  1565. // Modified, so it just use whatever the "FIRST" available video hardware
  1566.     if (devices.IsEmpty())
  1567.       deviceName = "Frame test N.0 - Moving line";
  1568.     else
  1569.       deviceName = grabber->GetDeviceNames()[0];
  1570.     //deviceName = config.GetString(VideoDeviceConfigKey, deviceName);
  1571. // Modified, so it does not use any config files
  1572.     //if (!grabber->Open(deviceName, FALSE) ||
  1573.     //    !grabber->SetVideoFormat((PVideoDevice::VideoFormat)config.GetInteger(VideoFormatConfigKey, PVideoDevice::Auto)) ||
  1574.     //    !grabber->SetChannel(config.GetInteger(VideoSourceConfigKey,1)) ||
  1575.     //   !grabber->SetColourFormatConverter("YUV420P") ||
  1576.     //    !grabber->SetFrameSize(videoWidth, videoHeight) ||
  1577.     //    !grabber->SetVFlipState(localFlip)) 
  1578.   if (!grabber->Open(deviceName, FALSE) ||
  1579.   !grabber->SetVideoFormat(PVideoDevice::Auto) ||  // Set Video Format to be Auto
  1580.   !grabber->SetChannel(1) ||  // Set Channel to be 1
  1581.   !grabber->SetColourFormatConverter("YUV420P") ||
  1582.   !grabber->SetFrameSize(180, 180) ||  // videoWidth = 180, videoHeight = 180 // To be fit in Dialog Audio Video
  1583.   !grabber->SetVFlipState(TRUE))
  1584. {
  1585.       PTRACE(1, "Failed to open or configure the video device "" << deviceName << '"');
  1586.       delete grabber;
  1587.       grabber = new PFakeVideoInputDevice();
  1588.       grabber->SetColourFormat("YUV420P");
  1589.       grabber->SetVideoFormat(PVideoDevice::PAL);
  1590.       grabber->SetFrameSize(180, 180);
  1591.       grabber->SetVFlipState(FALSE);
  1592.       grabber->SetChannel(atoi(&deviceName[13]));
  1593.     }
  1594.     grabber->Start();
  1595.     channel->AttachVideoReader(grabber);
  1596. // Always play it in Dialog Audio Video Window
  1597.    //a if (localVideo)
  1598. //a {
  1599. // Replace this, so it can play on Beacon Client Video
  1600.       //adisplayDevice = new VideoDevice(mainWindow, TRUE, connection.GetLocalPartyName(), FALSE);
  1601. //a }
  1602.     //a else
  1603. //a {
  1604.      //a displayDevice = new NullVideoOutputDevice;
  1605. //a }
  1606.   }
  1607.   else
  1608.     // Replace this, so it can play on Beacon Client Video
  1609. //displayDevice = new VideoDevice(mainWindow, FALSE, connection.GetRemotePartyName(), remoteFlip);
  1610.   // a displayDevice->SetFrameSize(180, 180);  // videowidth = 180, videoheight = 180
  1611.  
  1612.   //Give the video window (which plays video) to the channel.
  1613.   // a channel->AttachVideoPlayer(displayDevice);
  1614.   //return codec.AttachChannel(channel,TRUE);
  1615.   return TRUE;
  1616. }
  1617. */
  1618. //
  1619. //  if gateway is empty, then dest is assumed to be a IP address and optional port
  1620. //  if gateway is non-empty, then gateway is assumed to be an IP address and optional port, and
  1621. //  dest is passed to the gateway as the e164 address
  1622. //
  1623. void MyH323EndPoint::MakeOutgoingCall(const PString & dest,
  1624.                                       const PString & gateway)
  1625. {
  1626. // consoleStr+="rnInside Makeoutgoing call with default parameters";
  1627.   MakeOutgoingCall(dest, gateway, defaultCallOptions);
  1628. }
  1629. void MyH323EndPoint::MakeOutgoingCall(const PString & dest,
  1630.                                       const PString & gateway,
  1631.                                       CallOptions callOptions)
  1632. {
  1633. // consoleStr+="rn Inside Makeoutgoingcall with call options";
  1634. //consoleStr+=
  1635.   currentCallOptions = callOptions;
  1636.   PString fullAddress;
  1637.   if (!gateway)
  1638.     fullAddress = gateway;
  1639.   else 
  1640.     fullAddress = dest;
  1641.   if ((fullAddress.Find(':') == P_MAX_INDEX) && (callOptions.connectPort != H323ListenerTCP::DefaultSignalPort))
  1642.     fullAddress += psprintf(":%i", currentCallOptions.connectPort);
  1643.   if (!gateway)
  1644.     fullAddress = dest.Trim() + '@' + fullAddress;
  1645.   if (!MakeCall(fullAddress, currentCallToken)) {
  1646.     cout << "Error making call to "" << fullAddress << '"' << endl;
  1647.     return;
  1648.   }
  1649.   PConfig config("Calls");
  1650.   int index = config.GetInteger("index");
  1651.   PString lastCalledParty = config.GetString(PString(PString::Unsigned, index));
  1652.   index = (index + 1) % LAST_CALL_COUNT;
  1653.   PTime now;
  1654.   PString indexStr = PString(PString::Unsigned, index);
  1655.   config.SetString(indexStr,           fullAddress);
  1656.   config.SetString(indexStr + "_Time", now.AsString());
  1657.   config.SetString("index",            indexStr);
  1658.   cout << GetLocalUserName() << " is calling host " << fullAddress << endl;
  1659.   uiState = uiConnectingCall;
  1660. }
  1661. //
  1662. // StartCall accepts any of the following types of arguments
  1663. //    speedial '#'      lookup the string in the registry, and continue processing
  1664. //    ipaddress         dial this IP address or hostname
  1665. //    num ' ' gateway   dial the number using the specified gateway
  1666. //    
  1667. void MyH323EndPoint::StartCall(const PString & ostr)
  1668. {
  1669.   PString str = ostr.Trim();
  1670.   if (str.IsEmpty()) 
  1671.     cout << "Must supply hostname to connect to!n";
  1672.   CallOptions callOptions = defaultCallOptions;
  1673.   // check for speed dials, and match wild cards as we go
  1674.   PString key, prefix;
  1675.   if ((str.GetLength() > 1) && (str[str.GetLength()-1] == '#')) {
  1676.     key = str.Left(str.GetLength()-1).Trim();
  1677.     str = PString();
  1678.     PConfig config("Speeddial");
  1679.     PINDEX p;
  1680.     for (p = key.GetLength(); p > 0; p--) {
  1681.       PString newKey = key.Left(p);
  1682.       prefix = newKey;
  1683.       PINDEX q;
  1684.       // look for wild cards
  1685.       str = config.GetString(newKey + '*').Trim();
  1686.       if (!str.IsEmpty())
  1687.         break;
  1688.       // look for digit matches
  1689.       for (q = p; q < key.GetLength(); q++)
  1690.         newKey += '?';
  1691.       str = config.GetString(newKey).Trim();
  1692.       if (!str.IsEmpty())
  1693.         break;
  1694.     }
  1695.     if (str.IsEmpty()) {
  1696.       cout << "Speed dial "" << key << "" not defined";
  1697.       if (gatekeeper != NULL) {
  1698.         cout << ", trying gatekeeper ..." << endl;
  1699.         MakeOutgoingCall(key, PString(), callOptions);
  1700.         return;
  1701.       }
  1702.       else
  1703.         cout << endl;
  1704.     }
  1705.     else if ((p = str.Find('(')) != P_MAX_INDEX) {
  1706.       PString argStr = str.Mid(p);
  1707.       if (argStr.GetLength() > 0 && argStr[argStr.GetLength()-1] == ')')
  1708.         argStr = argStr.Mid(1, argStr.GetLength()-2);
  1709.  //Passing arguments to the call
  1710.   PArgList strArgs(argStr,
  1711.                        "f-fast-disable."
  1712.                        "T-h245tunneldisable."
  1713.                        "e-silence."
  1714.                        "j-jitter:"
  1715.                        "-connectport:"
  1716.                        "-connectring:");
  1717.       callOptions.Initialise(strArgs);
  1718.       str = str.Left(p);
  1719.       cout << "Per connection call options set: " << argStr << endl
  1720.            << callOptions
  1721.            << endl;
  1722.     }
  1723.   }
  1724.   if (!str.IsEmpty()) {
  1725.     PINDEX idx = str.Find(' ');
  1726.     if (idx == P_MAX_INDEX) {
  1727.       if (!key && (str[0] == '@'))
  1728.         MakeOutgoingCall(key, str.Mid(1), callOptions);
  1729.       else if (!key && !prefix && (str[0] == '%')) {
  1730.         if (key.Left(prefix.GetLength()) == prefix)
  1731.           key = key.Mid(prefix.GetLength());
  1732.         MakeOutgoingCall(key, str.Mid(1), callOptions);
  1733.       } else
  1734.         MakeOutgoingCall(str, PString(), callOptions);
  1735.     } else {
  1736.       PString host = str.Left(idx).Trim();
  1737.       PString gw   = str.Mid(idx).Trim();
  1738.       MakeOutgoingCall(host, gw, callOptions);
  1739.     }
  1740.     return;
  1741.   }
  1742.   uiState = MyH323EndPoint::uiCallHungup;
  1743. }
  1744. void MyH323EndPoint::AwaitTermination()
  1745. {
  1746.   PThread * userInterfaceThread = NULL;
  1747.   if (hasMenu)
  1748.     userInterfaceThread = new UserInterfaceThread(*this);
  1749. #if ! defined(HAS_LIDDEVICE)
  1750.   exitFlag.Wait();
  1751. #else
  1752.   if ((lidDevice == NULL) || !lidDevice->IsOpen())
  1753.     exitFlag.Wait();
  1754.   else {
  1755.     speakerphoneSwitch = FALSE;
  1756.     BOOL oldOnHook     = TRUE;
  1757.     BOOL oldRealOnHook = TRUE;
  1758.     int  olduiState    = uiStateIllegal;
  1759.     PTime offHookTime;
  1760.     PString digits;
  1761.     // poll the handset every 100ms looking for state changes
  1762.     while (!exitFlag.Wait(100)) {
  1763.       // lock the user interface state whilst we change it
  1764.       uiStateMutex.Wait();
  1765.       // get real hook state
  1766.       BOOL realOnHook = !lidDevice->IsLineOffHook(POTS_LINE);
  1767.       BOOL onHook     = realOnHook;
  1768.       // if in speakerphone mode,
  1769.       if (speakerphoneSwitch) {
  1770.         // if the phone is onhook then don't look at the real hook state
  1771.         if (realOnHook)
  1772.           onHook = FALSE;
  1773.         // if the handset just went offhook, then get out of speakerphone mode
  1774.         else if (realOnHook != oldRealOnHook) {
  1775.           speakerphoneSwitch = FALSE;
  1776.           lidDevice->EnableAudio(0, TRUE);
  1777.           if (verbose > 1)
  1778.             cout << "Speakerphone off" << endl;
  1779.         }
  1780.       }
  1781.       // handle onhook/offhook transitions
  1782.       if (onHook != oldOnHook) {
  1783.         if (onHook) {
  1784.           digits = PString();
  1785.           HandleHandsetOnHook();
  1786.         } else {
  1787.           HandleHandsetOffHook();
  1788.           offHookTime = PTime();
  1789.         }
  1790.         HandleStateChange(onHook);
  1791.         olduiState = uiState;
  1792.       } 
  1793.       // handle timeouts and DTMF digits
  1794.       if (!onHook) {
  1795.         HandleHandsetTimeouts(offHookTime);
  1796.         HandleHandsetDTMF(digits);
  1797.       }
  1798.       // handle any state changes
  1799.       if (uiState != olduiState) {
  1800.         offHookTime = PTime();
  1801.         HandleStateChange(onHook);
  1802.       }
  1803.       // save hook state so we can detect changes
  1804.       oldOnHook     = onHook;
  1805.       oldRealOnHook = realOnHook;
  1806.       // save the old UI state so we can detect changes
  1807.       olduiState = uiState;
  1808.       uiStateMutex.Signal();
  1809.     }
  1810.   }
  1811. #endif
  1812.   if (userInterfaceThread != NULL) {
  1813.     userInterfaceThread->Terminate();
  1814.     userInterfaceThread->WaitForTermination();
  1815.     delete userInterfaceThread;
  1816.   }
  1817. }
  1818. #if defined(HAS_LIDDEVICE)
  1819. #if 0
  1820. static char * stateNames[] = {
  1821.   "Dialtone",
  1822.   "AnsweringCall",
  1823.   "ConnectingCall",
  1824.   "WaitingForAnswer",
  1825.   "CallInProgress",
  1826.   "CallHungup",
  1827.   "StateIllegal"
  1828. };
  1829. #endif
  1830. void MyH323EndPoint::HandleStateChange(BOOL onHook)
  1831. {
  1832.   switch (uiState) {
  1833.     // dialtone whilst no call active
  1834.     case uiDialtone:
  1835.       if (onHook)
  1836.         lidDevice->RingLine(0, 0);
  1837.       else if (autoHook) {
  1838.         lidDevice->StopTone(0);
  1839.       } else {
  1840.         cout << "Playing dialtone" << endl;
  1841.         lidDevice->PlayTone(0, OpalLineInterfaceDevice::DialTone);
  1842.       }
  1843.       break;
  1844.     // no tone whilst waiting for remote party to connect
  1845.     case uiConnectingCall:
  1846.       if (onHook)
  1847.         lidDevice->RingLine(0, 0);
  1848.       else
  1849.         lidDevice->StopTone(0);
  1850.       break;
  1851.     // when connected, play ring tone
  1852.     case uiWaitingForAnswer:
  1853.       if (onHook)
  1854.         lidDevice->RingLine(0, 0);
  1855.       else {
  1856.         cout << "Playing ringtone" << endl;
  1857.         lidDevice->PlayTone(0, OpalLineInterfaceDevice::RingTone);
  1858.       }
  1859.       break;
  1860.     // when a call is in progress, stop all tones and remove DTMF tones from the stream
  1861.     case uiCallInProgress:
  1862.       if (onHook) 
  1863.         lidDevice->RingLine(0, 0);
  1864.       else {
  1865.         lidDevice->StopTone(0);
  1866.         lidDevice->SetRemoveDTMF(0, TRUE);
  1867.       }
  1868.       break;
  1869.     // remote end has hungup
  1870.     case uiCallHungup:
  1871.       if (terminateOnHangup)
  1872.         exitFlag.Signal();
  1873.       if (autoHook || onHook) {
  1874.         uiState = uiDialtone;
  1875.         lidDevice->RingLine(0, 0);
  1876.       } else {
  1877.         if (dialAfterHangup) 
  1878.           uiState = uiDialtone;
  1879.         else 
  1880.           lidDevice->PlayTone(POTS_LINE, OpalLineInterfaceDevice::BusyTone);
  1881.       }
  1882.       break;
  1883.     case uiAnsweringCall:
  1884.       if (autoHook || !onHook) 
  1885.         lidDevice->StopTone(0);
  1886.       else {
  1887.         lidDevice->SetCallerID(POTS_LINE, "");
  1888.         if (callerIdEnable) {
  1889.           MyH323Connection * connection = (MyH323Connection *)FindConnectionWithLock(currentCallToken);
  1890.           if (connection != NULL) {
  1891.             lidDevice->SetCallerID(POTS_LINE, connection->GetCallerIdString());
  1892.             connection->Unlock();
  1893.           }
  1894.         }
  1895.         lidDevice->RingLine(0, 0x33);
  1896.       }
  1897.       break;
  1898.    default:
  1899.       if (!onHook || autoHook) 
  1900.         lidDevice->StopTone(0);
  1901.       else
  1902.         lidDevice->RingLine(0, 0);
  1903.       break;
  1904.   }
  1905. }
  1906. void MyH323EndPoint::HandleHandsetOffHook()
  1907. {
  1908.   if (verbose > 1)
  1909.     cout << "Offhook - ";
  1910. //  if (speakerphoneSwitch) {
  1911. //    if (verbose > 1)
  1912. //      cout << "speakerphone off - ";
  1913. //    speakerphoneSwitch = FALSE;
  1914. //    lidDevice->EnableAudio(0, TRUE);
  1915. //  }
  1916.      
  1917.   switch (uiState) {
  1918.     case uiDialtone:
  1919.       if (!autoDial) {
  1920.         if (verbose > 1)
  1921.           cout << "auto-dialing " << autoDial << endl;
  1922.         StartCall(autoDial);
  1923.       } else {
  1924.         if (verbose > 1)
  1925.           cout << "dialtone" << endl;
  1926.       }
  1927.     break;
  1928.   
  1929.     case uiConnectingCall:
  1930.       if (verbose > 1)
  1931.         cout << "call connecting" << endl;
  1932.       break;   
  1933.   
  1934.     case uiAnsweringCall:
  1935.       if (verbose > 1)
  1936.         cout << "answering call" << endl;
  1937.       AnswerCall(H323Connection::AnswerCallNow);
  1938.       break;
  1939.   
  1940.     case uiWaitingForAnswer:
  1941.       if (verbose > 1)
  1942.         cout << "waiting for remote answer" << endl;
  1943.       break;
  1944.     case uiCallInProgress:  // should never occur!
  1945.       if (verbose > 1)
  1946.         cout << "call in progress" << endl;
  1947.       break;
  1948.   
  1949.     default:
  1950.       if (verbose > 1)
  1951.         cout << "not sure!" << endl;
  1952.       break;
  1953.   }
  1954. }
  1955. void MyH323EndPoint::HandleHandsetOnHook()
  1956. {
  1957.   if (uiState == uiCallHungup)
  1958.     uiState = uiDialtone;
  1959.   if (verbose > 1) 
  1960.     cout << "Onhook - ";
  1961. //#ifndef OLD_IXJ_DRIVER
  1962. //  if (speakerphoneSwitch) {
  1963. //    lidDevice->EnableAudio(0, FALSE);
  1964. //    if (verbose > 1)
  1965. //      cout << "speakerphone on." << endl;
  1966. //  } else
  1967. //#endif
  1968. //  {
  1969.     if (verbose > 1)
  1970.       cout << "ending call." << endl;
  1971.     ClearCall(currentCallToken);
  1972. //  }
  1973.   speakerphoneSwitch = FALSE;
  1974. }
  1975. void MyH323EndPoint::HandleHandsetDTMF(PString & digits)
  1976. {
  1977.   char newDigit = lidDevice->ReadDTMF(0);
  1978.   if (newDigit != '') {
  1979.     digits += newDigit;
  1980.     if (!digits) {
  1981.       switch (uiState) {
  1982.         case uiCallInProgress:
  1983.           {
  1984.             if (verbose > 1)
  1985.               cout << "Sending user indication message " << digits << endl;
  1986.             H323Connection * connection = FindConnectionWithLock(currentCallToken);
  1987.             if (connection != NULL) {
  1988.               connection->SendUserInput(digits);
  1989.               connection->Unlock();
  1990.             }
  1991.             digits = PString();
  1992.           }
  1993.           break;
  1994.     
  1995.         case uiDialtone:
  1996.           lidDevice->StopTone(0);
  1997.           if (digits.GetLength() > 0) {
  1998.             PINDEX i;
  1999.             for (i = 0; i < digits.GetLength(); i++)
  2000.               if (!isdigit(digits[i]))
  2001.                 break;
  2002.             BOOL allDigits = i == digits.GetLength();
  2003.             // handle strings ending in '#'
  2004.             if (digits[digits.GetLength()-1] == '#')  {
  2005.               // if pressed '#', then redial last number
  2006.               if (digits.GetLength() == 1) {
  2007.                 PConfig config("Calls");
  2008.                 int index = config.GetInteger("index");
  2009.                 PString lastCalledParty = config.GetString(PString(PString::Unsigned, index));
  2010.                 if (lastCalledParty.IsEmpty()) 
  2011.                   cout << "No last called party to dial" << endl;
  2012.                 else {
  2013.                   if (!MakeCall(lastCalledParty, currentCallToken)) 
  2014.                     cout << "Error making call to "" << lastCalledParty << '"' << endl;
  2015.                   else {
  2016.                     if (verbose > 1)
  2017.                       cout << "Redialling last number at " << lastCalledParty << endl;
  2018.                     uiState = uiConnectingCall;
  2019.                   }
  2020.                 }
  2021.               }
  2022.               // if pressed '*#', then redial last caller
  2023.               else if ((digits.GetLength() == 2) && (digits[0] == '*')) {
  2024.                 PConfig config("Callers");
  2025.                 int index = config.GetInteger("index");
  2026.                 PString lastCallingParty = config.GetString(PString(PString::Unsigned, index));
  2027.                 if (lastCallingParty.IsEmpty())
  2028.                   cout << "No last calling party to dial" << endl;
  2029.                 else {
  2030.                   if (!MakeCall(lastCallingParty, currentCallToken)) 
  2031.                     cout << "Error making call to "" << lastCallingParty << '"' << endl;
  2032.                   else {
  2033.                     if (verbose > 1)
  2034.                       cout << "Calling back last party at " << lastCallingParty << endl;
  2035.                     uiState = uiConnectingCall;
  2036.                   }
  2037.                 }
  2038.               }
  2039.               // if string starts with '*', then convert to IP address
  2040.               else if ((digits.GetLength() >= 9) && (digits[0] == '*')) {
  2041.                 digits = digits.Mid(1, digits.GetLength()-2);
  2042.                 digits.Replace('*', '.', TRUE);
  2043.                 StartCall(digits);
  2044.               // if there are some digits, then use them as a speed dial
  2045.               } else if (digits.GetLength() > 1)
  2046.                 StartCall(digits);
  2047.               // clear out the dialled digits
  2048.               digits = PString();
  2049.             } else if (allDigits && (digits.GetLength() == 10)) {
  2050.               while (digits[0] == '0')
  2051.                 digits = digits.Mid(1);
  2052.               if (digits.GetLength() > 0) {
  2053.                 StartCall(digits);
  2054.                 digits = PString();
  2055.               }
  2056.             }
  2057.           }
  2058.           break;
  2059.   
  2060.         default:
  2061.           break;
  2062.       }
  2063.     }
  2064.   }
  2065. }
  2066. void MyH323EndPoint::HandleHandsetTimeouts(const PTime & offHookTime)
  2067. {
  2068.   int timeout = 0;
  2069.   
  2070.   switch (uiState) {
  2071.     case uiDialtone:
  2072.       timeout = DEFAULT_TIMEOUT;
  2073.       break;
  2074.     case uiConnectingCall:
  2075.       timeout = DEFAULT_TIMEOUT;
  2076.       break;
  2077.     case uiWaitingForAnswer:
  2078.       timeout = DEFAULT_TIMEOUT;
  2079.       break;
  2080.     default:
  2081.       break;
  2082.   }
  2083.   if (timeout > 0) {
  2084.     PTime now;
  2085.     if ((now - offHookTime) > timeout) {
  2086.       if (verbose > 1)
  2087.         cout << "Operation timed out" << endl;
  2088.       ClearCall(currentCallToken);
  2089.       uiState = uiCallHungup;
  2090.     }
  2091.   }
  2092. }
  2093. #endif
  2094. void MyH323EndPoint::HandleUserInterface()
  2095. {
  2096.   PConsoleChannel console(PConsoleChannel::StandardInput);
  2097.   PTRACE(2, "BeaconClienttUser interface thread started.");
  2098.   PStringStream help;
  2099.   help << "Select:n"
  2100.           "  0-9 : send user indication messagen"
  2101.           "  C   : connect to remote hostn"
  2102.           "  T   : Transfer to another hostn"
  2103.           "  O   : Hold calln"
  2104.           "  S   : Display statisticsn"
  2105.           "  H   : Hang up phonen"
  2106.           "  L   : List speed dialsn"
  2107.           "  I   : Show call historyn"
  2108.           "  D   : Create new speed dialn"
  2109.           "  {}  : Increase/reduce record volumen"
  2110.           "  []  : Increase/reduce playback volumen"
  2111.           "  V   : Display current volumesn"
  2112. #ifdef HAS_LIDDEVICE
  2113.           "  A   : turn AEC up/downn"
  2114. #endif
  2115.           "  E   : Turn silence supression on/offn"
  2116.           "  F   : Forward call calls to addressn"
  2117.           "  J   : Flip video input top to bottomn";
  2118.          ;
  2119. #ifdef HAS_LIDDEVICE
  2120.   if (isXJack) {
  2121. #ifndef OLD_IXJ_DRIVER
  2122.     if ((lidDevice != NULL) && lidDevice->IsOpen())
  2123.       help << "  P   : Enter speakerphone moden";
  2124. #endif
  2125.   }
  2126. #endif
  2127.   help << "  X   : Exit programn";
  2128.   for (;;) {
  2129.     // display the prompt
  2130.     cout << "Command ? " << flush;
  2131.     // terminate the menu loop if console finished
  2132. //char ch = 'q';
  2133.     char ch = (char)console.peek();
  2134.     if (console.eof()) {
  2135.       if (verbose)
  2136.         cerr << "nConsole gone - menu disabled" << endl;
  2137.       return;
  2138.     }
  2139.     if (isdigit(ch)) {
  2140.       H323Connection * connection = FindConnectionWithLock(currentCallToken);
  2141.       if (connection == NULL) {
  2142.         cout << "No call in progressn";
  2143.         console.ignore(INT_MAX, 'n');
  2144.       } else {
  2145.         PString str;
  2146.         console >> str;
  2147.         cout << "Sending user indication: " << str << endl;
  2148.         connection->SendUserInput(str);
  2149.         connection->Unlock();
  2150.       }
  2151.     }
  2152.     else {
  2153.       console >> ch;
  2154.       switch (tolower(ch)) {
  2155.         case '?' :
  2156.           cout << help << endl;
  2157.           break;
  2158.         case 'x' :
  2159.         case 'q' :
  2160.         cout << "Exiting." << endl;
  2161.         ClearAllCalls();
  2162.         uiState = uiDialtone;
  2163.         exitFlag.Signal();
  2164.         console.ignore(INT_MAX, 'n');
  2165.         return;
  2166.         case 'h' :
  2167.         if (!currentCallToken) {
  2168.           cout << "Hanging up call." << endl;
  2169.           if (!ClearCall(currentCallToken))
  2170.             cout << "Could not hang up current call!n";
  2171.           speakerphoneSwitch = FALSE;
  2172.         }
  2173.         console.ignore(INT_MAX, 'n');
  2174.         break;
  2175.   
  2176.         case 't' :
  2177.           if (!currentCallToken) {
  2178.             PString str;
  2179.             console >> str;
  2180.             cout << "Transferring call to " << str << endl;
  2181.             TransferCall(currentCallToken, str.Trim());
  2182.           } 
  2183.           else
  2184.             console.ignore(INT_MAX, 'n');
  2185.           break;
  2186.         case 'o' :
  2187.           if (!currentCallToken) {
  2188.             cout << "Holding call." << endl;
  2189.             HoldCall(currentCallToken, TRUE);
  2190.           }
  2191.           console.ignore(INT_MAX, 'n');
  2192.           break;
  2193.         case 'y' :
  2194.           AnswerCall(H323Connection::AnswerCallNow);
  2195.           console.ignore(INT_MAX, 'n');
  2196.           break;
  2197.         case 'n' :
  2198.           AnswerCall(H323Connection::AnswerCallDenied);
  2199.           console.ignore(INT_MAX, 'n');
  2200.           break;
  2201.         case 'c' :
  2202.         if (!currentCallToken.IsEmpty()) 
  2203.           cout << "Cannot make call whilst call in progressn";
  2204.         else {
  2205.           PString str;
  2206.           console >> str;
  2207.           StartCall(str.Trim());
  2208.         }
  2209.         break;
  2210. /* CHANGED - star */
  2211.         //case 'l' :
  2212.         //  ListSpeedDials();
  2213.         //  break;
  2214.         /*case 'd' :
  2215.           {
  2216.             PString str;
  2217.             console >> str;
  2218.             NewSpeedDial(str.Trim());
  2219.           }
  2220.           break;*/
  2221. /* CHANGED - end */
  2222.         case 'e' :
  2223.           if (currentCallToken.IsEmpty())
  2224.             cout << "No call in progress" << endl;
  2225.           else {
  2226.             H323Connection * connection = FindConnectionWithLock(currentCallToken);
  2227.             if (connection == NULL) 
  2228.               cout << "No connection active.n";
  2229.             else {
  2230.               connection->Unlock();
  2231.               H323Channel * chan = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE);
  2232.               if (chan == NULL)
  2233.                 cout << "Cannot find audio channel" << endl;
  2234.               else {
  2235.                 H323Codec * rawCodec  = chan->GetCodec();
  2236.                 if (!rawCodec->IsDescendant(H323AudioCodec::Class()))
  2237.                   cout << "Audio channel is not audio!" << endl;
  2238.                 else {
  2239.                   H323AudioCodec * codec = (H323AudioCodec *)rawCodec;
  2240.                   H323AudioCodec::SilenceDetectionMode mode = codec->GetSilenceDetectionMode();
  2241.                   if (mode == H323AudioCodec::AdaptiveSilenceDetection) {
  2242.                     mode = H323AudioCodec::NoSilenceDetection;
  2243.                     cout << "Silence detection off" << endl;
  2244.                   } else {
  2245.                     mode = H323AudioCodec::AdaptiveSilenceDetection;
  2246.                     cout << "Silence detection on" << endl;
  2247.                   }
  2248.                   codec->SetSilenceDetectionMode(mode);
  2249.                 }
  2250.               }
  2251.             //  connection->Unlock();
  2252.           }
  2253.         }
  2254.         break;
  2255.         case 's' :
  2256.         if (currentCallToken.IsEmpty())
  2257.           cout << "No call in progress" << endl;
  2258.         else {
  2259.           H323Connection * connection = FindConnectionWithLock(currentCallToken);
  2260.           if (connection == NULL) 
  2261.             cout << "No connection statistics available.n";
  2262.           else {
  2263.             PTime now;
  2264.             PTime callStart = connection->GetConnectionStartTime();
  2265.             cout << "Connection statistics:n   "
  2266.                << "Remote party     : " << connection->GetRemotePartyName() << "n   "
  2267.                << "Start            : " << callStart << "n   "
  2268.                << "Duration         : " << setw(5) << setprecision(0) << (now - callStart) << " minsn   "
  2269.                << "Round trip delay : " << connection->GetRoundTripDelay().GetMilliSeconds() << " msec"
  2270.                << endl;
  2271.             RTP_Session * session = connection->GetSession(RTP_Session::DefaultAudioSessionID);
  2272.             if (session == NULL)
  2273.               cout << "No RTP session statistics available.n";
  2274.             else
  2275.               cout << "RTP session statistics:n   "
  2276.                  << session->GetPacketsSent() << '/'
  2277.                  << session->GetOctetsSent() 
  2278.                  << " packets/bytes sentn   "
  2279.               
  2280.                  << session->GetMaximumSendTime() << '/'
  2281.                  << session->GetAverageSendTime() << '/'
  2282.                  << session->GetMinimumSendTime() << " max/avg/min send timen   "
  2283.               
  2284.                  << session->GetPacketsReceived() << '/'
  2285.                  << session->GetOctetsReceived()
  2286.                  << " packets/bytes receivedn   "
  2287.               
  2288.                  << session->GetMaximumReceiveTime() << '/'
  2289.                  << session->GetAverageReceiveTime() << '/'
  2290.                  << session->GetMinimumReceiveTime() << " max/avg/min receive timen   "
  2291.               
  2292.                  << session->GetPacketsLost() << '/'
  2293.                  << session->GetPacketsOutOfOrder() << '/'
  2294.                  << session->GetPacketsTooLate() 
  2295.                  << " packets dropped/out of order/laten   "
  2296.               
  2297.                  << endl;
  2298.     
  2299.             connection->Unlock();
  2300.           }
  2301.         }
  2302.         break;
  2303. #ifdef HAS_LIDDEVICE
  2304. #ifndef OLD_IXJ_DRIVER
  2305.         case 'p' :
  2306.           if (isXJack) {
  2307.             if ((lidDevice != NULL) && lidDevice->IsOpen()) {
  2308.               speakerphoneSwitch = !speakerphoneSwitch;
  2309.               lidDevice->EnableAudio(0, !speakerphoneSwitch);
  2310.               if (verbose > 1)
  2311.                 cout << "Speakerphone " 
  2312.                      << (speakerphoneSwitch ? "on" : "off")
  2313.                      << endl;
  2314.             }
  2315.             console.ignore(INT_MAX, 'n');
  2316.           }
  2317.           break;
  2318. #endif
  2319.         case 'a' :
  2320.           if ((lidDevice != NULL) && lidDevice->IsOpen()) {
  2321.           int aec = lidDevice->GetAEC(0);
  2322.           if (ch == 'a')
  2323.             aec--;
  2324.           else
  2325.             aec++;
  2326.           if (aec < 0)
  2327.             aec = OpalLineInterfaceDevice::AECAGC;
  2328.           else if (aec > OpalLineInterfaceDevice::AECAGC)
  2329.             aec = OpalLineInterfaceDevice::AECOff;
  2330.   
  2331.           lidDevice->SetAEC(0, (OpalLineInterfaceDevice::AECLevels)aec);
  2332.   
  2333.           if (aec == OpalLineInterfaceDevice::AECAGC ||
  2334.              (ch == 'a' && aec == OpalLineInterfaceDevice::AECHigh) ||
  2335.              (ch == 'A' && aec == OpalLineInterfaceDevice::AECOff)) {
  2336.             unsigned recvol;
  2337.             lidDevice->GetRecordVolume(0, recvol);
  2338.             if (verbose > 2)
  2339.               cout << "New volume level is " << recvol << endl;
  2340.           }
  2341.           if (verbose > 2)
  2342.             cout << "New AEC level is " << AECLevelNames[aec] << endl;
  2343.         } else
  2344.           cout <<"AEC change ignored as device closed"<<endl;
  2345.         break;
  2346. #endif
  2347.         case 'v' :
  2348. #if defined(HAS_LIDDEVICE)
  2349.           if ((lidDevice != NULL) && lidDevice->IsOpen()) {
  2350.             unsigned vol;
  2351.             lidDevice->GetPlayVolume(0, vol);
  2352.             cout << "Play volume is " << vol << endl;
  2353.             lidDevice->GetRecordVolume(0, vol);
  2354.             cout << "Record volume is " << vol << endl;
  2355.           }
  2356. #endif
  2357. #if defined(HAS_LIDDEVICE) && defined(HAS_OSS)
  2358.           else
  2359. #endif
  2360. #ifdef HAS_OSS
  2361.           {
  2362.             cout << "Play volume is " << ossPlayVol << endl;
  2363.             cout << "Record volume is " << ossRecVol << endl;
  2364.           }
  2365. #endif
  2366.           break;
  2367.         case '[' :
  2368.         case ']' :
  2369.         case '{' :
  2370.         case '}' :
  2371. #ifdef HAS_LIDDEVICE
  2372.           if ((lidDevice != NULL) && lidDevice->IsOpen()) {
  2373.             unsigned vol;
  2374.             if (ch == '{' || ch == '}')
  2375.               lidDevice->GetRecordVolume(0, vol);
  2376.             else
  2377.               lidDevice->GetPlayVolume(0, vol);
  2378.             // adjust volume up or down
  2379.             vol += ((ch == '[') || (ch == '{')) ? -5 : 5;
  2380.             if (vol < 0)
  2381.               vol = 0;
  2382.             else if (vol > 100)
  2383.               vol = 100;
  2384.             // write to hardware
  2385.             if (ch == '{' || ch == '}') {
  2386.               lidDevice->SetRecordVolume(0, vol);
  2387.               if (verbose > 2)
  2388.                cout << "Record volume is " << vol << endl;
  2389.             } else {
  2390.               lidDevice->SetPlayVolume(0, vol);
  2391.               if (verbose > 2)
  2392.                cout << "Play volume is " << vol << endl;
  2393.             }
  2394.           }
  2395. #endif
  2396. #if defined(HAS_LIDDEVICE) && defined(HAS_OSS)
  2397.           else
  2398. #endif
  2399. #ifdef HAS_OSS
  2400.           {
  2401.             int vol;
  2402.             if (ch == '{' || ch == '}')
  2403.               vol = ossRecVol;
  2404.             else
  2405.               vol = ossPlayVol;
  2406.             
  2407.             vol += ((ch == '[') || (ch == '{')) ? -5 : 5;
  2408.             if (vol < 0)
  2409.               vol = 0;
  2410.             else if (vol > 100)
  2411.               vol = 100;
  2412.     
  2413.             if (mixerDev >= 0)  {
  2414.               int volVal = vol | (vol << 8);
  2415.               if (ch == '{' || ch == '}') {
  2416.                 ossRecVol = vol;
  2417.                 ::ioctl(mixerDev, MIXER_WRITE(mixerRecChan), &volVal);
  2418.                 cout << "Record volume is " << ossRecVol << endl;
  2419.               } else {
  2420.                 ossPlayVol = vol;
  2421.                 ::ioctl(mixerDev, SOUND_MIXER_WRITE_PCM, &volVal);
  2422.                 cout << "Play volume is " << ossPlayVol << endl;
  2423.               }
  2424.             } else
  2425.               cout << "Audio setting change ignored as mixer device disabled"<<endl;
  2426.           }
  2427. #endif
  2428.         break;
  2429.         case 'f' :
  2430.         console >> alwaysForwardParty;
  2431.         alwaysForwardParty = alwaysForwardParty.Trim();
  2432.         if (!alwaysForwardParty)
  2433.           cout << "Forwarding all calls to "" << alwaysForwardParty << '"' << endl;
  2434.         else
  2435.           cout << "Call forwarding of all calls disabled." << endl;
  2436.         break;
  2437.         case 'i' :
  2438.         case 'I' :
  2439.         {
  2440.           PString title;
  2441.           if (ch == 'i')
  2442.             title   = "Callers";
  2443.           else 
  2444.             title   = "Calls";
  2445.           cout << title << endl;
  2446.           PConfig config(title);
  2447.           int index = config.GetInteger("index");
  2448.           PINDEX i;
  2449.           for (i = 0; i < LAST_CALL_COUNT; i++) {
  2450.             PString indexStr = PString(PString::Unsigned, index);
  2451.             PString number = config.GetString(indexStr);
  2452.             if (number.IsEmpty())
  2453.               continue;
  2454.             cout << indexStr
  2455.                << ": "
  2456.                << number
  2457.                << " at "
  2458.                << config.GetString(indexStr + "_Time")
  2459.                << endl;
  2460.             if (index == 0)
  2461.               index = LAST_CALL_COUNT-1;
  2462.             else
  2463.               index--;
  2464.           }
  2465.         }
  2466.           break;
  2467.         case 'j' :
  2468.         if (currentCallToken.IsEmpty())
  2469.           cout << "No call in progress" << endl;
  2470.         else {
  2471.           H323Connection * connection = FindConnectionWithLock(currentCallToken);
  2472.           if (connection == NULL) 
  2473.             cout << "No connection active.n";
  2474.           else {
  2475.             connection->Unlock();
  2476.             H323Channel * chan = connection->FindChannel(RTP_Session::DefaultVideoSessionID, FALSE);
  2477.             if (chan == NULL)
  2478.               cout << "Cannot find sending video channel" << endl;
  2479.             else {
  2480.               H323Codec * rawCodec  = chan->GetCodec();
  2481.               if (!rawCodec->IsDescendant(H323VideoCodec::Class()))
  2482.               cout << "Sending video codec is not video!" << endl;
  2483.               else {
  2484.               H323VideoCodec * codec = (H323VideoCodec *)rawCodec;
  2485.   videoCodecDlgAudioVideo = (H323VideoCodec *)rawCodec;
  2486.               PChannel * rawChan = codec->GetRawDataChannel();
  2487.               if (NULL == rawChan)
  2488.                 cout << "Cannot find sending video channel" << endl;
  2489.               else {
  2490.                 if (!rawChan->IsDescendant(PVideoChannel::Class()))
  2491.                   cerr << "Sending video channel is not Class PVideoChannel!" << endl;
  2492.                 else {
  2493.                   PVideoChannel * videoChan = (PVideoChannel *)rawChan;
  2494.                   if (!videoChan->ToggleVFlipInput())
  2495.                     cerr << "nCould not toggle Vflip state of video input device" << endl;
  2496.                 }
  2497.               }
  2498.               }
  2499.             }
  2500.           }
  2501.         }                 
  2502.         break;
  2503.   
  2504.         default:
  2505.         cout << "Unknown command " << ch << endl;
  2506.         console.ignore(INT_MAX, 'n');
  2507.         break;
  2508.       }
  2509.     }
  2510.   }
  2511. }
  2512. void MyH323EndPoint::AnswerCall(H323Connection::AnswerCallResponse response)
  2513. {
  2514.   if (uiState != uiAnsweringCall)
  2515.     return;
  2516.   StopRinging();
  2517.   H323Connection * connection = FindConnectionWithLock(currentCallToken);
  2518.   if (connection == NULL)
  2519.     return;
  2520.   connection->AnsweringCall(response);
  2521.   connection->Unlock();
  2522.   if (response == H323Connection::AnswerCallNow) {
  2523.     cout << "Accepting call." << endl;
  2524.     uiState = uiCallInProgress;
  2525.   } else {
  2526.     cout << "Rejecting call." << endl;
  2527.     uiState = uiCallHungup;
  2528.   }
  2529. }
  2530. void MyH323EndPoint::HandleRinging()
  2531. {
  2532.   PSoundChannel dev(GetSoundChannelPlayDevice(), PSoundChannel::Player);
  2533.   if (!dev.IsOpen()) {
  2534.     PTRACE(2, "Cannot open sound device for ring");
  2535.     return;
  2536.   }
  2537.   if (ringDelay < 0) {
  2538.     PTRACE(2, "Playing " << ringFile);
  2539.     dev.PlayFile(ringFile, TRUE);
  2540.   } else {
  2541.     PTimeInterval delay(0, ringDelay);
  2542.     PTRACE(2, "Playing " << ringFile << " with repeat of " << delay << " ms");
  2543.     do {
  2544.       dev.PlayFile(ringFile, TRUE);
  2545.     } while (!ringFlag.Wait(delay));
  2546.   }
  2547. }
  2548. void MyH323EndPoint::StartRinging()
  2549. {
  2550.   PAssert(ringThread == NULL, "Ringing thread already present");
  2551.   if (!noAnswerForwardParty)
  2552.     noAnswerTimer = PTimeInterval(0, noAnswerTime);
  2553.   if (!ringFile)
  2554.     ringThread = new RingThread(*this);
  2555. }
  2556. void MyH323EndPoint::StopRinging()
  2557. {
  2558.   noAnswerTimer.Stop();
  2559.   if (ringThread == NULL)
  2560.     return;
  2561.   ringFlag.Signal();
  2562.   ringThread->WaitForTermination();
  2563.   delete ringThread;
  2564.   ringThread = NULL;
  2565. }
  2566. void MyH323EndPoint::SendDTMF(const char * tone)
  2567. {
  2568. #ifdef HAS_LIDDEVICE
  2569.   lidDevice->PlayDTMF(0, tone, 200, 100);
  2570. #endif
  2571. }
  2572. ///////////////////////////////////////////////////////////////
  2573. BOOL CallOptions::Initialise(PArgList & args)
  2574. {
  2575.   // set default connection options
  2576.   noFastStart          = args.HasOption('f');
  2577.   noH245Tunnelling     = args.HasOption('T');
  2578.   noSilenceSuppression = args.HasOption('e');
  2579.   if (args.HasOption("connectring"))
  2580.     connectRing = args.HasOption("connectring");
  2581.   if (!args.GetOptionString("connectport").IsEmpty())
  2582.     connectPort = (WORD)args.GetOptionString("connectport").AsInteger();
  2583.   if (args.HasOption('j')) {
  2584.     int newjitter = args.GetOptionString('j').AsUnsigned();
  2585.     if (newjitter >= 20 && newjitter <= 10000)
  2586.       jitter = newjitter;
  2587.     else {
  2588.       cerr << "Jitter should be between 20 milliseconds and 10 seconds." << endl;
  2589.       return FALSE;
  2590.     }
  2591.   }
  2592.   return TRUE;
  2593. }
  2594. void CallOptions::PrintOn(ostream & strm) const
  2595. {
  2596.   strm << "FastStart is " << !noFastStart << "n"
  2597.        << "H245Tunnelling is " << !noH245Tunnelling << "n"
  2598.        << "SilenceSupression is " << !noSilenceSuppression << "n"
  2599.        << "Jitter buffer: "  << jitter << " msn"
  2600.        << "Connect port: " << connectPort << "n";
  2601. }
  2602. void MyH323EndPoint::TestHandleUserInterface()
  2603. {
  2604.   PConsoleChannel console(PConsoleChannel::StandardInput);
  2605.   PTRACE(2, "BeaconClienttTESTING interface thread started.");
  2606.   PStringStream help;
  2607.   help << "Select:n"
  2608.           "  J   : Flip video input top to bottomn"
  2609.           "  Q   : Exit programn"
  2610.           "  X   : Exit programn";
  2611.   for (;;) {
  2612.     // display the prompt
  2613.     cout << "(testing) Command ? " << flush;
  2614.     // terminate the menu loop if console finished
  2615.     char ch = (char)console.peek();
  2616.     if (console.eof()) {
  2617.       if (verbose)
  2618.         cerr << "nConsole gone - menu disabled" << endl;
  2619.       return;
  2620.     }
  2621.     console >> ch;
  2622.     switch (tolower(ch)) {
  2623.     case 'j' : 
  2624.       if (NULL == localVideoChannel) {
  2625. cerr << "nNo video Channel" << endl;
  2626. break;
  2627.       }
  2628.       if (!localVideoChannel->ToggleVFlipInput())
  2629. cerr << "nCould not toggle Vflip state of video input device" << endl;
  2630.       break;
  2631.       
  2632.     case 'x' :
  2633.     case 'q' :
  2634.       cout << "Exiting." << endl;
  2635.       exitFlag.Signal();
  2636.       console.ignore(INT_MAX, 'n');
  2637.       return;
  2638.       break;
  2639.     case '?' :
  2640.     default:
  2641.       cout << help << endl;
  2642.       break;
  2643.       
  2644.     } // end switch
  2645.   } // end for
  2646. }
  2647. ///////////////////////////////////////////////////////////////
  2648. /* Modified One */
  2649. /*
  2650. MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
  2651.                                    unsigned callReference,
  2652.                                    unsigned options,
  2653.                                    WORD jitter,
  2654.                                    int _verbose)
  2655.  : H323Connection(ep, callReference, disableFastStart, disableTunneling),
  2656.     myEndpoint(ep),
  2657.     verbose(_verbose)
  2658. {
  2659.   SetMaxAudioDelayJitter(jitter);
  2660.   channelsOpen = 0;
  2661. }
  2662. */
  2663.   // New One
  2664. MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
  2665.                                    unsigned callReference,
  2666.                                    unsigned options,
  2667.                                    WORD jitter,
  2668.                                    int _verbose)
  2669.   : H323Connection(ep, callReference, options),
  2670.     myEndpoint(ep),
  2671.     verbose(_verbose)
  2672. {
  2673.   SetMaxAudioDelayJitter(jitter);
  2674.   channelsOpen = 0;
  2675. }
  2676. /*
  2677. // Old One
  2678. MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
  2679.                                    unsigned callReference,
  2680.                                    BOOL disableFastStart,
  2681.                                    BOOL disableTunneling,
  2682.                                    WORD jitter,
  2683.                                    int _verbose)
  2684.   : H323Connection(ep, callReference, disableFastStart, disableTunneling),
  2685.     myEndpoint(ep),
  2686.     verbose(_verbose)
  2687. {
  2688.   SetMaxAudioDelayJitter(jitter);
  2689.   channelsOpen = 0;
  2690. }
  2691. */
  2692. BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
  2693. {
  2694.   if (!myEndpoint.setupParameter) {
  2695.     setupPDU.m_h323_uu_pdu.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardData);
  2696.     setupPDU.m_h323_uu_pdu.m_nonStandardData.m_nonStandardIdentifier.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
  2697.     endpoint.SetH221NonStandardInfo(setupPDU.m_h323_uu_pdu.m_nonStandardData.m_nonStandardIdentifier);
  2698.     setupPDU.m_h323_uu_pdu.m_nonStandardData.m_data = myEndpoint.setupParameter;
  2699.   }
  2700.   return TRUE;
  2701. }
  2702. H323Connection::AnswerCallResponse
  2703.      MyH323Connection::OnAnswerCall(const PString & caller,
  2704.                                     const H323SignalPDU & /*setupPDU*/,
  2705.                                     H323SignalPDU & /*connectPDU*/)
  2706. {
  2707.   PTRACE(1, "H225tOnWaitForAnswer");
  2708.   PTime now;
  2709.   if (myEndpoint.autoAnswer) {
  2710.     cout << "Automatically accepting call at " << now << endl;
  2711.     return AnswerCallNow;
  2712.   }
  2713.   myEndpoint.currentCallToken = GetCallToken();
  2714.   myEndpoint.uiState = MyH323EndPoint::uiAnsweringCall;
  2715.   cout << "Incoming call from ""
  2716.        << caller
  2717.        << "" at "
  2718.        << now
  2719.        << ", answer call (Y/n)? "
  2720.        << flush;
  2721.   myEndpoint.StartRinging();
  2722.   
  2723.   return AnswerCallPending;
  2724. }
  2725. BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
  2726. {
  2727.   if (!H323Connection::OnStartLogicalChannel(channel))
  2728.     return FALSE;
  2729.   if (verbose >= 2) {
  2730.     cout << "Started logical channel: ";
  2731.     switch (channel.GetDirection()) {
  2732.       case H323Channel::IsTransmitter :
  2733.         cout << "sending ";
  2734.         break;
  2735.       case H323Channel::IsReceiver :
  2736.         cout << "receiving ";
  2737.         break;
  2738.       default :
  2739.         break;
  2740.     }
  2741.     cout << channel.GetCapability() << endl;  
  2742.   }
  2743.   if (channel.GetDirection() == H323Channel::IsReceiver) {
  2744.     int videoQuality = myEndpoint.videoQuality;
  2745.     if (channel.GetCodec()->IsDescendant(H323VideoCodec::Class()) && (videoQuality >= 0)) {
  2746.       //const H323_H261Capability & h261Capability = (const H323_H261Capability &)channel.GetCapability();
  2747.       //if (!h261Capability.GetTemporalSpatialTradeOffCapability()) 
  2748.       //  cout << "Remote endpoint does not allow video quality configuration" << endl;
  2749.       //else {
  2750.         cout << "Requesting remote endpoint to send video quality " << videoQuality << "/31" << endl;
  2751.   
  2752.         // kludge to wait for channel to ACK to be sent
  2753.         PThread::Current()->Sleep(2000);
  2754.   
  2755.         H323ControlPDU pdu;
  2756.         H245_CommandMessage & command = pdu.Build(H245_CommandMessage::e_miscellaneousCommand);
  2757.   
  2758.         H245_MiscellaneousCommand & miscCommand = command;
  2759.         miscCommand.m_logicalChannelNumber = (unsigned)channel.GetNumber();
  2760.         miscCommand.m_type.SetTag(H245_MiscellaneousCommand_type::e_videoTemporalSpatialTradeOff);
  2761.         PASN_Integer & value = miscCommand.m_type;
  2762.         value = videoQuality;
  2763.         WriteControlPDU(pdu);
  2764.       //}
  2765.     }
  2766.   }
  2767.   // adjust the count of channels we have open
  2768.   channelsOpen++;
  2769.   PTRACE(2, "MaintchannelsOpen = " << channelsOpen);
  2770.   // if we get to two channels (one open, one receive), then (perhaps) trigger a timeout for shutdown
  2771.   if (channelsOpen == 2)
  2772.     myEndpoint.TriggerDisconnect();
  2773.   return TRUE;
  2774. }
  2775. void MyH323Connection::OnClosedLogicalChannel(H323Channel & channel)
  2776. {
  2777.   channelsOpen--;
  2778.   H323Connection::OnClosedLogicalChannel(channel);
  2779. }
  2780. BOOL MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/,
  2781.                                   const PString & username)
  2782. {
  2783.   PAssert((myEndpoint.uiState == MyH323EndPoint::uiConnectingCall) ||
  2784.           (myEndpoint.uiState == MyH323EndPoint::uiWaitingForAnswer) ||
  2785.           !myEndpoint.callTransferCallToken,
  2786.      psprintf("Alerting received in state %i whilst not waiting for incoming call!", myEndpoint.uiState));
  2787.   if (verbose > 0)
  2788.     cout << "Ringing phone for "" << username << "" ..." << endl;
  2789.   myEndpoint.uiState = MyH323EndPoint::uiWaitingForAnswer;
  2790.   return TRUE;
  2791. }
  2792. void MyH323Connection::OnUserInputString(const PString & value)
  2793. {
  2794.   cout << "User input received: "" << value << '"' << endl;
  2795.  
  2796.   //strcpy(ReceivedDTMF,value);
  2797.   ReceivedDTMFMessages = value;
  2798. #ifdef HAS_LIDDEVICE
  2799.   //myEndpoint.SendDTMF(value);
  2800. #endif
  2801. }
  2802. PString MyH323Connection::GetCallerIdString() const
  2803. {
  2804.   H323TransportAddress addr = GetControlChannel().GetRemoteAddress();
  2805.   PIPSocket::Address ip;
  2806.   WORD port;
  2807.   addr.GetIpAndPort(ip, port);
  2808.   DWORD decimalIp = (ip[0] << 24) +
  2809.                     (ip[1] << 16) +
  2810.                     (ip[2] << 8) +
  2811.                      ip[3];
  2812.   PString remotePartyName = GetRemotePartyName();
  2813.   PINDEX bracket = remotePartyName.Find('[');
  2814.   if (bracket != P_MAX_INDEX)
  2815.     remotePartyName = remotePartyName.Left(bracket);
  2816.   bracket = remotePartyName.Find('(');
  2817.   if (bracket != P_MAX_INDEX)
  2818.     remotePartyName = remotePartyName.Left(bracket);
  2819.   return psprintf("%010litt", decimalIp) + remotePartyName;
  2820. }
  2821. // End of File ///////////////////////////////////////////////////////////////