Esempio n. 1
0
static VXIbool VXIrecSupportsHotwordTransfer(
  struct VXIrecInterface * pThis,
  const VXIMap  * properties,
  const VXIchar * transferDest)
{
  VXIbool result = FALSE;

  // this is really just to demonstrate how the platform could
  // support hotword for some type of transfers, but not others.
  // this could just as easily been based on other properties of
  // the transfer. i.e., destination type, required line type, etc...
  const VXIValue* dval = VXIMapGetProperty(properties, TEL_TRANSFER_TYPE);
  if( dval && VXIValueGetType(dval) == VALUE_STRING ){
    const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
	if (wcscmp(hid, L"consultation") == 0)
      return FALSE;
  }

  dval = VXIMapGetProperty(properties, L"SupportsHotwordTransfer");
  if( dval && VXIValueGetType(dval) == VALUE_STRING ){
    const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
	result = (wcscmp(hid, L"true") == 0) ? TRUE : FALSE;
  }

  return result;
}
Esempio n. 2
0
/**
 * Sample object setting the defaults document for subsequent calls
 *
 * @param properties    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param parameters    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param execute       [IN]  Specifies whether the object should be
 *                            executed (true) or simply validated (false)
 * @param result        [OUT] See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 *
 * @result VXIobj_RESULT_SUCCESS on success
 */
