(原文链接: http://blog.csdn.net/lujunql/archive/2009/07/21/4367770.aspx)
前一段时间一直做Windows mobile下的程序,其中软件有一部分功能涉及到来电的监听,涉及到TAPI功能,网上介绍TAPI的文章很多,我就不在多写了,只是简单的对所做过的工作和遇到的问题与处理方式介绍一下,以供参考。
Windows mobile下使用的是TAPI2.0的功能,还有部分功能是TAPI2.1的。TAPI中分为两类不同的功能函数,TAPI线路设备功能函数(TAPI Line Device Functions) 和TAPI电话功能函数(TAPI Phone Device Functions) ,我主要使用的是TAPI线路设备功能函数(TAPI Line Device Functions)。
1,lineInitialize函数如何使用。
l定义:
LONG lineInitialize( LPHLINEAPP lphLineApp, HINSTANCE hInstance, LINECALLBACK lpfnCallback, LPCWSTR lpszAppName, LPDWORD lpdwNumDevs );
参数:
- lphLineApp
- 输出参数,返回当前应用程序要使用的TAPI句柄,在lineOpen会用到。
- hInstance
- 输入参数,应用程序或DLL得实例句柄。
- lpfnCallback
- 输入参数,处理TAPI线路功能消息的回调函数,在SDK中有该回调函数的具体定义样式(lineCallbackFunc)。
- lpszAppName
- 输入参数,应用程序的名称,字符串,不能为空。
- lpdwNumDevs
- 输出参数,返回设备中线路设备的数目,这个参数是枚举设备信息判断设备所具有的能力时的关键。
- 返回:
- 该函数返回为(LINEERR_REINIT)0时表示线路初始成功,其他值有相应的不成功的定义。
- 使用:
- (Windows mobile SDK中所带例子中的源码)
- HINSTANCE g_hInst = NULL; // hInstance of the application
- TCHAR g_szAppName[] = TEXT("Hello");
- DWORD g_dwNumDevs = 0;
- HLINEAPP g_hLineApp = NULL;
- DWORD dwReturn;
- DWORD dwTimeCount = GetTickCount ();
- // Initialize the application's use of Tapi.dll. Keep trying until the
- // user cancels or stops getting LINEERR_REINIT.
- while ( (dwReturn = lineInitialize(&g_hLineApp,
- g_hInst,
- (LINECALLBACK)lineCallbackFunc,
- g_szAppName,
- &g_dwNumDevs))==LINEERR_REINIT)
- {
- // Bring up the message box if 5 seconds have passed.
- if (GetTickCount () > 5000 + dwTimeCount)
- {
- // Reset the time counter.
- dwTimeCount = GetTickCount ();
- }
- }
- // If function "lineInitialize" fails, then return.
- if (dwReturn)
- return false;
2,lineOpen函数的参数应该如何设置。
定义:
LONG lineOpen( HLINEAPP hLineApp, DWORD dwDeviceID, LPHLINE lphLine, DWORD dwAPIVersion, DWORD dwExtVersion, DWORD dwCallbackInstance, DWORD dwPrivileges, DWORD dwMediaModes, LPLINECALLPARAMS const lpCallParams );
参数:
- hLineApp
- 输入参数,句柄,来源于lineInitialize函数返回的lphLineApp 参数。
- dwDeviceID
- 输入参数,将要被打开有效线路设备的标示。在使用lineOpen前需要枚举判断线路设备的能力时得到。
lphLine
输出参数,返回被打开线路设备的句柄,在以后其他线路函数中要用到的。
- dwAPIVersion
- 输入参数,TAPI的版本号。
dwExtVersion
输入参数,为0。
dwCallbackInstance
输入参数,为0
- dwPrivileges
输入参数,呼叫权限。在联合 LINECALLPRIVILEGE中定义了几种不同的权限.
Value Description LINECALLPRIVILEGE_NONE
The application can make only outgoing calls.
LINECALLPRIVILEGE_MONITOR
The application can monitor only incoming and outgoing calls.
LINECALLPRIVILEGE_OWNER
The application can own only incoming calls of the types specified in dwMediaModes.
LINECALLPRIVILEGE_MONITOR + LINECALLPRIVILEGE_OWNER
The application can own only incoming calls of the types specified in dwMediaModes, but if it is not an owner of a call, it is a monitor.
LINECALLPRIVILEGE_NONE
只能拨出
LINECALLPRIVILEGE_MONITOR
只能监视呼入和拨出
LINECALLPRIVILEGE_OWNER
能控制指定的媒体类型(比如语音)呼入
LINECALLPRIVILEGE_MONITOR + LINECALLPRIVILEGE_OWNER
能控制指定的媒体类型(比如语音)呼入,但不是拨出的控制者,只是监视者
- dwMediaModes
- 输入参数,设备的媒体模式,在联合 LINEMEDIAMODE中定义了
Value Description LINEMEDIAMODE_AUTOMATEDVOICE = 0x00000008
Voice energy was detected on the call, and the voice is locally handled by an automated application such as with an answering machine application. When a service provider cannot distinguish between interactive and automated voice on an incoming call, it will report the call as interactive voice.
LINEMEDIAMODE_DATAMODEM = 0x00000010
A data modem session on the call. Current modem protocols require the called station to initiate the handshake. For an incoming data modem call, the application can typically make no positive detection. How the service provider makes this determination is its choice. For example, a period of silence just after answering an incoming call can be used as a heuristic to decide that this might be a data modem call.
LINEMEDIAMODE_ADSI = 0x00002000
An Analog Display Services Interface (ADSI) session on the call. ADSI enhances voice calls with alphanumeric information downloaded to the phone and the use of soft buttons on the phone.
LINEMEDIAMODE_DIGITALDATA = 0x00000100
A digital data stream of unspecified format.
LINEMEDIAMODE_G3FAX = 0x00000020
A group 3 fax is being sent or received over the call.
LINEMEDIAMODE_G4FAX = 0x00000080
A group 4 fax is being sent or received over the call.
LINEMEDIAMODE_INTERACTIVEVOICE = 0x00000004
Voice energy was detected on the call, and the call is handled as an interactive voice call with humans on both ends.
LINEMEDIAMODE_MIXED = 0x00001000
A mixed session on the call. Mixed is one of the ISDN telematic services.
LINEMEDIAMODE_TDD = 0x00000040
A Telephony Devices for the Deaf (TDD) () session on the call.
LINEMEDIAMODE_TELETEX = 0x00000200
A teletex session on the call. Teletex is one of the telematic services.
LINEMEDIAMODE_TELEX = 0x00000800
A telex session on the call. Telex is one of the telematic services.
LINEMEDIAMODE_VIDEOTEX = 0x00000400
A videotex session on the call. Videotex is one the telematic services.
LINEMEDIAMODE_VOICEVIEW = 0x00004000
The media type of the call is VoiceView. TAPI versions 1.4 and later.
LINEMEDIAMODE_UNKNOWN = 0x00000002
A media stream exists but its mode is not currently known and may become known later. This would correspond to a call with an unclassified media type. In typical analog telephony environments, an incoming call's media type may be unknown until after the call has been answered and the media stream has been filtered to make a determination.
If the unknown media-mode flag is set, other media flags can also be set. This is used to signify that the media is unknown but that it is likely to be one of the other selected media types.
- 该参数所定义的媒体模式是的设备的能力有关的,使用不正确,就会出现程序在接收到呼叫无响应的情况。我在最开始使用该参数时将其设置为LINEMEDIAMODE_DATAMODEM的就出现在检测到LINECALLSTATE_OFFERING消息后使用LONG re=lineAnswer((HCALL)hDevice ,NULL,0)进行应答,但lineAnswer调用完成后的返回值re是0x80000018(LINEERR_INVALCALLHANDLE)句柄不正确,后来将其改为LINEMEDIAMODE_INTERACTIVEVOICE 就正确了。所以要特别注意。
- lpCallParams
- 输入参数,为NULL。、
- 返回:
- 该函数返回为0时表示线路打开成功,其他值有相应的不成功的定义。
lineOpen函数的使用主要就是输入参数dwDeviceID ,dwPrivileges, dwMediaModes 的设置。针对不同设备能力的设备其设置是不同的,所以需要认真的分析实验。