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

Files at this revision

API Documentation at this revision

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

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
FatFileSystemCpp.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
fakeData.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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