tapiwave.c

来自「一个tapi开发的很好的语音通信程序」· C语言 代码 · 共 1,109 行 · 第 1/3 页

C
1,109
字号
            case LINECALLSTATE_BUSY:
            case LINECALLSTATE_DISCONNECTED:
               if (dwParam1 == LINECALLSTATE_BUSY)
                  printf("BUSY.  Hanging up.\n");
               else
                  printf("DISCONNECTED.  Hanging up.\n");

               if (!bDropped)
                  dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
               if (dwLineDropAsyncID < 0)
               {
                  printf("lineDrop failed.  Terminating\n");
                  hCall = 0;
                  StopEverything();
               }

               bDropped = TRUE;

               break;

            case LINECALLSTATE_OFFERING:
            case LINECALLSTATE_ACCEPTED:  // Could be handed off an accepted call
               if (bAnswered)
                  break;

               if (dwParam1 == LINECALLSTATE_OFFERING)
                  printf("Answering an OFFERING call.\r\n");
               else
                  printf("Answering an ACCEPTED call.\r\n");

               lRet = lineAnswer(hCall, NULL, 0);

               // Should check to make sure lineAnswer succeeded

               bAnswered = TRUE;

               break;

            case LINECALLSTATE_CONNECTED:
               if (!bConnected)
               {
                  bConnected = TRUE;
                  printf("CONNECTED.\n");

                  DoConnectedStuff();

                  if (!bDropped)
                  {
                     dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
                     if (dwLineDropAsyncID < 0)
                     {
                        printf("lineDrop failed.  Terminating\n");
                        hCall = 0;
                        StopEverything();
                     }

                     bDropped = TRUE;
                  }
               }
               break;
         }

         break;
      }
   }
}


BOOL GetCallInfo()
{
   while (TRUE)
   {
      if (lRet = lineGetCallInfo(hCall, lpLineCallInfo))
      {
         printf("lineGetCallInfo failed: %s.\n", FormatTapiError(lRet, szBuff));
         return FALSE;
      }

      if (lpLineCallInfo->dwNeededSize > lpLineCallInfo->dwTotalSize)
      {
         LocalReAlloc(lpLineCallInfo, lpLineCallInfo->dwNeededSize, LMEM_MOVEABLE);
         lpLineCallInfo->dwTotalSize = lpLineCallInfo->dwNeededSize;
         continue;
      }

      return TRUE;
   }
}


