Program the control the fischertechnik robo interface or intelligent interface via tcp socket or via a java gui.
Diff: ftserver.cpp
- Revision:
- 0:7f26f0680202
- Child:
- 1:2c9d412ad471
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ftserver.cpp Fri Dec 31 14:01:14 2010 +0000 @@ -0,0 +1,257 @@ +#include "mbed.h" +#include "EthernetNetIf.h" +#include "HTTPServer.h" +#include "ft.h" +#include "ftserver.h" +#include "debug.h" +#define MBED +#include "ftlib.h" + + +ftServer::ftServer(IpAddr host, unsigned short port) { + err = listeningSock.bind(Host(host, port)); + if (err) { + DBG("Binding failed!\n"); + errorMsg(); + return; + } + DBG("Bound to host\n"); + viaUsb.printf("listening on port %d\n", port); + listeningSock.setOnEvent(this, &ftServer::onTCPEvent); + index = 0; + isMsg = false; + text = 0; +} + +void ftServer::errorMsg() { + switch (err) { + case __TCPSOCKET_MIN: + DBG("Err: MIN"); + break; + case TCPSOCKET_SETUP: + DBG("Err:TCPSocket not properly configured"); + break; + case TCPSOCKET_TIMEOUT: + DBG("Err:Connection timed out"); + break; + case TCPSOCKET_IF: + DBG("Err:Interface has problems, does not exist or is not initialized"); + break; + case TCPSOCKET_MEM: + DBG("Err:Not enough mem"); + break; + case TCPSOCKET_INUSE: + DBG("Err:Interface / Port is in use"); + break; + case TCPSOCKET_EMPTY: + DBG("Err:Connections queue is empty"); + break; + case TCPSOCKET_RST: + DBG("Err:Connection was reset by remote host"); + break; + case TCPSOCKET_OK: + DBG("Err:Success"); + break; + default: + DBG("Err:Unknown"); + } + DBG("\r\n"); +} + +void ftServer::onTCPEvent(TCPSocketEvent ev) { + Host client; + TCPSocket *pConnectedSock; + switch (ev) { + case TCPSOCKET_ACCEPT: + DBG("Accept event\r\n"); + err = listeningSock.accept(&client, &pConnectedSock); + if (err) { + DBG("accept failed!\r\n"); + errorMsg(); + return; //Could not accept client + } + DBG("Accepted\r\n"); + queue.push_back(new connection(this, client, pConnectedSock)); + break; + default: + DBG("listenSocket other event\r\n"); + break; + } +} + +void ftServer::remove(connection *c) { + queue.remove(c); + delete c; + int n = 0; + char s[40]; + for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) { + sprintf(s, "You are in position %d in the queue", n++); + (*i)->writeStream(s); + } +} + +bool ftServer::startServer() { + err = listeningSock.listen(); //Starts listening + if (err) { + DBG("listen failed!\n"); + errorMsg(); + return false; + } + DBG("listen OK\t"); + return true; +} +/* +void ftServer::pollServer() { + Net::poll(); +} +*/ +char* ftServer::render() { + static char text[40]; + sprintf(text, "%02X %02X %02X %02X %02X %02X %02X; ", msg[0],msg[1],msg[2],msg[3],msg[4],msg[5],msg[6]); + return text; +} + +#if 1 +bool ftServer::readStream(TCPSocket *pConnectedSock) { + char c; + if (pConnectedSock != queue.front()->socket()) { + char flush[7]; + pConnectedSock->recv(flush, sizeof(flush)); + return false; + } + while (!isMsg) { + if (pConnectedSock->recv(&c, 1) == 0) { + DBG("NoData "); + return false; //no data available + } + isMsg = c == 0x90;//start of message + if (isMsg) {//potentially we are at the start of a message + msg[0] = c; //0x90 + DBG(" SOM "); + index = 1; + if (text) { + DBG(text); + delete[] text; + text = 0; + } + break; + } + //text + if (text == 0) { + textlen = c;//potential length of the string + text = new char[textlen+1]; + index = 0; + DBG("STX "); + } else { + text[index++] = c; + DBG("+"); + } + if (index == textlen) { //assume the entire string was read + text[index] = '\0'; + DBG(text); + DBG(" ETX "); +// if (s == "QUIT") +// return false;//in-band signalling, not used + delete[] text; + text = 0; + return false;//text messages are ignored + } + } + index += pConnectedSock->recv(msg+index, sizeof(msg) - index); + if (index >= sizeof(msg)) { + DBG(render()); + isMsg = false; //start over on the presumption of text + DBG(" EOM\r\n"); + return true; //message is ready + } + DBG("-"); + return false; +} +#else +bool ftServer::readStream() { + char c; + while (pConnectedSock->recv(&c, 1) == 1) { + char txt[20]; + sprintf(txt, "%02X ", c); + DBG(txt); + } + DBG(";"); + return false; +} +#endif + +bool ftServer::writeStream(char *s) { + for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) + (*i)->writeStream(s); + return true; +} + +bool ftServer::writeStream(SMESSAGE *m) { + for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) + (*i)->writeStream(m); + return true; +} + +void connection::onConnectedTCPSocketEvent(TCPSocketEvent ev) {//called as part of NetPoll + switch (ev) { + case TCPSOCKET_CONNECTED: + DBG("connectedSocket: Connected to host\n\r");//did not happen + return; + case TCPSOCKET_ACCEPT://should not happen + DBG("connectedSocket: Client is connected, must call accept() to get a new Socket\n\r"); + return; + case TCPSOCKET_READABLE: //this happens when data is received + //DBG("connectedSocket: Data in buf\n\r"); + if (server->readStream(pConnectedSock)) { + //writeStream("received the message"); + //writeStream((SMESSAGE*)(msg+1)); + server->handleMessage(); + } + return; + case TCPSOCKET_WRITEABLE://this happens + //DBG("connectedSocket: Can write data to buf\n\r"); + return; + case TCPSOCKET_CONTIMEOUT: + DBG("connectedSocket: Connection timed out\n\r"); + break; + case TCPSOCKET_CONRST: + DBG("connectedSocket: Connection was reset by remote host\n\r"); + break; + case TCPSOCKET_CONABRT: + DBG("connectedSocket: Connection was aborted\n\r"); + break; + case TCPSOCKET_ERROR: + DBG("connectedSocket: Unknown error\n\r"); + break; + case TCPSOCKET_DISCONNECTED://this happens + DBG("connectedSocket: Disconnected\n\r"); + break; + default: + DBG("connectedSocket: Unknown event\r\n"); + return; + } + //disconnected socket + server->remove(this); +} + +bool connection::writeStream(char *s) {//I'm not sure this works for large or rapid messages because NetPoll is not called, when I call it it may be recursively + if (!pConnectedSock) + return false; + char l = strlen(s); + while (pConnectedSock->send(&l, 1)==0); + while (strlen(s)) + s += pConnectedSock->send(s, strlen(s)); + return true; +} + +bool connection::writeStream(SMESSAGE *m) {//I'm not sure this works for large or rapid messages because NetPoll is not called, when I call it it may be recursively + if (!pConnectedSock) + return false; + char header = 0x90; + char l = 6; + char i = 0; + while (pConnectedSock->send(&header, 1)==0); + while (i<l) + i += pConnectedSock->send((char*)m+i, l-i); + return true; +}