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

📄 mstapi3.cpp

📁 jtapi for telephone
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
	Copyright (c) 2005 Serban Iordache 
	
	All rights reserved. 
	
	Permission is hereby granted, free of charge, to any person obtaining a 
	copy of this software and associated documentation files (the 
	"Software"), to deal in the Software without restriction, including 
	without limitation the rights to use, copy, modify, merge, publish, 
	distribute, and/or sell copies of the Software, and to permit persons 
	to whom the Software is furnished to do so, provided that the above 
	copyright notice(s) and this permission notice appear in all copies of 
	the Software and that both the above copyright notice(s) and this 
	permission notice appear in supporting documentation. 
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 
	OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
	HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 
	INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 
	FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
	NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
	WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
	
	Except as contained in this notice, the name of a copyright holder 
	shall not be used in advertising or otherwise to promote the sale, use 
	or other dealings in this Software without prior written authorization 
	of the copyright holder.
*/
#include "stdafx.h"
#include "MSTapi3.h"
#include "TAPI3EventNotification.h"
#include "Util.h"

// constructor
MSTapi3::MSTapi3() : tapi(NULL), tapi3EventNotification(NULL), currCallID(0), isDown(false) {
	logger = new Logger("MSTapi3");
	swapOnHold = false;
}

// destructor
MSTapi3::~MSTapi3() {
	logger->debug("MSTapi3 dtor.");
	ShutdownTapi();
	logger->debug("Deleting logger...");
	delete logger;
	logger = NULL;
	logger->debug("Logger deleted.");
}

list<wstring> MSTapi3::getAddressNames() {
	list<wstring> addressNames;
	for (AddressMap::iterator it = addresses.begin(); it != addresses.end(); ++it) {
		addressNames.push_back((*it).first);
	}
	return addressNames;
}

//////////////////////////////////////////////////////////////
// InitializeTapi
//
// Various tapi initializations
///////////////////////////////////////////////////////////////
HRESULT MSTapi3::InitializeTapi(CallbackNotification aCallback) {
    // cocreate the TAPI object
	logger->debug("InitializeTapi() called.");
    HRESULT hr = CoCreateInstance(
                          CLSID_TAPI,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ITTAPI,
                          (LPVOID *)&tapi
                         );
    if (FAILED(hr)) {
        logger->error("CoCreateInstance on TAPI failed: hr=%08X", hr);
        return hr;
    }
	logger->debug("CoCreateInstance on TAPI succeeded.");

	callback = aCallback;
    // call initialize.  this must be called before
    // any other tapi functions are called.
    hr = tapi->Initialize();

    if (FAILED(hr)) {
        logger->error("TAPI failed to initialize");

        tapi->Release();
        tapi = NULL;        
        return hr;
    }
	logger->debug("tapi->Initialize() succeeded.");

    //
    // Create our own event notification object and register it
    //
    tapi3EventNotification = new TAPI3EventNotification(this, callback);
	logger->debug("tapi3EventNotification created.");
    
    hr = RegisterTapiEventInterface();
    if (FAILED(hr)) {
        logger->error("RegisterTapiEventInterface() failed.");
        tapi->Release();
        tapi = NULL;        
        return hr;
    }
	logger->debug("RegisterTapiEventInterface() succeeded.");

    // Set the Event filter to only give us the events we process
    tapi->put_EventFilter(TE_ADDRESS | TE_CALLNOTIFICATION | TE_CALLSTATE | TE_CALLMEDIA | TE_CALLHUB | TE_CALLINFOCHANGE);
//    tapi->put_EventFilter(0x2FFFFFF);

    // find all address objects that we will use to listen for calls on
	logger->debug("Calling ListenOnAddresses...");
    hr = ListenOnAddresses();
    if (FAILED(hr)) {
        logger->error("Could not find any addresses to listen on");
        tapi->Release();
        tapi = NULL;
        return hr;
    }
	logger->debug("ListenOnAddresses() succeeded.");
    return S_OK;
}


