-
Dependencies: EthernetInterface TCPSocket_HelloWorld mbed-rtos mbed
Fork of TCPSocket_HelloWorld by
main.cpp@15:10c1be621ad6, 2015-11-07 (annotated)
- Committer:
- offroad
- Date:
- Sat Nov 07 15:46:54 2015 +0000
- Revision:
- 15:10c1be621ad6
- Parent:
- 11:59dcefdda506
- Child:
- 16:22169975b5d8
1v0
Who changed what in which revision?
User | Revision | Line number | New 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 | 15:10c1be621ad6 | 13 | static void FSM_handleChar(DigitalOut* gpo, char inputChar, char* bufOut, int* nOut){ |
offroad | 15:10c1be621ad6 | 14 | // === reset reply === |
offroad | 15:10c1be621ad6 | 15 | *nOut = 0; |
offroad | 15:10c1be621ad6 | 16 | |
offroad | 15:10c1be621ad6 | 17 | // === handle incoming char === |
offroad | 15:10c1be621ad6 | 18 | switch (FSM_state1){ |
offroad | 15:10c1be621ad6 | 19 | case FSM_STATE_IDLE: |
offroad | 15:10c1be621ad6 | 20 | // === handle new command char === |
offroad | 15:10c1be621ad6 | 21 | switch(inputChar){ |
offroad | 15:10c1be621ad6 | 22 | case '+': |
offroad | 15:10c1be621ad6 | 23 | case '-': |
offroad | 15:10c1be621ad6 | 24 | case '?': |
offroad | 15:10c1be621ad6 | 25 | FSM_cmd = inputChar; |
offroad | 15:10c1be621ad6 | 26 | FSM_state1 = FSM_STATE_READNUM; |
offroad | 15:10c1be621ad6 | 27 | goto doneCont; |
offroad | 15:10c1be621ad6 | 28 | default: |
offroad | 15:10c1be621ad6 | 29 | goto reset; |
offroad | 15:10c1be621ad6 | 30 | } // switch inputChar |
offroad | 15:10c1be621ad6 | 31 | goto lockup; |
offroad | 15:10c1be621ad6 | 32 | case FSM_STATE_READNUM: |
offroad | 15:10c1be621ad6 | 33 | if (FSM_state2 > 8) |
offroad | 15:10c1be621ad6 | 34 | goto reset; // too many digits |
offroad | 15:10c1be621ad6 | 35 | |
offroad | 15:10c1be621ad6 | 36 | if ((inputChar == 32 || inputChar == 9 || inputChar == 13 || inputChar == 10) && (FSM_state2 > 0)){ |
offroad | 15:10c1be621ad6 | 37 | // === got command terminated by whitespace, and at least one digit |
offroad | 15:10c1be621ad6 | 38 | FSM_buf[FSM_state2] = 0; |
offroad | 15:10c1be621ad6 | 39 | int ixGpio = atoi(FSM_buf); |
offroad | 15:10c1be621ad6 | 40 | if (ixGpio < 0 || ixGpio >= NPORTS) |
offroad | 15:10c1be621ad6 | 41 | goto reset; // invalid port number |
offroad | 15:10c1be621ad6 | 42 | switch(FSM_cmd){ |
offroad | 15:10c1be621ad6 | 43 | case '+': |
offroad | 15:10c1be621ad6 | 44 | // === set GPO === |
offroad | 15:10c1be621ad6 | 45 | *(gpo+ixGpio) = 1; |
offroad | 15:10c1be621ad6 | 46 | goto reset; // success |
offroad | 15:10c1be621ad6 | 47 | case '-': |
offroad | 15:10c1be621ad6 | 48 | // === clear GPO === |
offroad | 15:10c1be621ad6 | 49 | *(gpo+ixGpio) = 0; |
offroad | 15:10c1be621ad6 | 50 | goto reset; // success |
offroad | 15:10c1be621ad6 | 51 | case '?': |
offroad | 15:10c1be621ad6 | 52 | // === query GPO state (verify) === |
offroad | 15:10c1be621ad6 | 53 | bufOut[(*nOut)++] = *(gpo+ixGpio) ? '1' : '0'; |
offroad | 15:10c1be621ad6 | 54 | bufOut[(*nOut)++] = 13; |
offroad | 15:10c1be621ad6 | 55 | bufOut[(*nOut)++] = 10; |
offroad | 15:10c1be621ad6 | 56 | goto reset; // success |
offroad | 15:10c1be621ad6 | 57 | default: |
offroad | 15:10c1be621ad6 | 58 | goto reset; // invalid command byte |
offroad | 15:10c1be621ad6 | 59 | } |
offroad | 15:10c1be621ad6 | 60 | } |
offroad | 15:10c1be621ad6 | 61 | |
offroad | 15:10c1be621ad6 | 62 | if (inputChar >= '0' && inputChar <= '9'){ |
offroad | 15:10c1be621ad6 | 63 | // === append digit === |
offroad | 15:10c1be621ad6 | 64 | FSM_buf[FSM_state2++] = inputChar; |
offroad | 15:10c1be621ad6 | 65 | goto doneCont; |
offroad | 15:10c1be621ad6 | 66 | } |
offroad | 15:10c1be621ad6 | 67 | |
offroad | 15:10c1be621ad6 | 68 | // invalid character (not digit) |
offroad | 15:10c1be621ad6 | 69 | goto reset; |
offroad | 15:10c1be621ad6 | 70 | default: |
offroad | 15:10c1be621ad6 | 71 | // === invalid FSM state === |
offroad | 15:10c1be621ad6 | 72 | goto lockup; |
offroad | 15:10c1be621ad6 | 73 | } // switch FSM_state1 |
offroad | 15:10c1be621ad6 | 74 | |
offroad | 15:10c1be621ad6 | 75 | // === internal error. May never be reached === |
offroad | 15:10c1be621ad6 | 76 | lockup: |
offroad | 15:10c1be621ad6 | 77 | goto lockup; |
offroad | 15:10c1be621ad6 | 78 | |
offroad | 15:10c1be621ad6 | 79 | // === reset state machine (on completion and any invalid input === |
offroad | 15:10c1be621ad6 | 80 | reset: |
offroad | 15:10c1be621ad6 | 81 | FSM_state1 = FSM_STATE_IDLE; |
offroad | 15:10c1be621ad6 | 82 | FSM_state2 = 0; |
offroad | 15:10c1be621ad6 | 83 | FSM_cmd = 'x'; |
offroad | 15:10c1be621ad6 | 84 | |
offroad | 15:10c1be621ad6 | 85 | doneCont: |
offroad | 15:10c1be621ad6 | 86 | return; |
offroad | 15:10c1be621ad6 | 87 | } |
donatien | 0:bb128f0e952f | 88 | |
emilmont | 7:65188f4a8c25 | 89 | int main() { |
offroad | 15:10c1be621ad6 | 90 | printf("\r\nGPIO server v2 20151106 mn\r\n"); |
offroad | 15:10c1be621ad6 | 91 | fflush(stdout); |
offroad | 15:10c1be621ad6 | 92 | static DigitalOut myGpo[NPORTS] = { |
offroad | 15:10c1be621ad6 | 93 | DigitalOut(LED1), |
offroad | 15:10c1be621ad6 | 94 | DigitalOut(LED2), |
offroad | 15:10c1be621ad6 | 95 | DigitalOut(LED3), |
offroad | 15:10c1be621ad6 | 96 | DigitalOut(LED4), |
offroad | 15:10c1be621ad6 | 97 | DigitalOut(p5), |
offroad | 15:10c1be621ad6 | 98 | DigitalOut(p6), |
offroad | 15:10c1be621ad6 | 99 | DigitalOut(p7), |
offroad | 15:10c1be621ad6 | 100 | DigitalOut(p8), |
offroad | 15:10c1be621ad6 | 101 | DigitalOut(p9), |
offroad | 15:10c1be621ad6 | 102 | DigitalOut(p10), |
offroad | 15:10c1be621ad6 | 103 | DigitalOut(p11), |
offroad | 15:10c1be621ad6 | 104 | DigitalOut(p12), |
offroad | 15:10c1be621ad6 | 105 | DigitalOut(p13), |
offroad | 15:10c1be621ad6 | 106 | DigitalOut(p14), |
offroad | 15:10c1be621ad6 | 107 | DigitalOut(p15), |
offroad | 15:10c1be621ad6 | 108 | DigitalOut(p16), |
offroad | 15:10c1be621ad6 | 109 | DigitalOut(p17), |
offroad | 15:10c1be621ad6 | 110 | DigitalOut(p18), |
offroad | 15:10c1be621ad6 | 111 | DigitalOut(p19), |
offroad | 15:10c1be621ad6 | 112 | DigitalOut(p20), |
offroad | 15:10c1be621ad6 | 113 | DigitalOut(p21), |
offroad | 15:10c1be621ad6 | 114 | DigitalOut(p22), |
offroad | 15:10c1be621ad6 | 115 | DigitalOut(p23), |
offroad | 15:10c1be621ad6 | 116 | DigitalOut(p24), |
offroad | 15:10c1be621ad6 | 117 | DigitalOut(p25), |
offroad | 15:10c1be621ad6 | 118 | DigitalOut(p26), |
offroad | 15:10c1be621ad6 | 119 | DigitalOut(p27), |
offroad | 15:10c1be621ad6 | 120 | DigitalOut(p28), |
offroad | 15:10c1be621ad6 | 121 | DigitalOut(p29), |
offroad | 15:10c1be621ad6 | 122 | DigitalOut(p30)}; |
offroad | 15:10c1be621ad6 | 123 | |
offroad | 15:10c1be621ad6 | 124 | char buffer[256]; |
offroad | 15:10c1be621ad6 | 125 | char ipAddress[256]; |
offroad | 15:10c1be621ad6 | 126 | char subnetMask[256]; |
offroad | 15:10c1be621ad6 | 127 | sprintf(ipAddress, "%s", "192.168.1.10"); |
offroad | 15:10c1be621ad6 | 128 | sprintf(subnetMask, "%s", "255.255.255.0"); |
offroad | 15:10c1be621ad6 | 129 | int port = 7; |
offroad | 15:10c1be621ad6 | 130 | |
offroad | 15:10c1be621ad6 | 131 | FILE* f = fopen("/local/config.txt", "r"); |
offroad | 15:10c1be621ad6 | 132 | if (f != NULL){ |
offroad | 15:10c1be621ad6 | 133 | int n = fscanf(f, "%s", ipAddress); if (n <= 0) goto endOfFile; |
offroad | 15:10c1be621ad6 | 134 | n = fscanf(f, "%s", subnetMask); if (n <= 0) goto endOfFile; |
offroad | 15:10c1be621ad6 | 135 | n = fscanf(f, "%s", buffer); if (n <= 0) goto endOfFile; |
offroad | 15:10c1be621ad6 | 136 | port = atoi(buffer); |
offroad | 15:10c1be621ad6 | 137 | endOfFile: |
offroad | 15:10c1be621ad6 | 138 | fclose(f); |
offroad | 15:10c1be621ad6 | 139 | } |
offroad | 15:10c1be621ad6 | 140 | |
donatien | 0:bb128f0e952f | 141 | EthernetInterface eth; |
offroad | 15:10c1be621ad6 | 142 | eth.init(ipAddress, subnetMask, ""); |
donatien | 0:bb128f0e952f | 143 | eth.connect(); |
offroad | 15:10c1be621ad6 | 144 | printf("IP address: %s (configured: %s) port %i\r\n", eth.getIPAddress(), ipAddress, port); |
donatien | 0:bb128f0e952f | 145 | |
offroad | 15:10c1be621ad6 | 146 | TCPSocketServer server; |
offroad | 15:10c1be621ad6 | 147 | server.bind(port); |
offroad | 15:10c1be621ad6 | 148 | server.listen(); |
offroad | 15:10c1be621ad6 | 149 | |
emilmont | 7:65188f4a8c25 | 150 | while (true) { |
offroad | 15:10c1be621ad6 | 151 | printf("\nWait for new connection...\n"); |
offroad | 15:10c1be621ad6 | 152 | TCPSocketConnection client; |
offroad | 15:10c1be621ad6 | 153 | server.accept(client); |
offroad | 15:10c1be621ad6 | 154 | client.set_blocking(true, 0); |
offroad | 15:10c1be621ad6 | 155 | |
offroad | 15:10c1be621ad6 | 156 | printf("Connection from: %s\n", client.get_address()); |
offroad | 15:10c1be621ad6 | 157 | client.send_all(">\r\n", 3); |
offroad | 15:10c1be621ad6 | 158 | |
offroad | 15:10c1be621ad6 | 159 | // === main loop === |
offroad | 15:10c1be621ad6 | 160 | while (true) { |
offroad | 15:10c1be621ad6 | 161 | |
offroad | 15:10c1be621ad6 | 162 | // === read data from socket === |
offroad | 15:10c1be621ad6 | 163 | int n = client.receive(buffer, sizeof(buffer)); |
offroad | 15:10c1be621ad6 | 164 | |
offroad | 15:10c1be621ad6 | 165 | // === detect connection break === |
offroad | 15:10c1be621ad6 | 166 | if (n < 0) |
offroad | 15:10c1be621ad6 | 167 | break; |
offroad | 15:10c1be621ad6 | 168 | |
offroad | 15:10c1be621ad6 | 169 | // === handle incoming data === |
offroad | 15:10c1be621ad6 | 170 | int ix; |
offroad | 15:10c1be621ad6 | 171 | char bufOut[255]; |
offroad | 15:10c1be621ad6 | 172 | int nOut = 0; |
offroad | 15:10c1be621ad6 | 173 | for (ix = 0; ix < n; ++ix) |
offroad | 15:10c1be621ad6 | 174 | FSM_handleChar(&myGpo[0], buffer[ix], bufOut, &nOut); |
offroad | 15:10c1be621ad6 | 175 | |
offroad | 15:10c1be621ad6 | 176 | // === send reply === |
offroad | 15:10c1be621ad6 | 177 | if (nOut > 0) |
offroad | 15:10c1be621ad6 | 178 | client.send_all(bufOut, nOut); |
offroad | 15:10c1be621ad6 | 179 | } // while connection |
offroad | 15:10c1be621ad6 | 180 | client.close(); |
offroad | 15:10c1be621ad6 | 181 | } // eternal main loop |
offroad | 15:10c1be621ad6 | 182 | } // void main |