📄 osbclient.c
字号:
L"MSG", L"OSBtel WaitForCall failed", L"rc", telResult); return (telResult > 0 ? VXIplatform_RESULT_FAILURE : VXIplatform_RESULT_TEL_ERROR); } SBclientDiag(platform, CLIENT_API_TAG, L"VXIplatformWaitForCall", L"exiting: rc = %d", VXIplatform_RESULT_SUCCESS); SBclientDiag(platform, CLIENT_GEN_TAG, L"Leaving WaitForCall", NULL); return VXIplatform_RESULT_SUCCESS;}/** * Process a VoiceXML document. * * This function processes a VoiceXML document using the resources * specified by the passed platform pointer. It blocks until the * processing is complete and then returns VXIplatform_RESULT_SUCCESS. */VXIPLATFORM_API VXIplatformResultVXIplatformProcessDocument(const VXIchar *url, VXIMap *sessionArgs, VXIValue **documentResult, VXIplatform *platform){ VXIinterpreterResult interpreterResult; VXIinetResult inetResult; VXItelResult telResult; VXIpromptResult promptResult; VXIrecResult recResult; VXIchar *allocatedUrl = NULL; const VXIchar *finalUrl = NULL, *ani = NULL, *dnis = NULL; VXIVector *cookieJar = NULL; VXIMap *navigatorProps = NULL; if (!gblPlatformInitialized) { return VXIplatform_RESULT_NOT_INITIALIZED; } SBclientDiag(platform, CLIENT_API_TAG, L"VXIplatformProcessDocument", L"entering: %s, 0x%p, 0x%p, 0x%p", url, sessionArgs, documentResult, platform); /* If the URL is really a local file path, change it to be a full path so relative URL references in it can be resolved */ finalUrl = url; if (wcschr(url, L':') == NULL) { allocatedUrl = (VXIchar *) calloc(MAX_PATH + 1, sizeof(VXIchar)); CLIENT_CHECK_MEMALLOC(allocatedUrl, "Allocated URL");#ifdef WIN32 /* Win32 version */ { VXIchar *ignored; if (!allocatedUrl) CLIENT_CHECK_RESULT("full path allocation", -1); if (GetFullPathName(url, MAX_PATH, allocatedUrl, &ignored) <= 0) CLIENT_CHECK_RESULT("Win32 GetFullPathName()", -1); }#else { /* Unix version */ char cwd[MAX_PATH + 1]; cwd[0] = '\0'; getcwd (cwd, MAX_PATH); if (!cwd[0]) CLIENT_CHECK_RESULT("getcwd()", -1); if (strlen(cwd) + wcslen(url) + 1 > MAX_PATH) CLIENT_CHECK_RESULT("MAX_PATH exceeded for getting full path", -1); mbstowcs(allocatedUrl, cwd, MAX_PATH + 1); wcscat (allocatedUrl, L"/"); wcscat (allocatedUrl, url); }#endif finalUrl = allocatedUrl; } /* Set up OSBinet for a new call by enabling or disabling cookies as configured for the resource. When cookies are enabled, this implementation establishes a new cookie jar for each new call, and destroys it at the end of the call. This makes it so cookies do not persist across calls, meaning applications can use cookies to keep track of in-call state but not track state and callers across calls. Fully persistant cookies require a highly accurate mechanism for identifying individual callers (caller ID is not usually sufficient), a database for storing the cookie jar for each caller, and a way for individual callers to establish their privacy policy (web site or VoiceXML pages that allow them to configure whether cookies are enabled and cookie filters). Once in place, merely store the cookie jar at the end of the call, then once the caller is identified set the cookie jar to the previously stored one. */ if (platform->acceptCookies) { cookieJar = VXIVectorCreate(); CLIENT_CHECK_MEMALLOC(cookieJar, "VXIinet cookie jar"); } inetResult = platform->VXIinet->SetCookieJar (platform->VXIinet, cookieJar); CLIENT_CHECK_RESULT("VXIinet->SetCookieJar()", inetResult); VXIVectorDestroy (&cookieJar); /* Set up the telephony interface for a new call. Begin session has to be called at the start of every call. End session has to be called at the end of every call. */ telResult = platform->VXItel->BeginSession(platform->VXItel, NULL); CLIENT_CHECK_RESULT("VXItel->BeginSession()", telResult); /* Set up the prompt interface for a new call. Begin session has to be called at the start of every call. End session has to be called at the end of every call. */ promptResult = platform->VXIprompt->BeginSession(platform->VXIprompt, NULL); CLIENT_CHECK_RESULT("VXIprompt->BeginSession()", promptResult); /* Set up the recognizer for a new call. Begin session has to be called at the start of every call. End session has to be called at the end of every call. */ recResult = platform->VXIrec->BeginSession(platform->VXIrec, NULL); CLIENT_CHECK_RESULT("VXIrec->BeginSession()", recResult); /* Put the telephony map into the session map so they will be referenced as session.telephone.*. Note that ownership passes to the sessionArgs map. */ if (platform->telephonyProps) { const VXIValue *val; val = VXIMapGetProperty(platform->telephonyProps, L"ani"); if ((val) && (VXIValueGetType(val) == VALUE_STRING)) ani = VXIStringCStr((const VXIString *) val); val = VXIMapGetProperty(platform->telephonyProps, L"dnis"); if ((val) && (VXIValueGetType(val) == VALUE_STRING)) dnis = VXIStringCStr((const VXIString *) val); VXIMapSetProperty(sessionArgs, L"telephone", (VXIValue*)platform->telephonyProps); platform->telephonyProps = NULL; } /* Store properties for querying the browser implementation in the session map, they can be referenced as navigator.* (technically session.navigator.* but since the session scope is the global scope, navigator.* will be found, and the navigator.* form is what is universally used to query this information for HTML browsers). */ navigatorProps = VXIMapCreate(); CLIENT_CHECK_MEMALLOC(navigatorProps, "Navigator properties"); { /* User agent name is configured */ const VXIchar *start, *end; VXIString *str = VXIStringCreate(gblUserAgentName); CLIENT_CHECK_MEMALLOC(str, "Navigator User Agent Name"); VXIMapSetProperty(navigatorProps, L"userAgent", (VXIValue *)str); /* Code name is the portion of the user agent up to the slash */ end = wcschr(gblUserAgentName, L'/'); if ((end) && (*end)) str = VXIStringCreateN(gblUserAgentName, end - gblUserAgentName); else CLIENT_CHECK_RESULT("User Agent Name parse", VXIplatform_RESULT_INVALID_ARGUMENT); CLIENT_CHECK_MEMALLOC(str, "Navigator Browser Code Name"); VXIMapSetProperty(navigatorProps, L"appCodeName", (VXIValue *)str); /* Version is the portion of the user agent after the slash and up through the alphanumeric sequence that follows it */ start = end + 1; while (iswspace(*start)) start++; end = start; while ((iswalnum(*end)) || (*end == L'.')) end++; str = VXIStringCreateN(start, end - start); CLIENT_CHECK_MEMALLOC(str, "Navigator Browser Version"); VXIMapSetProperty(navigatorProps, L"appVersion", (VXIValue *)str); /* Application name is the full official product name */ str = VXIStringCreate(L"SpeechWorks OpenSpeech Browser PIK"); CLIENT_CHECK_MEMALLOC(str, "Navigator application name"); VXIMapSetProperty(navigatorProps, L"appName", (VXIValue *)str); } VXIMapSetProperty(sessionArgs,L"navigator",(VXIValue*)navigatorProps); /* Log the start of call event */ platform->VXIlog->Event(platform->VXIlog, VXIlog_EVENT_CALL_START, L"%s%s%s%s%s%s", L"ANII", (ani ? ani : L""), L"DNIS", (dnis ? dnis : L""), L"VURL", finalUrl); /* Ready to run the VXI. This will return with a result of one of the following: a) a VoiceXML page hits an <exit> tag. In this case result will contain the value of the exit. b) A page simply has no where to go. The application falls out of VoiceXML and ends. result will be NULL in this case. c) An error occurs. result will be NULL in this case. Note that the session arguments contain all the information that the platform wants to put into the ECMAScript variable session at channel startup. The initial URL will be fetched with a POST sending the session arguments in the initial POST. */ interpreterResult = platform->VXIinterpreter->Run(platform->VXIinterpreter, finalUrl, sessionArgs, documentResult); CLIENT_CHECK_RESULT_NO_EXIT("VXIinterpreter->Run()", interpreterResult); if (allocatedUrl) free(allocatedUrl); /* Log the end of call event */ platform->VXIlog->Event(platform->VXIlog, VXIlog_EVENT_CALL_END, NULL); /* Now end the recognizer, prompt, and tel session */ recResult = platform->VXIrec->EndSession(platform->VXIrec, NULL); CLIENT_CHECK_RESULT("OSBrec->EndSession()", recResult); promptResult = platform->VXIprompt->EndSession(platform->VXIprompt, NULL); CLIENT_CHECK_RESULT("OSBprompt->EndSession()", promptResult); telResult = platform->VXItel->EndSession(platform->VXItel, NULL); CLIENT_CHECK_RESULT("OSBtel->EndSession()", telResult); SBclientDiag(platform, CLIENT_API_TAG, L"VXIplatformProcessDocument", L"exiting: rc = %d, 0x%p", interpreterResult, (documentResult ? *documentResult : NULL)); /* Do a map of the interpreter result to a platform result */ return SBclientConvertInterpreterResult (interpreterResult);}/** * Log an error */VXIPLATFORM_API VXIlogResult SBclientError(VXIplatform *platform, const VXIchar *moduleName, VXIunsigned errorID, const VXIchar *format, ...){ VXIlogResult rc; VXIlogInterface *log = NULL; va_list arguments; if ((platform) && (platform->VXIlog)) log = platform->VXIlog; else if (gblLog) log = gblLog; else return VXIlog_RESULT_NON_FATAL_ERROR; if (format) { va_start(arguments, format); rc = (*log->VError)(log, moduleName, errorID, format, arguments); va_end(arguments); } else { rc = (*log->Error)(log, moduleName, errorID, NULL); } return rc;}/** * Log a diagnostic message */VXIPLATFORM_API VXIlogResult SBclientDiag(VXIplatform *platform, VXIunsigned tag, const VXIchar *subtag, const VXIchar *format, ...){ VXIlogResult rc; VXIlogInterface *log = NULL; va_list arguments; if ((platform) && (platform->VXIlog)) log = platform->VXIlog; else if (gblLog) log = gblLog; else return VXIlog_RESULT_NON_FATAL_ERROR; if (format) { va_start(arguments, format); rc = (*log->VDiagnostic)(log, tag, subtag, format, arguments); va_end(arguments); } else { rc = (*log->Diagnostic)(log, tag, subtag, NULL); } return rc;}/** * Enable/disable diagnostic tags based on the passed configuration data */VXIPLATFORM_API VXIplatformResult SBclientConfigureDiagnosticTags(const VXIMap *configArgs, VXIplatform *platform){ VXIplatformResult rc = VXIplatform_RESULT_SUCCESS; const VXIchar *key; const VXIValue *val; int prefixlen = wcslen(CLIENT_LOG_DIAG_TAG_KEY_PREFIX); VXIMapIterator *iter; VXIlogInterface *log = NULL; OSBlogInterface *osbLog = NULL; if (!configArgs) rc = VXIplatform_RESULT_INVALID_ARGUMENT; if ((platform) && (platform->VXIlog)) log = platform->VXIlog; else if (gblLog) log = gblLog; else return VXIlog_RESULT_NON_FATAL_ERROR; /* Determine the implementation */ if (wcsstr(log->GetImplementationName( ), L".OSBlog")) { osbLog = (OSBlogInterface *) log; } else { fprintf(stderr, "ERROR: Unknown log implementation for " "SBclientConfigureDiagnosticTags( ), returning failure"); return VXIlog_RESULT_FAILURE; } /* Configure the diagnostic tags */ iter = VXIMapGetFirstProperty(configArgs,&key,&val); if (iter) { do { if (wcsncmp(key, CLIENT_LOG_DIAG_TAG_KEY_PREFIX, prefixlen)==0) { if (VXIValueGetType(val) == VALUE_INTEGER) { VXIunsigned tflag = VXIIntegerValue((const VXIInteger*)val); /* get suffix TAG ID from the key */ VXIchar *ptr; VXIunsigned tagID = (VXIunsigned) wcstol (key + prefixlen,&ptr,10); if (tagID >= 0) osbLog->ControlDiagnosticTag(osbLog, tagID, tflag ? TRUE :FALSE); else fprintf(stderr, "ERROR: Invalid tag ID suffix for " "configuration parameter, %ls, integer greater then " "zero required\n", key); } else { fprintf(stderr, "ERROR: Invalid type for configuration " "parameter, %ls, VXIInteger required\n", key); } } } while (VXIMapGetNextProperty(iter, &key, &val) == 0); } VXIMapIteratorDestroy(&iter); return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -