NetworkServices with NUCLEO-L476RG and W5500 by SeeedStudio stack.

Dependents:   coap-example Borsch coap-example

Fork of NetworkServices by AMETEK Powervar

Committer:
sgnezdov
Date:
Wed Jul 05 18:34:39 2017 +0000
Revision:
17:c976088bf39d
Parent:
15:14382459c8b7
Changed setup interface to take MAC address, because W5500 may use software defined MAC when obtaining IP.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgriffin65 15:14382459c8b7 1 /* Copyright (C) 2013 Hiroshi Suga, MIT License
dgriffin65 15:14382459c8b7 2 *
dgriffin65 15:14382459c8b7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
dgriffin65 15:14382459c8b7 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
dgriffin65 15:14382459c8b7 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
dgriffin65 15:14382459c8b7 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
dgriffin65 15:14382459c8b7 7 * furnished to do so, subject to the following conditions:
dgriffin65 15:14382459c8b7 8 *
dgriffin65 15:14382459c8b7 9 * The above copyright notice and this permission notice shall be included in all copies or
dgriffin65 15:14382459c8b7 10 * substantial portions of the Software.
dgriffin65 15:14382459c8b7 11 *
dgriffin65 15:14382459c8b7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
dgriffin65 15:14382459c8b7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
dgriffin65 15:14382459c8b7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
dgriffin65 15:14382459c8b7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dgriffin65 15:14382459c8b7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
dgriffin65 15:14382459c8b7 17 */
dgriffin65 15:14382459c8b7 18
dgriffin65 15:14382459c8b7 19 #include "HTTPD.h"
dgriffin65 15:14382459c8b7 20 #include <ctype.h>
dgriffin65 15:14382459c8b7 21 #include <stdlib.h>
dgriffin65 15:14382459c8b7 22 #include <string.h>
dgriffin65 15:14382459c8b7 23
dgriffin65 15:14382459c8b7 24 #define MIMETABLE_NUM 9
dgriffin65 15:14382459c8b7 25 static const struct {
dgriffin65 15:14382459c8b7 26 char ext[5];
dgriffin65 15:14382459c8b7 27 char type[24];
dgriffin65 15:14382459c8b7 28 } mimetable[MIMETABLE_NUM] = {
dgriffin65 15:14382459c8b7 29 {"txt", "text/plain"}, // default
dgriffin65 15:14382459c8b7 30 {"html", "text/html"},
dgriffin65 15:14382459c8b7 31 {"htm", "text/html"},
dgriffin65 15:14382459c8b7 32 {"css", "text/css"},
dgriffin65 15:14382459c8b7 33 {"js", "application/javascript"},
dgriffin65 15:14382459c8b7 34 {"jpg", "image/jpeg"},
dgriffin65 15:14382459c8b7 35 {"png", "image/png"},
dgriffin65 15:14382459c8b7 36 {"gif", "image/gif"},
dgriffin65 15:14382459c8b7 37 {"ico", "image/x-icon"},
dgriffin65 15:14382459c8b7 38 };
dgriffin65 15:14382459c8b7 39
dgriffin65 15:14382459c8b7 40 char *HTTPD::getUri (int id) {
dgriffin65 15:14382459c8b7 41 return _state[id].uri;
dgriffin65 15:14382459c8b7 42 }
dgriffin65 15:14382459c8b7 43
dgriffin65 15:14382459c8b7 44 char *HTTPD::getFilename (int id) {
dgriffin65 15:14382459c8b7 45 return _state[id].filename;
dgriffin65 15:14382459c8b7 46 }
dgriffin65 15:14382459c8b7 47
dgriffin65 15:14382459c8b7 48 char *HTTPD::getQueryString (int id) {
dgriffin65 15:14382459c8b7 49 return _state[id].querystring;
dgriffin65 15:14382459c8b7 50 }
dgriffin65 15:14382459c8b7 51
dgriffin65 15:14382459c8b7 52 int HTTPD::receive (int id, char *buf, int len) {
dgriffin65 15:14382459c8b7 53 int i;
dgriffin65 15:14382459c8b7 54
dgriffin65 15:14382459c8b7 55 for (i = 0; i < len; i ++) {
dgriffin65 15:14382459c8b7 56 if (_state[id].buf->dequeue(&buf[i]) == false) break;
dgriffin65 15:14382459c8b7 57 }
dgriffin65 15:14382459c8b7 58 return i;
dgriffin65 15:14382459c8b7 59 }
dgriffin65 15:14382459c8b7 60
dgriffin65 15:14382459c8b7 61 int HTTPD::send (int id, const char *body, int len, const char *header) {
dgriffin65 15:14382459c8b7 62 char buf[HTTPD_CMD_SIZE];
dgriffin65 15:14382459c8b7 63
dgriffin65 15:14382459c8b7 64 strcpy(buf, "HTTP/1.1 200 OK\r\n");
dgriffin65 15:14382459c8b7 65 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 66 strcpy(buf, "Server: GSwifi httpd\r\n");
dgriffin65 15:14382459c8b7 67 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 68 if (_state[id].keepalive) {
dgriffin65 15:14382459c8b7 69 strcpy(buf, "Connection: Keep-Alive\r\n");
dgriffin65 15:14382459c8b7 70 } else {
dgriffin65 15:14382459c8b7 71 strcpy(buf, "Connection: close\r\n");
dgriffin65 15:14382459c8b7 72 }
dgriffin65 15:14382459c8b7 73 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 74 if (header) {
dgriffin65 15:14382459c8b7 75 _state[id].client->send((char*)header, strlen(header));
dgriffin65 15:14382459c8b7 76 }
dgriffin65 15:14382459c8b7 77 sprintf(buf, "Content-Length: %d\r\n\r\n", len);
dgriffin65 15:14382459c8b7 78 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 79
dgriffin65 15:14382459c8b7 80 return _state[id].client->send((char*)body, len);
dgriffin65 15:14382459c8b7 81 }
dgriffin65 15:14382459c8b7 82
dgriffin65 15:14382459c8b7 83 int HTTPD::sendstr (int id, const char *buf) {
dgriffin65 15:14382459c8b7 84 return _state[id].client->send((char*)buf, strlen(buf));
dgriffin65 15:14382459c8b7 85 }
dgriffin65 15:14382459c8b7 86
dgriffin65 15:14382459c8b7 87
dgriffin65 15:14382459c8b7 88 int HTTPD::hprintf(int id, const char* format, ...) {
dgriffin65 15:14382459c8b7 89 //FIX ME: This could result in memory overruns if the buffer size is exceeded
dgriffin65 15:14382459c8b7 90 static Mutex _mtx;
dgriffin65 15:14382459c8b7 91 static char _buf[1024];
dgriffin65 15:14382459c8b7 92
dgriffin65 15:14382459c8b7 93 std::va_list arg;
dgriffin65 15:14382459c8b7 94
dgriffin65 15:14382459c8b7 95 _mtx.lock();
dgriffin65 15:14382459c8b7 96
dgriffin65 15:14382459c8b7 97 va_start(arg, format);
dgriffin65 15:14382459c8b7 98 vsprintf(_buf, format, arg);
dgriffin65 15:14382459c8b7 99 va_end(arg);
dgriffin65 15:14382459c8b7 100
dgriffin65 15:14382459c8b7 101 int r = _state[id].client->send(_buf, strlen(_buf));
dgriffin65 15:14382459c8b7 102
dgriffin65 15:14382459c8b7 103 _mtx.unlock();
dgriffin65 15:14382459c8b7 104 return r;
dgriffin65 15:14382459c8b7 105 }
dgriffin65 15:14382459c8b7 106
dgriffin65 15:14382459c8b7 107 int HTTPD::getHandler (const char *uri) {
dgriffin65 15:14382459c8b7 108 int i;
dgriffin65 15:14382459c8b7 109
dgriffin65 15:14382459c8b7 110 for (i = 0; i < _handler_count; i ++) {
dgriffin65 15:14382459c8b7 111 if (strncmp(uri, _handler[i].uri, strlen(_handler[i].uri)) == NULL) {
dgriffin65 15:14382459c8b7 112 // found
dgriffin65 15:14382459c8b7 113 return i;
dgriffin65 15:14382459c8b7 114 }
dgriffin65 15:14382459c8b7 115 }
dgriffin65 15:14382459c8b7 116 return -1;
dgriffin65 15:14382459c8b7 117 }
dgriffin65 15:14382459c8b7 118
dgriffin65 15:14382459c8b7 119 int HTTPD::attach (const char *uri, const char *dir) {
dgriffin65 15:14382459c8b7 120 if (_handler_count < HTTPD_MAX_HANDLES) {
dgriffin65 15:14382459c8b7 121 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
dgriffin65 15:14382459c8b7 122 strcpy(_handler[_handler_count].uri, uri);
dgriffin65 15:14382459c8b7 123 _handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1);
dgriffin65 15:14382459c8b7 124 strcpy(_handler[_handler_count].dir, dir);
dgriffin65 15:14382459c8b7 125 _handler[_handler_count].funcCgi = NULL;
dgriffin65 15:14382459c8b7 126 _handler_count ++;
dgriffin65 15:14382459c8b7 127 return 0;
dgriffin65 15:14382459c8b7 128 } else {
dgriffin65 15:14382459c8b7 129 return -1;
dgriffin65 15:14382459c8b7 130 }
dgriffin65 15:14382459c8b7 131 }
dgriffin65 15:14382459c8b7 132
dgriffin65 15:14382459c8b7 133 int HTTPD::attach (const char *uri, void (*funcCgi)(int)) {
dgriffin65 15:14382459c8b7 134 if (_handler_count < HTTPD_MAX_HANDLES) {
dgriffin65 15:14382459c8b7 135 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
dgriffin65 15:14382459c8b7 136 strcpy(_handler[_handler_count].uri, uri);
dgriffin65 15:14382459c8b7 137 _handler[_handler_count].dir = NULL;
dgriffin65 15:14382459c8b7 138 _handler[_handler_count].funcCgi = funcCgi;
dgriffin65 15:14382459c8b7 139 _handler_count ++;
dgriffin65 15:14382459c8b7 140 return 0;
dgriffin65 15:14382459c8b7 141 } else {
dgriffin65 15:14382459c8b7 142 return -1;
dgriffin65 15:14382459c8b7 143 }
dgriffin65 15:14382459c8b7 144 }
dgriffin65 15:14382459c8b7 145
dgriffin65 15:14382459c8b7 146
dgriffin65 15:14382459c8b7 147 char *HTTPD::mimetype (char *file) {
dgriffin65 15:14382459c8b7 148 int i, j;
dgriffin65 15:14382459c8b7 149
dgriffin65 15:14382459c8b7 150 for (i = 0; i < MIMETABLE_NUM; i ++) {
dgriffin65 15:14382459c8b7 151 j = strlen(mimetable[i].ext);
dgriffin65 15:14382459c8b7 152 if (file[strlen(file) - j - 1] == '.' &&
dgriffin65 15:14382459c8b7 153 strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
dgriffin65 15:14382459c8b7 154 return (char*)mimetable[i].type;
dgriffin65 15:14382459c8b7 155 }
dgriffin65 15:14382459c8b7 156 }
dgriffin65 15:14382459c8b7 157 return (char*)mimetable[0].type;
dgriffin65 15:14382459c8b7 158 }
dgriffin65 15:14382459c8b7 159
dgriffin65 15:14382459c8b7 160 int HTTPD::strnicmp (const char *p1, const char *p2, int n) {
dgriffin65 15:14382459c8b7 161 int i, r = -1;
dgriffin65 15:14382459c8b7 162 char c1, c2;
dgriffin65 15:14382459c8b7 163
dgriffin65 15:14382459c8b7 164 for (i = 0; i < n; i ++) {
dgriffin65 15:14382459c8b7 165 c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i];
dgriffin65 15:14382459c8b7 166 c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i];
dgriffin65 15:14382459c8b7 167 r = c1 - c2;
dgriffin65 15:14382459c8b7 168 if (r) break;
dgriffin65 15:14382459c8b7 169 }
dgriffin65 15:14382459c8b7 170 return r;
dgriffin65 15:14382459c8b7 171 }
dgriffin65 15:14382459c8b7 172
dgriffin65 15:14382459c8b7 173
dgriffin65 15:14382459c8b7 174 /* base64encode code from
dgriffin65 15:14382459c8b7 175 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 176 */
dgriffin65 15:14382459c8b7 177 int HTTPD::base64encode (const char *input, int length, char *output, int len) {
dgriffin65 15:14382459c8b7 178 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
dgriffin65 15:14382459c8b7 179 unsigned int c, c1, c2, c3;
dgriffin65 15:14382459c8b7 180
dgriffin65 15:14382459c8b7 181 if (len < ((((length-1)/3)+1)<<2)) return -1;
dgriffin65 15:14382459c8b7 182 for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
dgriffin65 15:14382459c8b7 183 c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
dgriffin65 15:14382459c8b7 184 c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
dgriffin65 15:14382459c8b7 185 c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
dgriffin65 15:14382459c8b7 186
dgriffin65 15:14382459c8b7 187 c = ((c1 & 0xFC) >> 2);
dgriffin65 15:14382459c8b7 188 output[j+0] = base64[c];
dgriffin65 15:14382459c8b7 189 c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
dgriffin65 15:14382459c8b7 190 output[j+1] = base64[c];
dgriffin65 15:14382459c8b7 191 c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
dgriffin65 15:14382459c8b7 192 output[j+2] = (length>i+1)?base64[c]:'=';
dgriffin65 15:14382459c8b7 193 c = (c3 & 0x3F);
dgriffin65 15:14382459c8b7 194 output[j+3] = (length>i+2)?base64[c]:'=';
dgriffin65 15:14382459c8b7 195 }
dgriffin65 15:14382459c8b7 196 output[(((length-1)/3)+1)<<2] = '\0';
dgriffin65 15:14382459c8b7 197 return 0;
dgriffin65 15:14382459c8b7 198 }
dgriffin65 15:14382459c8b7 199
dgriffin65 15:14382459c8b7 200
dgriffin65 15:14382459c8b7 201 /* urlencode code from
dgriffin65 15:14382459c8b7 202 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 203 */
dgriffin65 15:14382459c8b7 204 int HTTPD::urlencode (const char *str, char *buf, int len) {
dgriffin65 15:14382459c8b7 205 // char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
dgriffin65 15:14382459c8b7 206 const char *pstr = str;
dgriffin65 15:14382459c8b7 207 char *pbuf = buf;
dgriffin65 15:14382459c8b7 208
dgriffin65 15:14382459c8b7 209 if (len < (strlen(str) * 3 + 1)) return -1;
dgriffin65 15:14382459c8b7 210 while (*pstr) {
dgriffin65 15:14382459c8b7 211 if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
dgriffin65 15:14382459c8b7 212 *pbuf++ = *pstr;
dgriffin65 15:14382459c8b7 213 else if (*pstr == ' ')
dgriffin65 15:14382459c8b7 214 *pbuf++ = '+';
dgriffin65 15:14382459c8b7 215 else
dgriffin65 15:14382459c8b7 216 *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
dgriffin65 15:14382459c8b7 217 pstr++;
dgriffin65 15:14382459c8b7 218 }
dgriffin65 15:14382459c8b7 219 *pbuf = '\0';
dgriffin65 15:14382459c8b7 220 return 0;
dgriffin65 15:14382459c8b7 221 }
dgriffin65 15:14382459c8b7 222
dgriffin65 15:14382459c8b7 223 /* urldecode code from
dgriffin65 15:14382459c8b7 224 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 225 */
dgriffin65 15:14382459c8b7 226 int HTTPD::urldecode (const char *str, char *buf, int len) {
dgriffin65 15:14382459c8b7 227 // char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
dgriffin65 15:14382459c8b7 228 const char *pstr = str;
dgriffin65 15:14382459c8b7 229 char *pbuf = buf;
dgriffin65 15:14382459c8b7 230
dgriffin65 15:14382459c8b7 231 if (len < (strlen(str) / 3 - 1)) return -1;
dgriffin65 15:14382459c8b7 232 while (*pstr) {
dgriffin65 15:14382459c8b7 233 if (*pstr == '%') {
dgriffin65 15:14382459c8b7 234 if (pstr[1] && pstr[2]) {
dgriffin65 15:14382459c8b7 235 *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
dgriffin65 15:14382459c8b7 236 pstr += 2;
dgriffin65 15:14382459c8b7 237 }
dgriffin65 15:14382459c8b7 238 } else if (*pstr == '+') {
dgriffin65 15:14382459c8b7 239 *pbuf++ = ' ';
dgriffin65 15:14382459c8b7 240 } else {
dgriffin65 15:14382459c8b7 241 *pbuf++ = *pstr;
dgriffin65 15:14382459c8b7 242 }
dgriffin65 15:14382459c8b7 243 pstr++;
dgriffin65 15:14382459c8b7 244 }
dgriffin65 15:14382459c8b7 245 *pbuf = '\0';
dgriffin65 15:14382459c8b7 246 return 0;
dgriffin65 15:14382459c8b7 247 }
dgriffin65 15:14382459c8b7 248
dgriffin65 15:14382459c8b7 249 int HTTPD::from_hex (int ch) {
dgriffin65 15:14382459c8b7 250 return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
dgriffin65 15:14382459c8b7 251 }
dgriffin65 15:14382459c8b7 252
dgriffin65 15:14382459c8b7 253 int HTTPD::to_hex (int code) {
dgriffin65 15:14382459c8b7 254 static char hex[] = "0123456789abcdef";
dgriffin65 15:14382459c8b7 255 return hex[code & 15];
dgriffin65 15:14382459c8b7 256 }