size_t ut_WiflyControl_FwSetFade_2(void) { led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_FADE; expectedOutgoingFrame.data.set_fade.addr[0] = 0x44; expectedOutgoingFrame.data.set_fade.addr[1] = 0x33; expectedOutgoingFrame.data.set_fade.addr[2] = 0x22; expectedOutgoingFrame.data.set_fade.addr[3] = 0x11; expectedOutgoingFrame.data.set_fade.red = 0x11; expectedOutgoingFrame.data.set_fade.green = 0x22; expectedOutgoingFrame.data.set_fade.blue = 0x33; expectedOutgoingFrame.data.set_fade.parallelFade = 0x01; //TODO why do we use fadeTmms == 1 for SetColor? expectedOutgoingFrame.data.set_fade.fadeTmms = htons(1000); TestCaseBegin(); Control testee(0, 0); // set color testee << FwCmdSetFade {0xff112233, 1000, 0x11223344, true}; TraceBuffer(ZONE_INFO, &g_SendFrame, sizeof(cmd_set_fade) + 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, sizeof(cmd_set_fade) + 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(cmd_set_fade) + 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetGradient(void) { led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_GRADIENT; expectedOutgoingFrame.data.set_gradient.red_1 = 0x11; expectedOutgoingFrame.data.set_gradient.green_1 = 0x22; expectedOutgoingFrame.data.set_gradient.blue_1 = 0x33; expectedOutgoingFrame.data.set_gradient.red_2 = 0x33; expectedOutgoingFrame.data.set_gradient.green_2 = 0x22; expectedOutgoingFrame.data.set_gradient.blue_2 = 0x11; expectedOutgoingFrame.data.set_gradient.parallelAndOffset = 0xff; expectedOutgoingFrame.data.set_gradient.numberOfLeds = 10; expectedOutgoingFrame.data.set_gradient.fadeTmms = htons(1000); TestCaseBegin(); Control testee(0, 0); testee << FwCmdSetGradient {0xff112233,0xff332211, 1000, true, 10, 127}; TraceBuffer(ZONE_INFO, &g_SendFrame, sizeof(cmd_set_gradient) + 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, sizeof(cmd_set_gradient) + 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(cmd_set_gradient) + 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetColorDirectThreeLeds_2(void) { TestCaseBegin(); Control testee(0, 0); // three leds only, all set to yellow const uint32_t argb = 0xffffff00; const uint32_t addr = 0x00000007; uint8_t shortBuffer[3 * 3]; memset(shortBuffer, 0, sizeof(shortBuffer)); shortBuffer[0 * 3 + 0] = 0xff; //first led red shortBuffer[1 * 3 + 1] = 0xff; //second led green shortBuffer[2 * 3 + 2] = 0xff; //third led blue led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_COLOR_DIRECT; memset(expectedOutgoingFrame.data.set_color_direct.ptr_led_array, 0, 3 * NUM_OF_LED); expectedOutgoingFrame.data.set_color_direct.ptr_led_array[0] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[1] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[2] = 0x00; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[3] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[4] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[5] = 0x00; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[6] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[7] = 0xff; expectedOutgoingFrame.data.set_color_direct.ptr_led_array[8] = 0x00; testee << FwCmdSetColorDirect {argb, addr}; TraceBuffer(ZONE_INFO, &g_SendFrame, sizeof(led_cmd) + 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, sizeof(led_cmd) + 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(led_cmd))); TestCaseEnd(); }
size_t ut_WiflyControl_BlEraseFlash(void) { TestCaseBegin(); srand(time_t(NULL)); /* fill gloabal random data pool */ for(unsigned int i = 0; i < sizeof(g_FlashRndDataPool); i++) g_FlashRndDataPool[i] = (uint8_t) rand() % 255; BlInfo blInfo; Control testctrl(0,0); try { testctrl.BlReadInfo(blInfo); testctrl.BlEraseFlash(); } catch(FatalError& e) { CHECK(false); } for(unsigned int i = 0; i < blInfo.GetAddress(); i++) { CHECK(0 == g_FlashRndDataPool[i]); } TestCaseEnd(); }
size_t ut_WiflyControl_BlFlashRead(void) { TestCaseBegin(); srand(time_t(NULL)); /* fill gloabal random data pool */ for(unsigned int i = 0; i < sizeof(g_FlashRndDataPool); i++) g_FlashRndDataPool[i] = (uint8_t) rand() % 255; Control testctrl(0,0); std::stringstream mStream; testctrl.BlReadFlash(mStream, 0, FLASH_SIZE); size_t counter = 0; do { uint8_t byte = 0; mStream >> byte; if(mStream.eof()) break; CHECK(g_FlashRndDataPool[counter++] == byte); } while(!mStream.eof()); CHECK(counter == FLASH_SIZE); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetRtc(void) { tm timeinfo; time_t rawtime; rawtime = time(NULL); localtime_r(&rawtime, &timeinfo); led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = SET_RTC; expectedOutgoingFrame.data.set_rtc.tm_sec = (uns8) timeinfo.tm_sec; expectedOutgoingFrame.data.set_rtc.tm_min = (uns8) timeinfo.tm_min; expectedOutgoingFrame.data.set_rtc.tm_hour = (uns8) timeinfo.tm_hour; expectedOutgoingFrame.data.set_rtc.tm_mday = (uns8) timeinfo.tm_mday; expectedOutgoingFrame.data.set_rtc.tm_mon = (uns8) timeinfo.tm_mon; expectedOutgoingFrame.data.set_rtc.tm_year = (uns8) timeinfo.tm_year; expectedOutgoingFrame.data.set_rtc.tm_wday = (uns8) timeinfo.tm_wday; TestCaseBegin(); Control testee(0, 0); testee << FwCmdSetRtc {timeinfo}; TraceBuffer(ZONE_INFO, &g_SendFrame, sizeof(rtc_time) + 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, sizeof(rtc_time) + 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(rtc_time) + 1)); TestCaseEnd(); }
size_t ut_WiflyControl_ConfSetWlan(void) { TestCaseBegin(); static const std::string phraseBase("12345678911234567892123456789312345678941234567895123456789612"); static const std::string phraseContainsNonAlNum(phraseBase + "\x1f"); static const std::string phrase(phraseBase + "3"); static const std::string phraseToLong(phrase + " "); static const std::string ssid ("12345678911234567892123456789312"); static const std::string ssidToLong(ssid + " "); Control testee(0, 0); // passphrase to short CHECK(!testee.ConfSetWlan("", ssid)); // passphrase to long CHECK(!testee.ConfSetWlan(phraseToLong, ssid)); // passphrase contains not only alphanumeric characters CHECK(!testee.ConfSetWlan(phraseContainsNonAlNum, ssid)); // ssid to short CHECK(!testee.ConfSetWlan(phrase, "")); // ssid to long CHECK(!testee.ConfSetWlan(phrase, ssidToLong)); // valid passphrase and ssid CHECK(testee.ConfSetWlan(phrase, ssid)); TestCaseEnd(); }
size_t ut_WiflyControl_FwClearScript(void) { led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = CLEAR_SCRIPT; TestCaseBegin(); Control testee(0, 0); testee << FwCmdClearScript {}; TraceBuffer(ZONE_INFO, &g_SendFrame, 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwLoopOn(void) { led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = LOOP_ON; TestCaseBegin(); Control testee(0, 0); testee << FwCmdLoopOn {}; TraceBuffer(ZONE_INFO, &g_SendFrame, 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetWait(void) { led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = WAIT; expectedOutgoingFrame.data.wait.waitTmms = htons(1000); TestCaseBegin(); Control testee(0, 0); testee << FwCmdWait {1000}; TraceBuffer(ZONE_INFO, &g_SendFrame, sizeof(cmd_wait) + 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, sizeof(cmd_wait) + 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(cmd_wait) + 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetColorDirectRedOnly(void) { TestCaseBegin(); Control testee(0, 0); // one leds only, first red uint8_t shortBuffer[1] {0xff}; led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_COLOR_DIRECT; memcpy(expectedOutgoingFrame.data.set_color_direct.ptr_led_array, shortBuffer, sizeof(shortBuffer)); memset(expectedOutgoingFrame.data.set_color_direct.ptr_led_array + sizeof(shortBuffer), 0x00, sizeof(cmd_set_color_direct) - sizeof(shortBuffer)); testee << FwCmdSetColorDirect {shortBuffer, sizeof(shortBuffer)}; CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(led_cmd))); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetColorDirectToMany(void) { TestCaseBegin(); Control testee(0, 0); // three leds only, first red, second green last blue uint8_t shortBuffer[2 * NUM_OF_LED * 3]; memset(shortBuffer, 0xff, sizeof(shortBuffer)); led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_COLOR_DIRECT; memcpy(expectedOutgoingFrame.data.set_color_direct.ptr_led_array, shortBuffer, NUM_OF_LED * 3); testee << FwCmdSetColorDirect(shortBuffer, sizeof(shortBuffer)); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(led_cmd))); TestCaseEnd(); }
size_t ut_WiflyControl_ConfSetDefaults(void) { TestCaseBegin(); static const std::string commands[] = { "set broadcast interval 0x1\r\n", // to support fast broadcast recognition "set comm close 0\r\n", // Disable *CLOS* string "set comm open 0\r\n", // Disable *OPEN* string "set comm remote 0\r\n", // Disable *Hello* string "set comm time 5\r\n", // Set flush timer to 5 ms "set comm idle 240\r\n", // Set idle timer to 240 s, to close tcp connections after 240s if there's no traffic "set dns name rn.microchip.com\r\n", // set dns of updateserver "set ip flags 0x6\r\n", // if the module loses the accesspoint connection, the connection is closed "set ip dhcp 1\r\n", // enable DHCP client // "set ftp address 169.254.7.57\r\n",// configure localhost as ftp server in ad-hoc connection "set ftp pass Pass123\r\n", // configure ftp password "set ftp user roving\r\n", // configure ftp username "set opt deviceid Wifly_Light\r\n", // Set deviceid which appears in broadcastmsg to "Wifly_Light" "set uart baud 115200\r\n", // PIC uart parameter "set uart flow 0\r\n", // PIC uart parameter "set uart mode 0\r\n", // PIC uart parameter "set wlan channel 0\r\n", // Set the wlan channel to 0 to perform an automatic scan for a free channel "set wlan auth 4\r\n", // use WPA2 protection "set wlan join 1\r\n", // scan for ap and auto join "set wlan rate 0\r\n", // slowest datarate but highest range "set wlan tx 12\r\n", // Set the Wi-Fi transmit power to maximum "set sys printlvl 0\r\n", // Disables Debug Messages to UART "set ip p 11\r\n", // Enable UDP, TCP_CLIENT and TCP Protocol //"set sys launch_string wps_app" // Choose Wps mode }; static const size_t numCommands = sizeof(commands) / sizeof(commands[0]); Control testee(0, 0); g_TestBuffer.clear(); CHECK(testee.ConfSetDefaults()); CHECK(!g_ProxyConnected); CHECK(g_ProxySaved); CHECK(numCommands == g_TestBuffer.size()); for(size_t i = 0; i < numCommands; i++) { CHECK(0 == commands[i].compare(g_TestBuffer.front())); g_TestBuffer.pop_front(); } TestCaseEnd(); }
size_t ut_WiflyControl_FwGetVersion(void) { led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = GET_FW_VERSION; TestCaseBegin(); Control testee(0, 0); try { testee.FwGetVersion(); } catch(std::exception) { } TraceBuffer(ZONE_INFO, &g_SendFrame, 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, 1)); TestCaseEnd(); }
size_t ut_WiflyControl_BlReadInfo(void) { TestCaseBegin(); Control testctrl(0,0); BlInfo mInfo; testctrl.BlReadInfo(mInfo); CHECK(mInfo.familyId == 4); CHECK(mInfo.versionMajor == 1); CHECK(mInfo.versionMinor == 5); CHECK(mInfo.zero == 0); CHECK(mInfo.sizeHigh == 3); CHECK(mInfo.sizeLow == 0); CHECK(mInfo.startU == 0); CHECK(mInfo.startHigh == 253); CHECK(mInfo.startLow == 0); CHECK(mInfo.cmdmaskHigh == 255); //CHECK(mInfo.cmdmaskLow == 0x84); TestCaseEnd(); }
size_t ut_WiflyControl_FwLoopOff(void) { led_cmd expectedOutgoingFrame = {0xff}; expectedOutgoingFrame.cmd = LOOP_OFF; expectedOutgoingFrame.data.loopEnd.numLoops = 100; expectedOutgoingFrame.data.loopEnd.counter = 0; expectedOutgoingFrame.data.loopEnd.depth = 0; expectedOutgoingFrame.data.loopEnd.startIndex = 0; TestCaseBegin(); Control testee(0, 0); testee << FwCmdLoopOff {100}; TraceBuffer(ZONE_INFO, &g_SendFrame, 1, "%02x ", "IS :"); TraceBuffer(ZONE_INFO, &expectedOutgoingFrame, 1, "%02x ", "SOLL:"); CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, 1)); TestCaseEnd(); }
size_t ut_WiflyControl_FwSetColorDirectThreeLeds(void) { TestCaseBegin(); Control testee(0, 0); // three leds only, first red, second green last blue uint8_t shortBuffer[3 * 3]; memset(shortBuffer, 0, sizeof(shortBuffer)); shortBuffer[0 * 3 + 0] = 0xff; //first led red shortBuffer[1 * 3 + 1] = 0xff; //second led green shortBuffer[2 * 3 + 2] = 0xff; //third led blue led_cmd expectedOutgoingFrame; expectedOutgoingFrame.cmd = SET_COLOR_DIRECT; memcpy(expectedOutgoingFrame.data.set_color_direct.ptr_led_array, shortBuffer, sizeof(shortBuffer)); memset(expectedOutgoingFrame.data.set_color_direct.ptr_led_array + sizeof(shortBuffer), 0x00, sizeof(cmd_set_color_direct) - sizeof(shortBuffer)); testee << FwCmdSetColorDirect {shortBuffer, sizeof(shortBuffer)}; CHECK(0 == memcmp(&g_SendFrame, &expectedOutgoingFrame, sizeof(led_cmd))); TestCaseEnd(); }
// Testcases size_t ut_WiflyControl_BlEraseEeprom(void) { TestCaseBegin(); srand(time_t(NULL)); /* fill gloabal random data pool */ for(unsigned int i = 0; i < sizeof(g_EepromRndDataPool); i++) { g_EepromRndDataPool[i] = (uint8_t) rand() % 255; } Control testctrl(0,0); testctrl.BlEraseEeprom(); for(unsigned int i = 0; i < EEPROM_SIZE; i++) { CHECK(0xff == g_EepromRndDataPool[i]); } TestCaseEnd(); }
size_t ut_WiflyControl_BlFlashWrite(void) { TestCaseBegin(); srand(time_t(NULL)); uint8_t m_FlashRndDataPool[FLASH_SIZE]; /* fill gloabal random data pool */ for(unsigned int i = 0; i < sizeof(g_FlashRndDataPool); i++) { g_FlashRndDataPool[i] = (uint8_t) rand() % 255; m_FlashRndDataPool[i] = (uint8_t) rand() % 255; } Control testctrl(0,0); testctrl.BlWriteFlash(0, m_FlashRndDataPool, sizeof(m_FlashRndDataPool)); for(unsigned int i = 0; i < FLASH_SIZE; i++) { CHECK(m_FlashRndDataPool[i] == g_FlashRndDataPool[i]); } TestCaseEnd(); }
// ------------------------------------------------------------------------------------------------ int main(int argc, const char **argv) { // Common variables NetBuf *inPkt; TcpHeader *inHdr; Packet *outPkt; TcpHeader *outHdr; TcpConn *conn; TestSetup(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSED, "RST", "segment dropped"); inPkt = NetAllocBuf(); inHdr = (TcpHeader *)inPkt->start; inHdr->srcPort = 100; inHdr->dstPort = 101; inHdr->seq = 1; inHdr->ack = 2; inHdr->off = 5 << 4; inHdr->flags = TCP_RST; inHdr->windowSize = TCP_WINDOW_SIZE; inHdr->checksum = 0; inHdr->urgent = 0; TcpInput(inPkt); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSED, "ACK", "RST sent"); inPkt = NetAllocBuf(); inHdr = (TcpHeader *)inPkt->start; inHdr->srcPort = 100; inHdr->dstPort = 101; inHdr->seq = 1; inHdr->ack = 2; inHdr->off = 5 << 4; inHdr->flags = TCP_ACK; inHdr->windowSize = TCP_WINDOW_SIZE; inHdr->checksum = 0; inHdr->urgent = 0; TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, 101); ASSERT_EQ_UINT(outHdr->dstPort, 100); ASSERT_EQ_UINT(outHdr->seq, 2); ASSERT_EQ_UINT(outHdr->ack, 0); ASSERT_EQ_HEX8(outHdr->flags, TCP_RST); free(outPkt); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSED, "no ACK", "RST/ACK sent"); inPkt = NetAllocBuf(); inHdr = (TcpHeader *)inPkt->start; inHdr->srcPort = 100; inHdr->dstPort = 101; inHdr->seq = 1; inHdr->ack = 2; inHdr->off = 5 << 4; inHdr->flags = 0; inHdr->windowSize = TCP_WINDOW_SIZE; inHdr->checksum = 0; inHdr->urgent = 0; TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, 101); ASSERT_EQ_UINT(outHdr->dstPort, 100); ASSERT_EQ_UINT(outHdr->seq, 0); ASSERT_EQ_UINT(outHdr->ack, 1); ASSERT_EQ_HEX8(outHdr->flags, TCP_RST | TCP_ACK); free(outPkt); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSED, "connect", "goto SYN_SENT"); conn = CreateConn(); ASSERT_TRUE(TcpConnect(conn, &s_ipAddr, 80)); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_TRUE(outHdr->srcPort >= 49152); ASSERT_EQ_UINT(outHdr->dstPort, 80); ASSERT_EQ_UINT(outHdr->seq, conn->iss); ASSERT_EQ_UINT(outHdr->ack, 0); ASSERT_EQ_HEX8(outHdr->flags, TCP_SYN); ASSERT_EQ_UINT(outHdr->windowSize, TCP_WINDOW_SIZE); ASSERT_EQ_UINT(outHdr->urgent, 0); free(outPkt); ExitState(conn, TCP_SYN_SENT); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "Bad ACK, no RST", "RST sent"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, conn->iss, TCP_ACK); TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, conn->localPort); ASSERT_EQ_UINT(outHdr->dstPort, conn->remotePort); ASSERT_EQ_UINT(outHdr->seq, inHdr->ack); ASSERT_EQ_UINT(outHdr->ack, 0); ASSERT_EQ_HEX8(outHdr->flags, TCP_RST); free(outPkt); ExitState(conn, TCP_SYN_SENT); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "Bad ACK, RST", "segment dropped"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, conn->iss, TCP_RST | TCP_ACK); TcpInput(inPkt); ExitState(conn, TCP_SYN_SENT); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "ACK, RST", "conn locally reset"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, conn->iss + 1, TCP_RST | TCP_ACK); TcpInput(inPkt); ExpectError(TCP_CONN_RESET); ExitState(conn, TCP_CLOSED); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "no ACK, RST", "segment dropped"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, conn->iss + 1, TCP_RST); TcpInput(inPkt); ExitState(conn, TCP_SYN_SENT); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "SYN, ACK", "goto ESTABLISHED"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, conn->iss + 1, TCP_SYN | TCP_ACK); TcpInput(inPkt); ASSERT_EQ_UINT(conn->irs, 1000); ASSERT_EQ_UINT(conn->rcvNxt, 1001); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, conn->localPort); ASSERT_EQ_UINT(outHdr->dstPort, conn->remotePort); ASSERT_EQ_UINT(outHdr->seq, conn->iss + 1); ASSERT_EQ_UINT(outHdr->ack, 1001); ASSERT_EQ_HEX8(outHdr->flags, TCP_ACK); free(outPkt); ExitState(conn, TCP_ESTABLISHED); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_SENT, "SYN, no ACK", "goto SYN_RECEIVED, resend SYN,ACK"); conn = CreateConn(); EnterState(conn, TCP_SYN_SENT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, 1000, 0, TCP_SYN); TcpInput(inPkt); ASSERT_EQ_UINT(conn->irs, 1000); ASSERT_EQ_UINT(conn->rcvNxt, 1001); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, conn->localPort); ASSERT_EQ_UINT(outHdr->dstPort, conn->remotePort); ASSERT_EQ_UINT(outHdr->seq, conn->iss); ASSERT_EQ_UINT(outHdr->ack, 1001); ASSERT_EQ_HEX8(outHdr->flags, TCP_SYN | TCP_ACK); free(outPkt); ExitState(conn, TCP_SYN_RECEIVED); TestCaseEnd(); // -------------------------------------------------------------------------------------------- uint generalStates[] = { TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSE_WAIT, TCP_CLOSING, TCP_LAST_ACK, TCP_TIME_WAIT, 0, }; for (uint *pState = generalStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "Bad seq, no RST", "resend ACK"); conn = CreateConn(); EnterState(conn, state); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt - 1, conn->sndNxt, TCP_ACK); TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, conn->localPort); ASSERT_EQ_UINT(outHdr->dstPort, conn->remotePort); ASSERT_EQ_UINT(outHdr->seq, conn->sndNxt); ASSERT_EQ_UINT(outHdr->ack, conn->rcvNxt); ASSERT_EQ_HEX8(outHdr->flags, TCP_ACK); free(outPkt); ExitState(conn, state); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- for (uint *pState = generalStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "Bad seq, RST", "segment dropped"); conn = CreateConn(); EnterState(conn, state); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt - 1, conn->sndNxt, TCP_RST | TCP_ACK); TcpInput(inPkt); ExitState(conn, state); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_RECEIVED, "RST, active", "conn refused"); conn = CreateConn(); EnterState(conn, TCP_SYN_RECEIVED); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, 0, TCP_RST); TcpInput(inPkt); ExpectError(TCP_CONN_REFUSED); TestCaseEnd(); // -------------------------------------------------------------------------------------------- uint rstStates1[] = { TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSE_WAIT, 0, }; for (uint *pState = rstStates1; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "RST", "conn reset"); conn = CreateConn(); EnterState(conn, state); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, 0, TCP_RST); TcpInput(inPkt); ExpectError(TCP_CONN_RESET); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- uint rstStates2[] = { TCP_CLOSING, TCP_LAST_ACK, TCP_TIME_WAIT, 0, }; for (uint *pState = rstStates2; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "RST", "conn closed"); conn = CreateConn(); EnterState(conn, state); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, 0, TCP_RST); TcpInput(inPkt); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- for (uint *pState = generalStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "SYN", "conn reset, RST sent"); conn = CreateConn(); EnterState(conn, state); u16 localPort = conn->localPort; u16 remotePort = conn->remotePort; u32 rcvNxt = conn->rcvNxt; inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, conn->sndNxt, TCP_SYN); TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, localPort); ASSERT_EQ_UINT(outHdr->dstPort, remotePort); ASSERT_EQ_UINT(outHdr->seq, 0); ASSERT_EQ_UINT(outHdr->ack, rcvNxt); ASSERT_EQ_HEX8(outHdr->flags, TCP_RST | TCP_ACK); free(outPkt); ExpectError(TCP_CONN_RESET); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_RECEIVED, "bad ACK", "RST sent"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_SYN_RECEIVED, "ACK", "goto ESTABLISHED"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- uint ackStates[] = { TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSE_WAIT, TCP_CLOSING, 0 }; for (uint *pState = ackStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "ACK", "update pointers"); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- for (uint *pState = ackStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "dup ACK", "ignore"); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- for (uint *pState = ackStates; *pState; ++pState) { uint state = *pState; TestCaseBegin(state, "unsent ACK", "resend ACK"); TestCaseEnd(); } // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_FIN_WAIT_1, "ACK, FIN not ACK'd", "ignore"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSING, "ACK, FIN not ACK'd", "ignore"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_FIN_WAIT_1, "ACK, FIN ACK'd", "goto FIN-WAIT-2"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_CLOSING, "ACK, FIN ACK'd", "goto TIME-WAIT"); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_LAST_ACK, "ACK, FIN not ACK'd", "ignore"); conn = CreateConn(); EnterState(conn, TCP_LAST_ACK); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, conn->sndNxt - 1, TCP_ACK); TcpInput(inPkt); ExitState(conn, TCP_LAST_ACK); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_LAST_ACK, "ACK, FIN ACK'd", "goto CLOSED"); conn = CreateConn(); EnterState(conn, TCP_LAST_ACK); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, conn->sndNxt, TCP_ACK); TcpInput(inPkt); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_TIME_WAIT, "ACK, no FIN", "ignore"); conn = CreateConn(); EnterState(conn, TCP_TIME_WAIT); inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, conn->sndNxt, TCP_ACK); TcpInput(inPkt); ExitState(conn, TCP_TIME_WAIT); TestCaseEnd(); // -------------------------------------------------------------------------------------------- TestCaseBegin(TCP_TIME_WAIT, "FIN", "reset 2MSL timer"); conn = CreateConn(); EnterState(conn, TCP_TIME_WAIT); g_pitTicks += 1000; inPkt = NetAllocBuf(); inHdr = PrepareInPkt(conn, inPkt, conn->rcvNxt, conn->sndNxt, TCP_FIN | TCP_ACK); TcpInput(inPkt); outPkt = PopPacket(); outHdr = (TcpHeader *)outPkt->data; TcpSwap(outHdr); ASSERT_EQ_UINT(outHdr->srcPort, conn->localPort); ASSERT_EQ_UINT(outHdr->dstPort, conn->remotePort); ASSERT_EQ_UINT(outHdr->seq, conn->sndNxt); ASSERT_EQ_UINT(outHdr->ack, conn->rcvNxt); ASSERT_EQ_HEX8(outHdr->flags, TCP_ACK); free(outPkt); ASSERT_EQ_UINT(conn->mslWait, g_pitTicks + 2 * TCP_MSL); ExitState(conn, TCP_TIME_WAIT); TestCaseEnd(); return EXIT_SUCCESS; }