⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cxx

📁 这是一个自动应答机程序
💻 CXX
📖 第 1 页 / 共 5 页
字号:
 * Fixed problem with recording zero length messages, and added autodelete of files
 *
 * Revision 1.2  1999/10/22 09:56:24  craigs
 * Fixed various compile warnings
 *
 * Revision 1.1  1999/10/11 00:15:18  craigs
 * Initial version
 *
 */

#include <ptlib.h>
#include <ptlib/pipechan.h>
#include <signal.h>

#include "version.h"

#include "opalvxml.h"
#include "main.h"

PCREATE_PROCESS(OpenAm);

#define	DEFAULT_MSG_LIMIT	30
#define DEFAULT_CALL_LOG	"call_log.txt"

#define	G7231_SAMPLES_PER_BLOCK	240

#define CHECK_PCM   1
#define CHECK_G7231 2

#define	MENU_PREFIX		"UserMenu-"

#define DISABLE_COUT  1

static PMutex logMutex;
static PTextFile logFile;
static PFilePath logFilename = DEFAULT_CALL_LOG;

PString G7231Ext(".g723");
PString WAVExt(".wav");
PString PCMExt(".sw");


#if OPENAM_VIDEO
#include <ptclib/pvfiledev.h>

PString VideoGrabberDriverName("YUVFile");

#define DEFAULT_VIDEO_FRAME_RATE  10
#define DEFAULT_VIDEO_SIZE        "qcif"
#define DEFAULT_VIDEO_FORMAT      "pal"
#define DEFAULT_VIDEO_MODE        PVideoInputDevice_YUVFile::Channel_PlayAndClose

// these must be in the same order as the enum in PVideoInputDevice_YUVFile
static const char * VideoModes[PVideoInputDevice_YUVFile::ChannelCount] = {
  "Close",
  "Repeat",
  "KeepLast",
  "Black",
};

#endif // OPENAM_VIDEO


///////////////////////////////////////////////////////////////////////////////////////////

static void LogMessage(const PString & str)
{
  PTime now;
  PString msg = now.AsString("hh:mm:ss dd/MM/yyyy") & str;
  logMutex.Wait();

  if (!logFile.IsOpen()) {
    logFile.Open(logFilename, PFile::ReadWrite);
    logFile.SetPosition(0, PFile::End);
  }

  logFile.WriteLine(msg);

  logFile.Close();
  
  logMutex.Signal();
}

static void LogCall(const PFilePath & fn,
                    const PString & from,
                    const PString & user,
                    unsigned len,
                    const PString & codec,
                    const PString & product,
                    const PString & to)
{
  PString addr = from;
  LogMessage(addr & "\"" + user + "\"" & PString(PString::Unsigned, len) & codec & "\"" + product + "\"" & "\"" + fn + "\"" & "\"" + to + "\"");
}


#ifdef _WIN32

BOOL WINAPI WinCtrlHandlerProc(DWORD dwCtrlType)
{
	PString eventName = "CTRL_UNKNOWN_EVENT";
	
	if( dwCtrlType == CTRL_LOGOFF_EVENT ) {
		eventName = "CTRL_LOGOFF_EVENT";
        LogMessage("OpenAM received " + eventName);
		// prevent shut down
		return FALSE;
	}
	
	if( dwCtrlType == CTRL_C_EVENT )
		eventName = "CTRL_C_EVENT";
	else if( dwCtrlType == CTRL_BREAK_EVENT )
		eventName = "CTRL_BREAK_EVENT";
	else if( dwCtrlType == CTRL_CLOSE_EVENT )
		eventName = "CTRL_CLOSE_EVENT";
	else if( dwCtrlType == CTRL_SHUTDOWN_EVENT )
		eventName = "CTRL_SHUTDOWN_EVENT";
	LogMessage("OpenAM shutdown due to " + eventName);

	OpenAm::Shutdown();	
	exit(1);
}

#else

void UnixShutdownHandler(int sig)
{
	LogMessage(PString("OpenAM received signal ") + PString(sig));

	OpenAm::Shutdown();	
	exit(1);
}

#endif

///////////////////////////////////////////////////////////////

MyH323EndPoint * OpenAm::endpoint = NULL;

