Figure 6: Server application model

UINT CMainFrame::AnswerCallThread(PVOID pParam)
{
    CMainFrame* pMainFrame = (CMainFrame*)pParam;

    // instantiate Remote Connect object - request inbound/use
    // default I/O thread
    CRemoteConnect obj(CRemoteConnect::ANSWERCALL,TRUE);

    // put user interface algorithm here - do a simple loopback as
    // an example
    CByteArray inMsg;

    // wait for call answer while checking for thread termination
    while (1)
    {
        HANDLE hndls[2] = {obj.GetConnectEventHandle(),
                           pMainFrame->m_exitThreadEvent};
        int rc = WaitForMultipleObjects(2,hndls,FALSE,INFINITE);
        if (rc == WAIT_OBJECT_0+1)
            return 0L;

        // while Modem connected and no termination,
        // echo 1..MAX_IO_BYTES byte messages back to sender
        while (obj.isModemConnected())
        {
            if (WaitForSingleObject(pMainFrame->m_exitThreadEvent,0)
                   != WAIT_TIMEOUT)
                return 0L;
            // Block on read message up to 100msec
            if (obj.SyncRead(inMsg,100) && obj.isModemConnected())
            {
                while (inMsg.GetSize())
                {
                    CByteArray outMsg;
                    outMsg.Add(inMsg.GetAt(0));
                    inMsg.RemoveAt(0);
                }
                obj.putMessage(outMsg);
            }
        }

        // next client
        if (!obj.ReAnswerModem())
            return 100L;
    }
}