1
Vote

TapiCall.GenerateDigits Blocks execution (doesn't return)

description

The Call.GenterateDigits method will block execution and never return, if the call's state changes to LINECALLSTATE_IDLE during a call to generate digits.

This occurs if the LINECALLSTATE_IDLE call state change occurs after GenerateDigits is invoked, but before the LINE_GENERATE TAPI response event has been received.


The reason for this is that the callstate change causes the TapiCall object to be deallocated (TapiCall.Deallocate) and the TAPI call handle is closed. Even if the LINE_GENERATE_TAPI is subsequently received there is no longer a reference to the call in the TapiCall.CallsMap Dictionary and the event will not be processed. This issue results in the ar.AsyncWaitHandle.WaitOne() blocking forever in the method EndGenerateDigits.

The same will be true for tone generation.

Here is a possible workaround in TapiCall for Digit Generation.
public bool EndGenerateDigits(IAsyncResult ar)
{
    if (ar == null)
        throw new ArgumentNullException("ar");

    // Start of Change
    // ar.AsyncWaitHandle.WaitOne();

    while(true)
    {
        if (ar.AsyncWaitHandle.WaitOne(50) == true)
        {
            break;
        }
        if (_hCall.IsClosed)
        {
            OnGenerateDigitsOrToneComplete(NativeMethods.LINEERR_OPERATIONFAILED);
            break;
            
        }
        
    }
    // End of Change
    
    var req = (PendingTapiRequest)ar;
    return (req.Result == 1);
}
UPDATE:
This issue was seen at a client-site with an NEC telephone system. This issue could not be reproduced on a CISCO telephone system where the TAPI driver appears to always sends the LINE_GENERATE_TAPI event before the call state change to LINECALLSTATE_IDLE

comments