nuttx-apps/nshlib/nsh_syscmds.c

536 lines
14 KiB
C
Raw Normal View History

/****************************************************************************
* apps/nshlib/nsh_syscmds.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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
* COPYRIGHT OWNER OR CONTRIBUTORS 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 <nuttx/rptun/rptun.h>
#include <sys/boardctl.h>
#include <sys/ioctl.h>
2015-07-04 23:13:11 +02:00
#include <sys/utsname.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "nsh.h"
#include "nsh_console.h"
/****************************************************************************
2015-07-04 23:13:11 +02:00
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ARCH_BOARD_CUSTOM
# ifndef CONFIG_ARCH_BOARD_CUSTOM_NAME
# define BOARD_NAME g_unknown
# else
# define BOARD_NAME CONFIG_ARCH_BOARD_CUSTOM_NAME
# endif
#else
# ifndef CONFIG_ARCH_BOARD
# define BOARD_NAME g_unknown
# else
# define BOARD_NAME CONFIG_ARCH_BOARD
# endif
#endif
2015-07-04 23:13:11 +02:00
#define UNAME_KERNEL (1 << 0)
#define UNAME_NODE (1 << 1)
#define UNAME_RELEASE (1 << 2)
#define UNAME_VERISON (1 << 3)
#define UNAME_MACHINE (1 << 4)
#define UNAME_PLATFORM (1 << 5)
#define UNAME_UNKNOWN (1 << 6)
2015-07-04 23:13:11 +02:00
#ifdef CONFIG_NET
# define UNAME_ALL (UNAME_KERNEL | UNAME_NODE | UNAME_RELEASE | \
UNAME_VERISON | UNAME_MACHINE | UNAME_PLATFORM)
2015-07-04 23:13:11 +02:00
#else
# define UNAME_ALL (UNAME_KERNEL | UNAME_RELEASE | UNAME_VERISON | \
UNAME_MACHINE | UNAME_PLATFORM)
2015-07-04 23:13:11 +02:00
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#ifndef CONFIG_NSH_DISABLE_UNAME
static const char g_unknown[] = "unknown";
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_shutdown
****************************************************************************/
#if (defined(CONFIG_BOARDCTL_POWEROFF) || defined(CONFIG_BOARDCTL_RESET)) && \
!defined(CONFIG_NSH_DISABLE_SHUTDOWN)
int cmd_shutdown(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
#if defined(CONFIG_BOARDCTL_POWEROFF) && defined(CONFIG_BOARDCTL_RESET)
/* If both shutdown and reset are supported, then a single option may
* be provided to select the reset behavior (--reboot). We know here
* that argc is either 1 or 2.
*/
if (argc == 2)
{
/* Verify that the single argument is --reboot */
if (strcmp(argv[1], "--reboot") != 0)
{
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
/* Invoke the BOARDIOC_RESET board control to reset the board. If
* the board_reset() function returns, then it was not possible to
* reset the board due to some constraints.
*/
boardctl(BOARDIOC_RESET, EXIT_SUCCESS);
}
else
{
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board.
* If the board_power_off function returns, then it was not possible
* to power-off the* board due to some constraints.
*/
boardctl(BOARDIOC_POWEROFF, EXIT_SUCCESS);
}
#elif defined(CONFIG_BOARDCTL_RESET)
/* Only reset behavior is supported and we already know that exactly one
* argument has been provided.
*/
/* Verify that the single argument is --reboot */
if (strcmp(argv[1], "--reboot") != 0)
{
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
/* Invoke the BOARDIOC_RESET board control to reset the board. If
* the board_reset() function returns, then it was not possible to
* reset the board due to some constraints.
*/
boardctl(BOARDIOC_RESET, EXIT_SUCCESS);
#else
/* Only the reset behavior is supported and we already know that there is
* no argument to the command.
*/
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board. If
* the board_power_off function returns, then it was not possible to power-
* off the board due to some constraints.
*/
boardctl(BOARDIOC_POWEROFF, EXIT_SUCCESS);
#endif
/* boarctl() will not return in any case. It if does, it means that
* there was a problem with the shutdown/resaet operation.
*/
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
return ERROR;
}
#endif /* CONFIG_BOARDCTL_POWEROFF && !CONFIG_NSH_DISABLE_SHUTDOWN */
/****************************************************************************
* Name: cmd_pmconfig
****************************************************************************/
#if defined(CONFIG_PM) && !defined(CONFIG_NSH_DISABLE_PMCONFIG)
int cmd_pmconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct boardioc_pm_ctrl_s ctrl =
{
};
if (argc == 1)
{
int current_state;
int normal_count;
int idle_count;
int standby_count;
int sleep_count;
ctrl.action = BOARDIOC_PM_QUERYSTATE;
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
current_state = ctrl.state;
ctrl.action = BOARDIOC_PM_STAYCOUNT;
ctrl.state = PM_NORMAL;
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
normal_count = ctrl.count;
ctrl.state = PM_IDLE;
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
idle_count = ctrl.count;
ctrl.state = PM_STANDBY;
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
standby_count = ctrl.count;
ctrl.state = PM_SLEEP;
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
sleep_count = ctrl.count;
nsh_output(vtbl, "Current state %d, PM stay [%d, %d, %d, %d]\n",
current_state, normal_count, idle_count, standby_count, sleep_count);
}
else if (argc == 3)
{
if (strcmp(argv[1], "stay") == 0)
{
ctrl.action = BOARDIOC_PM_STAY;
}
else if (strcmp(argv[1], "relax") == 0)
{
ctrl.action = BOARDIOC_PM_RELAX;
}
else
{
nsh_output(vtbl, g_fmtarginvalid, argv[1]);
return ERROR;
}
if (strcmp(argv[2], "normal") == 0)
{
ctrl.state = PM_NORMAL;
}
else if (strcmp(argv[2], "idle") == 0)
{
ctrl.state = PM_IDLE;
}
else if (strcmp(argv[2], "standby") == 0)
{
ctrl.state = PM_STANDBY;
}
else if (strcmp(argv[2], "sleep") == 0)
{
ctrl.state = PM_SLEEP;
}
else
{
nsh_output(vtbl, g_fmtarginvalid, argv[2]);
return ERROR;
}
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
}
else
{
nsh_error(vtbl, g_fmttoomanyargs, argv[0]);
return ERROR;
}
return 0;
}
#endif
/****************************************************************************
* Name: cmd_poweroff
****************************************************************************/
#if defined(CONFIG_BOARDCTL_POWEROFF) && !defined(CONFIG_NSH_DISABLE_POWEROFF)
int cmd_poweroff(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board. If
* the board_power_off function returns, then it was not possible to power-
* off the board due to some constraints.
*/
if (argc > 1)
{
boardctl(BOARDIOC_POWEROFF, atoi(argv[1]));
}
else
{
boardctl(BOARDIOC_POWEROFF, EXIT_SUCCESS);
}
/* boarctl() will not return in any case. It if does, it means that
* there was a problem with the shutdown operation.
*/
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
return ERROR;
}
#endif
/****************************************************************************
* Name: cmd_reboot
****************************************************************************/
#if defined(CONFIG_BOARDCTL_RESET) && !defined(CONFIG_NSH_DISABLE_REBOOT)
int cmd_reboot(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
/* Invoke the BOARDIOC_RESET board control to reset the board. If
* the board_reset() function returns, then it was not possible to
* reset the board due to some constraints.
*/
if (argc > 1)
{
boardctl(BOARDIOC_RESET, atoi(argv[1]));
}
else
{
boardctl(BOARDIOC_RESET, EXIT_SUCCESS);
}
/* boarctl() will not return in this case. It if does, it means that
* there was a problem with the reset operation.
*/
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
return ERROR;
}
#endif
2015-07-04 23:13:11 +02:00
/****************************************************************************
* Name: cmd_rptun
****************************************************************************/
#if defined(CONFIG_RPTUN) && !defined(CONFIG_NSH_DISABLE_RPTUN)
int cmd_rptun(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
int fd;
int cmd;
if (argc < 3)
{
nsh_output(vtbl, g_fmtargrequired, argv[0]);
return ERROR;
}
if (strcmp(argv[1], "start") == 0)
{
cmd = RPTUNIOC_START;
}
else if (strcmp(argv[1], "stop") == 0)
{
cmd = RPTUNIOC_STOP;
}
else
{
nsh_output(vtbl, g_fmtarginvalid, argv[1]);
return ERROR;
}
fd = open(argv[2], 0);
if (fd < 0)
{
nsh_output(vtbl, g_fmtarginvalid, argv[2]);
return ERROR;
}
ioctl(fd, cmd, 0);
close(fd);
return 0;
}
#endif
2015-07-04 23:13:11 +02:00
/****************************************************************************
* Name: cmd_uname
****************************************************************************/
#ifndef CONFIG_NSH_DISABLE_UNAME
int cmd_uname(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
FAR const char *str;
2015-07-04 23:13:11 +02:00
struct utsname info;
unsigned int set;
int option;
bool badarg;
bool first;
int ret;
int i;
/* Get the uname options */
2015-07-04 23:13:11 +02:00
set = 0;
badarg = false;
2015-07-04 23:13:11 +02:00
while ((option = getopt(argc, argv, "asonrvmpi")) != ERROR)
{
switch (option)
{
case 'a':
set = UNAME_ALL;
break;
case 'o':
case 's':
set |= UNAME_KERNEL;
break;
#ifdef CONFIG_NET
2015-07-04 23:13:11 +02:00
case 'n':
set |= UNAME_NODE;
break;
#endif
case 'r':
set |= UNAME_RELEASE;
break;
case 'v':
set |= UNAME_VERISON;
break;
case 'm':
set |= UNAME_MACHINE;
break;
case 'p':
if (set != UNAME_ALL)
{
set |= UNAME_UNKNOWN;
}
break;
case 'i':
set |= UNAME_PLATFORM;
break;
2015-07-04 23:13:11 +02:00
case '?':
default:
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
2015-07-04 23:13:11 +02:00
badarg = true;
break;
}
}
/* If a bad argument was encountered, then return without processing the
* command
*/
if (badarg)
{
return ERROR;
}
/* If nothing is provided on the command line, the default is -s */
if (set == 0)
{
set = UNAME_KERNEL;
}
/* Get uname data */
ret = uname(&info);
if (ret < 0)
{
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "uname", NSH_ERRNO);
2015-07-04 23:13:11 +02:00
return ERROR;
}
/* Process each option */
first = true;
for (i = 0; set != 0; i++)
{
unsigned int mask = (1 << i);
if ((set & mask) != 0)
{
set &= ~mask;
switch (i)
{
case 0: /* print the kernel/operating system name */
str = info.sysname;
break;
#ifdef CONFIG_NET
2015-07-04 23:13:11 +02:00
case 1: /* Print noname */
str = info.nodename;
break;
#endif
case 2: /* Print the kernel release */
str = info.release;
break;
case 3: /* Print the kernel version */
str = info.version;
break;
case 4: /* Print the machine hardware name */
str = info.machine;
break;
case 5: /* Print the machine platform name */
str = BOARD_NAME;
break;
case 6: /* Print "unknown" */
str = g_unknown;
2015-07-04 23:13:11 +02:00
break;
default:
2018-12-09 01:53:54 +01:00
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
2015-07-04 23:13:11 +02:00
return ERROR;
}
if (!first)
{
nsh_output(vtbl, " ");
}
nsh_output(vtbl, str);
first = false;
}
}
nsh_output(vtbl, "\n");
return OK;
}
#endif