VXImain.c
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:16k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. /* -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  23.  */
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <limits.h>
  28. #include <VXItrd.h>
  29. #include <VXIlog.h>
  30. #include <SBlog.h>
  31. #include "SBlogListeners.h"
  32. #include "VXIclient.h"
  33. #include "VXIplatform.h"
  34. #include "VXIclientUtils.h"
  35. #include "VXIclientConfig.h"
  36. #include "ConfigFile.h"
  37. /* Helper Macros */
  38. #ifdef WIN32
  39. #define PATH_SEPARATOR '\'
  40. #else
  41. #define PATH_SEPARATOR '/'
  42. #endif
  43. #define CHANNEL_CHECK_RESULT(_platform, _func, _res)                         
  44.     if ((VXIint)(_res) != 0) {                                               
  45.       VXIclientError((_platform), MODULE_NAME, 200, L"Function call failed", 
  46.         L"%s%S%s%d%s%S%s%d", L"FUNC", _func, L"RESULT", (_res),              
  47.         L"FILE", __FILE__, L"LINE", __LINE__);                               
  48.       return ((VXItrdThreadArg)_res);                                        
  49.     }
  50. /* Structure for controlling channel threads */
  51. typedef struct ChannelThreadArgs {
  52.   VXIunsigned    channelNum;
  53.   long           maxCalls;
  54.   const VXIMap  *configArgs;
  55.   const VXIchar *vxmlURL;
  56.   VXItrdThread  *threadHandle;
  57.   long           delayCallSec;
  58. } ChannelThreadArgs;
  59. /* Defaults for command line arguments */
  60. #define MODULE_NAME                   L"VXIClient"
  61. #define DEFAULT_CONFIG_FILENAME       "SBclient.cfg"
  62. #define DEFAULT_MAX_CHANNELS          1
  63. #define DEFAULT_MAX_CALLS             -1 /* loop forever */
  64. /* Helper funtions */
  65. void Usage(void)
  66. {
  67.   printf("nCommand-line arguments :n"
  68.         "[-v ] [-version] "
  69.         "[-url vxmlDocURL] [-channels nbChannels] [-config configFile]n"
  70.         "[-calls maxCalls] [-delay nbSeconds] [-sbinet]n"
  71.         "To show version specifiy either -v or -versionn"
  72.         "To run multiple channels, set nbChannels to desired numbern"
  73.         "To take unlimited calls, set maxCalls to -1n"
  74.         "To simulate delay between call, set nbSeconds to desired secondsn"
  75.         "-sbinet used by Vocalocity only to indicate sbinet is passed to OSRnn");
  76. }
  77. void ErrorMsg(const char* msg, const char* arg) {
  78.   printf("***ERROR***: %s%sn", msg, (arg ? arg : "") );
  79.   _exit(-1);  
  80. }
  81. static void 
  82. ShowResult(const VXIValue *result_val, int ChanNum, VXIplatform *platform)
  83. {
  84.   switch (VXIValueGetType(result_val)) {
  85.   case VALUE_INTEGER:
  86.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  87.      L"VXIInteger Result Value: %d",
  88.      VXIIntegerValue((const VXIInteger *) result_val));
  89.     break;
  90.   case VALUE_FLOAT:
  91.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  92.      L"VXIFloat Result Value: %f", 
  93.      VXIFloatValue((const VXIFloat *) result_val));
  94.     break;
  95.   case VALUE_DOUBLE: {
  96.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  97.      L"VXIDouble Result Value: %f", VXIDoubleValue((const VXIDouble *) result_val));
  98.   } break;
  99.   case VALUE_ULONG:
  100.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  101.      L"VXIULong Result Value: %u", 
  102.      VXIULongValue((const VXIULong *) result_val));
  103.     break;
  104.   case VALUE_LONG:
  105.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  106.      L"VXILong Result Value: %u", 
  107.      VXILongValue((const VXILong *) result_val));
  108.     break;
  109.   case VALUE_STRING:
  110.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  111.      L"VXIString Result Value: %s", 
  112.      VXIStringCStr((const VXIString *) result_val));
  113.     break;
  114.   case VALUE_PTR:
  115.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  116.      L"Result Type: VXIPtr: 0x%p",
  117.      VXIPtrValue((const VXIPtr *) result_val));
  118.     break;
  119.     
  120.   case VALUE_MAP:
  121.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  122.      L"Result Type: VXIMap");
  123.     break;
  124.   case VALUE_VECTOR:
  125.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  126.      L"Result Type: VXIVector");
  127.     break;
  128.   case VALUE_CONTENT:
  129.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  130.      L"Result Type: VXIContent");
  131.     break;
  132.   
  133.   case VALUE_BOOLEAN:
  134.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  135.      L"VXIBoolean Result Value: %d", 
  136.      VXIBooleanValue((const VXIBoolean *) result_val));
  137.     break;
  138.   
  139.   default:
  140.     VXIclientDiag(platform, 60001, L"testClient::ShowResult",
  141.      L"Result Type: Unknown type: %d", VXIValueGetType(result_val));
  142.     break;
  143.   }
  144. }
  145. /* Channel Thread */
  146. static VXITRD_DEFINE_THREAD_FUNC(ChannelThread, userData)
  147. {
  148.   const ChannelThreadArgs *channelArgs = (const ChannelThreadArgs *)userData;
  149.   unsigned long numCalls = 0;
  150.   VXIplatformResult platformResult;
  151.   VXIplatform *platform;
  152.   VXIMap *channelConfig;
  153.   VXItrdTimer *delayTimer = NULL;
  154.   /* Create delay timer */  
  155.   VXItrdTimerCreate(&delayTimer);
  156.   if ( channelArgs->configArgs )
  157.     channelConfig = VXIMapClone (channelArgs->configArgs);
  158.   else
  159.     channelConfig = NULL;
  160.   platformResult = VXIplatformCreateResources(channelArgs->channelNum,
  161.                                               channelConfig,
  162.                                               &platform);
  163.   if( platformResult != 0 ) {
  164.     CHECK_RESULT_NO_RETURN(NULL, "VXIplatformCreateResources()", platformResult);
  165.     return (VXItrdThreadArg)platformResult;
  166.   }
  167.   while ((channelArgs->maxCalls == -1) || (numCalls < channelArgs->maxCalls)) {
  168.     numCalls++;
  169.     platform->numCall = numCalls;
  170.     printf("Channel %d: Waiting for Call %ldn", channelArgs->channelNum, numCalls);
  171.     platformResult = VXIplatformEnableCall(platform);
  172.     if( platformResult != 0 ) {
  173.       CHECK_RESULT_NO_RETURN(platform, "VXIplatformEnableCall()", platformResult);
  174.       return (VXItrdThreadArg)platformResult;
  175.     }
  176.     
  177.     VXIclientDiag(platform, 60001, L"testClient::ChannelThread",
  178.                   L"About to call VXIplatformWaitForCall");
  179.     platformResult = VXIplatformWaitForCall(platform);
  180.     if( platformResult != 0 ) {
  181.       CHECK_RESULT_NO_RETURN(platform, "VXIplatformWaitForCall()", platformResult);
  182.       return (VXItrdThreadArg)platformResult;
  183.     }
  184.     VXIclientDiag(platform, 60001, L"testClient::ChannelThread", L"In a Call");
  185.     printf("Channel %d: In a Calln", channelArgs->channelNum);
  186.     {
  187.       VXIchar *sessionArgScript = NULL;
  188.       VXIValue *result = NULL ;
  189.       platformResult = VXIplatformProcessDocument(channelArgs->vxmlURL,
  190.                                                   &sessionArgScript, 
  191.                                                   &result, platform);
  192.       if((VXIint) platformResult != 0){
  193.         fprintf(stderr, "Error: ProcessDocument returned error code %in",
  194.                 platformResult);
  195.       }
  196.       else{
  197.         if(result) {
  198.           ShowResult(result, channelArgs->channelNum, platform);
  199.           VXIValueDestroy(&result);  /* Notes: must deallocate result */
  200.         }else{
  201.           VXIclientDiag(platform, 60001, L"testClient::ChannelThread", L"NULL result");
  202.         }
  203.       }
  204.         
  205.       /* free session ECMAScript */
  206.       if( sessionArgScript )
  207.       {
  208.         free(sessionArgScript);
  209.         sessionArgScript = NULL;
  210.       }
  211.     }
  212.     VXIclientDiag(platform, 60001, L"testClient::ChannelThread", L"Call Terminated");
  213.     printf("Channel %d: Call Terminatedn", channelArgs->channelNum);
  214.     
  215.     /* Simulate delay if user specify delay time */
  216.     if( (channelArgs->delayCallSec > 0) &&
  217.         (channelArgs->maxCalls == -1) || (numCalls < channelArgs->maxCalls) )
  218.       VXItrdTimerSleep(delayTimer, channelArgs->delayCallSec * 1000, NULL);  
  219.   }
  220.   platformResult = VXIplatformDestroyResources(&platform);
  221.   if( delayTimer ) VXItrdTimerDestroy(&delayTimer);   
  222.   if (channelConfig)
  223.     VXIMapDestroy(&channelConfig);
  224.   if( platformResult != 0 ) {
  225.     CHECK_RESULT_NO_RETURN(platform, "VXIplatformDestroyResources()", platformResult);
  226.     return (VXItrdThreadArg)platformResult;
  227.   }
  228.   return 0;
  229. }
  230. int main( int argc, char **argv)
  231. {
  232.   int i                 = 0;
  233.   int len               = 0;
  234.   int showVersion       = 0;
  235.   int nbChannels        = 1;
  236.   int maxCalls          = 1;
  237.   int nbSeconds         = 0;
  238.   int usedInternalInet  = 0;
  239.   VXIMap* configArgs    = NULL;
  240.   VXIString* vxmlURL    = NULL;
  241.   VXIchar* tempstr      = NULL;
  242.   char* cfgURL          = NULL;
  243.   const char* vxmlURLptr= NULL;
  244.   const char* cfgURLptr = NULL;
  245.   VXIplatformResult pfResult;
  246.   ChannelThreadArgs *channelArgs = NULL;
  247.   VXItrdThreadArg status;
  248.   VXItrdResult trdResult;
  249.   
  250.   Usage();
  251.   
  252.   /* Parse command line */  
  253.   for( i=1; i<argc; ++i ) {
  254.     if( strcmp(argv[i], "-url") == 0 ) {
  255.       if( vxmlURL ) VXIStringDestroy(&vxmlURL);
  256.       if( argv[++i] == NULL ) ErrorMsg("Missing vxmlDocURL argument", NULL);
  257.       vxmlURLptr = argv[i];
  258.       len = strlen(vxmlURLptr);
  259.       tempstr = (VXIchar*)malloc(sizeof(VXIchar)*(len+1));
  260.       if( !tempstr ) ErrorMsg("System memory exhausted!", NULL);
  261.       if ( char2wchar(tempstr, vxmlURLptr, len) != 0 )
  262.         ErrorMsg("Unable to convert char to wchar_t", NULL);
  263.       vxmlURL = VXIStringCreate(tempstr);
  264.       free(tempstr);      
  265.     }
  266.     else if( strcmp(argv[i], "-channels") == 0 ) {
  267.       if( argv[++i] == NULL ) ErrorMsg("Missing nbChannels argument", NULL);
  268.       nbChannels = atoi(argv[i]);
  269.       if( nbChannels < 1 ) ErrorMsg("nbChannels must be greater than 0.", NULL);
  270.       if( nbChannels == UINT_MAX ) ErrorMsg("nbChannels is too big", NULL);       
  271.     }
  272.     else if( strcmp(argv[i], "-calls") == 0 ) {
  273.       if( argv[++i] == NULL ) ErrorMsg("Missing maxCalls argument", NULL);
  274.       maxCalls = atoi(argv[i]);
  275.     }
  276.     else if( strcmp(argv[i], "-delay") == 0 ) {
  277.       if( argv[++i] == NULL ) ErrorMsg("Missing nbSeconds argument", NULL);
  278.       nbSeconds = atoi(argv[i]);
  279.       if( nbSeconds < 0 ) ErrorMsg("nbSeconds must be positive.", NULL);
  280.     }
  281.     else if( strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "-v") == 0) {
  282.       showVersion = 1;
  283.     }
  284.     else if( strcmp(argv[i], "-config") == 0 ) {
  285.       if( argv[++i] == NULL ) ErrorMsg("Missing configFile argument", NULL);
  286.       cfgURL = argv[i];
  287.       cfgURLptr = cfgURL;
  288.     }   
  289.     else if( strcmp(argv[i], "-sbinet") == 0 ) {
  290.       usedInternalInet = 1;  
  291.     }
  292.     else ErrorMsg("Unknown argument: ", argv[i]);
  293.   }
  294.     
  295.   /* Make sure the vxml url is given */
  296.   if( vxmlURL == NULL && !showVersion ) 
  297.     ErrorMsg("Required argument -url is missing!", NULL);
  298.   
  299.   /* If user does not specify -config, use defaut config. file */
  300.   {
  301.     const char* sbenv = getenv( "SWISBSDK" );
  302.     if( cfgURL == NULL ) {
  303.       if( !sbenv ) 
  304.         ErrorMsg("Required environment SWISBSDK is not defined!", NULL);
  305.       cfgURL = (char*)malloc
  306.                (sizeof(char)*(strlen(DEFAULT_CONFIG_FILENAME)+strlen(sbenv)+10));
  307.       if( !cfgURL ) ErrorMsg("System memory exhausted!", NULL);
  308.       sprintf(cfgURL, "%s%cconfig%c%s", sbenv, PATH_SEPARATOR,
  309.               PATH_SEPARATOR, DEFAULT_CONFIG_FILENAME);
  310.     } 
  311.   }
  312.   
  313.   /* Show argument list */
  314.   if( !showVersion ) {
  315.     printf("n===========================================================n");
  316.     printf("vxmlDocURL: %sn", (vxmlURLptr ? vxmlURLptr : "") );
  317.     printf("configFile: %s%sn", cfgURL, (cfgURLptr ? "" : " (default)") ); 
  318.     printf("nbChannels: %d, maxCalls: %d%s, nbSeconds: %dn", nbChannels, 
  319.             maxCalls, (maxCalls < 0 ? "(unlimited calls)" : ""), nbSeconds);
  320.     printf("===========================================================nn");
  321.   }
  322.   
  323.   /* Parse the configuration file */
  324.   pfResult = ParseConfigFile(&configArgs, cfgURL);
  325.   CHECK_RESULT_RETURN(NULL, "ParseConfigFile()", pfResult);
  326.   /* For use by Vocalocity only */
  327.   if( usedInternalInet ) {
  328.     VXIMapSetProperty(configArgs, OSR_USE_INTERNAL_SBINET, 
  329.                       (VXIValue*)VXIIntegerCreate(1));
  330.   }
  331.   /* For show version mode, enable the version output diagnostic tag,
  332.      and turn on logging to standard output */
  333.   if( showVersion ) {
  334.     char ntemp[64];
  335.     wchar_t temp[1024];
  336.     const VXIValue *clientBase = VXIMapGetProperty(configArgs, CLIENT_CLIENT_DIAG_BASE);
  337.     if (VXIValueGetType(clientBase) != VALUE_INTEGER) {
  338.       ErrorMsg("client.diagBase must be set to a VXIInteger value", NULL);
  339.     }
  340.       
  341.     sprintf(ntemp, "%d", VXIIntegerValue((const VXIInteger*)clientBase) + 1);
  342.     wcscpy(temp, CLIENT_LOG_DIAG_TAG_KEY_PREFIX);
  343.     char2wchar(&temp[wcslen(temp)], ntemp, strlen(ntemp) + 1);
  344.     VXIMapSetProperty(configArgs, temp, (VXIValue *) VXIIntegerCreate(1));      
  345.     VXIMapSetProperty(configArgs, CLIENT_LOG_LOG_TO_STDOUT,
  346.                  (VXIValue *) VXIIntegerCreate(1));
  347.   }
  348.   
  349.   /* Initialize the platform */
  350.   pfResult = VXIplatformInit(configArgs, (VXIunsigned*)&nbChannels);
  351.   CHECK_RESULT_RETURN(NULL, "VXIplatformInit()", pfResult);
  352.   /* In show version mode, initialize one channel to get the version
  353.      numbers, then exit */
  354.   if( showVersion ) {
  355.     VXIplatform *platform = NULL;
  356.     pfResult = VXIplatformCreateResources(0, configArgs, &platform);
  357.     CHECK_RESULT_RETURN(NULL, "VXIplatformCreateResources()", pfResult);
  358.     pfResult = VXIplatformDestroyResources(&platform);
  359.     CHECK_RESULT_RETURN(NULL,"VXIplatformDestroyResources()", pfResult);
  360.     goto shutdown;
  361.   }
  362.   
  363.   /* Start the call processing threads */
  364.   if (nbChannels > 0) {
  365.     channelArgs = (ChannelThreadArgs *)calloc(nbChannels, sizeof(ChannelThreadArgs));
  366.     CHECK_MEMALLOC_RETURN(NULL, channelArgs, "ChannelThreadArgs array");
  367.     for (i = 0; i < nbChannels ; i++) {
  368.       channelArgs[i].channelNum = i;
  369.       channelArgs[i].maxCalls = maxCalls;
  370.       channelArgs[i].configArgs = configArgs;
  371.       channelArgs[i].vxmlURL = VXIStringCStr(vxmlURL);
  372.       channelArgs[i].delayCallSec = nbSeconds;
  373.       
  374.       trdResult = VXItrdThreadCreate(&channelArgs[i].threadHandle,
  375.              ChannelThread,
  376.              (VXItrdThreadArg) &channelArgs[i]);
  377.       CHECK_RESULT_NO_RETURN(NULL, "VXItrdThreadCreate()", trdResult);
  378.     }
  379.   }
  380.   else {
  381.     fprintf(stderr, "ERROR: No channels available, file %s, line %in",
  382.       __FILE__, __LINE__);
  383.   }
  384.   /* Wait for threads to finish */
  385.   for (i = 0; i < nbChannels; i++) {
  386.     trdResult = VXItrdThreadJoin (channelArgs[i].threadHandle, &status, -1);
  387.     CHECK_RESULT_NO_RETURN(NULL, "VXItrdThreadJoin()", trdResult);
  388.     trdResult = VXItrdThreadDestroyHandle (&channelArgs[i].threadHandle);
  389.     CHECK_RESULT_NO_RETURN(NULL, "VXItrdThreadDestroyHandle()",trdResult);
  390.     if ( status != 0 ) {
  391.       /* Need to cast this twice, some compilers won't allow going directly
  392.          to VXIplatformResult */
  393.       pfResult = (VXIplatformResult) ((VXIint) status);
  394.       CHECK_RESULT_NO_RETURN(NULL, "VXItrdThreadJoin()", pfResult);
  395.     }
  396.   }
  397. shutdown:    
  398.   /* Shut down the platform */
  399.   pfResult = VXIplatformShutdown();
  400.   CHECK_RESULT_NO_RETURN(NULL, "VXIplatformShutdown()", pfResult);
  401.   
  402.   /* clean up memory */
  403.   if( !cfgURLptr ) free(cfgURL);
  404.   if( vxmlURL ) VXIStringDestroy(&vxmlURL);
  405.   if( configArgs ) VXIMapDestroy(&configArgs);
  406.   if( channelArgs ) free(channelArgs);
  407.   if (pfResult == VXIplatform_RESULT_SUCCESS)
  408.     printf("Successfully exitingn");
  409.   else
  410.     printf("Exiting with errors, rc = %dn", pfResult);
  411.   
  412.   return (int)pfResult;
  413. }