1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date         Author      Notes
8  * 2011-07-04   onelife     Derive from Energy Micro demo application
9  */
10 
11 /******************************************************************************
12  * @file
13  * @brief This file is dervied from the ``httpd.c'' skeleton.
14  * @author Energy Micro AS
15  * @@version 0.0.4
16  ******************************************************************************
17  * @section License
18  * <b>(C) Copyright 2009 Energy Micro AS, http://www.energymicro.com</b>
19  ******************************************************************************
20  *
21  * This source code is the property of Energy Micro AS. The source and compiled
22  * code may only be used on Energy Micro "EFM32" microcontrollers.
23  *
24  * This copyright notice may not be removed from the source code nor changed.
25  *
26  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
27  * obligation to support this Software. Energy Micro AS is providing the
28  * Software "AS IS", with no express or implied warranties of any kind,
29  * including, but not limited to, any implied warranties of merchantability
30  * or fitness for any particular purpose or warranties against infringement
31  * of any proprietary rights of a third party.
32  *
33  * Energy Micro AS will not be liable for any consequential, incidental, or
34  * special damages, or any other relief, or for any claim by any third party,
35  * arising from your use of this Software.
36  *
37  *****************************************************************************/
38 /**
39  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
40  * All rights reserved.
41  *
42  * Redistribution and use in source and binary forms, with or without modification,
43  * are permitted provided that the following conditions are met:
44  *
45  * 1. Redistributions of source code must retain the above copyright notice,
46  *    this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright notice,
48  *    this list of conditions and the following disclaimer in the documentation
49  *    and/or other materials provided with the distribution.
50  * 3. The name of the author may not be used to endorse or promote products
51  *    derived from this software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
54  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
55  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
56  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
57  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
58  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
61  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
62  * OF SUCH DAMAGE.
63  *
64  * This file is part of the lwIP TCP/IP stack.
65  *
66  * Author: Adam Dunkels <adam@sics.se>
67  *
68  */
69 
70 /***************************************************************************//**
71 * @addtogroup efm32_eth
72 * @{
73 ******************************************************************************/
74 
75 /* Includes ------------------------------------------------------------------*/
76 #include "rtthread.h"
77 #include "dev_misc.h"
78 
79 #if defined(RT_USING_LWIP) && defined(EFM32_USING_ETH_HTTPD)
80 #include "lwip/tcp.h"
81 #include "lwip/ip_addr.h"
82 
83 /* Private typedef -----------------------------------------------------------*/
84 /* Private define ------------------------------------------------------------*/
85 /* Private macro -------------------------------------------------------------*/
86 /* Private variables ---------------------------------------------------------*/
87 /* This is the data for the actual web page. */
88 static int temp, vdd;
89 static char indexdata[700];
90 static const char indexdata1[] =
91     "HTTP/1.0 200 OK\r\n\
92     Content-type: text/html\r\n\
93     Pragma: no-cache\r\n\
94     Refresh: 5\r\n\
95     \r\n\
96     <html>\
97     <head><title>EFM32 HTTPD DEMO</title><head>\
98     <body>\
99     <h1>This is a simple http server</h1>\
100     <br><br><B>Ethernet controller: ENC28J60</B>\
101     <br><br><B>Refreshing timers: ";
102 
103 static const char indexdata2[] =
104     "<br><br><B>Current Vdd: ";
105 
106 static const char indexdata3[] =
107     " V</B>\
108     <br><br><B>Current temperature: ";
109 
110 static const char indexdata4[] =
111     " C</B>\
112     </body>\
113     </html>";
114 
115 /* Private function prototypes -----------------------------------------------*/
116 /* Private functions ---------------------------------------------------------*/
117 /* This is the callback function that is called
118  * when a TCP segment has arrived in the connection. */
http_recv(void * arg,struct tcp_pcb * pcb,struct pbuf * p,err_t err)119 static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
120 {
121   static unsigned char temp_var = 0;
122   unsigned short       counter, i;
123   char                 *rq;
124   /* If we got a NULL pbuf in p, the remote end has closed
125    * the connection. */
126   if (p != NULL)
127   {
128     /* The payload pointer in the pbuf contains the data
129      * in the TCP segment. */
130     rq = p->payload;
131     /* Check if the request was an HTTP "GET / HTTP/1.1". */
132     if (rq[0] == 'G' && rq[1] == 'E' && rq[2] == 'T')
133     {
134       /* Send the web page to the remote host. A zero
135        * in the last argument means that the data should
136        * not be copied into internal buffers. */
137 
138       counter = 0;
139 
140       for (i = 0; i < sizeof(indexdata1) - 1; i++)
141       {
142         indexdata[counter] = indexdata1[i];
143         counter++;
144       }
145 
146       indexdata[counter] = ' ';
147       counter++;
148 
149       /*Copy page counter MSB*/
150       indexdata[counter] = temp_var / 10 + 0x30;
151       counter++;
152 
153       /*Copy page counter LSB*/
154       indexdata[counter] = temp_var % 10 + 0x30;
155       counter++;
156 
157       temp_var++;
158       if (temp_var > 100) temp_var = 1;
159 
160       for (i = 0; i < sizeof(indexdata2) - 1; i++)
161       {
162         indexdata[counter] = indexdata2[i];
163         counter++;
164       }
165 
166       vdd = rt_hw_get_vdd();
167       rt_sprintf(&indexdata[counter], "%1d.%02d", vdd / 100, vdd % 100);
168       counter += 4;
169 
170       for (i = 0; i < sizeof(indexdata3) - 1; i++)
171       {
172         indexdata[counter] = indexdata3[i];
173         counter++;
174       }
175 
176       temp = rt_hw_get_temp();
177       /*Set temperature sign*/
178       if (temp < 0)
179       {
180         indexdata[counter] = '-';
181         counter++;
182       }
183       rt_sprintf(&indexdata[counter], "%02d.%02d\n", temp / 100, temp % 100);
184       counter += 5;
185 
186       for (i = 0; i < sizeof(indexdata4); i++)
187       {
188         indexdata[counter] = indexdata4[i];
189         counter++;
190       }
191 
192       tcp_write(pcb, indexdata, counter, 1);
193     }
194     /* Free the pbuf. */
195     pbuf_free(p);
196   }
197   /* Close the connection. */
198   tcp_close(pcb);
199   return ERR_OK;
200 }
201 
202 /* This is the callback function that is called when
203  * a connection has been accepted. */
http_accept(void * arg,struct tcp_pcb * pcb,err_t err)204 static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
205 {
206   /* Set up the function http_recv() to be called when data
207    * arrives. */
208   tcp_recv(pcb, http_recv);
209   return ERR_OK;
210 }
211 
212 /* The initialization function. */
httpd_init(void)213 void httpd_init(void)
214 {
215   struct tcp_pcb *pcb;
216   /* Create a new TCP PCB. */
217   pcb = tcp_new();
218   /* Bind the PCB to TCP port 80. */
219   tcp_bind(pcb, NULL, 80);
220   /* Change TCP state to LISTEN. */
221   pcb = tcp_listen(pcb);
222   /* Set up http_accet() function to be called
223    * when a new connection arrives. */
224   tcp_accept(pcb, http_accept);
225 }
226 
227 #endif /* defined(RT_USING_LWIP) && defined(EFM32_USING_ETH_HTTPD) */
228 /***************************************************************************//**
229  * @}
230  ******************************************************************************/
231