April 17, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Exploring Extended TAPI Functions , Page 2

  • May 10, 2005
  • By Alex Gusev, Alex Gusev
  • Send Email »
  • More Articles »

Your application can use some of the above functions to verify radio presence, barring caps and states, system type, and so forth. The following sample code illustrates how to retrieve information about a given line device:

void CExTapiDlg::OnGetGeneralInfo()
{
   LPBYTE pLineGeneralInfoBytes = NULL;
   const DWORD dwMediaMode = LINEMEDIAMODE_DATAMODEM;
   LINEGENERALINFO lviGeneralInfo;
   LPLINEGENERALINFO plviGeneralInfo;
   LPTSTR tsManufacturer, tsModel, tsRevision, tsSerialNumber,
          tsSubscriberNumber;
   CString sInfo;

   lviGeneralInfo.dwTotalSize = sizeof(lviGeneralInfo);

   LONG lRes = ::lineGetGeneralInfo(m_hLine, &lviGeneralInfo);
   if (lRes != 0 && lRes != LINEERR_STRUCTURETOOSMALL)
   {
      TCHAR szMsg[255];
      GetTAPIErrorMsg(szMsg,sizeof(szMsg), lRes);
      AfxMessageBox(szMsg);
      return;
   }

   pLineGeneralInfoBytes = new BYTE[lviGeneralInfo.dwNeededSize];
   plviGeneralInfo = (LPLINEGENERALINFO)pLineGeneralInfoBytes;

   if(pLineGeneralInfoBytes != NULL)
   {
      plviGeneralInfo->dwTotalSize = lviGeneralInfo.dwNeededSize;
      if ( (lRes = ::lineGetGeneralInfo(m_hLine, plviGeneralInfo)) != 0 )
      {
         TCHAR szMsg[255];
         GetTAPIErrorMsg(szMsg,sizeof(szMsg), lRes);
         AfxMessageBox(szMsg);
      }
   else
   {
      TCHAR szUnavailable[] = L"Unavailable";
      if(plviGeneralInfo->dwManufacturerSize)
      {
         tsManufacturer = (WCHAR*)(((BYTE*)plviGeneralInfo)
                          +plviGeneralInfo->dwManufacturerOffset);
      }
      else
      {
         tsManufacturer = szUnavailable;
      }

      if(plviGeneralInfo->dwModelSize)
      {
         tsModel = (WCHAR*)(((BYTE*)plviGeneralInfo)
                   +plviGeneralInfo->dwModelOffset);
      }
      else
      {
         tsModel = szUnavailable;
      }

      if(plviGeneralInfo->dwRevisionSize)
      {
         tsRevision = (WCHAR*)(((BYTE*)plviGeneralInfo)
                      +plviGeneralInfo->dwRevisionOffset);
      }
      else
      {
         tsRevision = szUnavailable;
      }

      if(plviGeneralInfo->dwSerialNumberSize)
      {
         tsSerialNumber = (WCHAR*)(((BYTE*)plviGeneralInfo)
                           +plviGeneralInfo->dwSerialNumberOffset);
      }
      else
      {
         tsSerialNumber = szUnavailable;
      }

      if(plviGeneralInfo->dwSubscriberNumberSize)
      {
         tsSubscriberNumber = (WCHAR*)(((BYTE*)plviGeneralInfo)
            +plviGeneralInfo->dwSubscriberNumberOffset);
      }
      else
      {
         tsSubscriberNumber = szUnavailable;
      }

      sInfo.Format(L"Manufacturer: %s\nModel: %s\nRevision:
                   %s\nSerial No: %s\nSubscriber No: %s\n",
                   tsManufacturer,
                   tsModel,
                   tsRevision,
                   tsSerialNumber,
                   tsSubscriberNumber);
      AfxMessageBox(sInfo);
      }
   }

   delete [] pLineGeneralInfoBytes;
}

The companion project contains more examples of this group of functions; here, I'll drop the simplest one:

