blob: c01d789bb07e7270f149e36c03b9f3d9e3cd7570 [file] [log] [blame]
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <net/net_context.h>
#include <misc/printk.h>
#include "http_types.h"
#include "http_server.h"
#include "http_utils.h"
#include "http_write_utils.h"
#include "config.h"
static void network_setup(void);
void main(void)
{
http_ctx_init();
http_url_default_handler(http_write_soft_404_not_found);
http_url_add("/headers", HTTP_URL_STANDARD, http_write_header_fields);
http_url_add("/index.html", HTTP_URL_STANDARD, http_write_it_works);
network_setup();
}
/**
* @brief connection_cb Callback executed when a connection is accepted
* @param ctx Network context
* @param addr Client's address
* @param addr_len Address length
* @param status Status code, 0 on success, < 0 otherwise
* @param data User-provided data
*/
void connection_cb(struct net_context *net_ctx, struct sockaddr *addr,
socklen_t addr_len, int status, void *data)
{
struct http_server_ctx *http_ctx = NULL;
ARG_UNUSED(addr_len);
ARG_UNUSED(data);
if (status != 0) {
printk("Status code: %d\n", status);
net_context_put(net_ctx);
return;
}
print_client_banner(addr);
http_ctx = http_ctx_get();
if (!http_ctx) {
printk("Unable to get free HTTP context\n");
net_context_put(net_ctx);
return;
}
http_ctx_set(http_ctx, net_ctx);
net_context_recv(net_ctx, http_rx_tx, 0, http_ctx);
}
/**
* @brief network_setup This routine configures the HTTP server.
* It puts the application in listening mode and
* installs the accept connection callback.
*/
static void network_setup(void)
{
struct net_context *ctx = NULL;
struct sockaddr local_sock;
void *ptr;
int rc;
#ifdef CONFIG_NET_IPV6
net_sin6(&local_sock)->sin6_port = htons(ZEPHYR_PORT);
sock_addr.family = AF_INET6;
ptr = &(net_sin6(&local_sock)->sin6_addr);
rc = net_addr_pton(AF_INET6, ZEPHYR_ADDR, ptr);
#else
net_sin(&local_sock)->sin_port = htons(ZEPHYR_PORT);
local_sock.family = AF_INET;
ptr = &(net_sin(&local_sock)->sin_addr);
rc = net_addr_pton(AF_INET, ZEPHYR_ADDR, ptr);
#endif
if (rc) {
printk("Invalid IP address/Port: %s, %d\n",
ZEPHYR_ADDR, ZEPHYR_PORT);
}
#ifdef CONFIG_NET_IPV6
ptr = net_if_ipv6_addr_add(net_if_get_default(),
&net_sin6(&local_sock)->sin6_addr,
NET_ADDR_MANUAL, 0);
#else
ptr = net_if_ipv4_addr_add(net_if_get_default(),
&net_sin(&local_sock)->sin_addr,
NET_ADDR_MANUAL, 0);
#endif
print_server_banner(&local_sock);
#if defined(CONFIG_NET_IPV6)
rc = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, &ctx);
#else
rc = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ctx);
#endif
if (rc != 0) {
printk("net_context_get error\n");
return;
}
rc = net_context_bind(ctx, (const struct sockaddr *)&local_sock,
sizeof(local_sock));
if (rc != 0) {
printk("net_context_bind error\n");
goto lb_error;
}
rc = net_context_listen(ctx, 0);
if (rc != 0) {
printk("[%s:%d] net_context_listen %d, <%s>\n",
__func__, __LINE__, rc, RC_STR(rc));
goto lb_error;
}
rc = net_context_accept(ctx, connection_cb, 0, NULL);
if (rc != 0) {
printk("[%s:%d] net_context_accept %d, <%s>\n",
__func__, __LINE__, rc, RC_STR(rc));
goto lb_error;
}
return;
lb_error:
net_context_put(ctx);
}