lwip-1.4.1 (partial)

Dependents:   IGLOO_board

Committer:
ua1arn
Date:
Tue Jul 24 17:36:01 2018 +0000
Revision:
1:119c4f7144c8
lwip 1.4.1 with necessary servers

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ua1arn 1:119c4f7144c8 1 /*
ua1arn 1:119c4f7144c8 2 * The MIT License (MIT)
ua1arn 1:119c4f7144c8 3 *
ua1arn 1:119c4f7144c8 4 * Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
ua1arn 1:119c4f7144c8 5 *
ua1arn 1:119c4f7144c8 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
ua1arn 1:119c4f7144c8 7 * of this software and associated documentation files (the "Software"), to deal
ua1arn 1:119c4f7144c8 8 * in the Software without restriction, including without limitation the rights
ua1arn 1:119c4f7144c8 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ua1arn 1:119c4f7144c8 10 * copies of the Software, and to permit persons to whom the Software is
ua1arn 1:119c4f7144c8 11 * furnished to do so, subject to the following conditions:
ua1arn 1:119c4f7144c8 12 *
ua1arn 1:119c4f7144c8 13 * The above copyright notice and this permission notice shall be included in all
ua1arn 1:119c4f7144c8 14 * copies or substantial portions of the Software.
ua1arn 1:119c4f7144c8 15 *
ua1arn 1:119c4f7144c8 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ua1arn 1:119c4f7144c8 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ua1arn 1:119c4f7144c8 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ua1arn 1:119c4f7144c8 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ua1arn 1:119c4f7144c8 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ua1arn 1:119c4f7144c8 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
ua1arn 1:119c4f7144c8 22 * SOFTWARE.
ua1arn 1:119c4f7144c8 23 */
ua1arn 1:119c4f7144c8 24
ua1arn 1:119c4f7144c8 25 /*
ua1arn 1:119c4f7144c8 26 * version: 1.0 demo (7.02.2015)
ua1arn 1:119c4f7144c8 27 * brief: tiny http ipv4 server using lwip (pcb)
ua1arn 1:119c4f7144c8 28 */
ua1arn 1:119c4f7144c8 29
ua1arn 1:119c4f7144c8 30 #include "htserv.h"
ua1arn 1:119c4f7144c8 31
ua1arn 1:119c4f7144c8 32 static struct tcp_pcb *http_pcb = NULL;
ua1arn 1:119c4f7144c8 33
ua1arn 1:119c4f7144c8 34 htserv_on_req_t htserv_on_req = NULL;
ua1arn 1:119c4f7144c8 35 htserv_on_con_t htserv_on_con = NULL;
ua1arn 1:119c4f7144c8 36 htserv_on_err_t htserv_on_err = NULL;
ua1arn 1:119c4f7144c8 37
ua1arn 1:119c4f7144c8 38 typedef enum htcon_state_priv
ua1arn 1:119c4f7144c8 39 {
ua1arn 1:119c4f7144c8 40 CSP_ACTIVE, // as CON_ACTIVE
ua1arn 1:119c4f7144c8 41 CSP_CLOSING, // as CON_CLOSING
ua1arn 1:119c4f7144c8 42 CSP_CLOSED, // as CON_CLOSED
ua1arn 1:119c4f7144c8 43 CSP_RD_REQ,
ua1arn 1:119c4f7144c8 44 CSP_WR_RESP,
ua1arn 1:119c4f7144c8 45 CSP_NONE,
ua1arn 1:119c4f7144c8 46 } htcon_state_priv_t;
ua1arn 1:119c4f7144c8 47
ua1arn 1:119c4f7144c8 48 typedef struct htcon_priv
ua1arn 1:119c4f7144c8 49 {
ua1arn 1:119c4f7144c8 50 htcon_t htcon; // user connection struct
ua1arn 1:119c4f7144c8 51 char buff[HTTP_CON_BUFF_SIZE]; // request/response buffer
ua1arn 1:119c4f7144c8 52 htcon_state_priv_t state; // connection state
ua1arn 1:119c4f7144c8 53 struct tcp_pcb *pcb; // connection pcb
ua1arn 1:119c4f7144c8 54 http_reqb_t reqb; // request buffer
ua1arn 1:119c4f7144c8 55 http_resp_t resp; // responce
ua1arn 1:119c4f7144c8 56 // writing managment
ua1arn 1:119c4f7144c8 57 char *wbuff; // writing buffer
ua1arn 1:119c4f7144c8 58 int wsize; // writing buffer size
ua1arn 1:119c4f7144c8 59 int writed; // writed to buffer
ua1arn 1:119c4f7144c8 60 int wsended; // sended by tcp
ua1arn 1:119c4f7144c8 61 int wacksize; // acknowledged
ua1arn 1:119c4f7144c8 62 } htcon_priv_t;
ua1arn 1:119c4f7144c8 63
ua1arn 1:119c4f7144c8 64 htcon_priv_t htcons[HTTP_SERVER_MAX_CON];
ua1arn 1:119c4f7144c8 65
ua1arn 1:119c4f7144c8 66 void htserv_io(void);
ua1arn 1:119c4f7144c8 67
ua1arn 1:119c4f7144c8 68 void http_prepare_resp(http_resp_t *resp, int code)
ua1arn 1:119c4f7144c8 69 {
ua1arn 1:119c4f7144c8 70 resp->code = code;
ua1arn 1:119c4f7144c8 71 resp->server = HTTP_SERVER_NAME;
ua1arn 1:119c4f7144c8 72 resp->cont_lang = HTTP_DEF_CONT_LANG;
ua1arn 1:119c4f7144c8 73 resp->mime = MIME_TEXT_HTML;
ua1arn 1:119c4f7144c8 74 resp->cont_len = 0;
ua1arn 1:119c4f7144c8 75 resp->conn_type = CT_CLOSE;
ua1arn 1:119c4f7144c8 76 }
ua1arn 1:119c4f7144c8 77
ua1arn 1:119c4f7144c8 78 void htcon_req_finished(htcon_priv_t *con)
ua1arn 1:119c4f7144c8 79 {
ua1arn 1:119c4f7144c8 80 // 1. check request
ua1arn 1:119c4f7144c8 81 if (con->reqb.req.method != METHOD_GET)
ua1arn 1:119c4f7144c8 82 {
ua1arn 1:119c4f7144c8 83 //http_prepare_resp(&con->resp, 405); // Method Not Allowed
ua1arn 1:119c4f7144c8 84 //con->state = CSP_WR_RESP;
ua1arn 1:119c4f7144c8 85 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 86 htserv_io();
ua1arn 1:119c4f7144c8 87 return;
ua1arn 1:119c4f7144c8 88 }
ua1arn 1:119c4f7144c8 89 // 2. ask user
ua1arn 1:119c4f7144c8 90 if (htserv_on_req == NULL)
ua1arn 1:119c4f7144c8 91 {
ua1arn 1:119c4f7144c8 92 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 93 htserv_io();
ua1arn 1:119c4f7144c8 94 return;
ua1arn 1:119c4f7144c8 95 }
ua1arn 1:119c4f7144c8 96
ua1arn 1:119c4f7144c8 97 http_prepare_resp(&con->resp, 200);
ua1arn 1:119c4f7144c8 98
ua1arn 1:119c4f7144c8 99 if (htserv_on_req(&con->reqb.req, &con->resp, &con->htcon.arg))
ua1arn 1:119c4f7144c8 100 {
ua1arn 1:119c4f7144c8 101 int len;
ua1arn 1:119c4f7144c8 102 con->wbuff = con->buff + con->reqb.size;
ua1arn 1:119c4f7144c8 103 con->wsize = HTTP_CON_BUFF_SIZE - con->reqb.size;
ua1arn 1:119c4f7144c8 104 len = http_resp_str(&con->resp, con->wbuff, con->wsize);
ua1arn 1:119c4f7144c8 105 if (len >= con->wsize)
ua1arn 1:119c4f7144c8 106 {
ua1arn 1:119c4f7144c8 107 if (htserv_on_err != NULL)
ua1arn 1:119c4f7144c8 108 htserv_on_err(HTTP_RESP_NOMEM);
ua1arn 1:119c4f7144c8 109 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 110 }
ua1arn 1:119c4f7144c8 111 else
ua1arn 1:119c4f7144c8 112 {
ua1arn 1:119c4f7144c8 113 con->state = CSP_WR_RESP;
ua1arn 1:119c4f7144c8 114 con->wacksize = 0;
ua1arn 1:119c4f7144c8 115 con->writed = len;
ua1arn 1:119c4f7144c8 116 con->wsended = 0;
ua1arn 1:119c4f7144c8 117 }
ua1arn 1:119c4f7144c8 118 }
ua1arn 1:119c4f7144c8 119 else
ua1arn 1:119c4f7144c8 120 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 121
ua1arn 1:119c4f7144c8 122 htserv_io();
ua1arn 1:119c4f7144c8 123 }
ua1arn 1:119c4f7144c8 124
ua1arn 1:119c4f7144c8 125 void htcon_received(htcon_priv_t *con, const char *data, int size)
ua1arn 1:119c4f7144c8 126 {
ua1arn 1:119c4f7144c8 127 htserv_err_t err;
ua1arn 1:119c4f7144c8 128 err = HTTP_NO_ERROR;
ua1arn 1:119c4f7144c8 129
ua1arn 1:119c4f7144c8 130 if (con->state == CSP_RD_REQ)
ua1arn 1:119c4f7144c8 131 {
ua1arn 1:119c4f7144c8 132 http_reqb_push(&con->reqb, data, size);
ua1arn 1:119c4f7144c8 133 switch (con->reqb.state)
ua1arn 1:119c4f7144c8 134 {
ua1arn 1:119c4f7144c8 135 case REQB_UNFINISHED:
ua1arn 1:119c4f7144c8 136 return;
ua1arn 1:119c4f7144c8 137 case REQB_FINISHED:
ua1arn 1:119c4f7144c8 138 htcon_req_finished(con);
ua1arn 1:119c4f7144c8 139 return;
ua1arn 1:119c4f7144c8 140 case REQB_REQ_TO_BIG:
ua1arn 1:119c4f7144c8 141 err = HTTP_BIG_REQUEST;
ua1arn 1:119c4f7144c8 142 break;
ua1arn 1:119c4f7144c8 143 case REQB_SYNT_ERROR:
ua1arn 1:119c4f7144c8 144 err = HTTP_REQ_SYNT_ERR;
ua1arn 1:119c4f7144c8 145 break;
ua1arn 1:119c4f7144c8 146 }
ua1arn 1:119c4f7144c8 147 }
ua1arn 1:119c4f7144c8 148 if (err != HTTP_NO_ERROR)
ua1arn 1:119c4f7144c8 149 {
ua1arn 1:119c4f7144c8 150 if (htserv_on_err != NULL)
ua1arn 1:119c4f7144c8 151 htserv_on_err(err);
ua1arn 1:119c4f7144c8 152 con->htcon.state = CON_CLOSING;
ua1arn 1:119c4f7144c8 153 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 154 htserv_io();
ua1arn 1:119c4f7144c8 155 }
ua1arn 1:119c4f7144c8 156 }
ua1arn 1:119c4f7144c8 157
ua1arn 1:119c4f7144c8 158 err_t htcon_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
ua1arn 1:119c4f7144c8 159 {
ua1arn 1:119c4f7144c8 160 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 161
ua1arn 1:119c4f7144c8 162 con = (htcon_priv_t *)arg;
ua1arn 1:119c4f7144c8 163
ua1arn 1:119c4f7144c8 164 if (err == ERR_OK && p != NULL)
ua1arn 1:119c4f7144c8 165 {
ua1arn 1:119c4f7144c8 166 tcp_recved(pcb, p->tot_len);
ua1arn 1:119c4f7144c8 167 if (con != NULL)
ua1arn 1:119c4f7144c8 168 htcon_received(con, p->payload, p->tot_len);
ua1arn 1:119c4f7144c8 169 }
ua1arn 1:119c4f7144c8 170
ua1arn 1:119c4f7144c8 171 if (err == ERR_OK && p == NULL)
ua1arn 1:119c4f7144c8 172 {
ua1arn 1:119c4f7144c8 173 if (con != NULL)
ua1arn 1:119c4f7144c8 174 if (con->state != CSP_CLOSED)
ua1arn 1:119c4f7144c8 175 {
ua1arn 1:119c4f7144c8 176 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 177 con->htcon.state = CON_CLOSING;
ua1arn 1:119c4f7144c8 178 }
ua1arn 1:119c4f7144c8 179 }
ua1arn 1:119c4f7144c8 180
ua1arn 1:119c4f7144c8 181 if (p != NULL)
ua1arn 1:119c4f7144c8 182 pbuf_free(p);
ua1arn 1:119c4f7144c8 183
ua1arn 1:119c4f7144c8 184 return ERR_OK;
ua1arn 1:119c4f7144c8 185 }
ua1arn 1:119c4f7144c8 186
ua1arn 1:119c4f7144c8 187 static int find_free_con(void)
ua1arn 1:119c4f7144c8 188 {
ua1arn 1:119c4f7144c8 189 int i;
ua1arn 1:119c4f7144c8 190 for (i = 0; i < HTTP_SERVER_MAX_CON; i++)
ua1arn 1:119c4f7144c8 191 if (htcons[i].state == CSP_NONE) return i;
ua1arn 1:119c4f7144c8 192 return -1;
ua1arn 1:119c4f7144c8 193 }
ua1arn 1:119c4f7144c8 194
ua1arn 1:119c4f7144c8 195 err_t htcon_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
ua1arn 1:119c4f7144c8 196 {
ua1arn 1:119c4f7144c8 197 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 198 con = (htcon_priv_t *)arg;
ua1arn 1:119c4f7144c8 199 if (con == NULL) return ERR_OK;
ua1arn 1:119c4f7144c8 200 con->wacksize += len;
ua1arn 1:119c4f7144c8 201 // if (con->state == CSP_ACTIVE)
ua1arn 1:119c4f7144c8 202 // con->htcon.writed += len;
ua1arn 1:119c4f7144c8 203 return ERR_OK;
ua1arn 1:119c4f7144c8 204 }
ua1arn 1:119c4f7144c8 205
ua1arn 1:119c4f7144c8 206 void htcon_err(void *arg, err_t err)
ua1arn 1:119c4f7144c8 207 {
ua1arn 1:119c4f7144c8 208 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 209 con = (htcon_priv_t *)arg;
ua1arn 1:119c4f7144c8 210 if (con == NULL) return;
ua1arn 1:119c4f7144c8 211 if (htserv_on_err != NULL)
ua1arn 1:119c4f7144c8 212 htserv_on_err(HTTP_TRANSP_ERR);
ua1arn 1:119c4f7144c8 213 con->htcon.state = CON_CLOSING;
ua1arn 1:119c4f7144c8 214 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 215 }
ua1arn 1:119c4f7144c8 216
ua1arn 1:119c4f7144c8 217 err_t htserv_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
ua1arn 1:119c4f7144c8 218 {
ua1arn 1:119c4f7144c8 219 int index;
ua1arn 1:119c4f7144c8 220 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 221
ua1arn 1:119c4f7144c8 222 LWIP_UNUSED_ARG(arg);
ua1arn 1:119c4f7144c8 223 LWIP_UNUSED_ARG(err);
ua1arn 1:119c4f7144c8 224
ua1arn 1:119c4f7144c8 225 index = find_free_con();
ua1arn 1:119c4f7144c8 226 if (index < 0) return ERR_MEM;
ua1arn 1:119c4f7144c8 227 con = &htcons[index];
ua1arn 1:119c4f7144c8 228
ua1arn 1:119c4f7144c8 229 con->pcb = newpcb;
ua1arn 1:119c4f7144c8 230 http_reqb_init(&con->reqb, con->buff, HTTP_REQ_MAX_SIZE);
ua1arn 1:119c4f7144c8 231 con->wbuff = NULL;
ua1arn 1:119c4f7144c8 232 con->wsize = 0;
ua1arn 1:119c4f7144c8 233 con->wsended = 0;
ua1arn 1:119c4f7144c8 234 con->wacksize = 0;
ua1arn 1:119c4f7144c8 235 con->state = CSP_RD_REQ;
ua1arn 1:119c4f7144c8 236
ua1arn 1:119c4f7144c8 237 con->htcon.req = &con->reqb.req;
ua1arn 1:119c4f7144c8 238 con->htcon.resp = &con->resp;
ua1arn 1:119c4f7144c8 239 con->htcon.writed = 0;
ua1arn 1:119c4f7144c8 240 con->htcon.arg = NULL;
ua1arn 1:119c4f7144c8 241
ua1arn 1:119c4f7144c8 242
ua1arn 1:119c4f7144c8 243 tcp_setprio(newpcb, TCP_PRIO_MIN);
ua1arn 1:119c4f7144c8 244 tcp_arg(newpcb, con);
ua1arn 1:119c4f7144c8 245 tcp_recv(newpcb, htcon_recv);
ua1arn 1:119c4f7144c8 246 tcp_err(newpcb, htcon_err);
ua1arn 1:119c4f7144c8 247 tcp_sent(newpcb, htcon_sent);
ua1arn 1:119c4f7144c8 248 tcp_poll(newpcb, NULL, 4); // No polling here
ua1arn 1:119c4f7144c8 249
ua1arn 1:119c4f7144c8 250 return ERR_OK;
ua1arn 1:119c4f7144c8 251 }
ua1arn 1:119c4f7144c8 252
ua1arn 1:119c4f7144c8 253 void htserv_io(void) // state machine
ua1arn 1:119c4f7144c8 254 {
ua1arn 1:119c4f7144c8 255 for (int i = 0; i < HTTP_SERVER_MAX_CON; i++)
ua1arn 1:119c4f7144c8 256 {
ua1arn 1:119c4f7144c8 257 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 258 con = &htcons[i];
ua1arn 1:119c4f7144c8 259 if (con->state == CSP_NONE || con->state == CSP_CLOSED)
ua1arn 1:119c4f7144c8 260 continue;
ua1arn 1:119c4f7144c8 261
ua1arn 1:119c4f7144c8 262 // have data to send?
ua1arn 1:119c4f7144c8 263 if (con->state != CSP_CLOSING && con->writed > con->wsended)
ua1arn 1:119c4f7144c8 264 {
ua1arn 1:119c4f7144c8 265 int count;
ua1arn 1:119c4f7144c8 266 err_t err;
ua1arn 1:119c4f7144c8 267 count = con->writed - con->wsended;
ua1arn 1:119c4f7144c8 268 if (count > tcp_sndbuf(con->pcb))
ua1arn 1:119c4f7144c8 269 count = tcp_sndbuf(con->pcb);
ua1arn 1:119c4f7144c8 270 err = tcp_write(con->pcb, con->wbuff + con->wsended, count, TCP_WRITE_FLAG_COPY);
ua1arn 1:119c4f7144c8 271 if (err == ERR_OK)
ua1arn 1:119c4f7144c8 272 {
ua1arn 1:119c4f7144c8 273 con->wsended += count;
ua1arn 1:119c4f7144c8 274 tcp_output(con->pcb);
ua1arn 1:119c4f7144c8 275 }
ua1arn 1:119c4f7144c8 276 }
ua1arn 1:119c4f7144c8 277
ua1arn 1:119c4f7144c8 278 // data was successfully sended?
ua1arn 1:119c4f7144c8 279 if (con->state != CSP_CLOSING && con->wacksize >= con->wsended && con->wsended > 0)
ua1arn 1:119c4f7144c8 280 {
ua1arn 1:119c4f7144c8 281 con->writed = 0;
ua1arn 1:119c4f7144c8 282 con->wsended = 0;
ua1arn 1:119c4f7144c8 283 con->wacksize = 0;
ua1arn 1:119c4f7144c8 284 // is it http-response?
ua1arn 1:119c4f7144c8 285 if (con->state == CSP_WR_RESP)
ua1arn 1:119c4f7144c8 286 {
ua1arn 1:119c4f7144c8 287 con->htcon.state = CON_ACTIVE;
ua1arn 1:119c4f7144c8 288 con->state = CSP_ACTIVE;
ua1arn 1:119c4f7144c8 289 if (htserv_on_con != NULL)
ua1arn 1:119c4f7144c8 290 htserv_on_con(i);
ua1arn 1:119c4f7144c8 291 }
ua1arn 1:119c4f7144c8 292 else
ua1arn 1:119c4f7144c8 293 // is it document?
ua1arn 1:119c4f7144c8 294 if (con->state == CSP_ACTIVE && con->resp.conn_type != CT_KEEP_ALIVE)
ua1arn 1:119c4f7144c8 295 if (con->htcon.writed >= con->resp.cont_len)
ua1arn 1:119c4f7144c8 296 {
ua1arn 1:119c4f7144c8 297 con->htcon.state = CON_CLOSING;
ua1arn 1:119c4f7144c8 298 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 299 }
ua1arn 1:119c4f7144c8 300 }
ua1arn 1:119c4f7144c8 301
ua1arn 1:119c4f7144c8 302 // closing connection?
ua1arn 1:119c4f7144c8 303 if (con->state == CSP_CLOSING)
ua1arn 1:119c4f7144c8 304 // if (tcp_close(con->pcb) == ERR_OK)
ua1arn 1:119c4f7144c8 305 {
ua1arn 1:119c4f7144c8 306 con->htcon.state = CON_CLOSED;
ua1arn 1:119c4f7144c8 307 con->state = CSP_CLOSED;
ua1arn 1:119c4f7144c8 308 con->pcb = NULL;
ua1arn 1:119c4f7144c8 309 }
ua1arn 1:119c4f7144c8 310 }
ua1arn 1:119c4f7144c8 311 }
ua1arn 1:119c4f7144c8 312
ua1arn 1:119c4f7144c8 313 err_t htserv_init(uint16_t port)
ua1arn 1:119c4f7144c8 314 {
ua1arn 1:119c4f7144c8 315 int i;
ua1arn 1:119c4f7144c8 316 err_t err;
ua1arn 1:119c4f7144c8 317 tcp_init();
ua1arn 1:119c4f7144c8 318 htserv_free();
ua1arn 1:119c4f7144c8 319 if (http_pcb != NULL)
ua1arn 1:119c4f7144c8 320 return ERR_USE;
ua1arn 1:119c4f7144c8 321 http_pcb = tcp_new();
ua1arn 1:119c4f7144c8 322 if (http_pcb == NULL) return ERR_MEM;
ua1arn 1:119c4f7144c8 323 err = tcp_bind(http_pcb, IP_ADDR_ANY, port);
ua1arn 1:119c4f7144c8 324 if (err != ERR_OK)
ua1arn 1:119c4f7144c8 325 {
ua1arn 1:119c4f7144c8 326 htserv_free();
ua1arn 1:119c4f7144c8 327 return err;
ua1arn 1:119c4f7144c8 328 }
ua1arn 1:119c4f7144c8 329 for (i = 0; i < HTTP_SERVER_MAX_CON; i++)
ua1arn 1:119c4f7144c8 330 htcons[i].state = CSP_NONE;
ua1arn 1:119c4f7144c8 331 return ERR_OK;
ua1arn 1:119c4f7144c8 332 }
ua1arn 1:119c4f7144c8 333
ua1arn 1:119c4f7144c8 334 void htserv_free(void)
ua1arn 1:119c4f7144c8 335 {
ua1arn 1:119c4f7144c8 336 if (http_pcb == NULL) return;
ua1arn 1:119c4f7144c8 337 if (tcp_close(http_pcb) == ERR_OK)
ua1arn 1:119c4f7144c8 338 http_pcb = NULL;
ua1arn 1:119c4f7144c8 339 }
ua1arn 1:119c4f7144c8 340
ua1arn 1:119c4f7144c8 341 void htserv_tmr(uint32_t time_ms) //TODO
ua1arn 1:119c4f7144c8 342 {
ua1arn 1:119c4f7144c8 343 http_pcb = tcp_listen(http_pcb);
ua1arn 1:119c4f7144c8 344 if (http_pcb != NULL)
ua1arn 1:119c4f7144c8 345 {
ua1arn 1:119c4f7144c8 346 tcp_accept(http_pcb, htserv_accept);
ua1arn 1:119c4f7144c8 347 }
ua1arn 1:119c4f7144c8 348 htserv_io();
ua1arn 1:119c4f7144c8 349 }
ua1arn 1:119c4f7144c8 350
ua1arn 1:119c4f7144c8 351 const htcon_t *htcon(int index)
ua1arn 1:119c4f7144c8 352 {
ua1arn 1:119c4f7144c8 353 if (index < 0 || index >= HTTP_SERVER_MAX_CON)
ua1arn 1:119c4f7144c8 354 return NULL;
ua1arn 1:119c4f7144c8 355 if (htcons[index].state > CSP_CLOSED) return NULL;
ua1arn 1:119c4f7144c8 356 return &htcons[index].htcon;
ua1arn 1:119c4f7144c8 357 }
ua1arn 1:119c4f7144c8 358
ua1arn 1:119c4f7144c8 359 void htcon_close(int index)
ua1arn 1:119c4f7144c8 360 {
ua1arn 1:119c4f7144c8 361 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 362 con = (htcon_priv_t *)htcon(index);
ua1arn 1:119c4f7144c8 363 if (con == NULL) return;
ua1arn 1:119c4f7144c8 364 if (con->state == CSP_CLOSED) return;
ua1arn 1:119c4f7144c8 365 con->htcon.state = CON_CLOSING;
ua1arn 1:119c4f7144c8 366 con->state = CSP_CLOSING;
ua1arn 1:119c4f7144c8 367 htserv_io();
ua1arn 1:119c4f7144c8 368 }
ua1arn 1:119c4f7144c8 369
ua1arn 1:119c4f7144c8 370 void htcon_free(int index)
ua1arn 1:119c4f7144c8 371 {
ua1arn 1:119c4f7144c8 372 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 373 con = (htcon_priv_t *)htcon(index);
ua1arn 1:119c4f7144c8 374 if (con == NULL) return;
ua1arn 1:119c4f7144c8 375 if (con->state != CSP_CLOSED) return;
ua1arn 1:119c4f7144c8 376 htcons[index].state = CSP_NONE;
ua1arn 1:119c4f7144c8 377 }
ua1arn 1:119c4f7144c8 378
ua1arn 1:119c4f7144c8 379 int htcon_write_avail(int index)
ua1arn 1:119c4f7144c8 380 {
ua1arn 1:119c4f7144c8 381 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 382 con = (htcon_priv_t *)htcon(index);
ua1arn 1:119c4f7144c8 383 if (con == NULL) return 0;
ua1arn 1:119c4f7144c8 384 if (con->state != CSP_ACTIVE) return 0;
ua1arn 1:119c4f7144c8 385 return con->wsize - con->writed;
ua1arn 1:119c4f7144c8 386 }
ua1arn 1:119c4f7144c8 387
ua1arn 1:119c4f7144c8 388 int htcon_write(int index, const char *data, int size)
ua1arn 1:119c4f7144c8 389 {
ua1arn 1:119c4f7144c8 390 int res;
ua1arn 1:119c4f7144c8 391 htcon_priv_t *con;
ua1arn 1:119c4f7144c8 392 con = (htcon_priv_t *)htcon(index);
ua1arn 1:119c4f7144c8 393 if (con == NULL) return 0;
ua1arn 1:119c4f7144c8 394 if (con->state != CSP_ACTIVE) return 0;
ua1arn 1:119c4f7144c8 395 res = con->resp.cont_len - con->htcon.writed;
ua1arn 1:119c4f7144c8 396 if (size < res) res = size;
ua1arn 1:119c4f7144c8 397 if (con->wsize - con->writed < res)
ua1arn 1:119c4f7144c8 398 res = con->wsize - con->writed;
ua1arn 1:119c4f7144c8 399 if (res <= 0) return 0;
ua1arn 1:119c4f7144c8 400 memcpy(con->wbuff + con->writed, data, res);
ua1arn 1:119c4f7144c8 401 con->writed += res;
ua1arn 1:119c4f7144c8 402 con->htcon.writed += res;
ua1arn 1:119c4f7144c8 403 htserv_io();
ua1arn 1:119c4f7144c8 404 return res;
ua1arn 1:119c4f7144c8 405 }