TAPIAPP.CPP
上传用户:chinamans
上传日期:2013-03-17
资源大小:202k
文件大小:11k
源码类别:

TAPI编程

开发平台:

Visual C++

  1. // tapiapp.cpp : Defines the class behaviors for the TAPI application.
  2. // (c) Dialogic corp 1995, 1996
  3. #include "stdafx.h"
  4. #include <tapi.h>
  5. #include "tapiapp.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char BASED_CODE THIS_FILE[] = __FILE__;
  9. #endif
  10. //CMap<DWORD, DWORD, ASYNCCALL, ASYNCCALL&> g_cmAsyncCalls; // globally defined
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CTapiApp
  13. BEGIN_MESSAGE_MAP(CTapiApp, CWinApp)
  14. //{{AFX_MSG_MAP(CTapiApp)
  15. // NOTE - the ClassWizard will add and remove mapping macros here.
  16. //    DO NOT EDIT what you see in these blocks of generated code!
  17. //}}AFX_MSG
  18. ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  19. END_MESSAGE_MAP()
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CTalkApp construction
  22. CTapiApp::CTapiApp()
  23. {
  24. // TODO: add construction code here,
  25. // Place all significant initialization in InitInstance
  26. m_hApp = NULL;
  27. m_dwLines = 0L;
  28. m_hAsyncListSem = NULL;
  29. }
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CTapiApp initialization
  32. BOOL CTapiApp::InitInstance()
  33. {
  34. // Standard initialization; MUST be called by the child class & return TRUE
  35. // if success; the child decides what to do after
  36. Enable3dControls();
  37. LoadStdProfileSettings();  // Load standard INI file options (including MRU)
  38. if(!InitTAPIApp()) // lineInit etc
  39. {
  40. MessageBox(NULL, "Failed to initialize TAPI", NULL, MB_ICONSTOP);
  41. return FALSE;
  42. }
  43. return TRUE;
  44. }
  45. int CTapiApp::ExitInstance() 
  46. {
  47. CloseTAPIApp();
  48. return CWinApp::ExitInstance();
  49. }
  50. // Call lineInit
  51. BOOL CTapiApp::InitTAPIApp()
  52. {
  53. LONG lResult, i=0;
  54. while (LINEERR_REINIT == (lResult = lineInitialize(&m_hApp, m_hInstance,
  55.             LineCallBackProc, "Talker32", &m_dwLines)))
  56. {
  57. Sleep(1000);
  58. i++;
  59. if(i > 10) return FALSE;
  60. }
  61. m_pAsyncList = new CMAPASYNC; // list of asynchronous calls 
  62. if(lResult || m_pAsyncList == NULL) return FALSE;
  63. m_hAsyncListSem = CreateMutex(NULL, FALSE, "TALKER32_ASYNC_LIST");
  64. if(m_hAsyncListSem == NULL) return FALSE;
  65. return TRUE;
  66. }
  67. // MUST be protected
  68. void CTapiApp::SetAsyncID(DWORD dwID, WORD wState, WORD wFunc, LPVOID pvLine, LPVOID pvCall)
  69. {
  70. DWORD dwrc;
  71. PASYNCCALL pAsync = new ASYNCCALL;
  72. if(!pAsync) return;
  73. TRACE("*** TALKER32 ***: Set ID #%d entering wait for semn", dwID);
  74. dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
  75. if(dwrc != WAIT_OBJECT_0) 
  76. {
  77. TRACE("*** TALKER32 ***: Set ID #%d wait for sem failed rc=%lxn", dwID, dwrc);
  78. return;
  79. }
  80. pAsync->dwID = dwID;
  81. pAsync->wState = wState;
  82. pAsync->wFunction = wFunc;
  83. pAsync->pvLine = pvLine;
  84. pAsync->pvCall = pvCall;
  85. m_pAsyncList->SetAt(pAsync->dwID, pAsync);
  86. TRACE("*** TALKER32 ***: Set ID #%d releasing mutexn", dwID);
  87. ReleaseMutex(m_hAsyncListSem);
  88. }
  89. // MUST be protected
  90. PASYNCCALL CTapiApp::FindAsyncID(DWORD dwID, WORD wAction)
  91. {
  92. PASYNCCALL pAsync = NULL;
  93. ASSERT(m_pAsyncList != NULL);
  94. TRACE("*** TALKER32 ***: %s ID #%d entering wait for semn", wAction==FIND_ID?"find":"remove",dwID);
  95. DWORD dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
  96. if(dwrc != WAIT_OBJECT_0) 
  97. {
  98. TRACE("*** TALKER32 ***: Find async ID #%d wait for sem failed rc=%lxn",dwID, dwrc);
  99. return NULL;
  100. if(m_pAsyncList->Lookup(dwID, pAsync))
  101. {
  102. if(wAction == REMOVE_ID) 
  103. {  
  104. m_pAsyncList->RemoveKey(dwID);
  105. delete pAsync;
  106. TRACE("*** TALKER32 ***: ID#%d releasing mutexn", dwID);
  107. ReleaseMutex(m_hAsyncListSem);
  108. return NULL;
  109. }
  110. }
  111. // if found, returns what found
  112. TRACE("*** TALKER32 ***: ID #%d releasing mutexn", dwID);
  113. ReleaseMutex(m_hAsyncListSem);
  114. return pAsync;
  115. }
  116. void CTapiApp::CloseTAPIApp()
  117. {
  118. lineShutdown(m_hApp);
  119. PurgeAsyncQue();
  120. CloseHandle(m_hAsyncListSem);
  121. m_hAsyncListSem = NULL;
  122. // Delete the async requests queue; must be protected
  123. void CTapiApp::PurgeAsyncQue()
  124. {
  125. DWORD dwrc;
  126. if(m_pAsyncList != NULL) 
  127. {
  128. TRACE("*** TALKER32 ***: Purge queue entering wait for semn");
  129. dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
  130. if(dwrc != WAIT_OBJECT_0) 
  131. {
  132. TRACE("*** TALKER32 ***: Purge async queue wait for sem failed rc=%lxn", dwrc);
  133. return;
  134. }
  135. if(!m_pAsyncList->IsEmpty()) // list not empty, cleanup
  136. {
  137. PASYNCCALL pAsyncCall = NULL;
  138. DWORD dwID;
  139. int j;
  140. int nCount = m_pAsyncList->GetCount();
  141. POSITION pos = m_pAsyncList->GetStartPosition();
  142. for(j=0; j<nCount && pos != NULL; j++) // iterate thru list, delete all
  143. {
  144. m_pAsyncList->GetNextAssoc(pos, dwID, pAsyncCall);
  145. if(pAsyncCall) delete pAsyncCall;
  146. }
  147. }
  148. delete m_pAsyncList;
  149. m_pAsyncList = NULL;
  150. TRACE("*** TALKER32 ***: Purge queue releasing mutexn");
  151. ReleaseMutex(m_hAsyncListSem);
  152. }
  153. }
  154. void CTapiApp::OnLineReply(DWORD dwCallback, DWORD dwRequest, DWORD dwStatus)
  155. {
  156. // first, find the request
  157. PASYNCCALL pAC = FindAsyncID(dwRequest, FIND_ID);
  158. if(pAC == NULL)  // not found for some reason (???)
  159. {
  160. TRACE1("*** TALKER32 *** :Request ID=%lx not found!n", dwRequest);
  161. return;
  162. }
  163. ASSERT(pAC->dwID == dwRequest);  // sanity check
  164. FindAsyncID(dwRequest, REMOVE_ID); // Done, remove the ID from list
  165. }
  166. // get info on incoming call
  167. LPLINECALLINFO CTapiApp::GetCallInfo(HCALL hCall)
  168. {
  169.     LPLINECALLINFO lpCallInfo = NULL;
  170.     LONG lrc = 0;
  171.     DWORD dwSize = sizeof(LINECALLINFO)+1000;
  172.     DWORD i;
  173.     
  174.     // keep trying until buffer is big enough 
  175.     for (i=0; i<2; i++)
  176. {
  177.      lpCallInfo = (LPLINECALLINFO) new char[dwSize];
  178.      if (lpCallInfo == NULL)
  179.          return NULL;
  180.     lpCallInfo->dwTotalSize = dwSize;
  181.         lrc = lineGetCallInfo(hCall,lpCallInfo);
  182. if(lrc < 0) goto FinishLineCallInfo;
  183.         dwSize = lpCallInfo->dwNeededSize; 
  184. if(dwSize <= lpCallInfo->dwTotalSize) break;   // success
  185.          
  186. delete (char *) lpCallInfo;
  187.     return lpCallInfo;
  188. FinishLineCallInfo: 
  189.     if (lpCallInfo != NULL)
  190.         delete (LPBYTE) lpCallInfo;
  191.     return NULL;
  192. // get call status
  193. LPLINECALLSTATUS CTapiApp::GetCallStatus(HCALL hCall)
  194. {
  195.     LPLINECALLSTATUS lpCallInfo = NULL;
  196.     LONG lrc = 0;
  197.     DWORD dwSize = sizeof(LINECALLSTATUS)+1000;
  198.     DWORD i;
  199.     
  200.     // keep trying until buffer is big enough 
  201.     for (i=0; i<2; i++)
  202. {
  203.      lpCallInfo = (LPLINECALLSTATUS) new char[dwSize];
  204.      if (lpCallInfo == NULL)
  205.          return NULL;
  206.     lpCallInfo->dwTotalSize = dwSize;
  207.         lrc = lineGetCallStatus(hCall,lpCallInfo);
  208. if(lrc < 0) goto FinishLineCallStatus;
  209.         dwSize = lpCallInfo->dwNeededSize; 
  210. if(dwSize <= lpCallInfo->dwTotalSize) break;   // success
  211.          
  212. delete (char *) lpCallInfo;
  213.     return lpCallInfo;
  214. FinishLineCallStatus: 
  215.     if (lpCallInfo != NULL)
  216.         delete (LPBYTE) lpCallInfo;
  217.     return NULL;
  218. }
  219. extern "C" {
  220. VOID WINAPI LineCallBackProc(DWORD hDevice, DWORD dwMsg, 
  221.      DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, 
  222.      DWORD dwParam3)
  223. {
  224. // char szDigit[2]={0,0};
  225.  
  226. TRACE("*** TALKER32 *** lineCallBack:Message=%ld,P1=%lx, P2=%lx, P3=%lxn", 
  227. dwMsg, dwParam1,dwParam2,dwParam3); 
  228.     
  229.     switch (dwMsg) 
  230.         { 
  231.         case LINE_LINEDEVSTATE:
  232.             if (dwParam1 & LINEDEVSTATE_REINIT)
  233. {
  234.          TRACE("*** TALKER32 *** :LINEDEVSTATE_REINITn");
  235. } // see DIALER
  236.             if (dwParam1 & LINEDEVSTATE_TRANSLATECHANGE)
  237.     {
  238.          TRACE("*** TALKER32 *** :LINEDEVSTATE_TRANSLATECHANGEn");
  239. } // see DIALER
  240.             if (dwParam1 & LINEDEVSTATE_CAPSCHANGE)
  241.             {
  242.          TRACE("*** TALKER32 *** :LINEDEVSTATE_CAPSCHANGEn");
  243. } //  CAPSCHANGE, see DIALER 
  244.             if (dwParam1 & LINEDEVSTATE_REMOVED)
  245. {  // treat removal like a request to close the line 
  246.          TRACE("*** TALKER32 *** :LINEDEVSTATE_REMOVEDn");
  247. } // REMOVED, see DIALER 
  248.             break;
  249.         case LINE_ADDRESSSTATE:
  250.         TRACE("*** TALKER32 *** :LINE_ADDRESSSTATEn");
  251. break; // see DIALER
  252.         // process state transition 
  253.         case LINE_CALLSTATE:
  254.         TRACE("*** TALKER32 *** :LINE_CALLSTATEn");
  255. ((CTapiApp *)AfxGetApp())->OnCallState((HCALL) hDevice, dwCallbackInstance, dwParam1, 
  256. dwParam2, dwParam3);
  257.         break; // see DIALER
  258.         case LINE_CREATE:
  259.             // a new line is created 
  260.         TRACE("*** TALKER32 *** :LINE_CREATEn");
  261.             break;
  262.         case LINE_CLOSE: 
  263. // see if the closed line is the line on which we have an active call
  264. // if it is, do what would have been done if that call went idle
  265. // if not, see if it is a line for which we have a monitoring handle
  266. // if it is, mark that line as closed
  267. // if any calls are being monitored on that line, stop monitoring
  268.         TRACE("*** TALKER32 *** :LINE_CLOSEn");
  269.             break; 
  270.         // handle simple tapi request  
  271.         case LINE_REQUEST:
  272.         TRACE("*** TALKER32 *** :LINE_REQUESTn");
  273.             break;
  274.         // handle the async completion of TAPI functions
  275.         //   lineMakeCall/lineDropCall/lineAnswer
  276.         case LINE_REPLY:
  277.     TRACE("*** TALKER32 *** :LINE_REPLYn");
  278. ((CTapiApp *)AfxGetApp())->OnLineReply(dwCallbackInstance, dwParam1, dwParam2); // virtual handler
  279.             break;
  280.         // other messages that can be processed 
  281.         case LINE_CALLINFO:
  282.         TRACE("*** TALKER32 *** :LINE_CALLINFOn");
  283. ((CTapiApp *)AfxGetApp())->OnLineCallInfo((HCALL)hDevice, dwCallbackInstance, dwParam1);
  284.             break;
  285.         case LINE_DEVSPECIFIC:
  286.         TRACE("*** TALKER32 *** :LINE_DEVSPECIFICn");
  287. ((CTapiApp *)AfxGetApp())->OnLineDevSpec(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
  288.             break;
  289.         case LINE_DEVSPECIFICFEATURE:
  290.         TRACE("*** TALKER32 *** :LINE_DEVSPECIFICFEATUREn");
  291.             break;
  292.         case LINE_GATHERDIGITS: 
  293.         TRACE("*** TALKER32 *** :LINE_GATHERDIGITSn");
  294. ((CTapiApp *)AfxGetApp())->OnGatherDigits((HCALL)hDevice, dwCallbackInstance, dwParam1);
  295.             break;
  296.         case LINE_GENERATE:
  297.         TRACE("*** TALKER32 *** :LINE_GENERATEn");
  298.             break;
  299.         case LINE_MONITORDIGITS:
  300.         TRACE("*** TALKER32 *** :LINE_MONITORDIGITSn");
  301. ((CTapiApp *)AfxGetApp())->OnMonitorDigits((HCALL)hDevice, dwCallbackInstance, dwParam1, dwParam2);
  302. break;
  303.         case LINE_MONITORMEDIA:
  304.         TRACE("*** TALKER32 *** :LINE_MONITORMEDIAn");
  305. ((CTapiApp *)AfxGetApp())->OnMonitorMedia(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
  306.             break;
  307.         case LINE_MONITORTONE:
  308.         TRACE("*** TALKER32 *** :LINE_MONITORTONEn");
  309.             break;
  310. default:
  311.         TRACE("*** TALKER32 *** :UNACCOUNTED LINE MESSAGEn");
  312. break;
  313.         } /* switch */ 
  314.         
  315. } // LineCallBackProc 
  316. } // extern "C"