The function lineInitialize returns the number of available line devices. Next, an application typically needs to enumerate this list of devices to decide which one will be used to make a call. Often, a list of devices will be presented to the user from which one will be selected. This process of enumeration involves the following tasks for each line device:
Negotiating TAPI VersionVersion negotiation is used to ensure that all the parties the application, TAPI, and the service provider DLL agree on the version to use. The TAPI function lineNegotiateAPIVersion is used for this purpose.
The line device is designated by an integer number between 0 and the value dwNumLines 1 returned from lineInitialize. In Listing 11.2a three defines are used to specify the high and low versions that the application can support. The agreed TAPI version number is returned in the variable dwRAPIVersion. Listing 11.2a Negotiating TAPI version#define TAPI_VERSION_1_0 0x00010003 #define TAPI_VERSION_3_0 0x00030000 #define TAPI_CURRENT_VERSION TAPI_VERSION_3_0 DWORD NegotiateTAPIVersion(DWORD dwLineId) { DWORD dwReturn, dwRAPIVersion; if (dwReturn = lineNegotiateAPIVersion ( g_hLineApp, // TAPI registration handle dwLineId, // Line device to be queried TAPI_VERSION_1_0, // Least recent API version TAPI_CURRENT_VERSION, // Most recent API version &dwRAPIVersion, // Negotiated API version NULL)) // Must be NULL { cout _T("Could not negotiate TAPI version") dwLineId endl; return 0; } return dwRAPIVersion; } Getting Line Device CapabilitiesThe TAPI function lineGetDevCaps (Table 11.3) is used to return information about a line device in a LINEDEVCAPS structure. This function needs to be passed a negotiated TAPI version number and the device identifier representing the line device whose capabilities are to be returned. The complexity in calling this function results from the LINEDEVCAPS structure the size of the structure differs from line device to line device. Additional information is appended on to the end of the LINEDEVCAPS structure, the size of which depends on the line device. The LINEDEVCAPS structure member dwNeededSize contains, after a call to lineGetDevCaps, the required size of the LINEDEVCAPS structure. In Listing 11.2b, the negotiated TAPI version is obtained by calling the NegotiateTAPIVersion function from Listing 11.2a. A "do" loop is then executed that first calls lineGetDevCaps with a pointer to a LINEDEVCAPS structure initially created with the size of LINEDEVCAPS defined in TAPI.H. The LINEDEVCAPS structure is then reallocated using the size contained in the dwNeededSize member, and another call to lineGetDevCaps is made. This new structure should then be sufficiently large to return all the line device's capabilities.
Listing 11.2b Getting line device capabilitiesvoid DisplayLineInfo(DWORD dwLineId) { DWORD dwRAPIVersion, dwSize, dwReturn; LPLINEDEVCAPS lpLineDevCaps = NULL; LPTSTR lpszString; // first negotiate TAPI version dwRAPIVersion = NegotiateTAPIVersion(dwLineId); if(dwRAPIVersion == 0) { cout _T("Could not negotiate TAPI version") dwLineId endl; return; } dwSize = sizeof (LINEDEVCAPS); // Allocate enough memory for lpLineDevCaps. do { if (!(lpLineDevCaps = (LPLINEDEVCAPS) LocalAlloc (LPTR, dwSize))) { cout _T("Out of memory") endl; return; } lpLineDevCaps->dwTotalSize = dwSize; if (dwReturn = lineGetDevCaps (g_hLineApp, dwLineId, dwRAPIVersion, 0, lpLineDevCaps)) { cout _T("Could not get Dev Caps") endl; return; } // Stop if the allocated memory is equal to // or greater than the needed memory. if (lpLineDevCaps->dwNeededSize <= lpLineDevCaps->dwTotalSize) break; dwSize = lpLineDevCaps->dwNeededSize; LocalFree (lpLineDevCaps); lpLineDevCaps = NULL; } while (TRUE); lpszString = (LPTSTR)((LPBYTE)lpLineDevCaps + lpLineDevCaps->dwLineNameOffset); // now display information cout _T("Device: ") dwLineId _T(" ") lpszString endl; LocalFree (lpLineDevCaps); } void Listing11_2() { DWORD dwNumLines, dw; if(!(dwNumLines = InitializeTAPI())) return; for(dw = 0; dw < dwNumLines; dw++) DisplayLineInfo(dw); ShutdownTAPI(); } After the "do" loop, Listing 11.2b shows how to extract data at the end of the LINEDEVCAPS structure defined in Tapi.h. The device name is returned as a Unicode string, the offset of which is contained in the dwLineNameOffset member. The following code returns a pointer that uses this offset (as a number of bytes) from the start of the LINEDEVCAPS structure: lpszString = (LPTSTR)((LPBYTE)lpLineDevCaps + lpLineDevCaps->dwLineNameOffset); The LINEDEVCAPS structure contains a large number of members describing the line device's capability. Table 11.4 describes some of the more important members used in Windows CE.
The dwMediaMode parameter is important, as this indicates how data can be transmitted once the call is established. For example, if dwMediaMode includes the flag LINEMEDIAMODE_DATAMODEM, the serial communications functions like ReadFile and WriteFile can be used by an application to receive and send data.
|