Backing up an unused program in case of future need

Dependencies:   mbed

Committer:
andrewboyson
Date:
Fri Apr 22 09:23:57 2016 +0000
Revision:
2:06fa34661f19
Parent:
1:94282484baae
Child:
5:6226f3c566ef
Added configuration file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:09f915e6f9f6 1 #include "esp.h"
andrewboyson 0:09f915e6f9f6 2 #include "at.h"
andrewboyson 0:09f915e6f9f6 3 #include "io.h"
andrewboyson 0:09f915e6f9f6 4 #include "log.h"
andrewboyson 0:09f915e6f9f6 5 #include "time.h"
andrewboyson 0:09f915e6f9f6 6 #include "wifi.h"
andrewboyson 1:94282484baae 7 #define RECV_BUFFER_SIZE 1024
andrewboyson 1:94282484baae 8 #define SEND_BUFFER_SIZE 256
andrewboyson 0:09f915e6f9f6 9 #define SERVER_PORT 80
andrewboyson 0:09f915e6f9f6 10
andrewboyson 1:94282484baae 11 static char recvbuffer[RECV_BUFFER_SIZE];
andrewboyson 1:94282484baae 12 static char sendbuffer[SEND_BUFFER_SIZE];
andrewboyson 1:94282484baae 13
andrewboyson 1:94282484baae 14 #define WHAT_NOT_FOUND 0
andrewboyson 1:94282484baae 15 #define WHAT_BAD_REQUEST 1
andrewboyson 1:94282484baae 16 #define WHAT_BAD_METHOD 2
andrewboyson 1:94282484baae 17 #define WHAT_LED 3
andrewboyson 1:94282484baae 18 #define WHAT_LOG 4
andrewboyson 1:94282484baae 19 static int whatToSendToId[4];
andrewboyson 1:94282484baae 20 static int lineToSendToId[4]; //0 == do nothing; -1 == close
andrewboyson 0:09f915e6f9f6 21
andrewboyson 2:06fa34661f19 22 int ServerInit(void) //Make sure this is only called after any other ids are reserved.
andrewboyson 0:09f915e6f9f6 23 {
andrewboyson 0:09f915e6f9f6 24 for (int id = 0; id < 4; id++)
andrewboyson 0:09f915e6f9f6 25 {
andrewboyson 0:09f915e6f9f6 26 if (!EspIpdReserved[id])
andrewboyson 0:09f915e6f9f6 27 {
andrewboyson 0:09f915e6f9f6 28 EspIpdBuffer[id] = recvbuffer;
andrewboyson 1:94282484baae 29 EspIpdBufferLen[id] = RECV_BUFFER_SIZE;
andrewboyson 1:94282484baae 30 }
andrewboyson 1:94282484baae 31 whatToSendToId[id] = 0;
andrewboyson 1:94282484baae 32 lineToSendToId[id] = 0;
andrewboyson 1:94282484baae 33 }
andrewboyson 2:06fa34661f19 34 return 0;
andrewboyson 1:94282484baae 35 }
andrewboyson 1:94282484baae 36
andrewboyson 1:94282484baae 37 static int addChunk(int prevlen, char *text)
andrewboyson 1:94282484baae 38 {
andrewboyson 1:94282484baae 39 strncpy(sendbuffer + prevlen, text, SEND_BUFFER_SIZE - prevlen);
andrewboyson 1:94282484baae 40 int len = prevlen + strlen(text);
andrewboyson 1:94282484baae 41 return len < SEND_BUFFER_SIZE ? len : SEND_BUFFER_SIZE;
andrewboyson 1:94282484baae 42 }
andrewboyson 1:94282484baae 43 static int fillChunk(char * text)
andrewboyson 1:94282484baae 44 {
andrewboyson 1:94282484baae 45 strncpy(sendbuffer, text, SEND_BUFFER_SIZE);
andrewboyson 1:94282484baae 46 int len = strlen(text);
andrewboyson 1:94282484baae 47 return len < SEND_BUFFER_SIZE ? len : SEND_BUFFER_SIZE;
andrewboyson 1:94282484baae 48 }
andrewboyson 1:94282484baae 49 static int fillNotFound(int id)
andrewboyson 1:94282484baae 50 {
andrewboyson 1:94282484baae 51 int len = fillChunk("HTTP/1.0 404 Not Found\r\n\r\n");
andrewboyson 1:94282484baae 52 lineToSendToId[id] = -1;
andrewboyson 1:94282484baae 53 return len;
andrewboyson 1:94282484baae 54 }
andrewboyson 1:94282484baae 55 static int fillBadRequest(int id)
andrewboyson 1:94282484baae 56 {
andrewboyson 1:94282484baae 57 int len = fillChunk("HTTP/1.0 400 Bad Request\r\n\r\n");
andrewboyson 1:94282484baae 58 lineToSendToId[id] = -1;
andrewboyson 1:94282484baae 59 return len;
andrewboyson 1:94282484baae 60 }
andrewboyson 1:94282484baae 61 static int fillBadMethod(int id)
andrewboyson 1:94282484baae 62 {
andrewboyson 1:94282484baae 63 int len = fillChunk("HTTP/1.0 405 Method Not Allowed\r\nAllow: GET\r\n\r\n");
andrewboyson 1:94282484baae 64 lineToSendToId[id] = -1;
andrewboyson 1:94282484baae 65 return len;
andrewboyson 1:94282484baae 66 }
andrewboyson 1:94282484baae 67 static int fillLogChunk() //Returns length. If length is less than the buffer size then that was the last chunk to send: that could mean a length of zero.
andrewboyson 1:94282484baae 68 {
andrewboyson 1:94282484baae 69 static int enumerationStarted = false;
andrewboyson 1:94282484baae 70 if (!enumerationStarted)
andrewboyson 1:94282484baae 71 {
andrewboyson 1:94282484baae 72 LogEnumerateStart();
andrewboyson 1:94282484baae 73 enumerationStarted = true;
andrewboyson 1:94282484baae 74 }
andrewboyson 1:94282484baae 75 char* p = sendbuffer;
andrewboyson 1:94282484baae 76 while (p < sendbuffer + SEND_BUFFER_SIZE)
andrewboyson 1:94282484baae 77 {
andrewboyson 1:94282484baae 78 int c = LogEnumerate();
andrewboyson 1:94282484baae 79 if (c == EOF)
andrewboyson 1:94282484baae 80 {
andrewboyson 1:94282484baae 81 enumerationStarted = false;
andrewboyson 1:94282484baae 82 break;
andrewboyson 0:09f915e6f9f6 83 }
andrewboyson 1:94282484baae 84 *p++ = c;
andrewboyson 1:94282484baae 85 }
andrewboyson 1:94282484baae 86 return p - sendbuffer;
andrewboyson 1:94282484baae 87 }
andrewboyson 1:94282484baae 88 static char* header =
andrewboyson 1:94282484baae 89 "HTTP/1.0 200 OK\r\n"
andrewboyson 1:94282484baae 90 "Content-Type: text/html; charset=ISO-8859-1\r\n"
andrewboyson 1:94282484baae 91 "\r\n"
andrewboyson 1:94282484baae 92 "<!DOCTYPE html>\r\n"
andrewboyson 1:94282484baae 93 "<html>\r\n"
andrewboyson 1:94282484baae 94 "<head>\r\n"
andrewboyson 1:94282484baae 95 "<title>IoT mbed</title>\r\n"
andrewboyson 1:94282484baae 96 "</head>\r\n"
andrewboyson 1:94282484baae 97 "<body>\r\n";
andrewboyson 1:94282484baae 98
andrewboyson 1:94282484baae 99 static int fillLog(int id)
andrewboyson 1:94282484baae 100 {
andrewboyson 1:94282484baae 101 int len = 0;
andrewboyson 1:94282484baae 102
andrewboyson 1:94282484baae 103 switch (lineToSendToId[id])
andrewboyson 1:94282484baae 104 {
andrewboyson 1:94282484baae 105 case 1: len = fillChunk(header); lineToSendToId[id] += 1; break;
andrewboyson 1:94282484baae 106 case 2: len = fillChunk("<code><pre>"); lineToSendToId[id] += 1; break;
andrewboyson 1:94282484baae 107 case 3: len = fillLogChunk(); if (len < SEND_BUFFER_SIZE) lineToSendToId[id] += 1; break; //only increments after the last chunk
andrewboyson 1:94282484baae 108 case 4: len = fillChunk(
andrewboyson 1:94282484baae 109 "</pre></code>\r\n"
andrewboyson 1:94282484baae 110 "</body>\r\n"
andrewboyson 1:94282484baae 111 "</html>\r\n");
andrewboyson 1:94282484baae 112 lineToSendToId[id] = -1;
andrewboyson 1:94282484baae 113 break;
andrewboyson 1:94282484baae 114 }
andrewboyson 1:94282484baae 115 return len;
andrewboyson 1:94282484baae 116 }
andrewboyson 1:94282484baae 117
andrewboyson 1:94282484baae 118 static int fillLed(int id)
andrewboyson 1:94282484baae 119 {
andrewboyson 1:94282484baae 120 int len;
andrewboyson 1:94282484baae 121 switch (lineToSendToId[id])
andrewboyson 1:94282484baae 122 {
andrewboyson 1:94282484baae 123 case 1:
andrewboyson 1:94282484baae 124 len = fillChunk(header);
andrewboyson 1:94282484baae 125 lineToSendToId[id] += 1;
andrewboyson 1:94282484baae 126 break;
andrewboyson 1:94282484baae 127 case 2:
andrewboyson 2:06fa34661f19 128 len = fillChunk("Version: ");
andrewboyson 2:06fa34661f19 129 len = addChunk(len, AtEspVersion);
andrewboyson 2:06fa34661f19 130 len = addChunk(len, "\r\n");
andrewboyson 2:06fa34661f19 131 lineToSendToId[id] += 1;
andrewboyson 2:06fa34661f19 132 break;
andrewboyson 2:06fa34661f19 133 case 3:
andrewboyson 1:94282484baae 134 len = fillChunk(
andrewboyson 1:94282484baae 135 "<form action='/' method='get'>\r\n"
andrewboyson 1:94282484baae 136 "<input type='hidden' name='ledonoff'>\r\n");
andrewboyson 1:94282484baae 137 lineToSendToId[id] += 1;
andrewboyson 1:94282484baae 138 break;
andrewboyson 2:06fa34661f19 139 case 4:
andrewboyson 1:94282484baae 140 len = fillChunk("Led <input type='checkbox' name='led' value='on'");
andrewboyson 1:94282484baae 141 if (Led1) len = addChunk(len, " checked='checked'");
andrewboyson 1:94282484baae 142 len = addChunk(len, ">\r\n");
andrewboyson 1:94282484baae 143 lineToSendToId[id] += 1;
andrewboyson 1:94282484baae 144 break;
andrewboyson 2:06fa34661f19 145 case 5:
andrewboyson 1:94282484baae 146 len = fillChunk(
andrewboyson 1:94282484baae 147 "<input type='submit' value='Set'><br/>\r\n"
andrewboyson 1:94282484baae 148 "</form>\r\n"
andrewboyson 1:94282484baae 149 "</body>\r\n"
andrewboyson 1:94282484baae 150 "</html>\r\n");
andrewboyson 1:94282484baae 151 lineToSendToId[id] = -1;
andrewboyson 1:94282484baae 152 break;
andrewboyson 1:94282484baae 153 }
andrewboyson 1:94282484baae 154 return len;
andrewboyson 1:94282484baae 155 }
andrewboyson 1:94282484baae 156 static int fillSendBuffer(int id)
andrewboyson 1:94282484baae 157 {
andrewboyson 1:94282484baae 158 switch(whatToSendToId[id])
andrewboyson 1:94282484baae 159 {
andrewboyson 1:94282484baae 160 case WHAT_NOT_FOUND: return fillNotFound(id);
andrewboyson 1:94282484baae 161 case WHAT_BAD_REQUEST: return fillBadRequest(id);
andrewboyson 1:94282484baae 162 case WHAT_BAD_METHOD: return fillBadMethod(id);
andrewboyson 1:94282484baae 163 case WHAT_LOG: return fillLog(id);
andrewboyson 1:94282484baae 164 case WHAT_LED: return fillLed(id);
andrewboyson 1:94282484baae 165 default:
andrewboyson 1:94282484baae 166 LogF("No such 'whatToSendToId' %s", whatToSendToId[id]);
andrewboyson 1:94282484baae 167 return -1;
andrewboyson 0:09f915e6f9f6 168 }
andrewboyson 0:09f915e6f9f6 169 }
andrewboyson 1:94282484baae 170 static int splitRequest(char** ppMethod, char** ppPath, char** ppQuery, int *pLenMethod, int *pLenPath, int *pLenQuery) //returns 1 if malformed request; 0 if ok
andrewboyson 0:09f915e6f9f6 171 {
andrewboyson 1:94282484baae 172 char* p = recvbuffer;
andrewboyson 1:94282484baae 173 char* pE = recvbuffer + RECV_BUFFER_SIZE;
andrewboyson 1:94282484baae 174
andrewboyson 1:94282484baae 175 *ppMethod = NULL;
andrewboyson 1:94282484baae 176 *ppPath = NULL;
andrewboyson 1:94282484baae 177 *ppQuery = NULL;
andrewboyson 1:94282484baae 178 *pLenMethod = 0;
andrewboyson 1:94282484baae 179 *pLenPath = 0;
andrewboyson 1:94282484baae 180 *pLenQuery = 0;
andrewboyson 0:09f915e6f9f6 181
andrewboyson 1:94282484baae 182 while (*p == ' ') //Loop to non space
andrewboyson 1:94282484baae 183 {
andrewboyson 1:94282484baae 184 if (p == pE) return -1;
andrewboyson 1:94282484baae 185 if (*p < ' ') return -1;
andrewboyson 1:94282484baae 186 if (*p >= 0x7f) return -1;
andrewboyson 1:94282484baae 187 p++;
andrewboyson 1:94282484baae 188 }
andrewboyson 1:94282484baae 189 *ppMethod = p; //Record the start of the method GET or POST
andrewboyson 1:94282484baae 190
andrewboyson 1:94282484baae 191 while (*p != ' ') //Loop to a space
andrewboyson 1:94282484baae 192 {
andrewboyson 1:94282484baae 193 if (p == pE) return -1;
andrewboyson 1:94282484baae 194 if (*p < ' ') return -1;
andrewboyson 1:94282484baae 195 if (*p >= 0x7f) return -1;
andrewboyson 1:94282484baae 196 p++;
andrewboyson 1:94282484baae 197 }
andrewboyson 1:94282484baae 198 *pLenMethod = p - *ppMethod; //Record the length of the method GET or POST
andrewboyson 0:09f915e6f9f6 199
andrewboyson 1:94282484baae 200
andrewboyson 1:94282484baae 201 while (*p == ' ') //Loop to non space
andrewboyson 1:94282484baae 202 {
andrewboyson 1:94282484baae 203 if (p == pE) return -1;
andrewboyson 1:94282484baae 204 if (*p < ' ') return -1;
andrewboyson 1:94282484baae 205 if (*p >= 0x7f) return -1;
andrewboyson 1:94282484baae 206 p++;
andrewboyson 1:94282484baae 207 }
andrewboyson 1:94282484baae 208 *ppPath = p; //Record the start of the file part of the url
andrewboyson 1:94282484baae 209
andrewboyson 1:94282484baae 210 while (*p != ' ') //Loop to space
andrewboyson 1:94282484baae 211 {
andrewboyson 1:94282484baae 212 if (p == pE) return -1;
andrewboyson 1:94282484baae 213 if (*p < ' ') return -1;
andrewboyson 1:94282484baae 214 if (*p >= 0x7f) return -1;
andrewboyson 1:94282484baae 215 if (*p == '?') *ppQuery = p + 1;
andrewboyson 1:94282484baae 216 p++;
andrewboyson 1:94282484baae 217 }
andrewboyson 1:94282484baae 218
andrewboyson 1:94282484baae 219 if (*ppQuery) //Calulate length of the file and query parts
andrewboyson 0:09f915e6f9f6 220 {
andrewboyson 1:94282484baae 221 *pLenPath = *ppQuery - *ppPath - 1;
andrewboyson 1:94282484baae 222 *pLenQuery = p - *ppQuery;
andrewboyson 1:94282484baae 223 }
andrewboyson 1:94282484baae 224 else
andrewboyson 1:94282484baae 225 {
andrewboyson 1:94282484baae 226 *pLenPath = p - *ppPath;
andrewboyson 1:94282484baae 227 *pLenQuery = 0;
andrewboyson 1:94282484baae 228 }
andrewboyson 1:94282484baae 229
andrewboyson 1:94282484baae 230 return 0;
andrewboyson 1:94282484baae 231 }
andrewboyson 1:94282484baae 232 int compare(char* mem, int len, char* str) //Returns true if same and false if not
andrewboyson 1:94282484baae 233 {
andrewboyson 1:94282484baae 234 if (strlen(str) != len) return false;
andrewboyson 1:94282484baae 235 if (memcmp(mem, str, len)) return false;
andrewboyson 1:94282484baae 236 return true;
andrewboyson 1:94282484baae 237 }
andrewboyson 1:94282484baae 238 static int recvMain()
andrewboyson 1:94282484baae 239 {
andrewboyson 1:94282484baae 240 //Wait for data to be available oneshot
andrewboyson 1:94282484baae 241 if (EspDataAvailable != ESP_AVAILABLE) return 0;
andrewboyson 1:94282484baae 242
andrewboyson 1:94282484baae 243 //Ignore ids that have been reserved elsewhere (ie NTP)
andrewboyson 1:94282484baae 244 if (EspIpdReserved[EspIpdId]) return 0;
andrewboyson 1:94282484baae 245
andrewboyson 1:94282484baae 246 //Set up the next line to send to be the first
andrewboyson 1:94282484baae 247 lineToSendToId[EspIpdId] = 1;
andrewboyson 1:94282484baae 248
andrewboyson 1:94282484baae 249 char* pMethod;
andrewboyson 1:94282484baae 250 char* pPath;
andrewboyson 1:94282484baae 251 char* pQuery;
andrewboyson 1:94282484baae 252 int lenMethod;
andrewboyson 1:94282484baae 253 int lenQuery;
andrewboyson 1:94282484baae 254 int lenPath;
andrewboyson 1:94282484baae 255 int r = splitRequest(&pMethod, &pPath, &pQuery, &lenMethod, &lenPath, &lenQuery);
andrewboyson 1:94282484baae 256 if (r)
andrewboyson 1:94282484baae 257 {
andrewboyson 1:94282484baae 258 whatToSendToId[EspIpdId] = WHAT_BAD_REQUEST;
andrewboyson 1:94282484baae 259 return 0;
andrewboyson 1:94282484baae 260 }
andrewboyson 1:94282484baae 261
andrewboyson 1:94282484baae 262 if (!compare(pMethod, lenMethod, "GET"))
andrewboyson 1:94282484baae 263 {
andrewboyson 1:94282484baae 264 whatToSendToId[EspIpdId] = WHAT_BAD_METHOD;
andrewboyson 1:94282484baae 265 return 0;
andrewboyson 1:94282484baae 266 }
andrewboyson 1:94282484baae 267
andrewboyson 1:94282484baae 268 if (compare(pPath, lenPath, "/"))
andrewboyson 1:94282484baae 269 {
andrewboyson 1:94282484baae 270 if (pQuery)
andrewboyson 0:09f915e6f9f6 271 {
andrewboyson 1:94282484baae 272 if (compare(pQuery, lenQuery, "ledonoff=&led=on")) Led1 = 1;
andrewboyson 1:94282484baae 273 if (compare(pQuery, lenQuery, "ledonoff=" )) Led1 = 0;
andrewboyson 0:09f915e6f9f6 274 }
andrewboyson 1:94282484baae 275 whatToSendToId[EspIpdId] = WHAT_LED;
andrewboyson 1:94282484baae 276 return 0;
andrewboyson 1:94282484baae 277 }
andrewboyson 1:94282484baae 278
andrewboyson 1:94282484baae 279 if (compare(pPath, lenPath, "/log"))
andrewboyson 1:94282484baae 280 {
andrewboyson 1:94282484baae 281 whatToSendToId[EspIpdId] = WHAT_LOG;
andrewboyson 1:94282484baae 282 return 0;
andrewboyson 1:94282484baae 283 }
andrewboyson 1:94282484baae 284
andrewboyson 1:94282484baae 285 whatToSendToId[EspIpdId] = WHAT_NOT_FOUND;
andrewboyson 1:94282484baae 286 return 0;
andrewboyson 1:94282484baae 287 }
andrewboyson 1:94282484baae 288 static int sendMain()
andrewboyson 1:94282484baae 289 {
andrewboyson 1:94282484baae 290 //Do nothing if a command is already in progress
andrewboyson 1:94282484baae 291 if (AtBusy()) return 0;
andrewboyson 1:94282484baae 292
andrewboyson 1:94282484baae 293 //Send data. Do each id in turn to avoid interleaved calls to fillers like LogEnumerate which are not reentrant.
andrewboyson 1:94282484baae 294 for(int id = 0; id < 4; id++)
andrewboyson 1:94282484baae 295 {
andrewboyson 1:94282484baae 296 if (lineToSendToId[id] > 0)
andrewboyson 0:09f915e6f9f6 297 {
andrewboyson 1:94282484baae 298 int length = fillSendBuffer(id);
andrewboyson 1:94282484baae 299 if (length < 0) return -1;
andrewboyson 1:94282484baae 300 if (length > 0) AtSendData(id, length, sendbuffer, NULL);
andrewboyson 1:94282484baae 301 }
andrewboyson 1:94282484baae 302 else if (lineToSendToId[id] < 0)
andrewboyson 1:94282484baae 303 {
andrewboyson 1:94282484baae 304 AtClose(id, NULL);
andrewboyson 1:94282484baae 305 lineToSendToId[id] = 0;
andrewboyson 0:09f915e6f9f6 306 }
andrewboyson 0:09f915e6f9f6 307 }
andrewboyson 0:09f915e6f9f6 308
andrewboyson 1:94282484baae 309 return 0;
andrewboyson 1:94282484baae 310 }
andrewboyson 1:94282484baae 311 int startMain()
andrewboyson 1:94282484baae 312 {
andrewboyson 1:94282484baae 313 //Do nothing if a command is already in progress
andrewboyson 1:94282484baae 314 if (AtBusy()) return 0;
andrewboyson 1:94282484baae 315
andrewboyson 1:94282484baae 316 //Do nothing until WiFi is running
andrewboyson 1:94282484baae 317 if (!WifiStarted()) return 0;
andrewboyson 0:09f915e6f9f6 318
andrewboyson 1:94282484baae 319 //Start the server if not started
andrewboyson 1:94282484baae 320 static int startServerReply = AT_NONE;
andrewboyson 1:94282484baae 321 if (startServerReply != AT_SUCCESS) AtStartServer(SERVER_PORT, &startServerReply);
andrewboyson 1:94282484baae 322 return 0;
andrewboyson 1:94282484baae 323 }
andrewboyson 1:94282484baae 324 int ServerMain()
andrewboyson 1:94282484baae 325 {
andrewboyson 1:94282484baae 326 if (startMain()) return -1;
andrewboyson 1:94282484baae 327 if ( recvMain()) return -1;
andrewboyson 1:94282484baae 328 if ( sendMain()) return -1;
andrewboyson 0:09f915e6f9f6 329
andrewboyson 0:09f915e6f9f6 330 return 0;
andrewboyson 0:09f915e6f9f6 331 }