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
dgriffin65 15:14382459c8b7 21 HTTPD * HTTPD::_inst;
dgriffin65 15:14382459c8b7 22
dgriffin65 15:14382459c8b7 23 HTTPD::HTTPD () {
dgriffin65 15:14382459c8b7 24 _inst = this;
dgriffin65 15:14382459c8b7 25 memset(_state, 0, sizeof(_state));
dgriffin65 15:14382459c8b7 26 _handler_count = 0;
dgriffin65 15:14382459c8b7 27 }
dgriffin65 15:14382459c8b7 28
dgriffin65 15:14382459c8b7 29 int HTTPD::start (NetworkStack *ns, int port) {
dgriffin65 15:14382459c8b7 30 int i;
dgriffin65 15:14382459c8b7 31
dgriffin65 15:14382459c8b7 32 m_ns = ns;
dgriffin65 15:14382459c8b7 33
dgriffin65 15:14382459c8b7 34 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) {
dgriffin65 15:14382459c8b7 35 _state[i].buf = new CircBuffer<char>(HTTPD_BUF_SIZE);
dgriffin65 15:14382459c8b7 36 _state[i].thread = new Thread(osPriorityNormal, HTTPD_STACK_SIZE);
dgriffin65 15:14382459c8b7 37 _state[i].client = new TCPSocket();
dgriffin65 15:14382459c8b7 38 _state[i].thread->start(callback(child, (void*)i));
dgriffin65 15:14382459c8b7 39 }
dgriffin65 15:14382459c8b7 40
dgriffin65 15:14382459c8b7 41 #ifdef HTTPD_ENABLE_CLOSER
dgriffin65 15:14382459c8b7 42 _state[HTTPD_MAX_CLIENTS].thread = new Thread(closer, (void*)HTTPD_MAX_CLIENTS, osPriorityNormal, 128);
dgriffin65 15:14382459c8b7 43 _state[HTTPD_MAX_CLIENTS].client = new TCPSocket(m_ns);
dgriffin65 15:14382459c8b7 44 #endif
dgriffin65 15:14382459c8b7 45
dgriffin65 15:14382459c8b7 46 _server.open(m_ns);
dgriffin65 15:14382459c8b7 47 _server.bind(port);
dgriffin65 15:14382459c8b7 48 _server.set_blocking(true);
dgriffin65 15:14382459c8b7 49 _server.listen();
dgriffin65 15:14382459c8b7 50 _daemon = new Thread(osPriorityNormal, HTTPD_STACK_SIZE);
dgriffin65 15:14382459c8b7 51 _daemon->start(HTTPD::daemon);
dgriffin65 15:14382459c8b7 52 return 0;
dgriffin65 15:14382459c8b7 53 }
dgriffin65 15:14382459c8b7 54
dgriffin65 15:14382459c8b7 55 void HTTPD::daemon () {
dgriffin65 15:14382459c8b7 56 HTTPD *httpd = HTTPD::getInstance();
dgriffin65 15:14382459c8b7 57 int i, t = 0;
dgriffin65 15:14382459c8b7 58
dgriffin65 15:14382459c8b7 59 INFO("Wait for new connection...\r\n");
dgriffin65 15:14382459c8b7 60 for (;;) {
dgriffin65 15:14382459c8b7 61 if (t >= 0) {
dgriffin65 15:14382459c8b7 62 if (httpd->_server.accept(httpd->_state[t].client) == 0) {
dgriffin65 15:14382459c8b7 63 INFO("accept %d\r\n", t);
dgriffin65 15:14382459c8b7 64 httpd->_state[t].thread->signal_set(1);
dgriffin65 15:14382459c8b7 65 }
dgriffin65 15:14382459c8b7 66 } else {
dgriffin65 15:14382459c8b7 67 #ifdef HTTPD_ENABLE_CLOSER
dgriffin65 15:14382459c8b7 68 if (httpd->_server.accept(httpd->_state[HTTPD_MAX_CLIENTS].client) == 0) {
dgriffin65 15:14382459c8b7 69 INFO("accept x\r\n");
dgriffin65 15:14382459c8b7 70 httpd->_state[HTTPD_MAX_CLIENTS].thread->signal_set(1);
dgriffin65 15:14382459c8b7 71 }
dgriffin65 15:14382459c8b7 72 #endif
dgriffin65 15:14382459c8b7 73 }
dgriffin65 15:14382459c8b7 74
dgriffin65 15:14382459c8b7 75 t = -1;
dgriffin65 15:14382459c8b7 76 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) {
dgriffin65 15:14382459c8b7 77 if (httpd->_state[i].thread->get_state() == Thread::WaitingAnd) {
dgriffin65 15:14382459c8b7 78 if (t < 0) t = i; // next empty thread
dgriffin65 15:14382459c8b7 79 }
dgriffin65 15:14382459c8b7 80 }
dgriffin65 15:14382459c8b7 81 }
dgriffin65 15:14382459c8b7 82 }
dgriffin65 15:14382459c8b7 83
dgriffin65 15:14382459c8b7 84 void HTTPD::child (void const *arg) {
dgriffin65 15:14382459c8b7 85 HTTPD *httpd = HTTPD::getInstance();
dgriffin65 15:14382459c8b7 86 int id = (int)arg;
dgriffin65 15:14382459c8b7 87 int i, n;
dgriffin65 15:14382459c8b7 88 char buf[HTTPD_BUF_SIZE];
dgriffin65 15:14382459c8b7 89
dgriffin65 15:14382459c8b7 90 for (;;) {
dgriffin65 15:14382459c8b7 91 Thread::signal_wait(1);
dgriffin65 15:14382459c8b7 92 httpd->_state[id].mode = MODE_REQUEST;
dgriffin65 15:14382459c8b7 93 httpd->_state[id].buf->flush();
dgriffin65 15:14382459c8b7 94 httpd->_state[id].keepalive = 0;
dgriffin65 15:14382459c8b7 95 INFO("Connection from client\r\n");
dgriffin65 15:14382459c8b7 96 // INFO("Connection from %s\r\n", httpd->_state[id].client->get_ip_address());
dgriffin65 15:14382459c8b7 97
dgriffin65 15:14382459c8b7 98 httpd->_state[id].client->set_blocking(false);
dgriffin65 15:14382459c8b7 99 httpd->_state[id].client->set_timeout(HTTPD_TIMEOUT);
dgriffin65 15:14382459c8b7 100
dgriffin65 15:14382459c8b7 101 for (;;) {
dgriffin65 15:14382459c8b7 102 //if (! httpd->_state[id].client->is_connected()) break;
dgriffin65 15:14382459c8b7 103
dgriffin65 15:14382459c8b7 104 n = httpd->_state[id].client->recv(buf, sizeof(buf));
dgriffin65 15:14382459c8b7 105
dgriffin65 15:14382459c8b7 106 if (n < 0 ) {
dgriffin65 15:14382459c8b7 107 printf("HTTPD::child breaking n = %d\r\n", n);
dgriffin65 15:14382459c8b7 108 break;
dgriffin65 15:14382459c8b7 109 }
dgriffin65 15:14382459c8b7 110 buf[n] = 0;
dgriffin65 15:14382459c8b7 111 //DBG("Recv %d ", n);
dgriffin65 15:14382459c8b7 112 DBG("Recv %d '%s'", n, buf);
dgriffin65 15:14382459c8b7 113
dgriffin65 15:14382459c8b7 114 for (i = 0; i < n; i ++) {
dgriffin65 15:14382459c8b7 115 httpd->recvData(id, buf[i]);
dgriffin65 15:14382459c8b7 116 }
dgriffin65 15:14382459c8b7 117 }
dgriffin65 15:14382459c8b7 118
dgriffin65 15:14382459c8b7 119 httpd->_state[id].client->close();
dgriffin65 15:14382459c8b7 120 INFO("Closed client connection\r\n");
dgriffin65 15:14382459c8b7 121 //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address());
dgriffin65 15:14382459c8b7 122 }
dgriffin65 15:14382459c8b7 123 }
dgriffin65 15:14382459c8b7 124
dgriffin65 15:14382459c8b7 125 void HTTPD::closer (void const *arg) {
dgriffin65 15:14382459c8b7 126 HTTPD *httpd = HTTPD::getInstance();
dgriffin65 15:14382459c8b7 127 int id = (int)arg;
dgriffin65 15:14382459c8b7 128
dgriffin65 15:14382459c8b7 129 for (;;) {
dgriffin65 15:14382459c8b7 130 Thread::signal_wait(1);
dgriffin65 15:14382459c8b7 131
dgriffin65 15:14382459c8b7 132 httpd->_state[id].client->close();
dgriffin65 15:14382459c8b7 133 INFO("Closed client connection\r\n");
dgriffin65 15:14382459c8b7 134 //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address());
dgriffin65 15:14382459c8b7 135 }
dgriffin65 15:14382459c8b7 136 }
dgriffin65 15:14382459c8b7 137