Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions modules/Kconfig.civetweb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2019 Antmicro Ltd
#
# SPDX-License-Identifier: Apache-2.0

config CIVETWEB
bool "Civetweb Support"
help
This option enables the civetweb HTTP API.
8 changes: 8 additions & 0 deletions samples/net/sockets/civetweb/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)

include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(hello_world)

target_sources(app PRIVATE src/main.c src/libc_extensions.c)
34 changes: 34 additions & 0 deletions samples/net/sockets/civetweb/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# General config
CONFIG_CIVETWEB=y
CONFIG_JSON_LIBRARY=y

# pthreads
CONFIG_POSIX_API=y
CONFIG_PTHREAD_IPC=y
CONFIG_POSIX_MQUEUE=y

# networking
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
# CONFIG_NET_IPV6 is not set
CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=131072
CONFIG_NET_TX_STACK_SIZE=8192
CONFIG_NET_RX_STACK_SIZE=8192
CONFIG_ISR_STACK_SIZE=8192
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=2048
CONFIG_SOC_SERIES_SAME70=y

CONFIG_DNS_RESOLVER=y

CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="10.0.0.111"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="10.0.0.116"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="10.0.0.116"

# logging
CONFIG_NET_LOG=y
6 changes: 6 additions & 0 deletions samples/net/sockets/civetweb/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sample:
description: Civetweb HTTP API sample
name: civetweb
tests:
sample.net.sockets.civetweb:
platform_whitelist: sam_e70_xplained
28 changes: 28 additions & 0 deletions samples/net/sockets/civetweb/src/external_log_access.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2019 Antmicro Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/

static void log_access(const struct mg_connection *conn)
{
const struct mg_request_info *ri;
char src_addr[IP_ADDR_STR_LEN];

if (!conn || !conn->dom_ctx) {
return;
}

ri = &conn->request_info;

sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);

printf("%s - \"%s %s%s%s HTTP/%s\" %d\n",
src_addr,
ri->request_method ? ri->request_method : "-",
ri->request_uri ? ri->request_uri : "-",
ri->query_string ? "?" : "",
ri->query_string ? ri->query_string : "",
ri->http_version,
conn->status_code);
}
18 changes: 18 additions & 0 deletions samples/net/sockets/civetweb/src/external_mg_cry_internal_impl.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2019 Antmicro Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/

static void mg_cry_internal_impl(const struct mg_connection *conn,
const char *func,
unsigned line,
const char *fmt,
va_list ap)
{
(void)conn;

printf("[INTERNAL ERROR]: %s @ %d\n", func, line);
vprintf(fmt, ap);
printf("\n");
}
262 changes: 262 additions & 0 deletions samples/net/sockets/civetweb/src/libc_extensions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/*
* Copyright (c) 2019 Antmicro Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "libc_extensions.h"

#define FN_MISSING() printf("[IMPLEMENTATION MISSING : %s]\n", __func__)

size_t strcspn(const char *s1, const char *s2)
{
int i, j;

for (i = 0; i < strlen(s2); ++i) {
for (j = 0; j < strlen(s1); ++j) {
if (s1[j] == s2[i]) {
return j;
}
}
}

return strlen(s1);
}

int iscntrl(int c)
{
/* All the characters placed before the space on the ASCII table
* and the 0x7F character (DEL) are control characters.
*/
return (int)(c < ' ' || c == 0x7F);
}

size_t strftime(char *dst, size_t dst_size,
const char *fmt,
const struct tm *tm)
{
FN_MISSING();

return 0;
}

double difftime(time_t end, time_t beg)
{
return end - beg;
}

struct __strerr_wrap {
int err;
const char *errstr;
};

/* Implementation suggested by @rakons in #16527 */
#define STRERR_DEFINE(e) {e, #e}

