blob: 7831808f3581133cd98882aa43086676909406b0 [file]
/****************************************************************************
* apps/examples/webpanel/webpanel_main.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/mount.h>
#include <sys/boardctl.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <nuttx/drivers/ramdisk.h>
#include "netutils/thttpd.h"
#include "fsutils/mksmartfs.h"
#include "ws_terminal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SECTORSIZE 64
#define NSECTORS(b) (((b) + SECTORSIZE - 1) / SECTORSIZE)
#define WEBPANEL_RAMDISK_MINOR 2
#define ROMFSDEV "/dev/ram2"
#define ROMFS_MOUNTPT "/data/tmp_romfs"
#define BINFS_MOUNTPT "/data/tmp_binfs"
#define BINFS_PREFIX "cgi-bin"
#define UNIONFS_MOUNTPT CONFIG_THTTPD_PATH
#define SMARTFS_DEV "/dev/smart0"
#define SMARTFS_MNT "/mnt"
/****************************************************************************
* External References
****************************************************************************/
extern const unsigned char webpanel_romfs_img[];
extern const unsigned int webpanel_romfs_img_len;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: main
*
* Description:
* Initialize WebPanel filesystem mounts, start the websocket daemon,
* then launch the THTTPD server.
*
* Input Parameters:
* argc - Number of arguments.
* argv - Argument vector.
*
* Returned Value:
* EXIT_SUCCESS on success; EXIT_FAILURE on setup error.
*
****************************************************************************/
int main(int argc, FAR char *argv[])
{
struct boardioc_romdisk_s desc;
char *thttpd_argv = "thttpd";
struct statfs check_fs;
struct statfs sfs;
int ret;
/* Prevent duplicate startup (e.g. rcS runs again in child NSH) */
if (statfs(UNIONFS_MOUNTPT, &check_fs) == 0)
{
return 0;
}
/* Register the ROMFS image as a ramdisk */
printf("WebPanel: Registering ROMFS ramdisk\n");
desc.minor = WEBPANEL_RAMDISK_MINOR;
desc.nsectors = NSECTORS(webpanel_romfs_img_len);
desc.sectsize = SECTORSIZE;
desc.image = (FAR uint8_t *)webpanel_romfs_img;
ret = boardctl(BOARDIOC_ROMDISK, (uintptr_t)&desc);
if (ret < 0 && errno != EEXIST)
{
printf("WebPanel: ERROR romdisk_register failed: %d\n", ret);
return EXIT_FAILURE;
}
/* Create mount point directories */
mkdir("/data", 0777);
mkdir(ROMFS_MOUNTPT, 0777);
mkdir(BINFS_MOUNTPT, 0777);
/* Mount ROMFS at temp location */
printf("WebPanel: Mounting ROMFS at %s\n", ROMFS_MOUNTPT);
ret = mount(ROMFSDEV, ROMFS_MOUNTPT, "romfs", MS_RDONLY, NULL);
if (ret < 0 && errno != EBUSY)
{
printf("WebPanel: ERROR mount ROMFS failed: %d\n", errno);
return EXIT_FAILURE;
}
/* Mount BINFS at temp location (exposes built-in apps as CGI) */
printf("WebPanel: Mounting BINFS at %s\n", BINFS_MOUNTPT);
ret = mount(NULL, BINFS_MOUNTPT, "binfs", MS_RDONLY, NULL);
if (ret < 0 && errno != EBUSY)
{
printf("WebPanel: ERROR mount BINFS failed: %d\n", errno);
return EXIT_FAILURE;
}
/* Create UNIONFS: ROMFS content + BINFS under cgi-bin/ prefix */
printf("WebPanel: Creating UNIONFS at %s\n", UNIONFS_MOUNTPT);
ret = mount(NULL, UNIONFS_MOUNTPT, "unionfs", 0,
"fspath1=" ROMFS_MOUNTPT ",prefix1="
",fspath2=" BINFS_MOUNTPT ",prefix2=" BINFS_PREFIX);
if (ret < 0 && errno != EBUSY)
{
printf("WebPanel: ERROR mount UNIONFS failed: %d\n", errno);
return EXIT_FAILURE;
}
/* Ensure SmartFS is formatted and mounted at /mnt for user files */
if (statfs(SMARTFS_MNT, &sfs) != 0)
{
printf("WebPanel: SmartFS not mounted, formatting %s\n",
SMARTFS_DEV);
ret = mksmartfs(SMARTFS_DEV, 0);
if (ret < 0)
{
printf("WebPanel: WARNING mksmartfs failed: %d\n", errno);
}
else
{
mkdir(SMARTFS_MNT, 0777);
ret = mount(SMARTFS_DEV, SMARTFS_MNT, "smartfs", 0, NULL);
if (ret < 0)
{
printf("WebPanel: WARNING mount SmartFS failed: %d\n",
errno);
}
else
{
printf("WebPanel: SmartFS mounted at %s\n", SMARTFS_MNT);
}
}
}
else
{
printf("WebPanel: SmartFS already mounted at %s\n", SMARTFS_MNT);
}
/* Start WebSocket terminal server */
ret = ws_terminal_start();
if (ret < 0)
{
printf("WebPanel: WARNING WebSocket server failed to start\n");
}
/* Start THTTPD */
printf("WebPanel: Starting THTTPD (serving from %s)\n", UNIONFS_MOUNTPT);
fflush(stdout);
thttpd_main(1, &thttpd_argv);
printf("WebPanel: THTTPD terminated\n");
return 0;
}