Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Console.hxx
Go to the documentation of this file.
1
34#ifndef _CONSOLE_CONSOLE_HXX_
35#define _CONSOLE_CONSOLE_HXX_
36
37#include "openmrn_features.h"
38#include "utils/macros.h"
39#include "executor/Service.hxx"
41
42#if OPENMRN_FEATURE_BSD_SOCKETS
43#define CONSOLE_NETWORKING
44#endif
45
67class Console : public Service
68{
69private:
71 struct Command;
72
74 class Session;
75
76public:
87
90 typedef CommandStatus (*Callback)(FILE *, int, const char *argv[], void *);
91
98 Console(ExecutorBase *executor, uint16_t port);
99
108 Console(ExecutorBase *executor, int fd_in, int fd_out, int port = -1);
109
113 {
114 }
115
120 void add_session(int fd_in, int fd_out)
121 {
122 open_session(fd_in, fd_out);
123 }
124
130 void add_command(const char *name, Callback callback, void *context = NULL);
131
133 static const int FD_STDIN = 0;
134
136 static const int FD_STDOUT = 1;
137
176 {
177 protected:
182 CommandFlow(Console *console, const char *name);
183
186 ~CommandFlow();
187
192
197
199 int argc;
200
202 const char **argv;
203
205 FILE *fp;
206
218
224 {
225 this->status = status;
226 session->notify();
227 return STATE(exit);
228 }
229
230 private:
232 CommandStatus callback(Session *session, int fd, FILE *fp, int argc, const char *argv[])
233 {
234 this->session = session;
235 this->fd = fd;
236 this->fp = fp;
237 this->argc = argc;
238 this->argv = argv;
240
241 return COMMAND_NEXT;
242 }
243
246
248 int fd;
249
252
255
257 friend class Console;
258
260 friend class Session;
261
263 };
264
265private:
267 static const size_t MAX_ARGS = 10;
268
271 struct Command
272 {
279 Command(const char *name, Callback callback, void *context = NULL, Command *next = NULL)
280 : name(name)
283 , interactive(false)
284 , next(next)
285 {
286 }
287
293 Command(const char *name, CommandFlow *flow, Command *next = NULL)
294 : name(name)
295 , flow(flow)
296 , interactive(true)
297 , next(next)
298 {
299 }
300
301 const char *name;
302 union
303 {
304 struct
305 {
307 void *context;
308 };
310 };
313 };
314
315#if defined (CONSOLE_NETWORKING)
318 class Listen : public StateFlowBase
319 {
320 public:
325 Listen(Service *service, int port);
326
327 private:
332 {
333 return listen_and_call(&selectHelper, fdListen, STATE(accept));
334 }
335
340
342 int fdListen;
343
346
348 };
349#endif
350
353 class Session : public StateFlowBase
354 {
355 public:
361 Session(Service *service, int fd_in, int fd_out);
362
366 {
367 /* should only delete sockets, which should have the same read
368 * and write fds
369 */
370 HASSERT(fdIn == fdOut);
371 fclose(fp);
372 /* There is no need for a "close(fdIn)" because the "fclose(fp)"
373 * will already have completed that operation.
374 */
375 free(line);
376 }
377
378 private:
387
393
399
405 CommandStatus callback(int argc, const char *argv[]);
406
410 void prompt(FILE *fp)
411 {
412 fputs("> ", fp);
413 fflush(fp);
414 }
415
421 bool callback_result_process(CommandStatus status, const char *name);
422
423 int fdIn;
424 int fdOut;
425 FILE *fp;
426 char *line;
427 size_t line_size;
428 size_t pos;
429 const char *args[MAX_ARGS];
433
436
438 };
439
447 static CommandStatus help_command(FILE *fp, int argc, const char *argv[], void *context)
448 {
449 return static_cast<Console*>(context)->help_command(fp, argc, argv);
450 }
451
458 CommandStatus help_command(FILE *fp, int argc, const char *argv[]);
459
468 static CommandStatus quit_command(FILE *fp, int argc, const char *argv[], void *context)
469 {
470 return static_cast<Console*>(context)->quit_command(fp, argc, argv);
471 }
472
479 CommandStatus quit_command(FILE *fp, int argc, const char *argv[]);
480
485 void open_session(int fd_in, int fd_out);
486
489#if defined (CONSOLE_NETWORKING)
490 Listen listen;
491#endif
493 friend class CommandFlow;
494
496 friend class Listen;
497
499 friend class Session;
500
502};
503
504#endif // _CONSOLE_CONSOLE_HXX_
int accept(int socket, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition Socket.cxx:194
int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
Definition Socket.cxx:174
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
State flow base class that handles interactive commands.
Definition Console.hxx:176
~CommandFlow()
Destructor.
Definition Console.cxx:167
Command * command
Keep track of Command instance for destruction time.
Definition Console.hxx:245
virtual StateFlowBase::Action entry()=0
Entry point to command flow.
const char ** argv
list of arguments on command line
Definition Console.hxx:202
int argc
number of arguments on command line
Definition Console.hxx:199
StateFlowBase::Action wait_for_line_and_call(StateFlowBase::Callback c)
Wait for a complete line of input.
Definition Console.hxx:211
Session * session
Session flow to notify when command is complete.
Definition Console.hxx:251
CommandStatus callback(Session *session, int fd, FILE *fp, int argc, const char *argv[])
Start flow with the incoming data parameters.
Definition Console.hxx:232
int fd
file descriptor for input data
Definition Console.hxx:248
FILE * fp
FILE* reference for output data.
Definition Console.hxx:205
StateFlowBase::Action record_status_and_exit(CommandStatus status)
Record the CommandStatus and exit the CommandFlow.
Definition Console.hxx:223
CommandStatus status
Resulting status of running command.
Definition Console.hxx:254
StateFlowBase::Action read_line()
Read a line of input.
Console session metadata.
Definition Console.hxx:354
StateFlowBase::Action entry()
Entry point to the state machine.
Definition Console.hxx:382
~Session()
Desctructor.
Definition Console.hxx:365
StateFlowBase::Action exit_interactive()
Wait for completion of an interactive command in order to cleanup based on result.
Definition Console.cxx:408
Command * command
Command instance that we are currently acting on.
Definition Console.hxx:435
size_t pos
current line position
Definition Console.hxx:428
void prompt(FILE *fp)
Print the standard prompt.
Definition Console.hxx:410
size_t line_size
current max line size
Definition Console.hxx:427
CommandStatus callback(int argc, const char *argv[])
Process a potential callback for a given command.
Definition Console.cxx:379
StateFlowBase::StateFlowSelectHelper selectHelper
metadata for waiting on the listen socket to become active
Definition Console.hxx:432
int fdOut
output file descriptor of the session
Definition Console.hxx:424
const char * args[MAX_ARGS]
parsed argument list
Definition Console.hxx:429
char * line
current line content
Definition Console.hxx:426
FILE * fp
file pointer of session
Definition Console.hxx:425
int fdIn
input file descriptor of the session
Definition Console.hxx:423
StateFlowBase::Action process_read()
Process the incoming command line input.
Definition Console.cxx:278
bool callback_result_process(CommandStatus status, const char *name)
Process the result of the command callback.
Definition Console.cxx:428
This class provides a console available from stdin/stdout as well as via telnet.
Definition Console.hxx:68
friend class Listen
Give Listen class access to Console private members.
Definition Console.hxx:496
void add_command(const char *name, Callback callback, void *context=NULL)
Add a new command to the console.
Definition Console.cxx:94
~Console()
Destructor.
Definition Console.hxx:112
static const int FD_STDOUT
Default STDOUT file descriptor.
Definition Console.hxx:136
CommandStatus
Enumeration of recognized command callback results.
Definition Console.hxx:80
@ COMMAND_NOT_FOUND
Command not found.
Definition Console.hxx:85
@ COMMAND_ERROR
Command had some kind of error.
Definition Console.hxx:83
@ COMMAND_NEXT
Command waiting for input.
Definition Console.hxx:82
@ COMMAND_CLOSE
Command wants to close the session.
Definition Console.hxx:84
@ COMMAND_OK
Command executed successfully.
Definition Console.hxx:81
static CommandStatus help_command(FILE *fp, int argc, const char *argv[], void *context)
Print out the help menu by calling the in context helper function.
Definition Console.hxx:447
Command help
the "help" command instance
Definition Console.hxx:487
CommandStatus(* Callback)(FILE *, int, const char *argv[], void *)
Console command callback.
Definition Console.hxx:90
static CommandStatus quit_command(FILE *fp, int argc, const char *argv[], void *context)
Quit out of the current login session by calling the in context helper function.
Definition Console.hxx:468
static const int FD_STDIN
Default STDIN file descriptor.
Definition Console.hxx:133
Command helpMark
the help "?" command instance
Definition Console.hxx:488
void add_session(int fd_in, int fd_out)
Add a console session.
Definition Console.hxx:120
static const size_t MAX_ARGS
Maximum number of supported arguments including the command itself.
Definition Console.hxx:267
void open_session(int fd_in, int fd_out)
Open and initialize a new session.
Definition Console.cxx:83
This class implements an execution of tasks pulled off an input queue.
Definition Executor.hxx:64
Collection of related state machines that pend on incoming messages.
ExecutorBase * executor()
Return type for a state flow callback.
Base class for state machines.
Action read_single(StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
Attempts to read at most size_t bytes, and blocks the caller until at least one byte is read.
Service * service()
Return a pointer to the service I am bound to.
void notify() override
Wakeup call arrived.
Definition StateFlow.cxx:97
Action exit()
Terminate current StateFlow activity.
void start_flow(Callback c)
Resets the flow to the specified state and starts it.
Action wait_and_call(Callback c)
Wait for resource to become available before proceeding to next state.
Action(StateFlowBase::* Callback)()
State Flow callback prototype.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171
Console command metadata.
Definition Console.hxx:272
Command * next
next Command in list
Definition Console.hxx:312
CommandFlow * flow
state flow for interactive commands
Definition Console.hxx:309
void * context
context pointer to pass into callback
Definition Console.hxx:307
Command(const char *name, Callback callback, void *context=NULL, Command *next=NULL)
Construct a new command.
Definition Console.hxx:279
Callback callback
callback function for command
Definition Console.hxx:306
bool interactive
true if command is interactive
Definition Console.hxx:311
const char * name
command name
Definition Console.hxx:301
Command(const char *name, CommandFlow *flow, Command *next=NULL)
Construct a new command.
Definition Console.hxx:293
Use this class to read from an fd using select() in a state flow.