From 02a5e25f56a15b0051b0613412332a84ad582310 Mon Sep 17 00:00:00 2001 From: Vladimir Komendantskiy Date: Sun, 31 Jan 2016 09:07:46 -0600 Subject: [PATCH] apps/examples/ubloxmodem: app to control the power state of the modem in nsh. --- ChangeLog.txt | 2 + examples/Kconfig | 1 + examples/README.txt | 10 + examples/ubloxmodem/.gitignore | 11 + examples/ubloxmodem/Kconfig | 27 ++ examples/ubloxmodem/Make.defs | 39 +++ examples/ubloxmodem/Makefile | 134 ++++++++ examples/ubloxmodem/ubloxmodem.h | 80 +++++ examples/ubloxmodem/ubloxmodem_main.c | 441 ++++++++++++++++++++++++++ 9 files changed, 745 insertions(+) create mode 100644 examples/ubloxmodem/.gitignore create mode 100644 examples/ubloxmodem/Kconfig create mode 100644 examples/ubloxmodem/Make.defs create mode 100644 examples/ubloxmodem/Makefile create mode 100644 examples/ubloxmodem/ubloxmodem.h create mode 100644 examples/ubloxmodem/ubloxmodem_main.c diff --git a/ChangeLog.txt b/ChangeLog.txt index 5fd4f09c9..208352ecb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1536,4 +1536,6 @@ * apps/exmaples/chat and apps/netutils/chat: Contributed by by Vladimir Komendantskiy (2019-01-29). + * apps/examples/ubloxmodem: app to control the power state of the + modem in nsh. From Vladimir Komendantskiy (2019-01-31). diff --git a/examples/Kconfig b/examples/Kconfig index 9e0ee33b4..a2fcd4975 100644 --- a/examples/Kconfig +++ b/examples/Kconfig @@ -84,6 +84,7 @@ source "$APPSDIR/examples/udp/Kconfig" source "$APPSDIR/examples/udpblaster/Kconfig" source "$APPSDIR/examples/discover/Kconfig" source "$APPSDIR/examples/webserver/Kconfig" +source "$APPSDIR/examples/ubloxmodem/Kconfig" source "$APPSDIR/examples/unionfs/Kconfig" source "$APPSDIR/examples/usbserial/Kconfig" source "$APPSDIR/examples/usbterm/Kconfig" diff --git a/examples/README.txt b/examples/README.txt index 015be7cd6..04299c1b6 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1991,6 +1991,16 @@ examples/uavcan Illustrates use of canutils/uavcan. Contributed by Paul Alexander Patience. +examples/ubloxmodem +^^^^^^^^^^^^^^^^^^^ + + This app provides a command-line interface to GPIO power controls of u-blox + modem. The actual behaviour should be implemented in the lower-half modem + driver. Additionally the app can send test AT commands to the modem via the + TTY device node settable in the defconfig: + + CONFIG_EXAMPLES_UBLOXMODEM_TTY_DEVNODE="/dev/ttyS1" + examples/udp ^^^^^^^^^^^^ diff --git a/examples/ubloxmodem/.gitignore b/examples/ubloxmodem/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/examples/ubloxmodem/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/examples/ubloxmodem/Kconfig b/examples/ubloxmodem/Kconfig new file mode 100644 index 000000000..fcd6030e3 --- /dev/null +++ b/examples/ubloxmodem/Kconfig @@ -0,0 +1,27 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + + +menuconfig EXAMPLES_UBLOXMODEM + bool "u-blox modem configuration tool" + default n + ---help--- + Enable the u-blox modem configuration tool. + +if EXAMPLES_UBLOXMODEM + +config EXAMPLES_UBLOXMODEM_TTY_DEVNODE + string "u-blox modem TTY device node" + default "/dev/ttyS1" + ---help--- + TTY device node associated to the u-blox modem UART. + +config EXAMPLES_UBLOXMODEM_DEVNODE + string "u-blox modem device node" + default "/dev/ubxmdm" + ---help--- + Device node created by the u-blox modem driver. + +endif diff --git a/examples/ubloxmodem/Make.defs b/examples/ubloxmodem/Make.defs new file mode 100644 index 000000000..448de0904 --- /dev/null +++ b/examples/ubloxmodem/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/ubloxmodem/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. +# Author: Vladimir Komendantskiy +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_UBLOXMODEM),y) +CONFIGURED_APPS += examples/ubloxmodem +endif diff --git a/examples/ubloxmodem/Makefile b/examples/ubloxmodem/Makefile new file mode 100644 index 000000000..25c42b86e --- /dev/null +++ b/examples/ubloxmodem/Makefile @@ -0,0 +1,134 @@ +############################################################################ +# apps/examples/ubloxmodem/Makefile +# +# Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. +# Author: Vladimir Komendantskiy +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# u-blox modem tool + +ASRCS = +CSRCS = +MAINSRC = ubloxmodem_main.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_XYZ_PROGNAME ?= ubloxmodem$(EXEEXT) +PROGNAME = $(CONFIG_XYZ_PROGNAME) + +ROOTDEPPATH = --dep-path . +VPATH = + +APPNAME = ubloxmodem +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Build targets + +all: .built +.PHONY: context .depend depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + $(Q) touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/examples/ubloxmodem/ubloxmodem.h b/examples/ubloxmodem/ubloxmodem.h new file mode 100644 index 000000000..a542cf789 --- /dev/null +++ b/examples/ubloxmodem/ubloxmodem.h @@ -0,0 +1,80 @@ +/**************************************************************************** + * apps/examples/ubloxmodem/ubloxmodem.h + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * 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. + * + ****************************************************************************/ + +#ifndef __APPS_EXAMPLES_UBLOXMODEM_UBLOXMODEM_H +#define __APPS_EXAMPLES_UBLOXMODEM_UBLOXMODEM_H + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Command index */ + +enum ubloxmodem_cmd +{ + UBLOXMODEM_CMD_UNKNOWN = -1, + UBLOXMODEM_CMD_HELP = 0, + UBLOXMODEM_CMD_ON, + UBLOXMODEM_CMD_OFF, + UBLOXMODEM_CMD_RESET, + UBLOXMODEM_CMD_STATUS, + UBLOXMODEM_CMD_AT, +}; + +/* App context */ + +struct ubloxmodem_cxt +{ + int argc; + FAR char **argv; + enum ubloxmodem_cmd cmd; + int fd; +}; + +/* Type of function of the command state returning modified state */ + +typedef int (*ubloxmodem_fun)(FAR struct ubloxmodem_cxt* cxt); + +/* Command information tuple */ + +struct cmdinfo +{ + ubloxmodem_fun handler; /* Function that handles the command */ + FAR const char* name; /* Name of the command */ + FAR const char* desc; /* Short description */ + FAR const char* args; /* Description of command arguments */ +}; + +#endif // __APPS_EXAMPLES_UBLOXMODEM_UBLOXMODEM_H diff --git a/examples/ubloxmodem/ubloxmodem_main.c b/examples/ubloxmodem/ubloxmodem_main.c new file mode 100644 index 000000000..894a8f82d --- /dev/null +++ b/examples/ubloxmodem/ubloxmodem_main.c @@ -0,0 +1,441 @@ +/**************************************************************************** + * apps/examples/ubloxmodem/ubloxmodem_main.c + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * 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 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "ubloxmodem.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_MODEM_U_BLOX_DEBUG +# define m_dbg dbg +# define m_vdbg vdbg +# define m_vlldbg lldbg +# define m_vllvdbg llvdbg +#else +# define m_dbg(x...) +# define m_vdbg(x...) +# define m_lldbg(x...) +# define m_llvdbg(x...) +#endif + +#define UBLOXMODEM_MAX_REGISTERS 16 + +#if !defined(CONFIG_EXAMPLES_UBLOXMODEM_TTY_DEVNODE) +/* Use /dev/ttyS1 by default */ +# define CONFIG_EXAMPLES_UBLOXMODEM_TTY_DEVNODE "/dev/ttyS1" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int ubloxmodem_help (FAR struct ubloxmodem_cxt* cxt); +static int ubloxmodem_on (FAR struct ubloxmodem_cxt* cxt); +static int ubloxmodem_off (FAR struct ubloxmodem_cxt* cxt); +static int ubloxmodem_reset (FAR struct ubloxmodem_cxt* cxt); +static int ubloxmodem_status(FAR struct ubloxmodem_cxt* cxt); +static int ubloxmodem_at (FAR struct ubloxmodem_cxt* cxt); + +/* Mapping of command indices (@ubloxmodem_cmd@ implicit from the position in + * the list) to tuples containing the command handler and descriptive + * information. + */ + +static const struct cmdinfo cmdmap[] = +{ + {ubloxmodem_help, "help", "Show help", NULL}, + {ubloxmodem_on, "on", "Power ON", NULL}, + {ubloxmodem_off, "off", "Power OFF", NULL}, + {ubloxmodem_reset, "reset", "Reset", NULL}, + {ubloxmodem_status, "status", "Show status", NULL}, + {ubloxmodem_at, "at", "AT test", " "}, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int make_nonblock(int fd) +{ + int flags; + + if ((flags = fcntl(fd, F_GETFL, 0)) < 0) + { + return flags; + } + + if ((flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) < 0) + { + return flags; + } + + return 0; +} + +static int ubloxmodem_open_tty(void) +{ + int fd, ret; + + fd = open(CONFIG_EXAMPLES_UBLOXMODEM_TTY_DEVNODE, O_RDWR); + if (fd < 0) + { + m_vdbg("failed to open TTY\n"); + return fd; + } + + ret = make_nonblock(fd); + if (ret < 0) + { + m_vdbg("make_nonblock failed\n"); + close(fd); + return ret; + } + + return fd; +} + +static int chat_readb(int fd, FAR char* dst, int timeout_ms) +{ + struct pollfd fds; + int ret; + + fds.fd = fd; + fds.events = POLLIN; + fds.revents = 0; + + ret = poll(&fds, 1, timeout_ms); + if (ret <= 0) + { + m_vdbg("poll timed out\n"); + return -ETIMEDOUT; + } + + ret = read(fd, dst, 1); + if (ret != 1) + { + m_vdbg("read failed\n"); + return -EPERM; + } + + return 0; +} + +static int chat_match_response(int fd, FAR char* response, int timeout_ms) +{ + char c; + int ret; + int delim_countdown = 10; + + while (*response && delim_countdown >= 0) + { + ret = chat_readb(fd, &c, timeout_ms); + if (ret < 0) + { + return ret; + } + + if (c == *response) + { + response++; + } + else if (delim_countdown > 0 && (c == '\r' || c == '\n')) + { + delim_countdown--; + } + else + { + m_vdbg("expected %c (0x%02X), got %c (0x%02X)\n", + *response, *response, c, c); + return -EILSEQ; + } + } + + return 0; +} + +static int chat_single(int fd, FAR char* cmd, FAR char* resp) +{ + int ret; + + /* Write the command */ + + ret = write(fd, cmd, strlen(cmd)); + if (ret < 0) + { + return ret; + } + + /* Terminate the command with , hence sending it to the modem */ + + ret = write(fd, "\r", 1); + if (ret < 0) + { + return ret; + } + + /* Match the command echo */ + + ret = chat_match_response(fd, cmd, 5 * 1000); + if (ret < 0) + { + m_vdbg("invalid echo\n"); + return ret; + } + + /* Match the modem response to the command */ + + ret = chat_match_response(fd, resp, 5 * 1000); + return ret; +} + +static int ubloxmodem_help(FAR struct ubloxmodem_cxt* cxt) +{ + int i; + + printf("Usage: ubloxmodem [arguments]\n" + " where is one of\n"); + for (i = 0; + i < sizeof(cmdmap) / sizeof(struct cmdinfo); + i++) + { + printf("%s\n %s\n %s\n", + cmdmap[i].name, + cmdmap[i].desc, + (!cmdmap[i].args ? "No arguments" : cmdmap[i].args)); + } + + return 0; +} + +static int ubloxmodem_on(FAR struct ubloxmodem_cxt* cxt) +{ + int ret; + + ret = ioctl(cxt->fd, MODEM_IOC_POWERON, 0); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl failed: %d\n", errno); + return -EPERM; + } + + return ret; +} + +static int ubloxmodem_off(FAR struct ubloxmodem_cxt* cxt) +{ + int ret; + + ret = ioctl(cxt->fd, MODEM_IOC_POWEROFF, 0); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl failed: %d\n", errno); + return -EPERM; + } + + return ret; +} + +static int ubloxmodem_reset(FAR struct ubloxmodem_cxt* cxt) +{ + int ret; + + ret = ioctl(cxt->fd, MODEM_IOC_RESET, 0); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl failed: %d\n", errno); + return -EPERM; + } + + return ret; +} + +static int ubloxmodem_status(FAR struct ubloxmodem_cxt* cxt) +{ + int ret, i; + struct ubxmdm_status status; + + /* Allocate name-value pairs */ + + FAR struct ubxmdm_regval register_values[UBLOXMODEM_MAX_REGISTERS]; + char regname[4]; /* Null-terminated string buffer */ + + regname[3] = '\0'; /* Set the null string terminator */ + + /* Set the maximum value, to be updated by driver */ + + status.register_values_size = UBLOXMODEM_MAX_REGISTERS; + status.register_values = register_values; + + ret = ioctl(cxt->fd, MODEM_IOC_GETSTATUS, (unsigned long) &status); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl failed: %d\n", errno); + return EXIT_FAILURE; + } + + printf("Modem is %s\n", status.on ? "ON" : "OFF"); + for (i = 0; + i < status.register_values_size && i < UBLOXMODEM_MAX_REGISTERS; + i++) + { + strncpy(regname, status.register_values[i].name, 3); + printf("%s=%d ", + regname, + (int) status.register_values[i].val); + } + + printf("\n"); + return ret; +} + +static int ubloxmodem_at(FAR struct ubloxmodem_cxt* cxt) +{ + int fd, ret; + FAR char* atcmd; + FAR char* resp; + + atcmd = cxt->argv[2]; + resp = cxt->argv[3]; + + if (cxt->argc < 4 || atcmd == NULL || resp == NULL) + { + fprintf(stderr, "ERROR: missing arguments\n"); + return -EINVAL; + } + + fd = ubloxmodem_open_tty(); + if (fd < 0) + { + fprintf(stderr, "ERROR: cannot open TTY device: %d\n", errno); + return fd; + } + + ret = chat_single(fd, atcmd, resp); + + m_dbg("test result: %d\n", ret); + + close(fd); + return ret; +} + +static int ubloxmodem_parse(FAR struct ubloxmodem_cxt* cxt) +{ + int i; + + for (i = 0; + i < sizeof(cmdmap) / sizeof(struct cmdinfo) && + cxt->cmd == UBLOXMODEM_CMD_UNKNOWN; + i++) + { + if (!strcmp(cxt->argv[1], cmdmap[i].name)) + cxt->cmd = i; + } + + if (cxt->cmd == UBLOXMODEM_CMD_UNKNOWN) + { + cxt->cmd = UBLOXMODEM_CMD_HELP; + } + + return 0; +} + +inline int ubloxmodem_exec(FAR struct ubloxmodem_cxt* cxt) +{ + return (cmdmap[cxt->cmd].handler)(cxt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ubloxmodem_main + * + * Description: + * Main entry point for the u-blox modem tool. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char** argv) +#else +int ubloxmodem_main(int argc, FAR char** argv) +#endif +{ + struct ubloxmodem_cxt cxt; + int ret; + + cxt.argc = argc; + cxt.argv = argv; + cxt.cmd = UBLOXMODEM_CMD_UNKNOWN; + + ubloxmodem_parse(&cxt); + + cxt.fd = open(CONFIG_EXAMPLES_UBLOXMODEM_DEVNODE, O_RDWR); + if (cxt.fd < 0) + { + fprintf(stderr, "ERROR: Failed to open %s: %d\n", + CONFIG_EXAMPLES_UBLOXMODEM_DEVNODE, errno); + return EXIT_FAILURE; + } + + ret = ubloxmodem_exec(&cxt); + printf("Command result: %s (%d)\n", ret ? "FAIL" : "OK", ret); + + fflush(stdout); + close(cxt.fd); + + return 0; +}