-

Dependencies:   EthernetInterface TCPSocket_HelloWorld mbed-rtos mbed

Fork of TCPSocket_HelloWorld by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EthernetInterface.h"
00003 LocalFileSystem local("local");    
00004 
00005 #define NPORTS 30
00006 static char FSM_buf[16];
00007 #define FSM_STATE_IDLE      0
00008 #define FSM_STATE_READNUM   1
00009 static int FSM_state1 = FSM_STATE_IDLE;
00010 static int FSM_state2 = 0;
00011 static char FSM_cmd = 'x';
00012 
00013 static void FSM_reset(){
00014     FSM_state1 = FSM_STATE_IDLE;
00015     FSM_state2 = 0;
00016     FSM_cmd = 'x';
00017 }
00018 
00019 static void FSM_handleChar(DigitalOut* gpo, char inputChar, char** bufOut){
00020 
00021     // === handle incoming char ===
00022     switch (FSM_state1){
00023         case FSM_STATE_IDLE:
00024             // === handle new command char ===
00025             switch(inputChar){
00026                 case '+':
00027                 case '-':
00028                 case '?': 
00029                     FSM_cmd = inputChar;
00030                     FSM_state1 = FSM_STATE_READNUM;
00031                     goto doneCont;
00032                 default: 
00033                     goto reset;
00034             } // switch inputChar
00035             goto lockup;
00036         case FSM_STATE_READNUM:
00037             if (FSM_state2 > 8)
00038                 goto reset; // too many digits
00039             
00040             if ((inputChar == 32 || inputChar == 9 || inputChar == 13 || inputChar == 10) && (FSM_state2 > 0)){
00041                 // === got command terminated by whitespace, and at least one digit
00042                 FSM_buf[FSM_state2] = 0;
00043                 int ixGpio = atoi(FSM_buf);
00044                 if (ixGpio < 0 || ixGpio >= NPORTS)
00045                     goto reset; // invalid port number
00046                 switch(FSM_cmd){
00047                     case '+':
00048                         // === set GPO ===
00049                         *(gpo+ixGpio) = 1; 
00050                         goto reset; // success
00051                     case '-':
00052                         // === clear GPO ===
00053                         *(gpo+ixGpio) = 0;
00054                         goto reset; // success
00055                     case '?':
00056                         // === query GPO state (verify) ===
00057                         *((*bufOut)++) = *(gpo+ixGpio) ? '1' : '0';
00058                         *((*bufOut)++) = 13;
00059                         *((*bufOut)++) = 10;
00060                         goto reset; // success   
00061                     default:
00062                         goto reset; // invalid command byte
00063                 }
00064             }
00065             
00066             if (inputChar >= '0' && inputChar <= '9'){
00067                 // === append digit ===
00068                 FSM_buf[FSM_state2++] = inputChar;
00069                 goto doneCont;
00070             }
00071             
00072             // invalid character (not digit)
00073             goto reset;
00074         default:
00075             // === invalid FSM state ===
00076             goto lockup;
00077     } // switch FSM_state1
00078 
00079     // === internal error. Should never be reached. ===
00080 lockup: 
00081     goto lockup; 
00082 
00083     // === reset state machine (on completion and any invalid input ===
00084 reset:
00085     FSM_reset();
00086 
00087 doneCont:
00088     return;
00089 }
00090 
00091 int main() {
00092     printf("\r\nLANGPIO server v2.1 20151107 mn\r\n");
00093     fflush(stdout);
00094     static DigitalOut myGpo[NPORTS] = {
00095         DigitalOut(LED1),
00096         DigitalOut(LED2),
00097         DigitalOut(LED3),
00098         DigitalOut(LED4),
00099         DigitalOut(p5),
00100         DigitalOut(p6),
00101         DigitalOut(p7),
00102         DigitalOut(p8),
00103         DigitalOut(p9),
00104         DigitalOut(p10),
00105         DigitalOut(p11),
00106         DigitalOut(p12),
00107         DigitalOut(p13),
00108         DigitalOut(p14),
00109         DigitalOut(p15),
00110         DigitalOut(p16),
00111         DigitalOut(p17),
00112         DigitalOut(p18),
00113         DigitalOut(p19),
00114         DigitalOut(p20),
00115         DigitalOut(p21),
00116         DigitalOut(p22),
00117         DigitalOut(p23),
00118         DigitalOut(p24),
00119         DigitalOut(p25),
00120         DigitalOut(p26),
00121         DigitalOut(p27),
00122         DigitalOut(p28),
00123         DigitalOut(p29),
00124         DigitalOut(p30)};
00125 
00126     char buffer[256];
00127     char ipAddress[256];
00128     char subnetMask[256];
00129     sprintf(ipAddress, "%s", "192.168.1.10");
00130     sprintf(subnetMask, "%s", "255.255.255.0");
00131     int port = 7;
00132 
00133     FILE* f = fopen("/local/config.txt", "r");
00134     if (f != NULL){
00135         int n = fscanf(f, "%s", ipAddress); if (n <= 0) goto endOfFile;
00136         n = fscanf(f, "%s", subnetMask); if (n <= 0) goto endOfFile;
00137         n = fscanf(f, "%s", buffer); if (n <= 0) goto endOfFile;
00138         port = atoi(buffer);
00139     endOfFile:
00140         fclose(f);
00141     }
00142 
00143     EthernetInterface eth;
00144     eth.init(ipAddress, subnetMask, "");
00145     eth.connect();
00146     printf("IP address: %s (configured: %s) port %i\r\n", eth.getIPAddress(), ipAddress, port);
00147     
00148     TCPSocketServer server;
00149     server.bind(port);
00150     server.listen();
00151 
00152     while (true) {
00153         printf("\nWait for new connection...\n");
00154         TCPSocketConnection client;
00155         server.accept(client);
00156         client.set_blocking(true, 0);
00157         
00158         printf("Connection from: %s\n", client.get_address());
00159         client.send_all(">\r\n", 3);
00160         FSM_reset();
00161         
00162         // === main loop ===
00163         while (true) {
00164 
00165             // === read data from socket ===
00166             int n = client.receive(buffer, sizeof(buffer));
00167 
00168             // === detect connection break ===
00169             if (n < 0)
00170                 goto conn_exit;
00171             
00172             // maximum length of a single reply. Anything longer will be split.
00173             #define MAX_PACKETLEN (1024)
00174             // maximum length of a single message to guarantee there is enough output buffer
00175             #define MAX_MSGLEN (16)
00176             char bufOut[MAX_PACKETLEN];
00177             char* pWriteStart = &bufOut[0];
00178             char* pWrite = pWriteStart;
00179 
00180             // === iterate over input characters ===
00181             int ix;
00182             for (ix = 0; ix < n; ++ix){
00183                 FSM_handleChar(&myGpo[0], buffer[ix], &pWrite);
00184 
00185                 // === send reply, if there is any ===
00186                 // - when processing last char of incoming packet
00187                 // - when output buffer is too full
00188                 int nInBuf = pWrite - pWriteStart;
00189                 if (nInBuf > 0)
00190                     if ((ix == n-1) || (nInBuf > MAX_PACKETLEN - MAX_MSGLEN)){
00191                         client.send_all(bufOut, nInBuf);
00192                         pWrite = pWriteStart;
00193                     }
00194             } // for input character
00195         } // while connection
00196         
00197     conn_exit:
00198         client.close();
00199     } // eternal main loop
00200 } // void main