static VXIobjResult 
ProcessComSpeechworksSetDefaultsObject (struct VXIobjectInterface *pThis,
					const VXIMap              *properties,
					const VXIMap              *parameters,
					VXIbool                    execute,
					VXIValue                 **result)
{
  static const wchar_t func[] = L"ProcessComSpeechworksSetDefaults";
  GET_VXIOBJECT (pThis, sbObject, log, rc);

  if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;

  if(execute) {

    const VXIchar *defaults = NULL;

    const VXIValue *val = VXIMapGetProperty(parameters, L"defaults");
    if (! val) {
      Error(log, 202, L"%s%s", L"parameter", L"defaults");
      return VXIobj_RESULT_INVALID_PROP_VALUE;
    } else if (VXIValueGetType(val) != VALUE_STRING) {
      Error(log, 203, L"%s%s%s%d", L"parameter", L"defaults", 
	    L"type", VXIValueGetType(val));
      return VXIobj_RESULT_INVALID_PROP_VALUE;
    }
    defaults = VXIStringCStr(reinterpret_cast<const VXIString *>(val));
    if (! defaults[0]) {
      Error(log, 204, L"%s%s%s%s", L"parameter", L"defaults", L"value", defaults);
      return VXIobj_RESULT_INVALID_PROP_VALUE;
    }

    
    // Hack to set the defaults document
    VXIobjectAPI *objectAPI = (VXIobjectAPI *) pThis;
    if ( ! objectAPI ) { rc = VXIobj_RESULT_INVALID_ARGUMENT; return rc; }
    VXIplatform *plat = objectAPI->resources->platform;
    VXIMap *vxiProperties = VXIMapCreate();
    VXIString * valstr = VXIStringCreate(defaults);
    VXIMapSetProperty(vxiProperties, VXI_PLATFORM_DEFAULTS, (VXIValue *) valstr);
    plat->VXIinterpreter->SetProperties(plat->VXIinterpreter,
					vxiProperties);

    // Create the result object
    VXIMap *resultObj = VXIMapCreate();
    if(resultObj == NULL) {
      Error(log, 100, NULL);
      return VXIobj_RESULT_OUT_OF_MEMORY;
    }
    *result = reinterpret_cast<VXIValue *>(resultObj);

    // Set the result object's status field to 'success'
    VXIMapSetProperty(resultObj, L"status",
		      reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
  }

  return VXIobj_RESULT_SUCCESS;
}
Esempio n. 3
0
// Begin a session
//
   static 
VXItelResult OSBtelBeginSession(VXItelInterface * pThis, VXIMap *sessionArgs)
{
   OSBtelImpl *impl = ToOSBtelImpl(pThis);
   impl->live = -1; // not quite live yet, other threads shouldn't its access resources

   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"tel BeginSession");
   const VXIchar *callId = NULL;
   const VXIValue *val;
   val = VXIMapGetProperty(sessionArgs, L"callid");

   impl->pExitGuard = new OsBSem(OsBSem::Q_PRIORITY, OsBSem::FULL);
   impl->transferred = 0;
   impl->callId = NULL;
   if ((val) && (VXIValueGetType(val) == VALUE_STRING))
   {
      callId = VXIStringCStr((const VXIString *) val);
      int len = strlen((char*)callId) + 1;

      VXIchar *vxiCallid = (VXIchar *) calloc(len, sizeof(VXIchar));
      if (vxiCallid)
      {
         strncpy((char*)vxiCallid, (char*)callId, len);
         impl->callId = vxiCallid;
      }
      else
         return VXItel_RESULT_OUT_OF_MEMORY;
   }
   else
      return VXItel_RESULT_INVALID_ARGUMENT;


   impl->live = 1; // live
   return VXItel_RESULT_SUCCESS;
}
Esempio n. 4
0
static VXIrecResult VXIrecHotwordTransfer
(
  struct VXIrecInterface * pThis,
  struct VXItelInterface * tel,
  const VXIMap *properties,
  const VXIchar* transferDest,
  VXIrecTransferResult  ** transferResult
)
{
  const wchar_t* fnname = L"VXIrecHotwordTransfer";
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
  
  VXIrecResult res = VXIrec_RESULT_SUCCESS;

  // this is probably not how it would be done in real life...but for this
  // sample app it will suffice:
  // Do the transfer
  int activeGrammars = tp->GetActiveCount();

  VXIMap *xferResp = NULL;
  VXItelResult xferResult = tel->TransferBridge(tel, properties, transferDest, &xferResp);
  if (xferResult != VXItel_RESULT_SUCCESS) {
    res = VXIrec_RESULT_FAILURE;
  }
  else if (activeGrammars == 0) {
    *transferResult = new VXIrecTransferResult();
    (*transferResult)->Destroy = TransferResultDestroy;
    (*transferResult)->utterance = NULL;
    (*transferResult)->markname = NULL;
    (*transferResult)->marktime = 0;
    (*transferResult)->xmlresult = NULL;

    const VXIValue * v = VXIMapGetProperty(xferResp, TEL_TRANSFER_DURATION);
    if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER)
      (*transferResult)->duration = VXIIntegerValue(reinterpret_cast<const VXIInteger*>(v));

    v = VXIMapGetProperty(xferResp, TEL_TRANSFER_STATUS);
    if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER) {
      long temp = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(v));
      (*transferResult)->status = VXItelTransferStatus(temp);
    }

	VXIMapDestroy(&xferResp);
  }
  else {
    // get input from the user.
    VXIrecRecognitionResult *recResult = NULL;
    VXIrecResult localRes = pThis->Recognize(pThis, properties, &recResult);
	if (localRes == VXIrec_RESULT_SUCCESS){
      *transferResult = new VXIrecTransferResult();
	  if ((*transferResult) == NULL) {
        recResult->Destroy(&recResult);
        VXIMapDestroy(&xferResp);
        return VXIrec_RESULT_OUT_OF_MEMORY;
	  }

      // setup the transfer result by first copying the 
	  // RecResult.
      (*transferResult)->Destroy = TransferResultDestroy;
      (*transferResult)->utterance = recResult->utterance;
      (*transferResult)->markname = recResult->markname;
	  (*transferResult)->marktime = recResult->marktime;
      (*transferResult)->xmlresult = recResult->xmlresult;
	  (*transferResult)->duration = 0;
	  (*transferResult)->status = VXItel_TRANSFER_FAR_END_DISCONNECT;

      // we no long need the rec result (but we don't want the VXIContent
	  // fields destroyed).
	  recResult->utterance = NULL;
	  recResult->xmlresult = NULL;
	  recResult->Destroy(&recResult);

      // translate the status and duration to the transfer result fields.
	  // since this code is simply so that Hotword transfers work, any
	  // valid recognition (ignoring noinput and nomatch) will set the
	  // transfer to "near_end_disconnect".  Otherwise, we pretend that
	  // the other end terminated the transfer.
	  if((*transferResult)->xmlresult){
	    // we're going to ignore noinput and nomatch results.
        const VXIchar * contentType;
        const VXIbyte * content;
        VXIulong contentSize = 0; 
        VXIContentValue((*transferResult)->xmlresult, &contentType, &content, &contentSize);

	    // we're going to ignore noinput and nomatch results.
        if (   !wcsstr((VXIchar*)content, L"<noinput/>")
			&& !wcsstr((VXIchar*)content, L"<nomatch/>")){
          (*transferResult)->status = VXItel_TRANSFER_NEAR_END_DISCONNECT;
        }
      }

	  const VXIValue * v = VXIMapGetProperty(xferResp, TEL_TRANSFER_DURATION);
	  if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER)
	    (*transferResult)->duration = VXIIntegerValue(reinterpret_cast<const VXIInteger*>(v));

	  VXIMapDestroy(&xferResp);
	}
  }

  return res; 
}
Esempio n. 5
0
static VXIrecResult VXIrecLoadGrammarOption(VXIrecInterface * pThis,
                                      const VXIMap    * properties,
                                      const VXIVector * gramChoice,
                                      const VXIVector * gramValue,
                                      const VXIVector * gramAcceptance,
                                      const VXIbool     isDTMF,
                                      VXIrecGrammar  ** gram)
{
  const wchar_t* fnname = L"VXIrecLoadGrammarOption";
  std::ostringstream srgs_version;
  vxistring srgs_wide_version;
  VXIunsigned num_choices;
  VXIvalueType value_type;
  const VXIValue *utterance_value;
  // Check the arguments
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
    
  if (gram == NULL) {
    logger = VXIrec_RESULT_INVALID_ARGUMENT;
    return VXIrec_RESULT_INVALID_ARGUMENT;
  }

  //  DEBUG
  if (voiceglue_loglevel() >= LOG_DEBUG)
  {
      std::ostringstream logstring;
      logstring << "VXIrecLoadGrammarOption called with type "
		<< (isDTMF ? "DTMF" : "speech")
		<< ", choices "
		<< VXIValue_to_Std_String ((VXIValue *) gramChoice)
		<< ", values "
		<< VXIValue_to_Std_String ((VXIValue *) gramValue)
		<< ", properties "
		<< VXIValue_to_Std_String ((const VXIValue *) properties);
      voiceglue_log ((char) LOG_DEBUG, logstring);
  };

  tp->ShowPropertyValue(properties);

  //  Convert to SRGS grammar
  num_choices = VXIVectorLength (gramChoice);
  srgs_version << "<rule id=\"choice\">\n  <one-of>\n";
  for (VXIunsigned choice_num = 0; choice_num < num_choices; ++choice_num)
  {
      srgs_version << "    <item> ";
      utterance_value = VXIVectorGetElement (gramChoice, choice_num);
      value_type = VXIValueGetType (utterance_value);
      if (value_type == VALUE_INTEGER)
      {
	  srgs_version << VXIIntegerValue ((const VXIInteger*) utterance_value);
      }
      else if (value_type == VALUE_LONG)
      {
	  srgs_version << VXILongValue ((const VXILong*) utterance_value);
      }
      else if (value_type == VALUE_ULONG)
      {
	  srgs_version << VXIULongValue ((const VXIULong*) utterance_value);
      }
      else if (isDTMF)
      {
	  srgs_version << VXIchar_to_Std_String (
	      VXIStringCStr ((VXIString *) utterance_value));
      }
      else
      {
	  srgs_version << (choice_num + 1);
      };
      srgs_version << " <tag>"
		   << VXIchar_to_Std_String (
		       VXIStringCStr (
			   (VXIString *) VXIVectorGetElement
			   (gramValue, choice_num)))
		   << "</tag> </item>\n";
  };
  srgs_version << "  </one-of>\n</rule>\n";
  srgs_wide_version = Std_String_to_vxistring (srgs_version.str());
  return VXIrecLoadGrammarFromString
      (pThis,
       properties,
       L"text/x-grammar-choice-dtmf",
       (const VXIchar *) srgs_wide_version.c_str(),
       gram);
  
  VXIrecGrammar * gp = NULL;
  
  vxistring srgsGram;
  if( !tp->OptionToSRGS(properties, gramChoice, gramValue, 
                       gramAcceptance, isDTMF, srgsGram) )
    return VXIrec_RESULT_FAILURE;

  // Parsing SRGS grammar.
  // NOTES: The parsing is very simple, therefore it may not work
  // for complex grammar.  As you know, this is a simulator!!!
  
  VXIrecGrammar * gramPtr = tp->ParseSRGSGrammar(srgsGram, properties, isDTMF);
  if( gramPtr == NULL ) return VXIrec_RESULT_FAILURE;
  tp->AddGrammar(gramPtr);
  *gram = ToVXIrecGrammar(gramPtr);

  return VXIrec_RESULT_SUCCESS;
}
Esempio n. 6
0
/**
 * Validate an object, performing validity checks without execution
 *
 * @param properties  [IN] Map containing properties and attributes for
 *                      the <object> as specified in the VoiceXML
 *                      specification except that "expr" and "cond" are
 *                      always omitted (are handled by the interpreter).
 * @param parameters  [IN] Map containing parameters for the <object> as
 *                      specified by the VoiceXML <param> tag. The keys
 *                      of the map correspond to the parameter name ("name"
 *                      attribute) while the value of each key corresponds
 *                      to a VXIValue based type. See Execute( ) above 
 *                      for details.
 *
 * @return        VXIobj_RESULT_SUCCESS on success,
 *                VXIobj_RESULT_NON_FATAL_ERROR on error, 
 *                VXIobj_RESULT_UNSUPPORTED for unsupported object types
 *                 (this will cause interpreter to throw the correct event)
 */
