Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface FatFileSystemCpp SDFileSystem mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:53afc51b78a9
- Child:
- 1:6b90cbfe0c9e
diff -r 000000000000 -r 53afc51b78a9 main.cpp
--- /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);
+}