///////////////////////////////////////////////////////////////
// ShutdownTapi
///////////////////////////////////////////////////////////////
void MSTapi3::ShutdownTapi() {
	if(isDown) {
		logger->warn("TAPI already shut down");
		return;
	}
	isDown = true;
	ReleaseAddresses();
	UnregisterCallNotifications();
	HRESULT hr = UnregisterTapiEventInterface();
	if(FAILED(hr)) {
		logger->error("UnregisterTapiEventInterface() failed: hr=%08X", hr);
	} else {
		logger->debug("UnregisterTapiEventInterface() succeeded");
	}

    // release main object.
    if (NULL != tapi) {
		logger->debug("Shutting down tapi object...");
		try {
			HRESULT hr = tapi->Shutdown();
		} catch(...) {
			logger->error("tapi->Shutdown() failed.");
		}
		logger->debug("Releasing tapi object...");
        tapi->Release();
		tapi = NULL;
		logger->debug("Tapi object shut down and released.");
    } else {
		logger->info("tapi object already NULL.");
	}

}



/////////////////////////////////////////////////////////////////
// MakeTheCall
//
// Sets up and makes a call
/////////////////////////////////////////////////////////////////
HRESULT MSTapi3::MakeTheCall(int callID, wstring& address, wstring& destination) {
	ITAddress* pITAddress = getITAddress(address);
	if(pITAddress == NULL) {
		logger->error("Address not found: %S", address.c_str());
		return -1;
	}

    // find out which media types this address supports
    long lMediaTypes = 0;
    if ( AddressSupportsMediaType(pITAddress, TAPIMEDIATYPE_AUDIO) ) {
        lMediaTypes |= TAPIMEDIATYPE_AUDIO; // we will use audio
    }

    if ( AddressSupportsMediaType(pITAddress, TAPIMEDIATYPE_VIDEO) ) {
        lMediaTypes |= TAPIMEDIATYPE_VIDEO; // we will use video
    }

	logger->debug("MakeTheCall(%d, %S, %S)", callID, address.c_str(), destination.c_str());

	ITBasicCallControl* pCallControl = getCallControl(callID);
	if(pCallControl != NULL) {
		logger->warn("Call not null. Releasing old call...");
		removeCallControl(callID);
	} else {
		logger->debug("Ok: empty entry found for callID=%d.", callID);
	}

    // Create the call.
    HRESULT hr = pITAddress->CreateCall(const_cast<unsigned short*>(destination.c_str()),
                                LINEADDRESSTYPE_PHONENUMBER, lMediaTypes, &pCallControl);
    if (FAILED(hr)) {
        logger->error("Could not create a call to %S on %S.", destination, address);
        return hr;
    }
	calls[callID] = pCallControl;
	logger->debug("Call successfully created.");

    // Select our terminals on the call; if any of the selections fail, we proceed without that terminal.
    hr = SelectTerminalsOnCall(pITAddress, pCallControl);
	if(FAILED(hr)) {
		logger->warn("SelectTerminalsOnCall() failed: hr=%08X. Trying to make the call without a terminal.", hr);
	}

    ITCallInfo* pCallInfo;
	hr = pCallControl->QueryInterface( IID_ITCallInfo, (void**)&pCallInfo );
    if(FAILED(hr)) {
		logger->error("Getting callInfo failed. hr=%08X. Cannot set CIS_CALLEDIDNUMBER", hr);
    } else {
		BSTR bstrDestination = SysAllocString(destination.c_str());
		hr = pCallInfo->put_CallInfoString(CIS_CALLEDIDNUMBER, bstrDestination);
		if(FAILED(hr)) {
			logger->error("Cannot set CIS_CALLEDIDNUMBER. hr=%08X", hr);
		}
		pCallInfo->Release();
		SysFreeString(bstrDestination);
	}


    // We're now ready to call connect.
    //
    // the VARIANT_TRUE parameter indicates that this call is sychronous - that is, it won't
    // return until the call is in the connected state (or fails to connect).
    hr = pCallControl->Connect(VARIANT_TRUE);

    if (FAILED(hr)) {
		removeCallControl(callID);
        logger->error("Could not connect the call to %S on %S.", destination.c_str(), address.c_str());
        return hr;
    } else {
		logger->info("Successfully connected to %S on %S.", destination.c_str(), address.c_str());
	}
    return S_OK;
}

