PX4 Firmware
PX4 Autopilot Software http://px4.io
qshell.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2016 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file qshell.cpp
36  * Listener for shell commands from posix
37  *
38  * @author Nicolas de Palezieux <ndepal@gmail.com>
39  */
40 
41 #include "qshell.h"
42 
43 #include <px4_platform_common/log.h>
44 #include <px4_platform_common/time.h>
45 #include <px4_platform_common/posix.h>
46 #include <px4_platform_common/defines.h>
47 #include <dspal_platform.h>
48 
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <iostream>
53 #include <fstream>
54 #include <sstream>
55 #include <signal.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 
60 #include <drivers/drv_hrt.h>
61 #include "DriverFramework.hpp"
62 
63 #define MAX_ARGS 8 // max number of whitespace separated args after app name
64 
65 px4::AppState QShell::appState;
66 
68 {
69  init_app_map(m_apps);
70 }
71 
73 {
74  appState.setRunning(true);
75  int sub_qshell_req = orb_subscribe(ORB_ID(qshell_req));
76 
77  if (sub_qshell_req == PX4_ERROR) {
78  PX4_ERR("Error subscribing to qshell_req topic");
79  return -1;
80  }
81 
82  px4_pollfd_struct_t fds[1] = {};
83  fds[0].fd = sub_qshell_req;
84  fds[0].events = POLLIN;
85 
86  orb_advert_t qshell_pub = nullptr;
87 
88  while (!appState.exitRequested()) {
89 
90  int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 1000);
91 
92  if (pret > 0 && fds[0].revents & POLLIN) {
93 
94  orb_copy(ORB_ID(qshell_req), sub_qshell_req, &m_qshell_req);
95 
96  PX4_INFO("qshell gotten: %s", m_qshell_req.cmd);
97  char current_char;
98  std::string arg;
99  std::vector<std::string> appargs;
100 
101  for (unsigned str_idx = 0; str_idx < m_qshell_req.strlen; str_idx++) {
102  current_char = m_qshell_req.cmd[str_idx];
103 
104  if (isspace(current_char)) { // split at spaces
105  if (arg.length()) {
106  appargs.push_back(arg);
107  arg = "";
108  }
109 
110  } else {
111  arg += current_char;
112  }
113  }
114 
115  appargs.push_back(arg); // push last argument
116 
117  struct qshell_retval_s retval;
118  retval.return_value = run_cmd(appargs);
120 
121  if (retval.return_value) {
122  PX4_ERR("Failed to execute command: %s", m_qshell_req.cmd);
123 
124  } else {
125  PX4_INFO("Ok executing command: %s", m_qshell_req.cmd);
126  }
127 
128  int instance;
129  orb_publish_auto(ORB_ID(qshell_retval), &qshell_pub, &retval, &instance, ORB_PRIO_DEFAULT);
130 
131  } else if (pret == 0) {
132  // Timing out is fine.
133  } else {
134  // Something is wrong.
135  usleep(10000);
136  }
137  }
138 
139  appState.setRunning(false);
140  return 0;
141 }
142 
143 int QShell::run_cmd(const std::vector<std::string> &appargs)
144 {
145  // command is appargs[0]
146  std::string command = appargs[0];
147 
148  if (command.compare("help") == 0) {
149  list_builtins(m_apps);
150  return 0;
151  }
152 
153  //replaces app.find with iterator code to avoid null pointer exception
154  for (apps_map_type::iterator it = m_apps.begin(); it != m_apps.end(); ++it) {
155  if (it->first == command) {
156  // one for command name, one for null terminator
157  const char *arg[MAX_ARGS + 2];
158 
159  unsigned int i = 0;
160 
161  if (appargs.size() > MAX_ARGS + 1) {
162  PX4_ERR("%d too many arguments in run_cmd", appargs.size() - (MAX_ARGS + 1));
163  return 1;
164  }
165 
166  while (i < appargs.size() && appargs[i].c_str()[0] != '\0') {
167  arg[i] = (char *)appargs[i].c_str();
168  PX4_DEBUG(" arg%d = '%s'\n", i, arg[i]);
169  ++i;
170  }
171 
172  arg[i] = (char *)0;
173 
174  //PX4_DEBUG_PRINTF(i);
175  if (m_apps[command] == NULL) {
176  PX4_ERR("Null function !!\n");
177 
178  } else {
179  return m_apps[command](i, (char **)arg);
180  }
181 
182  }
183  }
184 
185  PX4_ERR("Command %s not found", command.c_str());
186  return 1;
187 }
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
Definition: uORB.cpp:90
char cmd[100]
Definition: qshell_req.h:57
int main()
Definition: qshell.cpp:72
static px4::AppState appState
Definition: qshell.h:56
int32_t return_value
Definition: qshell_retval.h:54
int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout)
int run_cmd(const std::vector< std::string > &appargs)
Definition: qshell.cpp:143
LidarLite * instance
Definition: ll40ls.cpp:65
High-resolution timer with callouts and timekeeping.
int orb_subscribe(const struct orb_metadata *meta)
Definition: uORB.cpp:75
QShell()
Definition: qshell.h:51
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
uint32_t request_sequence
Definition: qshell_req.h:56
#define MAX_ARGS
Definition: qshell.cpp:63
uint32_t strlen
Definition: qshell_req.h:55
struct qshell_req_s m_qshell_req
Definition: qshell.h:62
uint32_t return_sequence
Definition: qshell_retval.h:55
apps_map_type m_apps
Definition: qshell.h:63
static int orb_publish_auto(const struct orb_metadata *meta, orb_advert_t *handle, const void *data, int *instance, int priority)
Advertise as the publisher of a topic.
Definition: uORB.h:177