Table Of Contents
Cisco Unified TAPI Examples
This chapter provides examples that illustrate how to use the Cisco Unified TAPI implementation. This chapter includes the following subroutines:
MakeCall
STDMETHODIMP CTACtrl::MakeCall(BSTR destNumber, long pMakeCallReqID, long hLine, BSTR user2user, long translateAddr) {AFX_MANAGE_STATE(AfxGetStaticModuleState())USES_CONVERSION;tracer->tracef(SDI_LEVEL_ENTRY_EXIT, "CTACtrl::Makecall %s %d %d %s %d\n",T2A((LPTSTR)destNumber), pMakeCallReqID, hLine, T2A((LPTSTR)user2user),translateAddr);//CtPhoneNo m_pno;CtTranslateOutput to;//LPCSTR pszTranslatable;CString sDialable;CString theDestNumber(destNumber);CtCall* pCall;CtLine* pLine=CtLine::FromHandle((HLINE)hLine);if (pLine==NULL) {tracer->tracef(SDI_LEVEL_ERROR, "CTACtrl::MakeCall : pLine == NULL\n");return S_FALSE;} else {pCall=new CtCall(pLine);pCall->AddSink(this);sDialable = theDestNumber;if (translateAddr) {//m_pno.SetWholePhoneNo((LPCSTR)theDestNumber);//pszTranslatable = m_pno.GetTranslatable();if (TSUCCEEDED(to.TranslateAddress(pCall->GetLine()->GetDeviceID(),(LPCSTR)theDestNumber)) ) {sDialable = to.GetDialableString();}}TRESULT tr = pCall->MakeCall((LPCSTR)sDialable, 0, this);if( TPENDING(tr) || TSUCCEEDED(tr)) {//GCGC the correct hCall pointer is not being returned yetif (translateAddr)Fire_MakecallReply(hLine, (long)tr, (long)pCall->GetHandle(),sDialable.AllocSysString());elseFire_MakecallReply(hLine, (long)tr, (long)pCall->GetHandle(),destNumber);return S_OK;} else {//GCGC delete the call that was created above.tracer->tracef(SDI_LEVEL_ERROR, "CTACtrl::MakeCall : pCall->MakeCall failed\n");delete pCall;return S_FALSE;}}}OpenLine
STDMETHODIMP CTACtrl::OpenLine(long lDeviceID, BSTR lineDirNumber, long lPriviledges,long lMediaModes, BSTR receiveIPAddress, long lreceivePort) {USES_CONVERSION;tracer->tracef(SDI_LEVEL_ENTRY_EXIT, "CTACtrl::OpenLine %d %s %d %d %s %d\n",lDeviceID, T2A((LPTSTR)lineDirNumber), lPriviledges, lMediaModes,T2A((LPTSTR)receiveIPAddress), lreceivePort);int lineID;TRESULT tr;CString strReceiveIP(receiveIPAddress);CString strReqAddress(lineDirNumber);//bool bTermMedia=((!strReceiveIP.IsEmpty()) && (lreceivePort!=0));bool bTermMedia=(((lMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE) != 0) &&(lreceivePort!=0) && (!strReceiveIP.IsEmpty()));CtLine* pLine;AFX_MANAGE_STATE(AfxGetStaticModuleState())tracer->tracef(SDI_LEVEL_DETAILED, "TAC: --> OpenLine()\n");if ((lDeviceID<0) && !strcmp((char *)lineDirNumber, "")) {tracer->tracef(SDI_LEVEL_ERROR, "TCD: error - bad device ID and no dirn to open\n");return S_FALSE;}lineID=lDeviceID;if (lDeviceID<0) {//search for line ID in list of lines.CtLineDevCaps ldc;int numLines=::TfxGetNumLines();for( DWORD nLineID = 0; (int)nLineID < numLines; nLineID++ ) {if( /*ShouldShowLine(nLineID) &&*/ TSUCCEEDED(ldc.GetDevCaps(nLineID)) ) {CtAddressCaps ac;tracer->tracef(SDI_LEVEL_DETAILED, "CTACtrl::OpenLine :Calling ac.GetAddressCaps %d 0\n", nLineID);if ( TSUCCEEDED(ac.GetAddressCaps(nLineID, 0)) ) {// GCGC only one address supportedCString strCurrAddress(ac.GetAddress());if (strReqAddress==strCurrAddress) {lineID=nLineID;break;}}} else {tracer->tracef(SDI_LEVEL_ERROR, "TAC: error - GetAddressCaps() failed\n");}}}if (lDeviceID<0) {tracer->tracef(SDI_LEVEL_ERROR,"TAC: error - could not find dirn %s to open line.\n",(LPCSTR)lineDirNumber);return S_FALSE;}// if we are to do media termination; negotiate the extensions versionDWORD retExtVersion;if (bTermMedia) {TRESULT tr3;tracer->tracef(SDI_LEVEL_DETAILED,"TAC: lineNegotiateExtVersion - appHandle = %d, deviceID = %d, API ver = %d,HiVer = %d, LoVer = %d\n", CtLine::GetAppHandle(), lineID,CtLine::GetApiVersion(lineID),0x80000000 | 0x00010000L,0x80000000 | 0x00020000L );tr3=::lineNegotiateExtVersion(CtLine::GetAppHandle(),lineID, CtLine::GetApiVersion(lineID),0x80000000 | 0x00010000L, // TAPI v1.3,0x80000000 | 0x00020000L,&retExtVersion);tracer->tracef(SDI_LEVEL_DETAILED,"TAC: lineNegotiateExtVersion returned: %d\n", tr3);}pLine=new CtLine();tr=pLine->Open(lineID, this, lPriviledges, lMediaModes);if( TSUCCEEDED(tr)) {if (bTermMedia) {if (retExtVersion==0x10000) {CiscoLineDevSpecificUserControlRTPStream dsucr;dsucr.m_RecievePort=lreceivePort;dsucr.m_RecieveIP=::inet_addr((LPCSTR)strReceiveIP);TRESULT tr2;tr2=::lineDevSpecific(pLine->GetHandle(),0,0, dsucr.lpParams(),dsucr.dwSize());tracer->tracef(SDI_LEVEL_DETAILED,"TAC: lineDevSpecific returned: %d\n", tr2);} else {//GCGC here put in the new calls to set the media types!CiscoLineDevSpecificUserControlRTPStream2 dsucr;dsucr.m_RecievePort=lreceivePort;dsucr.m_RecieveIP=::inet_addr((LPCSTR)strReceiveIP);dsucr.m_MediaCapCount=4;dsucr.m_MediaCaps[0].MediaPayload=4;dsucr.m_MediaCaps[0].MaxFramesPerPacket=30;dsucr.m_MediaCaps[0].G723BitRate=0;dsucr.m_MediaCaps[1].MediaPayload=9;dsucr.m_MediaCaps[1].MaxFramesPerPacket=90;dsucr.m_MediaCaps[1].G723BitRate=1;dsucr.m_MediaCaps[2].MediaPayload=9;dsucr.m_MediaCaps[2].MaxFramesPerPacket=90;dsucr.m_MediaCaps[2].G723BitRate=2;dsucr.m_MediaCaps[3].MediaPayload=11;dsucr.m_MediaCaps[3].MaxFramesPerPacket=90;dsucr.m_MediaCaps[3].G723BitRate=0;TRESULT tr2;tr2=::lineDevSpecific(pLine->GetHandle(),0,0, dsucr.lpParams(),dsucr.dwSize());tracer->tracef(SDI_LEVEL_DETAILED,"TAC: lineDevSpecific returned: %d\n", tr2);}}CtAddressCaps ac;LPCSTR pszAddressName;if ( TSUCCEEDED(ac.GetAddressCaps(lineID, 0)) ) {// GCGC only one address supportedpszAddressName = ac.GetAddress();} else {pszAddressName = NULL;tracer->tracef(SDI_LEVEL_ERROR, "TAC: error - GetAddressCaps() failed.\n");}OpenedLine((long)pLine->GetHandle(), pszAddressName, 0);// now let's try to open the associated phone device// Get the phone from the lineDWORD nPhoneID;bool b_phoneFound=false;CtDeviceID did;if((m_bUsesPhones) && TSUCCEEDED(did.GetID("tapi/phone", pLine->GetHandle())) ) {nPhoneID = did.GetDeviceID();tracer->tracef(SDI_LEVEL_DETAILED,"TAC: Retrieved phone device %d for line.\n",nPhoneID);// check to see if phone device is already openlong hPhone;CtPhone* pPhone;if (!m_deviceID2phone.Lookup((long)nPhoneID,hPhone)) {tracer->tracef(SDI_LEVEL_SIGNIFICANT,"TAC: phone device not found in open list, opening it...\n");pPhone=new CtPhone();TRESULT tr_phone;tr_phone=pPhone->Open(nPhoneID,this);if (TSUCCEEDED(tr_phone)) {::phoneSetStatusMessages(pPhone->GetHandle(),PHONESTATE_DISPLAY | PHONESTATE_LAMP |PHONESTATE_HANDSETHOOKSWITCH | PHONESTATE_HEADSETHOOKSWITCH |PHONESTATE_REINIT | PHONESTATE_CAPSCHANGE | PHONESTATE_REMOVED,PHONEBUTTONMODE_KEYPAD | PHONEBUTTONMODE_FEATURE |PHONEBUTTONMODE_CALL |PHONEBUTTONMODE_LOCAL | PHONEBUTTONMODE_DISPLAY,PHONEBUTTONSTATE_UP | PHONEBUTTONSTATE_DOWN);m_phone2line.SetAt((long)pPhone->GetHandle(), (long)pLine->GetHandle());m_line2phone.SetAt((long)pLine->GetHandle(),(long)pPhone->GetHandle());m_deviceID2phone.SetAt((long)nPhoneID,(long)pPhone->GetHandle());m_phoneUseCount.SetAt((long)pPhone->GetHandle(), 1);} else {tracer->tracef(SDI_LEVEL_ERROR,"TAC: error - phoneOpen failed with code %d\n", tr_phone);}} else {pPhone=CtPhone::FromHandle((HPHONE)hPhone);long theCount;if (m_phoneUseCount.Lookup((long)pPhone->GetHandle(),theCount))m_phoneUseCount.SetAt((long)pPhone->GetHandle(), theCount+1);else {//GCGC this would be an error condition!tracer->tracef(SDI_LEVEL_ERROR,"TAC: error - m_phoneUseCount does not contain phone entry.\n");}}} else {tracer->tracef(SDI_LEVEL_ERROR,"TAC: error - could not retrieve PhoneID for line.\n");}tracer->tracef(SDI_LEVEL_DETAILED, "TAC: <-- OpenLine()\n");return S_OK;} else {tracer->tracef(SDI_LEVEL_ERROR, "TAC: error - lineOpen failed: %d\n", tr);tracer->tracef(SDI_LEVEL_DETAILED, "TAC: <-- OpenLine()\n");OpenLineFailed(tr,0);delete pLine;return S_FALSE;}}CloseLine
STDMETHODIMP CTACtrl::CloseLine(long hLine) {AFX_MANAGE_STATE(AfxGetStaticModuleState())tracer->tracef(SDI_LEVEL_ENTRY_EXIT, "CTACtrl::CloseLine %d\n", hLine);CtLine* pLine;pLine=CtLine::FromHandle((HLINE) hLine);if (pLine!=NULL) {// close the linepLine->Close();// remove it from the listdelete pLine;long hPhone;long theCount;if ((m_bUsesPhones) && (m_line2phone.Lookup(hLine,hPhone))) {CtPhone* pPhone=CtPhone::FromHandle((HPHONE)hPhone);if (pPhone!=NULL) {if (m_phoneUseCount.Lookup(hPhone,theCount))if (theCount>1) {// decrease the number of lines using this phonem_phoneUseCount.SetAt(hPhone,theCount-1);}else {//nobody else is using this phone, so let's remove it.m_deviceID2phone.RemoveKey((long)pPhone->GetDeviceID());m_phone2line.RemoveKey(hPhone);m_phoneUseCount.RemoveKey(hPhone);//now let's close the phonepPhone->Close();}}//either way, remove the map entry from line to phone.m_line2phone.RemoveKey(hLine);}return S_OK;}elsereturn S_FALSE;}