void CExTapiDlg::OnGetEquipmentState()
{
   TCHAR *szEqStates[] =
   {
      L"LINEEQUIPSTATE_MINIMUM",
      L"LINEEQUIPSTATE_RXONLY",
      L"LINEEQUIPSTATE_TXONLY",
      L"LINEEQUIPSTATE_NOTXRX",
      L"LINEEQUIPSTATE_FULL"
   };
   TCHAR *szRadioSupport[] =
   {
      L"LINERADIOSUPPORT_OFF",
      L"LINERADIOSUPPORT_ON",
      L"LINERADIOSUPPORT_UNKNOWN"
   };

   DWORD dwState = 0;
   DWORD dwRadioSupport = 0;
   LONG lRet = lineGetEquipmentState(m_hLine,&dwState,&dwRadioSupport);
   if ( lRet == 0 )
   {
      CString sInfo;
      sInfo.Format(L"State = %s, Radio = %s",
         szEqStates[dwState - 1],
         szRadioSupport[dwRadioSupport-1]);
      AfxMessageBox(sInfo);
   }
   else
   {
      TCHAR szMsg[255];
      GetTAPIErrorMsg(szMsg,sizeof(szMsg), lRet);
      AfxMessageBox(szMsg);
   }
}

Network operator related functions

ExTAPI exposes several functions that you can use to manage network operator-related stuff:

  • lineRegister
  • lineUnregister
  • lineGetRegisterStatus
  • lineGetCurrentOperator
  • lineGetOperatorStatus
  • lineSetPreferredOperator

If your application requires you to deal with these kinds of operations, these functions will help you to handle it. The tiny sample below queries all available network operators:

void CExTapiDlg::OnGetAvailOps()
{
   LINEOPERATORSTATUS lops;

   lops.dwTotalSize = sizeof(LINEOPERATORSTATUS);

   BeginWaitCursor();
   LONG lRes = ::lineGetOperatorStatus(m_hLine, &lops);
   if (lRes != 0 && lRes != LINEERR_STRUCTURETOOSMALL)
   {
      EndWaitCursor();

      TCHAR szMsg[255];
      GetTAPIErrorMsg(szMsg,sizeof(szMsg), lRes);
      AfxMessageBox(szMsg);
      return;
   }


   CString sInfo(L"Available Operators:\r\n");
   LPBYTE pLineOperatorStatusBytes = new BYTE[lops.dwNeededSize];
   LPLINEOPERATORSTATUS pStatus =
      (LPLINEOPERATORSTATUS)pLineOperatorStatusBytes;

   if(pLineOperatorStatusBytes != NULL)
   {
      pStatus->dwTotalSize = lops.dwNeededSize;
      if ( (lRes = ::lineGetOperatorStatus(m_hLine, pStatus)) != 0 )
      {
         TCHAR szMsg[255];
         GetTAPIErrorMsg(szMsg,sizeof(szMsg), lRes);
         AfxMessageBox(szMsg);
      }
      else
      {
         LPLINEOPERATOR pOperator = (LPLINEOPERATOR)((LPBYTE)pStatus+
                                    (pStatus->dwAvailableOffset));
         for(DWORD dwOperatorNumber = 0;dwOperatorNumber < pStatus->
                                      dwAvailableCount;
                                      dwOperatorNumber++)
         {
            sInfo += pOperator->lpszLongName;
            sInfo += L"\r\n";
            pOperator++;
         }
      }
   }

   delete[] pLineOperatorStatusBytes;
   EndWaitCursor();

   AfxMessageBox(sInfo);
}

If you run this sample, you will see that it takes some time to obtain the required information. Except for this, the code is quite common for TAPI:

  1. get required data buffer size
  2. allocate enough memory
  3. call the same function again
  4. iterate through returned data
  5. cleanup all allocated memory

Usually, you will store the original network operator, set up your own, and finally restore the previous settings. ExTAPI serves you just fine here.

Conclusion

In this acticle, you have observed Extended TAPI operations. They can or cannot be required in your applications, but anyway it's better to know your enemy before it beats you. You will continue investigating TAPI in next articles, because it is utterly not ended yet. Possible areas of intrest are managing calls, setting up conferences, and so forth. If all goes well, you will learn about these topics in the coming articles. Enjoy!

Download

Download the accompanying code's zip file here.

About the Author

Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel