greenhouse
webserver.cpp
Go to the documentation of this file.
2 #include "webserver.h"
3 #include "EthernetInterface.h"
4 #include "mbed.h"
5 #include "website.h"
6 #include <cstring>
7 #include <string>
8 
9 #define IP "192.168.1.100"
10 #define GATEWAY "192.168.1.1"
11 #define NETMASK "255.255.255.0"
12 #define PORT 80
13 
15 
16 EthernetInterface *net;
17 
18 TCPSocket server;
19 TCPSocket *client_socket;
20 SocketAddress client_address;
21 char rx_buffer[1024] = {0};
22 char tx_buffer[1024] = {0};
23 
24 int requests = 0;
25 
26 WebServer::WebServer(Database *database) { db = database; }
27 
29  net = new EthernetInterface;
30 
31  if (!net) {
32  return 0;
33  }
34 
35  net->set_network(IP, NETMASK, GATEWAY); // include to use static IP address
36  nsapi_size_or_error_t r = net->connect();
37  if (r != 0) {
38  printf("[webserver]: error! net->connect() returned: %d\n", r);
39  return r;
40  }
41 
42  // Show the network address
43  SocketAddress ip;
44  SocketAddress netmask;
45  SocketAddress gateway;
46 
47  net->get_ip_address(&ip);
48  net->get_netmask(&netmask);
49  net->get_gateway(&gateway);
50 
51  ip.set_port(PORT);
52 
53  const char *ip_addr = ip.get_ip_address();
54  const char *netmask_addr = netmask.get_ip_address();
55  const char *gateway_addr = gateway.get_ip_address();
56 
57  printf("[webserver]: IP address: %s\n", ip_addr ? ip_addr : "None");
58  printf("[webserver]: Netmask: %s\n", netmask_addr ? netmask_addr : "None");
59  printf("[webserver]: Gateway: %s\n", gateway_addr ? gateway_addr : "None");
60 
61  server.open(net);
62  server.bind(ip);
63  server.listen(MAX_CONN);
64 
65  return 1;
66 };
67 
68 void http_ok() {
69  sprintf(tx_buffer,
70  "HTTP/1.1 200 OK\n"
71  "Content-Length: %d\n"
72  "Content-Type: text\n"
73  "Connection: Close\n",
74  strlen(rx_buffer));
75 }
76 
78  sprintf(tx_buffer, "HTTP/1.1 204 No Content\n"
79  "Connection: Close\n");
80 }
81 
83  sprintf(tx_buffer, "HTTP/1.1 404 Not Found\n"
84  "Connection: Close\n");
85 }
86 
88  sprintf(tx_buffer, "HTTP/1.1 500 Internal Server Error\n"
89  "Connection: Close\n");
90 }
91 
93  printf("=========================================\n");
94 
95  nsapi_error_t error = 0;
96 
97  client_socket = server.accept(&error);
98  requests++;
99  if (error != 0) {
100  printf("[webserver]: Connection failed!\n");
101  } else {
102  client_socket->set_timeout(
103  0); // timeout of 0 makes it a non-blocking connection
104  client_socket->getpeername(&client_address);
105  printf("[webserver]: Client with IP address %s connected.\n",
106  client_address.get_ip_address());
107  error = client_socket->recv(rx_buffer, sizeof(rx_buffer));
108 
109  switch (error) {
110  case 0:
111  printf("[webserver]: Recieved buffer is empty.\n");
113  break;
114 
115  case -1:
116  printf("[webserver]: Failed to read data from client.\n");
118  break;
119 
120  default:
121  printf("[webserver]: Recieved Data: %d bytes\n%.*s\n", strlen(rx_buffer),
122  strlen(rx_buffer), rx_buffer);
123 
124  printf("%c", rx_buffer[4]);
125  if (rx_buffer[0] == 'G' && rx_buffer[1] == 'E' && rx_buffer[2] == 'T' &&
126  rx_buffer[4] == '/' && rx_buffer[5] == ' ') {
127  // setup http response header & data
128  http_ok();
129 
130  strcpy(tx_buffer, homepage);
131  } else if (rx_buffer[0] == 'P' && rx_buffer[1] == 'O' &&
132  rx_buffer[2] == 'S' && rx_buffer[3] == 'T') {
133  // POST request
134  string s = string(rx_buffer);
135  int len = s.length();
136  string data = s.substr(len - 11, len);
137 
138  string temp = data.substr(0, 4);
139  string dewity = data.substr(4, 4).substr(1, 2); // wat 🤡
140  string humidity = data.substr(8, 9);
141 
142  Row r = Row();
143  r.temperature = temp;
144  r.dewity = dewity;
145  r.humidity = humidity;
146 
147  db->append(r);
148 
149  HttpResponseBuilder builder(204);
150  builder.send(client_socket, nullptr, 0);
151 
152  http_no_content();
153  } else {
154  http_not_found();
155  }
156 
157  client_socket->send(tx_buffer, strlen(tx_buffer));
158  break;
159  }
160  }
161 
162  client_socket->close();
163 }
164 
165 TCPSocket *WebServer::getSocket() { return client_socket; }
void append(Row r)
Definition: database.cpp:20
nsapi_error_t send(TCPSocket *socket, const void *body, size_t body_size)
int start()
Definition: webserver.cpp:28
WebServer(Database *database)
Definition: webserver.cpp:26
void tick()
Definition: webserver.cpp:92
TCPSocket * getSocket()
Definition: webserver.cpp:165
Definition: database.h:6
std::string temperature
Definition: database.h:7
std::string humidity
Definition: database.h:9
std::string dewity
Definition: database.h:8
void http_ok()
Definition: webserver.cpp:68
char rx_buffer[1024]
Definition: webserver.cpp:21
TCPSocket server
Definition: webserver.cpp:18
#define PORT
Definition: webserver.cpp:12
void http_not_found()
Definition: webserver.cpp:82
#define GATEWAY
Definition: webserver.cpp:10
TCPSocket * client_socket
Definition: webserver.cpp:19
int requests
Definition: webserver.cpp:24
char tx_buffer[1024]
Definition: webserver.cpp:22
Database * db
Definition: webserver.cpp:14
void http_no_content()
Definition: webserver.cpp:77
void http_internal_server_error()
Definition: webserver.cpp:87
#define NETMASK
Definition: webserver.cpp:11
EthernetInterface * net
Definition: webserver.cpp:16
#define IP
Definition: webserver.cpp:9
SocketAddress client_address
Definition: webserver.cpp:20
static const int MAX_CONN
Definition: webserver.h:7
static const char homepage[]
Definition: website.h:3