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

📄 vxml.cxx

📁 安装 H323需要的pwlib库
💻 CXX
📖 第 1 页 / 共 5 页
字号:
  opts.SetCallingToken(callingCallToken );  opts.SetDestinationDNR(dest);  opts.SetSourceDNR(source);  opts.SetTimeout(connectTimeout);  opts.SetBridge(bridge);  DoTransfer(opts);  // Wait for the transfer result signal  transferSync.Wait();  return TRUE;}void PVXMLSession::OnTransfer(const PVXMLTransferResult & args){  // transfer has ended, save result  SetVar(args.GetName(), args);  // Signal transfer initiator that the transfer has ended and the VXML can   // continue  transferSync.Signal();}BOOL PVXMLSession::TraverseIf(){  // If 'cond' parameter evaluates to true, enter child entities, else  // go to next element.  PString condition = ((PXMLElement*)currentNode)->GetAttribute("cond");  // Find comparison type  PINDEX location = condition.Find("==");  BOOL isEqual = (location < condition.GetSize());  if (isEqual) {    // Find var name    PString varname = condition.Left(location);    // Find value, skip '=' signs    PString cond_value = condition.Right(condition.GetSize() - (location + 3));        // check if var value equals value from condition and if not skip child elements    PString value = GetVar(varname);    if (cond_value == value) {      PTRACE( 3, "VXMLSess\t\tCondition matched \"" << condition << "\"" );    } else {      PTRACE( 3, "VXMLSess\t\tCondition \"" << condition << "\"did not match, " << varname << " == " << value );      if (currentNode->IsElement()) {        PXMLElement* element = (PXMLElement*) currentNode;        if (element->HasSubObjects()) {          // Step to last child element (really last element is NULL?)          currentNode = element->GetElement(element->GetSize() - 1);        }      }    }  }  else {    PTRACE( 1, "\tPVXMLSession, <if> element contains condition with operator other than ==, not implemented" );    return FALSE;  }  return TRUE;}BOOL PVXMLSession::TraverseExit(){  currentNode = NULL;  forceEnd    = TRUE;  waitForEvent.Signal();  return TRUE;}BOOL PVXMLSession::TraverseSubmit(){  BOOL result = FALSE;  // Do HTTP client stuff here  // Find out what to submit, for now, only support a WAV file  PXMLElement * element = (PXMLElement *)currentNode;  if (!element->HasAttribute("namelist")){    PTRACE(1, "VXMLSess\t<submit> does not contain \"namelist\" parameter");    return FALSE;  }  PString name = element->GetAttribute("namelist");  if (name.Find(" ") < name.GetSize()) {    PTRACE(1, "VXMLSess\t<submit> does not support more than one value in \"namelist\" parameter");    return FALSE;  }  if (!element->HasAttribute("next")) {    PTRACE(1, "VXMLSess\t<submit> does not contain \"next\" parameter");    return FALSE;  }  PString url = element->GetAttribute("next");  if (url.Find( "http://" ) > url.GetSize()) {    PTRACE(1, "VXMLSess\t<submit> needs a full url as the \"next\" parameter");    return FALSE;  }  if (!(GetVar(name + ".type") == "audio/x-wav" )) {    PTRACE(1, "VXMLSess\t<submit> does not (yet) support submissions of types other than \"audio/x-wav\"");    return FALSE;  }  PString fileName = GetVar(name + ".filename");  if (!(element->HasAttribute("method"))) {    PTRACE(1, "VXMLSess\t<submit> does not (yet) support default method type \"get\"");    return FALSE;  }  if ( !PFile::Exists(fileName )) {    PTRACE(1, "VXMLSess\t<submit> cannot find file " << fileName);    return FALSE;  }  PString fileNameOnly;  int pos = fileName.FindLast( "/" );  if (pos < fileName.GetLength()) {    fileNameOnly = fileName.Right( ( fileName.GetLength() - pos ) - 1 );  }  else {    pos = fileName.FindLast("\\");    if (pos < fileName.GetSize()) {      fileNameOnly = fileName.Right((fileName.GetLength() - pos) - 1);    }    else {      fileNameOnly = fileName;    }  }  PHTTPClient client;  PMIMEInfo sendMIME, replyMIME;  if (element->GetAttribute("method") *= "post") {    //                            1         2         3        4123    PString boundary = "--------012345678901234567890123458VXML";    sendMIME.SetAt( PHTTP::ContentTypeTag, "multipart/form-data; boundary=" + boundary);    sendMIME.SetAt( PHTTP::UserAgentTag, "PVXML TraverseSubmit" );    sendMIME.SetAt( "Accept", "text/html" );    // After this all boundaries have a "--" prepended    boundary = "--" + boundary;    // Create the mime header    // First set the primary boundary    PString mimeHeader = boundary + "\r\n";    // Add content disposition    mimeHeader += "Content-Disposition: form-data; name=\"voicemail\"; filename=\"" + fileNameOnly + "\"\r\n";    // Add content type    mimeHeader += "Content-Type: audio/wav\r\n\r\n";    // Create the footer and add the closing of the content with a CR/LF    PString mimeFooter = "\r\n";    // Copy the header, buffer and footer together in one PString    // Load the WAV file into memory    PFile file( fileName, PFile::ReadOnly );    int size = file.GetLength();    PString mimeThing;    // Make PHP happy?    // Anyway, this shows how to add more variables, for when namelist containes more elements    PString mimeMaxFileSize = boundary + "\r\nContent-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n3000000\r\n";    // Finally close the body with the boundary again, but also add "--"    // to show this is the final boundary    boundary = boundary + "--";    mimeFooter += boundary + "\r\n";    mimeHeader = mimeMaxFileSize + mimeHeader;    mimeThing.SetSize( mimeHeader.GetSize() + size + mimeFooter.GetSize() );    // Copy the header to the result    memcpy( mimeThing.GetPointer(), mimeHeader.GetPointer(), mimeHeader.GetLength());    // Copy the contents of the file to the mime result    file.Read( mimeThing.GetPointer() + mimeHeader.GetLength(), size );    // Copy the footer to the result    memcpy( mimeThing.GetPointer() + mimeHeader.GetLength() + size, mimeFooter.GetPointer(), mimeFooter.GetLength());    // Send the POST request to the server    result = client.PostData( url, sendMIME, mimeThing, replyMIME );    // TODO, Later:    // Remove file?    // Load reply from server as new VXML docuemnt ala <goto>  }  else {    if (element->GetAttribute("method") != "get") {      PTRACE(1, "VXMLSess\t<submit> does not (yet) support method type \"" << element->GetAttribute( "method" ) << "\"");      return FALSE;    }    PString getURL = url + "?" + name + "=" + GetVar( name );    client.GetDocument( url, sendMIME, replyMIME );    // TODO, Later:    // Load reply from server as new VXML document ala <goto>  }  if (!result) {    PTRACE( 1, "VXMLSess\t<submit> to server failed with "        << client.GetLastResponseCode() << " "        << client.GetLastResponseInfo() );  }  return result;}BOOL PVXMLSession::TraverseProperty(){  PXMLElement* element = (PXMLElement *) currentNode;  if (element->HasAttribute("name"))    SetVar(element->GetAttribute("name"), element->GetAttribute("value"));  return TRUE;}BOOL PVXMLSession::TraverseMenu(){  BOOL result = FALSE;  PVXMLGrammar * newGrammar = new PVXMLDigitsGrammar((PXMLElement*) currentNode, 1, 1, "" );  LoadGrammar(newGrammar);  result = TRUE;  return result;}BOOL PVXMLSession::TraverseChoice(const PString & grammarResult){  // Iterate over all choice elements starting at currentnode  BOOL result = FALSE;  PXMLElement* element = (PXMLElement *) currentNode;  // Current node is a choice element  PString dtmf = element->GetAttribute( "dtmf" );  if (dtmf.IsEmpty())    dtmf = PString(PString::Unsigned, defaultDTMF);  // Check if DTMF value for grammarResult matches the DTMF value for the choice  if (dtmf == grammarResult) {    // Find the form at next parameter    PString formID = element->GetAttribute( "next" );    PTRACE(2, "VXMLsess\tFound form id " << formID );    if (!formID.IsEmpty()) {      formID = formID.Right( formID.GetLength() - 1 );      currentNode = FindForm( formID );      if (currentNode != NULL)        result = TRUE;    }  }  return result;}BOOL PVXMLSession::TraverseVar(){  BOOL result = FALSE;  PXMLElement* element = (PXMLElement *) currentNode;  PString name = element->GetAttribute( "name" );  PString expr = element->GetAttribute( "expr" );  if (name.IsEmpty() || expr.IsEmpty()) {    PTRACE( 1, "VXMLSess\t<var> has a problem with its parameters, name=\"" << name << "\", expr=\"" << expr << "\"" );  }  else {    SetVar(name, expr);    result = TRUE;  }  return result;}void PVXMLSession::OnEndRecording(const PString & /*channelName*/){  //SetVar(channelName + ".size", PString(incomingChannel->GetWAVFile()->GetDataLength() ) );  //SetVar(channelName + ".type", "audio/x-wav" );  //SetVar(channelName + ".filename", incomingChannel->GetWAVFile()->GetName() );}void PVXMLSession::Trigger(){  waitForEvent.Signal();}/////////////////////////////////////////////////////////////////////////////////////////PVXMLGrammar::PVXMLGrammar(PXMLElement * _field)  : field(_field), state(PVXMLGrammar::NOINPUT){}//////////////////////////////////////////////////////////////////PVXMLMenuGrammar::PVXMLMenuGrammar(PXMLElement * _field)  : PVXMLGrammar(_field){}//////////////////////////////////////////////////////////////////PVXMLDigitsGrammar::PVXMLDigitsGrammar(PXMLElement * _field, PINDEX _minDigits, PINDEX _maxDigits, PString _terminators)  : PVXMLGrammar(_field),  minDigits(_minDigits),  maxDigits(_maxDigits),  terminators(_terminators){  PAssert(_minDigits <= _maxDigits, "Error - invalid grammar parameter");}BOOL PVXMLDigitsGrammar::OnUserInput(const char ch){  // Ignore any other keys if we've already filled the grammar  if (state == PVXMLGrammar::FILLED || state == PVXMLGrammar::NOMATCH)    return TRUE;  // is this char the terminator?  if (terminators.Find(ch) != P_MAX_INDEX) {    state = (value.GetLength() >= minDigits && value.GetLength() <= maxDigits) ?       PVXMLGrammar::FILLED :       PVXMLGrammar::NOMATCH;    return TRUE;  }  // Otherwise add to the grammar and check to see if we're done  value += ch;  if (value.GetLength() == maxDigits) {    state = PVXMLGrammar::FILLED;   // the grammar is filled!    return TRUE;  }  return FALSE;}void PVXMLDigitsGrammar::Stop(){  // Stopping recognition here may change the state if something was  // recognized but it didn't fill the number of digits requested  if (!value.IsEmpty())    state = PVXMLGrammar::NOMATCH;  // otherwise the state will stay as NOINPUT}//////////////////////////////////////////////////////////////////PVXMLChannel::PVXMLChannel(unsigned _frameDelay, PINDEX frameSize)  : PDelayChannel(DelayReadsAndWrites, _frameDelay, frameSize){  vxmlInterface = NULL;   sampleFrequency = 8000;  closed          = FALSE;  recording       = FALSE;  recordable      = NULL;  playing         = FALSE;  silentCount     = 20;         // wait 20 frames before playing the OGM  paused          = FALSE;}BOOL PVXMLChannel::Open(PVXMLChannelInterface * _vxmlInterface){  vxmlInterface = _vxmlInterface;  return TRUE;}PVXMLChannel::~PVXMLChannel(){  EndRecording();}BOOL PVXMLChannel::IsOpen() const{  return !closed;}BOOL PVXMLChannel::Close(){   closed = TRUE;   PDelayChannel::Close();   return TRUE; }PString PVXMLChannel::AdjustWavFilename(const PString & ofn){  if (wavFilePrefix.IsEmpty())    return ofn;  PString fn = ofn;  // add in suffix required for channel format, if any  PINDEX pos = ofn.FindLast('.');  if (pos == P_MAX_INDEX) {    if (fn.Right(wavFilePrefix.GetLength()) != wavFilePrefix)      fn += wavFilePrefix;  }  else {    PString basename = ofn.Left(pos);    PString ext      = ofn.Mid(pos+1);    if (basename.Right(wavFilePrefix.GetLength()) != wavFilePrefix)      basename += wavFilePrefix;    fn = basename + "." + ext;  }  return fn;}PWAVFile * PVXMLChannel::CreateWAVFile(const PFilePath & fn, BOOL recording){   PWAVFile * wav = PWAVFile::format(mediaFormat);  if (wav == NULL) {    PTRACE(1, "VXML\tWAV file format " << mediaFormat << " not known");    return NULL;  }  wav->SetAutoconvert();  if (!wav->Open(AdjustWavFilename(fn),                  recording ? PFile::WriteOnly : PFile::ReadOnly,                 PFile::ModeDefault))    PTRACE(1, "VXML\tCould not open WAV file " << wav->GetName());  else if (recording) {    wav->SetChannels(1);    wav->SetSampleRate(8000);    wav->SetSampleSize(16);    return wav;  }     else if (!wav->IsValid())    PTRACE(1, "VXML\tWAV file header invalid for " << wav->GetName());  else if (wav->GetSampleRate() != sampleFrequency)    PTRACE(1, "VXML\tWAV file has unsupported sample frequency " << wav->GetSampleRate());  else if (wav->GetChannels() != 1)    PTRACE(1, "VXML\tWAV file has unsupported channel count " << wav->GetChannels());  else {    wav->SetAutoconvert();   /// enable autoconvert    PTRACE(4, "VXML\tOpened WAV file " << wav->GetName());    return wav;  }  delete wav;  return NULL;}BOOL PVXMLChannel::Write(const void * buf, PINDEX len){  if (closed)    return FALSE;  channelWriteMutex.Wait();  // let the recordable do silence det

⌨️ 快捷键说明

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