-

Dependencies:   EthernetInterface TCPSocket_HelloWorld mbed-rtos mbed

Fork of TCPSocket_HelloWorld by mbed official

Committer:
offroad
Date:
Tue Feb 09 11:56:52 2016 +0000
Revision:
16:22169975b5d8
Parent:
15:10c1be621ad6
initial public release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:bb128f0e952f 1 #include "mbed.h"
donatien 0:bb128f0e952f 2 #include "EthernetInterface.h"
offroad 15:10c1be621ad6 3 LocalFileSystem local("local");
offroad 15:10c1be621ad6 4
offroad 15:10c1be621ad6 5 #define NPORTS 30
offroad 15:10c1be621ad6 6 static char FSM_buf[16];
offroad 15:10c1be621ad6 7 #define FSM_STATE_IDLE 0
offroad 15:10c1be621ad6 8 #define FSM_STATE_READNUM 1
offroad 15:10c1be621ad6 9 static int FSM_state1 = FSM_STATE_IDLE;
offroad 15:10c1be621ad6 10 static int FSM_state2 = 0;
offroad 15:10c1be621ad6 11 static char FSM_cmd = 'x';
offroad 15:10c1be621ad6 12
offroad 16:22169975b5d8 13 static void FSM_reset(){
offroad 16:22169975b5d8 14 FSM_state1 = FSM_STATE_IDLE;
offroad 16:22169975b5d8 15 FSM_state2 = 0;
offroad 16:22169975b5d8 16 FSM_cmd = 'x';
offroad 16:22169975b5d8 17 }
offroad 16:22169975b5d8 18
offroad 16:22169975b5d8 19 static void FSM_handleChar(DigitalOut* gpo, char inputChar, char** bufOut){
offroad 15:10c1be621ad6 20
offroad 15:10c1be621ad6 21 // === handle incoming char ===
offroad 15:10c1be621ad6 22 switch (FSM_state1){
offroad 15:10c1be621ad6 23 case FSM_STATE_IDLE:
offroad 15:10c1be621ad6 24 // === handle new command char ===
offroad 15:10c1be621ad6 25 switch(inputChar){
offroad 15:10c1be621ad6 26 case '+':
offroad 15:10c1be621ad6 27 case '-':
offroad 15:10c1be621ad6 28 case '?':
offroad 15:10c1be621ad6 29 FSM_cmd = inputChar;
offroad 15:10c1be621ad6 30 FSM_state1 = FSM_STATE_READNUM;
offroad 15:10c1be621ad6 31 goto doneCont;
offroad 15:10c1be621ad6 32 default:
offroad 15:10c1be621ad6 33 goto reset;
offroad 15:10c1be621ad6 34 } // switch inputChar
offroad 15:10c1be621ad6 35 goto lockup;
offroad 15:10c1be621ad6 36 case FSM_STATE_READNUM:
offroad 15:10c1be621ad6 37 if (FSM_state2 > 8)
offroad 15:10c1be621ad6 38 goto reset; // too many digits
offroad 15:10c1be621ad6 39
offroad 15:10c1be621ad6 40 if ((inputChar == 32 || inputChar == 9 || inputChar == 13 || inputChar == 10) && (FSM_state2 > 0)){
offroad 15:10c1be621ad6 41 // === got command terminated by whitespace, and at least one digit
offroad 15:10c1be621ad6 42 FSM_buf[FSM_state2] = 0;
offroad 15:10c1be621ad6 43 int ixGpio = atoi(FSM_buf);
offroad 15:10c1be621ad6 44 if (ixGpio < 0 || ixGpio >= NPORTS)
offroad 15:10c1be621ad6 45 goto reset; // invalid port number
offroad 15:10c1be621ad6 46 switch(FSM_cmd){
offroad 15:10c1be621ad6 47 case '+':
offroad 15:10c1be621ad6 48 // === set GPO ===
offroad 15:10c1be621ad6 49 *(gpo+ixGpio) = 1;
offroad 15:10c1be621ad6 50 goto reset; // success
offroad 15:10c1be621ad6 51 case '-':
offroad 15:10c1be621ad6 52 // === clear GPO ===
offroad 15:10c1be621ad6 53 *(gpo+ixGpio) = 0;
offroad 15:10c1be621ad6 54 goto reset; // success
offroad 15:10c1be621ad6 55 case '?':
offroad 15:10c1be621ad6 56 // === query GPO state (verify) ===
offroad 16:22169975b5d8 57 *((*bufOut)++) = *(gpo+ixGpio) ? '1' : '0';
offroad 16:22169975b5d8 58 *((*bufOut)++) = 13;
offroad 16:22169975b5d8 59 *((*bufOut)++) = 10;
offroad 15:10c1be621ad6 60 goto reset; // success
offroad 15:10c1be621ad6 61 default:
offroad 15:10c1be621ad6 62 goto reset; // invalid command byte
offroad 15:10c1be621ad6 63 }
offroad 15:10c1be621ad6 64 }
offroad 15:10c1be621ad6 65
offroad 15:10c1be621ad6 66 if (inputChar >= '0' && inputChar <= '9'){
offroad 15:10c1be621ad6 67 // === append digit ===
offroad 15:10c1be621ad6 68 FSM_buf[FSM_state2++] = inputChar;
offroad 15:10c1be621ad6 69 goto doneCont;
offroad 15:10c1be621ad6 70 }
offroad 15:10c1be621ad6 71
offroad 15:10c1be621ad6 72 // invalid character (not digit)
offroad 15:10c1be621ad6 73 goto reset;
offroad 15:10c1be621ad6 74 default:
offroad 15:10c1be621ad6 75 // === invalid FSM state ===
offroad 15:10c1be621ad6 76 goto lockup;
offroad 15:10c1be621ad6 77 } // switch FSM_state1
offroad 15:10c1be621ad6 78
offroad 16:22169975b5d8 79 // === internal error. Should never be reached. ===
offroad 15:10c1be621ad6 80 lockup:
offroad 15:10c1be621ad6 81 goto lockup;
offroad 15:10c1be621ad6 82
offroad 15:10c1be621ad6 83 // === reset state machine (on completion and any invalid input ===
offroad 15:10c1be621ad6 84 reset:
offroad 16:22169975b5d8 85 FSM_reset();
offroad 15:10c1be621ad6 86
offroad 15:10c1be621ad6 87 doneCont:
offroad 15:10c1be621ad6 88 return;
offroad 15:10c1be621ad6 89 }
donatien 0:bb128f0e952f 90
emilmont 7:65188f4a8c25 91 int main() {
offroad 16:22169975b5d8 92 printf("\r\nLANGPIO server v2.1 20151107 mn\r\n");
offroad 15:10c1be621ad6 93 fflush(stdout);
offroad 15:10c1be621ad6 94 static DigitalOut myGpo[NPORTS] = {
offroad 15:10c1be621ad6 95 DigitalOut(LED1),
offroad 15:10c1be621ad6 96 DigitalOut(LED2),
offroad 15:10c1be621ad6 97 DigitalOut(LED3),
offroad 15:10c1be621ad6 98 DigitalOut(LED4),
offroad 15:10c1be621ad6 99 DigitalOut(p5),
offroad 15:10c1be621ad6 100 DigitalOut(p6),
offroad 15:10c1be621ad6 101 DigitalOut(p7),
offroad 15:10c1be621ad6 102 DigitalOut(p8),
offroad 15:10c1be621ad6 103 DigitalOut(p9),
offroad 15:10c1be621ad6 104 DigitalOut(p10),
offroad 15:10c1be621ad6 105 DigitalOut(p11),
offroad 15:10c1be621ad6 106 DigitalOut(p12),
offroad 15:10c1be621ad6 107 DigitalOut(p13),
offroad 15:10c1be621ad6 108 DigitalOut(p14),
offroad 15:10c1be621ad6 109 DigitalOut(p15),
offroad 15:10c1be621ad6 110 DigitalOut(p16),
offroad 15:10c1be621ad6 111 DigitalOut(p17),
offroad 15:10c1be621ad6 112 DigitalOut(p18),
offroad 15:10c1be621ad6 113 DigitalOut(p19),
offroad 15:10c1be621ad6 114 DigitalOut(p20),
offroad 15:10c1be621ad6 115 DigitalOut(p21),
offroad 15:10c1be621ad6 116 DigitalOut(p22),
offroad 15:10c1be621ad6 117 DigitalOut(p23),
offroad 15:10c1be621ad6 118 DigitalOut(p24),
offroad 15:10c1be621ad6 119 DigitalOut(p25),
offroad 15:10c1be621ad6 120 DigitalOut(p26),
offroad 15:10c1be621ad6 121 DigitalOut(p27),
offroad 15:10c1be621ad6 122 DigitalOut(p28),
offroad 15:10c1be621ad6 123 DigitalOut(p29),
offroad 15:10c1be621ad6 124 DigitalOut(p30)};
offroad 15:10c1be621ad6 125
offroad 15:10c1be621ad6 126 char buffer[256];
offroad 15:10c1be621ad6 127 char ipAddress[256];
offroad 15:10c1be621ad6 128 char subnetMask[256];
offroad 15:10c1be621ad6 129 sprintf(ipAddress, "%s", "192.168.1.10");
offroad 15:10c1be621ad6 130 sprintf(subnetMask, "%s", "255.255.255.0");
offroad 15:10c1be621ad6 131 int port = 7;
offroad 15:10c1be621ad6 132
offroad 15:10c1be621ad6 133 FILE* f = fopen("/local/config.txt", "r");
offroad 15:10c1be621ad6 134 if (f != NULL){
offroad 15:10c1be621ad6 135 int n = fscanf(f, "%s", ipAddress); if (n <= 0) goto endOfFile;
offroad 15:10c1be621ad6 136 n = fscanf(f, "%s", subnetMask); if (n <= 0) goto endOfFile;
offroad 15:10c1be621ad6 137 n = fscanf(f, "%s", buffer); if (n <= 0) goto endOfFile;
offroad 15:10c1be621ad6 138 port = atoi(buffer);
offroad 15:10c1be621ad6 139 endOfFile:
offroad 15:10c1be621ad6 140 fclose(f);
offroad 15:10c1be621ad6 141 }
offroad 15:10c1be621ad6 142
donatien 0:bb128f0e952f 143 EthernetInterface eth;
offroad 15:10c1be621ad6 144 eth.init(ipAddress, subnetMask, "");
donatien 0:bb128f0e952f 145 eth.connect();
offroad 15:10c1be621ad6 146 printf("IP address: %s (configured: %s) port %i\r\n", eth.getIPAddress(), ipAddress, port);
donatien 0:bb128f0e952f 147
offroad 15:10c1be621ad6 148 TCPSocketServer server;
offroad 15:10c1be621ad6 149 server.bind(port);
offroad 15:10c1be621ad6 150 server.listen();
offroad 15:10c1be621ad6 151
emilmont 7:65188f4a8c25 152 while (true) {
offroad 15:10c1be621ad6 153 printf("\nWait for new connection...\n");
offroad 15:10c1be621ad6 154 TCPSocketConnection client;
offroad 15:10c1be621ad6 155 server.accept(client);
offroad 15:10c1be621ad6 156 client.set_blocking(true, 0);
offroad 15:10c1be621ad6 157
offroad 15:10c1be621ad6 158 printf("Connection from: %s\n", client.get_address());
offroad 15:10c1be621ad6 159 client.send_all(">\r\n", 3);
offroad 16:22169975b5d8 160 FSM_reset();
offroad 16:22169975b5d8 161
offroad 15:10c1be621ad6 162 // === main loop ===
offroad 15:10c1be621ad6 163 while (true) {
offroad 15:10c1be621ad6 164
offroad 15:10c1be621ad6 165 // === read data from socket ===
offroad 15:10c1be621ad6 166 int n = client.receive(buffer, sizeof(buffer));
offroad 15:10c1be621ad6 167
offroad 15:10c1be621ad6 168 // === detect connection break ===
offroad 15:10c1be621ad6 169 if (n < 0)
offroad 16:22169975b5d8 170 goto conn_exit;
offroad 15:10c1be621ad6 171
offroad 16:22169975b5d8 172 // maximum length of a single reply. Anything longer will be split.
offroad 16:22169975b5d8 173 #define MAX_PACKETLEN (1024)
offroad 16:22169975b5d8 174 // maximum length of a single message to guarantee there is enough output buffer
offroad 16:22169975b5d8 175 #define MAX_MSGLEN (16)
offroad 16:22169975b5d8 176 char bufOut[MAX_PACKETLEN];
offroad 16:22169975b5d8 177 char* pWriteStart = &bufOut[0];
offroad 16:22169975b5d8 178 char* pWrite = pWriteStart;
offroad 16:22169975b5d8 179
offroad 16:22169975b5d8 180 // === iterate over input characters ===
offroad 15:10c1be621ad6 181 int ix;
offroad 16:22169975b5d8 182 for (ix = 0; ix < n; ++ix){
offroad 16:22169975b5d8 183 FSM_handleChar(&myGpo[0], buffer[ix], &pWrite);
offroad 15:10c1be621ad6 184
offroad 16:22169975b5d8 185 // === send reply, if there is any ===
offroad 16:22169975b5d8 186 // - when processing last char of incoming packet
offroad 16:22169975b5d8 187 // - when output buffer is too full
offroad 16:22169975b5d8 188 int nInBuf = pWrite - pWriteStart;
offroad 16:22169975b5d8 189 if (nInBuf > 0)
offroad 16:22169975b5d8 190 if ((ix == n-1) || (nInBuf > MAX_PACKETLEN - MAX_MSGLEN)){
offroad 16:22169975b5d8 191 client.send_all(bufOut, nInBuf);
offroad 16:22169975b5d8 192 pWrite = pWriteStart;
offroad 16:22169975b5d8 193 }
offroad 16:22169975b5d8 194 } // for input character
offroad 15:10c1be621ad6 195 } // while connection
offroad 16:22169975b5d8 196
offroad 16:22169975b5d8 197 conn_exit:
offroad 15:10c1be621ad6 198 client.close();
offroad 15:10c1be621ad6 199 } // eternal main loop
offroad 15:10c1be621ad6 200 } // void main