Как отследить момент звонка?
От: Krevio  
Дата: 07.06.08 09:51
Оценка:
Как из своего приложения отследить момент исходящего/входящего вызовов, чтоб не пытаться в это время чтото делать через gprs?
Через TAPI lineOpen и смотреть потом какието статусы (какие?) или в винде какие то сообщения ловить? Или неправильно рассуждаю?
Re: Как отследить момент звонка?
От: GGoga  
Дата: 08.06.08 13:25
Оценка: 31 (2)
Здравствуйте, Krevio, Вы писали:

K>Как из своего приложения отследить момент исходящего/входящего вызовов, чтоб не пытаться в это время чтото делать через gprs?

K>Через TAPI lineOpen и смотреть потом какието статусы (какие?) или в винде какие то сообщения ловить? Или неправильно рассуждаю?

Для этого нужно юзать или TAPI, или RIL. Я бы посоветовал именно TAPI.
Я делал так:

1. Объявляем необходимые переменные:
typedef struct tagLINEINFO
{
    HLINE hLine; // Line handle returned by lineOpen
    BOOL bVoiceLine; // Indicates if the line is a voice // line
    DWORD dwAPIVersion; // API version that the line supports
    DWORD dwNumOfAddress; // Number of available addresses on // the line
    DWORD dwPermanentLineID; // Permanent line identifier
    TCHAR szLineName[256]; // Name of the line

} LINEINFO, *LPLINEINFO;

class CMyClass
{
//...
protected:
    DWORD           dwLineID;
    DWORD           dwCurrentLineID;
    DWORD           dwNumDevs;
    LPCTSTR         szAppName;
    LINEINFO        CurrentLineInfo;
    HLINEAPP        hLineApp;
    HINSTANCE       hInst;
    LPLINEINFO      lpLineInfo;
    LPLINEDEVCAPS   lpLineDevCaps;
    HCALL           hCall;
//...
}


2. Инициализируем и открываем телефонную линию:
BOOL CMyClass::TAPIInit(void)
{
    if( 0 != lineInitialize (&hLineApp, hInst, (LINECALLBACK)lineCallbackFunc, szAppName, &dwNumDevs) )
        return FALSE;

    for (DWORD i = 0; i < dwNumDevs; i++)
    {
        if( 0 == lineNegotiateAPIVersion (
            hLineApp, // TAPI registration handle
            dwLineID, // Line device to be queried
            EARLY_TAPI_VERSION, // Least recent API version
            TAPI_CURRENT_VERSION, // Most recent API version
            &(lpLineInfo->dwAPIVersion), // Negotiated API version
            NULL) )
        {
            LINEDEVCAPS LineDevCaps;
            LineDevCaps.dwTotalSize = sizeof(LineDevCaps);

            if(0 == lineGetDevCaps(hLineApp, i, lpLineInfo->dwAPIVersion, 0, &LineDevCaps))
            {
                BYTE* pLineDevCapsBytes = new BYTE[LineDevCaps.dwNeededSize];

                if(0 != pLineDevCapsBytes)
                {
                    LINEDEVCAPS* pLineDevCaps = (LINEDEVCAPS*)pLineDevCapsBytes;
                    pLineDevCaps->dwTotalSize = LineDevCaps.dwNeededSize;
                    if(0 == lineGetDevCaps(hLineApp, i, lpLineInfo->dwAPIVersion, 0, pLineDevCaps))
                    {
                        if(0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset),
                            CELLTSP_LINENAME_STRING))
                        {
                            dwCurrentLineID = i;
                            delete[]  pLineDevCapsBytes;
                            break;
                        }
                    }
                    delete[]  pLineDevCapsBytes;
                }
            }
        }
    }
    if( 0 != lineOpen ( hLineApp, dwCurrentLineID, &CurrentLineInfo.hLine, CurrentLineInfo.dwAPIVersion,
        0, 0, LINECALLPRIVILEGE_MONITOR, LINEMEDIAMODE_DATAMODEM, NULL) )
        return FALSE;
    
    return TRUE;

}


3. Ловим сообщения:
// Global function for get TAPI messages
VOID FAR PASCAL lineCallbackFunc(DWORD hDevice, DWORD dwMsg,
     DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    if(!thisClass)
        return;
    
    switch(dwMsg)
    {
    case LINE_CALLSTATE: // Sent after change of call state
        switch(dwParam1)
        {
         // dwParam1 is the specific CALLSTATE change that is occurring.
         case LINECALLSTATE_OFFERING:
            //...
         break;

         case LINECALLSTATE_CONNECTED:
             break;

         case LINECALLSTATE_BUSY:
         case LINECALLSTATE_IDLE:
         case LINECALLSTATE_DISCONNECTED:
             break;
        }
    default:
        break;
    }
}


4. Закрываем линию, если уже в ней нет необходимости:
void CMyClass::TAPIUnInit(void)
{
    if (CurrentLineInfo.hLine)
        lineClose (CurrentLineInfo.hLine);
    // Reinitialize the variables.
    CurrentLineInfo.hLine = NULL;
    lineShutdown (hLineApp);
}



Для отслеживания события принятия звонка использовать проверять значение dwParam1 == LINECALLSTATE_CONNECTED, для отслеживания появления входящего звонка до взятия трубки соответсвенно LINECALLSTATE_OFFERING, для исходящего звонка, чесно сказать, не помню, нужно посмотреть в МСДН.

И еще, функция принимающая сообщения с тел. линии (lineCallbackFunc) должна быть глобальной, по крайней мере, сделать ее статической в классе у меня не получилось (просто не приходили сообщения).
Re[2]: Как отследить момент звонка?
От: Krevio  
Дата: 09.06.08 09:29
Оценка:
Здравствуйте, GGoga, Вы писали:

GG>Здравствуйте, Krevio, Вы писали:


K>>Как из своего приложения отследить момент исходящего/входящего вызовов, чтоб не пытаться в это время чтото делать через gprs?

K>>Через TAPI lineOpen и смотреть потом какието статусы (какие?) или в винде какие то сообщения ловить? Или неправильно рассуждаю?

GG>Для этого нужно юзать или TAPI, или RIL. Я бы посоветовал именно TAPI.

GG>Я делал так:

я уже примерно так и сделал (через TAPI), и все заработало, но реализация у меня получилась корявенькая.
со временем переделаю по аналогии с приведенным кодом.
спасибо.
Re[2]: Как отследить момент звонка?
От: GGoga  
Дата: 11.11.08 14:40
Оценка:
Подниму уже устарелый топик, потому как в примере есть некоторые неточности, чтобы не возникло проблем в последующем.

K>>Как из своего приложения отследить момент исходящего/входящего вызовов, чтоб не пытаться в это время чтото делать через gprs?

K>>Через TAPI lineOpen и смотреть потом какието статусы (какие?) или в винде какие то сообщения ловить? Или неправильно рассуждаю?

Для этого нужно юзать или TAPI, или RIL. Я бы посоветовал именно TAPI.
Я делал так:

1. Объявляем необходимые переменные:
typedef struct tagLINEINFO
{
    HLINE hLine; // Line handle returned by lineOpen
    BOOL bVoiceLine; // Indicates if the line is a voice // line
    DWORD dwAPIVersion; // API version that the line supports
    DWORD dwNumOfAddress; // Number of available addresses on // the line
    DWORD dwPermanentLineID; // Permanent line identifier
    TCHAR szLineName[256]; // Name of the line

} LINEINFO, *LPLINEINFO;

class CMyClass
{
//...
protected:
    DWORD           dwLineID;
    DWORD           dwCurrentLineID;
    DWORD           dwNumDevs;
    LPCTSTR         szAppName;
    LINEINFO        CurrentLineInfo;
    HLINEAPP        hLineApp;
    HINSTANCE       hInst;
    LPLINEINFO      lpLineInfo;
    LPLINEDEVCAPS   lpLineDevCaps;
    HCALL           hCall;
//...
}