// Parse the command line and change the default settings.
BOOL SetupEnvironment (int argc, char * argv[])
{
   int i = 0, j;
   char chFlag;
   BOOL bMaxCallsSet = FALSE;

   if (argc == 1)
   {
      PrintHelp();
      return FALSE;
   }

   while (++i < argc)
   {
      j = 0;
      if ((argv[i][j] == '/') || (argv[i][j] == '-') || (argv[i][j] == '+'))
         j = 1;

      chFlag = argv[i][j++];

      if (argv[i][j] == ':')
         j++;
      if (argv[i][j] == '\"')
         j++;

      switch(tolower(chFlag))
      {
         case '?':
            printf("Runs a test of the TAPI and WAVE system.\n");
            PrintHelp();
            return FALSE;

         case 'l':
            if (!sscanf(&argv[i][j], "%lu", &dwDeviceID))
            {
               printf("Invalid [L]ine selection.\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            break;

         case 'i':
            if (!sscanf(&argv[i][j], "%lu", &dwAddressID))
            {
               printf("Invalid Address [I]D selection.\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            break;

         case 'p':
            bDontClose = TRUE;
            break;

         case 'x':
            bLogExtraInfo = TRUE;
            printf("Extra call and data flow information will be displayed.\n");
            break;

         case 'a':
            bAnswer = TRUE;
            break;

         case 'd':
            if (!sscanf(&argv[i][j], "%s\"", &szPhoneNumber))
            {
               printf("Invalid phone number selection.\r\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            bAnswer = FALSE;
            break;

         case 'f':
            if (!sscanf(&argv[i][j], "%s\"", &szFileName))
            {
               printf("Invalid Wave File selection.\r\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            break;

         case 'w':
            if (!sscanf(&argv[i][j], "%lu", &WaveInID))
            {
               printf("Invalid [W]ave ID selection.\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            if (WaveInID == 99)
            {
               printf("Using WAVE_MAPPER.\n");
               WaveOutID = WaveInID = WAVE_MAPPER;

            }
            else
               WaveOutID = WaveInID;

            bWaveLocal = TRUE;
            break;

         case 't':
            if ((2 != sscanf(&argv[i][j], "%lu,%lu", 
                  &dwWaveBuffers, &dwWaveBuffSize)) ||
                !(dwWaveBuffers && dwWaveBuffSize))
            {
               printf("Invalid wave [T]est values.\n");
               bCommandLineError = TRUE;
               PrintHelp();
               return FALSE;
            }
            break;

         case 'z':
            dwWaveMapped = 0;
            break;

      }
   }

   return TRUE;
}


// Print the help screen.
void PrintHelp()
{
   printf(
"\n"
"%s [options]\n"
"\n"
"[Wave File]  File to record to or play back.\n"
"\n"
"Options:\n"
"/L:#        Line Device ID (dwDeviceID) to use.\n"
//"/I:#        Line Address ID to use.  Ignored when AutoAnswer is set.\n"
"/P          Pause and wait for ^C when finished.\n"
"/X          Display extra call and data flow information.\n"
"/F:file     Use file as the wave file\n"
"/D:[number] Dial number\n"
"/A          Answer a call\n"
"\n"
//"/W:#        Specify a wave ID to use for both IN and OUT.\n"
//"            If this flag is used, all TAPI is bypassed.\n"
//"            A wave ID of 99 means to use WAVE_MAPPER.\n"
//"/T:#1,#2    Test wave output with a #1 buffers of size #2.  ^c to terminate test.\n"
"/Z          Don't use WAVE_MAPPED\n"
"\n"
"defaults: /L:%lu /I:%lu\n /F:%s /A"
"\n",
szAppName, dwDeviceID, dwAddressID, szFileName);
}




// Break Hander: Try and terminate gracefully.
// Note that ^Break can call lineShutdown *DURING* a lineMakeCall.  Very
// unpredictable results; TAPI is not re-entrant and is *usually* protected by
// the Win16 Mutex.  However, a Break Handler is a special case.
BOOL BreakHandlerRoutine(DWORD dwCtrlType)
{
   // ^BREAK will always break.  
   // Use with care; it can mess up TAPI if in the middle of a TAPI API.
   if (dwCtrlType == CTRL_BREAK_EVENT)
   {
      printf("\r\n^[Break] terminated!  TAPI may not be left in a usable state.\r\n\r\n");

      lineShutdown(hLineApp);
      LocalFree(lpLineDevStatus);
      LocalFree(lpLineCallInfo);
      LocalFree(lpLineCallParams);
      CloseHandle(hSleep);
      ExitProcess(1);
   }
   else
   {
      if (hCall)
         printf("\r\n^C Dropping call in progress.\r\n\r\n");
      else 
         printf("\r\n^C stopped.\r\n\r\n");

      StopEverything();
      SetEvent(hSleep);
   }
   return TRUE;
}

BOOL PumpMessages(BOOL bWaitForMessage)
{
	static MSG msg;

   if (bReadyToEnd)
	   return FALSE;

   if (bWaitForMessage)
   {
      if (!GetMessage(&msg, NULL, 0, 0))
         return FALSE;
   }
   else
      if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
         return TRUE;
      else
         if (msg.message == WM_QUIT)
            return FALSE;

   TranslateMessage(&msg);
   DispatchMessage(&msg);

   return TRUE;
}


void StopEverything()
{
   bReadyToEnd = TRUE;

   if (bConnected)
       StopConnectedStuff();

   if (hCall && !bDropped)
   {
      dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
      if (dwLineDropAsyncID < 0)
      {
         printf("lineDrop failed.  Terminating\n");
         hCall = 0;
      }
      bDropped = TRUE;
   }

   // lets prime the pump with a message.
   PostThreadMessage(dwThreadID, WM_USER, 0, 0);
}


// ---------------

// CONNECTED!  Now do data steam testing.  Return FALSE to stop TAPI.
BOOL DoConnectedStuff()
{
   MMRESULT mmResult;

   if (!bWaveLocal)
   {
      if (lRet = lineGetID(0, 0, hCall, LINECALLSELECT_CALL, 
         (LPVARSTRING) lpVarString, "wave/in"))
      {
         printf("lineGetID failed %s\n", FormatTapiError(lRet, szBuff));
         return FALSE;
      }

      WaveInID = *((LPUINT)((LPBYTE) lpVarString +
                    (lpVarString -> dwStringOffset)));

      if (lRet = lineGetID(0, 0, hCall, LINECALLSELECT_CALL, 
         (LPVARSTRING) lpVarString, "wave/out"))
      {
         printf("lineGetID failed %s\n", FormatTapiError(lRet, szBuff));
         return FALSE;
      }

      WaveOutID = *((LPUINT)((LPBYTE) lpVarString +
                    (lpVarString -> dwStringOffset)));
   }

   printf("Using WaveInID %lu and WaveOutID %lu\n",
          (DWORD) WaveInID, (DWORD) WaveOutID);


   // Open the given file for reading using buffered I/O.
   if(!(hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF)))
   {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?