OpenAm::OpenAm()
  : PProcess("OpenH323 Project", "OpenAM",
             MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
{
}


OpenAm::~OpenAm()
{
}


void OpenAm::Main()
{
  cout << GetName()
       << " Version " << GetVersion(TRUE)
       << " by " << GetManufacturer()
       << " on " << GetOSClass() << ' ' << GetOSName()
       << " (" << GetOSVersion() << '-' << GetOSHardware() << ")\n\n";

#ifdef _WIN32
	SetConsoleCtrlHandler(WinCtrlHandlerProc, TRUE);
#else
	signal(SIGTERM, UnixShutdownHandler);
	signal(SIGINT, UnixShutdownHandler);
	signal(SIGQUIT, UnixShutdownHandler);
#endif

  PConfigArgs args(GetArguments());

  args.Parse(
             "D-disable:"
             "d-directory:"
             "g-gatekeeper:"         "n-no-gatekeeper."
             "-g711-ulaw."           "-no-g711-ulaw."
             "-g711-alaw."           "-no-g711-alaw."
             "-g711message:"         "-no-g711message."
             "-g7231."               "-no-g7231."
             "-g7231message:"        "-no-g7231message."
             "-ilbc."                "-no-ilbc."
             "-ilbcmessage:"         "-no-ilbcmessage."
             "-gsm."                 "-no-gsm."
             "-gsmmessage:"          "-no-gsmmessage."
             "h-help."
             "H-hangup."             "-no-hangup."
             "i-interface:"          "-no-interface."
             "k-kill."               "-no-kill."
             "l-limit:"              "-no-limit."
             "-listenport:"          "-no-listenport."
             "-lpc10message:"        "-no-lpc10message."
             "-speexmessage:"        "-no-speexmessage."
             "m-message:"            "-no-message."
             "-no-recordg7231."
             "-loop."
#if PTRACING
             "o-output:"
#endif
             "P-prefer:"
             "-pcm."                 "-no-pcm."
             "-pcmmessage:"          "-no-pcmmessage."
             "-port:"
             "r-run:"                "-no-run."
	           "-recordraw."
             "-require-gatekeeper."  "-no-require-gatekeeper."
             "-save."
#if PMEMORY_CHECK
             "-setallocationbreakpoint:"
#endif
#if PTRACING
             "t-trace."
#endif
	           "u-username:"           "-no-username."
             "p-password:"
#if OPENAM_VIDEO
             "-videomessage:"
             "-videorate:"
             "-videosize:"
             "-videoformat:"
             "-videomode:"
#endif
          , FALSE);

#if PMEMORY_CHECK
  if (args.HasOption("setallocationbreakpoint"))
    PMemoryHeap::SetAllocationBreakpoint(args.GetOptionString("setallocationbreakpoint").AsInteger());
#endif

#if PTRACING
  PTrace::Initialise(args.GetOptionCount('t'),
                     args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL);
#endif

  if (args.HasOption('h')) {
    cout << "Usage : " << GetName() << " [options]\n"
            "Options:\n"
            "  -d --directory dir  : Put recorded mesages into dir\n"
            "  -l --limit secs     : Limit recorded messages to secs duration (default " << DEFAULT_MSG_LIMIT << ")\n"
            "  -m --pcmmessage fn  : Set outgoing message for PCM derived codecs (G.711/GSM) to fn\n"
            "  --g7231message fn   : Set outgoing message for G723.1 codec to fn\n"
            "  --g711message fn    : Set outgoing message for G711 codec to fn\n"
            "  --gsmmessage fn     : Set outgoing message for GSM codec to fn\n"
            "  --lpc10message fn   : Set outgoing message for LPC10 codec to fn\n"
            "  --speexmessage fn   : Set outgoing message for Speex codec to fn\n"
            "  --ilbcmessage fn    : Set outgoing message for iLBC codec to fn\n"
#if OPENAM_VIDEO
            "  --videomessage fn   : Set outgoing message for video to fn\n"
            "  --videorate num     : Set video frame rate (default is " << DEFAULT_VIDEO_FRAME_RATE << ")\n"
            "  --videosize size    : Set video frame size (default is " << DEFAULT_VIDEO_SIZE << ")\n"
            "                      : Must be one of qcif or cif\n"
            "  --videoformat fmt   : Set video frame format (default is " << DEFAULT_VIDEO_FORMAT << ")\n"
            "                      : Must be one of pal or ntsc\n"
            "  --videomode mode:   : Set video play mode. Default is " << VideoModes[DEFAULT_VIDEO_MODE] << "\n"
            "                      : Must be one of Close, Repeat, KeepLast or Black\n"
#endif
            "  --loop              : loop message, no recording\n"

            "  --recordraw         : Record PCM audo in raw files (.sw) instead of .wav\n"
            "  -r --run cmd        : Run this command after each recorded message\n"
            "  -k --kill           : Kill recorded files after user command\n"
            "  -H --hangup         : hangup after playing message\n"
            "  -u --username str   : Set the local endpoint name to str\n"
            "  -p --password str   : Set the gatekeeper password to str\n"
            "  -i --interface ip   : Bind to a specific interface\n"
            "  --listenport port   : Listen on a specific port\n"
            "  -g --gatekeeper host: Specify gatekeeper host.\n"
            "  -n --no-gatekeeper  : Disable gatekeeper discovery.\n"
            "  --require-gatekeeper: Exit if gatekeeper discovery fails.\n"
            "  -D --disable codec  : Disable the specified codec (may be used multiple times)\n"
            "  -P --prefer codec   : Prefer the specified codec (may be used multiple times)\n"
#if PTRACING
            "  -t --trace          : Enable trace, use multiple times for more detail\n"
            "  -o --output         : File for trace output, default is stderr\n"
#endif
            "     --save           : Save arguments in configuration file\n"
            "  -h --help           : Display this help message\n";
    return;
  }

  args.Save("save");

  unsigned callLimit = DEFAULT_MSG_LIMIT;
  if (args.HasOption('l')) {
    callLimit = args.GetOptionString('l').AsInteger();
    if (callLimit > 3600) {
      cout << "warning: maximum call length " << callLimit << " is out of range. Using " << DEFAULT_MSG_LIMIT << " instead\n";
      callLimit = DEFAULT_MSG_LIMIT;
    } else if (callLimit == 0)
      cout << "warning: recorded message call limit disabled\n";
  }
  if (!args.HasOption("no-recordg7231") && !args.HasOption("loop"))
	  cout << "Recorded messages limited to " << callLimit << " seconds\n";
  else
	  cout << "Recording disabled\n";

  PString runCmd;
  if (args.HasOption('r')) {
    runCmd = args.GetOptionString('r');
    cout << "Executing \"" << runCmd << "\" after each message" << endl;
  }

  PDirectory dir;
  if (args.HasOption('d'))
    dir = args.GetOptionString('d');

  int flags = 0;

  if (args.HasOption("no-recordg7231")) {
    cout << "Supressing recording of G723.1 messages" << endl;
    flags |= MyH323EndPoint::NoRecordG7231;
  }
  if (args.HasOption('k')) {
    cout << "Deleting recorded files after processing" << endl;
    if (runCmd.IsEmpty()) 
      cout << "WARNING: recorded files will be deleted even though no run command is present" << endl;
    flags |= MyH323EndPoint::DeleteAfterRecord;
  }

  if (args.HasOption('H'))
    flags |= MyH323EndPoint::HangupAfterPlay;
  
  endpoint = new MyH323EndPoint(callLimit, runCmd, dir, flags);

  PString userName = "OpenH323 Answering Machine v" + GetVersion();
  if (args.HasOption('u'))
    userName = args.GetOptionString('u');
  endpoint->SetLocalUserName(userName);

  if (args.HasOption('p')) {
    const PString password = args.GetOptionString('p');
    endpoint->SetGatekeeperPassword(password);
  }
  
  if (!endpoint->Initialise(args))
    return;

  // start the H.323 listener
  H323ListenerTCP * listener;
  PIPSocket::Address interfaceAddress(INADDR_ANY);
  WORD listenPort = H323EndPoint::DefaultTcpPort;

  if (args.HasOption("listenport"))
    listenPort = (WORD)args.GetOptionString("listenport").AsInteger();

  if (args.HasOption('i'))
    interfaceAddress = PIPSocket::Address(args.GetOptionString('i'));

  listener  = new H323ListenerTCP(*endpoint, interfaceAddress, listenPort);

  if (!endpoint->StartListener(listener)) {
    cout <<  "Could not open H.323 listener port on "
         << listener->GetListenerPort() << endl;
    delete listener;
    return;
  }

  if (args.HasOption('g')) {
    PString gkName = args.GetOptionString('g');
    if (endpoint->SetGatekeeper(gkName, new H323TransportUDP(*endpoint)))
      cout << "Gatekeeper set: " << *endpoint->GetGatekeeper() << endl;
    else {
      cout << "Error registering with gatekeeper at \"" << gkName << '"' << endl;
      return;
    }
  }
  else if (!args.HasOption('n')) {
    cout << "Searching for gatekeeper..." << flush;
    if (endpoint->DiscoverGatekeeper(new H323TransportUDP(*endpoint)))
      cout << "\nGatekeeper found: " << *endpoint->GetGatekeeper() << endl;
    else {
      cout << "\nNo gatekeeper found." << endl;
      if (args.HasOption("require-gatekeeper"))
        return;
    }
  }

  cout << "Waiting for incoming calls for \"" << endpoint->GetLocalUserName() << '"' << endl;

  for (;;) 
    PThread::Current()->Sleep(5000);
}

void OpenAm::Shutdown()
{
	if (endpoint) {
		if (endpoint->IsRegisteredWithGatekeeper())
			endpoint->RemoveGatekeeper();
		delete endpoint;
	}
	exit(0);
}


///////////////////////////////////////////////////////////////

MyH323EndPoint::MyH323EndPoint(unsigned _callLimit,
                               const PString & _runCmd,
                               const PDirectory & _dir,
                               int   _flags)
  : callLimit(_callLimit), runCmd(_runCmd), dir(_dir), flags(_flags)
{
#if OPENAM_VIDEO
  videoSize    = 0;
  videoIsPal   = TRUE;
  frameRate    = DEFAULT_VIDEO_FRAME_RATE;
  videoChannel = DEFAULT_VIDEO_MODE;
#endif
}

BOOL MyH323EndPoint::OnIncomingCall(H323Connection & _conn,
                                    const H323SignalPDU & setupPDU,
                                    H323SignalPDU &)
{
  MyH323Connection & conn = (MyH323Connection &)_conn;

  // see if incoming call is to a getway address
  PString number;
  if (setupPDU.GetDestinationE164(number)) 
    conn.SetE164Number(number);

  return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -