⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapisend.cpp

📁 tapi3.0实现的数据发送程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:

                break;;
            }
        }


        //
        // can't use this address. release it
        //

        pAddress->Release();
        pAddress = NULL;

    }

    
    //
    // done with the enumeration. release.
    //

    pEnumAddress->Release();
    pEnumAddress = NULL;


    //
    // log a message if no address was found
    //

    if (NULL == *ppAddress)
    {
        LogError("FindAddress: no address found");

        return E_FAIL;

    }


    LogMessage("FindAddress: completed");

    return S_OK;
}


///////////////////////////////////////////////////////////////////////////////
//
// GetAddressType
//
// convert a address type specified by pszRequestedAddressType
// to tapi LINEADDRESSTYPE_ constants (LINEADDRESSTYPE_PHONENUMBER,
// LINEADDRESSTYPE_IPADDRESS, etc).
//
// returns E_FAIL if the string does not correspond to a valid address type
//
///////////////////////////////////////////////////////////////////////////////

HRESULT GetAddressType(IN char *pszRequestedAddressType, 
                       IN OUT long *pnAddressType)
{
    
    //
    // match address type specified by the user to one of the known
    // address types
    //

    *pnAddressType = 0;


    for (int i = 0; i < g_nNumberOfAddressTypes; i++)
    {

        if (0 == _stricmp(g_szAddressTypes[i], pszRequestedAddressType))
        {
            
            //
            // get the address type constant corresponding to the string
            //

            *pnAddressType =  g_nAddressTypeConstants[i];

            LogMessage("GetAddressType: "
                       "matched address type [%s] to address type [%d]", 
                       pszRequestedAddressType, *pnAddressType);

            return S_OK;
        }


    }

    LogError("GetAddressType: unrecognized address type [%s]", 
              pszRequestedAddressType);

    return E_FAIL;
}



///////////////////////////////////////////////////////////////////////////////
//
// CreateBSTRfromString
// 
// create a bstr from a string supplied. the caller is responsible for
// freeng the returned string by calling SysFreeString. 
//
// returns the allocated string or NULL if failed.
//
///////////////////////////////////////////////////////////////////////////////

BSTR CreateBSTRfromString(IN char *pszString)
{

    //
    // convert to wchar so we can create bstr
    //
    // allocate buffer for resulting string of wchars
    //
    
    size_t nStringLength = strlen(pszString) + 1;

    WCHAR *pwsString = (WCHAR *)AllocateMemory(sizeof(WCHAR) *  nStringLength);

    if (NULL == pwsString)
    {
        LogError("CreateBSTRfromString: "
                 "failed to allocate memory for address string.");

        return NULL;
    }


    //
    // convert to wchar
    //

    int rc = MultiByteToWideChar(CP_ACP, 
                                 0, 
                                 pszString, 
                                 -1, 
                                 pwsString, 
                                 (int)nStringLength);

    if (0 == rc)
    {
        LogError("CreateBSTRfromString: Failed to convert char to wchar");

        FreeMemory(pwsString);
        pwsString = NULL;

        return NULL;
    }


    //
    // create bstr
    //

    BSTR bstr = SysAllocString(pwsString);


    //
    // no longer needed, deallocate
    //

    FreeMemory(pwsString);
    pwsString = NULL;

    return bstr;

}


///////////////////////////////////////////////////////////////////////////////
//
// CreateAndConnectCall
//
// make a call using the address object specified, to the address specified
//
// if successful, returns S_OK and connected call, error otherwise
//
///////////////////////////////////////////////////////////////////////////////

HRESULT CreateAndConnectCall(IN  ITAddress *pAddress,
                             IN  char *pszDestinationAddress,
                             IN  long nAddressType,
                             OUT ITBasicCallControl **ppCall)
{

    HRESULT hr = E_FAIL;

    
    //
    // don't return garbage
    //

    *ppCall = NULL;


    //
    // create a call on the address
    //

    BSTR bstrDestinationAddress = CreateBSTRfromString(pszDestinationAddress);
    
    ITBasicCallControl *pCall = NULL;

    hr = pAddress->CreateCall(bstrDestinationAddress,
                              nAddressType,
                              TAPIMEDIATYPE_AUDIO,
                              &pCall);

    SysFreeString (bstrDestinationAddress);


    if (FAILED(hr))
    {
        LogError("CreateAndConnectCall: Failed to create a call");

        return hr;
    }


    //
    // call created. attempt to connect synchronously
    //

    LogMessage("CreateAndConnectCall: attempting a synchronous connect");

    hr = pCall->Connect(VARIANT_TRUE);

    if (S_OK != hr)
    {

        LogError("CreateAndConnectCall: failed to connect, hr = 0x%lx", hr);


        pCall->Disconnect(DC_NORMAL);


        //
        // we don't need the call object if it failed to connect
        //

        pCall->Release();
        pCall = NULL;

        hr = E_FAIL;

    }
    else
    {
        //
        // call is successful. return the call object
        //

        LogMessage("CreateAndConnectCall: call connected successfully");

        *ppCall = pCall;
    }


    return hr;
}


///////////////////////////////////////////////////////////////////////////////
//
// Call
//
// make a call to the specified address on the first address object
// of the requested type that supports audio
//
// if successful, returns S_OK and connected call, error otherwise
// 
///////////////////////////////////////////////////////////////////////////////

HRESULT Call(IN char *szDestinationAddress,
             IN char *szAddressType,
             OUT ITBasicCallControl **ppCall)
{
    HRESULT hr = E_FAIL;

    
    //
    // we don't want to return garbage even if we fail
    //

    *ppCall = NULL;


    //
    // find address type
    //

    long nAddressType = 0;
    
    hr = GetAddressType(szAddressType, &nAddressType);

    if (FAILED(hr))
    {
        LogError("Call: failed to recognize address type %s", szAddressType);

        return hr;
    }

    
    //
    // find an address for this address type that supports audio
    //
    
    ITAddress *pAddress = NULL;

    hr = FindAddress(nAddressType, &pAddress);

    if (FAILED(hr))
    {
        LogError("Call: failed to find an address with audio for type %s", 
                 szAddressType);

        return hr;
    }


    //
    // have the address. create and connect call
    //

    ITBasicCallControl *pCall = NULL;

    hr = CreateAndConnectCall(pAddress,
                              szDestinationAddress,
                              nAddressType,
                              &pCall);

    pAddress->Release();
    pAddress = NULL;
    
    if (FAILED(hr))
    {
        LogError("Call: Failed to create and connect call");

        return hr;
    }


    //
    // we have a connected call. return it.
    //

    *ppCall = pCall;

    LogMessage("Call: succeeded.");

    return S_OK;
}


///////////////////////////////////////////////////////////////////////////////
//
// FindAudioStream
// 
// given a call, return the first outgoing audio stream.
//
// returns S_OK if successful, error otherwise
//
///////////////////////////////////////////////////////////////////////////////

HRESULT FindAudioStream( IN  ITBasicCallControl *pCall, 
                         OUT ITStream **ppStream)
{
    
    HRESULT hr = E_FAIL;
    
    LogMessage("FindAudioStream: started");


    //
    // don't return garbage
    //

    *ppStream = NULL;


    //
    // enumerate streams on the call
    //



    //
    // get the ITStreamControl interface for this call
    //

    ITStreamControl *pStreamControl = NULL;

    hr = pCall->QueryInterface(IID_ITStreamControl,
                                (void **) &pStreamControl);

    if (FAILED(hr))
    {
        LogError("FindAudioStream: failed to QI call for ITStreamControl");

        return hr;
    }


    //
    // enumerate the streams
    //

    IEnumStream *pEnumStreams = NULL;
    
    hr = pStreamControl->EnumerateStreams(&pEnumStreams);
    
    pStreamControl->Release();
    pStreamControl = NULL;

    if (FAILED(hr))
    {
        LogError("CreateAndSelectMST: failed to enumerate streams on call");
        
        return hr;
    }

    
    //
    // walk through the streams on the call
    // return the first outgoing audio stream
    //
  
    while (TRUE)
    {
        ITStream *pStream = NULL;

        hr = pEnumStreams->Next(1, &pStream, NULL);

        if (S_OK != hr)
        {
            //
            // no more streams
            //

            break;
        }


        //
        // check the stream's direction
        //

        TERMINAL_DIRECTION td;

        hr = pStream->get_Direction(&td);

        if (FAILED(hr))
        {
            LogError("CreateAndSelectMST: Failed to get stream direction");
            
            pStream->Release();
            pStream = NULL;
            

            //
            // proceed to the next stream, if any
            //

            continue;
        }


        //
        // is the stream of the right direction?
        //

        if (TD_CAPTURE != td)
        {

            //
            // incoming stream. we need outgoing. 
            // release the stream and continue
            // 

            pStream->Release();
            pStream = NULL;

            continue;
        }


        //
        // check the stream's media type
        //

        long lMediaType = 0;

        hr = pStream->get_MediaType(&lMediaType);

        if (FAILED(hr))
        {
            LogError("CreateAndSelectMST: Failed to get media type");

            pStream->Release();
            pStream = NULL;
            
            continue;
        }

        //
        // Does this stream have the right media type?
        // Streams are defined as having exactly one media type
        // (not a bitmask).
        //

        if ( lMediaType == TAPIMEDIATYPE_AUDIO )
        {

            LogMessage("FindAudioStream: stream found");


            //
            // this is what we need, so stop looking
            //

            *ppStream = pStream;

            break;
        }


        pStream->Release();
        pStream = NULL;

    } // while (walking through the call's streams)



    //
    // release stream enumeration
    //

    pEnumStreams->Release();
    pEnumStreams = NULL;


    //
    // return the error code, depending on whether we found a stream or not
    //

    if (NULL == *ppStream)
    {
        LogMessage("FindAudioStream: didn't find an audio stream");

        return E_FAIL;
    }

    LogMessage("FindAudioStream: succeded");

    return S_OK;

}


///////////////////////////////////////////////////////////////////////////////
//
// CreateCaptureMediaStreamingTerminal
//
// create media streaming terminal for outgoing data
//
// returns the created terminal or NULL if failed
//
///////////////////////////////////////////////////////////////////////////////

ITTerminal *CreateCaptureMediaStreamingTerminal(IN ITBasicCallControl *pCall)
{
    
    HRESULT hr = E_FAIL;


    //
    // get the call's call info so we can get the call's address 
    //

    ITCallInfo *pCallInfo = NULL;

    hr = pCall->QueryInterface(IID_ITCallInfo, (void**)&pCallInfo);

    if (FAILED(hr))
    {
        LogError("CreateCaptureMediaStreamingTerminal: "
                 "failed to qi call for ITCallInfo");

        return NULL;
    }


    //
    // now we can get the address
    //

    ITAddress *pAddress = NULL;

    hr = pCallInfo->get_Address(&pAddress);
    
    pCallInfo->Release();
    pCallInfo = NULL;

    if (FAILED(hr))
    {
        LogError("CreateCaptureMediaStreamingTerminal: "
                 "failed to get call's address");
        return NULL;
    }

    
    //
    // get the terminal support interface
    //

    ITTerminalSupport *pTerminalSupport = NULL;

    hr = pAddress->QueryInterface( IID_ITTerminalSupport, 
                                   (void **)&pTerminalSupport );

⌨️ 快捷键说明

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