2011-03-20 19:18:19 +01:00
|
|
|
/****************************************************************************
|
2021-06-16 09:22:16 +02:00
|
|
|
* apps/examples/webserver/webserver_main.c
|
2011-03-20 19:18:19 +01:00
|
|
|
*
|
2015-07-12 19:53:23 +02:00
|
|
|
* Copyright (C) 2007, 2009-2012, 2015 Gregory Nutt. All rights reserved.
|
2012-07-20 00:32:19 +02:00
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
2011-03-20 19:18:19 +01:00
|
|
|
*
|
|
|
|
* Based on uIP which also has a BSD style license:
|
|
|
|
*
|
|
|
|
* Copyright (c) 2001, Adam Dunkels.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by Adam Dunkels.
|
|
|
|
* 4. The name of the author may not be used to endorse or promote
|
|
|
|
* products derived from this software without specific prior
|
|
|
|
* written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
|
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
2014-07-05 03:13:08 +02:00
|
|
|
#include <netinet/in.h>
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2016-07-11 18:11:18 +02:00
|
|
|
#include "netutils/netlib.h"
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
|
2011-03-20 19:18:19 +01:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Here we include the header file for the application(s) we use in
|
|
|
|
* our project as defined in the config/<board-name>/defconfig file
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* DHCPC may be used in conjunction with any other feature (or not) */
|
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
|
2016-07-11 18:11:18 +02:00
|
|
|
# include "netutils/dhcpc.h"
|
2011-03-20 19:18:19 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Include uIP webserver definitions */
|
|
|
|
|
2016-07-11 18:11:18 +02:00
|
|
|
#include "netutils/httpd.h"
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2012-09-01 01:05:51 +02:00
|
|
|
#include "cgi.h"
|
|
|
|
|
2011-03-20 19:18:19 +01:00
|
|
|
/****************************************************************************
|
2014-10-08 16:33:00 +02:00
|
|
|
* Pre-processor Definitions
|
2011-03-20 19:18:19 +01:00
|
|
|
****************************************************************************/
|
|
|
|
|
2022-10-04 17:48:54 +02:00
|
|
|
#ifndef CONFIG_NETUTILS_WEBSERVER
|
|
|
|
# error "CONFIG_NETUTILS_WEBSERVER is required to get WebServer working"
|
|
|
|
#endif
|
|
|
|
|
2011-03-20 19:18:19 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Private Data
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
2014-07-04 01:31:17 +02:00
|
|
|
* webserver_main
|
2011-03-20 19:18:19 +01:00
|
|
|
****************************************************************************/
|
|
|
|
|
2014-09-06 17:23:23 +02:00
|
|
|
int main(int argc, FAR char *argv[])
|
2011-03-20 19:18:19 +01:00
|
|
|
{
|
2019-10-07 10:37:56 +02:00
|
|
|
#ifndef CONFIG_NSH_NETINIT
|
2019-07-26 19:04:05 +02:00
|
|
|
/* We are running standalone (as opposed to a NSH built-in app). Therefore
|
|
|
|
* we need to initialize the network before we start.
|
|
|
|
*/
|
|
|
|
|
2011-03-20 19:18:19 +01:00
|
|
|
struct in_addr addr;
|
2014-07-04 01:31:17 +02:00
|
|
|
#if defined(CONFIG_EXAMPLES_WEBSERVER_DHCPC) || defined(CONFIG_EXAMPLES_WEBSERVER_NOMAC)
|
2011-03-20 19:18:19 +01:00
|
|
|
uint8_t mac[IFHWADDRLEN];
|
|
|
|
#endif
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
|
2023-04-11 12:25:04 +02:00
|
|
|
FAR void *handle;
|
2011-03-20 19:18:19 +01:00
|
|
|
#endif
|
|
|
|
|
2021-01-04 00:00:55 +01:00
|
|
|
/* Many embedded network interfaces must have a software assigned MAC */
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_NOMAC
|
2011-03-20 19:18:19 +01:00
|
|
|
mac[0] = 0x00;
|
|
|
|
mac[1] = 0xe0;
|
2012-07-20 00:32:19 +02:00
|
|
|
mac[2] = 0xde;
|
|
|
|
mac[3] = 0xad;
|
|
|
|
mac[4] = 0xbe;
|
|
|
|
mac[5] = 0xef;
|
2014-07-03 00:52:02 +02:00
|
|
|
netlib_setmacaddr("eth0", mac);
|
2011-03-20 19:18:19 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Set up our host address */
|
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
|
2011-03-20 19:18:19 +01:00
|
|
|
addr.s_addr = 0;
|
|
|
|
#else
|
2014-07-04 01:31:17 +02:00
|
|
|
addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_IPADDR);
|
2011-03-20 19:18:19 +01:00
|
|
|
#endif
|
2015-01-18 21:17:00 +01:00
|
|
|
netlib_set_ipv4addr("eth0", &addr);
|
2011-03-20 19:18:19 +01:00
|
|
|
|
|
|
|
/* Set up the default router address */
|
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_DRIPADDR);
|
2015-01-18 21:17:00 +01:00
|
|
|
netlib_set_dripv4addr("eth0", &addr);
|
2011-03-20 19:18:19 +01:00
|
|
|
|
|
|
|
/* Setup the subnet mask */
|
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_NETMASK);
|
2015-01-18 21:17:00 +01:00
|
|
|
netlib_set_ipv4netmask("eth0", &addr);
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2017-05-19 17:30:26 +02:00
|
|
|
/* New versions of netlib_set_ipvXaddr will not bring the network up,
|
2017-05-19 17:50:26 +02:00
|
|
|
* So ensure the network is really up at this point.
|
|
|
|
*/
|
2017-05-19 17:30:26 +02:00
|
|
|
|
|
|
|
netlib_ifup("eth0");
|
|
|
|
|
2014-07-04 01:31:17 +02:00
|
|
|
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
|
2011-03-20 19:18:19 +01:00
|
|
|
/* Get the MAC address of the NIC */
|
|
|
|
|
2014-07-03 00:52:02 +02:00
|
|
|
netlib_getmacaddr("eth0", mac);
|
2011-03-20 19:18:19 +01:00
|
|
|
|
|
|
|
/* Set up the DHCPC modules */
|
|
|
|
|
2017-05-19 22:34:00 +02:00
|
|
|
handle = dhcpc_open("eth0", &mac, IFHWADDRLEN);
|
2011-03-20 19:18:19 +01:00
|
|
|
|
2021-01-04 00:00:55 +01:00
|
|
|
/* Get an IP address. Note: there is no logic here for renewing the
|
|
|
|
* address in this example. The address should be renewed in
|
|
|
|
* ds.lease_time/2 seconds.
|
2011-03-20 19:18:19 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
printf("Getting IP address\n");
|
|
|
|
if (handle)
|
|
|
|
{
|
2021-01-04 00:00:55 +01:00
|
|
|
struct dhcpc_state ds;
|
2022-08-01 11:18:52 +02:00
|
|
|
char inetaddr[INET_ADDRSTRLEN];
|
|
|
|
|
2021-01-04 00:00:55 +01:00
|
|
|
dhcpc_request(handle, &ds);
|
|
|
|
netlib_set_ipv4addr("eth0", &ds.ipaddr);
|
|
|
|
|
|
|
|
if (ds.netmask.s_addr != 0)
|
|
|
|
{
|
|
|
|
netlib_set_ipv4netmask("eth0", &ds.netmask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ds.default_router.s_addr != 0)
|
|
|
|
{
|
|
|
|
netlib_set_dripv4addr("eth0", &ds.default_router);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ds.dnsaddr.s_addr != 0)
|
|
|
|
{
|
|
|
|
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
dhcpc_close(handle);
|
2022-08-01 11:18:52 +02:00
|
|
|
printf("IP: %s\n", inet_ntoa_r(ds.ipaddr, inetaddr, sizeof(inetaddr)));
|
2011-03-20 19:18:19 +01:00
|
|
|
}
|
|
|
|
#endif
|
2019-10-07 10:37:56 +02:00
|
|
|
#endif /* CONFIG_NSH_NETINIT */
|
2011-03-20 19:18:19 +01:00
|
|
|
|
|
|
|
#ifdef CONFIG_NET_TCP
|
|
|
|
printf("Starting webserver\n");
|
|
|
|
httpd_init();
|
2019-07-03 14:20:29 +02:00
|
|
|
#ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
|
2012-09-01 01:05:51 +02:00
|
|
|
cgi_register();
|
2019-07-03 14:20:29 +02:00
|
|
|
#endif
|
2011-03-20 19:18:19 +01:00
|
|
|
httpd_listen();
|
|
|
|
#endif
|
|
|
|
|
apps/examples/webserver: When NSH app, allow terminating
The examples/webserver app can be built in two modes:
(1) in standalone mode, or
(2) as a NSH built-in app.
When run in standalone mode, the webserver program is responsible for
bringing up the network (including DHCP if configured). Also, the
webserver program must never exit, so if httpd fails (i.e., if
httpd_listen() returns), webserver_main() goes into an endless loop.
When run as a NSH built-in app, network bring-up is the responsibility
of other processes and the webserver program assumes the network is
already properly configured when it starts. Also, if httpd_listen()
returns, the webserver program should terminate.
Prior to this change, the webserver program would *not* terminate,
even when running as a NSH built-in app. For example:
nsh> webserver &
webserver [6:100]
nsh> Starting webserver
nsh> kill -9 6
nsh> webserver_main: Still running
nsh> webserver_main: Still running
nsh> webserver_main: Still running
nsh> webserver_main: Still running
The line "webserver_main: Still running" would be forever printed
every 3 seconds, however httpd_listen() is no longer running and the
webserver is not functional.
This change makes the webserver play nicely when running as a NSH
built-in app. With this change applied:
nsh> webserver &
webserver [6:100]
nsh> Starting webserver
nsh> kill -9 6
nsh> webserver_main: Exiting
apps/examples/webserver/webserver_main.c:
* main(): Infer from CONFIG_NSH_BUILTIN_APPS if this is a
standalone program or a NSH built-in app. (See [1], where
similar logic was added to decide whether to do network bring-up
or not.) If standalone, run forever as before. If built-in
app, exit when httpd terminates.
References:
[1] Commit 3a21b0b22263c06b5ba54ea2525521c8ca84b349
2021-01-03 23:58:04 +01:00
|
|
|
#ifndef CONFIG_NSH_NETINIT
|
2019-07-26 19:04:05 +02:00
|
|
|
/* We are running standalone (as opposed to a NSH built-in app). Therefore
|
|
|
|
* we should not exit after httpd failure.
|
|
|
|
*/
|
|
|
|
|
2014-04-12 21:09:48 +02:00
|
|
|
while (1)
|
2011-03-20 19:18:19 +01:00
|
|
|
{
|
|
|
|
sleep(3);
|
2014-07-04 01:31:17 +02:00
|
|
|
printf("webserver_main: Still running\n");
|
2011-03-20 19:18:19 +01:00
|
|
|
fflush(stdout);
|
|
|
|
}
|
2014-04-12 21:09:48 +02:00
|
|
|
|
apps/examples/webserver: When NSH app, allow terminating
The examples/webserver app can be built in two modes:
(1) in standalone mode, or
(2) as a NSH built-in app.
When run in standalone mode, the webserver program is responsible for
bringing up the network (including DHCP if configured). Also, the
webserver program must never exit, so if httpd fails (i.e., if
httpd_listen() returns), webserver_main() goes into an endless loop.
When run as a NSH built-in app, network bring-up is the responsibility
of other processes and the webserver program assumes the network is
already properly configured when it starts. Also, if httpd_listen()
returns, the webserver program should terminate.
Prior to this change, the webserver program would *not* terminate,
even when running as a NSH built-in app. For example:
nsh> webserver &
webserver [6:100]
nsh> Starting webserver
nsh> kill -9 6
nsh> webserver_main: Still running
nsh> webserver_main: Still running
nsh> webserver_main: Still running
nsh> webserver_main: Still running
The line "webserver_main: Still running" would be forever printed
every 3 seconds, however httpd_listen() is no longer running and the
webserver is not functional.
This change makes the webserver play nicely when running as a NSH
built-in app. With this change applied:
nsh> webserver &
webserver [6:100]
nsh> Starting webserver
nsh> kill -9 6
nsh> webserver_main: Exiting
apps/examples/webserver/webserver_main.c:
* main(): Infer from CONFIG_NSH_BUILTIN_APPS if this is a
standalone program or a NSH built-in app. (See [1], where
similar logic was added to decide whether to do network bring-up
or not.) If standalone, run forever as before. If built-in
app, exit when httpd terminates.
References:
[1] Commit 3a21b0b22263c06b5ba54ea2525521c8ca84b349
2021-01-03 23:58:04 +01:00
|
|
|
#else /* CONFIG_NSH_NETINIT */
|
|
|
|
/* We are running as a NSH built-in app. Therefore we should exit. This
|
|
|
|
* allows to 'kill -9' the webserver app, assuming it was started as a
|
|
|
|
* background process. For example:
|
|
|
|
*
|
|
|
|
* nsh> webserver &
|
|
|
|
* webserver [6:100]
|
|
|
|
* nsh> Starting webserver
|
|
|
|
*
|
|
|
|
* nsh> kill -9 6
|
|
|
|
* nsh> webserver_main: Exiting
|
|
|
|
*/
|
|
|
|
|
|
|
|
printf("webserver_main: Exiting\n");
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
#endif /* CONFIG_NSH_NETINIT */
|
|
|
|
|
2011-03-20 19:18:19 +01:00
|
|
|
return 0;
|
|
|
|
}
|