Simple HTTP Server with support for SD Card file serving and CGI commands
Dependencies: EthernetInterface TCPEchoServer SDFileSystem mbed-rtos mbed
Fork of TCPEchoServer by
main.cpp
00001 #include "mbed.h" 00002 #include "EthernetInterface.h" 00003 #include "SDFileSystem.h" 00004 #include <stdio.h> 00005 #include <string.h> 00006 00007 #define HTTPD_SERVER_PORT 80 00008 #define HTTPD_MAX_REQ_LENGTH 1023 00009 #define HTTPD_MAX_HDR_LENGTH 255 00010 #define HTTPD_MAX_FNAME_LENGTH 127 00011 #define I2C_BUFFER_SIZE 63 00012 00013 SDFileSystem sd(p5, p6, p7, p8, "sd"); // 00014 I2C i2c(p28, p27); 00015 EthernetInterface eth; 00016 TCPSocketServer server; 00017 TCPSocketConnection client; 00018 00019 char buffer[HTTPD_MAX_REQ_LENGTH+1]; 00020 char httpHeader[HTTPD_MAX_HDR_LENGTH+1]; 00021 char filename[HTTPD_MAX_FNAME_LENGTH+1]; 00022 char data[I2C_BUFFER_SIZE]; 00023 char *uristr; 00024 char *eou; 00025 char *qrystr; 00026 00027 FILE *fp; 00028 int rdCnt; 00029 00030 void cmd_i2c_write(char* qry) 00031 { 00032 int addr = 0; 00033 int dlen = 0; 00034 int dtmp = 0; 00035 if (sscanf(qry, "%2x", &addr) == 1) { 00036 qry += 2; 00037 printf("Addr: %x Data: ", addr); 00038 while (sscanf(qry, "&%2x", &dtmp) == 1) { 00039 data[dlen] = dtmp; 00040 qry +=3; 00041 dlen +=1; 00042 printf("%x ", dtmp); 00043 } 00044 printf("Bytes: %d\r\n ", dlen); 00045 } else { 00046 dlen = -1; 00047 printf("Invalid address: %s\r\n", qry); 00048 } 00049 if (dlen > 0 ) { 00050 printf("Write %d bytes to %x\r\n", dlen, addr); 00051 i2c.write(addr, data, dlen); 00052 } 00053 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n%d", dlen); 00054 client.send(httpHeader,strlen(httpHeader)); 00055 } 00056 00057 void cmd_i2c_read(char* qry) 00058 { 00059 int addr = 0; 00060 int dlen = 0; 00061 if (sscanf(qry, "%2x", &addr) == 1) { 00062 qry += 2; 00063 printf("Read from addr %x ", addr); 00064 if (sscanf(qry, "&%2x", &dlen) == 1) { 00065 if (i2c.read(addr, data, dlen)!=0) { 00066 dlen = -1; 00067 printf("failed\r\n"); 00068 } else { 00069 printf("%d bytes\r\n ", dlen); 00070 } 00071 } else { 00072 printf("\r\nInvalid data length: %s\r\n", qry); 00073 } 00074 } else { 00075 dlen = -1; 00076 printf("Invalid address: %s\r\n", qry); 00077 } 00078 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n%d", dlen); 00079 client.send(httpHeader,strlen(httpHeader)); 00080 while (dlen > 0) { 00081 dlen -= 1; 00082 sprintf(httpHeader," %x", data[dlen]); 00083 client.send(httpHeader,strlen(httpHeader)); 00084 } 00085 } 00086 00087 void cmd_i2c_addr_read(char* qry) 00088 { 00089 int addr = 0; 00090 int radd = 0; 00091 int dlen = 0; 00092 if (sscanf(qry, "%2x", &addr) == 1) { 00093 qry += 2; 00094 printf("Addressed Read from I2C addr %x ", addr); 00095 if (sscanf(qry, "&%2x", &radd) == 1) { 00096 qry += 3; 00097 printf("reg addr %x ", radd); 00098 if (sscanf(qry, "&%2x", &dlen) == 1) { 00099 data[0] = radd; 00100 i2c.write(addr, data, 1, false); 00101 if (i2c.read(addr, data, dlen)!=0) { 00102 dlen = -1; 00103 printf("failed\r\n"); 00104 } else { 00105 printf("%d bytes\r\n ", dlen); 00106 } 00107 } else { 00108 printf("\r\nInvalid data length: %s\r\n", qry); 00109 } 00110 } else { 00111 dlen = -1; 00112 printf("Invalid register address: %s\r\n", qry); 00113 00114 } 00115 } else { 00116 dlen = -1; 00117 printf("Invalid address: %s\r\n", qry); 00118 } 00119 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n%d", dlen); 00120 client.send(httpHeader,strlen(httpHeader)); 00121 while (dlen > 0) { 00122 dlen -= 1; 00123 sprintf(httpHeader," %x", data[dlen]); 00124 client.send(httpHeader,strlen(httpHeader)); 00125 } 00126 } 00127 void get_file(char* uri) 00128 { 00129 char *lstchr = strrchr(uri, NULL) -1; 00130 if ('/' == *lstchr) { 00131 printf("Open directory /sd%s\n", uri); 00132 *lstchr = 0; 00133 sprintf(filename, "/sd%s", uri); 00134 DIR *d = opendir(filename); 00135 if (d != NULL) { 00136 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"); 00137 client.send(httpHeader,strlen(httpHeader)); 00138 sprintf(httpHeader,"<html><head><title>Directory Listing</title></head><body><h1>%s</h1><ul>", uri); 00139 client.send(httpHeader,strlen(httpHeader)); 00140 struct dirent *p; 00141 while((p = readdir(d)) != NULL) { 00142 printf("%s\n", p->d_name); 00143 sprintf(httpHeader,"<li>%s</li>", p->d_name); 00144 client.send(httpHeader,strlen(httpHeader)); 00145 } 00146 } 00147 closedir(d); 00148 printf("Directory closed\n"); 00149 sprintf(httpHeader,"</ul></body></html>"); 00150 client.send(httpHeader,strlen(httpHeader)); 00151 } else { 00152 sprintf(filename, "/sd%s", uri); 00153 fp = fopen(filename, "r"); 00154 if (fp == NULL) { 00155 sprintf(httpHeader,"HTTP/1.1 404 Not Found \r\nContent-Type: text\r\nConnection: Close\r\n\r\n"); 00156 client.send(httpHeader,strlen(httpHeader)); 00157 client.send(uri,strlen(uri)); 00158 } else { 00159 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"); 00160 client.send(httpHeader,strlen(httpHeader)); 00161 while ((rdCnt = fread(buffer, sizeof( char ), 1024, fp)) == 1024) { 00162 client.send(buffer, rdCnt); 00163 } 00164 client.send(buffer, rdCnt); 00165 fclose(fp); 00166 } 00167 } 00168 } 00169 00170 void get_cgi(char* uri, char* qry) 00171 { 00172 if (!strncmp(uri, "i2cW", 4)) { // i2cW [addr] [data] [data] [data] ... 00173 cmd_i2c_write(qry); 00174 } else if (!strncmp(uri, "i2cR", 4)) { // i2cR [addr] [count] 00175 cmd_i2c_read(qry); 00176 } else if (!strncmp(uri, "i2cAR", 5)) { // i2cAR [addr] [radd] [count] 00177 cmd_i2c_addr_read(qry); 00178 } else { 00179 sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"); 00180 client.send(httpHeader,strlen(httpHeader)); 00181 sprintf(httpHeader,"<html><head><title>Unrecognized CGI Command</title></head><body><h1>Unrecognized CGI Command</h1>"); 00182 client.send(httpHeader,strlen(httpHeader)); 00183 sprintf(httpHeader,"<h2>Command: %s</h2>", uri); 00184 client.send(httpHeader,strlen(httpHeader)); 00185 sprintf(httpHeader,"<h2>Query: %s</h2>", qry); 00186 client.send(httpHeader,strlen(httpHeader)); 00187 sprintf(httpHeader,"<h2>Supported Commands: </h2><ul>"); 00188 client.send(httpHeader,strlen(httpHeader)); 00189 sprintf(httpHeader,"<li>i2cR [addr] [count]"); 00190 client.send(httpHeader,strlen(httpHeader)); 00191 sprintf(httpHeader,"<li>i2cAR [addr] [radd] [count]"); 00192 client.send(httpHeader,strlen(httpHeader)); 00193 sprintf(httpHeader,"<li>i2cW [addr] [data] [data] [data] ..."); 00194 client.send(httpHeader,strlen(httpHeader)); 00195 sprintf(httpHeader,"</ul><br>addr = I2C address<br>radd = register address<br>count = number of bytes to read<br>data = data byte to send<br>All values are in two digit hexdecimal bytes."); 00196 client.send(httpHeader,strlen(httpHeader)); 00197 sprintf(httpHeader,"</body></html>"); 00198 client.send(httpHeader,strlen(httpHeader)); 00199 } 00200 } 00201 00202 00203 int main (void) 00204 { 00205 // EthernetInterface eth; 00206 eth.init(); //Use DHCP 00207 eth.connect(); 00208 printf("IP Address is %s\n", eth.getIPAddress()); 00209 00210 // TCPSocketServer server; 00211 server.bind(HTTPD_SERVER_PORT); 00212 server.listen(); 00213 00214 while (true) { 00215 printf("\nWait for new connection...\r\n"); 00216 server.accept(client); 00217 client.set_blocking(false, 1500); // Timeout after (1.5)s 00218 00219 printf("Connection from: %s\r\n", client.get_address()); 00220 while (true) { 00221 int n = client.receive(buffer, sizeof(buffer)); 00222 if (n <= 0) break; 00223 printf("Recieved Data: %d\r\n\r\n%.*s\r\n",n,n,buffer); 00224 if (n >= 1024) { 00225 sprintf(httpHeader,"HTTP/1.1 413 Request Entity Too Large \r\nContent-Type: text\r\nConnection: Close\r\n\r\n"); 00226 client.send(httpHeader,strlen(httpHeader)); 00227 client.send(buffer,n); 00228 break; 00229 } else { 00230 buffer[n]=0; 00231 } 00232 if (!strncmp(buffer, "GET ", 4)) { 00233 uristr = buffer + 4; 00234 eou = strstr(uristr, " "); 00235 if (eou == NULL) { 00236 sprintf(httpHeader,"HTTP/1.1 400 Bad Request \r\nContent-Type: text\r\nConnection: Close\r\n\r\n"); 00237 client.send(httpHeader,strlen(httpHeader)); 00238 client.send(buffer,n); 00239 } else { 00240 *eou = 0; 00241 qrystr = strstr(uristr, "?"); 00242 if (qrystr != NULL) { 00243 *qrystr = 0; 00244 qrystr++; 00245 } 00246 if (!strncmp(uristr, "/cgi/", 5)) { 00247 get_cgi(uristr+5, qrystr); 00248 } else { 00249 get_file(uristr); 00250 } 00251 } 00252 } 00253 } 00254 00255 client.close(); 00256 } 00257 }
Generated on Sat Jul 16 2022 20:08:52 by 1.7.2