/////////////////////////////////////////////////////////////////////
// Dial a number on the call
// This allows extra digits, such as long distance authorization codes, to
// be dialed on a call.
/////////////////////////////////////////////////////////////////////
HRESULT MSTapi3::Dial(int callID, wstring& destination) {
	logger->debug("Dial(%d, %S)", callID, destination.c_str());

  // get a handle on the call control
	ITBasicCallControl* pCallControl = getCallControl(callID);
	if(pCallControl == NULL) {
    logger->warn("Error: Call is null.");
		return S_FALSE;
	} else {
		logger->debug("Ok: empty entry found for callID=%d.", callID);
	}

  // Now dial the digits on the call
  HRESULT hr = pCallControl->Dial(const_cast<unsigned short*>(destination.c_str()));

  // test for success. Don't remove callcontrol on failure -- we didn't create it.
  if (FAILED(hr)) {
    logger->error("Could not dial the call to %S.", destination.c_str());
    return hr;
  } else {
	  logger->info("Successfully dialed to %S.", destination.c_str());
	}

  return S_OK;
}

/////////////////////////////////////////////////////////////////////
// Answer the call
/////////////////////////////////////////////////////////////////////
HRESULT MSTapi3::AnswerTheCall(int callID) {
	logger->debug("Answering callID=%d...", callID);
	ITBasicCallControl* callControl = getCallControl(callID);
    if (NULL == callControl) {
		logger->error("Cannot answer. CallID %d not found", callID);
        return E_UNEXPECTED;
    }

    // get the address object of this call
    ITCallInfo* pCallInfo;
	HRESULT hr = callControl->QueryInterface( IID_ITCallInfo, (void**)&pCallInfo );
    if(FAILED(hr)) {
		logger->error("Getting callInfo failed. hr=%08X", hr);
		removeCallControl(callID);
        return hr;
    }

    ITAddress* pAddress;
    hr = pCallInfo->get_Address( &pAddress );
    pCallInfo->Release();
    if (FAILED(hr)) {
		removeCallControl(callID);
		logger->error("get_Address() failed. hr=%08X", hr);
        return hr;
    }
	BSTR bstrAddrName;
	hr = pAddress->get_AddressName(&bstrAddrName);
	if(FAILED(hr)) {
		logger->error("get_AddressName() failed: hr=%08X", hr);
		pAddress->Release();
		return hr;
	}
	wstring strAddress = bstrAddrName;
	SysFreeString(bstrAddrName);

    // Select our terminals on the call; if any of the selections fail, we proceed without that terminal
    hr = SelectTerminalsOnCall(pAddress, callControl);
    pAddress->Release();
    if(FAILED(hr)) {
		logger->error("SelectTerminalsOnCall() failed. hr=%08X. Answering without a terminal.", hr);
    }

    // Now we can actually answer the call
    hr = callControl->Answer();
    if(FAILED(hr)) {
		logger->error("Answer() failed. hr=%08X", hr);
    } else {
		logger->debug("Answer() successfully done.");

		callback(net_sourceforge_gjtapi_raw_tapi3_Tapi3Provider_METHOD_TERMINAL_CONNECTION_TALKING, callID, strAddress, 
				net_sourceforge_gjtapi_raw_tapi3_Tapi3Provider_JNI_CAUSE_NORMAL, NULL);
	}
    return hr;
}

//////////////////////////////////////////////////////////////////////
// HoldTheCall
//
// Holds the call
//////////////////////////////////////////////////////////////////////
HRESULT MSTapi3::HoldTheCall(int callID) {
	logger->debug("Holding callID=%d...", callID);
	ITBasicCallControl* callControl = getCallControl(callID);
    if (NULL != callControl) {
		bool swapIt = swapOnHold;
		HRESULT hr;

		if(!swapIt) {
			hr = callControl->Hold(VARIANT_TRUE);

⌨️ 快捷键说明

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