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

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. #include <iostream>
  23. #include <cstdio>
  24. #include <string>
  25. #include <cstring>
  26. #define VXIstrcmp wcscmp
  27. #include <VXIvalue.h>
  28. #include <VXItrd.h>
  29. #define VXITEL_EXPORTS
  30. #include "VXItelAPI.h"
  31. #include "SWIstring.h"
  32. typedef std::basic_string<VXIchar> vxistring;
  33.   
  34. // ------*---------*---------*---------*---------*---------*---------*---------
  35. // Global for the base diagnostic tag ID
  36. //
  37. static VXIunsigned gblDiagLogBase = 0;
  38. // Constants for diagnostic logging tags
  39. //
  40. static const VXIunsigned DIAG_TAG_SIGNALING = 0;
  41. static inline VXItelTransferStatus GetXferStatus( const wchar_t* hupStrId )
  42. {
  43.   if( hupStrId )
  44.   {
  45.     if( wcscmp(hupStrId, L"far_end_disconnect") == 0 )
  46.       return VXItel_TRANSFER_FAR_END_DISCONNECT;
  47.     else if( wcscmp(hupStrId, L"near_end_disconnect") == 0 )
  48.       return VXItel_TRANSFER_NEAR_END_DISCONNECT;
  49.     else if( wcscmp(hupStrId, L"busy") == 0 )
  50.       return VXItel_TRANSFER_BUSY;
  51.     else if( wcscmp(hupStrId, L"noanswer") == 0 )
  52.       return VXItel_TRANSFER_NOANSWER;
  53.     else if( wcscmp(hupStrId, L"network_busy") == 0 )
  54.       return VXItel_TRANSFER_NETWORK_BUSY;
  55.     else if( wcscmp(hupStrId, L"network_disconnect") == 0 )
  56.       return VXItel_TRANSFER_NETWORK_DISCONNECT;
  57.     else if( wcscmp(hupStrId, L"maxtime_disconnect") == 0 )
  58.       return VXItel_TRANSFER_MAXTIME_DISCONNECT;
  59.     else if( wcscmp(hupStrId, L"caller_hangup") == 0 )
  60.       return VXItel_TRANSFER_CALLER_HANGUP;
  61.   }
  62.   return VXItel_TRANSFER_UNKNOWN; 
  63. }
  64. // VXItel implementation of the VXItel interface
  65. //
  66. class VXItelImpl {
  67. public:
  68.   VXItelImpl()
  69.   : statusMutex(NULL), status(VXItel_STATUS_INACTIVE)
  70.   {
  71.     VXItrdMutexCreate(&statusMutex);
  72.   }  
  73.   ~VXItelImpl()
  74.   {
  75.     VXItrdMutexDestroy(&statusMutex);
  76.   }
  77.   
  78.   // Set Line Status
  79.   void SetLineStatus(VXItelStatus st)
  80.   {
  81.     VXItrdMutexLock(statusMutex);
  82.     status = st;
  83.     VXItrdMutexUnlock(statusMutex);
  84.   }
  85.   // Get Line Status
  86.   VXItelStatus GetLineStatus(void)
  87.   {
  88.     VXItelStatus st;
  89.     VXItrdMutexLock(statusMutex);
  90.     st = status;
  91.     VXItrdMutexUnlock(statusMutex);
  92.     return st;
  93.   }
  94.   
  95.   // Base interface, must be first
  96.   VXItelInterfaceEx telIntf;
  97.   // Log interface for this resource
  98.   VXIlogInterface *log;
  99.   
  100.   // Line status
  101.   VXItelStatus status;
  102.   
  103.   // Mutex for line status
  104.   VXItrdMutex *statusMutex;
  105. };
  106. // A few conversion functions...
  107. static inline VXItelImpl * ToVXItelImpl(VXItelInterface * i)
  108. { return reinterpret_cast<VXItelImpl *>(i); }
  109. static inline VXItelImpl * ToVXItelImpl(VXItelInterfaceEx * i)
  110. { return reinterpret_cast<VXItelImpl *>(i); }
  111. /*******************************************************
  112.  *
  113.  * Utility functions
  114.  *
  115.  *******************************************************/ 
  116. /**
  117.  * Log an error
  118.  */
  119. static VXIlogResult Error(VXItelImpl *impl, VXIunsigned errorID,
  120.                           const VXIchar *format, ...)
  121. {
  122.   VXIlogResult rc;
  123.   va_list arguments;
  124.   if ((! impl) || (! impl->log))
  125.     return VXIlog_RESULT_NON_FATAL_ERROR;
  126.   
  127.   if (format) {
  128.     va_start(arguments, format);
  129.     rc = (*impl->log->VError)(impl->log, COMPANY_DOMAIN L".VXItel", 
  130.                               errorID, format, arguments);
  131.     va_end(arguments);
  132.   } else {
  133.     rc = (*impl->log->Error)(impl->log, COMPANY_DOMAIN L".VXItel",
  134.                              errorID, NULL);
  135.   }
  136.   return rc;
  137. }
  138. /**
  139.  * Log a diagnostic message
  140.  */
  141. static VXIlogResult Diag(VXItelImpl *impl, VXIunsigned tag, 
  142.                          const VXIchar *subtag, const VXIchar *format, ...)
  143. {
  144.   VXIlogResult rc;
  145.   va_list arguments;
  146.   if ((! impl) || (! impl->log))
  147.     return VXIlog_RESULT_NON_FATAL_ERROR;
  148.   if (format) {
  149.     va_start(arguments, format);
  150.     rc = (*impl->log->VDiagnostic)(impl->log, tag + gblDiagLogBase, subtag,
  151.                                    format, arguments);
  152.     va_end(arguments);
  153.   } else {
  154.     rc = (*impl->log->Diagnostic)(impl->log, tag + gblDiagLogBase, subtag,
  155.                                   NULL);
  156.   }
  157.   return rc;
  158. }
  159. /*******************************************************
  160.  *
  161.  * Method routines for VXItelInterface structure
  162.  *
  163.  *******************************************************/ 
  164. // Get the VXItel interface version supported
  165. //
  166. static VXIint32 VXItelGetVersion(void)
  167. {
  168.   return VXI_CURRENT_VERSION;
  169. }
  170. // Get the implementation name
  171. //
  172. static const VXIchar* VXItelGetImplementationName(void)
  173. {
  174.   static const VXIchar IMPLEMENTATION_NAME[] = COMPANY_DOMAIN L".VXItel";
  175.   return IMPLEMENTATION_NAME;
  176. }
  177. // Begin a session
  178. //
  179. static 
  180. VXItelResult VXItelBeginSession(VXItelInterface * pThis, VXIMap *)
  181. {
  182.   if( !pThis ) return VXItel_RESULT_INVALID_ARGUMENT;
  183.   VXItelImpl *impl = ToVXItelImpl(pThis);
  184.   impl->SetLineStatus(VXItel_STATUS_ACTIVE);
  185.   return VXItel_RESULT_SUCCESS;
  186. }
  187. // End a session
  188. //
  189. static
  190. VXItelResult VXItelEndSession(VXItelInterface *pThis, VXIMap *)
  191. {
  192.   if( !pThis ) return VXItel_RESULT_INVALID_ARGUMENT;
  193.   VXItelImpl *impl = ToVXItelImpl(pThis);
  194.   impl->SetLineStatus(VXItel_STATUS_INACTIVE);
  195.   return VXItel_RESULT_SUCCESS;
  196. }
  197. static
  198. VXItelResult VXItelGetStatus(VXItelInterface * pThis, VXItelStatus *status)
  199. {
  200.   if( !pThis ) return VXItel_RESULT_INVALID_ARGUMENT;
  201.   VXItelImpl *impl = ToVXItelImpl(pThis);
  202.   *status = impl->GetLineStatus();
  203.   return VXItel_RESULT_SUCCESS;
  204. }
  205. /**
  206.  * Disconnect caller (ie hang up).
  207.  *
  208.  * @param  ch   A handle to the channel resource manager
  209.  */
  210. static
  211. VXItelResult VXItelDisconnect(VXItelInterface * pThis,const VXIMap *namelist)
  212. {
  213.   if( !pThis ) return VXItel_RESULT_INVALID_ARGUMENT;
  214.   VXItelImpl *impl = ToVXItelImpl(pThis);
  215.   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"Disconnect");
  216.   impl->SetLineStatus(VXItel_STATUS_INACTIVE); 
  217.   return VXItel_RESULT_SUCCESS;
  218. }
  219. static bool GetReturnCode(const VXIMap* props, VXItelResult& retcode)
  220. {
  221.   const VXIValue* val = VXIMapGetProperty(props, L"ReturnCode");
  222.   if (val != NULL && VXIValueGetType(val) == VALUE_STRING) {
  223.     const VXIchar* strval = VXIStringCStr(reinterpret_cast<const VXIString*>(val));
  224.     if( strval ) {
  225.       if( wcscmp(strval, L"VXItel_RESULT_CONNECTION_NO_AUTHORIZATION") == 0 ) {
  226.         retcode = VXItel_RESULT_CONNECTION_NO_AUTHORIZATION;
  227.         return true;  
  228.       }        
  229.       else if( wcscmp(strval, L"VXItel_RESULT_CONNECTION_BAD_DESTINATION") == 0 ) {
  230.         retcode = VXItel_RESULT_CONNECTION_BAD_DESTINATION;
  231.         return true;  
  232.       }        
  233.       else if( wcscmp(strval, L"VXItel_RESULT_CONNECTION_NO_ROUTE") == 0 ) {
  234.         retcode = VXItel_RESULT_CONNECTION_NO_ROUTE;
  235.         return true;  
  236.       }        
  237.       else if( wcscmp(strval, L"VXItel_RESULT_CONNECTION_NO_RESOURCE") == 0 ) {
  238.         retcode = VXItel_RESULT_CONNECTION_NO_RESOURCE;
  239.         return true;  
  240.       }        
  241.       else if( wcscmp(strval, L"VXItel_RESULT_UNSUPPORTED_URI") == 0 ) {
  242.         retcode = VXItel_RESULT_UNSUPPORTED_URI;
  243.         return true;  
  244.       }        
  245.       else if( wcscmp(strval, L"VXItel_RESULT_UNSUPPORTED") == 0 ) {
  246.         retcode = VXItel_RESULT_UNSUPPORTED;
  247.         return true;  
  248.       }        
  249.     }   
  250.   }
  251.   return false;
  252. }
  253. /**
  254.  * Blind Transfer.
  255.  */
  256. static
  257. VXItelResult VXItelTransferBlind(VXItelInterface * vxip, 
  258.                                  const VXIMap * prop,
  259.                                  const VXIchar * transferDestination,
  260.                                  VXIMap **resp)
  261. {
  262.   VXItelImpl *impl = ToVXItelImpl(vxip);
  263.   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"TransferBlind: %s", 
  264.        transferDestination);
  265.   *resp = VXIMapCreate();
  266.   VXItelTransferStatus xferStatus = VXItel_TRANSFER_UNKNOWN;
  267.   const VXIValue* dval = VXIMapGetProperty(prop, L"TransferStatus");
  268.   if( dval && VXIValueGetType(dval) == VALUE_STRING ){
  269.     const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
  270.     xferStatus = GetXferStatus(hid);
  271.   }
  272.   VXIMapSetProperty(*resp, TEL_TRANSFER_STATUS, 
  273.                     (VXIValue *) VXIIntegerCreate(xferStatus));
  274.   return VXItel_RESULT_SUCCESS;
  275. }
  276. /**
  277.  * Consultation Transfer.
  278.  */
  279. static
  280. VXItelResult VXItelTransferConsultation(VXItelInterface * vxip, 
  281.                                  const VXIMap * prop,
  282.                                  const VXIchar * transferDestination,
  283.                                  VXIMap **resp)
  284. {
  285.   VXItelImpl *impl = ToVXItelImpl(vxip);
  286.   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"TransferConsultation: %s", 
  287.        transferDestination);
  288.   *resp = VXIMapCreate();
  289.   VXItelTransferStatus xferStatus = VXItel_TRANSFER_CONNECTED;
  290.   const VXIValue* dval = VXIMapGetProperty(prop, L"AnswerDelay");
  291.   if( dval && VXIValueGetType(dval) == VALUE_STRING ){
  292.     const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
  293.     int answerDelay = SWIwtoi(hid);
  294.     const VXIValue* ct = VXIMapGetProperty(prop, TEL_CONNECTTIMEOUT);
  295.     if (answerDelay > VXIIntegerValue(reinterpret_cast<const VXIInteger*>(ct)))
  296.       xferStatus = VXItel_TRANSFER_NOANSWER;
  297.   }
  298.   else {
  299.     dval = VXIMapGetProperty(prop, L"TransferStatus");
  300.     if( dval && VXIValueGetType(dval) == VALUE_STRING ){
  301.       const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
  302.       xferStatus = GetXferStatus(hid);
  303.       // ignore maxtime_disconnect since it can't happen on consultation
  304.       if (xferStatus == VXItel_TRANSFER_MAXTIME_DISCONNECT)
  305.          xferStatus = VXItel_TRANSFER_CONNECTED;
  306.     }
  307.   }
  308.   VXIMapSetProperty(*resp, TEL_TRANSFER_STATUS, 
  309.                     (VXIValue *) VXIIntegerCreate(xferStatus));
  310.   return VXItel_RESULT_SUCCESS;
  311. }
  312. /**
  313.  * Bridging Transfer.
  314.  *
  315.  */
  316. static
  317. VXItelResult VXItelTransferBridge(VXItelInterface * vxip, 
  318.                                   const VXIMap * prop,
  319.                                   const VXIchar * transferDestination,
  320.                                   VXIMap **resp)
  321. {
  322.   VXItelImpl *impl = ToVXItelImpl(vxip);
  323.   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"TransferBridge: %s", 
  324.        transferDestination);
  325.   *resp = VXIMapCreate();
  326.   // check for return code
  327.   VXItelResult rc = VXItel_RESULT_SUCCESS;
  328.   if( GetReturnCode(prop, rc) ) return rc;
  329.   VXItelTransferStatus xferStatus = VXItel_TRANSFER_FAR_END_DISCONNECT;
  330.   
  331.   const VXIValue* dval = VXIMapGetProperty(prop, L"AnswerDelay");
  332.   if( dval && VXIValueGetType(dval) == VALUE_STRING ){
  333.     const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
  334. int answerDelay = SWIwtoi(hid);
  335. const VXIValue* ct = VXIMapGetProperty(prop, TEL_CONNECTTIMEOUT);
  336. if (answerDelay > VXIIntegerValue(reinterpret_cast<const VXIInteger*>(ct)))
  337.   xferStatus = VXItel_TRANSFER_NOANSWER;
  338.   }
  339.   else {
  340.     dval = VXIMapGetProperty(prop, L"TransferStatus");
  341.     if( dval && VXIValueGetType(dval) == VALUE_STRING ){
  342.       const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
  343.       xferStatus = GetXferStatus(hid);
  344.     }
  345.   }
  346.   VXIMapSetProperty(*resp, TEL_TRANSFER_STATUS, 
  347.                     (VXIValue *) VXIIntegerCreate(xferStatus));
  348.   VXIMapSetProperty(*resp, TEL_TRANSFER_DURATION, (VXIValue *) VXIIntegerCreate(12000));
  349.   return VXItel_RESULT_SUCCESS;
  350. }
  351. /**
  352.  * Enable calls on the channel
  353.  *
  354.  */
  355. static VXItelResult
  356. VXItelEnableCall(struct VXItelInterfaceEx  *pThis)
  357. {
  358.   if (! pThis) return VXItel_RESULT_INVALID_ARGUMENT;
  359.   return VXItel_RESULT_SUCCESS;
  360. }
  361. /**
  362.  * Wait for and answer a call on the channel
  363.  *
  364.  */
  365. static VXItelResult
  366. VXItelWaitForCall(struct VXItelInterfaceEx  *vxip,
  367.                   VXIMap                 **telephonyProps)
  368. {
  369.   if ((! vxip) || (! telephonyProps))
  370.     return VXItel_RESULT_INVALID_ARGUMENT;
  371.   VXItelImpl *impl = ToVXItelImpl(vxip);
  372.   Diag(impl, DIAG_TAG_SIGNALING, NULL, L"New call");
  373.   *telephonyProps = VXIMapCreate();
  374.   if (! *telephonyProps) return VXItel_RESULT_OUT_OF_MEMORY;
  375.   VXIMapSetProperty(*telephonyProps, L"dnis",
  376.                     (VXIValue *)VXIStringCreate(L"6174284444"));
  377.   VXIMapSetProperty(*telephonyProps, L"ani", 
  378.                     (VXIValue *)VXIStringCreate(L"6508470000"));
  379.   return VXItel_RESULT_SUCCESS;
  380. }
  381. /*******************************************************
  382.  * Factory and init routines
  383.  *******************************************************/ 
  384. /**
  385.  * Global initialization of Telephony platform.
  386.  */
  387. VXITEL_API VXItelResult VXItelInit (VXIlogInterface  *log,
  388.                                     VXIunsigned       diagLogBase,
  389.                                     VXIMap            *args)
  390. {
  391.   if (! log) return VXItel_RESULT_INVALID_ARGUMENT;
  392.   gblDiagLogBase = diagLogBase;
  393.   return VXItel_RESULT_SUCCESS;
  394. }
  395. /**
  396.  * Global shutdown of Telephony platform.
  397.  */
  398. VXITEL_API VXItelResult VXItelShutDown (VXIlogInterface  *log)
  399. {
  400.   if (! log) return VXItel_RESULT_INVALID_ARGUMENT;
  401.   return VXItel_RESULT_SUCCESS;
  402. }
  403. /**
  404.  * Creates an VXItel implementation of the VXItel interface
  405.  */
  406. VXITEL_API VXItelResult VXItelCreateResource(VXIlogInterface *log,
  407.                                              VXItelInterface **tel)
  408. {
  409.   if (! log) return VXItel_RESULT_INVALID_ARGUMENT;
  410.   VXItelImpl* pp = new VXItelImpl();
  411.   if (pp == NULL) return VXItel_RESULT_OUT_OF_MEMORY;
  412.   pp->log = log;
  413.   pp->telIntf.vxitel.GetVersion     = VXItelGetVersion;
  414.   pp->telIntf.vxitel.GetImplementationName = VXItelGetImplementationName;
  415.   pp->telIntf.vxitel.BeginSession   = VXItelBeginSession;
  416.   pp->telIntf.vxitel.EndSession     = VXItelEndSession;
  417.   pp->telIntf.vxitel.GetStatus      = VXItelGetStatus;
  418.   pp->telIntf.vxitel.Disconnect     = VXItelDisconnect;
  419.   pp->telIntf.vxitel.TransferBlind  = VXItelTransferBlind;
  420.   pp->telIntf.vxitel.TransferBridge = VXItelTransferBridge;
  421.   pp->telIntf.vxitel.TransferConsultation = VXItelTransferConsultation;
  422.   pp->telIntf.EnableCall          = VXItelEnableCall;
  423.   pp->telIntf.WaitForCall         = VXItelWaitForCall;
  424.   *tel = &pp->telIntf.vxitel;
  425.   return VXItel_RESULT_SUCCESS;
  426. }
  427. /**
  428.  * Destroys the specified VXItel implementation
  429.  */
  430. VXITEL_API VXItelResult VXItelDestroyResource(VXItelInterface **tel)
  431. {
  432.   if (tel == NULL || *tel == NULL) return VXItel_RESULT_INVALID_ARGUMENT;
  433.   VXItelImpl* telImpl = reinterpret_cast<VXItelImpl*>(*tel);
  434.   delete telImpl;
  435.   *tel = NULL;
  436.   return VXItel_RESULT_SUCCESS;
  437. }