⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comm.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    dcb.Parity = NOPARITY;
    dcb.fRtsControl=RTS_CONTROL_ENABLE;
    dcb.fDtrControl=DTR_CONTROL_ENABLE;
    dcb.StopBits = ONESTOPBIT;
    ok(SetCommState(hcom, &dcb), "SetCommState failed\n");

    ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
    ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
    ok(written == sizeof(tbuf),"WriteFile %ld bytes written, expected %d\n",
       written, sizeof(tbuf));

    trace("WaitCommEventEV_RXCHAR\n");
    ok(WaitCommEvent(hcom, &evtmask, NULL), "WaitCommEvent failed\n");
    ok(evtmask == EV_RXCHAR, "WaitCommEvent: Unexpected EvtMask 0x%08lx, expected 0x%08x\n",
       evtmask, EV_RXCHAR);

    before = GetTickCount();
    res = ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL);
    after = GetTickCount();
    ok(res, "Readfile failed\n");
    ok(read == sizeof(tbuf),"ReadFile read %ld bytes, expected %d\n", read, sizeof(tbuf));
    diff = after - before;
    trace("Readfile for %d chars with %d avail took %ld ms\n",
	  sizeof(rbuf), sizeof(tbuf), diff);
    ok( (diff > TIMEOUT - TIMEDELTA) && (diff < TIMEOUT + TIMEDELTA),
	"Timedout Wait took %ld ms, expected around %d\n", diff, TIMEOUT);

    /* now do a plain read with slow speed
     * This will result in several low level reads and a timeout to happen
     */
    dcb.BaudRate = SLOWBAUD;
    ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
    ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
    before = GetTickCount();
    read = 0;
    read1 =0;
    i=0;
    do 
    {
	res = ReadFile(hcom, rbuf+read, sizeof(rbuf-read), &read1, NULL);
	ok(res, "Readfile failed\n");
	read += read1;
	i++;
    }
    while ((read < sizeof(tbuf)) && (i <10));
    after =  GetTickCount();
    ok( read == sizeof(tbuf),"ReadFile read %ld bytes, expected %d\n", read, sizeof(tbuf));
    trace("Plain Read for %d char at %d baud took %ld ms\n", sizeof(tbuf), SLOWBAUD, after-before);
    
}

static void test_LoopbackCtsRts(HANDLE hcom)
{
    DWORD ModemStat, defaultStat;
    DCB dcb;

    ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
    if (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE)
    {
	trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate RTS\n");
	return;
    }
    ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
    /* XP returns some values in the low nibble, so mask them out*/
    defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
    if(defaultStat & MS_CTS_ON)
    {
	ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_CTS_ON) == 0, "CTS didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat & ~MS_CTS_ON));
	ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to clear RTS\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore CTS: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
    else
    {
	ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to set RTS\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_CTS_ON) == MS_CTS_ON,
	    "CTS didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat | MS_CTS_ON));
	ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore CTS: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
}

static void test_LoopbackDtrDcd(HANDLE hcom)
{
    DWORD ModemStat, defaultStat;
    DCB dcb;

    ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
    if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
    {
	trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
	return;
    }
    ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
    /* XP returns some values in the low nibble, so mask them out*/
    defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
    if(defaultStat & MS_RLSD_ON)
    {
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_RLSD_ON) == 0, "RLSD didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat & ~MS_RLSD_ON));
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore RLSD: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
    else
    {
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_RLSD_ON) == MS_RLSD_ON,
	    "RLSD didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat | MS_RLSD_ON));
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore RLSD: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
}

static void test_LoopbackDtrDsr(HANDLE hcom)
{
    DWORD ModemStat, defaultStat;
    DCB dcb;

    ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
    if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
    {
	trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
	return;
    }
    ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
    /* XP returns some values in the low nibble, so mask them out*/
    defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
    if(defaultStat & MS_DSR_ON)
    {
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_DSR_ON) == 0, "CTS didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat & ~MS_DSR_ON));
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore DSR: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
    else
    {
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_DSR_ON) == MS_DSR_ON,
	    "CTS didn't react: 0x%04lx,expected 0x%04lx\n",
	    ModemStat, (defaultStat | MS_DSR_ON));
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore DSR: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
}

