NetworkServices with NUCLEO-L476RG and W5500 by SeeedStudio stack.

Dependents:   coap-example Borsch coap-example

Fork of NetworkServices by AMETEK Powervar

Committer:
dgriffin65
Date:
Thu Jun 15 20:29:03 2017 +0000
Revision:
15:14382459c8b7
Converted to a single library

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