Program the control the fischertechnik robo interface or intelligent interface via tcp socket or via a java gui.
ftserver.cpp@0:7f26f0680202, 2010-12-31 (annotated)
- Committer:
- networker
- Date:
- Fri Dec 31 14:01:14 2010 +0000
- Revision:
- 0:7f26f0680202
- Child:
- 1:2c9d412ad471
initial release: comprises ftlib (no usb), ft-over-ip socket server, and the http server (the html page and java jar I still have to publish somewhere)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
networker | 0:7f26f0680202 | 1 | #include "mbed.h" |
networker | 0:7f26f0680202 | 2 | #include "EthernetNetIf.h" |
networker | 0:7f26f0680202 | 3 | #include "HTTPServer.h" |
networker | 0:7f26f0680202 | 4 | #include "ft.h" |
networker | 0:7f26f0680202 | 5 | #include "ftserver.h" |
networker | 0:7f26f0680202 | 6 | #include "debug.h" |
networker | 0:7f26f0680202 | 7 | #define MBED |
networker | 0:7f26f0680202 | 8 | #include "ftlib.h" |
networker | 0:7f26f0680202 | 9 | |
networker | 0:7f26f0680202 | 10 | |
networker | 0:7f26f0680202 | 11 | ftServer::ftServer(IpAddr host, unsigned short port) { |
networker | 0:7f26f0680202 | 12 | err = listeningSock.bind(Host(host, port)); |
networker | 0:7f26f0680202 | 13 | if (err) { |
networker | 0:7f26f0680202 | 14 | DBG("Binding failed!\n"); |
networker | 0:7f26f0680202 | 15 | errorMsg(); |
networker | 0:7f26f0680202 | 16 | return; |
networker | 0:7f26f0680202 | 17 | } |
networker | 0:7f26f0680202 | 18 | DBG("Bound to host\n"); |
networker | 0:7f26f0680202 | 19 | viaUsb.printf("listening on port %d\n", port); |
networker | 0:7f26f0680202 | 20 | listeningSock.setOnEvent(this, &ftServer::onTCPEvent); |
networker | 0:7f26f0680202 | 21 | index = 0; |
networker | 0:7f26f0680202 | 22 | isMsg = false; |
networker | 0:7f26f0680202 | 23 | text = 0; |
networker | 0:7f26f0680202 | 24 | } |
networker | 0:7f26f0680202 | 25 | |
networker | 0:7f26f0680202 | 26 | void ftServer::errorMsg() { |
networker | 0:7f26f0680202 | 27 | switch (err) { |
networker | 0:7f26f0680202 | 28 | case __TCPSOCKET_MIN: |
networker | 0:7f26f0680202 | 29 | DBG("Err: MIN"); |
networker | 0:7f26f0680202 | 30 | break; |
networker | 0:7f26f0680202 | 31 | case TCPSOCKET_SETUP: |
networker | 0:7f26f0680202 | 32 | DBG("Err:TCPSocket not properly configured"); |
networker | 0:7f26f0680202 | 33 | break; |
networker | 0:7f26f0680202 | 34 | case TCPSOCKET_TIMEOUT: |
networker | 0:7f26f0680202 | 35 | DBG("Err:Connection timed out"); |
networker | 0:7f26f0680202 | 36 | break; |
networker | 0:7f26f0680202 | 37 | case TCPSOCKET_IF: |
networker | 0:7f26f0680202 | 38 | DBG("Err:Interface has problems, does not exist or is not initialized"); |
networker | 0:7f26f0680202 | 39 | break; |
networker | 0:7f26f0680202 | 40 | case TCPSOCKET_MEM: |
networker | 0:7f26f0680202 | 41 | DBG("Err:Not enough mem"); |
networker | 0:7f26f0680202 | 42 | break; |
networker | 0:7f26f0680202 | 43 | case TCPSOCKET_INUSE: |
networker | 0:7f26f0680202 | 44 | DBG("Err:Interface / Port is in use"); |
networker | 0:7f26f0680202 | 45 | break; |
networker | 0:7f26f0680202 | 46 | case TCPSOCKET_EMPTY: |
networker | 0:7f26f0680202 | 47 | DBG("Err:Connections queue is empty"); |
networker | 0:7f26f0680202 | 48 | break; |
networker | 0:7f26f0680202 | 49 | case TCPSOCKET_RST: |
networker | 0:7f26f0680202 | 50 | DBG("Err:Connection was reset by remote host"); |
networker | 0:7f26f0680202 | 51 | break; |
networker | 0:7f26f0680202 | 52 | case TCPSOCKET_OK: |
networker | 0:7f26f0680202 | 53 | DBG("Err:Success"); |
networker | 0:7f26f0680202 | 54 | break; |
networker | 0:7f26f0680202 | 55 | default: |
networker | 0:7f26f0680202 | 56 | DBG("Err:Unknown"); |
networker | 0:7f26f0680202 | 57 | } |
networker | 0:7f26f0680202 | 58 | DBG("\r\n"); |
networker | 0:7f26f0680202 | 59 | } |
networker | 0:7f26f0680202 | 60 | |
networker | 0:7f26f0680202 | 61 | void ftServer::onTCPEvent(TCPSocketEvent ev) { |
networker | 0:7f26f0680202 | 62 | Host client; |
networker | 0:7f26f0680202 | 63 | TCPSocket *pConnectedSock; |
networker | 0:7f26f0680202 | 64 | switch (ev) { |
networker | 0:7f26f0680202 | 65 | case TCPSOCKET_ACCEPT: |
networker | 0:7f26f0680202 | 66 | DBG("Accept event\r\n"); |
networker | 0:7f26f0680202 | 67 | err = listeningSock.accept(&client, &pConnectedSock); |
networker | 0:7f26f0680202 | 68 | if (err) { |
networker | 0:7f26f0680202 | 69 | DBG("accept failed!\r\n"); |
networker | 0:7f26f0680202 | 70 | errorMsg(); |
networker | 0:7f26f0680202 | 71 | return; //Could not accept client |
networker | 0:7f26f0680202 | 72 | } |
networker | 0:7f26f0680202 | 73 | DBG("Accepted\r\n"); |
networker | 0:7f26f0680202 | 74 | queue.push_back(new connection(this, client, pConnectedSock)); |
networker | 0:7f26f0680202 | 75 | break; |
networker | 0:7f26f0680202 | 76 | default: |
networker | 0:7f26f0680202 | 77 | DBG("listenSocket other event\r\n"); |
networker | 0:7f26f0680202 | 78 | break; |
networker | 0:7f26f0680202 | 79 | } |
networker | 0:7f26f0680202 | 80 | } |
networker | 0:7f26f0680202 | 81 | |
networker | 0:7f26f0680202 | 82 | void ftServer::remove(connection *c) { |
networker | 0:7f26f0680202 | 83 | queue.remove(c); |
networker | 0:7f26f0680202 | 84 | delete c; |
networker | 0:7f26f0680202 | 85 | int n = 0; |
networker | 0:7f26f0680202 | 86 | char s[40]; |
networker | 0:7f26f0680202 | 87 | for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) { |
networker | 0:7f26f0680202 | 88 | sprintf(s, "You are in position %d in the queue", n++); |
networker | 0:7f26f0680202 | 89 | (*i)->writeStream(s); |
networker | 0:7f26f0680202 | 90 | } |
networker | 0:7f26f0680202 | 91 | } |
networker | 0:7f26f0680202 | 92 | |
networker | 0:7f26f0680202 | 93 | bool ftServer::startServer() { |
networker | 0:7f26f0680202 | 94 | err = listeningSock.listen(); //Starts listening |
networker | 0:7f26f0680202 | 95 | if (err) { |
networker | 0:7f26f0680202 | 96 | DBG("listen failed!\n"); |
networker | 0:7f26f0680202 | 97 | errorMsg(); |
networker | 0:7f26f0680202 | 98 | return false; |
networker | 0:7f26f0680202 | 99 | } |
networker | 0:7f26f0680202 | 100 | DBG("listen OK\t"); |
networker | 0:7f26f0680202 | 101 | return true; |
networker | 0:7f26f0680202 | 102 | } |
networker | 0:7f26f0680202 | 103 | /* |
networker | 0:7f26f0680202 | 104 | void ftServer::pollServer() { |
networker | 0:7f26f0680202 | 105 | Net::poll(); |
networker | 0:7f26f0680202 | 106 | } |
networker | 0:7f26f0680202 | 107 | */ |
networker | 0:7f26f0680202 | 108 | char* ftServer::render() { |
networker | 0:7f26f0680202 | 109 | static char text[40]; |
networker | 0:7f26f0680202 | 110 | sprintf(text, "%02X %02X %02X %02X %02X %02X %02X; ", msg[0],msg[1],msg[2],msg[3],msg[4],msg[5],msg[6]); |
networker | 0:7f26f0680202 | 111 | return text; |
networker | 0:7f26f0680202 | 112 | } |
networker | 0:7f26f0680202 | 113 | |
networker | 0:7f26f0680202 | 114 | #if 1 |
networker | 0:7f26f0680202 | 115 | bool ftServer::readStream(TCPSocket *pConnectedSock) { |
networker | 0:7f26f0680202 | 116 | char c; |
networker | 0:7f26f0680202 | 117 | if (pConnectedSock != queue.front()->socket()) { |
networker | 0:7f26f0680202 | 118 | char flush[7]; |
networker | 0:7f26f0680202 | 119 | pConnectedSock->recv(flush, sizeof(flush)); |
networker | 0:7f26f0680202 | 120 | return false; |
networker | 0:7f26f0680202 | 121 | } |
networker | 0:7f26f0680202 | 122 | while (!isMsg) { |
networker | 0:7f26f0680202 | 123 | if (pConnectedSock->recv(&c, 1) == 0) { |
networker | 0:7f26f0680202 | 124 | DBG("NoData "); |
networker | 0:7f26f0680202 | 125 | return false; //no data available |
networker | 0:7f26f0680202 | 126 | } |
networker | 0:7f26f0680202 | 127 | isMsg = c == 0x90;//start of message |
networker | 0:7f26f0680202 | 128 | if (isMsg) {//potentially we are at the start of a message |
networker | 0:7f26f0680202 | 129 | msg[0] = c; //0x90 |
networker | 0:7f26f0680202 | 130 | DBG(" SOM "); |
networker | 0:7f26f0680202 | 131 | index = 1; |
networker | 0:7f26f0680202 | 132 | if (text) { |
networker | 0:7f26f0680202 | 133 | DBG(text); |
networker | 0:7f26f0680202 | 134 | delete[] text; |
networker | 0:7f26f0680202 | 135 | text = 0; |
networker | 0:7f26f0680202 | 136 | } |
networker | 0:7f26f0680202 | 137 | break; |
networker | 0:7f26f0680202 | 138 | } |
networker | 0:7f26f0680202 | 139 | //text |
networker | 0:7f26f0680202 | 140 | if (text == 0) { |
networker | 0:7f26f0680202 | 141 | textlen = c;//potential length of the string |
networker | 0:7f26f0680202 | 142 | text = new char[textlen+1]; |
networker | 0:7f26f0680202 | 143 | index = 0; |
networker | 0:7f26f0680202 | 144 | DBG("STX "); |
networker | 0:7f26f0680202 | 145 | } else { |
networker | 0:7f26f0680202 | 146 | text[index++] = c; |
networker | 0:7f26f0680202 | 147 | DBG("+"); |
networker | 0:7f26f0680202 | 148 | } |
networker | 0:7f26f0680202 | 149 | if (index == textlen) { //assume the entire string was read |
networker | 0:7f26f0680202 | 150 | text[index] = '\0'; |
networker | 0:7f26f0680202 | 151 | DBG(text); |
networker | 0:7f26f0680202 | 152 | DBG(" ETX "); |
networker | 0:7f26f0680202 | 153 | // if (s == "QUIT") |
networker | 0:7f26f0680202 | 154 | // return false;//in-band signalling, not used |
networker | 0:7f26f0680202 | 155 | delete[] text; |
networker | 0:7f26f0680202 | 156 | text = 0; |
networker | 0:7f26f0680202 | 157 | return false;//text messages are ignored |
networker | 0:7f26f0680202 | 158 | } |
networker | 0:7f26f0680202 | 159 | } |
networker | 0:7f26f0680202 | 160 | index += pConnectedSock->recv(msg+index, sizeof(msg) - index); |
networker | 0:7f26f0680202 | 161 | if (index >= sizeof(msg)) { |
networker | 0:7f26f0680202 | 162 | DBG(render()); |
networker | 0:7f26f0680202 | 163 | isMsg = false; //start over on the presumption of text |
networker | 0:7f26f0680202 | 164 | DBG(" EOM\r\n"); |
networker | 0:7f26f0680202 | 165 | return true; //message is ready |
networker | 0:7f26f0680202 | 166 | } |
networker | 0:7f26f0680202 | 167 | DBG("-"); |
networker | 0:7f26f0680202 | 168 | return false; |
networker | 0:7f26f0680202 | 169 | } |
networker | 0:7f26f0680202 | 170 | #else |
networker | 0:7f26f0680202 | 171 | bool ftServer::readStream() { |
networker | 0:7f26f0680202 | 172 | char c; |
networker | 0:7f26f0680202 | 173 | while (pConnectedSock->recv(&c, 1) == 1) { |
networker | 0:7f26f0680202 | 174 | char txt[20]; |
networker | 0:7f26f0680202 | 175 | sprintf(txt, "%02X ", c); |
networker | 0:7f26f0680202 | 176 | DBG(txt); |
networker | 0:7f26f0680202 | 177 | } |
networker | 0:7f26f0680202 | 178 | DBG(";"); |
networker | 0:7f26f0680202 | 179 | return false; |
networker | 0:7f26f0680202 | 180 | } |
networker | 0:7f26f0680202 | 181 | #endif |
networker | 0:7f26f0680202 | 182 | |
networker | 0:7f26f0680202 | 183 | bool ftServer::writeStream(char *s) { |
networker | 0:7f26f0680202 | 184 | for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) |
networker | 0:7f26f0680202 | 185 | (*i)->writeStream(s); |
networker | 0:7f26f0680202 | 186 | return true; |
networker | 0:7f26f0680202 | 187 | } |
networker | 0:7f26f0680202 | 188 | |
networker | 0:7f26f0680202 | 189 | bool ftServer::writeStream(SMESSAGE *m) { |
networker | 0:7f26f0680202 | 190 | for (list<connection*>::iterator i = queue.begin(); i != queue.end(); i++) |
networker | 0:7f26f0680202 | 191 | (*i)->writeStream(m); |
networker | 0:7f26f0680202 | 192 | return true; |
networker | 0:7f26f0680202 | 193 | } |
networker | 0:7f26f0680202 | 194 | |
networker | 0:7f26f0680202 | 195 | void connection::onConnectedTCPSocketEvent(TCPSocketEvent ev) {//called as part of NetPoll |
networker | 0:7f26f0680202 | 196 | switch (ev) { |
networker | 0:7f26f0680202 | 197 | case TCPSOCKET_CONNECTED: |
networker | 0:7f26f0680202 | 198 | DBG("connectedSocket: Connected to host\n\r");//did not happen |
networker | 0:7f26f0680202 | 199 | return; |
networker | 0:7f26f0680202 | 200 | case TCPSOCKET_ACCEPT://should not happen |
networker | 0:7f26f0680202 | 201 | DBG("connectedSocket: Client is connected, must call accept() to get a new Socket\n\r"); |
networker | 0:7f26f0680202 | 202 | return; |
networker | 0:7f26f0680202 | 203 | case TCPSOCKET_READABLE: //this happens when data is received |
networker | 0:7f26f0680202 | 204 | //DBG("connectedSocket: Data in buf\n\r"); |
networker | 0:7f26f0680202 | 205 | if (server->readStream(pConnectedSock)) { |
networker | 0:7f26f0680202 | 206 | //writeStream("received the message"); |
networker | 0:7f26f0680202 | 207 | //writeStream((SMESSAGE*)(msg+1)); |
networker | 0:7f26f0680202 | 208 | server->handleMessage(); |
networker | 0:7f26f0680202 | 209 | } |
networker | 0:7f26f0680202 | 210 | return; |
networker | 0:7f26f0680202 | 211 | case TCPSOCKET_WRITEABLE://this happens |
networker | 0:7f26f0680202 | 212 | //DBG("connectedSocket: Can write data to buf\n\r"); |
networker | 0:7f26f0680202 | 213 | return; |
networker | 0:7f26f0680202 | 214 | case TCPSOCKET_CONTIMEOUT: |
networker | 0:7f26f0680202 | 215 | DBG("connectedSocket: Connection timed out\n\r"); |
networker | 0:7f26f0680202 | 216 | break; |
networker | 0:7f26f0680202 | 217 | case TCPSOCKET_CONRST: |
networker | 0:7f26f0680202 | 218 | DBG("connectedSocket: Connection was reset by remote host\n\r"); |
networker | 0:7f26f0680202 | 219 | break; |
networker | 0:7f26f0680202 | 220 | case TCPSOCKET_CONABRT: |
networker | 0:7f26f0680202 | 221 | DBG("connectedSocket: Connection was aborted\n\r"); |
networker | 0:7f26f0680202 | 222 | break; |
networker | 0:7f26f0680202 | 223 | case TCPSOCKET_ERROR: |
networker | 0:7f26f0680202 | 224 | DBG("connectedSocket: Unknown error\n\r"); |
networker | 0:7f26f0680202 | 225 | break; |
networker | 0:7f26f0680202 | 226 | case TCPSOCKET_DISCONNECTED://this happens |
networker | 0:7f26f0680202 | 227 | DBG("connectedSocket: Disconnected\n\r"); |
networker | 0:7f26f0680202 | 228 | break; |
networker | 0:7f26f0680202 | 229 | default: |
networker | 0:7f26f0680202 | 230 | DBG("connectedSocket: Unknown event\r\n"); |
networker | 0:7f26f0680202 | 231 | return; |
networker | 0:7f26f0680202 | 232 | } |
networker | 0:7f26f0680202 | 233 | //disconnected socket |
networker | 0:7f26f0680202 | 234 | server->remove(this); |
networker | 0:7f26f0680202 | 235 | } |
networker | 0:7f26f0680202 | 236 | |
networker | 0:7f26f0680202 | 237 | 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 |
networker | 0:7f26f0680202 | 238 | if (!pConnectedSock) |
networker | 0:7f26f0680202 | 239 | return false; |
networker | 0:7f26f0680202 | 240 | char l = strlen(s); |
networker | 0:7f26f0680202 | 241 | while (pConnectedSock->send(&l, 1)==0); |
networker | 0:7f26f0680202 | 242 | while (strlen(s)) |
networker | 0:7f26f0680202 | 243 | s += pConnectedSock->send(s, strlen(s)); |
networker | 0:7f26f0680202 | 244 | return true; |
networker | 0:7f26f0680202 | 245 | } |
networker | 0:7f26f0680202 | 246 | |
networker | 0:7f26f0680202 | 247 | 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 |
networker | 0:7f26f0680202 | 248 | if (!pConnectedSock) |
networker | 0:7f26f0680202 | 249 | return false; |
networker | 0:7f26f0680202 | 250 | char header = 0x90; |
networker | 0:7f26f0680202 | 251 | char l = 6; |
networker | 0:7f26f0680202 | 252 | char i = 0; |
networker | 0:7f26f0680202 | 253 | while (pConnectedSock->send(&header, 1)==0); |
networker | 0:7f26f0680202 | 254 | while (i<l) |
networker | 0:7f26f0680202 | 255 | i += pConnectedSock->send((char*)m+i, l-i); |
networker | 0:7f26f0680202 | 256 | return true; |
networker | 0:7f26f0680202 | 257 | } |