// Default constructor
CMyClass::CMyClass()
{
    // ...
    lpLineInfo        = &CurrentLineInfo;
    lpLineDevCaps    = 0;
    dwLineID        = 0;
    dwCurrentLineID    = 0;
    dwNumDevs        = 0;
    hCall        = 0;
}


2. Инициализируем и открываем телефонную линию:
BOOL CMyClass::TAPIInit(void)
{
    if( 0 != lineInitialize (&hLineApp, hInst, (LINECALLBACK)lineCallbackFunc, szAppName, &dwNumDevs) )
        return FALSE;

    for (DWORD i = 0; i < dwNumDevs; i++)
    {
        if( 0 == lineNegotiateAPIVersion (
            hLineApp, // TAPI registration handle
            i, // Line device to be queried
            EARLY_TAPI_VERSION, // Least recent API version
            TAPI_CURRENT_VERSION, // Most recent API version
            &(lpLineInfo->dwAPIVersion), // Negotiated API version
            NULL) )
        {
            LINEDEVCAPS LineDevCaps;
            LineDevCaps.dwTotalSize = sizeof(LineDevCaps);

            if(0 == lineGetDevCaps(hLineApp, i, lpLineInfo->dwAPIVersion, 0, &LineDevCaps))
            {
                BYTE* pLineDevCapsBytes = new BYTE[LineDevCaps.dwNeededSize];

                if(0 != pLineDevCapsBytes)
                {
                    LINEDEVCAPS* pLineDevCaps = (LINEDEVCAPS*)pLineDevCapsBytes;
                    pLineDevCaps->dwTotalSize = LineDevCaps.dwNeededSize;
                    if(0 == lineGetDevCaps(hLineApp, i, lpLineInfo->dwAPIVersion, 0, pLineDevCaps))
                    {
                        if(0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset),
                            CELLTSP_LINENAME_STRING))
                        {
                            dwCurrentLineID = i;
                            delete[]  pLineDevCapsBytes;
                            break;
                        }
                    }
                    delete[]  pLineDevCapsBytes;
                }
            }
        }
    }
    if( 0 != lineOpen ( hLineApp, dwCurrentLineID, &CurrentLineInfo.hLine, CurrentLineInfo.dwAPIVersion,
        0, 0, LINECALLPRIVILEGE_MONITOR, LINEMEDIAMODE_DATAMODEM, NULL) )
        return FALSE;
    
    return TRUE;

}


3. Ловим сообщения:
// Global function for get TAPI messages
VOID FAR PASCAL lineCallbackFunc(DWORD hDevice, DWORD dwMsg,
     DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    if(!thisClass)
        return;
    
    switch(dwMsg)
    {
    case LINE_CALLSTATE: // Sent after change of call state
        switch(dwParam1)
        {
         // dwParam1 is the specific CALLSTATE change that is occurring.
         case LINECALLSTATE_OFFERING:
            //...
         break;

         case LINECALLSTATE_CONNECTED:
             break;

         case LINECALLSTATE_BUSY:
         case LINECALLSTATE_IDLE:
         case LINECALLSTATE_DISCONNECTED:
             break;
        }
    default:
        break;
    }
}


4. Закрываем линию, если уже в ней нет необходимости:
void CMyClass::TAPIUnInit(void)
{
    if (CurrentLineInfo.hLine)
        lineClose (CurrentLineInfo.hLine);
    // Reinitialize the variables.
    CurrentLineInfo.hLine = NULL;
    lineShutdown (hLineApp);
}



Для отслеживания события принятия звонка использовать проверять значение dwParam1 == LINECALLSTATE_CONNECTED, для отслеживания появления входящего звонка до взятия трубки соответсвенно LINECALLSTATE_OFFERING, для исходящего звонка, чесно сказать, не помню, нужно посмотреть в МСДН.

И еще, функция принимающая сообщения с тел. линии (lineCallbackFunc) должна быть глобальной, по крайней мере, сделать ее статической в классе у меня не получилось (просто не приходили сообщения).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.