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