static void test_LoopbackDtrRing(HANDLE hcom)
{
    DWORD ModemStat, defaultStat;
    DCB dcb;

    ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
    if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
    {
	trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
	return;
    }
    ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
    /* XP returns some values in the low nibble, so mask them out*/
    defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
    if(defaultStat & MS_RING_ON)
    {
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_RING_ON) == 0, "RING didn't react: 0x%04lx,  expected 0x%04lx\n",
	    ModemStat, (defaultStat & ~MS_RING_ON));
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore RING: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
    else
    {
	ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok ((ModemStat & MS_RING_ON) == MS_RING_ON,
	    "RING didn't react: 0x%04lx,expected 0x%04lx\n",
	    ModemStat, (defaultStat | MS_RING_ON));
	ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
	ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
	ok (ModemStat ==  defaultStat, "Failed to restore RING: 0x%04lx, expected 0x%04lx\n",
	    ModemStat, defaultStat);
    }
}

/*
 * Set up a WaitCommEvent for anything in the receive buffer,
 * then write to TX to put a character
 * into the RX buffer
 * Need Loopback TX->RX
*/

static void  test_WaitRx(HANDLE hcom)
{
    OVERLAPPED overlapped, overlapped_w;
    HANDLE hComPortEvent, hComWriteEvent;
    DWORD before, after, after1, diff, success_wait = FALSE, success_write;
    DWORD err_wait, err_write, written, evtmask=0;

    ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
    hComPortEvent =  CreateEvent( NULL, TRUE, FALSE, NULL );
    ok(hComPortEvent != 0, "CreateEvent failed\n");
    ZeroMemory( &overlapped, sizeof(overlapped));
    overlapped.hEvent = hComPortEvent;

    ok((hComWriteEvent =  CreateEvent( NULL, TRUE, FALSE, NULL )) !=0,
       "CreateEvent res 0x%08lx\n",
       GetLastError());
    ZeroMemory( &overlapped_w, sizeof(overlapped_w));
    overlapped_w.hEvent = hComWriteEvent;

    before = GetTickCount();
    {success_wait = WaitCommEvent(hcom, &evtmask, &overlapped);}
    err_wait = GetLastError();
    after = GetTickCount();
    trace("Success 0x%08lx err 0x%08lx evtmask 0x%08lx\n", success_wait, err_wait, evtmask);
    ok(success_wait || err_wait == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
    trace("overlapped WriteCommEvent returned.\n");

    success_write= WriteFile(hcom, "X", 1, &written, &overlapped_w);
    err_write = GetLastError();
    ok(success_write || err_write == ERROR_IO_PENDING,
       "overlapped WriteFile failed, err 0x%08lx\n",
       err_write);

    if (!success_write && (err_write == ERROR_IO_PENDING)) {
      success_write = WaitForSingleObjectEx(hComWriteEvent, TIMEOUT, TRUE);
      err_write = GetLastError();
      ok(success_write == WAIT_OBJECT_0, "WaitForSingleObjectEx, res 0x%08lx, err 0x%08lx\n",
	 success_write, err_write);
    }
    Sleep(TIMEOUT >>1);
    success_write = GetOverlappedResult(hcom, &overlapped_w, &written, FALSE);
    err_write = GetLastError();

    trace("Write after Wait res 0x%08lx err 0x%08lx\n",success_write, err_write);
    ok(success_write && written ==1, "Write after Wait res 0x%08lx err 0x%08lx\n",
       success_write, err_write);

    if (!success_wait && (err_wait == ERROR_IO_PENDING)) {
      success_wait = WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE);
      err_wait = GetLastError();
      ok(success_wait == WAIT_OBJECT_0, "wait hComPortEvent, res 0x%08lx, err 0x%08lx\n",
	 success_wait, err_wait);
    }
    success_wait = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
    err_wait = GetLastError();
    after1 = GetTickCount();
    trace("Success 0x%08lx err 0x%08lx evtmask 0x%08lx diff1 %ld, diff2 %ld\n",
	  success_wait, err_wait, evtmask, after-before, after1-before);

    ok(evtmask & EV_RXCHAR, "Detect  EV_RXCHAR: 0x%08lx, expected 0x%08x\n",
       evtmask, EV_RXCHAR);
    diff = after1 - before;
    ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
	"Unexpected time %ld, expected around %d\n", diff, TIMEOUT>>1);

}

/* Change the controling line after the given timeout to the given state
   By the loopback, this should trigger the WaitCommEvent
*/
static DWORD CALLBACK toggle_ctlLine(LPVOID arg)
{
    DWORD *args = (DWORD *) arg;
    DWORD timeout = args[0];
    DWORD ctl     = args[1];
    HANDLE hcom   = (HANDLE) args[2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -