program to test the TCP socket connection of EthernetInterface. specifically, to reproduce a problem that results in the mbed re-sending the wrong packet after a packet loss
Dependencies: EthernetInterface FatFileSystemCpp SDFileSystem mbed-rtos mbed
Revision 0:53afc51b78a9, committed 2012-09-22
- Comitter:
- uci1
- Date:
- Sat Sep 22 04:01:27 2012 +0000
- Child:
- 1:6b90cbfe0c9e
- Commit message:
- program to test the TCP socket connection of EthernetInterface
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#a0ee3ae75cfa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FatFileSystemCpp.lib Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/igorsk/code/FatFileSystemCpp/#88f22c32a456
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/SomeRandomBloke/code/SDFileSystem/#9c5f0c655284
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fakeData.h Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,111 @@ +#ifndef __FAKE_DATA__ +#define __FAKE_DATA__ + +static const int kFakeDataSize=1024; +const char gFakeData[kFakeDataSize] = { + 0x48, 0x65, 0x06, 0x53, 0x63, 0xc6, 0x58, 0x64, 0xb6, 0x62, + 0x65, 0x66, 0x3d, 0x64, 0xe6, 0x2f, 0x64, 0x46, 0x40, 0x64, + 0x96, 0x5f, 0x65, 0x46, 0x37, 0x64, 0x46, 0x43, 0x64, 0x36, + 0x60, 0x65, 0xa6, 0x46, 0x65, 0x86, 0x30, 0x65, 0x56, 0x4b, + 0x65, 0xb6, 0x48, 0x64, 0x36, 0x44, 0x64, 0x66, 0x3d, 0x64, + 0xa6, 0x3a, 0x65, 0xf6, 0x5f, 0x64, 0xe6, 0x52, 0x65, 0x16, + 0x4d, 0x64, 0xf6, 0x37, 0x64, 0xd6, 0x3d, 0x65, 0xe6, 0x24, + 0x64, 0xc6, 0x3f, 0x65, 0xd6, 0x4c, 0x64, 0x06, 0x42, 0x64, + 0x36, 0x43, 0x64, 0x16, 0x50, 0x66, 0x16, 0x49, 0x64, 0xc6, + 0x6a, 0x62, 0x76, 0x3a, 0x65, 0x96, 0x58, 0x66, 0x56, 0x4e, + 0x65, 0x96, 0x60, 0x66, 0x16, 0x49, 0x65, 0x76, 0x48, 0x65, + 0x86, 0x6f, 0x65, 0x46, 0x49, 0x65, 0x26, 0x55, 0x65, 0x46, + 0x54, 0x65, 0x36, 0x58, 0x65, 0x86, 0x4d, 0x65, 0x66, 0x44, + 0x65, 0xa6, 0x68, 0x64, 0x56, 0x42, 0x65, 0x36, 0x41, 0x65, + 0x06, 0x57, 0x63, 0xf6, 0x5a, 0x63, 0x66, 0x5d, 0x64, 0x86, + 0x53, 0x64, 0x56, 0x50, 0x65, 0x66, 0x48, 0x65, 0x06, 0x5c, + 0x66, 0x26, 0x4c, 0x64, 0x16, 0x55, 0x65, 0x26, 0x47, 0x65, + 0xb6, 0x34, 0x63, 0x86, 0x48, 0x64, 0xd6, 0x41, 0x65, 0x76, + 0x6d, 0x63, 0xb6, 0x4b, 0x64, 0xa6, 0x5e, 0x64, 0xf6, 0x4b, + 0x63, 0xf6, 0x43, 0x65, 0xa6, 0x48, 0x66, 0x56, 0x45, 0x65, + 0xf6, 0x41, 0x64, 0xc6, 0x52, 0x64, 0x56, 0x61, 0x64, 0x76, + 0x48, 0x63, 0xf6, 0x4d, 0x65, 0xe6, 0x44, 0x64, 0xd6, 0x5e, + 0x65, 0x66, 0x44, 0x65, 0xb6, 0x5b, 0x64, 0xb6, 0x3c, 0x64, + 0x26, 0x49, 0x64, 0x96, 0x54, 0x65, 0xf6, 0x4c, 0x65, 0xa6, + 0x48, 0x64, 0xd6, 0x50, 0x64, 0xb6, 0x4f, 0x64, 0xc6, 0x3e, + 0x66, 0x06, 0x3c, 0x65, 0x46, 0x50, 0x63, 0xb6, 0x58, 0x64, + 0xf6, 0x50, 0x65, 0x16, 0x3d, 0x64, 0xa6, 0x44, 0x66, 0x06, + 0x62, 0x66, 0x36, 0x63, 0x65, 0xd6, 0x61, 0x65, 0x76, 0x44, + 0x65, 0x56, 0x49, 0x64, 0xa6, 0x61, 0x65, 0xc6, 0x50, 0x64, + 0xf6, 0x60, 0x65, 0x36, 0x59, 0x64, 0xc6, 0x49, 0x65, 0x26, + 0x63, 0x63, 0xf6, 0x55, 0x64, 0xe6, 0x51, 0x66, 0x46, 0x4d, + 0x66, 0x06, 0x50, 0x64, 0xd6, 0x51, 0x64, 0xc6, 0x5a, 0x64, + 0x06, 0x59, 0x65, 0xa6, 0x5d, 0x63, 0x16, 0x38, 0x65, 0x86, + 0x3f, 0x64, 0x36, 0x45, 0x64, 0xe6, 0x5a, 0x64, 0xa6, 0x4a, + 0x64, 0xb6, 0x3c, 0x63, 0xe6, 0x4d, 0x64, 0x06, 0x46, 0x64, + 0x96, 0x5e, 0x65, 0x06, 0x4e, 0x65, 0xa6, 0x43, 0x64, 0xc6, + 0x50, 0x63, 0xf6, 0x4f, 0x65, 0x06, 0x41, 0x64, 0x16, 0x22, + 0x65, 0xf6, 0x62, 0x64, 0x26, 0x4e, 0x63, 0x76, 0x52, 0x63, + 0xa6, 0x57, 0x64, 0x56, 0x62, 0x66, 0x46, 0x50, 0x65, 0x86, + 0x4e, 0x63, 0xc6, 0x55, 0x64, 0xc6, 0x57, 0x64, 0x26, 0x5e, + 0x65, 0x16, 0x4b, 0x65, 0xd6, 0x3f, 0x66, 0x16, 0x37, 0x65, + 0xf6, 0x4c, 0x64, 0x26, 0x4e, 0x65, 0x06, 0x63, 0x65, 0x16, + 0x44, 0x63, 0x86, 0x53, 0x66, 0x66, 0x3a, 0x64, 0xc6, 0x37, + 0x65, 0x26, 0x56, 0x66, 0x56, 0x53, 0x64, 0x66, 0x56, 0x65, + 0x96, 0x60, 0x63, 0x96, 0x5a, 0x66, 0x16, 0x42, 0x65, 0x76, + 0x3e, 0x64, 0x86, 0x58, 0x64, 0xe6, 0x54, 0x63, 0x46, 0x4e, + 0x66, 0x46, 0x67, 0x66, 0x86, 0x67, 0x24, 0x11, 0xb6, 0x2b, + 0x50, 0x17, 0x03, 0x00, 0x00, 0x01, 0x75, 0x21, 0x00, 0x00, + 0x98, 0x01, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x64, 0x56, 0x38, 0x64, 0x76, 0x2a, + 0x65, 0x96, 0x50, 0x63, 0xc6, 0x3d, 0x63, 0xe6, 0x3d, 0x65, + 0x16, 0x3a, 0x64, 0x06, 0x56, 0x62, 0xf6, 0x37, 0x63, 0xb6, + 0x4b, 0x62, 0xa6, 0x52, 0x64, 0xc6, 0x3a, 0x63, 0xc6, 0x60, + 0x64, 0x76, 0x2b, 0x63, 0x46, 0x2c, 0x63, 0xb6, 0x3a, 0x65, + 0x86, 0x2d, 0x62, 0xb6, 0x24, 0x64, 0x46, 0x47, 0x63, 0xf6, + 0x38, 0x63, 0x86, 0x59, 0x62, 0xa6, 0x38, 0x64, 0x06, 0x3d, + 0x64, 0xf6, 0x43, 0x63, 0x96, 0x37, 0x63, 0x46, 0x45, 0x64, + 0x06, 0x2d, 0x60, 0xb6, 0x19, 0x65, 0x06, 0x9d, 0x67, 0x36, + 0x57, 0x63, 0xa6, 0x14, 0x61, 0xf6, 0x15, 0x64, 0x56, 0x3c, + 0x64, 0x66, 0x3b, 0x63, 0x36, 0x40, 0x63, 0x26, 0x4c, 0x65, + 0x16, 0x49, 0x64, 0xc6, 0x50, 0x64, 0x76, 0x44, 0x63, 0xf6, + 0x49, 0x63, 0x56, 0x35, 0x63, 0x66, 0x47, 0x63, 0xc6, 0x2e, + 0x63, 0x36, 0x4c, 0x63, 0xb6, 0x4e, 0x64, 0xc6, 0x4e, 0x63, + 0xc6, 0x34, 0x63, 0x76, 0x4d, 0x65, 0x26, 0x22, 0x63, 0x86, + 0x3a, 0x62, 0x76, 0x50, 0x65, 0x56, 0x57, 0x61, 0xe5, 0x61, + 0x42, 0xc3, 0x93, 0x40, 0xf4, 0xe9, 0x5b, 0x76, 0x2b, 0x63, + 0xf6, 0x31, 0x61, 0xb6, 0x3a, 0x64, 0x06, 0x49, 0x64, 0x16, + 0x48, 0x65, 0x06, 0x53, 0x63, 0xc6, 0x58, 0x64, 0xb6, 0x62, + 0x65, 0x66, 0x3d, 0x64, 0xe6, 0x2f, 0x64, 0x46, 0x40, 0x64, + 0x96, 0x5f, 0x65, 0x46, 0x37, 0x64, 0x46, 0x43, 0x64, 0x36, + 0x60, 0x65, 0xa6, 0x46, 0x65, 0x86, 0x30, 0x65, 0x56, 0x4b, + 0x65, 0xb6, 0x48, 0x64, 0x36, 0x44, 0x64, 0x66, 0x3d, 0x64, + 0xa6, 0x3a, 0x65, 0xf6, 0x5f, 0x64, 0xe6, 0x52, 0x65, 0x16, + 0x4d, 0x64, 0xf6, 0x37, 0x64, 0xd6, 0x3d, 0x65, 0xe6, 0x24, + 0x64, 0xc6, 0x3f, 0x65, 0xd6, 0x4c, 0x64, 0x06, 0x42, 0x64, + 0x36, 0x43, 0x64, 0x16, 0x50, 0x66, 0x16, 0x49, 0x64, 0xc6, + 0x6a, 0x62, 0x76, 0x3a, 0x65, 0x96, 0x58, 0x66, 0x56, 0x4e, + 0x65, 0x96, 0x60, 0x66, 0x16, 0x49, 0x65, 0x76, 0x48, 0x65, + 0x86, 0x6f, 0x65, 0x46, 0x49, 0x65, 0x26, 0x55, 0x65, 0x46, + 0x54, 0x65, 0x36, 0x58, 0x65, 0x86, 0x4d, 0x65, 0x66, 0x44, + 0x65, 0xa6, 0x68, 0x64, 0x56, 0x42, 0x65, 0x36, 0x41, 0x65, + 0x06, 0x57, 0x63, 0xf6, 0x5a, 0x63, 0x66, 0x5d, 0x64, 0x86, + 0x53, 0x64, 0x56, 0x50, 0x65, 0x66, 0x48, 0x65, 0x06, 0x5c, + 0x66, 0x26, 0x4c, 0x64, 0x16, 0x55, 0x65, 0x26, 0x47, 0x65, + 0xb6, 0x34, 0x63, 0x86, 0x48, 0x64, 0xd6, 0x41, 0x65, 0x76, + 0x6d, 0x63, 0xb6, 0x4b, 0x64, 0xa6, 0x5e, 0x64, 0xf6, 0x4b, + 0x63, 0xf6, 0x43, 0x65, 0xa6, 0x48, 0x66, 0x56, 0x45, 0x65, + 0xf6, 0x41, 0x64, 0xc6, 0x52, 0x64, 0x56, 0x61, 0x64, 0x76, + 0x48, 0x63, 0xf6, 0x4d, 0x65, 0xe6, 0x44, 0x64, 0xd6, 0x5e, + 0x65, 0x66, 0x44, 0x65, 0xb6, 0x5b, 0x64, 0xb6, 0x3c, 0x64, + 0x26, 0x49, 0x64, 0x96, 0x54, 0x65, 0xf6, 0x4c, 0x65, 0xa6, + 0x48, 0x64, 0xd6, 0x50, 0x64, 0xb6, 0x4f, 0x64, 0xc6, 0x3e, + 0x66, 0x06, 0x3c, 0x65, 0x46, 0x50, 0x63, 0xb6, 0x58, 0x64, + 0xf6, 0x50, 0x65, 0x16, 0x3d, 0x64, 0xa6, 0x44, 0x66, 0x06, + 0x62, 0x66, 0x36, 0x63, 0x65, 0xd6, 0x61, 0x65, 0x76, 0x44, + 0x65, 0x56, 0x49, 0x64, 0xa6, 0x61, 0x65, 0xc6, 0x50, 0x64, + 0xf6, 0x60, 0x65, 0x36, 0x59, 0x64, 0xc6, 0x49, 0x65, 0x26, + 0x63, 0x63, 0xf6, 0x55, 0x64, 0xe6, 0x51, 0x66, 0x46, 0x4d, + 0x66, 0x06, 0x50, 0x64, 0xd6, 0x51, 0x64, 0xc6, 0x5a, 0x64, + 0x06, 0x59, 0x65, 0xa6, 0x5d, 0x63, 0x16, 0x38, 0x65, 0x86, + 0x3f, 0x64, 0x36, 0x45, 0x64, 0xe6, 0x5a, 0x64, 0xa6, 0x4a, + 0x64, 0xb6, 0x3c, 0x63, 0xe6, 0x4d, 0x64, 0x06, 0x46, 0x64, + 0x96, 0x5e, 0x65, 0x06 +}; + +#endif // __FAKE_DATA__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,303 @@ +#include "mbed.h" + +#include "SDFileSystem.h" +#include "TCPSocketConnection.h" +#include "EthernetInterface.h" +#include "string" +#include "fakeData.h" + +//#define DEBUG // turn on debug output if defined (note this slows down processing due to serial baud rate!) +//#define PRINT_DOIO_RESULT // print the number of bytes DoIO returns + +// if this is defined, read files starting with "S" from the SD card +// otherwise use the fake data in fakeData.h (from memory) +//#define USE_DATA_FROM_SD + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +static const char* kRserv = "128.195.204.151"; +static const unsigned short kRport = 6666; + +static const char* kMyIp = "128.195.204.148"; +static const char* kMyMask = "255.255.255.0"; +static const char* kMyGate = "128.195.204.1"; + +static const unsigned int kBSTime = 946684800u; // 1/1/2000 00:00:00 UTC +static const int kSecsPerDay = 3600*24; +static const int kBuffSize = 1024; +// all chunks must be smaller than kBuffSize +static const int kNCsizes = 5; +static const int gChunkSize[kNCsizes] = { 9, 26, 711, 40, 432 }; +static const int kTotFakeDat = 2097152; // if sending fake data, send 2 MB total +static const int kTimeout = 300; // seconds + +static const char* kSDsubDir = "/sd"; +static const char* kFileTag = "S"; // send files starting with this tag + +static char gBuff[kBuffSize]; +static SDFileSystem sd(p5, p6, p7, p8, kSDsubDir+1); +static LocalFileSystem local("local"); +static EthernetInterface* gEth(0); +static TCPSocketConnection* gSock(0); +static Serial gCpu( USBTX, USBRX ); + +// function pointer to send, receive, etc +typedef int (TCPSocketConnection::*TCPSendRecv)(char*, int); +#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) + +// forward declarations +bool Connect(const int timeout); +void SendData(FILE* inf, const int timeout); +FILE* OpenSDFile(const char* name, const char* mode); +void SendAllFakeData(const int totalBytes, const int timeout); +void SendAllFiles(const int timeout); +bool IsTimedOut(const int timeout_clock); +void dispStrBytes(const char* const s, const int len); +int DoIO(char* const data, + const int length, + const int timeout_clock, + TCPSendRecv fcn); +int ReceiveAll(char* const buf, const int mlen, const int timeout_clock); +int SendAll(char* const data, const int length, const int timeout_clock); + + +int main() { + led1=1; + set_time(kBSTime); + if (Connect(time(0)+kTimeout)) { + led2=1; +#ifdef USE_DATA_FROM_SD + SendAllFiles(time(0)+kTimeout); +#else + SendAllFakeData(kTotFakeDat, time(0)+kTimeout); +#endif + } else { + led4=1; + } + if (gSock!=0) { + gSock->close(); + } + if (gEth!=0) { + gEth->disconnect(); + } + while (true) { + led1=0; wait(0.5); led1=1; wait(0.5); + } +} + +bool Connect(const int timeout) { + +#ifdef DEBUG + printf("Connect\r\n"); +#endif + + gEth = new EthernetInterface; + gSock = new TCPSocketConnection; + + gEth->init(kMyIp, kMyMask, kMyGate); + + bool isConn = false; + + while ( (isConn==false) && (IsTimedOut(timeout)==false) ) { + wait_ms(250); + isConn = (gEth->connect()==0); + } +#ifdef DEBUG + printf("eth isConn=%d\r\n",(int)isConn); +#endif + + isConn=false; + while ( (isConn==false) && (IsTimedOut(timeout)==false) ) { + wait_ms(250); + isConn = (gSock->connect(kRserv, kRport)==0); + } +#ifdef DEBUG + printf("sock isConn=%d\r\n",(int)isConn); +#endif + return isConn; +} + +void SendAllFakeData(const int totalBytes, const int timeout) { + // send the fake data in chunks + + const int* const csend = gChunkSize + kNCsizes; + const int* cs = gChunkSize; + + int br=0; // bytes read/sent so far + int tcs=0; // this chunk size + while ( br<totalBytes ) { + + // read a chunk + tcs = (*cs < kFakeDataSize) ? (*cs) : kFakeDataSize; + memcpy(gBuff, gFakeData, tcs); + + // send this chunk + br += SendAll(gBuff, tcs, timeout); + + // change chunk size + ++cs; + if (cs==csend) { + cs = gChunkSize; + } + } +} + +void SendData(FILE* inf, const int timeout) { + // send the SD card data in chunks + + // store position in file so we can go back to it afterwards + const int fpos = ftell(inf); + if (fpos>0) { + fseek(inf, 0, SEEK_SET); + } + // how many bytes? + fseek(inf, 0, SEEK_END); // go to end + const int fend = ftell(inf); + fseek(inf, 0, SEEK_SET); // go to start +#ifdef DEBUG + printf("fend=%d\r\n",fend); + printf("fpos=%d\r\n",fpos); +#endif + + const int* const csend = gChunkSize + kNCsizes; + const int* cs = gChunkSize; + + int br=0; // bytes read/sent so far + int tcs=0; // this chunk size + while ( br<fend ) { + + // read a chunk or the remainder of the file + tcs = ((br+(*cs))<fend) ? (*cs) : (fend-br); + fread(gBuff, tcs, 1, inf); + + // send this chunk + br += SendAll(gBuff, tcs, timeout); + + // change chunk size + ++cs; + if (cs==csend) { + cs = gChunkSize; + } + } + +} + +FILE* OpenSDFile(const char* name, const char* mode) { + // TODO: check if we have memory? + std::string fn(name); + if (strncmp(name, kSDsubDir, strlen(kSDsubDir))!=0) { + // filename lacks directory + fn = kSDsubDir; + fn += "/"; + fn += name; + } +#ifdef DEBUG + printf("OpenSDFile: %s, mode %s\r\n",fn.c_str(),mode); +#endif + return fopen(fn.c_str(), mode); +} + +void SendAllFiles(const int timeout) { + + DIR* d; + struct dirent* dent; + + if ( (d = opendir( kSDsubDir ))!=NULL ) { + FILE* f; + while ( (dent = readdir(d))!=NULL ) { + if (strncmp(dent->d_name, kFileTag, strlen(kFileTag))==0) { + f = OpenSDFile(dent->d_name, "rb"); + SendAll(dent->d_name, strlen(dent->d_name), timeout); + SendData(f, timeout); + fclose(f); + } + } + closedir(d); + } +} + +bool IsTimedOut(const int timeout_clock) { + if (timeout_clock==0) { + // for not obeying timeout option + return false; + } else { + const int ct = time(0); + if ( (ct==0) || + (abs(static_cast<double>(timeout_clock-ct))>kSecsPerDay) ) { + // clock problems! timeout now. +#ifdef DEBUG + printf("clock problem. timing out\r\n"); +#endif + return true; + } else { + const bool rt = (ct>timeout_clock); +#ifdef DEBUG + if (rt) { + printf("timing out.\r\n"); + } +#endif + return rt; + } + } +} + +void dispStrBytes(const char* const s, const int len) { + const char* c = s; + for (int i=0; i<len; ++i, ++c) { + if (*c>0x1F && *c<0x7F) { + printf("%c", *c); + } else { + printf(".x%02x.", *c); + } + } +} + +int DoIO(char* const data, + const int length, + const int timeout_clock, + TCPSendRecv fcn) { + // TODO: if B64, must return number of bytes of raw (non encoded) message +#ifdef DEBUG + printf("DoIO data:\r\n"); + dispStrBytes(data, length); + printf("\r\n"); +#endif + int res=0; + int b=0; + while ( (length>b) ) { + if (IsTimedOut(timeout_clock)) { +#ifdef DEBUG + printf("DoIO timing out\r\n"); +#endif + break; + } + res = CALL_MEMBER_FN(*gSock, fcn)(data+b, length-b); + switch (res) { + case -1: + // TODO: how to check the error? + continue; + case 0: + return res; + default: + b += res; + }; + //wait_ms(100); + } +#if defined(DEBUG) || defined(PRINT_DOIO_RESULT) + printf("return b=%d\r\n",b); +#endif + return b; // timeout +} + +int ReceiveAll(char* const buf, const int mlen, const int timeout_clock) { + // use regular receive; DoIO will do a receive_all but use our timeout + return DoIO(buf, mlen, timeout_clock, &TCPSocketConnection::receive); +} + +int SendAll(char* const data, const int length, const int timeout_clock) { + // use regular send; DoIO will do a send_all but use our timeout + return DoIO(data, length, timeout_clock, &TCPSocketConnection::send); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#9654a71f5a90
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Sep 22 04:01:27 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/cd19af002ccc \ No newline at end of file