static
VXIobjResult VXIobjectValidate(struct VXIobjectInterface *pThis,
                               const VXIMap              *properties,
                               const VXIMap              *parameters)
{
  static const wchar_t func[] = L"VXIobjectValidate";
  GET_VXIOBJECT (pThis, sbObject, log, rc);
  Diag (log, LOG_API, func, L"entering: 0x%p, 0x%p, 0x%p", 
  pThis, properties, parameters);

  if(properties == NULL) {
    Error (log, 201, NULL);
    return VXIobj_RESULT_INVALID_ARGUMENT;
  }

  // Get the name of the object to execute
  const VXIValue *val = VXIMapGetProperty(properties, OBJECT_CLASS_ID);
  if(val == NULL) {
    Error(log, 202, L"%s%s", L"parameter", OBJECT_CLASS_ID);
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  } else if (VXIValueGetType(val) != VALUE_STRING) {
    Error(log, 203, L"%s%s%s%d", L"parameter", OBJECT_CLASS_ID,
    L"type", VXIValueGetType(val));
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }
  const VXIchar *classID = VXIStringCStr((VXIString *)val);

  // Handle the object
  if (::wcscmp(classID, L"com.vocalocity.diag") == 0) {
    //
    // Sample diagnostic logging object
    // 
    rc = ProcessComSpeechworksDiagObject(pThis, properties, parameters, false,
           NULL);
    if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  }
  else if (::wcscmp(classID, L"com.vocalocity.echo") == 0) {
    //
    // Sample object echoing back all attributes and parameters
    // 
    rc = ProcessComSpeechworksEchoObject(pThis, properties, parameters, false,
           NULL);
    if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  } 
  else if (::wcscmp(classID, L"com.vocalocity.saveRecording") == 0) {
    //
    // Sample object that saves a recording to a file
    // 
    rc = ProcessComSpeechworksSaveRecordingObject(pThis, properties, 
              parameters, false, NULL);
    if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  } 
  else if (::wcscmp(classID, L"com.vocalocity.setDefaults") == 0) {
    //
    // Sample object that sets the defaults document for subsequent
    // calls. This is really a hack and not recommended. This was
    // done more for fun than any value.
    // 
    rc = ProcessComSpeechworksSetDefaultsObject(pThis, properties, 
              parameters, false, NULL);
    if(rc != VXIobj_RESULT_SUCCESS) rc = VXIobj_RESULT_NON_FATAL_ERROR;
  } 
  else {
    //
    // Unsupported object
    //
    rc = VXIobj_RESULT_UNSUPPORTED;
  }

  Diag (log, LOG_API, func, L"exiting: returned %d", rc);
  return rc;
}
Esempio n. 7
0
/**
 * Sample object to save a recording to a file
 *
 * @param properties    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param parameters    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param execute       [IN]  Specifies whether the object should be
 *                            executed (true) or simply validated (false)
 * @param result        [OUT] See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 *
 * @result VXIobj_RESULT_SUCCESS on success
 */
static VXIobjResult 
ProcessComSpeechworksSaveRecordingObject (struct VXIobjectInterface *pThis,
            const VXIMap             *properties,
            const VXIMap             *parameters,
            VXIbool                    execute,
            VXIValue                 **result)
{
  static const wchar_t func[] = L"ProcessComSpeechworksSaveRecordingObject";
  GET_VXIOBJECT (pThis, sbObject, log, rc);

  if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;

  // Get the recording, MIME type, size, and destination path
  const VXIbyte *recording = NULL;
  const VXIchar *type = NULL, *dest = NULL;
  VXIulong size = 0;
  const VXIValue *val = VXIMapGetProperty(parameters, L"recording");
  if (! val) {
    Error(log, 202, L"%s%s", L"parameter", L"recording");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  } else if (VXIValueGetType(val) != VALUE_CONTENT) {
    Error(log, 203, L"%s%s%s%d", L"parameter", L"recording", 
    L"type", VXIValueGetType(val));
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }
  if (VXIContentValue(reinterpret_cast<const VXIContent *>(val),
          &type, &recording, &size) != VXIvalue_RESULT_SUCCESS) {
    Error(log, 204, L"%s%s", L"parameter", L"recording");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  } else if (size < 1) {
    Error(log, 204, L"%s%s%s%d", L"parameter", L"recording.size", 
    L"value", L"size");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }
  
  val = VXIMapGetProperty(parameters, L"dest");
  if (! val) {
    Error(log, 202, L"%s%s", L"parameter", L"dest");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  } else if (VXIValueGetType(val) != VALUE_STRING) {
    Error(log, 203, L"%s%s%s%d", L"parameter", L"dest", 
    L"type", VXIValueGetType(val));
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }
  dest = VXIStringCStr(reinterpret_cast<const VXIString *>(val));
  if (! dest[0]) {
    Error(log, 204, L"%s%s%s%s", L"parameter", L"dest", L"value", dest);
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }

  if(execute) {
    // Convert the destination to narrow characters, use an upside
    // down question mark for unsupported Unicode characters
    size_t len = wcslen(dest);
    char *ndest = new char [len + 1];
    if (! ndest) {
      Error(log, 100, NULL);
      return VXIobj_RESULT_OUT_OF_MEMORY;
    }
    for (size_t i = 0; i <= len; i++)
      ndest[i] = (dest[i] & 0xff00 ? '\277' : static_cast<char>(dest[i]));
    
    // Open the destination and save the file
    size_t totWritten = 0;
#ifdef VXIOBJECT_PERMIT_FILE_WRITES
    FILE *fp = fopen(ndest, "wb");
    delete [] ndest;
    if (fp) {
      do {
  size_t w = fwrite(&recording[totWritten], 1, 
        ((size_t) size) - totWritten, fp);
  totWritten += w;
      } while ((totWritten < (size_t) size) && (! ferror(fp)));
      
      fclose(fp);
    } else {
      Error(log, 205, L"%s%s%s%d", L"file", dest, L"errno", errno);
    }
#else
    Error(log, 206, L"%s%s", L"file", dest);
#endif

    // Create the result object
    VXIMap *resultObj = VXIMapCreate();
    if(resultObj == NULL) {
      Error(log, 100, NULL);
      return VXIobj_RESULT_OUT_OF_MEMORY;
    }
    *result = reinterpret_cast<VXIValue *>(resultObj);

    // Set the result object's status field to 'success' or 'failure'
    if (totWritten == (size_t) size)
      VXIMapSetProperty(resultObj, L"status",
               reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
    else
      VXIMapSetProperty(resultObj, L"status", 
               reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure")));
  }

  return VXIobj_RESULT_SUCCESS;
}
Esempio n. 8
0
/**
 * Sample diagnostic logging object
 *
 * @param properties    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param parameters    [IN]  See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 * @param execute       [IN]  Specifies whether the object should be
 *                            executed (true) or simply validated (false)
 * @param result        [OUT] See description in VXIobjectExecute() 
 *                            or VXIobjectValidate()
 *
 * @result VXIobj_RESULT_SUCCESS on success
 */
static VXIobjResult 
ProcessComSpeechworksDiagObject (struct VXIobjectInterface *pThis,
                                 const VXIMap              *properties,
                                 const VXIMap              *parameters,
                                 VXIbool                    execute,
         VXIValue                 **result)
{
  static const wchar_t func[] = L"ProcessComSpeechworksDiagObject";
  GET_VXIOBJECT (pThis, sbObject, log, rc);

  if((execute) && (result == NULL)) return VXIobj_RESULT_INVALID_ARGUMENT;
  if((! properties) || (! parameters)) return VXIobj_RESULT_INVALID_ARGUMENT;

  // Get the tag ID
  const VXIValue *val = VXIMapGetProperty(parameters, L"tag");
  if(val == NULL) {
    Error(log, 202, L"%s%s", L"parameter", L"tag");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  } 
  VXIint tag;
  switch (VXIValueGetType(val)) {
  case VALUE_INTEGER:
    tag = VXIIntegerValue((VXIInteger *)val);
    break;
  case VALUE_STRING: {
    wchar_t *ptr;
    tag = ::wcstol(VXIStringCStr((VXIString *)val), &ptr, 10);
    } break;
  default:
    Error(log, 203, L"%s%s%s%d", L"parameter", L"tag", 
    L"type", VXIValueGetType(val));
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }

  // Get the message string
  val = VXIMapGetProperty(parameters, L"message");
  if(val == NULL) {
    Error(log, 202, L"%s%s", L"parameter", L"message");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }

  // Check whether the message was sent in "data" or "ref" format.
  // If it is "ref", we need to retrieve it in the embedded map.
  const VXIchar *messageStr = NULL;
  switch (VXIValueGetType(val)) {
  case VALUE_MAP: {
    const VXIValue *val2 = VXIMapGetProperty((const VXIMap *)val, 
                                             OBJECT_VALUE);
    if (VXIValueGetType(val2) == VALUE_STRING)
      messageStr = VXIStringCStr((VXIString *)val2);
    } break;
  case VALUE_STRING:
    messageStr = VXIStringCStr((VXIString *)val);
    break;
  default:
    Error(log, 203, L"%s%s%s%d", L"parameter", L"message", 
    L"type", VXIValueGetType(val));
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }

  if ((! messageStr) || (! messageStr[0])) {
    Error(log, 204, L"%s%s", L"parameter", L"message");
    return VXIobj_RESULT_INVALID_PROP_VALUE;
  }
  
  if(execute) {
    // Print a diagnostic message using the retrieved arguments.
    // To see this message, you must enable client.log.diagTag.xxx
    // in your VXIclient configuration file, where 'xxx' is the 
    // value of client.object.diagLogBase defined in the same file.
    VXIlogResult rc = Diag (log, tag, NULL, messageStr);

    // Create the result object
    VXIMap *resultObj = VXIMapCreate();
    if(resultObj == NULL) {
      Error(log, 100, NULL);
      return VXIobj_RESULT_OUT_OF_MEMORY;
    }
    *result = reinterpret_cast<VXIValue *>(resultObj);

    // Set the result object's status field to 'success' or 'failure'
    if(rc == VXIlog_RESULT_SUCCESS)
      VXIMapSetProperty(resultObj, L"status",
               reinterpret_cast<VXIValue *>(VXIStringCreate(L"success")));
    else
      VXIMapSetProperty(resultObj, L"status", 
               reinterpret_cast<VXIValue *>(VXIStringCreate(L"failure")));
  }

  return VXIobj_RESULT_SUCCESS;
}
Esempio n. 9
0
static void ShowPropertyValues(const VXIchar *key,
           const VXIValue *value, VXIunsigned PROP_TAG,
           VXIlogInterface *log)
{
  VXIchar subtag[512] = L"Property";
  if( value == 0 ) return;
  VXIvalueType type = VXIValueGetType(value);
  {
    switch( type )
    {
      case VALUE_INTEGER:
        wcscpy(subtag, L"Property:INT");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value));
        break;
      case VALUE_FLOAT:
        wcscpy(subtag, L"Property:FLT");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%f", key, VXIFloatValue((const VXIFloat*)value));
        break;
      case VALUE_BOOLEAN:     
        wcscpy(subtag, L"Property:BOOL");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value));
        break;
      case VALUE_STRING:
        wcscpy(subtag, L"Property:STR");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%s", key, VXIStringCStr((const VXIString*)value));
        break;
      case VALUE_PTR:
        wcscpy(subtag, L"Property:PTR");
        Diag(log, PROP_TAG, subtag, 
             L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value));
        break;
      case VALUE_CONTENT:
        wcscpy(subtag, L"Property:CNT");
        Diag(log, PROP_TAG, subtag, 
             L"%s(content)=0x%p", key, value);
        break;
      case VALUE_MAP:
        {
          VXIchar endtag[512];
          const VXIchar *mykey = key ? key : L"NULL";
          wcscpy(subtag, L"Property:MAP:BEG");
          wcscpy(endtag, L"Property:MAP:END");
          Diag(log, PROP_TAG, subtag, L"%s", mykey);
          const VXIchar *key = NULL;
          const VXIValue *gvalue = NULL;

          VXIMapIterator *it = VXIMapGetFirstProperty((const VXIMap*)value, &key, &gvalue);
          int ret = 0;
          while( ret == 0 && key && gvalue )
          {
            ShowPropertyValues(key, gvalue, PROP_TAG, log);
            ret = VXIMapGetNextProperty(it, &key, &gvalue);
          }
          VXIMapIteratorDestroy(&it);         
          Diag(log, PROP_TAG, endtag, L"%s", mykey);
        }   
        break;
      case VALUE_VECTOR:
        {
          VXIunsigned vlen = VXIVectorLength((const VXIVector*)value);
          for(VXIunsigned i = 0; i < vlen; ++i)
          {
            const VXIValue *gvalue = VXIVectorGetElement((const VXIVector*)value, i);
            ShowPropertyValues(L"Vector", gvalue, PROP_TAG, log);
          }
        }
        break;
      default:
        Diag(log, PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN");
    }          
  }
  return;
}
Esempio n. 10
0
// Open the entry
VXIcacheResult SBcacheEntryDetails::Open(VXIlogInterface       *log,
					 const SBcacheString   &moduleName,
					 const SBcacheKey      &key,
					 const SBcachePath     &path,
					 VXIcacheOpenMode       mode,
					 VXIint32               flags,
					 VXIulong               maxSizeBytes,
					 const VXIMap          *properties,
					 VXIMap                *streamInfo,
					 VXIcacheStream       **stream)
{
  VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  FILE *filePtr = NULL;

  // Lock and copy input data
  switch ( mode ) {
  case CACHE_MODE_WRITE:
    if ( _rwMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    } else {
      // If the open fails due to directory not existing, call
      // path.CreateDirectories( ) to create the dir tree then open
      // again
      if ( ! _invalidated ) {
	filePtr = fopen (path.c_str( ), "wb");
        int retries = 10; // work around possible race condition w/ rmdir
	while ((retries-- > 0) &&
            ( ! filePtr ) &&
            ( path.CreateDirectories( ) == VXIcache_RESULT_SUCCESS ))
	  filePtr = fopen (path.c_str( ), "wb");
      }

      if ( ! filePtr ) {
	if ( _invalidated ) {
	  // Invalidated or another thread attempted an open for write
	  // and failed, we only got here due to a race condition
	  // where we were waiting on the mutex to start our write
	  // before the failure/invalidation happened by the previous
	  // writer
	  rc = VXIcache_RESULT_FAILURE;
	} else {
	  // File open error
	  LogIOError (log, 213, path);
	  rc = VXIcache_RESULT_IO_ERROR;
	}

	_fileExists = false;
	_rwMutex.Unlock( );
      } else {
	_fileExists = true;
	_creationCost = CACHE_CREATION_COST_DEFAULT;
	_flags = flags;
	_sizeBytes = 0;

        // Only set the path and key if they differ
        if (path != _path || key != _key) {
          _path = path;
          _key = key;
        }

	// Load properties
	if ( properties ) {
	  const VXIValue *value =
	    VXIMapGetProperty (properties, CACHE_CREATION_COST);
	  if ( value ) {
	    if ( VXIValueGetType(value) == VALUE_INTEGER )
	      _creationCost = (VXIcacheCreationCost)
		VXIIntegerValue ((const VXIInteger *) value);
	    else
	      Error (log, 301, L"%s%d", L"VXIValueType",
		     VXIValueGetType(value));
	  }
	}
      }
    }
    break;

  case CACHE_MODE_READ:
    if ( _rwMutex.StartRead( ) != VXItrd_RESULT_SUCCESS ) {
      Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, reader");
      rc = VXIcache_RESULT_SYSTEM_ERROR;
    } else {
      if (( _fileExists ) && ( ! _invalidated )) {
	filePtr = fopen (_path.c_str( ), "rb");
	if ( ! filePtr ) {
	  _fileExists = false;
	  LogIOError (log, 214, _path);
	  _rwMutex.EndRead( );
	  rc = VXIcache_RESULT_IO_ERROR;
	}
      } else {
	// Invalidated or another thread attempted an open for write
	// and failed, we only got here due to a race condition where
	// we were waiting on the mutex to start our read before the
	// failure/invalidation happened by the writer
	_rwMutex.EndRead( );
	rc = VXIcache_RESULT_FAILURE;
      }
    }
    break;

  default:
    Error (log, 215, L"%s%d", L"mode", mode);
    rc = VXIcache_RESULT_UNSUPPORTED;
  }

  if ( rc == VXIcache_RESULT_SUCCESS ) {
    // Update the accessed time
    _lastAccessed = time(0);
    if (mode == CACHE_MODE_WRITE)
      _lastModified = _lastAccessed;

    // Return stream information
    if ( streamInfo ) {
      if (( VXIMapSetProperty (streamInfo, CACHE_INFO_LAST_MODIFIED,
			       (VXIValue *) VXIIntegerCreate(_lastModified)) !=
	    VXIvalue_RESULT_SUCCESS ) ||
	  ( VXIMapSetProperty (streamInfo, CACHE_INFO_SIZE_BYTES,
			       (VXIValue *) VXIIntegerCreate (_sizeBytes)) !=
	    VXIvalue_RESULT_SUCCESS )) {
	Error (log, 100, NULL);
	rc = VXIcache_RESULT_OUT_OF_MEMORY;
      }
    }
  }

  // Return the stream
  if ( rc == VXIcache_RESULT_SUCCESS ) {
    SBcacheEntry entry(this);
    *stream = new SBcacheStream (log, GetDiagBase( ), moduleName, key,
				 entry, mode,
				 ((flags & CACHE_FLAG_NONBLOCKING_IO) == 0),
				 maxSizeBytes, filePtr);
    if ( ! *stream ) {
      Error (log, 100, NULL);
      fclose (filePtr);
      Close (log, mode, 0, true);
      rc = VXIcache_RESULT_OUT_OF_MEMORY;
    }
  }

  Diag (log, SBCACHE_ENTRY_TAGID, L"Open", L"%s, %S, 0x%x, 0x%x: rc = %d",
	key.c_str( ), path.c_str( ), mode, flags, rc);
  return rc;
}
Esempio n. 11
0
VXIinetResult
SBinetFileStream::Open(VXIint32                  flags,
		       const VXIMap             *properties,
		       VXIMap                   *streamInfo)
{
  VXIinetResult returnValue = VXIinet_RESULT_SUCCESS;

  /*
     Get the flag to determine whether to open local files. Also check
     the validator to see if it contains INET_INFO_VALIDATOR and if it
     does contain the modified time. */
  SBinetValidator validator(GetLog(), GetDiagBase());
  const VXIValue *validatorVal = NULL;
  if (properties)
  {
    const VXIValue *val = VXIMapGetProperty(properties, INET_OPEN_LOCAL_FILE);
    if (val != NULL)
    {
      if (VXIValueGetType(val) == VALUE_INTEGER)
      {
        if (VXIIntegerValue((const VXIInteger *) val) == FALSE)
          returnValue = VXIinet_RESULT_LOCAL_FILE;
      }
      else
      {
        Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
             L"Passed invalid type for INET_OPEN_LOCAL_FILE property");
      }
    }

    // SBinetValidator::Create() logs errors for us
    validatorVal = VXIMapGetProperty(properties, INET_OPEN_IF_MODIFIED);
    if((validatorVal != NULL) &&
       (validator.Create(validatorVal) != VXIinet_RESULT_SUCCESS))
      validatorVal = NULL;
  }

  Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
       _url->getAbsolute( ));

  // Stat the file to make sure it exists and to get the length and
  // last modified time
  VXIStatStruct statInfo;
  if (VXIStat(SBinetNString(_url->getPath()).c_str(), &statInfo) != 0) {
    Error(222, L"%s%s", L"File", _url->getPath());
    return(VXIinet_RESULT_NOT_FOUND);
  }

  _content_length = statInfo.st_size;

  // If there is a conditional open using a validator, see if the
  // validator is still valid (no need to re-read and re-process)
  if (validatorVal)
  {
    if (! validator.isModified(statInfo.st_mtime, statInfo.st_size))
    {
      Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
           L"Validator OK, returning NOT_MODIFIED");
      returnValue = VXIinet_RESULT_NOT_MODIFIED;
    }
    else
    {
      Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
           L"Validator modified, must re-fetch");
    }
  }

  if (returnValue != VXIinet_RESULT_LOCAL_FILE)
  {
    // Use fopen for now. Note: Open support reads for now
    _pFile = ::fopen( SBinetNString(_url->getPath()).c_str(), "rb" );
    if(!_pFile){
      Error(223, L"%s%s", L"File", _url->getPath());
      return(VXIinet_RESULT_NOT_FOUND);
    }
    _ReadSoFar = 0;
  }

  if (streamInfo != NULL)
  {
    // Set FILE data source information   
    VXIMapSetProperty(streamInfo, INET_INFO_DATA_SOURCE, 
                     (VXIValue*) VXIIntegerCreate(INET_DATA_SOURCE_FILE));
    
    // Use extension mapping algorithm to determine MIME content type
    VXIString *guessContent = _url->getContentTypeFromUrl();
    if (guessContent == NULL) {
      guessContent = VXIStringCreate(_channel->getDefaultMimeType());
      // This error message is useful, but unfortunately it gets printed
      // for all the grammar files etc. whose extensions are unknown...
      //Error (303, L"%s%s", L"URL", _url->getPath());
    }
    VXIMapSetProperty(streamInfo, INET_INFO_MIME_TYPE, (VXIValue*) guessContent);

    // Set the absolute path, any file:// prefix and host name is
    // already stripped prior to this method being invoked
    VXIMapSetProperty(streamInfo, INET_INFO_ABSOLUTE_NAME,
		      (VXIValue*)VXIStringCreate( _url->getPath() ));

    // Set the validator property
    VXIValue *newValidator = NULL;
    if (returnValue == VXIinet_RESULT_NOT_MODIFIED) {
      newValidator = VXIValueClone(validatorVal);
    } else {
      SBinetValidator validator(GetLog(), GetDiagBase());
      if (validator.Create(_url->getPath(), statInfo.st_size,
                           statInfo.st_mtime) == VXIinet_RESULT_SUCCESS)
      {
	newValidator = (VXIValue *) validator.serialize();
      }
    }

    if (newValidator)
      VXIMapSetProperty(streamInfo, INET_INFO_VALIDATOR, newValidator);
    else {
      Error(103, NULL);
      returnValue = VXIinet_RESULT_OUT_OF_MEMORY;
    }

    // Set the size
    VXIMapSetProperty(streamInfo, INET_INFO_SIZE_BYTES,
		      (VXIValue*)VXIIntegerCreate( _content_length));
  }

  if (!validatorVal && (returnValue == VXIinet_RESULT_NOT_MODIFIED))
    return VXIinet_RESULT_SUCCESS;

  return returnValue;
}
Esempio n. 12
0
// This function is responsible for calling the VXIrec level Recognize function
// and then mapping the grammar back to the corresponding VXML node.
//
int GrammarManager::Recognize(const VXIMapHolder & properties,
                              RecognitionAnswer & recAnswer,
                              VXMLElement & recNode)
{
  recNode = VXMLElement();
  VXIrecRecognitionResult * answer = NULL;

  // (1) Do VXIrec level Recognitize and process return value.

  // (1.1) Recognize.
  VXIrecResult err = vxirec->Recognize(vxirec, properties.GetValue(),
                                       &answer);
  if (err == VXIrec_RESULT_OUT_OF_MEMORY) {
    log.LogDiagnostic(0,L"GrammarManager::InternalRecognize - Out of memory.");
    return GrammarManager::OutOfMemory;
  }

  if (err == VXIrec_RESULT_DISCONNECT) {
    // Here is the case that the call is being disconnected before the 
    // recognition even starts
    return GrammarManager::Disconnect;
  }

  // (1.2) Anything other than success indicates that recognition failed
  // (badly).  The normal error conditions are returned through the recogntion
  // result structure.
  if (err != VXIrec_RESULT_SUCCESS) {
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned " << int (err);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function did not return the expected VXIrecSUCCESS result");
    return GrammarManager::InternalError;
  }

  // (1.3) The answer structure must be defined.
  if (answer == NULL) {
    // Here is the case that the call is being disconnected before the recording even starts
    return GrammarManager::Disconnect;
  }

  // (1.4) Attach the answer structure returned by VXIrec and the waveform to
  // the recAnswer class.
  recAnswer.Bind(answer);
  recAnswer.waveform = answer->waveform;

  // (2) Process all non-Successful results.

  // (2.1) First the status code.

  switch (answer->status) {
  case REC_STATUS_SUCCESS:    // Recognition returned a hypothesis
  case REC_STATUS_DTMFSUCCESS:    // Recognition returned a hypothesis
    break;
  case REC_STATUS_FAILURE:    // Speech detected, no likely hypothesis
    return GrammarManager::Failure;
  case REC_STATUS_TIMEOUT:    // No speech was detected
    return GrammarManager::Timeout;
  case REC_STATUS_DISCONNECT: // Caller has disconnected; no hypothesis
    return GrammarManager::Disconnect;
  case REC_STATUS_ERROR:      // An error aborted recognition
    return GrammarManager::Error;
  default:
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned status " << int(answer->status);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an invalid VXIrecStatus code");
    return GrammarManager::InternalError;
  }

  // (2.2) Recognition success. Verify that the input mode was set correctly.

  switch (answer->mode) {
  case REC_INPUT_MODE_DTMF:
  case REC_INPUT_MODE_SPEECH:
    break;
  default:
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned mode " << int(answer->mode);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an invalid VXIrecInputMode value");
    return GrammarManager::InternalError;
  }

  // (3) Walk through results array and sanity check the results.

  // (3.1) How many answers are there?

  if (answer->results == NULL) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned a null results vector");
    return GrammarManager::InternalError;
  }

  unsigned int NUM_ANSWERS = VXIVectorLength(answer->results);
  if (NUM_ANSWERS == 0) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an empty results vector");
    return GrammarManager::InternalError;
  }

  const VXIMap * bestAnswer = NULL;

  for (unsigned int i = 0; i < NUM_ANSWERS; ++i) {
    // (3.2) Find each element in the result vector.
    
    const VXIValue * temp = VXIVectorGetElement(answer->results, i);
    if (temp == NULL) {
      log.LogError(400, SimpleLogger::MESSAGE,
                   L"VXIVectorGetElement failed to return answer.");
      return GrammarManager::InternalError;
    }
    
    if (VXIValueGetType(temp) != VALUE_MAP) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"function returned an invalid results vector");
      return GrammarManager::InternalError;
    }

    const VXIMap * nthAnswer = reinterpret_cast<const VXIMap*>(temp);
    if (i == 0) bestAnswer = nthAnswer;

    // (3.3) Validate types of member keys.

    temp = VXIMapGetProperty(nthAnswer, REC_KEYS);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_KEYS must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * keys = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_VALUES);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_VALUES must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * values = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_CONF);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_CONF must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * scores = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_RAW);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_RAW must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * utts = reinterpret_cast<const VXIVector *>(temp);

    // (3.4) Validate vector lengths.

    const VXIunsigned length = VXIVectorLength(keys);
    if (length < 1) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"result vector must have length of at least one");
      throw VXIException::Fatal();
    }
    if (length != VXIVectorLength(values) ||
        length != VXIVectorLength(scores) ||
        length != VXIVectorLength(utts))
    {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"result vector length must all match");
      return GrammarManager::InternalError;
    }

    temp = VXIVectorGetElement(keys, 0);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_STRING) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"first REC_KEYS must be defined with type string");
      return GrammarManager::InternalError;
    }

    // (3.5) Copy into results class.

    recAnswer.keys.push_back(keys);
    recAnswer.values.push_back(values);
    recAnswer.scores.push_back(scores);
    recAnswer.utts.push_back(utts);
  }

  recAnswer.numAnswers = NUM_ANSWERS;

  // (4) Find the VXML element associated with the matched grammar.

  // (4.1) Find the grammar corresponding to the best answer.

  const VXIValue * temp = VXIMapGetProperty(bestAnswer, REC_GRAMMAR);
  if (temp == NULL || VXIValueGetType(temp) != VALUE_PTR) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"unable to obtain grammar key from 'results' #0");
    return GrammarManager::InternalError;
  }

  const VXIPtr * tempptr = reinterpret_cast<const VXIPtr *>(temp);
  const VXIrecGrammar * bestGrammar =
    reinterpret_cast<const VXIrecGrammar*>(VXIPtrValue(tempptr));

  // (4.2) Map the VXIrecGrammar pointer back to the source VXMLElement.

  for (GRAMMARS::iterator j = grammars.begin(); j != grammars.end(); ++j) 
  {
    if ((answer->mode == REC_INPUT_MODE_DTMF && REC_STATUS_DTMFSUCCESS != answer->status) 
      && (*j)->GetRecGrammar() != bestGrammar) continue;

    if (!(*j)->IsEnabled()) 
    {
      if (j == grammars.end()) {
        log.LogError(420, SimpleLogger::MESSAGE,
                     L"function returned an inactive grammar");
        return GrammarManager::InternalError;
      }
      continue;
    }

    (*j)->GetElement(recNode);

    if (answer->mode == REC_INPUT_MODE_DTMF)
      return GrammarManager::SuccessDTMF;

    return GrammarManager::Success;
  }

  log.LogError(420, SimpleLogger::MESSAGE,
               L"function returned a non-existent grammar");
  return GrammarManager::InternalError;
}