static const struct __strerr_wrap error_strings[] = {
STRERR_DEFINE(EILSEQ),
STRERR_DEFINE(EDOM),
STRERR_DEFINE(ERANGE),
STRERR_DEFINE(ENOTTY),
STRERR_DEFINE(EACCES),
STRERR_DEFINE(EPERM),
STRERR_DEFINE(ENOENT),
STRERR_DEFINE(ESRCH),
STRERR_DEFINE(EEXIST),
STRERR_DEFINE(ENOSPC),
STRERR_DEFINE(ENOMEM),
STRERR_DEFINE(EBUSY),
STRERR_DEFINE(EINTR),
STRERR_DEFINE(EAGAIN),
STRERR_DEFINE(ESPIPE),
STRERR_DEFINE(EXDEV),
STRERR_DEFINE(EROFS),
STRERR_DEFINE(ENOTEMPTY),
STRERR_DEFINE(ECONNRESET),
STRERR_DEFINE(ETIMEDOUT),
STRERR_DEFINE(ECONNREFUSED),
STRERR_DEFINE(EHOSTDOWN),
STRERR_DEFINE(EHOSTUNREACH),
STRERR_DEFINE(EADDRINUSE),
STRERR_DEFINE(EPIPE),
STRERR_DEFINE(EIO),
STRERR_DEFINE(ENXIO),
STRERR_DEFINE(ENOTBLK),
STRERR_DEFINE(ENODEV),
STRERR_DEFINE(ENOTDIR),
STRERR_DEFINE(EISDIR),
STRERR_DEFINE(ETXTBSY),
STRERR_DEFINE(ENOEXEC),
STRERR_DEFINE(EINVAL),
STRERR_DEFINE(E2BIG),
STRERR_DEFINE(ELOOP),
STRERR_DEFINE(ENAMETOOLONG),
STRERR_DEFINE(ENFILE),
STRERR_DEFINE(EMFILE),
STRERR_DEFINE(EBADF),
STRERR_DEFINE(ECHILD),
STRERR_DEFINE(EFAULT),
STRERR_DEFINE(EFBIG),
STRERR_DEFINE(EMLINK),
STRERR_DEFINE(ENOLCK),
STRERR_DEFINE(EDEADLK),
STRERR_DEFINE(ECANCELED),
STRERR_DEFINE(ENOSYS),
STRERR_DEFINE(ENOMSG),
STRERR_DEFINE(ENOSTR),
STRERR_DEFINE(ENODATA),
STRERR_DEFINE(ETIME),
STRERR_DEFINE(ENOSR),
STRERR_DEFINE(EPROTO),
STRERR_DEFINE(EBADMSG),
STRERR_DEFINE(ENOTSOCK),
STRERR_DEFINE(EDESTADDRREQ),
STRERR_DEFINE(EMSGSIZE),
STRERR_DEFINE(EPROTOTYPE),
STRERR_DEFINE(ENOPROTOOPT),
STRERR_DEFINE(EPROTONOSUPPORT),
STRERR_DEFINE(ESOCKTNOSUPPORT),
STRERR_DEFINE(ENOTSUP),
STRERR_DEFINE(EPFNOSUPPORT),
STRERR_DEFINE(EAFNOSUPPORT),
STRERR_DEFINE(EADDRNOTAVAIL),
STRERR_DEFINE(ENETDOWN),
STRERR_DEFINE(ENETUNREACH),
STRERR_DEFINE(ENETRESET),
STRERR_DEFINE(ECONNABORTED),
STRERR_DEFINE(ENOBUFS),
STRERR_DEFINE(EISCONN),
STRERR_DEFINE(ENOTCONN),
STRERR_DEFINE(ESHUTDOWN),
STRERR_DEFINE(EALREADY),
STRERR_DEFINE(EINPROGRESS),
};

static char *strerr_unknown = "UNKNOWN";

char *strerror(int err)
{
int i;

for (i = 0; i < ARRAY_SIZE(error_strings); ++i) {
if (error_strings[i].err == err) {
return (char *)error_strings[i].errstr;
}
}

return strerr_unknown;
}

int sscanf(const char *s, const char *format, ...)
{
FN_MISSING();

return 0;
}

double atof(const char *str)
{
/* XXX good enough for civetweb uses */
return (double)atoi(str);
}

long long int strtoll(const char *str, char **endptr, int base)
{
/* XXX good enough for civetweb uses */
return (long long int)strtol(str, endptr, base);
}

time_t time(time_t *t)
{
return 0;
}

/*
* Most of the wrappers below are copies of the wrappers in net/sockets.h,
* but they are available only if CONFIG_NET_SOCKETS_POSIX_NAMES is enabled
* which is impossible here.
*/

int getsockname(int sock, struct sockaddr *addr,
socklen_t *addrlen)
{
return zsock_getsockname(sock, addr, addrlen);
}

int poll(struct zsock_pollfd *fds, int nfds, int timeout)
{
return zsock_poll(fds, nfds, timeout);
}

int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
char *host, socklen_t hostlen,
char *serv, socklen_t servlen, int flags)
{
return zsock_getnameinfo(addr, addrlen, host, hostlen,
serv, servlen, flags);
}

ssize_t send(int sock, const void *buf, size_t len, int flags)
{
return zsock_send(sock, buf, len, flags);
}

ssize_t recv(int sock, void *buf, size_t max_len, int flags)
{
return zsock_recv(sock, buf, max_len, flags);
}

int socket(int family, int type, int proto)
Copy link
Contributor

@tbursztyka tbursztyka Jul 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why re-declaring all these functions since include/net/socket.h does it already when CONFIG_NET_SOCKETS_OFFLOAD is not set. (and when it is, the offloading part provides these anyway).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only provides zsock_socket. socket and the like are only provided if CONFIG_NET_SOCKETS_POSIX_NAMES is enabled which cannot be used together with POSIX_APIS in general. So until #16621 is merged we were told to add this stuff to the sample (see #16683 and other issues referenced there).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

{
return zsock_socket(family, type, proto);
}

int getaddrinfo(const char *host, const char *service,
const struct zsock_addrinfo *hints,
struct zsock_addrinfo **res)
{
return zsock_getaddrinfo(host, service, hints, res);
}

void freeaddrinfo(struct zsock_addrinfo *ai)
{
zsock_freeaddrinfo(ai);
}

int connect(int sock, const struct sockaddr *addr,
socklen_t addrlen)
{
return zsock_connect(sock, addr, addrlen);
}

int getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen)
{
return zsock_getsockopt(sock, level, optname, optval, optlen);
}

int setsockopt(int sock, int level, int optname,
const void *optval, socklen_t optlen)
{
return zsock_setsockopt(sock, level, optname, optval, optlen);
}

int listen(int sock, int backlog)
{
return zsock_listen(sock, backlog);
}

int bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
return zsock_bind(sock, addr, addrlen);
}

int accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
{
return zsock_accept(sock, addr, addrlen);
}
Loading